diff --git a/.codacy.yaml b/.codacy.yaml deleted file mode 100644 index bec2d654f..000000000 --- a/.codacy.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -exclude_paths: - - "examples/**" - - "__tests__/**" - - "scripts/**" - - "forge-sql-orm-cli/__tests__/**" - - "forge-sql-orm-extra/__tests__/**" - - "forge-sql-orm-cli/src/actions/generate-models.ts" - - "vitest.config.mjs" \ No newline at end of file diff --git a/.codeclimate.yml b/.codeclimate.yml deleted file mode 100644 index 8ec3c3ca8..000000000 --- a/.codeclimate.yml +++ /dev/null @@ -1,25 +0,0 @@ -version: '2' -checks: - argument-count: - enabled: true - method-complexity: - enabled: false - -exclude_paths: - - "examples/" - - "forge-sql-orm-cli/" - - "node_modules/" - - "dist/" - - "coverage/" - - "**/*.test.ts" - -plugins: - eslint: - enabled: true - channel: "stable" - duplication: - enabled: false - fixme: - enabled: true - complexity: - enabled: fa diff --git a/.codeqlignore b/.codeqlignore deleted file mode 100644 index 48ace4fd7..000000000 --- a/.codeqlignore +++ /dev/null @@ -1,4 +0,0 @@ -# .codeqlignore -examples -schemas -img \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 851260b6c..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,3 +0,0 @@ -# These are supported funding model platforms - -open_collective: forge-sql-orm diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 251fb035b..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Define Entity '...' -2. Run query '...' -3. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Environment (please complete the following information):** - - Atlassian Product: [e.g. Jira, Confluence] - - Forge Runtime: [e.g. Node.js 20.x] - - Library Version: [e.g. 2.1.21] - -**Relevant Manifest.yaml** -Please provide the `permissions` and `modules` section from your `manifest.yaml`: -```yaml -permissions: - scopes: - - storage:app - - ... -``` -**Additional context** -Add any other context about the problem here (e.g. logs, error stack trace). diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bbcbbe7d6..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 109b314f5..000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,24 +0,0 @@ -# Description - -Please include a summary of the changes and the related issue. - -Fixes # (issue) - -## Type of change - -- [ ] Bug fix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] Refactoring (no functional changes, no api changes) - -## Checklist: - -**Important:** I have run the strict pre-commit checks locally. - -- [ ] I have run `npm run format` -- [ ] I have run `npm run build` (Type checking) -- [ ] I have run `npm run knip` (Dependency check) -- [ ] I have run `npm run lint` -- [ ] I have run `npm run test` and coverage is sufficient (>80%) -- [ ] I have added tests that prove my fix is effective or that my feature works -- [ ] I have updated the documentation (if applicable) diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 6a8e1c2ce..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,479 +0,0 @@ -version: 2 -updates: - # ========================================== - # ROOT & CLI - # ========================================== - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-root: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/forge-sql-orm-cli" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-cli: - patterns: - - "*" - - # ========================================== - # EXAMPLES - # ========================================== - - # --- drizzle-driver-simple --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-drizzle-driver-simple" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-drizzle: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-drizzle-driver-simple/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-drizzle-static: - patterns: - - "*" - - # --- dynamic --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-dynamic" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-dynamic: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-dynamic/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-dynamic-static: - patterns: - - "*" - - # --- optimistic-locking --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-optimistic-locking" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-optimistic: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-optimistic-locking/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-optimistic-static: - patterns: - - "*" - - # --- query-analyses --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-query-analyses" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-query-analyses: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-query-analyses/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-query-analyses-static: - patterns: - - "*" - - # --- simple --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-simple" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-simple: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-simple/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-simple-static: - patterns: - - "*" - - # --- checklist --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-checklist" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-checklist: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-checklist/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-checklist-static: - patterns: - - "*" - - # --- org-tracker --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-org-tracker" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-org-tracker: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-org-tracker/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-org-tracker-static: - patterns: - - "*" - - # --- sql-executor --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-sql-executor" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-sql-executor: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-sql-executor/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-sql-executor-static: - patterns: - - "*" - - # --- cache --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-cache" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-cache: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-cache/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-cache-static: - patterns: - - "*" - - # --- atlascamp --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-atlascamp" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-atlascamp: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-atlascamp/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-atlascamp-static: - patterns: - - "*" - - # --- vector --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-vector" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-vector: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-vector/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-vector-static: - patterns: - - "*" - - # --- ai --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-ai" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-ai: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-ai/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-ai-static: - patterns: - - "*" - - # --- backend-ai (3 folders: root, ai-lib, static) --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-backend-ai" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-backend-ai: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-backend-ai/ai-lib" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-backend-ai-lib: - patterns: - - "*" - - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-backend-ai/static/forge-orm-example" - ignore: - - dependency-name: "react" - - dependency-name: "react-dom" - - dependency-name: "@types/react" - - dependency-name: "@types/react-dom" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-backend-ai-static: - patterns: - - "*" - - # --- ui-kit --- - - package-ecosystem: "npm" - directory: "/examples/forge-sql-orm-example-ui-kit" - ignore: - - dependency-name: "react" - schedule: - interval: "daily" - open-pull-requests-limit: 5 - labels: - - dependencies - - npm - groups: - all-deps-ui-kit: - patterns: - - "*" diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml deleted file mode 100644 index 04fd90025..000000000 --- a/.github/workflows/automerge.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Auto-merge dependencies - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - labeled -permissions: - pull-requests: write - contents: write - -jobs: - enable-automerge: - runs-on: ubuntu-latest - # Match: dependabot bot PRs, plus any PR carrying the dependencies_updated - # label (set by .github/workflows/autoupdate.yml). - if: > - github.actor == 'dependabot[bot]' || - contains(github.event.pull_request.labels.*.name, 'dependencies_updated') - steps: - - name: Enable auto-merge for PR - run: gh pr merge --auto --merge "$PR_URL" - env: - PR_URL: ${{ github.event.pull_request.html_url }} - GH_TOKEN: ${{ secrets.AUTOUPDATE_PAT }} diff --git a/.github/workflows/autoupdate.yml b/.github/workflows/autoupdate.yml deleted file mode 100644 index f84fd50a2..000000000 --- a/.github/workflows/autoupdate.yml +++ /dev/null @@ -1,128 +0,0 @@ -name: Dependency autoupdate (every 6h) - -on: - schedule: - # Every 6 hours at the top of the hour (00:00, 06:00, 12:00, 18:00 UTC) - - cron: "0 */6 * * *" - workflow_dispatch: {} - -permissions: - contents: write - pull-requests: write - issues: write - -concurrency: - group: autoupdate - cancel-in-progress: true - -jobs: - autoupdate: - runs-on: ubuntu-latest - timeout-minutes: 60 - steps: - - name: Checkout master - uses: actions/checkout@v4 - with: - ref: master - fetch-depth: 0 - token: ${{ secrets.AUTOUPDATE_PAT }} - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: 24.x - cache: "npm" - - - name: Install ncu globally (pinned + no install scripts) - # Pinned version satisfies S8543; --ignore-scripts satisfies S6505. - run: npm install -g --ignore-scripts npm-check-updates@18.0.2 - - - name: Configure git as PR author - run: | - git config user.name "Vasyl Zakharchenko" - git config user.email "vaszakharchenko@gmail.com" - - - name: Ensure label exists - env: - GH_TOKEN: ${{ secrets.AUTOUPDATE_PAT }} - run: | - gh label create dependencies_updated \ - --color "0E8A16" \ - --description "Automated dependency updates" \ - --force - - - name: Close existing autoupdate PRs and delete their branches - env: - GH_TOKEN: ${{ secrets.AUTOUPDATE_PAT }} - run: | - # 1) Close PRs carrying the label (auto-deletes the head branch). - prs=$(gh pr list --label dependencies_updated --state open --json number --jq '.[].number') - if [ -n "$prs" ]; then - for pr in $prs; do - echo "Closing PR #$pr" - gh pr close "$pr" \ - --delete-branch \ - --comment "Superseded by today's autoupdate run." - done - else - echo "No existing autoupdate PRs to close." - fi - - # 2) Sweep up orphan dependencies/auto-* branches (pushed but never - # PR'd — e.g. when a previous run failed before gh pr create). - orphans=$(gh api -X GET repos/${{ github.repository }}/branches \ - --paginate --jq '.[].name' | grep '^dependencies/auto-' || true) - for b in $orphans; do - echo "Deleting orphan branch $b" - git push origin --delete "$b" || true - done - - - name: Run autoupdate.sh - run: | - chmod +x ./autoupdate.sh - ./autoupdate.sh - - - name: Detect changes - id: changes - run: | - # autoupdate.sh stages files per section; merge into one staged set - if git diff --cached --quiet && git diff --quiet; then - echo "changed=false" >> "$GITHUB_OUTPUT" - echo "Nothing to update." - else - echo "changed=true" >> "$GITHUB_OUTPUT" - fi - - - name: Create branch, commit, push, open PR - if: steps.changes.outputs.changed == 'true' - env: - GH_TOKEN: ${{ secrets.AUTOUPDATE_PAT }} - run: | - DATE=$(date -u +%Y-%m-%d) - BRANCH="dependencies/auto-${DATE}" - - git checkout -b "$BRANCH" - # Stage anything autoupdate.sh did not stage explicitly - git add -A - - # Final guard: the husky pre-commit hook re-runs npm i during commit, - # which can regenerate package-lock.json deterministically and - # collapse the diff that Detect changes saw. If nothing remains - # staged after the final add -A, exit cleanly — no PR needed. - if git diff --cached --quiet; then - echo "Nothing staged to commit after final add -A. Exiting cleanly." - exit 0 - fi - - git commit -m "chore(deps): daily autoupdate ${DATE}" - # Force-push as a safety net: the orphan-branch sweep above usually - # clears any pre-existing remote ref, but a same-day re-run would - # otherwise hit non-fast-forward on the second push. - git push -u origin "$BRANCH" --force - - gh pr create \ - --base master \ - --head "$BRANCH" \ - --title "chore(deps): daily autoupdate ${DATE}" \ - --body "Automated dependency update produced by \`.github/workflows/autoupdate.yml\`. Will auto-merge once required checks pass." \ - --label dependencies_updated diff --git a/.github/workflows/badge.yml b/.github/workflows/badge.yml deleted file mode 100644 index 8be07f626..000000000 --- a/.github/workflows/badge.yml +++ /dev/null @@ -1,132 +0,0 @@ -name: Badges - -on: - push: - branches: - - master - workflow_dispatch: {} - -permissions: - contents: write - -concurrency: - group: badges - cancel-in-progress: true - -jobs: - loc: - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout master - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: master - fetch-depth: 1 - - - name: Use Node.js 24.x - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version: 24.x - cache: 'npm' - - - name: Install deps (for license scan) - run: npm ci --ignore-scripts - - - name: Install forge-sql-orm-extra deps (for license scan) - run: cd forge-sql-orm-extra && npm ci --ignore-scripts - - - name: Prepare output dir - run: mkdir -p output - - # cloc-based LoC counter; pinned to commit SHA per repo policy. - # `loc-full` counts everything (incl. examples) minus markup/config noise. - - name: LoC (whole repo, including examples) - uses: alexispurslane/GHA-LoC-Badge@811a7fa2bae9860e8f254bcb9cfb71d021931a77 # v2.0.0 - with: - debug: true - directory: ./ - badge: ./output/loc-full.svg - badge_label: "LoC (full)" - badge_color: "blue" - ignore: "node_modules|dist|dist-cli|build|build-static|coverage|.qlty|*.js|*.jsx|*.mjs|*.cjs|*.min.js|package-lock.json|*.json|*.yml|*.yaml|*.md|*.css|*.html" - - # `loc-src` counts only src/ + forge-sql-orm-cli/src/. - # The action's `directory:` doesn't combine well with a synthetic staging - # dir (cloc receives glob-relative paths but runs from the workspace - # root, so a sub-`directory:` resolves to nothing). Restricting via - # `patterns:` keeps glob anchored at the workspace root. - - name: LoC (library + CLI sources only) - uses: alexispurslane/GHA-LoC-Badge@811a7fa2bae9860e8f254bcb9cfb71d021931a77 # v2.0.0 - with: - debug: true - directory: ./ - badge: ./output/loc-src.svg - badge_label: "LoC (src)" - badge_color: "green" - patterns: "src/**|forge-sql-orm-cli/src/**|forge-sql-orm-extra/src/**" - ignore: "*.js|*.jsx|*.mjs|*.cjs|*.min.js" - - # Runs the same blocklist gate as CI; one badge per package (core + extra). - # `badge` CLI ships with badge-maker (the shields.io renderer) — fetched - # via npx, so no extra dependency in package.json. - - name: License compliance badges - run: | - mkdir -p output - - write_license_badge() { - local check_status=$1 - local output_file=$2 - local label=$3 - if [ "$check_status" -eq 0 ]; then - message="no copyleft" - color=":brightgreen" - else - message="copyleft found" - color=":red" - fi - npx --yes -p badge-maker badge "$label" "$message" "$color" @flat > "$output_file" - } - - set +e - npm run license:check > /dev/null 2>&1 - core_status=$? - (cd forge-sql-orm-extra && npm run license:check > /dev/null 2>&1) - extra_status=$? - set -e - - write_license_badge "$core_status" output/license-compliance.svg licenses - write_license_badge "$extra_status" output/extra-license-compliance.svg "extra licenses" - - - name: Publish badges to `badges` branch - run: | - set -euo pipefail - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - # Stash badge SVGs outside the worktree so the orphan reset - # below doesn't wipe them. - TMP=$(mktemp -d) - cp output/loc-full.svg "$TMP/" - cp output/loc-src.svg "$TMP/" - cp output/license-compliance.svg "$TMP/" - cp output/extra-license-compliance.svg "$TMP/" - - git checkout --orphan badges - git rm -rf --quiet . || true - git clean -fdx -e output - - mv "$TMP/loc-full.svg" ./loc-full.svg - mv "$TMP/loc-src.svg" ./loc-src.svg - mv "$TMP/license-compliance.svg" ./license-compliance.svg - mv "$TMP/extra-license-compliance.svg" ./extra-license-compliance.svg - - git add loc-full.svg loc-src.svg license-compliance.svg extra-license-compliance.svg - if git diff --cached --quiet; then - echo "No badge changes — nothing to publish." - exit 0 - fi - - git commit -m "chore(badges): refresh repo badges" - git push -f origin badges diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml deleted file mode 100644 index 88e240c54..000000000 --- a/.github/workflows/node.js.yml +++ /dev/null @@ -1,316 +0,0 @@ -# CI split into jobs: quality gate + CLI + examples matrix (built/deployed in parallel). -name: forge-sql-orm CI -on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] - -concurrency: - group: ${{ github.workflow }}-${{ github.actor == 'dependabot[bot]' && github.run_id || github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} - -jobs: - # --- Quality gate: core library lint / build / tests / coverage scanners --- - quality: - runs-on: ubuntu-latest - env: - SONARCLOUD_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }} - QLTY_COVERAGE_TOKEN: ${{ secrets.QLTY_COVERAGE_TOKEN }} - CODACY_API_TOKEN: ${{ secrets.CODACY_API_TOKEN }} - permissions: - contents: read - packages: write - pull-requests: write - strategy: - matrix: - node-version: [24.x] - outputs: - core_version: ${{ steps.publish_core.outputs.core_version }} - extra_version: ${{ steps.publish_extra.outputs.extra_version }} - cli_version: ${{ steps.publish_cli.outputs.cli_version }} - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - fetch-depth: 0 - persist-credentials: false - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: npm ci --ignore-scripts - - name: REUSE / SPDX compliance - uses: fsfe/reuse-action@bb774aa972c2a89ff34781233d275075cbddf542 # v5 - - run: npm run knip - - name: License compliance (no GPL/LGPL/AGPL/copyleft) - run: npm run license:check - - run: npm run lint - - run: npm run build - - run: npm run format:check - - run: npm run test:coverage - - name: Publish forge-sql-orm to GitHub Packages (not npmjs.com) - if: github.actor != 'dependabot[bot]' - id: publish_core - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - node scripts/ci/github-packages.mjs publish-core - echo "core_version=$(node scripts/ci/github-packages.mjs ci-version)" >> "$GITHUB_OUTPUT" - - name: Extra package (knip / build / tests with coverage) - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - cd forge-sql-orm-extra - npm ci --ignore-scripts - if [ "${{ github.actor }}" != "dependabot[bot]" ]; then - node ../scripts/ci/github-packages.mjs install-workspace . "${{ steps.publish_core.outputs.core_version }}" - fi - npm run license:check - npm run knip - npm run build - npm run test:coverage - - name: Publish forge-sql-orm-extra to GitHub Packages - if: github.actor != 'dependabot[bot]' - id: publish_extra - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - node scripts/ci/github-packages.mjs publish-extra "${{ steps.publish_core.outputs.core_version }}" - echo "extra_version=$(node scripts/ci/github-packages.mjs ci-version forge-sql-orm-extra)" >> "$GITHUB_OUTPUT" - - name: CLI package (knip / lint / build / tests with coverage) - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - cd forge-sql-orm-cli - npm ci --ignore-scripts - if [ "${{ github.actor }}" != "dependabot[bot]" ]; then - node ../scripts/ci/github-packages.mjs install-workspace . "${{ steps.publish_core.outputs.core_version }}" - fi - npm run knip - npm run lint - npm run build - npm run test:coverage - - name: Publish forge-sql-orm-cli to GitHub Packages - if: github.actor != 'dependabot[bot]' - id: publish_cli - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - node scripts/ci/github-packages.mjs publish-cli "${{ steps.publish_core.outputs.core_version }}" - echo "cli_version=$(node scripts/ci/github-packages.mjs ci-version forge-sql-orm-cli)" >> "$GITHUB_OUTPUT" - - name: Merge library + EXTRA + CLI coverage into a single report - if: env.SONARCLOUD_TOKEN != '' || env.QLTY_COVERAGE_TOKEN != '' || env.CODACY_API_TOKEN != '' - run: npm run coverage:merge - - name: SonarQube Scan - if: env.SONARCLOUD_TOKEN != '' - uses: SonarSource/sonarqube-scan-action@c7ee0f9df90b7aa20e8dcf9695dcfe2e7da5b4f2 # v7.2.1 - env: - SONAR_TOKEN: ${{ env.SONARCLOUD_TOKEN }} - - name: Upload to Qlty - if: env.QLTY_COVERAGE_TOKEN != '' - uses: qltysh/qlty-action/coverage@141b881236146435192435eb7b0e06ea0b70b4d9 # main as of 2026-05-12 - with: - coverage-token: ${{ env.QLTY_COVERAGE_TOKEN }} - files: ./coverage/lcov.info - - name: Upload coverage to Codacy - if: env.CODACY_API_TOKEN != '' - uses: codacy/codacy-coverage-reporter-action@89d6c85cfafaec52c72b6c5e8b2878d33104c699 # v1.3.0 - with: - api-token: ${{ env.CODACY_API_TOKEN }} - coverage-reports: ./coverage/lcov.info - - # --- Examples: one matrix entry per example, built & deployed in parallel --- - examples: - needs: quality - runs-on: ubuntu-latest - permissions: - contents: read - packages: read - environment: ${{ github.event_name == 'push' && 'production' || (github.event_name == 'workflow_dispatch' && inputs.environment || 'development') }} - strategy: - fail-fast: false - max-parallel: 5 - matrix: - include: - # static: true-> has static/forge-orm-example frontend - # ai_lib: true-> has ai-lib that needs build:arm64 - - { dir: forge-sql-orm-example-drizzle-driver-simple, static: true } - - { dir: forge-sql-orm-example-simple, static: true } - - { dir: forge-sql-orm-example-optimistic-locking, static: true } - - { dir: forge-sql-orm-example-query-analyses, static: true } - - { dir: forge-sql-orm-example-checklist, static: true } - - { dir: forge-sql-orm-example-org-tracker, static: true } - - { dir: forge-sql-orm-example-dynamic, static: true } - - { dir: forge-sql-orm-example-sql-executor, static: true } - - { dir: forge-sql-orm-example-cache, static: true } - - { dir: forge-sql-orm-example-atlascamp, static: true } - - { dir: forge-sql-orm-example-vector, static: true } - - { dir: forge-sql-orm-example-ai, static: true } - - { dir: forge-sql-orm-example-backend-ai, static: true, ai_lib: true } - - { dir: forge-sql-orm-example-ui-kit } - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version: 24.x - cache: 'npm' - - run: npm install -g @forge/cli && forge settings set usage-analytics true - - # push / dispatch-production -> "production"; everything else (PRs, - # dispatch-development) -> per-actor env named after the sanitized actor. - - name: Resolve Forge environment - env: - EVENT_NAME: ${{ github.event_name }} - INPUT_ENV: ${{ inputs.environment }} - ACTOR: ${{ github.actor }} - run: | - if [ "$EVENT_NAME" = "push" ] || { [ "$EVENT_NAME" = "workflow_dispatch" ] && [ "$INPUT_ENV" = "production" ]; }; then - forge_env="production" - else - forge_env="$(echo "$ACTOR" | tr -cd '[:alnum:]')" - fi - echo "FORGE_ENV=$forge_env" >> "$GITHUB_ENV" - echo "Resolved FORGE_ENV=$forge_env" - - - name: Install example deps - run: cd examples/${{ matrix.dir }} && npm ci --ignore-scripts - - name: Install published workspace packages from GitHub Packages - if: github.actor != 'dependabot[bot]' && needs.quality.outputs.core_version != '' - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - node scripts/ci/github-packages.mjs install-example \ - "examples/${{ matrix.dir }}" \ - "${{ needs.quality.outputs.core_version }}" \ - "${{ needs.quality.outputs.extra_version }}" \ - "${{ needs.quality.outputs.cli_version }}" - - name: Knip (example) - run: cd examples/${{ matrix.dir }} && npm run knip - - name: Build example - run: cd examples/${{ matrix.dir }} && npm run build:ci - - - name: Build ai-lib (arm64) - if: matrix.ai_lib - run: cd examples/${{ matrix.dir }}/ai-lib && npm ci --ignore-scripts && npm run build:arm64 - - - name: Install frontend deps - if: matrix.static - run: cd examples/${{ matrix.dir }}/static/forge-orm-example && npm ci --ignore-scripts - - name: Knip (frontend) - if: matrix.static - run: cd examples/${{ matrix.dir }}/static/forge-orm-example && npm run knip - - name: Build frontend - if: matrix.static - run: cd examples/${{ matrix.dir }}/static/forge-orm-example && npm run build - - # One retry: Forge deploys hit transient Atlassian-side failures. - - name: Forge Deploy (${{ env.FORGE_ENV }}) - if: github.actor != 'dependabot[bot]' - env: - FORGE_EMAIL: ${{ secrets.FORGE_EMAIL }} - FORGE_API_TOKEN: ${{ secrets.FORGE_API_TOKEN }} - run: | - cd "examples/${{ matrix.dir }}" - for attempt in 1 2; do - if forge deploy --non-interactive -e "$FORGE_ENV"; then - exit 0 - fi - echo "::warning::forge deploy attempt $attempt failed for ${{ matrix.dir }}" - [ "$attempt" -lt 2 ] && sleep $((RANDOM % 21 + 10)) - done - echo "forge deploy failed after 2 attempts" - exit 1 - # Existing install on this site+environment -> --upgrade; otherwise a - # fresh install. The install list is parsed inline with Node.js. - # One retry (re-evaluated each attempt) for transient Atlassian failures. - - name: Forge Install (${{ env.FORGE_ENV }}) - if: github.actor != 'dependabot[bot]' - env: - FORGE_EMAIL: ${{ secrets.FORGE_EMAIL }} - FORGE_API_TOKEN: ${{ secrets.FORGE_API_TOKEN }} - FORGE_HOSTNAME: ${{ secrets.FORGE_HOSTNAME }} - run: | - cd "examples/${{ matrix.dir }}" - if [ -z "${FORGE_HOSTNAME:-}" ]; then - echo "::error::FORGE_HOSTNAME secret is empty or unset — refusing to install (an empty host matches every site)" - exit 1 - fi - install_once() { - # Don't mask failures: if the list call fails (e.g. transient - # network error) return non-zero so the loop retries the whole - # sequence, instead of silently assuming "not installed". - if ! installs="$(forge install list --json)"; then - echo "::warning::forge install list failed for ${{ matrix.dir }}" - return 1 - fi - already_installed="$(FORGE_INSTALLS="$installs" node -e ' - const raw = process.env.FORGE_INSTALLS || "[]"; - let data; - try { data = JSON.parse(raw); } catch { data = []; } - const list = Array.isArray(data) ? data : (data.installations || data.result || data.data || []); - const host = (process.env.FORGE_HOSTNAME || "").toLowerCase(); - const envName = (process.env.FORGE_ENV || "").toLowerCase(); - const found = !!host && list.some((i) => { - const site = String(i.site || i.siteUrl || i.host || i.hostname || "").toLowerCase(); - const env = String(i.environmentKey || i.environment || i.environmentType || "").toLowerCase(); - return site.includes(host) && env === envName; - }); - process.stdout.write(found ? "yes" : "no"); - ')" - if [ "$already_installed" = "yes" ]; then - echo "Found existing installation on $FORGE_HOSTNAME ($FORGE_ENV) -> upgrading" - forge install -e "$FORGE_ENV" -s "$FORGE_HOSTNAME" -p Jira --confirm-scopes --non-interactive --upgrade - else - echo "No installation on $FORGE_HOSTNAME ($FORGE_ENV) -> fresh install" - forge install -e "$FORGE_ENV" -s "$FORGE_HOSTNAME" -p Jira --confirm-scopes --non-interactive - fi - } - for attempt in 1 2; do - if install_once; then - exit 0 - fi - echo "::warning::forge install attempt $attempt failed for ${{ matrix.dir }}" - [ "$attempt" -lt 2 ] && sleep $((RANDOM % 21 + 10)) - done - echo "forge install failed after 2 attempts" - exit 1 - - build: - if: always() - needs: [quality, examples] - runs-on: ubuntu-latest - permissions: - contents: read - strategy: - matrix: - node-version: [24.x] - steps: - - name: Fail if any dependency failed or was cancelled - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') - run: | - echo "One or more jobs did not succeed: ${{ join(needs.*.result, ', ') }}" - exit 1 - - name: All required jobs passed - run: echo "quality and all examples succeeded" - - # Every run publishes ephemeral -ci.* versions for downstream jobs; delete them - # after the workflow finishes so GitHub Packages storage does not accumulate. - cleanup-gpr: - needs: [build] - if: always() && github.actor != 'dependabot[bot]' - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - name: Delete CI package versions from GitHub Packages - continue-on-error: true - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: node scripts/ci/github-packages.mjs cleanup-ci-versions diff --git a/.github/workflows/weekly-gpr.yml b/.github/workflows/weekly-gpr.yml deleted file mode 100644 index e408c965d..000000000 --- a/.github/workflows/weekly-gpr.yml +++ /dev/null @@ -1,126 +0,0 @@ -# Weekly snapshot of master → GitHub Packages (dist-tag: latest). -# Runs the same quality gate as CI (lint, knip, build, tests) before publish. -# Official semver releases stay on npmjs.com (manual). -name: Weekly GitHub Packages (latest) - -on: - schedule: - # Sunday 02:00 UTC - - cron: "0 2 * * 0" - workflow_dispatch: {} - -permissions: - contents: read - packages: write - -concurrency: - group: weekly-gpr - cancel-in-progress: false - -jobs: - weekly-latest: - runs-on: ubuntu-latest - timeout-minutes: 45 - env: - GH_TOKEN: ${{ github.token }} - NODE_AUTH_TOKEN: ${{ github.token }} - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: master - fetch-depth: 1 - - - name: Use Node.js 24.x - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version: 24.x - cache: npm - - - name: Install core dependencies - run: npm ci --ignore-scripts - - - name: REUSE / SPDX compliance - uses: fsfe/reuse-action@bb774aa972c2a89ff34781233d275075cbddf542 # v5 - - - run: npm run knip - - - name: License compliance (no GPL/LGPL/AGPL/copyleft) - run: npm run license:check - - - run: npm run lint - - run: npm run build - - run: npm run format:check - - run: npm run test:coverage - - - name: Set weekly version suffix - id: weekly - run: | - if [ "${{ github.event_name }}" = "schedule" ]; then - echo "date=$(date -u +%Y%m%d)" >> "$GITHUB_OUTPUT" - else - echo "date=$(date -u +%Y%m%d)-m${{ github.run_number }}" >> "$GITHUB_OUTPUT" - fi - - - name: Publish weekly forge-sql-orm to GitHub Packages (latest) - id: publish_weekly_core - env: - WEEKLY_BUILD_DATE: ${{ steps.weekly.outputs.date }} - run: | - node scripts/ci/github-packages.mjs publish-weekly-core - echo "core_version=$(node scripts/ci/github-packages.mjs weekly-version)" >> "$GITHUB_OUTPUT" - - - name: Extra package (quality gate) - env: - WEEKLY_BUILD_DATE: ${{ steps.weekly.outputs.date }} - run: | - cd forge-sql-orm-extra - npm ci --ignore-scripts - node ../scripts/ci/github-packages.mjs install-workspace . "${{ steps.publish_weekly_core.outputs.core_version }}" - npm run license:check - npm run knip - npm run build - npm run test:coverage - - - name: Publish weekly forge-sql-orm-extra to GitHub Packages (latest) - id: publish_weekly_extra - env: - WEEKLY_BUILD_DATE: ${{ steps.weekly.outputs.date }} - run: | - node scripts/ci/github-packages.mjs publish-weekly-extra "${{ steps.publish_weekly_core.outputs.core_version }}" - echo "extra_version=$(node scripts/ci/github-packages.mjs weekly-version forge-sql-orm-extra)" >> "$GITHUB_OUTPUT" - - - name: CLI package (quality gate) - env: - WEEKLY_BUILD_DATE: ${{ steps.weekly.outputs.date }} - run: | - cd forge-sql-orm-cli - npm ci --ignore-scripts - node ../scripts/ci/github-packages.mjs install-workspace . "${{ steps.publish_weekly_core.outputs.core_version }}" - npm run knip - npm run lint - npm run build - npm run test:coverage - - - name: Publish weekly forge-sql-orm-cli to GitHub Packages (latest) - id: publish_weekly_cli - env: - WEEKLY_BUILD_DATE: ${{ steps.weekly.outputs.date }} - run: | - node scripts/ci/github-packages.mjs publish-weekly-cli "${{ steps.publish_weekly_core.outputs.core_version }}" - echo "cli_version=$(node scripts/ci/github-packages.mjs weekly-version forge-sql-orm-cli)" >> "$GITHUB_OUTPUT" - - - name: Delete all ephemeral ci.* versions from GitHub Packages - continue-on-error: true - run: node scripts/ci/github-packages.mjs cleanup-all-ci-versions - - - name: Summary - run: | - echo "## Weekly GitHub Packages (latest)" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "| Package | Version | dist-tag |" >> "$GITHUB_STEP_SUMMARY" - echo "| --- | --- | --- |" >> "$GITHUB_STEP_SUMMARY" - echo "| forge-sql-orm | ${{ steps.publish_weekly_core.outputs.core_version }} | latest |" >> "$GITHUB_STEP_SUMMARY" - echo "| forge-sql-orm-extra | ${{ steps.publish_weekly_extra.outputs.extra_version }} | latest |" >> "$GITHUB_STEP_SUMMARY" - echo "| forge-sql-orm-cli | ${{ steps.publish_weekly_cli.outputs.cli_version }} | latest |" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "Commit: \`${{ github.sha }}\`" >> "$GITHUB_STEP_SUMMARY" diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 5a3577ea9..000000000 --- a/.gitignore +++ /dev/null @@ -1,150 +0,0 @@ -# CI-generated auth for GitHub Packages (scripts/ci/github-packages.mjs) -.npmrc - -# Logs -logs -*.log -.qlty -.qlty/** -.claude -.claude/** -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist -dist-cli - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* -dependency-chunks.html -.cursor -.idea -.env - -# Frontend bundles in example projects (regenerated by `npm run build`) -examples/*/static/forge-orm-example/build-*/ - -# macOS metadata -.DS_Store -**/.DS_Store - -# Editor / tool backups -*.bak \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 204267067..000000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -set -e -echo '🔍 Running forge-sql-orm checks...' - -echo '➡️ lint-staged (forge-sql-orm)' -npx lint-staged || { echo '❌ lint-staged failed for resolver'; exit 1; } - -echo '➡️ typecheck (forge-sql-orm)' -npm run build || { echo '❌ build failed'; exit 1; } - -echo '➡️ dependencies check' -npm run knip || { echo '❌ Dependency check failed.'; exit 1; } - -echo '➡️ lint check' -npm run lint || { echo '❌ lint check failed.'; exit 1; } - -echo '➡️ run tests check' -npm run test || { echo '❌ tests check failed.'; exit 1; } - -echo '🔍 Running forge-sql-orm-extra resources checks...' -( - cd forge-sql-orm-extra || exit 1 - - echo '➡️ lint-staged (forge-sql-orm-extra resources)' - npx lint-staged || { echo '❌ lint-staged failed for forge-sql-orm-extra resources'; exit 1; } - - echo '➡️ dependencies check' - npm run knip || { echo '❌ Dependency check for forge-sql-orm-extra resources failed.'; exit 1; } - - echo '➡️ run tests check' - npm run test || { echo '❌ tests check forge-sql-orm-extra failed.'; exit 1; } - - echo '➡️ build' - npm run build || { echo '❌Build forge-sql-orm-extra failed'; exit 1; } -) - -echo '🔍 Running forge-sql-orm-cli resources checks...' -( - cd forge-sql-orm-cli || exit 1 - - echo '➡️ lint-staged (forge-sql-orm-cli resources)' - npx lint-staged || { echo '❌ lint-staged failed for forge-sql-orm-cli resources'; exit 1; } - - echo '➡️ dependencies check' - npm run knip || { echo '❌ Dependency check for forge-sql-orm-cli resources failed.'; exit 1; } - - echo '➡️ run tests check' - npm run test || { echo '❌ tests check failed.'; exit 1; } - - echo '➡️ build' - npm run build || { echo '❌ Build failed'; exit 1; } -) \ No newline at end of file diff --git a/.ncurc.json b/.ncurc.json deleted file mode 100644 index 921b45cfc..000000000 --- a/.ncurc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "reject": [] -} diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 51c3d5d72..000000000 --- a/.prettierignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules -dist -dist-cli -scripts/postinstall.ts -package-lock.json diff --git a/.qltyignore b/.qltyignore deleted file mode 100644 index aa9915ccb..000000000 --- a/.qltyignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules/ -dist/ -coverage/ -examples/ -scripts/ -forge-sql-orm-cli/ -img -schemas \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 37f25dcf7..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,1162 +0,0 @@ -# Changelog - -All notable changes to this project are documented in this file. -The entries are generated from the corresponding GitHub Releases and -preserved verbatim. The project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -> See also: [GitHub Releases](https://github.com/forge-sql-orm/forge-sql-orm/releases). - -## [2.2.0] - 2026-06-06 - -🚀 What's New - -📦 Modular packages ([#2321](https://github.com/forge-sql-orm/forge-sql-orm/issues/2321)) - -Advanced capabilities are split out of the monolith so **ORM-only** apps get a smaller dependency footprint and fewer surprises from transitive packages during Forge bundling and lint (see also [#2128](https://github.com/forge-sql-orm/forge-sql-orm/issues/2128)). Keeping everything in one package with `optionalDependencies` was not sufficient: Forge often still resolves and analyzes those dependencies even when a feature is unused. - -| Package | Responsibility | -| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`forge-sql-orm`** | Core ORM: Drizzle + `@forge/sql`, migrations, optimistic locking, query observability, **Level 1 local cache**, `Cache` SPI + default **`NopCache`** | -| **`forge-sql-orm-extra`** | **Level 2** global cache (`@forge/kvs`, `KVSCache`, SQL-parser cache invalidation), Rovo, `clearCacheSchedulerTrigger` | -| **`forge-sql-orm-cli`** | Schema / migration CLI (unchanged role) | - -The core package remains fully usable **without** installing `forge-sql-orm-extra`. - -🧩 Cache SPI (Level 2) - -- New **`Cache`** interface in core (`getQueryResultsFromCache`, `setQueryResult`, `clearExpiredCache`, `clearTablesCache`). -- **`NopCache`** in core — default on `forge-sql-orm`; global cache methods do not persist to KVS. -- **`KVSCache`** in **forge-sql-orm-extra** — default on `forge-sql-orm-extra`; Forge KVS backend (cursor pagination, batched deletes, retry with backoff). -- `cacheImplementation` on `ForgeSqlOrmOptions` to plug in a custom backend or tests. - -**Level 1 (local / in-memory) cache** (`executeWithLocalContext`, `selectFrom`, `execute`, …) stays in **core** and works the same with either import. - -Manual global cache eviction is simplified: - -```typescript -await forgeSQL.evictCache(["users", "orders"]); -await forgeSQL.evictCacheEntities([Users, Orders]); -``` - -📖 Documentation split between [README.md](README.md) (core) and [forge-sql-orm-extra/README.md](forge-sql-orm-extra/README.md) (L2 cache + Rovo). - ---- - -⚠️ Migration to 2.2.x - -### Why this release - -- **Smaller core** for users who only need SQL + Drizzle + migrations. -- **Fewer transitive risks** (`node-sql-parser`, `@forge/kvs`, Rovo code paths) for apps that never enable those features. -- **Clear boundaries** between core, extensions, and CLI — easier maintenance and future optional modules. - -### If you only use the ORM (no global KVS cache, no Rovo) - -**No migration required.** - -```bash -npm install forge-sql-orm @forge/sql drizzle-orm -S -``` - -```typescript -import ForgeSQL from "forge-sql-orm"; -const forgeSQL = new ForgeSQL(); -``` - -Local cache, versioning, and Drizzle helpers behave as before. Core defaults to `NopCache()` for Level 2. - -### If you use global cache (Level 2) and/or Rovo - -1. Install the extension (keep core deps): - - ```bash - npm install forge-sql-orm-extra @forge/kvs -S - ``` - -2. Change the import — **logic, options, and queries stay the same**: - - ```typescript - // Before (monolith ≤ 2.1.x) - import ForgeSQL from "forge-sql-orm"; - - // After (2.2.x) - import ForgeSQL from "forge-sql-orm-extra"; - ``` - -3. Keep existing cache configuration, for example: - - ```typescript - const forgeSQL = new ForgeSQL({ - cacheEntityName: "cache", - cacheTTL: 300, - }); - ``` - -4. Update moved imports, for example: - - ```typescript - import { clearCacheSchedulerTrigger } from "forge-sql-orm-extra"; - ``` - -5. Replace manual eviction via `modifyWithVersioningAndEvictCache().evictCache*` with: - - ```typescript - await forgeSQL.evictCache(["users", "orders"]); - await forgeSQL.evictCacheEntities([Users, Orders]); - ``` - -`forge-sql-orm-extra` defaults to `new KVSCache()` — equivalent to the old monolith behaviour once you switch the import. - -Full details: [README — Breaking Changes (2.2.x)](README.md#4-breaking-changes-22x--core-vs-extra) and [forge-sql-orm-extra README](forge-sql-orm-extra/README.md). - ---- - -🧪 CLI Test Suite & Merged Coverage - -`forge-sql-orm-cli` now has its own test safety net, and coverage from the library and the CLI is reported together. - -- Added Vitest unit tests for the CLI (command wiring, model generation, migration create/update/drop, schema diffing) behind an 80% coverage gate. -- Library and CLI `lcov` reports are merged into a single report for SonarCloud and Qlty. - -🧹 Quality & Static Analysis - -- Banned explicit `any` in the CLI (`@typescript-eslint/no-explicit-any`) and replaced `any` in catch blocks across the codebase. -- Lowered cognitive complexity in the CLI model/migration generators and applied SonarCloud fixes (`node:` import prefixes, `Number.parseInt`, locale-aware sorting, and more). -- Stricter Knip configuration, SPDX/REUSE license headers, and a license-compliance check that fails on GPL/LGPL/AGPL/copyleft dependencies. -- Documented the console-based logging policy (NFR-11). - -🛠 CI / Release Automation - -- Split the monolithic pipeline into separate quality / CLI / examples jobs; example deploys are capped at `max-parallel: 5`. -- Randomized Forge deploy/install retry backoff to ride out transient Atlassian failures. -- Codacy `exclude_paths` tuning and a Codacy badge in the README. -- **Weekly GitHub Packages (`latest`)** — workflow [`.github/workflows/weekly-gpr.yml`](.github/workflows/weekly-gpr.yml) runs every **Sunday 02:00 UTC** (and on manual dispatch). It checks out `master`, runs the same quality gate as CI (REUSE, Knip, license, lint, build, format, tests for core / extra / CLI), then publishes all three packages to [GitHub Packages](https://github.com/orgs/forge-sql-orm/packages) with dist-tag **`latest`** (version `{semver}-weekly.{YYYYMMDD}`). Ephemeral **`ci.*`** GPR versions are cleaned up after each weekly run. **Official semver releases stay on [npmjs.com](https://www.npmjs.com/package/forge-sql-orm)** — see [Installing from GitHub Packages (weekly `latest`)](README.md#installing-from-github-packages-weekly-latest) in the README. - -📦 Dependency Updates - -Updated npm dependencies to their latest versions to ensure improved compatibility, security, and overall performance. - -## [2.1.29] - 2026-05-21 - -🚀 What's New - -⬆️ TypeScript 6 & ESLint 10 Upgrade - -The toolchain jumped a full major on both fronts. The codebase and example apps were adapted so they keep building cleanly under the stricter compiler. - -- TypeScript: bumped from 5.9.3 to 6.0.3 (root + CLI). -- ESLint: now on 10.4.x with matching @typescript-eslint 8.59.4. -- Imports: restored the explicit node: prefix on async_hooks / crypto so module resolution stays predictable on TS 6. - -🧹 Cyclomatic Complexity Cleanup - -Several utilities were refactored to lower complexity flagged by Qlty while keeping behaviour identical. The result is shorter, flatter helpers that are easier to read and test. - -🛠 CI / Release Automation - -The release pipeline got a noticeable hardening pass. - -- Daily autoupdate workflow: new autoupdate.yml that runs npm-check-updates - so opened PRs actually trigger CI. -- Dependabot auto-merge: PRs get merged automatically once green. -- Pinned third-party actions to commit SHA for supply-chain safety. -- Concurrency: added concurrency settings to the Node.js workflow so duplicate runs cancel themselves on rapid pushes. -- Husky portability: pre-commit no longer uses pushd / popd — it now runs in a ( … ) subshell so /bin/sh is happy on every platform. - -📦 Dependency Updates - -Bumped runtime + dev dependencies to their latest compatible versions. - -- Peer: @forge/sql ^3.0.23 → ^3.0.24. -- Runtime: @forge/api ^7.1.4 → ^7.2.0. -- Dev: vitest 4.1.5 → 4.1.7, knip 6.11.0 → 6.14.1, @types/node 25.6.0 → 25.9.1, inquirer 13.4.2 → 13.4.3, vite 8.0.10 → 8.0.14, plus alignments across all example apps. - -## [2.1.28] - 2026-05-05 - -🚀 What’s New - -📦 Bundle Optimization & Forge Lint Fix -Moved advanced integration dependencies to optionalDependencies to optimize bundle size and resolve strict build errors in Atlassian Forge environments. - -**Optional Dependencies:** `node-sql-parser` and `@forge/events` are now marked as optional. They are no longer bundled by default unless you explicitly use the advanced features. - -## [2.1.27] - 2026-04-21 - -🚀 **What’s New** - -### 🧬 Binary & UUID Custom Types Support - -Introducing a set of custom types for compact binary storage and optimized UUID handling in Atlassian Forge. - -- **uuidBinary**: Store UUID primary keys in a compact `VARBINARY(16)` form. It automatically handles `UUID_TO_BIN` on writes and returns clean UUID strings on reads. -- **forgeBLOB & Friends**: New types for binary payloads: `forgeBLOB`, `forgeTinyBLOB`, `forgeMediumBLOB`, `forgeBinary`, and `forgeVarBinary`. - -### 🤖 New AI Semantic Search Examples - -Added two new real-world example projects demonstrating different architectural approaches for AI in Forge: - -- [Frontend Embeddings (Custom UI)](https://github.com/forge-sql-orm/forge-sql-orm/tree/master/examples/forge-sql-orm-example-ai): Computes embeddings directly in the browser. Forge SQL is used to store `document` + `embedding` and perform vector similarity search. -- [Backend Embeddings (Forge Resolvers)](https://github.com/forge-sql-orm/forge-sql-orm/tree/master/examples/forge-sql-orm-example-backend-ai): Computes embeddings server-side using the `ai-lib` sidecar. The UI only sends raw text, keeping the logic entirely on the backend. - -Article: [AI Magic in Atlassian Forge: Local Semantic Search with Forge SQL](https://community.developer.atlassian.com/t/ai-magic-in-atlassian-forge-local-semantic-search-with-forge-sql/100163) - -### 🛠️ Comprehensive TiDB SQL Function Helpers - -Added a massive collection of ready-to-use SQL helper modules. These helpers return Drizzle `sql` fragments, making it easy to use TiDB-specific functions inside your query builders: - -- **String & Numeric**: `concat`, `substring`, `trim`, `round`, `trigonometry`, and more. -- **JSON & Date**: Specialized helpers for JSON mutation/validation and complex `DATE_ADD`/`DATE_SUB` calculations. -- **Advanced**: Bitwise operators, Encryption/Hashing (`AES`, `SHA`, `MD5`), and Window functions (`rowNumber`, `rank`, `lag`, `lead`). - -### 🛡️ Parameterized Vector Inputs (Security Fix) - -Improved the security and reliability of vector operations in `VectorTiDB` helpers. - -- **Placeholder Support**: Inputs for `VEC_FROM_TEXT` are now properly **parameterized** using placeholders (`?`) instead of being inlined as raw strings. -- **Injection Prevention**: This change eliminates potential SQL injection risks when handling vector strings and ensures more predictable query execution. - -### 📦 Dependency Updates - -Updated npm dependencies to their latest versions to ensure improved compatibility, security, and overall performance. - -## [2.1.26] - 2026-04-08 - -🚀 What’s New - -🔢 TiDB VECTOR Type Support for Forge SQL -Forge SQL ORM now supports the [TiDB VECTOR](https://docs.pingcap.com/ai/vector-search-data-types/) data type and vector SQL helpers. - -This means Forge SQL can now be used for [vector search](https://docs.pingcap.com/ai/vector-search-overview/) workloads on top of TiDB vector capabilities. - -Typical use cases include: -• semantic search -• retrieval-augmented generation (RAG) -• recommendation scenarios -• storing embeddings directly in Forge SQL and querying them with vector distance functions - -This release adds the foundation for AI-oriented SQL workflows while keeping relational data and vector embeddings in the same database. - -📚 New Official-Style Vector Example -Added a new example project: -[forge-sql-orm-example-vector](https://github.com/forge-sql-orm/forge-sql-orm/tree/master/examples/forge-sql-orm-example-vector) - -This example follows the same flow as the [official TiDB SQL quickstart for vector search](https://docs.pingcap.com/ai/quickstart-via-sql/): -• create a vector table -• insert embeddings -• fetch stored rows -• run cosine-distance vector search - -The goal is to make it easier to start with vector search in Forge using a practical example that mirrors the official TiDB documentation. - -🕒 Fixed datetime Handling for Midnight Values -Fixed datetime processing for values where the time part is 00:00:00. - -Midnight values are now handled correctly. - -📦 Dependency Updates - -Updated npm dependencies to their latest versions to ensure improved compatibility, security, and overall performance. - -## [2.1.25] - 2026-03-12 - -## 🚀 What’s New - -### ⚡ Optimized Global Caching with Forge KVS - -- **Native KVS TTL Support:** The global cache system now leverages the native Forge KVS TTL feature (`{ ttl: { unit: "SECONDS", value: number } }`) to mark entries as expired automatically. -- **Batch Deletion (`kvs.batchDelete`):** The deletion of outdated or evicted cache records in KVS has been significantly optimized. The ORM now uses the `kvs.batchDelete` method, which greatly improves the performance of cache invalidation and scheduled cleanup operations. -- **Proactive Expiration Management:** Since Forge KVS TTL deletion is asynchronous (and can take up to 48 hours), a large cache might impact `INSERT`/`UPDATE` performance. I've updated the architecture and documentation to highlight the optional `clearCacheSchedulerTrigger` for proactive, immediate cleanup of expired entries in batches. - -### 🎓 New Atlas Camp Example Project - -- Added a new real-world example project based on the recent Atlas Camp presentation: [forge-sql-orm-example-atlascamp](https://github.com/forge-sql-orm/forge-sql-orm/tree/master/examples/forge-sql-orm-example-atlascamp). -- 📺 **Watch the presentation:** Check out the full talk and demonstration on YouTube — [Watch the video](https://www.youtube.com/watch?v=EL-kbJgk12o). - -### 📦 Dependency Updates - -- Updated npm dependencies to their latest versions to ensure improved compatibility, security, and overall performance. - -## [2.1.24] - 2026-02-04 - -## Changes - -- Added a new **UI Kit** example project. -- Updated dependencies for compatibility and security. -- Minor internal stability improvements. - -## Notes - -- No functional changes. -- Recommended for all users to stay up-to-date with the latest fixes from external libraries. - -## [2.1.23] - 2026-01-25 - -## Changes - -- Updated dependency versions to improve compatibility and security. -- Minor internal stability improvements. - -## Notes - -- No functional changes. -- Recommended for all users to stay up-to-date with the latest fixes from external libraries. - -## [2.1.22] - 2026-01-11 - -**Organization Move & Infrastructure Updates** - -This release consolidates the repository into a dedicated GitHub Organization and updates the CI/CD tooling. - -#### 🚀 What’s New - -**📦 Repository Moved to Organization** -The project is now hosted under the `forge-sql-orm` organization. Old URLs will automatically redirect to the new location. - -- **New URL:** `https://github.com/forge-sql-orm/forge-sql-orm` -- **Recommended:** Update your local remote to match the new origin: - -```bash -git remote set-url origin https://github.com/forge-sql-orm/forge-sql-orm.git -``` - -**🛠 CI/CD & Tooling Updates** - -- **SonarCloud Integration:** Replaced Coveralls with **SonarCloud** for static analysis and security scanning. -- **Husky & Knip:** Added validation via pre-commit hooks. Commits are now checked locally for unused dependencies (`knip`), type safety, and linting rules. -- **Test Coverage:** Vitest coverage thresholds (>80%) are now enforced in the pipeline. - -**📄 Repository Standards** -Added standard documentation files to define project processes: - -- **Security:** Added `SECURITY.md` with disclosure guidelines. -- **Contributing:** Added `CONTRIBUTING.md` with setup instructions. -- **Code of Conduct:** Added `CODE_OF_CONDUCT.md`. -- **Templates:** Added structured Issue templates (including `manifest.yaml` fields) and a Pull Request template. - -## [2.1.21] - 2025-12-30 - -🚀 What’s New - -🛡️ Safer Development WebTriggers. -Development WebTriggers now strictly verify the environment and will not run in Production. Note: Please remember to remove these triggers from your production manifest. - -Available Developer WebTriggers: - -- **fetchSchemaWebTrigger**. Generates a DDL script of the current Forge-SQL database, allowing schema export to any MySQL-compatible DB for debugging. -- **dropSchemaMigrations**. Performs a complete cleanup by dropping all tables and sequences. -- **dropTableSchemaMigrations**. Drops all tables while preserving sequences. - -✨ Updated Examples • All examples have been updated to align with RoA eligibility. • Development triggers in examples are now disabled by default. - -🐛 CLI Bug Fixes • Fixed various bugs in forge-sql-orm-cli to improve stability. - -🤖 Improved Rovo Integration - -- Added support for single quotes (') in context variables. -- Ensures correct syntax handling when wrapping variables for AI context. - -📦 Dependency Updates • Dependencies updated for better stability. - -## [2.1.18] - 2025-12-21 - -✨ What’s New / Updated - -🟢 Node.js 24 Examples -• All examples have been updated to node24.x -• Aligns sample code with the latest Forge runtime - -🛠 forge-sql-orm-cli: migration:create -• Migration generation no longer relies on drizzle-orm-cli -• Table metadata is now fetched directly from the database (SHOW TABLES) -• More predictable and reliable migration creation - -📦 Dependency Updates -• Project dependencies have been updated -• Improves compatibility, stability, and security - -## [2.1.17] - 2025-12-17 - -✨ What’s New - -✅ Node.js 24 Support -• Full compatibility with Node.js 24 -• No breaking changes for existing Node 20/22 users -• Ready for upcoming Forge runtime updates - -⚡ Non-Blocking Query Degradation Analysis -• Query analysis now runs asynchronously -• Resolver responses are not blocked by performance diagnostics -• Uses Forge event queue + consumer model - -🔁 Automatic Fallback -• If async queue push fails or times out, analysis falls back to synchronous execution -• Guarantees analysis is never skipped - -🔗 Log Correlation with Job IDs -• Resolver and consumer logs include a shared Job ID -• Makes tracing async analysis straightforward in production logs - -🎯 Why It Matters -• Faster resolvers in production -• Safer performance diagnostics -• Scales observability without impacting user experience - -## [2.1.16] - 2025-12-07 - -🔧 Improved Migration Engine & CLI Stability - -This release focuses on making schema evolution more predictable and strengthening the CLI, especially around complex Drizzle-based diff generation and safe NOT NULL transitions. - -✨ What’s New - -1. Refined forge-sql-orm-cli Behavior - -1.1 Removed Dynamic Imports During Diff Generation -The CLI no longer relies on dynamic imports when resolving schema diffs between the reference database and Drizzle models. - -1.2 Safe NOT NULL Field Introduction (3-Step Migration) -When adding a new field that is NOT NULL in the reference schema, the CLI now generates a deterministic 3-migration sequence: -• Migration 1 — create the field as nullable -• Migration 2 — populate the field with a default value (if the default is not defined in schema, it must be provided manually) -• Migration 3 — convert the field to NOT NULL - -This avoids runtime failures and ensures smooth transitions in production schemas. - -1.3 Converting Nullable → NOT NULL (2-Step Migration) -When updating an existing column from nullable to not null, the CLI now generates: -• Migration 1 —update all existing rows with a default value (if the default is not defined in the schema, it must be provided manually) where the field is NULL -• Migration 2 — apply the NOT NULL constraint - -This prevents TiDB errors and enforces predictable schema tightening. - -⸻ - -2. Improved Table Extraction Logic (Regex as Fallback) - -The mechanism for extracting table names from SQL queries has been redesigned: -• The new parser avoids regex entirely for the primary extraction logic -• Regex is used only as a fallback for unusual or nested SQL structures - -This improvement is essential for the caching layer: -by reliably detecting which tables a query touches, the ORM can precisely determine which cache entries should be invalidated — without over-invalidating or missing dependencies. - -## [2.1.15] - 2025-11-29 - -🔍 Enhanced Observability Layer - -This release introduces a fully updated SQL observability system with deterministic diagnostics, safer failure analysis, and improved tooling for resolver-level profiling. - -✨ What’s New - -1. Deterministic TopSlowest Mode (New Default) - -The default mode no longer depends on CLUSTER_STATEMENTS_SUMMARY. -• Logs exact SQL digests executed inside a resolver -• Prints slowest queries with optional EXPLAIN ANALYZE -• Stable diagnostics for long-running workflows - -``` -{ - topQueries: 2, - showSlowestPlans: true, -} -``` - -2. Improved SummaryTable Mode (Optional) - -``` -summaryTableWindowTime: 15000 // 15s -``` - -Now treated as an advanced diagnostic mode. -Automatically falls back to TopSlowest if resolver execution exceeds the window. - -3. Updated Diagnostics API - -```js -executeWithMetadata(fn, onStats, { - mode: "TopSlowest" | "SummaryTable", - summaryTableWindowTime: 15000, - topQueries: 1, - showSlowestPlans: true, -}); -``` - -Gives full control over plan printing, thresholds, and sampling. - -4. Post-Mortem Analysis for Timeout & OOM - -On Timeout or OOM errors, forge-sql-orm now performs an immediate post-mortem lookup: -• Captures the actual failing SQL -• Captures the real TiDB execution plan (no re-execution) -• Fully Forge-safe (metadata only) - -Useful for diagnosing severe SQL failures without triggering them again. - -5. Deprecated Method Temporarily Restored - -The deprecated trigger: - -``` -topSlowestStatementLastHourTrigger(...) -``` - -was restored for backward compatibility. -• Still marked `@deprecated` -• Internally wraps slowQuerySchedulerTrigger -• Will be removed in a future version -• Not equivalent to the new executeWithMetadata system -• Provided only to support existing apps during migration - -Developers are encouraged to migrate to the new observability system: -• TopSlowest mode (default) for deterministic profiling -• SummaryTable mode for advanced use cases -• Automatic fallbacks and reliable post-mortem diagnostics - -## [2.1.14] - 2025-11-21 - -🔒 **Rovo Integration - Secure Natural-Language Analytics** - -Forge SQL ORM now includes Rovo — a secure pattern for enabling AI-powered natural-language analytics with comprehensive security validations. - -- **Secure Dynamic SQL Execution** - - • Enables safe execution of user-generated SQL queries for AI analytics features. - - • Multiple layers of security validations prevent SQL injection and unauthorized data access. - - • AST-based SQL normalization ensures queries are properly parsed and validated before execution. - - • Example: - - const rovo = forgeSQL.rovo(); - const settings = await rovo - .rovoSettingBuilder(usersTable, accountId) - .useRLS() - .addRlsColumn(usersTable.id) - .addRlsWherePart((alias) => `${alias}.id = '${accountId}'`) - .finish() - .build(); - - const result = await rovo.dynamicIsolatedQuery( - "SELECT id, name FROM users WHERE status = 'active'", - settings - ); - - **Comprehensive Security Validations** - - • **Query Type Restriction**: Only SELECT queries are allowed — blocks INSERT, UPDATE, DELETE, and other data modification operations. - - • **Single Table Isolation**: Queries are restricted to a single table to prevent cross-table data access. - - • **JOIN Detection**: Automatically detects and blocks JOIN operations using EXPLAIN analysis. - - • **Subquery Blocking**: Prevents scalar subqueries in SELECT columns that could access other tables. - - • **Window Function Blocking**: Blocks window functions (e.g., `COUNT(*) OVER()`) for security. - - • **Execution Plan Validation**: Verifies that only the expected table is accessed in the query execution plan. - - • **Post-Execution Validation**: Ensures all result fields come from the correct table and required security fields are present. - -- **Row-Level Security (RLS) Support** - - • Built-in RLS support for data isolation based on user context. - - • Conditional RLS activation based on user roles or permissions. - - • Type-safe column references using Drizzle ORM table objects. - - • Automatic query wrapping with RLS filtering when enabled. - - • Example: - - const settings = await rovo - .rovoSettingBuilder(securityNotesTable, accountId) - .useRLS() - .addRlsCondition(async () => { - const userService = getUserService(); - return !(await userService.isAdmin()); // Only apply RLS for non-admin users - }) - .addRlsColumn(securityNotesTable.createdBy) - .addRlsWherePart((alias) => `${alias}.createdBy = '${accountId}'`) - .finish() - .build(); - - **Type-Safe Configuration** - - • Uses Drizzle ORM table objects for type-safe column references. - - • Supports both raw table names and Drizzle table objects. - - • Context parameter substitution for dynamic query values. - - • Optional query logging for debugging (`logRawSqlQuery` option). - -⚡ Designed to enable secure AI-powered analytics features where users can query data using natural language, with comprehensive security validations built directly into Forge SQL ORM. - -📖 **Real-World Example**: See [Forge-Secure-Notes-for-Jira](https://github.com/vzakharchenko/Forge-Secure-Notes-for-Jira) for a complete implementation of Rovo AI agent with secure natural-language analytics. - -## [2.1.13] - 2025-11-20 - -## What's Changed - -- Bump @vitest/coverage-v8 from 4.0.7 to 4.0.8 by @dependabot[bot] in https://github.com/vzakharchenko/forge-sql-orm/pull/1028 - -**Full Changelog**: https://github.com/vzakharchenko/forge-sql-orm/compare/2.1.12...2.1.13 - -## [2.1.12] - 2025-10-31 - -🚀 **What’s New** - -✨ **Enhanced Observability Layer** -Forge SQL ORM now provides end-to-end observability — from resolver-level profiling to automatic diagnostics and scheduled slow-query monitoring. - -- **Resolver-Level Observability** - • Added built-in profiling across all SQL queries executed inside a resolver. - • Automatically aggregates `totalDbExecutionTime` and `totalResponseSize` for every invocation. - • Emits performance warnings when exceeding baseline thresholds and can print execution plans for analysis. - • Example: - - ```ts - resolver.define("fetch", async (req: Request) => { - try { - return await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(demoUsers); - const orders = await forgeSQL - .selectFrom(demoOrders) - .where(eq(demoOrders.userId, demoUsers.id)); - return { users, orders }; - }, - async (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - const threshold = 500; // ms baseline - if (totalDbExecutionTime > threshold * 1.5) { - console.warn( - `[Performance Warning fetch] Resolver exceeded DB time: ${totalDbExecutionTime} ms`, - ); - await printQueriesWithPlan(); // log or capture diagnostics - } else if (totalDbExecutionTime > threshold) { - console.debug(`[Performance Debug fetch] High DB time: ${totalDbExecutionTime} ms`); - } - }, - ); - } catch (e) { - const error = e?.cause?.debug?.sqlMessage ?? e?.cause; - console.error(error, e); - throw error; - } - }); - ``` - -- **Automatic Error Analysis** - • Automatically detects and diagnoses queries that fail with - `“Your query has been cancelled due to exceeding the allowed memory limit for a single SQL query.”` - or - `“The provided query took more than 5000 milliseconds to execute.”` - • Retrieves execution plans for failed queries directly from TiDB metadata tables for instant analysis. - • Works entirely within Forge SQL ORM — no external tools required. - -- **Slow Query Scheduler Trigger** - • Introduces an hourly scheduler trigger that automatically collects and logs slow queries. - • Leverages `INFORMATION_SCHEMA.CLUSTER_SLOW_QUERY` to track execution time, memory usage, and query plans. - • Example: - - ```ts - import ForgeSQL, { slowQuerySchedulerTrigger } from "forge-sql-orm"; - - const forgeSQL = new ForgeSQL(); - - export const slowQueryTrigger = () => - slowQuerySchedulerTrigger(forgeSQL, { hours: 1, timeout: 3000 }); - ``` - - Configure in `manifest.yml`: - - ```yaml - scheduledTrigger: - - key: slow-query-trigger - function: slowQueryTrigger - interval: hour - function: - - key: slowQueryTrigger - handler: index.slowQueryTrigger - ``` - -⚡ Designed to provide full resolver-level profiling, automatic failure diagnostics, and periodic slow-query monitoring — all built directly into Forge SQL ORM. - -## [2.1.9] - 2025-10-02 - -🚀 **What’s New** - -✨ **New Execution APIs** -I added three new execution helpers to make working with Forge SQL more powerful and transparent: - -- **`executeWithMetadata(query, onMetadata)`** - • Runs any SQL/ORM query and provides full execution metadata. - • Exposes `totalDbExecutionTime`, `totalResponseSize`, and raw `ForgeSQLMetadata`. - • Perfect for monitoring query performance, logging, or building custom dashboards. - • Example: - - ```ts - const result = await forgeSQL.executeWithMetadata( - () => forgeSQL.select().from(users).where(eq(users.id, 1)), - (dbTime, size, meta) => { - console.log(`DB time: ${dbTime}ms, size: ${size} bytes`, meta); - }, - ); - ``` - -- **`executeDDL(sql)`** - • Execute DDL statements like `CREATE`, `ALTER`, `DROP`, `TRUNCATE`. - • Ensures proper context handling for schema modifications in Forge SQL. - • Example: - - ```ts - await forgeSQL.executeDDL(` - CREATE TABLE users ( - id INT PRIMARY KEY AUTO_INCREMENT, - name VARCHAR(255) NOT NULL, - email VARCHAR(255) UNIQUE - ) - `); - ``` - -- **`executeDDLActions(actions)`** - • Run a series of queries wrapped in a DDL operation context. - • Useful for treating normal SQL as DDL for monitoring / tracking purposes. - • Example: - ```ts - const slowQueries = await forgeSQL.executeDDLActions(async () => { - return await forgeSQL.execute(` - SELECT * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY - WHERE AVG_LATENCY > 1000000 - `); - }); - ``` - -⚡ Designed to make query execution more transparent, schema management safer, and monitoring easier inside Forge apps. - -## [2.1.5] - 2025-09-21 - -🚀 What’s New - -✨ Memory & Latency Monitoring Trigger -I added a built-in scheduled trigger to help surface problematic queries automatically: -• topSlowestStatementLastHourTrigger(warnThresholdMs, warnMemMb?) -• Checks the slowest query or the most memory-intensive query from the last hour. -• Outputs compact JSON and writes structured warnings to the Forge Developer Console logs for easy inspection. -• Provides digest, preview of SQL text, latency (ms), memory (MB), and an execution plan snapshot. -• Skips noise (e.g., empty digest and USE/SET/SHOW statements). -• Designed for tenant-isolated Forge apps, helping stay within the Forge SQL ~16 MiB per-query limit. - -📦 [Cache Example](https://github.com/vzakharchenko/forge-sql-orm/tree/master/examples/forge-sql-orm-example-cache) Update -• Cache Example now shows advanced caching combined with topSlowestStatementLastHourTrigger. -• Demonstrates how caching + monitoring can both optimize query performance and detect high-latency or high-memory queries early. - -## [2.1.3] - 2025-09-18 - -**Full Changelog**: https://github.com/vzakharchenko/forge-sql-orm/compare/2.1.2...2.1.3 - -Changes 1. Improved logging. 2. Added validation for timestamp values. Atlassian Forge does not handle 0 timestamps correctly, which caused data in responses to shift if a table contained a zero date. - -## [2.1.2] - 2025-09-15 - -🚀 What’s New - -✨ Two-Level Query Caching - -I added a two-level caching system to improve query performance and reduce load on Forge SQL: -• L1 Local Cache (in-memory) -• Works within a single resolver invocation. -• Prevents duplicate KVS lookups and speeds up repeated queries inside the same function call. -• Automatically bypassed in Cache Context if tables are modified. -• L2 Global Cache (powered by @forge/kvs) -• Stores query results across invocations with configurable TTL. -• Supports automatic eviction on data modifications (\*AndEvictCache methods) and batch eviction with executeWithCacheContext. -• Helps keep apps within Forge SQL quotas and improves p95 latency for dashboards and reports. - -🛠 Improvements -• Unified eviction query for Cache Context (single OR-filter across affected tables). -• Date handling: -• Switched from UTC-only formatting to SQL-native date handling. -• Dates are now validated before being transformed into SQL format, preventing invalid values. -• Updated README with detailed cache diagrams and usage guidelines. - -## [2.1.0] - 2025-09-14 - -🚀 What’s New - -✨ Two-Level Query Caching - -I added a two-level caching system to improve query performance and reduce load on Forge SQL: -• L1 Local Cache (in-memory) -• Works within a single resolver invocation. -• Prevents duplicate KVS lookups and speeds up repeated queries inside the same function call. -• Automatically bypassed in Cache Context if tables are modified. -• L2 Global Cache (powered by @forge/kvs) -• Stores query results across invocations with configurable TTL. -• Supports automatic eviction on data modifications (\*AndEvictCache methods) and batch eviction with executeWithCacheContext. -• Helps keep apps within Forge SQL quotas and improves p95 latency for dashboards and reports. - -🛠 Improvements -• Unified eviction query for Cache Context (single OR-filter across affected tables). -• Date handling: -• Switched from UTC-only formatting to SQL-native date handling. -• Dates are now validated before being transformed into SQL format, preventing invalid values. -• Updated README with detailed cache diagrams and usage guidelines. - -## [2.0.30] - 2025-09-01 - -✨ Compatibility Fixes for @forge/cli ≥ 12.5.0 -• Replaced moment dependency with luxon -• Fixed errors: - -``` -Unknown module type for “./src/migration/ lazy ^\.\/migrationV.*$ namespace object -``` - -and - -``` -Unknown module type for "./node_modules/moment/locale/ sync ^\\.\\/.*$". -``` - -📦 Dependency Updates -• Updated internal dependencies to improve compatibility and security. - -## [2.0.28] - 2025-08-23 - -Changes -Updated dependency versions to improve compatibility and security. -Minor internal stability improvements. -Notes -No functional changes. -Recommended for all users to stay up-to-date with the latest fixes from external libraries. - -## [2.0.27] - 2025-08-12 - -## Changes - -- Updated dependency versions to improve compatibility and security. -- Minor internal stability improvements. -- fixed examples -- added sort to apply schema - -## Notes - -- No functional changes. -- Recommended for all users to stay up-to-date with the latest fixes from external libraries. - ---- - -## [2.0.26] - 2025-07-29 - -## Changes - -- Updated dependency versions to improve compatibility and security. -- Minor internal stability improvements. - -## Notes - -- No functional changes. -- Recommended for all users to stay up-to-date with the latest fixes from external libraries. - ---- - -## [2.0.25] - 2025-06-26 - -## Changes - -- Updated dependency versions to improve compatibility and security. -- Minor internal stability improvements. - -## Notes - -- No functional changes. -- Recommended for all users to stay up-to-date with the latest fixes from external libraries. - ---- - -## [2.0.23] - 2025-06-16 - -## Changes - -- Updated dependency versions to improve compatibility and security. -- Minor internal stability improvements. - -## Notes - -- No functional changes. -- Recommended for all users to stay up-to-date with the latest fixes from external libraries. - ---- - -## [2.0.22] - 2025-05-30 - -# forge-sql-orm v2.0.22 - -## Changes - -- Updated dependency versions to improve compatibility and security. -- Minor internal stability improvements. - -## Notes - -- No functional changes. -- Recommended for all users to stay up-to-date with the latest fixes from external libraries. - ---- - -## [2.0.21] - 2025-05-17 - -# forge-sql-orm v2.0.21 - -## 🚀 What's New - -### ✨ Features - -- **`nextVal` helper for SEQUENCE-based inserts** - Enables safe and convenient use of SQL `SEQUENCE` values when inserting rows. - - ```ts - import { nextVal } from "forge-sql-orm"; - - const user = { - id: nextVal("user_id_seq"), - name: "user test", - organization_id: 1, - }; - - const id = await forgeSQL.modify().insert(appUser, [user]); - ``` - -- **`formatLimitOffset` utility** - Helps safely format numeric `LIMIT` and `OFFSET` values in raw SQL queries. - - ```ts - import { formatLimitOffset } from "forge-sql-orm"; - - const result = await forgeSQL - .select() - .from(orderItem) - .orderBy(asc(orderItem.createdAt)) - .limit(formatLimitOffset(10)) - .offset(formatLimitOffset(350000)); - - // Generates: - // SELECT * FROM order_item - // ORDER BY created_at ASC - // LIMIT 10 - // OFFSET 350000 - ``` - -### 🧪 Examples - -- **`forge-sql-orm-example-checklist`** - Demonstrates the use of optimistic locking in Forge SQL ORM. This example implements a checklist feature that prevents data loss during concurrent updates in Jira issues. - -- **`forge-sql-orm-example-org-tracker`** - A practical organization tracking system built with Forge SQL ORM. It showcases search, filtering, and real-time user-organization mapping. - -### 📦 Dependency Updates - -- Updated internal dependencies to improve compatibility and security. - -## [2.0.20] - 2025-04-29 - -# forge-sql-orm v2.0.20 - -## Changes - -- Updated dependency versions to improve compatibility and security. -- Minor internal stability improvements. - -## Notes - -- No functional changes. -- Recommended for all users to stay up-to-date with the latest fixes from external libraries. - ---- - -## [2.0.19] - 2025-04-11 - -### ✨ New: Query Analysis API - -A powerful new API is now available under `forgeSqlOrm.analyze()` — enabling in-depth query diagnostics and performance insights directly from your Forge app. - -**Highlights:** - -- `explain()` / `explainAnalyze()` — for Drizzle queries -- `explainRaw()` / `explainAnalyzeRaw()` — for raw SQL queries -- `analyzeSlowQueries()` — access to slow query logs with query plans -- `analyzeQueriesHistory()` — query history per table (Drizzle objects) with query plans -- `analyzeQueriesHistoryRaw()` — query history per table (string names) with query plans - -Useful for performance tuning in TiDB, MySQL, and other compatible systems. - ---- - -### 🛠 Deprecations - -- `forgeSqlOrm.crud()` has been **deprecated** and will be removed in a future release. - Please migrate to `forgeSqlOrm.modify()` — the API remains the same, just with an updated name that better reflects its intent. - -#### Migration Example: - -```ts -// Before: -const query = forgeSqlOrm.crud().select().from(...) - -// After: -const query = forgeSqlOrm.modify().select().from(...) -``` - ---- - -### 🧪 Code Quality & Fixes - -- Integrated static code analyzers for improved consistency and safety -- Expanded test coverage across core components -- Minor bug fixes and internal stability improvements - -## [2.0.18] - 2025-04-08 - -✨ New Features -SQL Hints Support: You can now add SQL hints to SELECT, INSERT, UPDATE, and DELETE queries for fine-tuned query optimization and execution behavior. - -🐞 Bug Fixes -Fixed issues related to selectAlias and selectAliasDistinct that could cause incorrect alias resolution or unexpected results in some edge cases. - -## [2.0.16] - 2025-04-06 - -### ✨ What's New - -#### 1. Improved Unique Aliases in `select` - -Enhanced how column aliases are generated in `select` when duplicate field names appear across different groups. Now, each field receives a unique alias to avoid collisions in the final query result. - -**Example:** - -```ts -forgeSqlOrm - .select({ - group1: { name: user.name }, - group2: { name: user.name }, - }) - .from(users); -``` - -Previously, this could result in naming conflicts. With this update, each `name` field is uniquely aliased under the hood. - -#### 2. Smarter Group Null Handling in Response - -A new post-processing step ensures that when all values in a selected group are `null` (e.g., due to a `leftJoin` with no match), the entire group is returned as `null` instead of a group of `null` values. - -**Example:** - -```ts -forgeSqlOrm - .select({ - group1: { name: user.name }, - group2: { name: userStatus.name }, - }) - .from(users) - .leftJoin(userStatus, eq(userStatus.id, user.id)); -``` - -**Before (undesired):** - -```ts -{ - group2: { - name: null; - } -} -``` - -**Now (correct):** - -```ts -{ - group2: null; -} -``` - -This leads to cleaner and more intuitive data structures when dealing with optional or missing related records. - -## [2.0.13] - 2025-04-05 - -### 📦 CLI moved to a separate package - -The CLI has been extracted from the main `forge-sql-orm` package into its own dedicated package: [`[forge-sql-orm-cli](https://www.npmjs.com/package/forge-sql-orm-cli)`](https://www.npmjs.com/package/forge-sql-orm-cli). - -#### ❗ What’s changed? - -Previously, you could run the CLI directly via: - -```bash -npx forge-sql-orm --help -``` - -Now, you need to install and use the new CLI package: - -```bash -npm install forge-sql-orm-cli --save-dev -npx forge-sql-orm-cli --help -``` - -#### 💡 Why this change? - -In the previous setup, the CLI was bundled with the main package, meaning all CLI-related dependencies were included — even if you were only using the core library. Since `devDependencies` are not available during CLI execution, many of them had to be listed under regular `dependencies`, increasing the size of the package unnecessarily. - -By turning the CLI into a standalone app, all CLI-specific dependencies now live in `forge-sql-orm-cli`, keeping the main `forge-sql-orm` package lightweight and focused solely on the ORM functionality. - -#### 🔧 How to upgrade - -If you're using the CLI, update your setup as follows: - -1. **Install the new CLI package**: - - ```bash - npm install forge-sql-orm-cli --save-dev - ``` - -2. **Update your `package.json` scripts** to use the new CLI command: - - ```json - "scripts": { - "models:create": "forge-sql-orm-cli generate:model --output src/entities", - "migration:create": "forge-sql-orm-cli migrations:create", - "migration:update": "forge-sql-orm-cli migrations:update", - "migration:drop": "forge-sql-orm-cli migrations:drop" - } - ``` - -3. **Update any references in your documentation or tooling** from: - - ```bash - npx forge-sql-orm ... - ``` - - to: - - ```bash - npx forge-sql-orm-cli ... - ``` - -No other changes are needed — all CLI functionality remains the same, just now under a separate, focused package. - -## [2.0.11] - 2025-04-03 - -## What's Changed - -- Bump the npm_and_yarn group across 4 directories with 2 updates by @dependabot in https://github.com/vzakharchenko/forge-sql-orm/pull/13 - -**Full Changelog**: https://github.com/vzakharchenko/forge-sql-orm/compare/2.0.10...2.0.11 - -## [2.0.10] - 2025-03-29 - -## [2.0.8] - 2025-03-28 - -## [2.0.7] - 2025-03-27 - -## [2.0.5] - 2025-03-27 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 1c7804d8e..000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,128 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -vaszakharchenko@gmail.com. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 4326e1573..000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,168 +0,0 @@ -# Contributing to Forge SQL ORM - -First off, thanks for taking the time to contribute! 🎉 - -The following is a set of guidelines for contributing to Forge SQL ORM. - -For product scope, platform limits, and documentation obligations, see [REQUIREMENTS.md](REQUIREMENTS.md). - -## Repository layout - -This monorepo publishes three npm packages: - -| Package | Directory | When you change it | -| ---------------------- | ---------------------- | --------------------------------------------------------------------------------------------- | -| `forge-sql-orm` (core) | `src/`, `__tests__/` | Run checks from the repository root (see [Pre-commit Requirements](#pre-commit-requirements)) | -| `forge-sql-orm-extra` | `forge-sql-orm-extra/` | Also run `npm ci`, `npm run build`, and `npm run test:coverage` inside `forge-sql-orm-extra/` | -| `forge-sql-orm-cli` | `forge-sql-orm-cli/` | Also run `npm ci`, `npm run build`, and `npm run test:coverage` inside `forge-sql-orm-cli/` | - -CI runs the full quality gate for all three packages on every pull request to `master`. See [REQUIREMENTS.md §2.4](REQUIREMENTS.md#24-modular-package-architecture) for how features are split between core and extra. - -## Weekly GitHub Packages (maintainers) - -In addition to PR CI, [`.github/workflows/weekly-gpr.yml`](.github/workflows/weekly-gpr.yml) publishes a **weekly snapshot** of `master` to GitHub Packages (`dist-tag: latest`) after the same quality checks (Knip, lint, build, tests). Ephemeral `ci.*` GPR versions are bulk-deleted at the end of that job. - -Consumer install instructions (`.npmrc`, npm aliases): [README — Installing from GitHub Packages (weekly `latest`)](README.md#installing-from-github-packages-weekly-latest). You do not need to run the weekly workflow locally when contributing — merge to `master` and wait for the schedule, or trigger **Weekly GitHub Packages (latest)** manually from Actions if needed. - -## Code of Conduct - -This project and everyone participating in it is governed by the [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. - -## Development Setup & Strict Checks - -This project uses **Husky** to enforce high code quality standards via git hooks. - -```bash -# Clone the repository -git clone https://github.com/forge-sql-orm/forge-sql-orm.git - -# Install dependencies (this automatically sets up Husky) -npm install -``` - -## Pre-commit Requirements - -Important: Simply running npm run test is NOT sufficient. Our pre-commit hook is strict and performs a full health check. - -Before committing, ensure your code passes the following suite: - -```bash -# 1. Format code (Essential!) -npm run format - -# 2. Type-checking & Build -npm run build - -# 3. Dependency validation (Knip) -npm run knip - -# 4. Linter -npm run lint - -# 5. Tests with Coverage -npm run test -``` - -If you changed **`forge-sql-orm-extra`** or **`forge-sql-orm-cli`**, run the same checks in that package directory before opening a PR: - -```bash -# forge-sql-orm-extra -cd forge-sql-orm-extra -npm ci -npm run knip -npm run build -npm run test:coverage - -# forge-sql-orm-cli -cd forge-sql-orm-cli -npm ci -npm run knip -npm run build -npm run test:coverage -``` - -## Code Coverage Requirements - -This project enforces strict code coverage thresholds via Vitest **in each package** (root, `forge-sql-orm-extra/`, `forge-sql-orm-cli/`). If your PR lowers the coverage below these limits, the build will fail: - -- **Statements: > 80%** -- **Branches: > 80%** -- **Functions: > 80%** -- **Lines: > 80%** - -Please ensure that any new logic includes corresponding unit tests. - -## How Can I Contribute? - -**Reporting Bugs & Suggestions** - -- Use a clear title and describe the problem or suggestion in detail. -- Provide reproduction steps (code snippets or repo links are highly appreciated). -- Explain expected vs. actual behavior. - -**Pull Requests** - -1. Fork the repo and create your branch from master. -2. Make sure you have run the Pre-commit Requirements listed above. -3. Ensure strict coverage thresholds are met. -4. Issue that pull request! - -## Pull Request Review Policy - -Forge SQL ORM is a solo-maintained open-source project. To keep review discipline strong without a team of human reviewers, every PR goes through an **automated review pipeline** whose comments are treated as binding review items. - -**Review tools that run on every PR to `master`:** - -| Tool | Role | -| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| [CodeRabbit](https://www.coderabbit.ai/) | AI line-level review (correctness, style, likely defects). Operates under the **free tier** — rate-limited but covers every PR. | -| [Codacy AI Reviewer](https://www.codacy.com/) | AI comments on security, duplication, and best practices. | -| [SonarCloud Quality Gate](https://sonarcloud.io/) | Coverage, code smells, vulnerabilities, security hotspots. Blocks merge if the Quality Gate fails. | -| [Qlty](https://qlty.sh/) | Maintainability score, coverage tracking. | -| [DeepScan](https://deepscan.io/), [Snyk](https://snyk.io/) | Static defect and vulnerability analysis. | -| [REUSE / SPDX](https://reuse.software/) | License-header compliance, enforced via `fsfe/reuse-action` in CI. | - -**Comment resolution is mandatory:** - -- Every comment posted by any tool above is a **blocking review item**, regardless of severity. -- A **human maintainer must explicitly resolve each comment** — by applying a fix, replying with reasoning that the comment is wrong/inapplicable and marking it resolved, or filing a follow-up issue if it is out of scope. -- Auto-merge is enabled **only after** the pipeline passes _and_ every outstanding comment has been resolved by a human. -- PRs with unresolved bot comments will not be merged. - -This replaces, by design, the need for a second human reviewer on a solo-maintained project. See [REQUIREMENTS.md §8.2](REQUIREMENTS.md#82-code-review-and-comment-resolution) for the corresponding requirements-level definition. - -## Example Apps & Forge Deployment Flow - -The CI pipeline (`.github/workflows/node.js.yml`, job `examples`) builds **and deploys** every example app to Atlassian Forge. The target environment depends on the trigger: - -- **Push to `master`** → the `production` Forge environment. -- **Pull request (or manual `development` dispatch)** → a **per-contributor Forge environment**, named after your sanitized GitHub username (`github.actor` with everything except letters/digits stripped, e.g. `Jane-Doe` → `JaneDoe`). Each example is then installed on `FORGE_HOSTNAME` for that environment. - -The install step is idempotent: it runs `forge install list --json`, checks whether the app already exists on `FORGE_HOSTNAME` in that environment, and either `--upgrade`s it or performs a fresh install. - -All deployments run under the **maintainer's** Forge credentials (`FORGE_EMAIL` / `FORGE_API_TOKEN` repository secrets) against the maintainer's apps and `FORGE_HOSTNAME` site — **you do not need any Forge account, site access, or Developer Console membership to contribute.** The per-contributor environment naming only namespaces the dev deploys so concurrent PRs don't collide. - -## Logging - -Diagnostic logging goes through the platform-native `console.*` API — Atlassian Forge captures `console` output from resolvers and triggers, and we deliberately avoid third-party logging frameworks to keep dependencies lean (see [REQUIREMENTS.md NFR-11](REQUIREMENTS.md#4-non-functional-requirements)). - -Because of this, `no-console` is configured as an **ESLint error**. You cannot just drop in a `console.log`: - -- Each intentional log must be opted in per line with `// eslint-disable-next-line no-console`. -- Think before adding one — keep it intentional and minimal, and gate noisy output behind a flag where appropriate (e.g. `logRawSqlQuery`): - -```ts -if (newOptions.logRawSqlQuery) { - // eslint-disable-next-line no-console - console.debug("Initializing ForgeSQLORM..."); -} -``` - -The explicit opt-in is intentional: it keeps every log line visible in review rather than letting console output accumulate accidentally. - -## Styleguides - -- Use the present tense ("Add feature" not "Added feature"). -- Reference issues and pull requests liberally. - -# Thank you for your contribution! diff --git a/LICENSE b/LICENSE deleted file mode 100644 index a63d6d4fe..000000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Vasiliy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt deleted file mode 100644 index 32e53e7a7..000000000 --- a/LICENSES/MIT.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index e326d3729..000000000 --- a/README.md +++ /dev/null @@ -1,2493 +0,0 @@ -# Forge SQL ORM - -[![npm version (core)](https://img.shields.io/npm/v/forge-sql-orm?label=core)](https://www.npmjs.com/package/forge-sql-orm) -[![npm downloads (core)](https://img.shields.io/npm/dm/forge-sql-orm?label=core%20downloads)](https://www.npmjs.com/package/forge-sql-orm) -[![npm version (extra)](https://img.shields.io/npm/v/forge-sql-orm-extra?label=extra)](https://www.npmjs.com/package/forge-sql-orm-extra) -[![npm downloads (extra)](https://img.shields.io/npm/dm/forge-sql-orm-extra?label=extra%20downloads)](https://www.npmjs.com/package/forge-sql-orm-extra) -[![npm version (CLI)](https://img.shields.io/npm/v/forge-sql-orm-cli?label=cli)](https://www.npmjs.com/package/forge-sql-orm-cli) -[![npm downloads (CLI)](https://img.shields.io/npm/dm/forge-sql-orm-cli?label=cli%20downloads)](https://www.npmjs.com/package/forge-sql-orm-cli) - -[![forge-sql-orm CI](https://github.com/forge-sql-orm/forge-sql-orm/actions/workflows/node.js.yml/badge.svg)](https://github.com/forge-sql-orm/forge-sql-orm/actions/workflows/node.js.yml) - -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=forge-sql-orm_forge-sql-orm&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=forge-sql-orm_forge-sql-orm) -[![Code Coverage](https://qlty.sh/gh/forge-sql-orm/projects/forge-sql-orm/coverage.svg)](https://qlty.sh/gh/forge-sql-orm/projects/forge-sql-orm) -[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=forge-sql-orm_forge-sql-orm&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=forge-sql-orm_forge-sql-orm) -[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=forge-sql-orm_forge-sql-orm&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=forge-sql-orm_forge-sql-orm) -[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=forge-sql-orm_forge-sql-orm&metric=bugs)](https://sonarcloud.io/summary/new_code?id=forge-sql-orm_forge-sql-orm) -[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=forge-sql-orm_forge-sql-orm&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=forge-sql-orm_forge-sql-orm) -[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=forge-sql-orm_forge-sql-orm&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=forge-sql-orm_forge-sql-orm) - -[![DeepScan grade](https://deepscan.io/api/teams/26652/projects/30920/branches/997203/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=26652&pid=30920&bid=997203) -[![Codacy Badge](https://app.codacy.com/project/badge/Grade/5a850fba74734c658a5f88822cff4fd0)](https://app.codacy.com/gh/forge-sql-orm/forge-sql-orm/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) -[![Snyk Vulnerabilities](https://snyk.io/test/github/forge-sql-orm/forge-sql-orm/badge.svg)](https://snyk.io/test/github/forge-sql-orm/forge-sql-orm) -[![Maintainability](https://qlty.sh/gh/forge-sql-orm/projects/forge-sql-orm/maintainability.svg)](https://qlty.sh/gh/forge-sql-orm/projects/forge-sql-orm) -[![Socket Badge](https://badge.socket.dev/npm/package/forge-sql-orm/latest)](https://badge.socket.dev/npm/package/forge-sql-orm/latest) - -[![LoC (full)](https://raw.githubusercontent.com/forge-sql-orm/forge-sql-orm/badges/loc-full.svg)](https://github.com/forge-sql-orm/forge-sql-orm/actions/workflows/badge.yml) -[![LoC (src)](https://raw.githubusercontent.com/forge-sql-orm/forge-sql-orm/badges/loc-src.svg)](https://github.com/forge-sql-orm/forge-sql-orm/actions/workflows/badge.yml) - -[![License](https://img.shields.io/github/license/forge-sql-orm/forge-sql-orm)](https://github.com/forge-sql-orm/forge-sql-orm/blob/master/LICENSE) -[![REUSE status](https://api.reuse.software/badge/github.com/forge-sql-orm/forge-sql-orm)](https://api.reuse.software/info/github.com/forge-sql-orm/forge-sql-orm) -[![License compliance (core)](https://raw.githubusercontent.com/forge-sql-orm/forge-sql-orm/badges/license-compliance.svg)](https://github.com/forge-sql-orm/forge-sql-orm/actions/workflows/badge.yml) -[![License compliance (extra)](https://raw.githubusercontent.com/forge-sql-orm/forge-sql-orm/badges/extra-license-compliance.svg)](https://github.com/forge-sql-orm/forge-sql-orm/actions/workflows/badge.yml) - -**Forge SQL ORM** is a TypeScript ORM for [Atlassian Forge](https://developer.atlassian.com/platform/forge/) apps that use [@forge/sql](https://developer.atlassian.com/platform/forge/storage-reference/sql-tutorial/) — Atlassian’s managed SQL storage (TiDB-compatible) inside Forge resolvers, triggers, and scheduled jobs. - -Instead of calling `@forge/sql` with hand-written SQL strings, you define schemas and queries with [Drizzle ORM](https://orm.drizzle.team) and get full type safety, migrations, and Forge-specific helpers out of the box. The library provides a **custom Drizzle driver** for `@forge/sql`, **schema migrations**, **local in-memory caching**, **optimistic locking**, **query analysis**, and TiDB-oriented types (vectors, binary columns, SQL function helpers). - -**Packages in this repository:** - -| Package | Role | -| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`forge-sql-orm`** (this README) | Core ORM — Drizzle integration, migrations, local cache, query analysis | -| [**forge-sql-orm-extra**](forge-sql-orm-extra/README.md) | Optional add-on — global query cache ([@forge/kvs](https://developer.atlassian.com/platform/forge/storage-reference/storage-api-custom-entities/)) and Rovo natural-language analytics | -| [**forge-sql-orm-cli**](forge-sql-orm-cli/README.md) | CLI — generate entities and migrations from existing MySQL/TiDB schemas | - -Start with **`forge-sql-orm`** for any Forge SQL app; add **forge-sql-orm-extra** only when you need cross-invocation caching or Rovo. - -## Key Features - -- ✅ **Custom Drizzle Driver** for direct integration with @forge/sql -- ✅ **Local Cache System (Level 1)** for in-memory query optimization within single resolver invocation scope -- ✅ **Performance Monitoring**: Query execution metrics and analysis capabilities with automatic error analysis for timeout and OOM errors, scheduled slow query monitoring with execution plans, and async query degradation analysis for non-blocking performance monitoring -- ✅ **Type-Safe Query Building**: Write SQL queries with full TypeScript support -- ✅ **Supports complex SQL queries** with joins and filtering using Drizzle ORM -- ✅ **Advanced Query Methods**: `selectFrom()`, `selectDistinctFrom()` for all-column queries with field aliasing ([`selectCacheableFrom()` / global cache](forge-sql-orm-extra/README.md) in **forge-sql-orm-extra**) -- ✅ **Query Execution with Metadata**: `executeWithMetadata()` method for capturing detailed execution metrics including database execution time, response size, and query analysis capabilities with performance monitoring. Supports two modes for query plan printing: TopSlowest mode (default) and SummaryTable mode -- ✅ **Raw SQL Execution**: `execute()`, `executeDDL()`, and `executeDDLActions()` for direct SQL (local caching; [`executeCacheable()`](forge-sql-orm-extra/README.md) in **forge-sql-orm-extra**) -- ✅ **Common Table Expressions (CTEs)**: `with()` method for complex queries with subqueries -- ✅ **Schema migration support**, allowing automatic schema evolution -- ✅ **Automatic entity generation** from MySQL/tidb databases -- ✅ **Automatic migration generation** from MySQL/tidb databases -- ✅ **Drop Migrations** Generate a migration to drop all tables and clear migrations history for subsequent schema recreation -- ✅ **Schema Fetching** Development-only web trigger to retrieve current database schema and generate SQL statements for schema recreation -- ✅ **Ready-to-use Migration Triggers** Built-in web triggers for applying migrations, dropping tables (development-only), and fetching schema (development-only) with proper error handling and security controls -- ✅ **Optimistic Locking** Ensures data consistency by preventing conflicts when multiple users update the same record -- ✅ **Query Plan Analysis**: Detailed execution plan analysis and optimization insights -- ✅ **Level 2 (global KVS) cache & Rovo** via [**forge-sql-orm-extra**](forge-sql-orm-extra/README.md); **Level 1 local cache** stays in core -- ✅ **TiDB `VECTOR` type & vector SQL helpers** — Drizzle column type `vectorTiDBType` plus `vecCosineDistance`, `vecL2Distance`, `vecDims`, and related helpers for **SQL with AI** (embeddings storage and similarity search) -- ✅ **Binary custom types (`BINARY` / `VARBINARY` / `BLOB`)** — built-in `forgeBinary`, `forgeVarBinary`, `forgeBLOB`, `forgeTinyBLOB`, `forgeMediumBLOB`, and `uuidBinary` for compact binary storage in Atlassian Forge -- ✅ **AI semantic search examples for Forge** — embeddings in [Custom UI (frontend)](examples/forge-sql-orm-example-ai) or on the [Forge backend](examples/forge-sql-orm-example-backend-ai) via an `ai-lib` sidecar; both use vector search in SQL - -## Table of Contents - -### 🚀 Getting Started - -- [Key Features](#key-features) -- [Usage Approaches](#usage-approaches) -- [Installation](#installation) -- [Installing from GitHub Packages (weekly `latest`)](#installing-from-github-packages-weekly-latest) -- [CLI Commands](#cli-commands) | [CLI Documentation](forge-sql-orm-cli/README.md) -- [Quick Start](#quick-start) - -### 📖 Core Features - -- [Field Name Collision Prevention](#field-name-collision-prevention-in-complex-queries) -- [Drizzle Usage with forge-sql-orm](#drizzle-usage-with-forge-sql-orm) -- [Direct Drizzle Usage with Custom Driver](#direct-drizzle-usage-with-custom-driver) - -### 🗄️ Database Operations - -- [Fetch Data](#fetch-data) -- [Modify Operations](#modify-operations) -- [SQL Utilities](#sql-utilities) - -### ⚡ Caching & Rovo ([forge-sql-orm-extra](forge-sql-orm-extra/README.md)) - -- **Level 2 (global KVS)** — [forge-sql-orm-extra](forge-sql-orm-extra/README.md) only -- **Level 1 (local cache)** — [core](#usage-approaches) (`executeWithLocalContext`, `selectFrom`, `execute`, …); same in extra, L2 not required - -### 🔒 Advanced Features - -- [Optimistic Locking](#optimistic-locking) -- [Rovo Integration](forge-sql-orm-extra/README.md#rovo-integration) — in **forge-sql-orm-extra** -- [Query Analysis and Performance Optimization](#query-analysis-and-performance-optimization) -- [Automatic Error Analysis](#automatic-error-analysis) - Automatic timeout and OOM error detection with execution plans -- [Slow Query Monitoring](#slow-query-monitoring) - Scheduled monitoring of slow queries with execution plans -- [Date and Time Types](#date-and-time-types) -- [TiDB vector types (AI / similarity search)](#tidb-vector-types-ai--similarity-search) -- [Custom types for binary and UUID data](#custom-types-for-binary-and-uuid-data) -- [TiDB SQL function helpers](#tidb-sql-function-helpers) - -### 🛠️ Development Tools - -- [CLI Commands](#cli-commands) | [CLI Documentation](forge-sql-orm-cli/README.md) -- [Web Triggers for Migrations](#web-triggers-for-migrations) -- [Step-by-Step Migration Workflow](#step-by-step-migration-workflow) -- [Drop Migrations](#drop-migrations) - -### 📚 Examples - -- [Simple Example](examples/forge-sql-orm-example-simple) -- [Drizzle Driver Example](examples/forge-sql-orm-example-drizzle-driver-simple) -- [Optimistic Locking Example](examples/forge-sql-orm-example-optimistic-locking) -- [Dynamic Queries Example](examples/forge-sql-orm-example-dynamic) -- [Query Analysis Example](examples/forge-sql-orm-example-query-analyses) -- [Organization Tracker Example](examples/forge-sql-orm-example-org-tracker) -- [Checklist Example](examples/forge-sql-orm-example-checklist) -- [Cache Example](examples/forge-sql-orm-example-cache) — uses **forge-sql-orm-extra** ([docs](forge-sql-orm-extra/README.md)) -- [Vector / AI SQL Example](examples/forge-sql-orm-example-vector) - `VECTOR` columns, embeddings, cosine-distance search (TiDB-compatible) -- [AI Semantic Search (frontend embeddings)](examples/forge-sql-orm-example-ai) - Custom UI computes embeddings in the browser; resolvers store vectors and run cosine search -- [AI Semantic Search (backend embeddings)](examples/forge-sql-orm-example-backend-ai) - Resolvers compute embeddings server-side (`ai-lib` sidecar); Custom UI sends text only -- [Rovo Integration Example](https://github.com/vzakharchenko/Forge-Secure-Notes-for-Jira) - Real-world Rovo AI agent implementation with secure natural-language analytics - -### 📚 Reference - -- [Product requirements](REQUIREMENTS.md) — scope, platform limits (Forge SQL / KVS), traceability -- [ForgeSqlOrmOptions](#forgesqlormoptions) -- [Migration Guide](#migration-guide) - - [Migrating from 2.0.x to 2.1.x](#migrating-from-20x-to-21x) - - [Migrating from 2.1.x to 2.2.x](#migrating-from-21x-to-22x) - -## 🚀 Quick Navigation - -**New to Forge-SQL-ORM?** Start here: - -- [Quick Start](#quick-start) - Get up and running in 5 minutes -- [Installation](#installation) - Complete setup guide -- [Basic Usage Examples](#fetch-data) - Simple query examples - -**Looking for specific features?** - -- [Global cache & Rovo](forge-sql-orm-extra/README.md) — **forge-sql-orm-extra** -- [Local Cache (Level 1)](#usage-approaches) - In-memory invocation caching (core) -- [Optimistic Locking](#optimistic-locking) - Data consistency -- [Rovo Integration](forge-sql-orm-extra/README.md#rovo-integration) - In **forge-sql-orm-extra** -- [Migration Tools](#web-triggers-for-migrations) - Database migrations -- [Query Analysis](#query-analysis-and-performance-optimization) - Performance optimization - -**Looking for practical examples?** - -- [Simple Example](examples/forge-sql-orm-example-simple) - Basic ORM usage -- [Optimistic Locking Example](examples/forge-sql-orm-example-optimistic-locking) - Real-world conflict handling -- [Organization Tracker Example](examples/forge-sql-orm-example-org-tracker) - Complex relationships -- [Checklist Example](examples/forge-sql-orm-example-checklist) - Jira integration -- [Cache Example](examples/forge-sql-orm-example-cache) - Advanced caching capabilities -- [AI Semantic Search (frontend embeddings)](examples/forge-sql-orm-example-ai) - Embeddings in the browser; Forge SQL stores `title`/`document`/`embedding` and runs vector search -- [AI Semantic Search (backend embeddings)](examples/forge-sql-orm-example-backend-ai) - Embeddings in Forge functions; UI sends `title`/`document` and search text only -- [Rovo Integration Example](https://github.com/vzakharchenko/Forge-Secure-Notes-for-Jira) - Real-world Rovo AI agent with secure analytics - -## Usage Approaches - -### 1. Full Forge-SQL-ORM Usage - -```typescript -import ForgeSQL from "forge-sql-orm"; -const forgeSQL = new ForgeSQL(); -``` - -Best for: Advanced features like optimistic locking, automatic versioning, and automatic field name collision prevention in complex queries. - -### 2. Direct Drizzle Usage - -```typescript -import { drizzle } from "drizzle-orm/mysql-proxy"; -import { forgeDriver } from "forge-sql-orm"; -const db = drizzle(forgeDriver); -``` - -Best for: Simple Modify operations without optimistic locking. Note that you need to manually patch drizzle `patchDbWithSelectAliased` for select fields to prevent field name collisions in Atlassian Forge SQL. - -### 3. Local Cache Optimization - -```typescript -import ForgeSQL from "forge-sql-orm"; -const forgeSQL = new ForgeSQL(); - -// Optimize repeated queries within a single invocation -await forgeSQL.executeWithLocalContext(async () => { - // Multiple queries here will benefit from local caching - const users = await forgeSQL - .select({ id: users.id, name: users.name }) - .from(users) - .where(eq(users.active, true)); - - // This query will use local cache (no database call) - const cachedUsers = await forgeSQL - .select({ id: users.id, name: users.name }) - .from(users) - .where(eq(users.active, true)); - - // Using new methods for better performance - const usersFrom = await forgeSQL.selectFrom(users).where(eq(users.active, true)); - - // This will use local cache (no database call) - const cachedUsersFrom = await forgeSQL.selectFrom(users).where(eq(users.active, true)); - - // Raw SQL with local caching - const rawUsers = await forgeSQL.execute("SELECT id, name FROM users WHERE active = ?", [true]); -}); -``` - -Best for: Performance optimization of repeated queries within a single resolver invocation (**Level 1**). Available in **forge-sql-orm**; unchanged in 2.2.x (only **Level 2** moved to extra). - -## Field Name Collision Prevention in Complex Queries - -When working with complex queries involving multiple tables (joins, inner joins, etc.), Atlassian Forge SQL has a specific behavior where fields with the same name from different tables get collapsed into a single field with a null value. This is not a Drizzle ORM issue but rather a characteristic of Atlassian Forge SQL's behavior. - -Forge-SQL-ORM provides two ways to handle this: - -### Using Forge-SQL-ORM - -```typescript -import ForgeSQL from "forge-sql-orm"; - -const forgeSQL = new ForgeSQL(); - -// Automatic field name collision prevention -await forgeSQL - .select({ user: users, order: orders }) - .from(orders) - .innerJoin(users, eq(orders.userId, users.id)); -``` - -### Using Direct Drizzle - -```typescript -import { drizzle } from "drizzle-orm/mysql-proxy"; -import { forgeDriver, patchDbWithSelectAliased } from "forge-sql-orm"; - -const db = patchDbWithSelectAliased(drizzle(forgeDriver)); - -// Manual field name collision prevention -await db - .selectAliased({ user: users, order: orders }) - .from(orders) - .innerJoin(users, eq(orders.userId, users.id)); -``` - -### Important Notes - -- This is a specific behavior of Atlassian Forge SQL, not Drizzle ORM -- For complex queries involving multiple tables, it's recommended to always specify select fields and avoid using `select()` without field selection -- The solution automatically creates unique aliases for each field by prefixing them with the table name -- This ensures that fields with the same name from different tables remain distinct in the query results - -## Installation - -Forge-SQL-ORM is designed to work with [@forge/sql](https://developer.atlassian.com/platform/forge/storage-reference/sql-tutorial/) and [Drizzle ORM](https://orm.drizzle.team). - -```sh -npm install forge-sql-orm @forge/sql drizzle-orm -S -``` - -For **global cache** ([@forge/kvs](https://developer.atlassian.com/platform/forge/storage-reference/storage-api-custom-entities/)) and **Rovo**, use [**forge-sql-orm-extra**](forge-sql-orm-extra/README.md): - -```sh -npm install forge-sql-orm-extra @forge/kvs -S -``` - -(You still need the core dependencies above.) - -### Installing from GitHub Packages (weekly `latest`) - -Besides [official releases on npmjs.com](https://www.npmjs.com/package/forge-sql-orm), the repository publishes a **weekly snapshot of `master`** to [GitHub Packages](https://github.com/orgs/forge-sql-orm/packages) every **Sunday 02:00 UTC** (workflow [Weekly GitHub Packages (latest)](.github/workflows/weekly-gpr.yml); also runnable manually from the Actions tab). These builds pass the same quality gate as CI (lint, Knip, tests, license check) before publish. - -| Channel | Registry | dist-tag | When | -| ---------------------------- | -------------------------------------------------------- | ------------ | --------------------------------- | -| **Production (recommended)** | [npmjs.com](https://www.npmjs.com/package/forge-sql-orm) | npm `latest` | Manual semver release + CHANGELOG | -| **Bleeding-edge snapshot** | GitHub Packages | GPR `latest` | Weekly from current `master` | - -GPR package names are scoped: `@forge-sql-orm/forge-sql-orm`, `@forge-sql-orm/forge-sql-orm-extra`, `@forge-sql-orm/forge-sql-orm-cli`. Published versions look like `2.1.29-weekly.20260608` (immutable); the **`latest`** tag always points at the most recent weekly build. - -**1. Authenticate** — create or edit `.npmrc` in your project (use a [GitHub personal access token](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry) with `read:packages`, or `GITHUB_TOKEN` in CI): - -```ini -@forge-sql-orm:registry=https://npm.pkg.github.com -//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN -``` - -Keep the default registry for everything else (Forge apps still install `@forge/sql` and `drizzle-orm` from npmjs.com): - -```ini -registry=https://registry.npmjs.org/ -``` - -**2. Install core** (npm alias — your `import` stays `forge-sql-orm`): - -```bash -npm install forge-sql-orm@npm:@forge-sql-orm/forge-sql-orm@latest @forge/sql drizzle-orm -S -``` - -**3. Optional — extra and CLI from GPR:** - -```bash -npm install forge-sql-orm-extra@npm:@forge-sql-orm/forge-sql-orm-extra@latest @forge/kvs -S -npm install forge-sql-orm-cli@npm:@forge-sql-orm/forge-sql-orm-cli@latest -D -``` - -Pin a specific weekly version instead of `@latest` when you need reproducibility, for example `@forge-sql-orm/forge-sql-orm@2.1.29-weekly.20260608`. - -Weekly GPR builds are **not** the supported production channel for most apps — prefer npm semver releases. Use GPR `latest` to try fixes on `master` before the next npm release, or for internal smoke tests. - -## forge-sql-orm-extra - -[**forge-sql-orm-extra**](forge-sql-orm-extra/README.md) adds **Level 2 (global KVS) cache** and **Rovo** on top of core. **Level 1 (local cache)** remains in **forge-sql-orm** and works unchanged with either import. - -- **Level 2** — `@forge/kvs`, `selectCacheable*`, `*AndEvictCache`, cache contexts, scheduler cleanup -- **Rovo** — secure dynamic SQL for AI / natural-language analytics - -Install: `npm install forge-sql-orm-extra @forge/kvs -S`. Import: `import ForgeSQL from "forge-sql-orm-extra"` and pass `cacheEntityName` / `cacheTTL` as in the [extra README](forge-sql-orm-extra/README.md). - -## Quick Start - -### 1. Basic Setup - -```typescript -import ForgeSQL from "forge-sql-orm"; - -// Initialize ForgeSQL -const forgeSQL = new ForgeSQL(); - -// Simple query -const users = await forgeSQL.select().from(users); -``` - -### 2. With global cache ([forge-sql-orm-extra](forge-sql-orm-extra/README.md)) - -Install `forge-sql-orm-extra` and `@forge/kvs` (see [extra README](forge-sql-orm-extra/README.md#installation)). Same API, different import: - -```typescript -import ForgeSQL from "forge-sql-orm-extra"; - -const forgeSQL = new ForgeSQL({ - cacheEntityName: "cache", - cacheTTL: 300, -}); - -const users = await forgeSQL - .selectCacheable({ id: users.id, name: users.name }) - .from(users) - .where(eq(users.active, true)); -``` - -### 3. Local Cache Optimization - -```typescript -// Optimize repeated queries within a single invocation -await forgeSQL.executeWithLocalContext(async () => { - const users = await forgeSQL - .select({ id: users.id, name: users.name }) - .from(users) - .where(eq(users.active, true)); - - // This query will use local cache (no database call) - const cachedUsers = await forgeSQL - .select({ id: users.id, name: users.name }) - .from(users) - .where(eq(users.active, true)); - - // Using new methods for better performance - const usersFrom = await forgeSQL.selectFrom(users).where(eq(users.active, true)); - - // Raw SQL with local caching - const rawUsers = await forgeSQL.execute("SELECT id, name FROM users WHERE active = ?", [true]); -}); -``` - -### 4. Resolver Performance Monitoring - -```typescript -// Resolver with performance monitoring -resolver.define("fetch", async (req: Request) => { - try { - return await forgeSQL.executeWithMetadata( - async () => { - // Resolver logic with multiple queries - const users = await forgeSQL.selectFrom(demoUsers); - const orders = await forgeSQL - .selectFrom(demoOrders) - .where(eq(demoOrders.userId, demoUsers.id)); - return { users, orders }; - }, - async (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - const threshold = 500; // ms baseline for this resolver - - if (totalDbExecutionTime > threshold * 1.5) { - console.warn( - `[Performance Warning fetch] Resolver exceeded DB time: ${totalDbExecutionTime} ms`, - ); - await printQueriesWithPlan(); // Optionally log or capture diagnostics for further analysis - } else if (totalDbExecutionTime > threshold) { - console.debug(`[Performance Debug fetch] High DB time: ${totalDbExecutionTime} ms`); - } - }, - { - // Optional: Configure query plan printing behavior - mode: "TopSlowest", // Print top slowest queries (default) - topQueries: 3, // Print top 3 slowest queries - }, - ); - } catch (e) { - const error = e?.cause?.debug?.sqlMessage ?? e?.cause; - console.error(error, e); - throw error; - } -}); -``` - -**Query Plan Printing Options:** - -The `printQueriesWithPlan` function supports two modes: - -1. **TopSlowest Mode (default)**: Prints execution plans for the slowest queries from the current resolver invocation - - `mode`: Set to `'TopSlowest'` (default) - - `topQueries`: Number of top slowest queries to analyze (default: 1) - -2. **SummaryTable Mode**: Uses `CLUSTER_STATEMENTS_SUMMARY` for query analysis - - `mode`: Set to `'SummaryTable'` - - `summaryTableWindowTime`: Time window in milliseconds (default: 15000ms) - - Only works if queries are executed within the specified time window - -### 5. Rovo (forge-sql-orm-extra) - -Secure dynamic SQL for natural-language analytics: [**forge-sql-orm-extra**](forge-sql-orm-extra/README.md#rovo-integration) (`import ForgeSQL from "forge-sql-orm-extra"`, `forgeSQL.rovo()`). - -### 6. Next Steps - -- [Full Installation Guide](#installation) - Complete setup instructions -- [Core Features](#core-features) - Learn about key capabilities -- [Global cache & Rovo](forge-sql-orm-extra/README.md) — extension package -- [Local Cache](#usage-approaches) - In-memory caching (core) -- [Rovo Integration](forge-sql-orm-extra/README.md#rovo-integration) - In **forge-sql-orm-extra** -- [API Reference](#reference) - Complete API documentation - -## Drizzle Usage with forge-sql-orm - -If you prefer to use Drizzle ORM with the additional features of Forge-SQL-ORM (like optimistic locking and caching), you can use the enhanced API: - -```typescript -import ForgeSQL from "forge-sql-orm"; -const forgeSQL = new ForgeSQL(); - -// Versioned operations (recommended) -await forgeSQL.modifyWithVersioning().insert(Users, [userData]); -await forgeSQL.modifyWithVersioning().updateById(updateData, Users); - -// Basic Drizzle operations -await forgeSQL.insert(Users).values(userData); -await forgeSQL.update(Users).set(updateData).where(eq(Users.id, 1)); - -// Direct Drizzle access -const db = forgeSQL.getDrizzleQueryBuilder(); -const users = await db.select().from(users); - -// Using new methods for enhanced functionality -const usersFrom = await forgeSQL.selectFrom(users).where(eq(users.active, true)); - -const usersDistinct = await forgeSQL.selectDistinctFrom(users).where(eq(users.active, true)); - -// Raw SQL execution -const rawUsers = await forgeSQL.execute("SELECT * FROM users WHERE active = ?", [true]); - -// Raw SQL with execution metadata and performance monitoring -const usersWithMetadata = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - const orders = await forgeSQL - .selectFrom(ordersTable) - .where(eq(ordersTable.userId, usersTable.id)); - return { users, orders }; - }, - (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - const threshold = 500; // ms baseline for this resolver - - if (totalDbExecutionTime > threshold * 1.5) { - console.warn(`[Performance Warning] Resolver exceeded DB time: ${totalDbExecutionTime} ms`); - await printQueriesWithPlan(); // Analyze and print query execution plans - } else if (totalDbExecutionTime > threshold) { - console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`); - } - - console.log(`DB response size: ${totalResponseSize} bytes`); - }, - { - // Optional: Configure query plan printing - mode: "TopSlowest", // Print top slowest queries (default) - topQueries: 2, // Print top 2 slowest queries - }, -); - -// DDL operations for schema modifications -await forgeSQL.executeDDL(` - CREATE TABLE users ( - id INT PRIMARY KEY AUTO_INCREMENT, - name VARCHAR(255) NOT NULL, - email VARCHAR(255) UNIQUE - ) -`); - -// Execute regular SQL queries in DDL context for performance monitoring -await forgeSQL.executeDDLActions(async () => { - // Execute regular SQL queries in DDL context for monitoring - const slowQueries = await forgeSQL.execute(` - SELECT * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY - WHERE AVG_LATENCY > 1000000 - `); - - // Execute complex analysis queries in DDL context - const performanceData = await forgeSQL.execute(` - SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY_HISTORY - WHERE SUMMARY_END_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR) - `); - - return { slowQueries, performanceData }; -}); - -// Common Table Expressions (CTEs) -const userStats = await forgeSQL - .with( - forgeSQL.selectFrom(users).where(eq(users.active, true)).as("activeUsers"), - forgeSQL.selectFrom(orders).where(eq(orders.status, "completed")).as("completedOrders"), - ) - .select({ - totalActiveUsers: sql`COUNT(au.id)`, - totalCompletedOrders: sql`COUNT(co.id)`, - }) - .from(sql`activeUsers au`) - .leftJoin(sql`completedOrders co`, eq(sql`au.id`, sql`co.userId`)); - -// Global cache, cache eviction, and Rovo: see forge-sql-orm-extra/README.md -``` - -This approach gives you direct access to all Drizzle ORM features while still using the @forge/sql backend with optimistic locking and local caching. For KVS global cache and Rovo, use [forge-sql-orm-extra](forge-sql-orm-extra/README.md). - -## Direct Drizzle Usage with Custom Driver - -If you prefer to use Drizzle ORM directly without the additional features of Forge-SQL-ORM (like optimistic locking), you can use the custom driver: - -```typescript -import { drizzle } from "drizzle-orm/mysql-proxy"; -import { forgeDriver, patchDbWithSelectAliased } from "forge-sql-orm"; - -// Initialize drizzle with the custom driver and patch it for aliased selects -const db = patchDbWithSelectAliased(drizzle(forgeDriver)); - -// Use drizzle directly -const users = await db.select().from(users); -const users = await db.selectAliased(getTableColumns(users)).from(users); -const users = await db.selectAliasedDistinct(getTableColumns(users)).from(users); -await db.insert(users)...; -await db.update(users)...; -await db.delete(users)...; -// Using new methods with direct drizzle -const usersFrom = await forgeSQL.selectFrom(users) - .where(eq(users.active, true)); - -const usersDistinct = await forgeSQL.selectDistinctFrom(users) - .where(eq(users.active, true)); - -// Raw SQL execution -const rawUsers = await forgeSQL.execute( - "SELECT * FROM users WHERE active = ?", - [true] -); - -// Raw SQL with execution metadata and performance monitoring -const usersWithMetadata = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - const orders = await forgeSQL.selectFrom(ordersTable).where(eq(ordersTable.userId, usersTable.id)); - return { users, orders }; - }, - (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - const threshold = 500; // ms baseline for this resolver - - if (totalDbExecutionTime > threshold * 1.5) { - console.warn(`[Performance Warning] Resolver exceeded DB time: ${totalDbExecutionTime} ms`); - await printQueriesWithPlan(); // Analyze and print query execution plans - } else if (totalDbExecutionTime > threshold) { - console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`); - } - - console.log(`DB response size: ${totalResponseSize} bytes`); - }, - { - // Optional: Configure query plan printing - mode: 'TopSlowest', // Print top slowest queries (default) - topQueries: 1, // Print top slowest query - }, -); -``` - -## Step-by-Step Migration Workflow - -1. **Install CLI and setup scripts** - - ```bash - npm install forge-sql-orm-cli -D - npm pkg set scripts.models:create="forge-sql-orm-cli generate:model --output src/entities --saveEnv" - npm pkg set scripts.migration:create="forge-sql-orm-cli migrations:create --force --output src/migration --entitiesPath src/entities" - npm pkg set scripts.migration:update="forge-sql-orm-cli migrations:update --entitiesPath src/entities --output src/migration" - npm pkg set scripts.schema:create="forge-sql-orm-cli schema:create --entitiesPath src/entities" - ``` - - _(This is done only once when setting up the project)_ - -2. **Generate initial schema from an existing database** - - ```sh - npm run models:create - ``` - - _(This will prompt for database credentials on first run and save them to `.env` file)_ - -3. **Create the first migration** - - ```sh - npm run migration:create - ``` - - _(This initializes the database migration structure, also done once)_ - -4. **Deploy to Forge and verify that migrations work** - - Deploy your **Forge app** with migrations. - - Run migrations using a **Forge web trigger** or **Forge scheduler**. - -5. **Modify the database (e.g., add a new column, index, etc.)** - - Use **DbSchema** or manually alter the database schema. - -6. **Update the migration** - - ```sh - npm run migration:update - ``` - - - ⚠️ **Do NOT update schema before this step!** - - If schema is updated first, the migration will be empty! - -7. **Deploy to Forge and verify that the migration runs without issues** - - Run the updated migration on Forge. - -8. **Update the schema** - - ```sh - npm run models:create - ``` - -9. **Repeat steps 5-8 as needed** - -**⚠️ WARNING:** - -- **Do NOT swap steps 7 and 5!** If you update schema before generating a migration, the migration will be empty! -- Always generate the **migration first**, then update the **schema**. - -## Drop Migrations - -The Drop Migrations feature allows you to completely reset your database schema in Atlassian Forge SQL. This is useful when you need to: - -- Start fresh with a new schema -- Reset all tables and their data -- Clear migration history -- Ensure your local schema matches the deployed database - -### Important Requirements - -Before using Drop Migrations, ensure that: - -1. Your local schema exactly matches the current database schema deployed in Atlassian Forge SQL -2. You have a backup of your data if needed -3. You understand that this operation will delete all tables and data - -### Usage - -1. First, ensure your local schema matches the deployed database: - - ```bash - npm run models:create - ``` - -2. Generate the drop migration: - - ```bash - npm run migration:drop - ``` - - _(Add this script to your package.json: `npm pkg set scripts.migration:drop="forge-sql-orm-cli migrations:drop --entitiesPath src/entities --output src/migration"`)_ - -3. Deploy and run the migration in your Forge app: - - ```js - import migrationRunner from "./database/migration"; - import { MigrationRunner } from "@forge/sql/out/migration"; - - const runner = new MigrationRunner(); - await migrationRunner(runner); - await runner.run(); - ``` - -4. After dropping all tables, you can create a new migration to recreate the schema: - ```bash - npm run migration:create - ``` - The `--force` parameter is already included in the script to allow creating migrations after dropping all tables. - -### Example Migration Output - -The generated drop migration will look like this: - -```js -import { MigrationRunner } from "@forge/sql/out/migration"; - -export default (migrationRunner: MigrationRunner): MigrationRunner => { - return migrationRunner - .enqueue("v1_MIGRATION0", "ALTER TABLE `orders` DROP FOREIGN KEY `fk_orders_users`") - .enqueue("v1_MIGRATION1", "DROP INDEX `idx_orders_user_id` ON `orders`") - .enqueue("v1_MIGRATION2", "DROP TABLE IF EXISTS `orders`") - .enqueue("v1_MIGRATION3", "DROP TABLE IF EXISTS `users`") - .enqueue("MIGRATION_V1_1234567890", "DELETE FROM __migrations"); -}; -``` - -### ⚠️ Important Notes - -- This operation is **irreversible** - all data will be lost -- Make sure your local schema is up-to-date with the deployed database -- Consider backing up your data before running drop migrations -- The migration will clear the `__migrations` table to allow for fresh migration history -- Drop operations are performed in the correct order: first foreign keys, then indexes, then tables - ---- - -## Date and Time Types - -When working with date and time fields in your models, you should use the custom types provided by Forge-SQL-ORM to ensure proper handling of date/time values. This is necessary because Forge SQL has specific format requirements for date/time values: - -| Date type | Required Format | Example | -| --------- | ------------------------------ | -------------------------- | -| DATE | YYYY-MM-DD | 2024-09-19 | -| TIME | HH:MM:SS[.fraction] | 06:40:34 | -| TIMESTAMP | YYYY-MM-DD HH:MM:SS[.fraction] | 2024-09-19 06:40:34.999999 | - -```typescript -// ❌ Don't use standard Drizzle date/time types -export const testEntityTimeStampVersion = mysqlTable("test_entity", { - id: int("id").primaryKey().autoincrement(), - time_stamp: timestamp("times_tamp").notNull(), - date_time: datetime("date_time").notNull(), - time: time("time").notNull(), - date: date("date").notNull(), -}); - -// ✅ Use Forge-SQL-ORM custom types instead -import { - forgeDateTimeString, - forgeDateString, - forgeTimestampString, - forgeTimeString, -} from "forge-sql-orm"; - -export const testEntityTimeStampVersion = mysqlTable("test_entity", { - id: int("id").primaryKey().autoincrement(), - time_stamp: forgeTimestampString("times_tamp").notNull(), - date_time: forgeDateTimeString("date_time").notNull(), - time: forgeTimeString("time").notNull(), - date: forgeDateString("date").notNull(), -}); -``` - -### Why Custom Types? - -The custom types in Forge-SQL-ORM handle the conversion between JavaScript Date objects and Forge SQL's required string formats automatically. Without these custom types, you would need to manually format dates like this: - -```typescript -// Without custom types, you'd need to do this manually: -const date = moment().format("YYYY-MM-DD"); -const time = moment().format("HH:mm:ss.SSS"); -const timestamp = moment().format("YYYY-MM-DDTHH:mm:ss.SSS"); -``` - -Our custom types provide: - -- Automatic conversion between JavaScript Date objects and Forge SQL's required string formats -- Consistent date/time handling across your application -- Type safety for date/time fields -- Proper handling of timezone conversions -- Support for all Forge SQL date/time types (datetime, timestamp, date, time) - -### Available Custom Types - -- `forgeDateTimeString` - For datetime fields (YYYY-MM-DD HH:MM:SS[.fraction]) -- `forgeTimestampString` - For timestamp fields (YYYY-MM-DD HH:MM:SS[.fraction]) -- `forgeDateString` - For date fields (YYYY-MM-DD) -- `forgeTimeString` - For time fields (HH:MM:SS[.fraction]) - -Each type ensures that the data is properly formatted according to Forge SQL's requirements while providing a clean, type-safe interface for your application code. - ---- - -## TiDB vector types (AI / similarity search) - -Forge SQL ORM exposes **TiDB-compatible** `VECTOR` columns and vector functions so you can store **embeddings** and run **similarity search** in SQL—typical for **AI** features (semantic search, RAG-style retrieval) built on Forge SQL. - -### Schema: `vectorTiDBType` - -Use the Drizzle custom column type from `forge-sql-orm`. With a fixed dimension, DDL becomes `VECTOR(n)`; without it, `VECTOR`. - -```typescript -import { int, mysqlTable, primaryKey, text } from "drizzle-orm/mysql-core"; -import { vectorTiDBType } from "forge-sql-orm"; - -export const documents = mysqlTable( - "documents", - { - id: int().autoincrement().notNull(), - body: text().notNull(), - embedding: vectorTiDBType("embedding", { dimension: 1536 }).notNull(), - }, - (table) => [primaryKey({ columns: [table.id], name: "id" })], -); -``` - -Values in application code are **`number[]`**; the driver maps them to the textual form TiDB expects. - -### Queries: distance helpers - -Helpers build the same expressions as TiDB’s vector functions (e.g. `VEC_COSINE_DISTANCE`). Use them inside `forgeSQL.select()`, `where()`, `orderBy()`, etc. - -```typescript -import { asc, sql } from "drizzle-orm"; -import { vecCosineDistance } from "forge-sql-orm"; -import { documents } from "./schema"; - -const queryVector = [0.1, 0.2, 0.3]; - -const distanceAlias = sql.raw("distance"); -const distance = sql`${vecCosineDistance(documents.embedding, queryVector)} AS \`${distanceAlias}\``; - -const nearest = await forgeSQL - .select({ - id: documents.id, - body: documents.body, - distance, - }) - .from(documents) - .orderBy(asc(distanceAlias)) - .limit(10); -``` - -Also available (see `src/core/VectorTiDB.ts`): `vecFromText`, `vecAsText`, `vecDims`, `vecL2Norm`, `vecL2Distance`, `vecL1Distance`, `vecNegativeInnerProduct`. - -### Example app - -See **[examples/forge-sql-orm-example-vector](examples/forge-sql-orm-example-vector)** for a full Forge app (migrations, resolvers, UI) aligned with [Get Started with Vector Search via SQL](https://docs.pingcap.com/tidb/stable/vector-search-get-started-using-sql). - -For **semantic search** with learned embeddings, use **[examples/forge-sql-orm-example-ai](examples/forge-sql-orm-example-ai)** (embeddings in Custom UI) or **[examples/forge-sql-orm-example-backend-ai](examples/forge-sql-orm-example-backend-ai)** (embeddings in Forge resolvers via `ai-lib`). - -## Custom types for binary and UUID data - -Forge SQL ORM provides custom types from `src/core/customTypes.ts` for compact binary storage and UUID primary keys. - -| Type | SQL type | Use case | -| ----------------- | --------------- | --------------------------------------------------------------------------------------------------------- | -| `uuidBinary` | `VARBINARY(16)` | Store UUID primary keys in compact binary form; writes use `UUID_TO_BIN(...)`, reads return UUID strings. | -| `forgeVarBinary` | `VARBINARY(n)` | Variable-length binary payloads (e.g., small encrypted payloads or protocol bytes). | -| `forgeBinary` | `BINARY(n)` | Fixed-length binary values (e.g., hashes, signatures, fixed-size binary tokens). | -| `forgeBLOB` | `BLOB` | General-purpose binary files/content. | -| `forgeTinyBLOB` | `TINYBLOB` | Small binary payloads. | -| `forgeMediumBLOB` | `MEDIUMBLOB` | Medium-size binary payloads. | - -Binary custom types encode data to Base64 in JS and write through `FROM_BASE64(...)`, which keeps SQL safe and works well with Forge SQL payload constraints. - -### Example (with BLOB) - -```typescript -import { int, mysqlTable, text } from "drizzle-orm/mysql-core"; -import { forgeBLOB, uuidBinary } from "forge-sql-orm"; - -export const files = mysqlTable("files", { - id: uuidBinary("id").primaryKey().notNull(), - name: text("name").notNull(), - content: forgeBLOB("content").notNull(), -}); - -await forgeSQL.insert(files).values({ - id: "00112233-4455-6677-8899-aabbccddeeff", - name: "avatar.png", - content: Buffer.from([137, 80, 78, 71]), // PNG signature bytes (example) -}); -``` - -## TiDB SQL function helpers - -`forge-sql-orm` also includes ready-to-use TiDB/MySQL SQL helper modules in `src/core/functions`. They return Drizzle `sql` fragments, so you can compose them inside `select`, `where`, `orderBy`, `groupBy`, computed columns, and other query builders. - -| Module | What it does | -| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| `VectorTiDB` | Vector search helpers such as cosine distance, L1/L2 distance, dimensions, and vector text conversion. | -| `StringTiDB` | String manipulation helpers such as concatenation, substring, replace, trim, case conversion, and pattern-oriented string operations. | -| `NumericTiDB` | Arithmetic and numeric helpers such as addition/subtraction operators, rounding, powers, logarithms, trigonometry, and random values. | -| `DateTiDB` | Date/time helpers such as `DATE_ADD`, `DATE_SUB`, formatting, extraction, timestamp conversion, and calendar calculations. | -| `BitTiDB` | Bitwise operators and bit functions such as AND/OR/XOR, shifts, negation, and bit counting. | -| `CastTiDB` | SQL casting helpers for `CAST`, `CONVERT`, binary conversion, and reusable cast target builders. | -| `EncryptTiDB` | Encryption, hashing, compression, and password-strength helpers such as AES, SHA, MD5, and compression functions. | -| `InformationTiDB` | Metadata helpers such as current database/user, connection id, version, row count, and TiDB environment info. | -| `JsonTiDB` | JSON creation, extraction, search, mutation, validation, schema checking, and storage inspection helpers. | -| `AggregateTiDB` | Extra aggregate helpers not already covered by Drizzle, such as percentile/approximation and specialized aggregate expressions. | -| `WindowTiDB` | Window function call helpers such as `rowNumber`, `rank`, `denseRank`, `lag`, `lead`, and `firstValue` for use with `OVER (...)`. | -| `SequenceTiDB` | Sequence helpers such as `NEXTVAL`, `LASTVAL`, and `SETVAL` for working with TiDB sequences. | -| `UtilityTiDB` | Small utility helpers such as byte and nanosecond formatting functions. | -| `MiscellaneousTiDB` | Miscellaneous helpers such as UUID/IP utilities, `sleep`, `default`, and compatibility helpers. | -| `TiDBSpecificTiDB` | TiDB-specific helpers such as TSO parsing, resource-group helpers, SQL digest helpers, MVCC inspection, and key encoding helpers. | - -### Example - -```typescript -import { sql } from "drizzle-orm"; -import { concat } from "forge-sql-orm"; -import { users } from "./schema"; - -const rows = await forgeSQL - .select({ - label: sql`${concat(users.firstName, sql`' '`, users.lastName)}`, - }) - .from(users); -``` - -In this example, `concat(...)` builds a safe SQL fragment that Drizzle can embed into the final query. - -# Connection to ORM - -```js -import ForgeSQL from "forge-sql-orm"; - -const forgeSQL = new ForgeSQL(); -``` - -or - -```typescript -import { drizzle } from "drizzle-orm/mysql-proxy"; -import { forgeDriver } from "forge-sql-orm"; - -// Initialize drizzle with the custom driver -const db = drizzle(forgeDriver); - -// Use drizzle directly -const users = await db.select().from(users); -``` - -## Fetch Data - -### Basic Fetch Operations - -```js -// Using forgeSQL.select() -const user = await forgeSQL.select({ user: users }).from(users); - -// Using forgeSQL.selectDistinct() -const user = await forgeSQL.selectDistinct({ user: users }).from(users); - -// Using forgeSQL.selectFrom() - Select all columns with field aliasing -const user = await forgeSQL.selectFrom(users).where(eq(users.id, 1)); - -// Using forgeSQL.selectDistinctFrom() - Select distinct all columns with field aliasing -const user = await forgeSQL.selectDistinctFrom(users).where(eq(users.id, 1)); - -// Using forgeSQL.execute() - Execute raw SQL with local caching -const user = await forgeSQL.execute("SELECT * FROM users WHERE id = ?", [1]); - -// Using forgeSQL.getDrizzleQueryBuilder() -const user = await forgeSQL.getDrizzleQueryBuilder().select().from(Users).where(eq(Users.id, 1)); - -// OR using direct drizzle with custom driver -const db = drizzle(forgeDriver); -const user = await db.select().from(Users).where(eq(Users.id, 1)); -// Returns: { id: 1, name: "John Doe" } - -// Using executeQueryOnlyOne for single result with error handling -const user = await forgeSQL - .fetch() - .executeQueryOnlyOne( - forgeSQL.getDrizzleQueryBuilder().select().from(Users).where(eq(Users.id, 1)), - ); -// Returns: { id: 1, name: "John Doe" } -// Throws error if multiple records found -// Returns undefined if no records found - -// Using with aliases -// With forgeSQL -const usersAlias = alias(Users, "u"); -const result = await forgeSQL - .getDrizzleQueryBuilder() - .select({ - userId: sql < string > `${usersAlias.id} as \`userId\``, - userName: sql < string > `${usersAlias.name} as \`userName\``, - }) - .from(usersAlias); - -// OR with direct drizzle -const db = drizzle(forgeDriver); -const result = await db - .select({ - userId: sql < string > `${usersAlias.id} as \`userId\``, - userName: sql < string > `${usersAlias.name} as \`userName\``, - }) - .from(usersAlias); -// Returns: { userId: 1, userName: "John Doe" } -``` - -### Complex Queries - -```js -// Using joins with automatic field name collision prevention -// With forgeSQL -const orderWithUser = await forgeSQL - .select({ user: users, order: orders }) - .from(orders) - .innerJoin(users, eq(orders.userId, users.id)); - -// Using new selectFrom methods with joins -const orderWithUser = await forgeSQL - .selectFrom(orders) - .innerJoin(users, eq(orders.userId, users.id)) - .where(eq(orders.id, 1)); - -// Using with() for Common Table Expressions (CTEs) -const userStats = await forgeSQL - .with( - forgeSQL.selectFrom(users).where(eq(users.active, true)).as("activeUsers"), - forgeSQL.selectFrom(orders).where(eq(orders.status, "completed")).as("completedOrders"), - ) - .select({ - totalActiveUsers: sql`COUNT(au.id)`, - totalCompletedOrders: sql`COUNT(co.id)`, - }) - .from(sql`activeUsers au`) - .leftJoin(sql`completedOrders co`, eq(sql`au.id`, sql`co.userId`)); - -// OR with direct drizzle -const db = patchDbWithSelectAliased(drizzle(forgeDriver)); -const orderWithUser = await db - .selectAliased({ user: users, order: orders }) - .from(orders) - .innerJoin(users, eq(orders.userId, users.id)); -// Returns: { -// user_id: 1, -// user_name: "John Doe", -// order_id: 1, -// order_product: "Product 1" -// } - -// Using distinct with aliases -const uniqueUsers = await db.selectAliasedDistinct({ user: users }).from(users); -// Returns unique users with aliased fields - -// Using executeQueryOnlyOne for unique results -const userStats = await forgeSQL.fetch().executeQueryOnlyOne( - forgeSQL - .getDrizzleQueryBuilder() - .select({ - totalUsers: sql`COUNT(*) as \`totalUsers\``, - uniqueNames: sql`COUNT(DISTINCT name) as \`uniqueNames\``, - }) - .from(Users), -); -// Returns: { totalUsers: 100, uniqueNames: 80 } -// Throws error if multiple records found -``` - -### Raw SQL Queries - -```js -// Using executeRawSQL for direct SQL queries -const users = await forgeSQL - .fetch() - .executeRawSQL("SELECT * FROM users"); - -// Using execute() for raw SQL with local caching -const users = await forgeSQL - .execute("SELECT * FROM users WHERE active = ?", [true]); - -// Using executeWithMetadata() for capturing execution metrics and performance monitoring -const usersWithMetadata = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - const orders = await forgeSQL.selectFrom(ordersTable).where(eq(ordersTable.userId, usersTable.id)); - return { users, orders }; - }, - (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - const threshold = 500; // ms baseline for this resolver - - if (totalDbExecutionTime > threshold * 1.5) { - console.warn(`[Performance Warning] Resolver exceeded DB time: ${totalDbExecutionTime} ms`); - await printQueriesWithPlan(); // Analyze and print query execution plans - } else if (totalDbExecutionTime > threshold) { - console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`); - } - - console.log(`DB response size: ${totalResponseSize} bytes`); - }, - { - // Optional: Configure query plan printing - mode: 'TopSlowest', // Print top slowest queries (default) - topQueries: 1, // Print top slowest query - }, -); - -// Using executeDDL() for DDL operations (CREATE, ALTER, DROP, etc.) -await forgeSQL.executeDDL(` - CREATE TABLE users ( - id INT PRIMARY KEY AUTO_INCREMENT, - name VARCHAR(255) NOT NULL, - email VARCHAR(255) UNIQUE - ) -`); - -await forgeSQL.executeDDL(sql` - ALTER TABLE users - ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -`); - -await forgeSQL.executeDDL("DROP TABLE IF EXISTS old_users"); - -// Using executeDDLActions() for executing regular SQL queries in DDL context -// This method executes a series of actions within a DDL operation context for monitoring -await forgeSQL.executeDDLActions(async () => { - // Execute regular SQL queries in DDL context for performance monitoring - const slowQueries = await forgeSQL.execute(` - SELECT * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY - WHERE AVG_LATENCY > 1000000 - `); - - // Execute complex analysis queries in DDL context - const performanceData = await forgeSQL.execute(` - SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY_HISTORY - WHERE SUMMARY_END_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR) - `); - - return { slowQueries, performanceData }; -}); - -// Using execute() with complex queries -const userStats = await forgeSQL - .execute(` - SELECT - u.id, - u.name, - COUNT(o.id) as order_count, - SUM(o.amount) as total_amount - FROM users u - LEFT JOIN orders o ON u.id = o.user_id - WHERE u.active = ? - GROUP BY u.id, u.name - `, [true]); -``` - -## Modify Operations - -Forge-SQL-ORM provides multiple approaches for Modify operations, each with different characteristics: - -### 1. Basic Drizzle Operations - -```js -await forgeSQL.insert(Users).values({ id: 1, name: "Smith" }); -await forgeSQL.update(Users).set({ name: "Smith Updated" }).where(eq(Users.id, 1)); -await forgeSQL.delete(Users).where(eq(Users.id, 1)); -``` - -> Cache-aware variants (`insertAndEvictCache`, `modifyWithVersioningAndEvictCache`, `executeWithCacheContext`, …) are in [**forge-sql-orm-extra**](forge-sql-orm-extra/README.md). - -### 2. Versioned Operations (recommended) - -```js -// Insert with versioning only (no cache management) -const userId = await forgeSQL.modifyWithVersioning().insert(Users, [{ id: 1, name: "Smith" }]); - -// Update with versioning only -await forgeSQL.modifyWithVersioning().updateById({ id: 1, name: "Smith Updated" }, Users); - -// Delete with versioning only -await forgeSQL.modifyWithVersioning().deleteById(1, Users); -``` - -### 5. Legacy Modify Operations (Removed in 2.1.x) - -⚠️ **BREAKING CHANGE**: The `crud()` and `modify()` methods have been completely removed in version 2.1.x. - -```js -// ❌ These methods no longer exist in 2.1.x -// const userId = await forgeSQL.crud().insert(Users, [{ id: 1, name: "Smith" }]); -// await forgeSQL.crud().updateById({ id: 1, name: "Smith Updated" }, Users); -// await forgeSQL.crud().deleteById(1, Users); - -// ✅ Use the new methods instead -const userId = await forgeSQL.modifyWithVersioning().insert(Users, [{ id: 1, name: "Smith" }]); -await forgeSQL.modifyWithVersioning().updateById({ id: 1, name: "Smith Updated" }, Users); -await forgeSQL.modifyWithVersioning().deleteById(1, Users); -``` - -### Advanced Operations - -```js -// Insert with sequence (nextVal) -import { nextVal } from "forge-sql-orm"; - -const user = { - id: nextVal("user_id_seq"), - name: "user test", - organization_id: 1, -}; -const id = await forgeSQL.modifyWithVersioning().insert(appUser, [user]); - -// Update with custom WHERE condition -await forgeSQL - .modifyWithVersioning() - .updateFields({ name: "New Name", age: 35 }, Users, eq(Users.email, "smith@example.com")); - -// Insert with duplicate handling -await forgeSQL.modifyWithVersioning().insert( - Users, - [ - { id: 4, name: "Smith" }, - { id: 4, name: "Vasyl" }, - ], - true, -); -``` - -## SQL Utilities - -### formatLimitOffset - -The `formatLimitOffset` utility function is used to safely insert numeric values directly into SQL queries for LIMIT and OFFSET clauses. This is necessary because Atlassian Forge SQL doesn't support parameterized queries for these clauses. - -```typescript -import { formatLimitOffset } from "forge-sql-orm"; - -// Example usage in a query -const result = await forgeSQL - .select() - .from(orderItem) - .orderBy(asc(orderItem.createdAt)) - .limit(formatLimitOffset(10)) - .offset(formatLimitOffset(350000)); - -// The generated SQL will be: -// SELECT * FROM order_item -// ORDER BY created_at ASC -// LIMIT 10 -// OFFSET 350000 -``` - -**Important Notes:** - -- The function performs type checking to prevent SQL injection -- It throws an error if the input is not a valid number -- Use this function instead of direct parameter binding for LIMIT and OFFSET clauses -- The function is specifically designed to work with Atlassian Forge SQL's limitations - -**Security Considerations:** - -- The function includes validation to ensure the input is a valid number -- This prevents SQL injection by ensuring only numeric values are inserted -- Always use this function instead of string concatenation for LIMIT and OFFSET values - -## Optimistic Locking - -[↑ Back to Top](#table-of-contents) - -Optimistic locking is a concurrency control mechanism that prevents data conflicts when multiple transactions attempt to update the same record concurrently. Instead of using locks, this technique relies on a version field in your entity models. - -### Supported Version Field Types - -- `datetime` - Timestamp-based versioning -- `timestamp` - Timestamp-based versioning -- `integer` - Numeric version increment -- `decimal` - Numeric version increment - -### Configuration - -```typescript -const options = { - additionalMetadata: { - users: { - tableName: "users", - versionField: { - fieldName: "updatedAt", - }, - }, - }, -}; - -const forgeSQL = new ForgeSQL(options); -``` - -### Example Usage - -```typescript -// The version field will be automatically handled -await forgeSQL.modifyWithVersioning().updateById( - { - id: 1, - name: "Updated Name", - updatedAt: new Date(), // Will be automatically set if not provided - }, - Users, -); -``` - -With global cache, use `modifyWithVersioningAndEvictCache()` from [**forge-sql-orm-extra**](forge-sql-orm-extra/README.md). - -## ForgeSqlOrmOptions - -The `ForgeSqlOrmOptions` object allows customization of ORM behavior (core). Global cache options (`cacheEntityName`, `cacheTTL`, …) are documented in [**forge-sql-orm-extra**](forge-sql-orm-extra/README.md#forgesqlormoptions-cache). - -| Option | Type | Description | -| -------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `logRawSqlQuery` | `boolean` | Enables logging of raw SQL queries in the Atlassian Forge Developer Console. Useful for debugging and monitoring. Defaults to `false`. | -| `disableOptimisticLocking` | `boolean` | Disables optimistic locking. When set to `true`, no additional condition (e.g., a version check) is added during record updates, which can improve performance. However, this may lead to conflicts when multiple transactions attempt to update the same record concurrently. | -| `additionalMetadata` | `object` | Allows adding custom metadata to all entities. This is useful for tracking common fields across all tables (e.g., `createdAt`, `updatedAt`, `createdBy`, etc.). The metadata will be automatically added to all generated entities. | -| `hints` | `object` | SQL hints for query optimization. Optional configuration for advanced query tuning. | - -## CLI Commands - -Forge-SQL-ORM provides a command-line interface for managing database migrations and model generation. - -**📖 [Full CLI Documentation](forge-sql-orm-cli/README.md)** - Complete CLI reference with all commands and options. - -### Quick CLI Reference - -The CLI tool provides the following main commands: - -- `generate:model` - Generate Drizzle ORM models from your database schema -- `migrations:create` - Create new migration files -- `migrations:update` - Update existing migrations with schema changes -- `migrations:drop` - Create migration to drop tables -- `schema:create` - Apply schema directly from Drizzle models to database - -### Installation - -The CLI tool must be installed as a local dependency and used via npm scripts in your `package.json`: - -```bash -npm install forge-sql-orm-cli -D -``` - -### Setup npm Scripts - -Add the following scripts to your `package.json`: - -```bash -npm pkg set scripts.models:create="forge-sql-orm-cli generate:model --output src/entities --saveEnv" -npm pkg set scripts.migration:create="forge-sql-orm-cli migrations:create --force --output src/migration --entitiesPath src/entities" -npm pkg set scripts.migration:update="forge-sql-orm-cli migrations:update --entitiesPath src/entities --output src/migration" -npm pkg set scripts.schema:create="forge-sql-orm-cli schema:create --entitiesPath src/entities" -``` - -### Basic Usage - -After setting up the scripts, use them via npm: - -```bash -# Generate models from database -npm run models:create - -# Create migration -npm run migration:create - -# Update migration -npm run migration:update - -# Apply schema directly from Drizzle models -npm run schema:create -``` - -**Note:** The CLI tool is designed to work as a local dependency through npm scripts. Configuration is saved to `.env` file using the `--saveEnv` flag, so you only need to provide database credentials once. - -For detailed information about all available options and advanced usage, see the [Full CLI Documentation](forge-sql-orm-cli/README.md). - -## Web Triggers for Migrations - -Forge-SQL-ORM provides web triggers for managing database migrations in Atlassian Forge: - -### 1. Apply Migrations Trigger - -This trigger allows you to apply database migrations through a web endpoint. It's useful for: - -- Manually triggering migrations -- Running migrations as part of your deployment process -- Testing migrations in different environments - -```typescript -// Example usage in your Forge app -import { applySchemaMigrations } from "forge-sql-orm"; -import migration from "./migration"; - -export const handlerMigration = async () => { - return applySchemaMigrations(migration); -}; -``` - -Configure in `manifest.yml`: - -```yaml -webtrigger: - - key: invoke-schema-migration - function: runSchemaMigration - security: - egress: - allowDataEgress: false - allowedResponses: - - statusCode: 200 - body: '{"body": "Migrations successfully executed"}' -sql: - - key: main - engine: mysql -function: - - key: runSchemaMigration - handler: index.handlerMigration -``` - -### 2. Drop Migrations Trigger - -⚠️ **WARNING**: This trigger will permanently delete all data in the specified tables and clear the migrations history. This operation cannot be undone! - -This trigger allows you to completely reset your database schema. It's useful for: - -- Development environments where you need to start fresh -- Testing scenarios requiring a clean database -- Resetting the database before applying new migrations - -**Important**: The trigger will drop all tables including migration. - -```typescript -// Example usage in your Forge app -import { dropSchemaMigrations } from "forge-sql-orm"; - -export const dropMigrations = () => { - return dropSchemaMigrations(); -}; -``` - -Configure in `manifest.yml`: - -```yaml -webtrigger: - - key: drop-schema-migration - function: dropMigrations -sql: - - key: main - engine: mysql -function: - - key: dropMigrations - handler: index.dropMigrations -``` - -### 3. Fetch Schema Trigger - -⚠️ **DEVELOPMENT ONLY**: This trigger is designed for development environments only and should not be used in production. - -This trigger retrieves the current database schema from Atlassian Forge SQL and generates SQL statements that can be used to recreate the database structure. It's useful for: - -- Development environment setup -- Schema documentation -- Database structure verification -- Creating backup scripts - -**Security Considerations**: - -- This trigger exposes your database structure -- It temporarily disables foreign key checks -- It may expose sensitive table names and structures -- Should only be used in development environments - -```typescript -// Example usage in your Forge app -import { fetchSchemaWebTrigger } from "forge-sql-orm"; - -export const fetchSchema = async () => { - return fetchSchemaWebTrigger(); -}; -``` - -Configure in `manifest.yml`: - -```yaml -webtrigger: - - key: fetch-schema - function: fetchSchema -sql: - - key: main - engine: mysql -function: - - key: fetchSchema - handler: index.fetchSchema -``` - -The response will contain SQL statements like: - -```sql -SET foreign_key_checks = 0; -CREATE TABLE IF NOT EXISTS users (...); -CREATE TABLE IF NOT EXISTS orders (...); -SET foreign_key_checks = 1; -``` - -### 4. Clear Cache Scheduler Trigger - -Requires [**forge-sql-orm-extra**](forge-sql-orm-extra/README.md) and `@forge/kvs`. See [Setting Up Caching](forge-sql-orm-extra/README.md#setting-up-caching-with-forgekvs) for `clearCacheSchedulerTrigger`, manifest configuration, and when to enable the scheduler. - -### 5. Slow Query Scheduler Trigger - -This scheduler trigger automatically monitors and analyzes slow queries on a scheduled basis. For detailed information, see the [Slow Query Monitoring](#slow-query-monitoring) section. - -**Quick Setup:** - -```typescript -import ForgeSQL, { slowQuerySchedulerTrigger } from "forge-sql-orm"; - -const forgeSQL = new ForgeSQL(); - -export const slowQueryTrigger = () => - slowQuerySchedulerTrigger(forgeSQL, { hours: 1, timeout: 3000 }); -``` - -Configure in `manifest.yml`: - -```yaml -scheduledTrigger: - - key: slow-query-trigger - function: slowQueryTrigger - interval: hour -function: - - key: slowQueryTrigger - handler: index.slowQueryTrigger -``` - -> **💡 Note**: For complete documentation, examples, and configuration options, see the [Slow Query Monitoring](#slow-query-monitoring) section. - -### Important Notes - -**Security Considerations**: - -- The drop migrations trigger should be restricted to development environments -- The fetch schema trigger should only be used in development -- Consider implementing additional authentication for these endpoints - -**Best Practices**: - -- Always backup your data before using the drop migrations trigger -- Test migrations in a development environment first -- Use these triggers as part of your deployment pipeline -- Monitor the execution logs in the Forge Developer Console - -## Query Analysis and Performance Optimization - -[↑ Back to Top](#table-of-contents) - -Forge-SQL-ORM provides comprehensive query analysis tools to help you optimize your database queries and identify performance bottlenecks. - -### About Atlassian's Built-in Analysis Tools - -Atlassian provides comprehensive query analysis tools in the development console, including: - -- Basic query performance metrics -- Slow query tracking (queries over 500ms) -- Basic execution statistics -- Query history and patterns - -Our analysis tools complement these built-in features by providing additional insights directly from TiDB's system schemas. - -### Automatic Error Analysis - -Forge-SQL-ORM automatically intercepts and analyzes critical query errors to help you diagnose performance issues. When a query fails due to **timeout** or **out-of-memory** errors, the library automatically: - -1. **Detects the error type** (SQL_QUERY_TIMEOUT or Out of Memory) -2. **Logs detailed error information** to the Forge Developer Console -3. **Waits for system tables to populate** (200ms delay) -4. **Retrieves and logs the execution plan** for the failed query -5. **Provides performance metrics** including memory usage, execution time, and query details - -This automatic analysis happens transparently - no additional code is required on your part. - -#### Supported Error Types - -- **SQL_QUERY_TIMEOUT**: Queries that exceed the execution time limit -- **Out of Memory (OOM)**: Queries that exceed the 16 MiB memory limit (errno: 8175) - -#### Example Console Output - -When a query fails, you'll see output like this in the Forge Developer Console: - -``` -❌ TIMEOUT detected - Query exceeded time limit -⏳ Waiting 200ms for CLUSTER_STATEMENTS_SUMMARY to populate... -📊 Analyzing query performance and execution plan... -⏱️ Query duration: 10500ms - -SQL: SELECT * FROM users u INNER JOIN orders o ON u.id = o.user_id WHERE u.active = ? | Memory: 12.45 MB | Time: 10500.00 ms | stmtType: Select | Executions: 1 - Plan: -id task estRows operator info actRows execution info memory disk -Projection_7 root 1000.00 forge_38dd1c6156b94bb59c2c9a45582bbfc7.users.id, ... 1000 time:10.5s, loops:1 12.45 MB N/A -└─IndexHashJoin_14 root 1000.00 inner join, ... 1000 time:10.2s, loops:1 11.98 MB N/A -``` - -#### How It Works - -The error analysis mechanism: - -1. **Error Detection**: When a query fails, the driver proxy checks the error code/errno -2. **Error Logging**: Logs the specific error type to console.error -3. **Data Population Wait**: Waits 200ms for TiDB's `CLUSTER_STATEMENTS_SUMMARY` table to be populated with the failed query's metadata -4. **Query Analysis**: Automatically calls `printQueriesWithPlan()` to retrieve and display: - - SQL query text - - Memory consumption (average and max in MB) - - Execution time (average in ms) - - Statement type - - Number of executions - - Detailed execution plan - -#### Benefits - -- **Zero Configuration**: Works automatically - no setup required -- **Immediate Insights**: Get execution plans for failed queries instantly -- **Performance Debugging**: Identify bottlenecks without manual investigation -- **Development Console Integration**: All logs appear in Atlassian Forge Developer Console -- **No Code Changes**: Existing code automatically benefits from error analysis - -> **💡 Tip**: The automatic error analysis only triggers for timeout and OOM errors. Other errors are logged normally without plan analysis. - -### Resolver-Level Performance Monitoring - -The `executeWithMetadata()` method provides resolver-level profiling with configurable query plan printing. It aggregates metrics across all database operations within a resolver and supports two modes for query plan analysis. - -#### Basic Usage - -```typescript -const result = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - const orders = await forgeSQL - .selectFrom(ordersTable) - .where(eq(ordersTable.userId, usersTable.id)); - return { users, orders }; - }, - async (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - const threshold = 500; // ms baseline for this resolver - - if (totalDbExecutionTime > threshold * 1.5) { - console.warn(`[Performance Warning] Resolver exceeded DB time: ${totalDbExecutionTime} ms`); - await printQueriesWithPlan(); // Analyze and print query execution plans - } else if (totalDbExecutionTime > threshold) { - console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`); - } - - console.log(`DB response size: ${totalResponseSize} bytes`); - }, -); -``` - -#### Query Plan Printing Options - -The `printQueriesWithPlan` function supports two modes, configurable via the optional `options` parameter: - -**1. TopSlowest Mode (default)**: Prints execution plans for the slowest queries from the current resolver invocation - -```typescript -// Full configuration example -const result = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - return users; - }, - async (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - if (totalDbExecutionTime > 1000) { - await printQueriesWithPlan(); // Will print top 3 slowest queries with execution plans - } - }, - { - mode: "TopSlowest", // Print top slowest queries (default) - topQueries: 3, // Number of top slowest queries to analyze (default: 1) - showSlowestPlans: true, // Show execution plans (default: true) - }, -); - -// Minimal configuration - only specify what you need -const result2 = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - return users; - }, - async (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - if (totalDbExecutionTime > 1000) { - await printQueriesWithPlan(); // Will print top 3 slowest queries (all other options use defaults) - } - }, - { - topQueries: 3, // Only specify topQueries, mode and showSlowestPlans use defaults - }, -); - -// Disable execution plans - only show SQL and execution time -const result3 = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - return users; - }, - async (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - if (totalDbExecutionTime > 1000) { - await printQueriesWithPlan(); // Will print SQL and time only, no execution plans - } - }, - { - showSlowestPlans: false, // Disable execution plan printing - }, -); - -// Use all defaults - pass empty object or omit options parameter -const result4 = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - return users; - }, - async (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - if (totalDbExecutionTime > 1000) { - await printQueriesWithPlan(); // Uses all defaults: TopSlowest mode, topQueries: 1, showSlowestPlans: true - } - }, - {}, // Empty object - all options use defaults -); -``` - -<|tool▁calls▁begin|><|tool▁call▁begin|> -read_file - -**2. SummaryTable Mode**: Uses `CLUSTER_STATEMENTS_SUMMARY` for query analysis - -```typescript -const result = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - return users; - }, - async (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - if (totalDbExecutionTime > 1000) { - await printQueriesWithPlan(); // Will use CLUSTER_STATEMENTS_SUMMARY if within time window - } - }, - { - mode: "SummaryTable", // Use SummaryTable mode - summaryTableWindowTime: 10000, // Time window in milliseconds (default: 15000ms) - }, -); -``` - -#### Configuration Options - -All options are **optional**. If not specified, default values are used. You can pass only the options you need to customize. - -| Option | Type | Default | Description | -| ------------------------ | -------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mode` | `'TopSlowest' \| 'SummaryTable'` | `'TopSlowest'` | Query plan printing mode. `'TopSlowest'` prints execution plans for the slowest queries from the current resolver. `'SummaryTable'` uses `CLUSTER_STATEMENTS_SUMMARY` when within time window | -| `summaryTableWindowTime` | `number` | `15000` | Time window in milliseconds for summary table queries. Only used when `mode` is `'SummaryTable'` | -| `topQueries` | `number` | `1` | Number of top slowest queries to analyze when `mode` is `'TopSlowest'` | -| `showSlowestPlans` | `boolean` | `true` | Whether to show execution plans for slowest queries in TopSlowest mode. If `false`, only SQL and execution time are printed | -| `normalizeQuery` | `boolean` | `true` | When `true`, slow-query output uses `normalizationSQL()` (regex-based in core). Set to `false` to log raw SQL if normalization causes issues with complex queries | -| `asyncQueueName` | `string` | `""` | Queue name for async processing. If provided, query analysis will be queued for background processing instead of running synchronously. Requires consumer configuration in `manifest.yml` | - -**Examples:** - -```typescript -// Use all defaults - omit options or pass empty object -await forgeSQL.executeWithMetadata(queryFn, onMetadataFn); // or { } - -// Customize only what you need -await forgeSQL.executeWithMetadata(queryFn, onMetadataFn, { topQueries: 3 }); -await forgeSQL.executeWithMetadata(queryFn, onMetadataFn, { mode: "SummaryTable" }); -await forgeSQL.executeWithMetadata(queryFn, onMetadataFn, { showSlowestPlans: false }); -await forgeSQL.executeWithMetadata(queryFn, onMetadataFn, { normalizeQuery: false }); // Disable query normalization - -// Combine multiple options -await forgeSQL.executeWithMetadata(queryFn, onMetadataFn, { - mode: "TopSlowest", - topQueries: 5, - showSlowestPlans: false, - normalizeQuery: true, // Enable query normalization (default) -}); -``` - -#### How It Works - -1. **TopSlowest Mode** (default): - - Collects all queries executed within the resolver - - Sorts them by execution time (slowest first) - - Prints execution plans for the top N queries (configurable via `topQueries`) - - If `showSlowestPlans` is `false`, only prints SQL and execution time without plans - - Works immediately after query execution - -2. **SummaryTable Mode**: - - Attempts to use `CLUSTER_STATEMENTS_SUMMARY` for query analysis - - Only works if queries are executed within the specified time window (`summaryTableWindowTime`) - - If the time window expires, falls back to TopSlowest mode - - Provides aggregated statistics from TiDB's system tables - -#### SQL normalization (`normalizationSQL`) - -When `normalizeQuery` is `true` (default), SQL printed by `printQueriesWithPlan()` is passed through `forgeSQL.normalizationSQL(sql)` so queries with different literal values collapse to the same shape (for example `WHERE id = 42` and `WHERE id = 7` both become `WHERE id = ?`). - -**Core (`forge-sql-orm`)** — regex-based normalization (`normalizeSqlForLoggingRegex`): - -- Lightweight, no extra dependencies -- Replaces string, numeric, boolean, and `NULL` literals with `?` -- Does not handle escaped quotes inside string literals (`''`); use `normalizeQuery: false` for those edge cases - -```typescript -forgeSQL.normalizationSQL("SELECT * FROM users WHERE id = 42 AND name = 'Alice'"); -// SELECT * FROM users WHERE id = ? AND name = ? -``` - -You can call `normalizationSQL` directly for custom logging or metrics: - -```typescript -const key = forgeSQL.normalizationSQL(rawSql); -``` - -**With `forge-sql-orm-extra`**, the same method uses `node-sql-parser` to canonicalize SQL structure first, then applies regex for literals — better for complex queries. See [forge-sql-orm-extra README](./forge-sql-orm-extra/README.md#sql-normalization-normalizationsql). - -#### Example: Real-World Resolver - -```typescript -resolver.define("fetch", async (req: Request) => { - try { - return await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(demoUsers); - const orders = await forgeSQL - .selectFrom(demoOrders) - .where(eq(demoOrders.userId, demoUsers.id)); - return { users, orders }; - }, - async (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - const threshold = 500; // ms baseline for this resolver - - if (totalDbExecutionTime > threshold * 1.5) { - console.warn( - `[Performance Warning fetch] Resolver exceeded DB time: ${totalDbExecutionTime} ms`, - ); - await printQueriesWithPlan(); // Analyze and print query execution plans - } else if (totalDbExecutionTime > threshold) { - console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`); - } - }, - { - mode: "TopSlowest", // Print top slowest queries (default) - topQueries: 2, // Print top 2 slowest queries - }, - ); - } catch (e) { - const error = e?.cause?.debug?.sqlMessage ?? e?.cause; - console.error(error, e); - throw error; - } -}); -``` - -#### Benefits - -- **Resolver-Level Profiling**: Aggregates metrics across all database operations in a resolver -- **Configurable Analysis**: Choose between TopSlowest mode or SummaryTable mode -- **Automatic Plan Formatting**: Execution plans are formatted in a readable format -- **Performance Thresholds**: Set custom thresholds for performance warnings -- **Zero Configuration**: Works out of the box with sensible defaults - -> **💡 Tip**: When multiple resolvers are running concurrently, their query data may also appear in `printQueriesWithPlan()` analysis when using SummaryTable mode, as it queries the global `CLUSTER_STATEMENTS_SUMMARY` table. - -### Async Query Degradation Analysis - -Forge-SQL-ORM supports asynchronous processing of query degradation analysis, allowing you to offload performance analysis to a background queue. This is particularly useful for production environments where you want to avoid blocking resolver responses while still capturing detailed performance metrics. - -#### Key Features - -- **Non-Blocking Analysis**: Query analysis runs asynchronously without blocking resolver responses -- **Automatic Fallback**: Falls back to synchronous execution if async queue fails -- **Log Correlation**: Job IDs help correlate resolver logs with consumer logs -- **Queue-Based Processing**: Uses Forge's event queue system for reliable processing -- **Configurable Timeout**: Customizable timeout for event queuing (default: 1200ms) - -#### Basic Setup - -**1. Configure consumer in `manifest.yml`:** - -```yaml -modules: - consumer: - - key: print-degradation-queries - queue: degradationQueue - function: handlerAsyncDegradation - - function: - - key: handlerAsyncDegradation - handler: index.handlerAsyncDegradation -``` - -**2. Create the handler function:** - -```typescript -import { AsyncEvent } from "@forge/events"; -import { printDegradationQueriesConsumer } from "forge-sql-orm"; -import { FORGE_SQL_ORM } from "./utils/forgeSqlOrmUtils"; - -export const handlerAsyncDegradation = (event: AsyncEvent) => { - return printDegradationQueriesConsumer(FORGE_SQL_ORM, event); -}; -``` - -**3. Enable async processing in resolver:** - -```typescript -resolver.define("fetch", async (req: Request) => { - return await FORGE_SQL_ORM.executeWithMetadata( - async () => { - // ... your queries ... - return await SQL_QUERY; - }, - async (totalDbExecutionTime, totalResponseSize, printQueries) => { - if (totalDbExecutionTime > 800) { - await printQueries(); // Will queue for async processing - } - }, - { asyncQueueName: "degradationQueue" }, // Enable async processing - ); -}); -``` - -#### Configuration Options - -The `asyncQueueName` option enables async processing: - -| Option | Type | Default | Description | -| ---------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `asyncQueueName` | `string` | `""` | Queue name for async processing. If provided, query analysis will be queued instead of running synchronously. If empty or not provided, runs synchronously | - -#### How It Works - -1. **Resolver Execution**: When `printQueriesWithPlan()` is called with `asyncQueueName` configured: - - Creates an event payload with query statistics and metadata - - Sends event to the specified queue with a timeout (default: 1200ms) - - Logs a warning message with Job ID for correlation - - Returns immediately without waiting for analysis - -2. **Async Processing**: The consumer function (`handlerAsyncDegradation`): - - Receives the event from the queue - - Logs processing start with Job ID - - Executes query analysis (TopSlowest or SummaryTable mode) - - Prints execution plans and performance metrics - -3. **Fallback Behavior**: If queue push fails or times out: - - Falls back to synchronous execution automatically - - Logs a warning message - - Analysis still completes, just synchronously - -#### Log Correlation - -Both resolver and consumer logs include Job IDs to help you correlate related events: - -**Resolver log (when event is queued):** - -``` -WARN [Performance Analysis] Query degradation event queued for async processing | Job ID: abc-123 | Total DB time: 3531ms | Queries: 3 | Look for consumer log with jobId: abc-123 -``` - -**Consumer log (when event is processed):** - -``` -WARN [Performance Analysis] Processing query degradation event | Job ID: abc-123 | Total DB time: 3531ms | Queries: 3 | Started: 2025-12-15T18:12:34.251Z -WARN SQL: SELECT ... | Time: 3514 ms - Plan: - Projection_7 | task:root | ... -``` - -**To find all related logs:** - -- Search logs for: `"Job ID: abc-123"` -- This will show both the queuing event and the processing event - -#### Example: Complete Setup - -**manifest.yml:** - -```yaml -modules: - consumer: - - key: print-degradation-queries - queue: degradationQueue - function: handlerAsyncDegradation - - function: - - key: handlerAsyncDegradation - handler: index.handlerAsyncDegradation -``` - -**index.ts:** - -```typescript -import { AsyncEvent } from "@forge/events"; -import { printDegradationQueriesConsumer } from "forge-sql-orm"; -import { FORGE_SQL_ORM } from "./utils/forgeSqlOrmUtils"; - -// Consumer handler -export const handlerAsyncDegradation = (event: AsyncEvent) => { - return printDegradationQueriesConsumer(FORGE_SQL_ORM, event); -}; - -// Resolver with async analysis -resolver.define("fetch", async (req: Request) => { - return await FORGE_SQL_ORM.executeWithMetadata( - async () => { - const users = await FORGE_SQL_ORM.selectFrom(demoUsers); - const orders = await FORGE_SQL_ORM.selectFrom(demoOrders); - return { users, orders }; - }, - async (totalDbExecutionTime, totalResponseSize, printQueries) => { - const threshold = 800; // ms baseline - - if (totalDbExecutionTime > threshold) { - console.warn(`[Performance Warning] Resolver exceeded DB time: ${totalDbExecutionTime} ms`); - await printQueries(); // Queued for async processing - } - }, - { - asyncQueueName: "degradationQueue", // Enable async processing - mode: "TopSlowest", - topQueries: 1, - }, - ); -}); -``` - -#### Benefits - -- **Non-Blocking**: Resolver responses are not delayed by query analysis -- **Production Ready**: Suitable for production environments where performance is critical -- **Reliable**: Automatic fallback ensures analysis always completes -- **Traceable**: Job IDs enable easy log correlation -- **Scalable**: Queue-based processing handles high load scenarios - -#### When to Use Async Processing - -**Use async processing when:** - -- You're in a production environment -- Resolver response time is critical -- You want to avoid blocking user requests -- You need detailed analysis but can process it later - -**Use synchronous processing when:** - -- You're in development/debugging -- You need immediate analysis results -- You want simpler setup (no queue configuration) - -> **💡 Tip**: The async queue name must match the queue name configured in your `manifest.yml` consumer section. If the queue doesn't exist or the event fails to send, the system automatically falls back to synchronous execution. - -### Slow Query Monitoring - -Forge-SQL-ORM provides a scheduler trigger (`slowQuerySchedulerTrigger`) that automatically monitors and analyzes slow queries on an hourly basis. This trigger queries TiDB's slow query log system table and provides detailed performance information including SQL query text, memory usage, execution time, and execution plans. - -#### Key Features - -- **Automatic Monitoring**: Runs on a scheduled interval (recommended: hourly) -- **Detailed Performance Metrics**: Memory usage, execution time, and execution plans -- **Console Logging**: Results are automatically logged to the Forge Developer Console -- **Configurable Time Window**: Analyze queries from the last N hours (default: 1 hour) -- **Automatic Plan Retrieval**: Execution plans are included for all slow queries - -#### Basic Setup - -**1. Create the trigger function:** - -```typescript -import ForgeSQL, { slowQuerySchedulerTrigger } from "forge-sql-orm"; - -const forgeSQL = new ForgeSQL(); - -// Monitor slow queries from the last hour (recommended for hourly schedule) -export const slowQueryTrigger = () => - slowQuerySchedulerTrigger(forgeSQL, { hours: 1, timeout: 3000 }); -``` - -**2. Configure in `manifest.yml`:** - -```yaml -modules: - scheduledTrigger: - - key: slow-query-trigger - function: slowQueryTrigger - interval: hour # Run every hour - - function: - - key: slowQueryTrigger - handler: index.slowQueryTrigger -``` - -#### Configuration Options - -| Option | Type | Default | Description | -| --------- | -------- | ------- | ---------------------------------------------------------- | -| `hours` | `number` | `1` | Number of hours to look back for slow queries | -| `timeout` | `number` | `3000` | Timeout in milliseconds for the diagnostic query execution | - -#### Example Console Output - -When slow queries are detected, you'll see output like this in the Forge Developer Console: - -``` -Found SlowQuery SQL: SELECT * FROM users u INNER JOIN orders o ON u.id = o.user_id WHERE u.active = ? | Memory: 8.50 MB | Time: 2500.00 ms - Plan: -id task estRows operator info actRows execution info memory disk -Projection_7 root 1000.00 forge_38dd1c6156b94bb59c2c9a45582bbfc7.users.id, ... 1000 time:2.5s, loops:1 8.50 MB N/A -└─IndexHashJoin_14 root 1000.00 inner join, ... 1000 time:2.2s, loops:1 7.98 MB N/A - -Found SlowQuery SQL: SELECT * FROM products WHERE category = ? ORDER BY created_at DESC | Memory: 6.25 MB | Time: 1800.00 ms - Plan: -... -``` - -#### Advanced Configuration - -```typescript -import ForgeSQL, { slowQuerySchedulerTrigger } from "forge-sql-orm"; - -const forgeSQL = new ForgeSQL(); - -// Monitor queries from the last 6 hours (for less frequent checks) -export const sixHourSlowQueryTrigger = () => - slowQuerySchedulerTrigger(forgeSQL, { hours: 6, timeout: 5000 }); - -// Monitor queries from the last 24 hours (daily monitoring) -export const dailySlowQueryTrigger = () => - slowQuerySchedulerTrigger(forgeSQL, { hours: 24, timeout: 3000 }); -``` - -#### How It Works - -1. **Scheduled Execution**: The trigger runs automatically on the configured interval (hourly recommended) -2. **Query Analysis**: Queries TiDB's slow query log system table for queries executed within the specified time window -3. **Performance Metrics**: Extracts and logs: - - SQL query text (sanitized for readability) - - Maximum memory usage (in MB) - - Query execution time (in ms) - - Detailed execution plan -4. **Console Logging**: Results are logged to the Forge Developer Console via `console.warn()` for easy monitoring - -#### Best Practices - -- **Hourly Intervals**: Use `interval: hour` for timely detection of slow queries -- **Default Time Window**: 1 hour is recommended for hourly schedules to avoid overlap -- **Monitor Regularly**: Check console logs regularly to identify patterns in slow queries - -#### Benefits - -- **Proactive Monitoring**: Catch slow queries before they become critical issues -- **Performance Trends**: Track query performance over time -- **Optimization Insights**: Execution plans help identify optimization opportunities -- **Zero Manual Intervention**: Fully automated monitoring with scheduled execution -- **Production Safe**: Works silently in the background, only logs when slow queries are found - -> **💡 Tip**: The trigger queries up to 50 slow queries to prevent excessive logging. Transient timeouts are usually fine; repeated timeouts indicate the diagnostic query itself is slow and should be investigated. - -### Available Analysis Tools - -```typescript -import ForgeSQL from "forge-sql-orm"; - -const forgeSQL = new ForgeSQL(); -const analyzeForgeSql = forgeSQL.analyze(); -``` - -#### Query Plan Analysis - -Query plan analysis helps you understand how your queries are executed and identify optimization opportunities. - -```typescript -// Example usage for analyzing a specific query -const forgeSQL = new ForgeSQL(); -const analyzeForgeSql = forgeSQL.analyze(); - -// Analyze a Drizzle query -const plan = await analyzeForgeSql.explain( - forgeSQL - .select({ - table1: testEntityJoin1, - table2: { name: testEntityJoin2.name, email: testEntityJoin2.email }, - count: rawSql`COUNT(*)`, - table3: { - table12: testEntityJoin1.name, - table22: testEntityJoin2.email, - table32: testEntity.id, - }, - }) - .from(testEntityJoin1) - .innerJoin(testEntityJoin2, eq(testEntityJoin1.id, testEntityJoin2.id)), -); - -// Analyze a raw SQL query -const rawPlan = await analyzeForgeSql.explainRaw("SELECT * FROM users WHERE id = ?", [1]); - -// Analyze new methods -const usersFromPlan = await analyzeForgeSql.explain( - forgeSQL.selectFrom(users).where(eq(users.active, true)), -); - -// Analyze Common Table Expressions (CTEs) -const ctePlan = await analyzeForgeSql.explain( - forgeSQL - .with( - forgeSQL.selectFrom(users).where(eq(users.active, true)).as("activeUsers"), - forgeSQL.selectFrom(orders).where(eq(orders.status, "completed")).as("completedOrders"), - ) - .select({ - totalActiveUsers: sql`COUNT(au.id)`, - totalCompletedOrders: sql`COUNT(co.id)`, - }) - .from(sql`activeUsers au`) - .leftJoin(sql`completedOrders co`, eq(sql`au.id`, sql`co.userId`)), -); -``` - -This analysis provides insights into: - -- How the database executes your query -- Which indexes are being used -- Estimated vs actual row counts -- Resource usage at each step -- Performance optimization opportunities - -## Migration Guide - -### Migrating from 2.0.x to 2.1.x - -This section covers the breaking changes introduced in version 2.1.x and how to migrate your existing code. - -#### 1. Method Renaming (BREAKING CHANGES) - -**Removed Methods:** - -- `forgeSQL.modify()` → **REMOVED** (use `forgeSQL.modifyWithVersioning()`) -- `forgeSQL.crud()` → **REMOVED** (use `forgeSQL.modifyWithVersioning()`) - -**Migration Steps:** - -1. **Replace `modify()` calls:** - - ```typescript - // ❌ Old (2.0.x) - NO LONGER WORKS - await forgeSQL.modify().insert(Users, [userData]); - await forgeSQL.modify().updateById(updateData, Users); - await forgeSQL.modify().deleteById(1, Users); - - // ✅ New (2.1.x) - REQUIRED - await forgeSQL.modifyWithVersioning().insert(Users, [userData]); - await forgeSQL.modifyWithVersioning().updateById(updateData, Users); - await forgeSQL.modifyWithVersioning().deleteById(1, Users); - ``` - -2. **Replace `crud()` calls:** - - ```typescript - // ❌ Old (2.0.x) - NO LONGER WORKS - await forgeSQL.crud().insert(Users, [userData]); - await forgeSQL.crud().updateById(updateData, Users); - await forgeSQL.crud().deleteById(1, Users); - - // ✅ New (2.1.x) - REQUIRED - await forgeSQL.modifyWithVersioning().insert(Users, [userData]); - await forgeSQL.modifyWithVersioning().updateById(updateData, Users); - await forgeSQL.modifyWithVersioning().deleteById(1, Users); - ``` - -#### 2. New API Methods - -**New Methods Available:** - -- `forgeSQL.insert()` - Basic Drizzle operations -- `forgeSQL.update()` - Basic Drizzle operations -- `forgeSQL.delete()` - Basic Drizzle operations -- `forgeSQL.selectFrom()` - All-column queries with field aliasing -- `forgeSQL.selectDistinctFrom()` - Distinct all-column queries with field aliasing -- `forgeSQL.execute()` - Raw SQL queries with local caching -- Global cache methods (`insertAndEvictCache`, `selectCacheableFrom`, `executeCacheable`, …) — [**forge-sql-orm-extra**](forge-sql-orm-extra/README.md) -- `forgeSQL.executeDDL()` - DDL operations (CREATE, ALTER, DROP, etc.) -- `forgeSQL.executeDDLActions()` - Execute actions within DDL operation context -- `forgeSQL.with()` - Common Table Expressions (CTEs) - -**Optional Migration:** -You can optionally migrate to the new API methods for better performance and cache management: - -```typescript -// ❌ Old approach (still works) -await forgeSQL.modifyWithVersioning().insert(Users, [userData]); - -// ✅ New approach (recommended for new code) -await forgeSQL.insert(Users).values(userData); -// ✅ New query methods for better performance -const users = await forgeSQL.selectFrom(Users).where(eq(Users.active, true)); - -const usersDistinct = await forgeSQL.selectDistinctFrom(Users).where(eq(Users.active, true)); - -// ✅ Raw SQL execution with local caching -const rawUsers = await forgeSQL.execute("SELECT * FROM users WHERE active = ?", [true]); - -// Global cache: use forge-sql-orm-extra — see forge-sql-orm-extra/README.md - -// ✅ Raw SQL execution with metadata capture and performance monitoring -const usersWithMetadata = await forgeSQL.executeWithMetadata( - async () => { - const users = await forgeSQL.selectFrom(usersTable); - const orders = await forgeSQL - .selectFrom(ordersTable) - .where(eq(ordersTable.userId, usersTable.id)); - return { users, orders }; - }, - (totalDbExecutionTime, totalResponseSize, printQueriesWithPlan) => { - const threshold = 500; // ms baseline for this resolver - - if (totalDbExecutionTime > threshold * 1.5) { - console.warn(`[Performance Warning] Resolver exceeded DB time: ${totalDbExecutionTime} ms`); - await printQueriesWithPlan(); // Analyze and print query execution plans - } else if (totalDbExecutionTime > threshold) { - console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`); - } - - console.log(`DB response size: ${totalResponseSize} bytes`); - }, - { - // Optional: Configure query plan printing - mode: "TopSlowest", // Print top slowest queries (default) - topQueries: 1, // Print top slowest query - }, -); - -// ✅ DDL operations for schema modifications -await forgeSQL.executeDDL(` - CREATE TABLE users ( - id INT PRIMARY KEY AUTO_INCREMENT, - name VARCHAR(255) NOT NULL, - email VARCHAR(255) UNIQUE - ) -`); - -await forgeSQL.executeDDL(sql` - ALTER TABLE users - ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -`); - -// ✅ Execute regular SQL queries in DDL context for performance monitoring -await forgeSQL.executeDDLActions(async () => { - // Execute regular SQL queries in DDL context for monitoring - const slowQueries = await forgeSQL.execute(` - SELECT * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY - WHERE AVG_LATENCY > 1000000 - `); - - // Execute complex analysis queries in DDL context - const performanceData = await forgeSQL.execute(` - SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY_HISTORY - WHERE SUMMARY_END_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR) - `); - - return { slowQueries, performanceData }; -}); - -// ✅ Common Table Expressions (CTEs) -const userStats = await forgeSQL - .with( - forgeSQL.selectFrom(users).where(eq(users.active, true)).as("activeUsers"), - forgeSQL.selectFrom(orders).where(eq(orders.status, "completed")).as("completedOrders"), - ) - .select({ - totalActiveUsers: sql`COUNT(au.id)`, - totalCompletedOrders: sql`COUNT(co.id)`, - }) - .from(sql`activeUsers au`) - .leftJoin(sql`completedOrders co`, eq(sql`au.id`, sql`co.userId`)); -``` - -#### 3. Automatic Migration Script - -You can use a simple find-and-replace to migrate your code: - -```bash -# Replace modify() calls -find . -name "*.ts" -o -name "*.js" | xargs sed -i 's/forgeSQL\.modify()/forgeSQL.modifyWithVersioning()/g' - -# Replace crud() calls -find . -name "*.ts" -o -name "*.js" | xargs sed -i 's/forgeSQL\.crud()/forgeSQL.modifyWithVersioning()/g' -``` - -### Migrating from 2.1.x to 2.2.x - -Starting with **2.2.x**, the library is split into two packages to keep the core smaller and reduce dependencies for apps that do not need global cache or Rovo. - -#### 1. Understand the package split - -| Package | Install | Use when | -| ----------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| **forge-sql-orm** | `npm install forge-sql-orm @forge/sql drizzle-orm -S` | Drizzle + `@forge/sql`, **Level 1 local cache**, migrations, optimistic locking (no L2 KVS) | -| **forge-sql-orm-extra** | `npm install forge-sql-orm-extra @forge/kvs -S` | **Level 2** global KVS cache, Rovo — L1 still from core; see [extra README](forge-sql-orm-extra/README.md) | - -#### 2. Stay on core if you do not use L2 or Rovo - -**If you did not use global cache (L2) or Rovo:** nothing changes. Keep: - -```typescript -import ForgeSQL from "forge-sql-orm"; -``` - -Local cache (`executeWithLocalCacheContext`, `selectFrom`, `execute`, …) stays on core. - -#### 3. Add the extension package (L2 cache or Rovo only) - -**If you used Level 2 global cache** (`cacheEntityName`, `selectCacheable*`, `executeCacheable`, `*AndEvictCache`, `executeWithCacheContext`, …) **or Rovo** (`forgeSQL.rovo()`): - -```bash -npm install forge-sql-orm-extra @forge/kvs -S -``` - -Core dependencies (`forge-sql-orm`, `@forge/sql`, `drizzle-orm`) stay as before. Level 1 local cache alone does **not** require extra. - -#### 4. Change the import - -```typescript -// ❌ Before (2.1.x monolith) -import ForgeSQL from "forge-sql-orm"; - -// ✅ After (2.2.x with cache or Rovo) -import ForgeSQL from "forge-sql-orm-extra"; -``` - -The rest of your logic stays the same — options, method names, and call patterns are unchanged. - -#### 5. Keep existing options and calls - -```typescript -const forgeSQL = new ForgeSQL({ - cacheEntityName: "cache", - cacheTTL: 300, -}); - -const users = await forgeSQL - .selectCacheable({ id: users.id, name: users.name }) - .from(users) - .where(eq(users.active, true)); -``` - -#### 6. Update imports for helpers that moved with cache - -If you use web triggers or utilities that moved to the extension package, update their import path, for example: - -```typescript -// ❌ Before -import { clearCacheSchedulerTrigger } from "forge-sql-orm"; - -// ✅ After -import { clearCacheSchedulerTrigger } from "forge-sql-orm-extra"; -``` - -See [forge-sql-orm-extra README](forge-sql-orm-extra/README.md) for the full list of cache and Rovo APIs. - -## License - -This project is licensed under the **MIT License**. -Feel free to use it for commercial and personal projects. diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md deleted file mode 100644 index 5a56bfadf..000000000 --- a/REQUIREMENTS.md +++ /dev/null @@ -1,339 +0,0 @@ -# Product Requirements — Forge SQL ORM - -This document defines **what** Forge SQL ORM must deliver and **which platform limits** it must respect. It complements: - -| Artifact | Role | -| ---------------------------------------------------------------------- | --------------------------------------------------------------------------- | -| [README.md](README.md) | User-facing feature documentation and API usage (canonical feature catalog) | -| [forge-sql-orm-extra/README.md](forge-sql-orm-extra/README.md) | Extended ORM package — global cache, Rovo, and related APIs | -| [CHANGELOG.md](CHANGELOG.md) | Version history and breaking-change notes | -| [CONTRIBUTING.md](CONTRIBUTING.md) | Contributor process and quality gates | -| [GitHub Issues](https://github.com/forge-sql-orm/forge-sql-orm/issues) | Bug reports, feature requests, and traceability | -| [forge-sql-orm-cli/README.md](forge-sql-orm-cli/README.md) | CLI-specific behavior | - -Official Atlassian references: - -- [Forge SQL](https://developer.atlassian.com/platform/forge/storage-reference/sql/) — SQL storage, limits, schema management -- [KVS and Custom Entity Store limits](https://developer.atlassian.com/platform/forge/storage-reference/kvs-limits/) — limits relevant to global (Level 2) caching - ---- - -## 1. Documentation philosophy - -Forge SQL ORM follows a **documentation-first** development model: - -1. **Every shipped feature is documented** in [README.md](README.md), [forge-sql-orm-extra/README.md](forge-sql-orm-extra/README.md), or [forge-sql-orm-cli/README.md](forge-sql-orm-cli/README.md) before or together with the release that exposes it. -2. **Removed or deprecated features** are removed or marked in the same documentation in the release that removes them. -3. **Breaking changes** are called out in [CHANGELOG.md](CHANGELOG.md) and, when applicable, in the README migration sections. -4. **Nothing intentionally undocumented** — if it is part of the public API or behavior consumers rely on, it must appear in docs or linked examples. -5. **Examples** under `examples/` demonstrate end-to-end usage for major capabilities (migrations, caching, vectors, Rovo, and others listed in the README). - -This requirements document does not duplicate the full API; it states obligations and constraints. The README remains the detailed specification of behavior. - ---- - -## 2. Purpose and scope - -### 2.1 Purpose - -Provide a **type-safe ORM layer** for [Atlassian Forge](https://developer.atlassian.com/platform/forge/) apps that use [@forge/sql](https://developer.atlassian.com/platform/forge/storage-reference/sql-tutorial/), built on [Drizzle ORM](https://orm.drizzle.team), including migrations, caching, observability, and Forge-specific SQL types. - -### 2.2 In scope - -- npm package `forge-sql-orm` (core library) -- npm package `forge-sql-orm-extra` (extended library — global cache, Rovo, SQL-parser cache invalidation) -- npm package `forge-sql-orm-cli` (schema/migration tooling) -- Custom Drizzle driver for `@forge/sql` -- Schema migration queueing and execution patterns aligned with Forge SQL -- Optional two-level caching (in-memory + `@forge/kvs`) -- Query analysis, slow-query monitoring, and timeout/OOM diagnostics -- Forge/TiDB-oriented custom column types and SQL function helpers -- Documented example applications under `examples/` - -### 2.3 Out of scope - -- Hosting or provisioning Forge SQL (Atlassian platform responsibility) -- Replacing Drizzle ORM; consumers may still use Drizzle directly via the custom driver -- General-purpose ORM for non-Forge MySQL/TiDB deployments -- Atlassian Government Cloud (AGC) — Forge SQL is [not supported on AGC](https://developer.atlassian.com/platform/forge/storage-reference/sql/) at the time of writing; this library targets standard Forge environments where `@forge/sql` is available -- Guaranteed TiDB-specific features beyond what Forge SQL documents as supported; prefer **ANSI SQL** where possible - -### 2.4 Modular package architecture - -The repository is a **monorepo** with three independently published npm packages. Consumers choose packages at install time; runtime code lives in `forge-sql-orm` or `forge-sql-orm-extra`, not both as primary imports. - -| Package | Directory | Role | -| ------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`forge-sql-orm`** | `src/` | Core ORM over `@forge/sql` — Drizzle driver, migrations, Level 1 (in-memory) cache, optimistic locking, query analysis, Forge/TiDB types and SQL helpers. No `@forge/kvs` in production dependencies. | -| **`forge-sql-orm-extra`** | `forge-sql-orm-extra/` | Extended ORM — includes everything from core (via `forge-sql-orm` dependency) plus Level 2 global cache (`@forge/kvs`), Rovo integration, and `node-sql-parser`-based cache invalidation. Drop-in replacement: import `forge-sql-orm-extra` instead of `forge-sql-orm`. | -| **`forge-sql-orm-cli`** | `forge-sql-orm-cli/` | CLI for generating entities and migrations from existing MySQL/TiDB schemas; not loaded in Forge app runtime. | - -**Feature placement rules:** - -- Capabilities that need only `@forge/sql` and Drizzle belong in **core**. -- Capabilities that need `@forge/kvs`, Rovo, or heavy optional parsers belong in **extra** (see NFR-9 bundle discipline). -- Tooling that runs outside Forge resolvers belongs in **CLI**. - -**Versioning:** Packages share aligned **major** versions when breaking changes affect consumers across packages. **Minor** and **patch** versions may diverge between packages within the same major line. - -**Release channels:** - -| Channel | Registry | Audience | Documented in | -| ------------------------ | -------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------- | -| Semver release | npmjs.com | Production Forge apps | README Installation, CHANGELOG | -| Weekly `master` snapshot | GitHub Packages (`latest`) | Early adopters / smoke tests | [README § GitHub Packages](../README.md#installing-from-github-packages-weekly-latest), CHANGELOG 2.2.0 | - -Weekly publishes must run the quality gate defined in §8 before GPR upload; ephemeral `ci.*` GPR versions are not a consumer channel. - ---- - -## 3. Functional requirements - -Each requirement maps to documentation in [README.md](README.md) unless noted. - -### 3.1 Core data access - -| ID | Requirement | -| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FR-1 | Integrate with `@forge/sql` through a custom Drizzle driver so apps can run type-safe queries in Forge resolvers and triggers. | -| FR-2 | Support SELECT/INSERT/UPDATE/DELETE via Drizzle query builder and documented extension methods (`selectFrom`, `selectDistinctFrom`, CTEs via `with()`, raw `execute` in core; cacheable variants and `executeCacheable` in extra). | -| FR-3 | Prevent ambiguous column names in multi-table selects (field name collision handling). | -| FR-4 | Support DDL via `executeDDL` / `executeDDLActions` consistent with Forge SQL migration patterns. | - -### 3.2 Migrations and schema - -| ID | Requirement | -| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FR-5 | Support queued DDL migrations compatible with Forge SQL’s queue + scheduled execution model. | -| FR-6 | Provide CLI commands to generate models and migrations from a development database and to update or drop migrations ([CLI README](forge-sql-orm-cli/README.md)). | -| FR-7 | Provide optional web triggers to apply migrations, fetch schema (development), and drop tables (development) with documented security constraints. | -| FR-8 | Document backward-compatible schema change practices per Atlassian recommendations (see §5.1). | - -### 3.3 Caching - -| ID | Package | Requirement | -| ----- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| FR-9 | core | **Level 1:** In-memory cache scoped to a single resolver/trigger invocation. | -| FR-10 | extra | **Level 2 (optional):** Cross-invocation cache via `@forge/kvs` with invalidation and context-aware operations, respecting KVS limits (§5.2). | -| FR-11 | extra | Expose cache-aware query helpers and manual cache management APIs documented in [forge-sql-orm-extra/README.md](forge-sql-orm-extra/README.md). | - -### 3.4 Reliability and observability - -| ID | Requirement | -| ----- | ------------------------------------------------------------------------------------------------- | -| FR-12 | Expose query execution metadata (`executeWithMetadata`) including timing and response size. | -| FR-13 | Detect timeout/OOM-class failures and support automatic post-mortem analysis where documented. | -| FR-14 | Support scheduled slow-query monitoring and query-plan analysis modes (TopSlowest, SummaryTable). | -| FR-15 | Support **optimistic locking** for concurrent updates. | - -### 3.5 Advanced / domain-specific - -| ID | Package | Requirement | -| ----- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FR-16 | core | Provide Forge-specific date/time column types matching Forge SQL string formats. | -| FR-17 | core | Provide binary/UUID custom types (`forgeBinary`, `uuidBinary`, BLOB variants, etc.). | -| FR-18 | core | Provide TiDB `VECTOR` type and vector distance helpers for embeddings/similarity search where Forge SQL allows. | -| FR-19 | core | Provide TiDB SQL function helper modules (aggregates, JSON, window, encrypt, etc.) as documented. | -| FR-20 | extra | Provide a **Rovo integration** pattern with security validations and optional RLS for dynamic SQL (documented in [forge-sql-orm-extra/README.md](forge-sql-orm-extra/README.md); see external example linked from README). | - ---- - -## 4. Non-functional requirements - -| ID | Requirement | -| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| NFR-1 | **Type safety:** Public APIs are typed in TypeScript; `tsc` build must pass in CI. | -| NFR-2 | **Test coverage:** Each package’s `src/` maintains Vitest coverage ≥ 80% statements/lines/functions and ≥ 75% branches ([CONTRIBUTING.md](CONTRIBUTING.md)). Integration with Forge SQL is exercised via `@forge/sql` mocks (§8.1), not live cloud DB tests in CI. | -| NFR-3 | **Static analysis:** CI runs ESLint, Knip, SonarCloud, and related checks on every PR to `master`. | -| NFR-4 | **Code review:** Every pull request is reviewed by an automated pipeline (CodeRabbit, Codacy AI Reviewer, SonarCloud, Qlty, DeepScan, Snyk, REUSE). **All bot comments are mandatory** and must be resolved by a human maintainer before merge. See §8.2. | -| NFR-5 | **Releases:** Semantic versioning; release notes in [GitHub Releases](https://github.com/forge-sql-orm/forge-sql-orm/releases) and [CHANGELOG.md](CHANGELOG.md). **Production** packages publish to **npmjs.com** on maintainer semver releases. **Weekly snapshots** of `master` publish to **GitHub Packages** with dist-tag `latest` (see [README — Installing from GitHub Packages](../README.md#installing-from-github-packages-weekly-latest)); workflow `.github/workflows/weekly-gpr.yml`. | -| NFR-6 | **License:** MIT ([LICENSE](LICENSE)). | -| NFR-7 | **Security:** Vulnerabilities reported per [SECURITY.md](SECURITY.md), not via public issues. | -| NFR-8 | **Peer dependencies:** `drizzle-orm` and `@forge/sql` versions documented in `package.json`; consumers must align with supported ranges. | -| NFR-9 | **Bundle discipline:** Optional/heavy dependencies (e.g. `@forge/kvs`, `node-sql-parser`, `@forge/events`) stay in **forge-sql-orm-extra** or optional paths so **forge-sql-orm** core installs remain lean (see §2.4). | -| NFR-10 | **Dependency license compliance:** the production dependency tree must remain free of strong/weak copyleft licenses (GPL/LGPL/AGPL/SSPL/EUPL/OSL). Enforced in CI via `npm run license:check` (`license-checker-rseidelsohn`, blocking). This complements REUSE/SPDX file-header compliance (NFR-4, §8.2), which is a separate concern. | -| NFR-11 | **Logging strategy:** Diagnostic logging uses the platform-native `console` API (Atlassian Forge captures `console.*` output from resolvers/triggers). The library deliberately does **not** depend on any third-party logging framework, consistent with bundle discipline (NFR-9). ESLint enforces `no-console: "error"`; every intentional log is opted in per line with `// eslint-disable-next-line no-console`, so console usage stays deliberate and reviewable rather than accidental. | - ---- - -## 5. Platform constraints - -The library **must not encourage patterns that violate** Atlassian platform limits. Implementations should fail gracefully or document constraints when limits apply. - -### 5.1 Forge SQL limits (per installation) - -Source: [Forge SQL — Limitations](https://developer.atlassian.com/platform/forge/storage-reference/sql/) (verify on Atlassian docs for updates). - -**Behavioral constraints** - -| Constraint | Implication for Forge SQL ORM | -| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- | -| MySQL-compliant, ANSI SQL encouraged | Prefer portable SQL in examples and generated migrations; avoid undocumented TiDB-only behavior | -| **Foreign keys not supported** | Do not rely on FK DDL or `ON DELETE CASCADE`; document JOIN + explicit deletes | -| **One SQL statement per call** | Driver and batch helpers must not send multi-statement strings in a single Forge SQL request | -| Schema applied per installation | Migrations must be installation-scoped via Forge SQL migration runner | -| Adding Forge SQL to an existing app requires **major version** + admin consent | Document in app migration guides (README Migration Guide) | - -**Per-install quotas** - -| Resource | Limit | -| -------------------------------------------- | ----------------------------------------------------------------------- | -| Total stored data | 1 GiB (production), 256 MiB (staging), 128 MiB (development/custom env) | -| Number of tables | 200 | -| DML requests per second | 150 | -| DDL requests per minute | 25 | -| Size per row | 6 MiB | -| Total query execution time (all invocations) | 62.5 seconds per minute | - -**Per-query / per-response limits** - -| Resource | Limit | -| ------------------------------- | ------------- | -| Memory usage per query | 16 MiB | -| Query time per minute | 62.5 s/minute | -| Request size | 1 MiB | -| Response size | 4 MiB | -| SELECT timeout (per connection) | 5 s | -| INSERT/UPDATE/DELETE timeout | 10 s | -| DDL timeout | 20 s | - -**Schema and data design recommendations (Atlassian)** - -- DDL changes must remain **backward compatible** with schema versions still migrating on customer sites. -- SQL used by older app versions must keep working on newer schemas. -- Avoid destructive schema changes that break cross-version compatibility. -- Avoid plain `AUTO_INCREMENT` hotspots; prefer `AUTO_RANDOM` or `BINARY(16)` UUIDs as documented by Atlassian/TiDB. - -### 5.2 @forge/kvs limits (Level 2 cache) - -Source: [KVS and Custom Entity Store limits](https://developer.atlassian.com/platform/forge/storage-reference/kvs-limits/). - -Global caching **must** account for: - -| Parameter | Limit | -| ---------------------- | ------------------------------------------------------------ | -| Request rate | 1000 RPS per installation | -| Read throughput | 4000 × 10 KB requests/min | -| Write throughput | 4000 × 10 KB requests/min | -| Request size rounding | Rounded up to nearest 10 KB (batching reduces counted usage) | -| Key length | 500 characters | -| Key format | `^(?!\s+$)[a-zA-Z0-9:._\s-#]+$` | -| Value size | 240 KiB (raw) per value | -| Object depth | 31 | -| Transaction operations | Max 25 ops per transaction | -| Transaction payload | 4 MiB | - -**Design implications for FR-9–FR-11** - -- Cache entries must stay within **240 KiB** per key; large result sets may require chunking or SQL-only strategies. -- High churn caches must respect **RPS and read/write buckets**; bulk workloads should use async events (Atlassian recommendation). -- Prefer **batch KVS operations** where the library batches writes/reads to reduce 10 KB rounding overhead. -- Do not store secrets in plain KVS values; use `kvs.setSecret` and encrypted environment variables for credentials. - ---- - -## 6. Compatibility and versioning - -| ID | Requirement | -| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -| COMPAT-1 | **Semantic versioning** for `forge-sql-orm`, `forge-sql-orm-extra`, and `forge-sql-orm-cli` (aligned major versions when breaking changes span packages). | -| COMPAT-2 | Breaking API or behavior changes require a **major** bump and an entry in CHANGELOG under a clearly marked section. | -| COMPAT-3 | Database-facing changes must remain compatible with Forge SQL migration and multi-version install guidance (§5.1). | -| COMPAT-4 | Deprecations should be announced in CHANGELOG and README before removal in the next major release where feasible. | - ---- - -## 7. Traceability - -| Work type | Where it is tracked | -| ----------------------- | ---------------------------------------------------------------------- | -| Bugs / defects | [GitHub Issues](https://github.com/forge-sql-orm/forge-sql-orm/issues) | -| Features / enhancements | GitHub Issues + README + CHANGELOG on release | -| Security | Private report per SECURITY.md | -| Implementation | Pull requests with linked issue when applicable | -| Release verification | GitHub Actions CI, SonarCloud, Qlty coverage | - -Example of community-reported defect tracking: [Issue #2128](https://github.com/forge-sql-orm/forge-sql-orm/issues/2128) (Forge lint / TypeScript duplicate property reporting). - ---- - -## 8. Verification - -Requirements in §3–§4 are verified by: - -- Automated tests in the repository root (`__tests__/`, Vitest) and in workspace packages (`forge-sql-orm-extra/__tests__/`, `forge-sql-orm-cli/__tests__/`) with coverage thresholds per package -- CI workflow [`.github/workflows/node.js.yml`](.github/workflows/node.js.yml) (lint, build, test:coverage for core, extra, and CLI; dependency license compliance (`license:check`); SonarCloud, example builds, Forge deploy smoke paths) -- Manual review of README/CHANGELOG on each release -- Example applications built and deployed in CI (smoke validation of packaging and Forge app lifecycle; not a substitute for automated SQL integration tests) - -### 8.1 Integration testing and Forge SQL - -**Live integration tests against Forge SQL are not part of this repository’s automated test suite.** - -Forge SQL is a **hosted, per-installation cloud database** on Atlassian infrastructure. Running deterministic integration tests in CI would require a live Forge app installation, platform credentials, tenant-isolated data, and network access to `@forge/sql` on every pull request. That is impractical for an open-source library consumed across many sites and environments, and it would couple test reliability to external quota limits (see §5.1). - -**Strategy: mock the official low-level API (`@forge/sql`).** - -Instead of hitting a remote database, tests **mock `@forge/sql`** at the boundary the library actually uses — `sql.prepare(query)` returning objects with `bindParams()` and `execute()` — and assert the **SQL strings, parameters, and ORM behavior** (including Drizzle integration) end-to-end through the public API. - -Primary suites (large, query-aware mocks): - -| Test file | What it exercises | -| ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | -| [`__tests__/src/core/ForgeSQLCrudOperations.test.ts`](__tests__/src/core/ForgeSQLCrudOperations.test.ts) | INSERT, UPDATE, DELETE, optimistic locking, versioned entities | -| [`__tests__/src/core/ForgeSQLSelectOperations.test.ts`](__tests__/src/core/ForgeSQLSelectOperations.test.ts) | SELECT, JOINs, CTEs, vector helpers, custom types, metadata (core) | -| [`forge-sql-orm-extra/__tests__/src/cache/ForgeSQLCacheOperations.test.ts`](forge-sql-orm-extra/__tests__/src/cache/ForgeSQLCacheOperations.test.ts) | Level 2 cache, cacheable selects, KVS integration (extra) | -| [`forge-sql-orm-extra/__tests__/src/rovo/Rovo.test.ts`](forge-sql-orm-extra/__tests__/src/rovo/Rovo.test.ts) | Rovo dynamic SQL, RLS, security validations (extra) | - -Additional tests use the same `@forge/sql` mock pattern where needed (e.g. [`ForgeSQLLocalCache.test.ts`](__tests__/src/core/ForgeSQLLocalCache.test.ts), [`forgeDriver.test.ts`](__tests__/src/utils/forgeDriver.test.ts), migration web triggers under `__tests__/src/webtriggers/`). - -This approach satisfies **integration-style coverage** of the ORM stack (Drizzle → custom driver → `@forge/sql` call shape) without a cloud database. **Manual** validation against real Forge SQL remains the responsibility of app authors and is supported via documented `examples/*` apps and CI Forge deploy steps. - -| ID | Requirement | -| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| TEST-1 | Core SQL generation and CRUD/SELECT behavior must be covered by Vitest suites that mock `@forge/sql`, not by requiring a live Forge SQL instance in CI. | -| TEST-2 | New query shapes or Forge SQL interactions should extend the mock-based suites above (or add analogous tests in the relevant package) with assertions on generated SQL and `bindParams` usage. | - -### 8.2 Code review and comment resolution - -Forge SQL ORM is solo-maintained. To keep review discipline at the level a quality rubric expects without a second human reviewer, every pull request to `master` is reviewed by an **automated pipeline** whose comments are treated as binding review items. - -**Pipeline (runs on every PR):** - -| Tool | Role | Operating mode | -| --------------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------ | -| [CodeRabbit](https://www.coderabbit.ai/) | AI line-level review of correctness, style, and likely defects | **Free tier** — rate-limited but covers every PR | -| [Codacy AI Reviewer](https://www.codacy.com/) | Additional AI comments on security, duplication, best practice | Comments posted on the PR | -| [SonarCloud Quality Gate](https://sonarcloud.io/) | Coverage, code smells, vulnerabilities, security hotspots | Blocks merge if the Quality Gate fails | -| [Qlty](https://qlty.sh/) | Maintainability score, coverage tracking | Comments + bot tracking on coverage delta | -| [DeepScan](https://deepscan.io/), [Snyk](https://snyk.io/) | Static security and runtime-defect scanning | Comments on PR / dashboard alerts | -| [REUSE / SPDX](https://reuse.software/) via `fsfe/reuse-action` | License-header compliance for every source file | Blocking CI step | - -**Comment resolution policy:** - -- Every comment posted by any of the tools above is a **mandatory review item**, regardless of severity (info/minor included). -- A **human maintainer must resolve every comment** before merge — by fixing the code, by replying with explicit reasoning that the comment is wrong or inapplicable and marking it resolved, or by filing a follow-up issue if the concern is out of scope. -- Auto-merge is enabled **only after** the pipeline passes _and_ every outstanding bot comment has been resolved by a human. -- PRs with unresolved bot comments will not be merged. - -This pipeline, combined with mandatory human-driven comment resolution, satisfies the "code review" quality dimension on a solo-maintained project. See [CONTRIBUTING.md — Pull Request Review Policy](CONTRIBUTING.md#pull-request-review-policy) for the contributor-facing version of this policy. - -| ID | Requirement | -| ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| REV-1 | Every PR to `master` must be reviewed by the automated pipeline above. Auto-merge is gated on all required checks passing. | -| REV-2 | Every comment produced by any bot in the pipeline is mandatory and must be resolved by a human maintainer (fix, reasoned dismissal, or follow-up issue) before merge. Unresolved bot comments block merge. | -| REV-3 | If a tool from the pipeline is removed or replaced, NFR-4 and §8.2 must be updated in the same PR. | - ---- - -## 9. Document maintenance - -| Event | Action | -| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -| New public feature | Update README and/or package README (core, extra, or CLI); add example if non-trivial; add CHANGELOG entry on release | -| Breaking change | CHANGELOG + README migration notes; bump major if needed | -| Platform limit change by Atlassian | Update §5 and README warnings | -| New quality gate | Update CONTRIBUTING and §4 | -| Dependency-license policy change | Update NFR-10 and the `license:check` blocklist in `package.json` | - -**Last updated:** 2026-06-05 (release channels §2.4; NFR-5 weekly GPR) diff --git a/REUSE.toml b/REUSE.toml deleted file mode 100644 index 823ce6fc2..000000000 --- a/REUSE.toml +++ /dev/null @@ -1,7 +0,0 @@ -version = 1 - -[[annotations]] -path = "**" -precedence = "closest" -SPDX-FileCopyrightText = "2025-2026 Vasyl Zakharchenko" -SPDX-License-Identifier = "MIT" diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index fd4f51b0d..000000000 --- a/SECURITY.md +++ /dev/null @@ -1,32 +0,0 @@ -# Security Policy - -## Supported Versions - -We are committed to fixing security vulnerabilities in the latest stable release of each published package from this repository. - -| Version | Supported | -| ------- | ------------------ | -| 2.x.x | :white_check_mark: | -| < 2.0.0 | :x: | - -**In scope:** npm packages published from this repository: - -- `forge-sql-orm` (core ORM) -- `forge-sql-orm-extra` (extended ORM — global cache, Rovo) -- `forge-sql-orm-cli` (schema/migration CLI) - -## Reporting a Vulnerability - -**Please DO NOT report security vulnerabilities through public GitHub issues.** - -If you believe you have found a security vulnerability in any of the packages above, please report it by emailing us directly at: -**vaszakharchenko@gmail.com** - -### Our Security Pledge: - -1. **Response:** We will acknowledge your email within 48 hours. -2. **Investigation:** We will investigate the issue and keep you updated on the progress. -3. **Fix:** Once the vulnerability is confirmed, we will release a patch as quickly as possible. -4. **Disclosure:** We will not disclose the issue publicly until a fix is available. - -Thank you for helping keep Forge SQL ORM safe! diff --git a/__tests__/entities/CustomTypeEntity.ts b/__tests__/entities/CustomTypeEntity.ts deleted file mode 100644 index 1ee5e6f48..000000000 --- a/__tests__/entities/CustomTypeEntity.ts +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { int, mysqlTable, primaryKey } from "drizzle-orm/mysql-core"; -import { forgeBinary, forgeBLOB, forgeMediumBLOB, forgeTinyBLOB, forgeVarBinary } from "../../src"; - -export const customTypeEntity = mysqlTable( - "custom_Type_Entity", - { - id: int("id").autoincrement(), - blob: forgeBLOB("blob", { length: 255 }).notNull(), - tinyBlob: forgeTinyBLOB("tinyBlob").notNull(), - mediumBlob: forgeMediumBLOB("mediumBlob", { length: 255 }).notNull(), - binary: forgeBinary("binary", { length: 1024 }).notNull(), - varBinary: forgeVarBinary("varBinary").notNull(), - }, - (table) => [primaryKey({ columns: [table.id], name: "users_id" })], -); diff --git a/__tests__/entities/TestDataEntity.ts b/__tests__/entities/TestDataEntity.ts deleted file mode 100644 index 91cb76db1..000000000 --- a/__tests__/entities/TestDataEntity.ts +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { testEntity } from "./TestEntity"; -import { mysqlTable, int, varchar } from "drizzle-orm/mysql-core"; - -export class TestDataEntity { - id!: number; - data?: string; -} - -export const testDataEntity = mysqlTable("test_data_entity", { - id: int("id") - .primaryKey() - .autoincrement() - .references(() => testEntity.id), - data: varchar("data", { length: 255 }).notNull(), -}); diff --git a/__tests__/entities/TestEntity.ts b/__tests__/entities/TestEntity.ts deleted file mode 100644 index a144e9732..000000000 --- a/__tests__/entities/TestEntity.ts +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { int, mysqlTable, primaryKey, varchar } from "drizzle-orm/mysql-core"; - -export class TestEntity { - id!: number; - name?: string; -} - -export const testEntity = mysqlTable( - "test_entity", - { - id: int("id").autoincrement(), - name: varchar("name", { length: 255 }).notNull(), - }, - (table) => [primaryKey({ columns: [table.id], name: "users_id" })], -); diff --git a/__tests__/entities/TestEntityDateVersion.ts b/__tests__/entities/TestEntityDateVersion.ts deleted file mode 100644 index baebafe3a..000000000 --- a/__tests__/entities/TestEntityDateVersion.ts +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { forgeDateTimeString } from "../../src"; -import { mysqlTable, int, varchar } from "drizzle-orm/mysql-core"; - -export class TestEntityDateVersion { - id!: number; - name!: string; - version!: Date; -} - -export const testEntityDateVersion = mysqlTable("test_entity_date_version", { - id: int("id").primaryKey().autoincrement(), - name: varchar("name", { length: 255 }).notNull(), - version: forgeDateTimeString("version").notNull(), -}); diff --git a/__tests__/entities/TestEntityJoin1.ts b/__tests__/entities/TestEntityJoin1.ts deleted file mode 100644 index 17a43c7d0..000000000 --- a/__tests__/entities/TestEntityJoin1.ts +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { int, mysqlTable, primaryKey, varchar } from "drizzle-orm/mysql-core"; -import { uuidBinary } from "../../src"; - -export const testEntityJoin1 = mysqlTable( - "test_entity_join1", - { - id: int("id").autoincrement(), - name: varchar("name", { length: 255 }).notNull(), - email: varchar("email", { length: 255 }).notNull(), - customType: uuidBinary("custom_type").notNull(), - }, - (table) => [primaryKey({ columns: [table.id], name: "users_id" })], -); diff --git a/__tests__/entities/TestEntityJoin2.ts b/__tests__/entities/TestEntityJoin2.ts deleted file mode 100644 index f567be272..000000000 --- a/__tests__/entities/TestEntityJoin2.ts +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { int, mysqlTable, primaryKey, varchar } from "drizzle-orm/mysql-core"; - -export const testEntityJoin2 = mysqlTable( - "test_entity_join2", - { - id: int("id").autoincrement(), - name: varchar("name", { length: 255 }).notNull(), - email: varchar("email", { length: 255 }).notNull(), - }, - (table) => [primaryKey({ columns: [table.id], name: "users_id" })], -); diff --git a/__tests__/entities/TestEntityTimeStampVersion.ts b/__tests__/entities/TestEntityTimeStampVersion.ts deleted file mode 100644 index c40a39bd9..000000000 --- a/__tests__/entities/TestEntityTimeStampVersion.ts +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { forgeTimestampString } from "../../src"; -import { mysqlTable, int, varchar } from "drizzle-orm/mysql-core"; - -export class TestEntityTimeStampVersion { - id!: number; - name?: string; - version!: Date; -} - -export const testEntityTimeStampVersion = mysqlTable("test_entity_timestamp_version", { - id: int("id").primaryKey().autoincrement(), - name: varchar("name", { length: 255 }).notNull(), - version: forgeTimestampString("version").notNull(), -}); diff --git a/__tests__/entities/TestEntityVector.ts b/__tests__/entities/TestEntityVector.ts deleted file mode 100644 index 30f8cd9d8..000000000 --- a/__tests__/entities/TestEntityVector.ts +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { int, mysqlTable, primaryKey, varchar } from "drizzle-orm/mysql-core"; -import { vectorTiDBType } from "../../src"; - -export class TestEntity { - id!: number; - name?: string; -} - -export const testEntityVector = mysqlTable( - "test_entity_vector", - { - id: int("id").autoincrement(), - name: varchar("name", { length: 255 }).notNull(), - embedding: vectorTiDBType("embedding", { dimension: 10 }).notNull(), - }, - (table) => [primaryKey({ columns: [table.id], name: "id" })], -); diff --git a/__tests__/entities/TestEntityVersion.ts b/__tests__/entities/TestEntityVersion.ts deleted file mode 100644 index ac1acddba..000000000 --- a/__tests__/entities/TestEntityVersion.ts +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { mysqlTable, int, varchar } from "drizzle-orm/mysql-core"; - -export class TestEntityVersion { - id!: number; - name?: string; - version!: number; -} -export const testEntityVersion = mysqlTable("test_entity_version", { - id: int("id").primaryKey().autoincrement(), - name: varchar("name", { length: 255 }).notNull(), - version: int("version").notNull().default(0), -}); diff --git a/__tests__/entities/TestEntityVersionDifferentField.ts b/__tests__/entities/TestEntityVersionDifferentField.ts deleted file mode 100644 index 74781d30e..000000000 --- a/__tests__/entities/TestEntityVersionDifferentField.ts +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { mysqlTable, int, varchar } from "drizzle-orm/mysql-core"; - -export class TestEntityVersion { - id!: number; - name?: string; - version!: number; -} -export const TestEntityVersionDifferentField = mysqlTable("test_entity_diff_version", { - id: int("id").primaryKey().autoincrement(), - name: varchar("name", { length: 255 }).notNull(), - version: int("version_different_field").notNull().default(0), -}); diff --git a/__tests__/entities/TestEntityVersionDifferentFieldDate.ts b/__tests__/entities/TestEntityVersionDifferentFieldDate.ts deleted file mode 100644 index 7ff5388cc..000000000 --- a/__tests__/entities/TestEntityVersionDifferentFieldDate.ts +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { mysqlTable, int, varchar } from "drizzle-orm/mysql-core"; -import { forgeDateTimeString } from "../../src"; - -export const testEntityVersionDifferentDateField = mysqlTable("test_entity_diff_date_version", { - id: int("id").primaryKey().autoincrement(), - name: varchar("name", { length: 255 }).notNull(), - versionField: forgeDateTimeString("version_different_date_field").notNull(), -}); diff --git a/__tests__/src/async/PrintQueryConsumer.test.ts b/__tests__/src/async/PrintQueryConsumer.test.ts deleted file mode 100644 index 1e5d03246..000000000 --- a/__tests__/src/async/PrintQueryConsumer.test.ts +++ /dev/null @@ -1,282 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; -import { printDegradationQueriesConsumer } from "../../../src/async/PrintQueryConsumer"; -import { AsyncEvent } from "@forge/events"; -import { AsyncEventPrintQuery } from "../../../src/async/PrintQueryConsumer"; -import { ForgeSqlOperation } from "../../../src/core/ForgeSQLQueryBuilder"; -import { ForgeSQLMetadata } from "../../../src/utils/forgeDriver"; - -// Mock dependencies -const mockPrintDegradationQueries = vi.fn(); -vi.mock("../../../src/utils/metadataContextUtils", () => ({ - printDegradationQueries: (...args: any[]) => mockPrintDegradationQueries(...args), -})); - -describe("PrintQueryConsumer", () => { - let mockForgeSQLORM: ForgeSqlOperation; - let consoleWarnSpy: ReturnType; - let mockEvent: AsyncEvent; - let mockBody: AsyncEventPrintQuery; - - beforeEach(() => { - // Mock console.warn - consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - - // Mock ForgeSQLORM - mockForgeSQLORM = {} as ForgeSqlOperation; - - // Create mock event body - const beginTime = new Date("2023-01-01T12:00:00Z"); - mockBody = { - totalDbExecutionTime: 1500, - totalResponseSize: 2048, - beginTime: beginTime, - options: { - mode: "TopSlowest", - topQueries: 1, - summaryTableWindowTime: 15000, - showSlowestPlans: true, - normalizeQuery: true, - asyncQueueName: "", - }, - statistics: [ - { - query: "SELECT * FROM users", - params: [], - metadata: { - dbExecutionTime: 1500, - responseSize: 2048, - fields: [], - } as ForgeSQLMetadata, - }, - ], - }; - - // Create mock event - mockEvent = { - jobId: "test-job-id-123", - body: mockBody, - } as AsyncEvent; - - // Reset mocks - mockPrintDegradationQueries.mockClear(); - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe("printDegradationQueriesConsumer", () => { - it("should process event and call printDegradationQueries", async () => { - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - expect(mockPrintDegradationQueries).toHaveBeenCalledTimes(1); - expect(mockPrintDegradationQueries).toHaveBeenCalledWith( - mockForgeSQLORM, - expect.objectContaining({ - totalDbExecutionTime: 1500, - totalResponseSize: 2048, - statistics: mockBody.statistics, - options: mockBody.options, - }), - ); - }); - - it("should convert beginTime string to Date object", async () => { - const beginTimeString = "2023-01-01T12:00:00Z"; - const beginTimeDate = new Date(beginTimeString); - - mockEvent.body = { - ...mockBody, - beginTime: beginTimeString as any, // Simulate string from JSON - } as any; - - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - // Verify that beginTime was converted to Date - const callArgs = mockPrintDegradationQueries.mock.calls[0][1] as AsyncEventPrintQuery; - expect(callArgs.beginTime).toBeInstanceOf(Date); - expect(callArgs.beginTime.getTime()).toBe(beginTimeDate.getTime()); - }); - - it("should log warning with correct information", async () => { - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - expect(consoleWarnSpy).toHaveBeenCalledTimes(1); - const logMessage = consoleWarnSpy.mock.calls[0][0] as string; - - expect(logMessage).toContain("[Performance Analysis] Processing query degradation event"); - expect(logMessage).toContain(`Job ID: ${mockEvent.jobId}`); - expect(logMessage).toContain(`Total DB time: ${mockBody.totalDbExecutionTime}ms`); - expect(logMessage).toContain(`Queries: ${mockBody.statistics.length}`); - expect(logMessage).toContain(`Started: ${mockBody.beginTime.toISOString()}`); - }); - - it("should handle event with multiple statistics", async () => { - const multipleStatsBody: AsyncEventPrintQuery = { - ...mockBody, - statistics: [ - { - query: "SELECT * FROM users", - params: [], - metadata: { - dbExecutionTime: 500, - responseSize: 1024, - fields: [], - } as ForgeSQLMetadata, - }, - { - query: "SELECT * FROM orders", - params: [], - metadata: { - dbExecutionTime: 1000, - responseSize: 2048, - fields: [], - } as ForgeSQLMetadata, - }, - ], - }; - - mockEvent.body = multipleStatsBody; - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringContaining(`Queries: ${multipleStatsBody.statistics.length}`), - ); - expect(mockPrintDegradationQueries).toHaveBeenCalledWith( - mockForgeSQLORM, - expect.objectContaining({ - statistics: multipleStatsBody.statistics, - }), - ); - }); - - it("should handle event with zero statistics", async () => { - const emptyStatsBody: AsyncEventPrintQuery = { - ...mockBody, - statistics: [], - }; - - mockEvent.body = emptyStatsBody; - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining("Queries: 0")); - expect(mockPrintDegradationQueries).toHaveBeenCalledWith( - mockForgeSQLORM, - expect.objectContaining({ - statistics: [], - }), - ); - }); - - it("should handle different job IDs", async () => { - const differentJobId = "different-job-id-456"; - mockEvent.jobId = differentJobId; - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringContaining(`Job ID: ${differentJobId}`), - ); - }); - - it("should handle different totalDbExecutionTime values", async () => { - const highDbTimeBody: AsyncEventPrintQuery = { - ...mockBody, - totalDbExecutionTime: 5000, - }; - - mockEvent.body = highDbTimeBody; - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining("Total DB time: 5000ms")); - }); - - it("should preserve all options when calling printDegradationQueries", async () => { - const customOptionsBody: AsyncEventPrintQuery = { - ...mockBody, - options: { - mode: "SummaryTable", - topQueries: 5, - summaryTableWindowTime: 20000, - showSlowestPlans: false, - normalizeQuery: false, - asyncQueueName: "customQueue", - }, - }; - - mockEvent.body = customOptionsBody; - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - expect(mockPrintDegradationQueries).toHaveBeenCalledWith( - mockForgeSQLORM, - expect.objectContaining({ - options: customOptionsBody.options, - }), - ); - }); - - it("should handle errors from printDegradationQueries", async () => { - const error = new Error("Test error"); - mockPrintDegradationQueries.mockRejectedValue(error); - - await expect(printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent)).rejects.toThrow( - "Test error", - ); - - expect(mockPrintDegradationQueries).toHaveBeenCalledTimes(1); - }); - - it("should handle Date object beginTime correctly", async () => { - const beginTimeDate = new Date("2023-06-15T10:30:00Z"); - const dateBody: AsyncEventPrintQuery = { - ...mockBody, - beginTime: beginTimeDate, - }; - - mockEvent.body = dateBody; - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - const callArgs = mockPrintDegradationQueries.mock.calls[0][1] as AsyncEventPrintQuery; - expect(callArgs.beginTime).toBeInstanceOf(Date); - expect(callArgs.beginTime.getTime()).toBe(beginTimeDate.getTime()); - }); - - it("should handle ISO string beginTime and convert to Date", async () => { - const isoString = "2023-12-25T15:45:30.123Z"; - const expectedDate = new Date(isoString); - - mockEvent.body = { - ...mockBody, - beginTime: isoString as any, // Simulate string from JSON - } as any; - - mockPrintDegradationQueries.mockResolvedValue(undefined); - - await printDegradationQueriesConsumer(mockForgeSQLORM, mockEvent); - - const callArgs = mockPrintDegradationQueries.mock.calls[0][1] as AsyncEventPrintQuery; - expect(callArgs.beginTime).toBeInstanceOf(Date); - expect(callArgs.beginTime.toISOString()).toBe(expectedDate.toISOString()); - }); - }); -}); diff --git a/__tests__/src/core/ForgeSQLAnalizeOperations.test.ts b/__tests__/src/core/ForgeSQLAnalizeOperations.test.ts deleted file mode 100644 index 50f4be29d..000000000 --- a/__tests__/src/core/ForgeSQLAnalizeOperations.test.ts +++ /dev/null @@ -1,361 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, vi, beforeEach } from "vitest"; -import { ForgeSQLAnalyseOperation } from "../../../src/core/ForgeSQLAnalyseOperations"; -import { ForgeSqlOperation } from "../../../src/core/ForgeSQLQueryBuilder"; -import { testEntity } from "../../entities/TestEntity"; -import { testEntityJoin2 } from "../../entities/TestEntityJoin2"; - -// Mock dependencies -vi.mock("../../../src/core/ForgeSQLQueryBuilder", () => ({ - ForgeSqlOperation: vi.fn(), -})); - -describe("ForgeSQLAnalizeOperation", () => { - let forgeOperations: ForgeSqlOperation; - let analyzeOperation: ForgeSQLAnalyseOperation; - - beforeEach(() => { - // Reset mocks before each test - vi.clearAllMocks(); - - // Setup mock ForgeSqlOperation - forgeOperations = { - fetch: vi.fn().mockReturnValue({ - executeRawSQL: vi.fn(), - }), - } as unknown as ForgeSqlOperation; - - analyzeOperation = new ForgeSQLAnalyseOperation(forgeOperations); - }); - - describe("explainAnalyzeRaw", () => { - it("should execute EXPLAIN ANALYZE query and return formatted results", async () => { - // Mock raw SQL execution results - const mockResults = [ - { - id: "1", - estRows: "100", - actRows: "95", - task: "TableScan", - "access object": "table:t1", - "execution info": "time:1ms", - "operator info": "scan:t1", - memory: "1MB", - disk: "0B", - }, - ]; - - (forgeOperations.fetch().executeRawSQL as any).mockResolvedValue(mockResults); - - const result = await analyzeOperation.explainAnalyzeRaw("SELECT * FROM t1", []); - - expect(result).toEqual([ - { - id: "1", - estRows: "100", - actRows: "95", - task: "TableScan", - accessObject: "table:t1", - executionInfo: "time:1ms", - operatorInfo: "scan:t1", - memory: "1MB", - disk: "0B", - }, - ]); - - expect(forgeOperations.fetch().executeRawSQL).toHaveBeenCalledWith( - "EXPLAIN ANALYZE SELECT * FROM t1", - [], - ); - }); - - it("should handle empty results", async () => { - (forgeOperations.fetch().executeRawSQL as any).mockResolvedValue([]); - - const result = await analyzeOperation.explainAnalyzeRaw("SELECT * FROM t1", []); - - expect(result).toEqual([]); - }); - }); - - describe("explainAnalyze", () => { - it("should execute EXPLAIN ANALYZE on a Drizzle query", async () => { - const mockQuery = { - toSQL: vi.fn().mockReturnValue({ - sql: "SELECT * FROM t1", - params: ["param1"], - }), - }; - - const mockResults = [ - { - id: "1", - estRows: "100", - actRows: "95", - task: "TableScan", - "access object": "table:t1", - "execution info": "time:1ms", - "operator info": "scan:t1", - memory: "1MB", - disk: "0B", - }, - ]; - const realResults = [ - { - id: "1", - estRows: "100", - actRows: "95", - task: "TableScan", - accessObject: "table:t1", - executionInfo: "time:1ms", - operatorInfo: "scan:t1", - memory: "1MB", - disk: "0B", - }, - ]; - - (forgeOperations.fetch().executeRawSQL as any).mockResolvedValue(mockResults); - - const result = await analyzeOperation.explainAnalyze(mockQuery); - - expect(result).toEqual(realResults); - expect(forgeOperations.fetch().executeRawSQL).toHaveBeenCalledWith( - "EXPLAIN ANALYZE SELECT * FROM t1", - ["param1"], - ); - }); - }); - - describe("decodedPlan", () => { - it("should decode a plan string into structured data", () => { - const planString = `id\testRows\tactRows\ttask\taccess object\texecution info\toperator info\tmemory\tdisk -1\t100\t95\tTableScan\ttable:t1\ttime:1ms\tscan:t1\t1MB\t0B`; - - const result = analyzeOperation.decodedPlan(planString); - - expect(result).toEqual([ - { - id: "1", - estRows: "100", - actRows: "95", - task: "TableScan", - accessObject: "table:t1", - executionInfo: "time:1ms", - operatorInfo: "scan:t1", - memory: "1MB", - disk: "0B", - }, - ]); - }); - - it("should handle empty input", () => { - const result = analyzeOperation.decodedPlan(""); - expect(result).toEqual([]); - }); - - it("should handle malformed input", () => { - const result = analyzeOperation.decodedPlan("invalid plan string"); - expect(result).toEqual([]); - }); - }); - - describe("normalizeSlowQuery", () => { - it("should normalize a slow query row", () => { - const rawQuery = { - Time: "2024-01-01 12:00:00", - Txn_start_ts: 1234567890, - User: "test_user", - Host: "localhost", - Conn_ID: 1, - DB: "test_db", - Query: "SELECT * FROM t1", - Digest: "abc123", - Query_time: 1.5, - Compile_time: 0.1, - Optimize_time: 0.2, - Process_time: 0.8, - Wait_time: 0.4, - Parse_time: 0.05, - Rewrite_time: 0.05, - Cop_time: 0.3, - Cop_proc_avg: 0.1, - Cop_proc_max: 0.2, - Cop_proc_p90: 0.15, - Cop_proc_addr: "127.0.0.1", - Cop_wait_avg: 0.1, - Cop_wait_max: 0.2, - Cop_wait_p90: 0.15, - Cop_wait_addr: "127.0.0.1", - Mem_max: 1024, - Disk_max: 0, - Total_keys: 100, - Process_keys: 95, - Request_count: 1, - KV_total: 0.5, - PD_total: 0.2, - Result_rows: 10, - Rocksdb_block_cache_hit_count: 50, - Rocksdb_block_read_count: 5, - Rocksdb_block_read_byte: 1024, - Plan: "TableScan", - Binary_plan: "binary_plan", - Plan_digest: "plan_digest", - }; - - const result = analyzeOperation.normalizeSlowQuery(rawQuery); - - expect(result).toEqual({ - time: "2024-01-01 12:00:00", - txnStartTs: 1234567890, - user: "test_user", - host: "localhost", - connId: 1, - db: "test_db", - query: "SELECT * FROM t1", - digest: "abc123", - queryTime: 1.5, - compileTime: 0.1, - optimizeTime: 0.2, - processTime: 0.8, - waitTime: 0.4, - parseTime: 0.05, - rewriteTime: 0.05, - copTime: 0.3, - copProcAvg: 0.1, - copProcMax: 0.2, - copProcP90: 0.15, - copProcAddr: "127.0.0.1", - copWaitAvg: 0.1, - copWaitMax: 0.2, - copWaitP90: 0.15, - copWaitAddr: "127.0.0.1", - memMax: 1024, - diskMax: 0, - totalKeys: 100, - processKeys: 95, - requestCount: 1, - kvTotal: 0.5, - pdTotal: 0.2, - resultRows: 10, - rocksdbBlockCacheHitCount: 50, - rocksdbBlockReadCount: 5, - rocksdbBlockReadByte: 1024, - plan: "TableScan", - binaryPlan: "binary_plan", - planDigest: "plan_digest", - parsedPlan: [], - }); - }); - }); - - describe("buildClusterStatementQuery", () => { - it("should build a query with table conditions", () => { - const tables = ["t1", "t2"]; - const query = analyzeOperation.buildClusterStatementQuery(tables); - - expect(query).toContain("TABLE_NAMES LIKE CONCAT(SCHEMA_NAME, '.', '%', 't1', '%')"); - expect(query).toContain("TABLE_NAMES LIKE CONCAT(SCHEMA_NAME, '.', '%', 't2', '%')"); - }); - - it("should include date range conditions when provided", () => { - const tables = ["t1"]; - const fromDate = new Date("2024-01-01"); - const toDate = new Date("2024-01-02"); - - const query = analyzeOperation.buildClusterStatementQuery(tables, fromDate, toDate); - - expect(query).toContain("SUMMARY_BEGIN_TIME >= "); - expect(query).toContain("SUMMARY_END_TIME <= "); - }); - }); - - describe("analyzeSlowQueries", () => { - it("should fetch and normalize slow queries", async () => { - const mockRawQueries = [ - { - Time: "2024-01-01 12:00:00", - Query: "SELECT * FROM t1", - // ... other fields - }, - ]; - - (forgeOperations.fetch().executeRawSQL as any).mockResolvedValue(mockRawQueries); - - const result = await analyzeOperation.analyzeSlowQueries(); - - expect(result).toHaveLength(1); - expect(result[0].time).toBe("2024-01-01 12:00:00"); - expect(result[0].query).toBe("SELECT * FROM t1"); - }); - }); - - describe("mapToCamelCaseClusterStatement", () => { - it("should convert snake_case to camelCase", () => { - const input = { - INSTANCE: "instance1", - SUMMARY_BEGIN_TIME: "2024-01-01", - PLAN: "TableScan", - }; - - const result = analyzeOperation.mapToCamelCaseClusterStatement(input); - - expect(result).toEqual({ - instance: "instance1", - summaryBeginTime: "2024-01-01", - plan: "TableScan", - parsedPlan: [], - }); - }); - - it("should handle empty input", () => { - const result = analyzeOperation.mapToCamelCaseClusterStatement({}); - expect(result).toEqual({ parsedPlan: [] }); - }); - }); - - describe("analyzeQueriesHistory", () => { - it("should analyze queries for Drizzle tables", async () => { - const mockResults = [ - { - INSTANCE: "instance1", - SUMMARY_BEGIN_TIME: "2024-01-01", - PLAN: "TableScan", - }, - ]; - - (forgeOperations.fetch().executeRawSQL as any).mockResolvedValue(mockResults); - - const result = await analyzeOperation.analyzeQueriesHistory([testEntity, testEntityJoin2]); - - expect(result).toHaveLength(1); - expect(result[0].instance).toBe("instance1"); - expect(result[0].summaryBeginTime).toBe("2024-01-01"); - }); - }); - - describe("analyzeQueriesHistoryRaw", () => { - it("should analyze queries for raw table names", async () => { - const tables = ["t1", "t2"]; - const fromDate = new Date("2024-01-01"); - const toDate = new Date("2024-01-02"); - - const mockResults = [ - { - INSTANCE: "instance1", - SUMMARY_BEGIN_TIME: "2024-01-01", - PLAN: "TableScan", - }, - ]; - - (forgeOperations.fetch().executeRawSQL as any).mockResolvedValue(mockResults); - - const result = await analyzeOperation.analyzeQueriesHistoryRaw(tables, fromDate, toDate); - - expect(result).toHaveLength(1); - expect(result[0].instance).toBe("instance1"); - expect(result[0].summaryBeginTime).toBe("2024-01-01"); - }); - }); -}); diff --git a/__tests__/src/core/ForgeSQLCrudOperations.test.ts b/__tests__/src/core/ForgeSQLCrudOperations.test.ts deleted file mode 100644 index c594d0e62..000000000 --- a/__tests__/src/core/ForgeSQLCrudOperations.test.ts +++ /dev/null @@ -1,674 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeEach, vi } from "vitest"; -const OriginalDate = global.Date; -import { clearCache, clearTablesCache } from "../../../src/utils/cacheUtils"; -vi.mock("../../../src/utils/cacheUtils"); -vi.useFakeTimers(); -vi.setSystemTime(new Date("2023-04-12 00:00:01")); -vi.mock("@forge/sql", () => ({ - sql: { - prepare: vi.fn((query: string) => { - if ( - query === - "select `id`, `version` from `test_entity_version` where `test_entity_version`.`id` = ?" || - query === - "select `id` as `a_id_id`, `version` as `a_version_version` from `test_entity_version` where `test_entity_version`.`id` = ?" - ) { - const testEntityVersion = { - id: 1, - name: "test", - version: 5, - } as TestEntityVersion; - const mockResult = { - query: "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn().mockImplementation((params) => { - mockResult.params = params; - return mockResult; - }), - execute: () => ({ rows: [testEntityVersion] }), - } as any; - return mockResult; - } else if ( - query === - "select `t0`.`id`, `t0`.`version` from `test_entity_date_version` as `t0` where `t0`.`id` = 1" - ) { - const testEntityVersion = { - id: 1, - name: "test", - version: new Date("01.01.2000 00:00:00"), - } as TestEntityDateVersion; - const mockResult = { - query: "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn().mockImplementation((params) => { - mockResult.params = params; - return mockResult; - }), - execute: () => ({ rows: [testEntityVersion] }), - } as any; - return mockResult; - } else if (query.startsWith("update")) { - const mockResult = { - query: "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn().mockImplementation((params) => { - mockResult.params = params; - return mockResult; - }), - execute: vi.fn().mockResolvedValue({ rows: { affectedRows: 1, insertId: 0 } }), - } as any; - return mockResult; - } else if (query.startsWith("insert")) { - const mockResult = { - query: "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn().mockImplementation((params) => { - mockResult.params = params; - return mockResult; - }), - execute: vi.fn().mockResolvedValue({ rows: { affectedRows: 1, insertId: 1 } }), - } as any; - return mockResult; - } else if (query.startsWith("delete")) { - const mockResult = { - query: "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn().mockImplementation((params) => { - mockResult.params = params; - return mockResult; - }), - execute: vi.fn().mockResolvedValue({ rows: { affectedRows: 1, insertId: 0 } }), - } as any; - return mockResult; - } - const mockResult = { - query: "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn().mockImplementation((params) => { - mockResult.params = params; - return mockResult; - }), - execute: vi.fn().mockResolvedValue({ rows: [] }), - } as any; - return mockResult; - }), - }, -})); - -import { sql } from "@forge/sql"; -import ForgeSQLORM, { ForgeSqlOperation } from "../../../src"; -import { testEntity } from "../../entities/TestEntity"; -import { testEntityVersion, TestEntityVersion } from "../../entities/TestEntityVersion"; -import { testEntityDateVersion, TestEntityDateVersion } from "../../entities/TestEntityDateVersion"; -import { customTypeEntity } from "../../entities/CustomTypeEntity"; -import { eq } from "drizzle-orm"; -import { testEntityTimeStampVersion } from "../../entities/TestEntityTimeStampVersion"; -import { TestEntityVersionDifferentField } from "../../entities/TestEntityVersionDifferentField"; -import { testEntityJoin1 } from "../../entities/TestEntityJoin1"; - -describe("ForgeSQLCrudOperations", () => { - let forgeSqlOperation: ForgeSqlOperation; - - beforeEach(() => { - forgeSqlOperation = new ForgeSQLORM({ - cacheEntityName: "cache", - logRawSqlQuery: true, - additionalMetadata: { - test_entity_version: { - tableName: "test_entity_version", - versionField: { - fieldName: "version", - }, - }, - test_entity_date_version: { - tableName: "test_entity_date_version", - versionField: { - fieldName: "version", - }, - }, - test_entity_timestamp_version: { - tableName: "test_entity_timestamp_version", - versionField: { - fieldName: "version", - }, - }, - test_entity_diff_version: { - tableName: "test_entity_diff_version", - versionField: { - fieldName: "version_different_field", - }, - }, - }, - }); - }); - - it("should call SQL prepare and execute on insert", async () => { - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: { - fieldCount: 0, - affectedRows: 1, - insertId: 30006, - info: "", - serverStatus: 2, - warningStatus: 0, - changedRows: 0, - }, - metadata: { dbExecutionTime: 5, responseSize: 111, fields: [] }, - }), - }) as any, - ); - let number = await forgeSqlOperation - .modifyWithVersioning() - .insert(testEntity, [{ id: 1, name: "Test" }]); - expect(number).toEqual(30006); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity` (`id`, `name`) values (?, ?)", - ); - - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Test"); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should serialize binary customTypes on insert via FROM_BASE64 and null literal", async () => { - await forgeSqlOperation.modifyWithVersioning().insert(customTypeEntity, [ - { - id: 1, - blob: Buffer.from([1, 2, 3]), - tinyBlob: new Uint8Array([4, 5]) as any, - mediumBlob: "hello" as any, - binary: { a: 1 } as any, - varBinary: null as any, - }, - ]); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `custom_Type_Entity` (`id`, `blob`, `tinyBlob`, `mediumBlob`, `binary`, `varBinary`) values (?, FROM_BASE64(?), FROM_BASE64(?), FROM_BASE64(?), FROM_BASE64(?), ?)", - ); - - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith( - 1, - Buffer.from([1, 2, 3]).toString("base64"), - Buffer.from([4, 5]).toString("base64"), - Buffer.from("hello").toString("base64"), - Buffer.from(JSON.stringify({ a: 1 })).toString("base64"), - null, - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should use UUID_TO_BIN for uuidBinary customType on insert", async () => { - await forgeSqlOperation.modifyWithVersioning().insert(testEntityJoin1, [ - { - id: 1, - name: "Test", - email: "test@example.com", - customType: "00112233-4455-6677-8899-aabbccddeeff", - }, - ]); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity_join1` (`id`, `name`, `email`, `custom_type`) values (?, ?, ?, UUID_TO_BIN(?))", - ); - - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith( - 1, - "Test", - "test@example.com", - "00112233-4455-6677-8899-aabbccddeeff", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on insert with empty versioning number", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .insert(testEntityVersion, [{ id: 1, name: "Test" }]); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity_version` (`id`, `name`, `version`) values (?, ?, ?)", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Test", 1); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on insert with not empty versioning number", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .insert(testEntityVersion, [{ id: 1, name: "Test", version: 11111 }]); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity_version` (`id`, `name`, `version`) values (?, ?, ?)", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Test", 1); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on insert with empty versioning date", async () => { - await forgeSqlOperation.modifyWithVersioning().insert(testEntityDateVersion, [ - { - id: 1, - name: "Test", - version: new Date(), - } as { id: number; name: string; version: Date }, - ]); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity_date_version` (`id`, `name`, `version`) values (?, ?, ?)", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Test", "2023-04-12 00:00:01.000"); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on insert notEmpty empty versioning date", async () => { - await forgeSqlOperation.modifyWithVersioning().insert(testEntityDateVersion, [ - { - id: 1, - name: "Test", - version: new OriginalDate(), - } as { id: number; name: string; version: Date }, - ]); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity_date_version` (`id`, `name`, `version`) values (?, ?, ?)", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Test", "2023-04-12 00:00:01.000"); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on deleteById", async () => { - await forgeSqlOperation.modifyWithVersioning().deleteById(1, testEntity); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "delete from `test_entity` where `test_entity`.`id` = ?", - ); - - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on deleteById Versioning Field number", async () => { - await forgeSqlOperation.modifyWithVersioning().deleteById(1, testEntityVersion); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "select `id` as `a_id_id`, `version` as `a_version_version` from `test_entity_version` where `test_entity_version`.`id` = ?", - ); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "delete from `test_entity_version` where (`test_entity_version`.`id` = ? and `test_entity_version`.`version` = ?)", - ); - }); - - it("should call SQL prepare and execute on updateById", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .updateById({ id: 1, name: "Updated" }, testEntity); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith(expect.any(String)); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "update `test_entity` set `id` = ?, `name` = ? where `test_entity`.`id` = ?", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Updated", 1); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on updateById With version", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .updateById({ id: 1, name: "Updated", version: 2 }, testEntityVersion); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "update `test_entity_version` set `id` = ?, `name` = ?, `version` = ? where (`test_entity_version`.`id` = ? and `test_entity_version`.`version` = ?)", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Updated", 3, 1, 2); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - it("should call SQL prepare and execute on updateById With version column", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .updateById({ id: 1, name: "Updated", version: 2 }, TestEntityVersionDifferentField); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "update `test_entity_diff_version` set `id` = ?, `name` = ?, `version_different_field` = ? where (`test_entity_diff_version`.`id` = ? and `test_entity_diff_version`.`version_different_field` = ?)", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Updated", 3, 1, 2); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on updateById With version Date", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .updateById({ id: 1, version: new Date("01.01.2010 00:00:00") }, testEntityDateVersion); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "update `test_entity_date_version` set `id` = ?, `version` = ? where (`test_entity_date_version`.`id` = ? and `test_entity_date_version`.`version` = ?)", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith( - 1, - "2023-04-12 00:00:01.000", - 1, - "2010-01-01 00:00:00.000", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on updateById With version TimeStamp", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .updateById({ id: 1, version: new Date("01.01.2010 00:00:00") }, testEntityTimeStampVersion); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "update `test_entity_timestamp_version` set `id` = ?, `version` = ? where (`test_entity_timestamp_version`.`id` = ? and `test_entity_timestamp_version`.`version` = ?)", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith( - 1, - "2023-04-12 00:00:01.000", - 1, - "2010-01-01 00:00:00.000", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on updateFields2 only update", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .updateFields({ id: 1, name: "Updated" }, testEntity, eq(testEntity.id, 10000)); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "update `test_entity` set `id` = ?, `name` = ? where `test_entity`.`id` = ?", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Updated", 10000); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should call SQL prepare and execute on updateFields only update Wrong Where", async () => { - await expect( - forgeSqlOperation.modifyWithVersioning().updateFields({ name: "Updated" }, testEntity), - ).rejects.toThrow("WHERE conditions must be provided"); - }); - - describe("Error Handling", () => { - it("should throw error when insert fails", async () => { - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockRejectedValue(new Error("Insert failed")), - }) as any, - ); - - await expect( - forgeSqlOperation.modifyWithVersioning().insert(testEntity, [{ id: 1, name: "Test" }]), - ).rejects.toThrow( - "Failed query: insert into `test_entity` (`id`, `name`) values (?, ?)\n" + "params: 1,Test", - ); - }); - - it("should throw error when update fails", async () => { - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockRejectedValue(new Error("Update failed")), - }) as any, - ); - - await expect( - forgeSqlOperation.modifyWithVersioning().updateById({ id: 1, name: "Updated" }, testEntity), - ).rejects.toThrow( - "Failed query: update `test_entity` set `id` = ?, `name` = ? where `test_entity`.`id` = ?\n" + - "params: 1,Updated,1", - ); - }); - - it("should throw error when delete fails", async () => { - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockRejectedValue(new Error("Delete failed")), - }) as any, - ); - - await expect( - forgeSqlOperation.modifyWithVersioning().deleteById(1, testEntity), - ).rejects.toThrow( - "Failed query: delete from `test_entity` where `test_entity`.`id` = ?\n" + "params: 1", - ); - }); - }); - - describe("Bulk Operations", () => { - it("should handle bulk insert with multiple records", async () => { - const records = [ - { id: 1, name: "Test1" }, - { id: 2, name: "Test2" }, - { id: 3, name: "Test3" }, - ]; - - await forgeSqlOperation.modifyWithVersioning().insert(testEntity, records); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity` (`id`, `name`) values (?, ?), (?, ?), (?, ?)", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Test1", 2, "Test2", 3, "Test3"); - }); - - it("should handle bulk insert with versioning", async () => { - const records = [ - { id: 1, name: "Test1", version: 1 }, - { id: 2, name: "Test2", version: 1 }, - { id: 3, name: "Test3", version: 1 }, - ]; - - await forgeSqlOperation.modifyWithVersioning().insert(testEntityVersion, records); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity_version` (`id`, `name`, `version`) values (?, ?, ?), (?, ?, ?), (?, ?, ?)", - ); - }); - }); - - describe("Versioning Edge Cases", () => { - it("should handle version conflict during update", async () => { - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ rows: { affectedRows: 0, insertId: 0 } }), - }) as any, - ); - - await expect( - forgeSqlOperation - .modifyWithVersioning() - .updateById({ id: 1, name: "Updated", version: 2 }, testEntityVersion), - ).rejects.toThrow("Optimistic locking failed: record with primary key 1 has been modified"); - }); - - it("should handle version field with undefined value", async () => { - expect( - await forgeSqlOperation - .modifyWithVersioning() - .updateById({ id: 1, name: "Updated", version: undefined }, testEntityVersion), - ).toBe(1); - }); - - it("should handle version field with invalid type", async () => { - const invalidVersion = { id: 1, name: "Updated", version: NaN }; - expect( - await forgeSqlOperation - .modifyWithVersioning() - .updateById({ id: 1, name: "Updated", version: undefined }, testEntityVersion), - ).toBe(1); - }); - - it("should handle version field with negative value", async () => { - expect( - await forgeSqlOperation - .modifyWithVersioning() - .updateById({ id: 1, name: "Updated", version: -1 }, testEntityVersion), - ).toBe(1); - }); - }); - - describe("Query Building", () => { - it("should build correct query for update with multiple conditions", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .updateFields({ name: "Updated" }, testEntity, eq(testEntity.id, 1)); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "update `test_entity` set `name` = ? where `test_entity`.`id` = ?", - ); - }); - - it("should build correct query for update with versioning and multiple conditions", async () => { - await forgeSqlOperation - .modifyWithVersioning() - .updateFields( - { name: "Updated", version: 2 }, - testEntityVersion, - eq(testEntityVersion.id, 1), - ); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "update `test_entity_version` set `name` = ?, `version` = ? where `test_entity_version`.`id` = ?", - ); - }); - }); - - it("simple Insert", async () => { - await forgeSqlOperation.insert(testEntityDateVersion).values([ - { - id: 1, - name: "Test", - version: new Date(), - } as { id: number; name: string; version: Date }, - ]); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity_date_version` (`id`, `name`, `version`) values (?, ?, ?)", - ); - expect(vi.mocked(clearCache)).not.toHaveBeenCalled(); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Test", "2023-04-12 00:00:01.000"); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("simple update", async () => { - await forgeSqlOperation.update(testEntity).set({ name: "Updated" }).where(eq(testEntity.id, 1)); - expect(vi.mocked(clearTablesCache)).not.toHaveBeenCalled(); - expect(vi.mocked(clearCache)).not.toHaveBeenCalled(); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "update `test_entity` set `name` = ? where `test_entity`.`id` = ?", - ); - }); - - it("simple delete", async () => { - await forgeSqlOperation.delete(testEntity).where(eq(testEntity.id, 1)); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "delete from `test_entity` where `test_entity`.`id` = ?", - ); - - expect(vi.mocked(clearTablesCache)).not.toHaveBeenCalled(); - expect(vi.mocked(clearCache)).not.toHaveBeenCalled(); - - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("simple Insert in localCache", async () => { - await forgeSqlOperation.executeWithLocalContext(async () => { - // real call and put result in cache - await forgeSqlOperation - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - // get from local cache - await forgeSqlOperation - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - // get from local cache - await forgeSqlOperation - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - // insert and evict cache - await forgeSqlOperation.insert(testEntityDateVersion).values([ - { - id: 1, - name: "Test", - version: new Date(), - } as { id: number; name: string; version: Date }, - ]); - // real call and put result in cache - await forgeSqlOperation - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - // get from local cache - await forgeSqlOperation - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - - // real call and put result in cache - await forgeSqlOperation - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - }); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledTimes(3); // 1- before insert, 2 - insert, 3 - after insert - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "insert into `test_entity_date_version` (`id`, `name`, `version`) values (?, ?, ?)", - ); - expect(vi.mocked(clearCache)).not.toHaveBeenCalled(); - - const preparedStatement = vi.mocked(sql.prepare).mock.results[1].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith(1, "Test", "2023-04-12 00:00:01.000"); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); -}); diff --git a/__tests__/src/core/ForgeSQLLocalCache.test.ts b/__tests__/src/core/ForgeSQLLocalCache.test.ts deleted file mode 100644 index 817f3f844..000000000 --- a/__tests__/src/core/ForgeSQLLocalCache.test.ts +++ /dev/null @@ -1,368 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeEach, vi, afterEach } from "vitest"; -import { eq } from "drizzle-orm"; -import ForgeSQL from "../../../src/core/ForgeSQLORM"; -import { testEntityDateVersion } from "../../entities/TestEntityDateVersion"; - -// Mock @forge/sql -vi.mock("@forge/sql", () => ({ - sql: { - prepare: vi.fn((query: string) => { - const procedureMock = vi.fn().mockResolvedValue({ - rows: [{ id: 1, name: "Test", version: "2023-04-12 00:00:01.000" }], - }); - return { - query: query || "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn(), - execute: procedureMock, - }; - }), - }, -})); - -// Mock @forge/kvs -vi.mock("@forge/kvs", () => ({ - kvs: { - entity: vi.fn(() => ({ - get: vi.fn(), - set: vi.fn(), - query: vi.fn(() => ({ - index: vi.fn(() => ({ - filters: vi.fn(() => ({ - cursor: vi.fn(() => ({ - limit: vi.fn(() => ({ - getMany: vi.fn(), - })), - })), - })), - where: vi.fn(() => ({ - cursor: vi.fn(() => ({ - limit: vi.fn(() => ({ - getMany: vi.fn(), - })), - })), - })), - })), - })), - })), - transact: vi.fn(() => ({ - set: vi.fn().mockReturnThis(), - delete: vi.fn().mockReturnThis(), - execute: vi.fn(), - })), - }, - Filter: vi.fn(() => ({ - or: vi.fn().mockReturnThis(), - })), - FilterConditions: { - contains: vi.fn((value) => ({ contains: value })), - }, - WhereConditions: { - lessThan: vi.fn((value) => ({ lessThan: value })), - }, -})); - -// Mock cacheContextUtils -vi.mock("../../../src/utils/cacheContextUtils", () => ({ - cacheApplicationContext: { - getStore: vi.fn(), - run: vi.fn(), - }, - localCacheApplicationContext: { - getStore: vi.fn(), - run: vi.fn(), - }, - isTableContainsTableInCacheContext: vi.fn().mockResolvedValue(false), - saveTableIfInsideCacheContext: vi.fn(), - saveQueryLocalCacheQuery: vi.fn(), - getQueryLocalCacheQuery: vi.fn(), - evictLocalCacheQuery: vi.fn(), -})); - -describe("ForgeSQL Local Cache", () => { - let forgeSQL: ForgeSQL; - - beforeEach(() => { - vi.clearAllMocks(); - forgeSQL = new ForgeSQL({ - logRawSqlQuery: false, - disableOptimisticLocking: false, - cacheWrapTable: true, - cacheTTL: 120, - }); - }); - - afterEach(() => { - vi.useRealTimers(); - }); - - describe("executeWithLocalContext", () => { - it("should execute operations within local cache context", async () => { - const { localCacheApplicationContext } = await import("../../../src/utils/cacheContextUtils"); - const mockRun = vi.fn().mockImplementation((context, callback) => callback()); - (localCacheApplicationContext.run as any).mockImplementation(mockRun); - - let executed = false; - await forgeSQL.executeWithLocalContext(async () => { - executed = true; - }); - - expect(executed).toBe(true); - expect(mockRun).toHaveBeenCalledWith({ cache: {} }, expect.any(Function)); - }); - - it("should handle errors in local cache context", async () => { - const { localCacheApplicationContext } = await import("../../../src/utils/cacheContextUtils"); - const mockRun = vi.fn().mockImplementation((context, callback) => callback()); - (localCacheApplicationContext.run as any).mockImplementation(mockRun); - - const error = new Error("Test error"); - await expect( - forgeSQL.executeWithLocalContext(async () => { - throw error; - }), - ).rejects.toThrow("Test error"); - }); - }); - - describe("executeWithLocalCacheContextAndReturnValue", () => { - it("should execute operations and return value within local cache context", async () => { - const { localCacheApplicationContext } = await import("../../../src/utils/cacheContextUtils"); - const mockRun = vi.fn().mockImplementation((context, callback) => callback()); - (localCacheApplicationContext.run as any).mockImplementation(mockRun); - - const result = await forgeSQL.executeWithLocalCacheContextAndReturnValue(async () => { - return "test result"; - }); - - expect(result).toBe("test result"); - expect(mockRun).toHaveBeenCalledWith({ cache: {} }, expect.any(Function)); - }); - - it("should handle errors and return undefined", async () => { - const { localCacheApplicationContext } = await import("../../../src/utils/cacheContextUtils"); - const mockRun = vi.fn().mockImplementation((context, callback) => callback()); - (localCacheApplicationContext.run as any).mockImplementation(mockRun); - - const error = new Error("Test error"); - await expect( - forgeSQL.executeWithLocalCacheContextAndReturnValue(async () => { - throw error; - }), - ).rejects.toThrow("Test error"); - }); - }); - - describe("Local Cache Query Operations", () => { - it("should cache select queries within local context", async () => { - const { localCacheApplicationContext, getQueryLocalCacheQuery, saveQueryLocalCacheQuery } = - await import("../../../src/utils/cacheContextUtils"); - - // Mock local cache context - const mockContext = { cache: {} }; - const mockRun = vi.fn().mockImplementation((context, callback) => { - (localCacheApplicationContext.getStore as any).mockReturnValue(mockContext); - return callback(); - }); - (localCacheApplicationContext.run as any).mockImplementation(mockRun); - - // Mock cache operations - (getQueryLocalCacheQuery as any).mockResolvedValue(undefined); - (saveQueryLocalCacheQuery as any).mockResolvedValue(undefined); - - await forgeSQL.executeWithLocalContext(async () => { - // First call - should execute and cache - const result1 = await forgeSQL - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - - // Second call - should get from cache - const result2 = await forgeSQL - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - - expect(result1).toEqual(result2); - }); - - expect(getQueryLocalCacheQuery).toHaveBeenCalled(); - expect(saveQueryLocalCacheQuery).toHaveBeenCalled(); - }); - - it("should evict local cache on insert operations", async () => { - const { localCacheApplicationContext, evictLocalCacheQuery } = - await import("../../../src/utils/cacheContextUtils"); - - // Mock local cache context - const mockContext = { cache: {} }; - const mockRun = vi.fn().mockImplementation((context, callback) => { - (localCacheApplicationContext.getStore as any).mockReturnValue(mockContext); - return callback(); - }); - (localCacheApplicationContext.run as any).mockImplementation(mockRun); - - // Mock evict operation - (evictLocalCacheQuery as any).mockResolvedValue(undefined); - - await forgeSQL.executeWithLocalContext(async () => { - await forgeSQL.insert(testEntityDateVersion).values([ - { - id: 1, - name: "Test", - version: new Date(), - } as { id: number; name: string; version: Date }, - ]); - }); - - expect(evictLocalCacheQuery).toHaveBeenCalledWith(testEntityDateVersion, expect.any(Object)); - }); - - it("should evict local cache on update operations", async () => { - const { localCacheApplicationContext, evictLocalCacheQuery } = - await import("../../../src/utils/cacheContextUtils"); - - // Mock local cache context - const mockContext = { cache: {} }; - const mockRun = vi.fn().mockImplementation((context, callback) => { - (localCacheApplicationContext.getStore as any).mockReturnValue(mockContext); - return callback(); - }); - (localCacheApplicationContext.run as any).mockImplementation(mockRun); - - // Mock evict operation - (evictLocalCacheQuery as any).mockResolvedValue(undefined); - - await forgeSQL.executeWithLocalContext(async () => { - await forgeSQL - .update(testEntityDateVersion) - .set({ name: "Updated" }) - .where(eq(testEntityDateVersion.id, 1)); - }); - - expect(evictLocalCacheQuery).toHaveBeenCalledWith(testEntityDateVersion, expect.any(Object)); - }); - - it("should evict local cache on delete operations", async () => { - const { localCacheApplicationContext, evictLocalCacheQuery } = - await import("../../../src/utils/cacheContextUtils"); - - // Mock local cache context - const mockContext = { cache: {} }; - const mockRun = vi.fn().mockImplementation((context, callback) => { - (localCacheApplicationContext.getStore as any).mockReturnValue(mockContext); - return callback(); - }); - (localCacheApplicationContext.run as any).mockImplementation(mockRun); - - // Mock evict operation - (evictLocalCacheQuery as any).mockResolvedValue(undefined); - - await forgeSQL.executeWithLocalContext(async () => { - await forgeSQL.delete(testEntityDateVersion).where(eq(testEntityDateVersion.id, 1)); - }); - - expect(evictLocalCacheQuery).toHaveBeenCalledWith(testEntityDateVersion, expect.any(Object)); - }); - }); - - describe("Integration Test - Complete Scenario", () => { - it("should handle complete local cache scenario", async () => { - const { - localCacheApplicationContext, - getQueryLocalCacheQuery, - saveQueryLocalCacheQuery, - evictLocalCacheQuery, - } = await import("../../../src/utils/cacheContextUtils"); - - // Mock local cache context - const mockContext = { cache: {} }; - const mockRun = vi.fn().mockImplementation((context, callback) => { - (localCacheApplicationContext.getStore as any).mockReturnValue(mockContext); - return callback(); - }); - (localCacheApplicationContext.run as any).mockImplementation(mockRun); - - // Mock cache operations - let cacheHit = false; - (getQueryLocalCacheQuery as any).mockImplementation(() => { - if (cacheHit) { - return Promise.resolve([{ id: 1, version: "2023-04-12 00:00:01.000" }]); - } - return Promise.resolve(undefined); - }); - - (saveQueryLocalCacheQuery as any).mockImplementation(() => { - cacheHit = true; - return Promise.resolve(); - }); - - (evictLocalCacheQuery as any).mockImplementation(() => { - cacheHit = false; - return Promise.resolve(); - }); - - await forgeSQL.executeWithLocalContext(async () => { - // First select - should execute and cache - const result1 = await forgeSQL - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - - // Second select - should get from cache - const result2 = await forgeSQL - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - - // Third select - should get from cache - const result3 = await forgeSQL - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - - // Insert - should evict cache - await forgeSQL.insert(testEntityDateVersion).values([ - { - id: 1, - name: "Test", - version: new Date(), - } as { id: number; name: string; version: Date }, - ]); - - // Fourth select - should execute and cache again - const result4 = await forgeSQL - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - - // Fifth select - should get from cache - const result5 = await forgeSQL - .select({ id: testEntityDateVersion.id, version: testEntityDateVersion.version }) - .from(testEntityDateVersion) - .where(eq(testEntityDateVersion.id, 1)); - - expect(result1).toHaveLength(1); - expect(result1[0]).toHaveProperty("id", 1); - expect(result2).toHaveLength(1); - expect(result2[0]).toHaveProperty("id", 1); - expect(result3).toHaveLength(1); - expect(result3[0]).toHaveProperty("id", 1); - expect(result4).toHaveLength(1); - expect(result4[0]).toHaveProperty("id", 1); - expect(result5).toHaveLength(1); - expect(result5[0]).toHaveProperty("id", 1); - }); - - // Verify cache operations were called - expect(getQueryLocalCacheQuery).toHaveBeenCalledTimes(5); - expect(saveQueryLocalCacheQuery).toHaveBeenCalledTimes(2); // After first and fourth select - expect(evictLocalCacheQuery).toHaveBeenCalledTimes(1); // After insert - }); - }); -}); diff --git a/__tests__/src/core/ForgeSQLORM.test.ts b/__tests__/src/core/ForgeSQLORM.test.ts deleted file mode 100644 index c4ee3bfaf..000000000 --- a/__tests__/src/core/ForgeSQLORM.test.ts +++ /dev/null @@ -1,341 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { beforeEach, describe, expect, it, vi } from "vitest"; -import { eq, sql as rawSql } from "drizzle-orm"; -import { sql } from "@forge/sql"; -import ForgeSQLORM from "../../../src/core/ForgeSQLORM"; -import type { ForgeSqlOperation } from "../../../src/core/ForgeSQLQueryBuilder"; -import { NopCache } from "../../../src/lib/cache/NopCache"; -import { testEntity } from "../../entities/TestEntity"; - -vi.mock("@forge/sql", () => ({ - sql: { - prepare: vi.fn((query: string) => { - const statement = { - query: query || "MOCK_QUERY", - params: [] as unknown[], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [{ id: 1, name: "Test" }], - metadata: { dbExecutionTime: 10, responseSize: 100 }, - }), - }; - statement.bindParams.mockReturnValue(statement); - return statement; - }), - }, -})); - -vi.mock("@forge/sql/out/sql", () => ({ - SQL_API_ENDPOINTS: { EXECUTE_DDL: "EXECUTE_DDL" }, -})); - -type ForgeSQLORMInternal = InstanceType & { - ormInstance: ForgeSqlOperation; -}; - -function getOrmInstance(forgeSQL: ForgeSQLORM): ForgeSqlOperation { - return (forgeSQL as ForgeSQLORMInternal).ormInstance; -} - -describe("ForgeSQLORM", () => { - let forgeSQL: ForgeSQLORM; - let consoleErrorSpy: ReturnType; - - beforeEach(() => { - vi.clearAllMocks(); - consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - forgeSQL = new ForgeSQLORM({ - logRawSqlQuery: false, - disableOptimisticLocking: false, - cacheWrapTable: true, - cacheTTL: 120, - cacheImplementation: new NopCache(), - }); - }); - - describe("singleton and surface", () => { - it("returns the same underlying instance for repeated construction", () => { - const second = new ForgeSQLORM({ logRawSqlQuery: true }); - expect(getOrmInstance(second)).toBe(getOrmInstance(forgeSQL)); - }); - - it("exposes fetch, analyze, modifyWithVersioning, and drizzle builder", () => { - expect(forgeSQL.fetch()).toBeDefined(); - expect(forgeSQL.analyze()).toBeDefined(); - expect(forgeSQL.modifyWithVersioning()).toBeDefined(); - const qb = forgeSQL.getDrizzleQueryBuilder(); - expect(typeof qb.selectAliased).toBe("function"); - expect(typeof qb.selectAliasedDistinct).toBe("function"); - }); - }); - - describe("executeWithMetadata", () => { - it("returns the query result and invokes onMetadata with aggregated metrics", async () => { - const onMetadata = vi.fn().mockResolvedValue(undefined); - - const result = await forgeSQL.executeWithMetadata( - async () => { - await forgeSQL.select({ id: testEntity.id }).from(testEntity); - return { ok: true }; - }, - onMetadata, - { mode: "TopSlowest", topQueries: 2 }, - ); - - expect(result).toEqual({ ok: true }); - expect(onMetadata).toHaveBeenCalledWith( - expect.any(Number), - expect.any(Number), - expect.any(Function), - ); - }); - - it("skips onMetadata when getLastestMetadata returns undefined", async () => { - const metadataUtils = await import("../../../src/utils/metadataContextUtils"); - const spy = vi.spyOn(metadataUtils, "getLastestMetadata").mockResolvedValue(undefined); - - const onMetadata = vi.fn(); - const result = await forgeSQL.executeWithMetadata(async () => "done", onMetadata); - - expect(result).toBe("done"); - expect(onMetadata).not.toHaveBeenCalled(); - spy.mockRestore(); - }); - - it("logs and swallows errors from the onMetadata callback", async () => { - const result = await forgeSQL.executeWithMetadata( - async () => "value", - () => { - throw new Error("metadata callback failed"); - }, - ); - - expect(result).toBe("value"); - expect(consoleErrorSpy).toHaveBeenCalledWith( - "[ForgeSQLORM][executeWithMetadata] Failed to run onMetadata callback", - expect.objectContaining({ - errorMessage: "metadata callback failed", - errorStack: expect.any(String), - }), - expect.any(Error), - ); - }); - - it("invokes the initial printQueriesWithPlan stub in the metadata context", async () => { - const metadataUtils = await import("../../../src/utils/metadataContextUtils"); - const originalRun = metadataUtils.metadataQueryContext.run.bind( - metadataUtils.metadataQueryContext, - ); - const runSpy = vi - .spyOn(metadataUtils.metadataQueryContext, "run") - .mockImplementation((store, fn) => { - void store.printQueriesWithPlan(); - return originalRun(store, fn); - }); - - await forgeSQL.executeWithMetadata(async () => "ok", vi.fn()); - - runSpy.mockRestore(); - }); - - it("handles non-Error throws in the onMetadata callback", async () => { - await forgeSQL.executeWithMetadata( - async () => undefined, - () => { - throw "plain failure"; - }, - ); - - expect(consoleErrorSpy).toHaveBeenCalledWith( - "[ForgeSQLORM][executeWithMetadata] Failed to run onMetadata callback", - expect.objectContaining({ - errorMessage: "plain failure", - errorStack: undefined, - }), - "plain failure", - ); - }); - }); - - describe("select helpers", () => { - it("throws when select fields are empty", () => { - const impl = getOrmInstance(forgeSQL); - expect(() => impl.select(null as never)).toThrow("fields is empty"); - expect(() => impl.selectDistinct(undefined as never)).toThrow("fields is empty"); - }); - - it("delegates select and selectDistinct to aliased drizzle helpers", () => { - const impl = getOrmInstance(forgeSQL); - expect(impl.select({ id: testEntity.id })).toBeDefined(); - expect(impl.selectDistinct({ id: testEntity.id })).toBeDefined(); - }); - }); - - describe("ForgeSQLORMImpl-only query entry points", () => { - it("selectFrom and selectDistinctFrom run through the impl drizzle instance", async () => { - const impl = getOrmInstance(forgeSQL); - - await impl.selectFrom(testEntity); - await impl.selectDistinctFrom(testEntity); - - expect(sql.prepare).toHaveBeenCalledWith( - "select `id` as `a_id_id`, `name` as `a_name_name` from `test_entity`", - ); - expect(sql.prepare).toHaveBeenCalledWith( - "select distinct `id` as `a_id_id`, `name` as `a_name_name` from `test_entity`", - ); - }); - - it("$with and with run through the impl drizzle instance", async () => { - const impl = getOrmInstance(forgeSQL); - const withQuery = impl - .$with("orm_impl_with") - .as(impl.select({ id: rawSql`${testEntity.id}`.as("id") }).from(testEntity)); - const result = await impl.with(withQuery).select({ id: withQuery.id }).from(withQuery); - - expect(sql.prepare).toHaveBeenCalledWith( - "with `orm_impl_with` as (select `id` as `id` from `test_entity`) select `id` from `orm_impl_with`", - ); - expect(result).toEqual([{ id: 1 }]); - }); - }); - - describe("DDL and raw execution", () => { - it("executeDDLActions on the public wrapper delegates to the impl", async () => { - const result = await forgeSQL.executeDDLActions(async () => { - return await forgeSQL.execute("SELECT 1"); - }); - - expect(result).toBeDefined(); - }); - - it("executeDDL wraps executeQuery in DDL context", async () => { - await forgeSQL.executeDDL("CREATE TABLE t (id INT)"); - expect(sql.prepare).toHaveBeenCalled(); - }); - - it("insert, update, and delete return drizzle builders", () => { - expect(forgeSQL.insert(testEntity)).toBeDefined(); - expect(forgeSQL.update(testEntity)).toBeDefined(); - expect(forgeSQL.delete(testEntity)).toBeDefined(); - }); - }); - - describe("public-only APIs", () => { - it("selectDistinctCacheableFrom uses the cacheable distinct helper", async () => { - await forgeSQL.selectDistinctCacheableFrom(testEntity, 60).where(eq(testEntity.id, 1)); - - expect(sql.prepare).toHaveBeenCalledWith( - "select distinct `id` as `a_id_id`, `name` as `a_name_name` from `test_entity` where `test_entity`.`id` = ?", - ); - }); - - it("$with and with on the public class use getDrizzleQueryBuilder", async () => { - const withQuery = forgeSQL - .$with("public_with") - .as(forgeSQL.select({ id: rawSql`${testEntity.id}`.as("id") }).from(testEntity)); - await forgeSQL.with(withQuery).select({ id: withQuery.id }).from(withQuery); - - expect(sql.prepare).toHaveBeenCalledWith( - "with `public_with` as (select `id` as `id` from `test_entity`) select `id` from `public_with`", - ); - }); - }); - - describe("local cache context", () => { - it("executeWithLocalContext runs the callback", async () => { - const callback = vi.fn().mockResolvedValue(undefined); - await forgeSQL.executeWithLocalContext(callback); - expect(callback).toHaveBeenCalled(); - }); - - it("executeWithLocalCacheContextAndReturnValue returns the callback result", async () => { - const result = await forgeSQL.executeWithLocalCacheContextAndReturnValue(async () => 99); - expect(result).toBe(99); - }); - }); - - describe("normalizationSQL", () => { - it("replaces literals via regex on the public wrapper and impl", () => { - const sql = "SELECT * FROM users WHERE id = 42 AND name = 'Alice'"; - - const publicResult = forgeSQL.normalizationSQL(sql); - const implResult = getOrmInstance(forgeSQL).normalizationSQL(sql); - - expect(publicResult).toBe(implResult); - expect(publicResult).toContain("id = ?"); - expect(publicResult).toContain("name = ?"); - expect(publicResult).not.toContain("Alice"); - expect(publicResult).not.toContain("42"); - }); - }); - - describe("public wrapper delegation", () => { - it("selectFrom and selectDistinctFrom delegate to getDrizzleQueryBuilder", async () => { - await forgeSQL.selectFrom(testEntity); - await forgeSQL.selectDistinctFrom(testEntity); - - expect(sql.prepare).toHaveBeenCalledWith( - "select `id` as `a_id_id`, `name` as `a_name_name` from `test_entity`", - ); - expect(sql.prepare).toHaveBeenCalledWith( - "select distinct `id` as `a_id_id`, `name` as `a_name_name` from `test_entity`", - ); - }); - - it("execute delegates to the underlying impl", async () => { - await forgeSQL.execute("SELECT 1"); - expect(sql.prepare).toHaveBeenCalled(); - }); - - it("selectDistinct delegates to the underlying impl", () => { - expect(forgeSQL.selectDistinct({ id: testEntity.id })).toBeDefined(); - }); - }); -}); - -describe("ForgeSQLORM isolated module initialization", () => { - afterEach(() => { - vi.doUnmock("../../../src/utils/forgeDriverProxy"); - vi.resetModules(); - }); - - it("logs debug output when logRawSqlQuery is enabled", async () => { - const debugSpy = vi.spyOn(console, "debug").mockImplementation(() => {}); - vi.resetModules(); - - const { default: IsolatedForgeSQLORM } = await import("../../../src/core/ForgeSQLORM"); - new IsolatedForgeSQLORM({ logRawSqlQuery: true }); - - expect(debugSpy).toHaveBeenCalledWith("Initializing ForgeSQLORM..."); - debugSpy.mockRestore(); - }); - - it("applies default options when none are provided", async () => { - vi.resetModules(); - - const { default: IsolatedForgeSQLORM } = await import("../../../src/core/ForgeSQLORM"); - const instance = new IsolatedForgeSQLORM(); - - expect(instance.fetch()).toBeDefined(); - }); - - it("logs and rethrows when driver initialization fails", async () => { - vi.doMock("../../../src/utils/forgeDriverProxy", () => ({ - createForgeDriverProxy: vi.fn(() => { - throw new Error("driver init failed"); - }), - })); - vi.resetModules(); - - const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - const { default: IsolatedForgeSQLORM } = await import("../../../src/core/ForgeSQLORM"); - - expect(() => new IsolatedForgeSQLORM()).toThrow("driver init failed"); - expect(errorSpy).toHaveBeenCalledWith("ForgeSQLORM initialization failed:", expect.any(Error)); - - errorSpy.mockRestore(); - }); -}); diff --git a/__tests__/src/core/ForgeSQLQueryBuilder.test.ts b/__tests__/src/core/ForgeSQLQueryBuilder.test.ts deleted file mode 100644 index d9b969a0b..000000000 --- a/__tests__/src/core/ForgeSQLQueryBuilder.test.ts +++ /dev/null @@ -1,241 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeAll, afterAll } from "vitest"; -import { mysqlTable, int } from "drizzle-orm/mysql-core"; -import { - forgeDateTimeString, - forgeTimestampString, - forgeDateString, - forgeTimeString, -} from "../../../src/core/ForgeSQLQueryBuilder"; -import { formatDateTime, parseDateTime } from "../../../src/utils/sqlUtils"; -import { Settings } from "luxon"; - -beforeAll(() => { - Settings.defaultZone = "utc"; -}); - -afterAll(() => { - Settings.defaultZone = "system"; -}); - -describe("ForgeSQLQueryBuilder - Custom Types", () => { - describe("forgeDateTimeString", () => { - it("should create a column with datetime type", () => { - const testTable = mysqlTable("test_table", { - id: int("id").primaryKey(), - dateTimeField: forgeDateTimeString("date_time_field"), - }); - - expect(testTable).toBeDefined(); - expect(testTable.dateTimeField).toBeDefined(); - }); - - it("should convert Date to MySQL datetime string format", () => { - const date = new Date("2024-01-15T14:30:45.123Z"); - // Test the formatDateTime function directly (used by toDriver) - const result = formatDateTime(date, "yyyy-MM-dd' 'HH:mm:ss.SSS", false); - // Format: yyyy-MM-dd' 'HH:mm:ss.SSS - expect(result).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}$/); - expect(result).toContain("2024-01-15"); - }); - - it("should parse MySQL datetime string to Date", () => { - const dateString = "2024-01-15 14:30:45.123"; - // Test the parseDateTime function directly (used by fromDriver) - const result = parseDateTime(dateString, "yyyy-MM-dd' 'HH:mm:ss.SSS"); - expect(result).toBeInstanceOf(Date); - expect(result.getFullYear()).toBe(2024); - expect(result.getMonth()).toBe(0); // January (0-indexed) - expect(result.getDate()).toBe(15); - }); - - it("should handle different datetime formats", () => { - const date = new Date("2023-12-25T10:15:30.456Z"); - const result = formatDateTime(date, "yyyy-MM-dd' 'HH:mm:ss.SSS", false); - expect(result).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}$/); - }); - - it("should parse ISO date-only value with midnight time", () => { - const testTable = mysqlTable("test_table", { - id: int("id").primaryKey(), - dateTimeField: forgeDateTimeString("date_time_field"), - }); - - const mapped = (testTable.dateTimeField as any).mapFrom("2026-06-12"); - expect(mapped).toBeInstanceOf(Date); - expect(mapped.getUTCFullYear()).toBe(2026); - expect(mapped.getUTCMonth()).toBe(5); - expect(mapped.getUTCDate()).toBe(12); - expect(mapped.getUTCHours()).toBe(0); - expect(mapped.getUTCMinutes()).toBe(0); - expect(mapped.getUTCSeconds()).toBe(0); - }); - - it("should return null and undefined from driver as is", () => { - const testTable = mysqlTable("test_table", { - id: int("id").primaryKey(), - dateTimeField: forgeDateTimeString("date_time_field"), - }); - - expect((testTable.dateTimeField as any).mapFrom(null)).toBeNull(); - expect((testTable.dateTimeField as any).mapFrom(undefined)).toBeUndefined(); - }); - }); - - describe("forgeTimestampString", () => { - it("should create a column with timestamp type", () => { - const testTable = mysqlTable("test_table", { - id: int("id").primaryKey(), - timestampField: forgeTimestampString("timestamp_field"), - }); - - expect(testTable).toBeDefined(); - expect(testTable.timestampField).toBeDefined(); - }); - - it("should convert Date to MySQL timestamp string format", () => { - const date = new Date("2024-01-15T14:30:45.123Z"); - // Test the formatDateTime function with UTC conversion (used by toDriver) - const result = formatDateTime(date, "yyyy-MM-dd' 'HH:mm:ss.SSS", true); - // Format: yyyy-MM-dd' 'HH:mm:ss.SSS (with UTC conversion) - expect(result).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}$/); - }); - - it("should parse MySQL timestamp string to Date", () => { - const timestampString = "2024-01-15 14:30:45.123"; - // Test the parseDateTime function directly (used by fromDriver) - const result = parseDateTime(timestampString, "yyyy-MM-dd' 'HH:mm:ss.SSS"); - expect(result).toBeInstanceOf(Date); - expect(result.getUTCFullYear()).toBe(2024); - expect(result.getUTCMonth()).toBe(0); - expect(result.getUTCDate()).toBe(15); - }); - - it("should handle UTC conversion for timestamps", () => { - const date = new Date("2023-06-15T12:00:00.000Z"); - const result = formatDateTime(date, "yyyy-MM-dd' 'HH:mm:ss.SSS", true); - expect(result).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}$/); - }); - }); - - describe("forgeDateString", () => { - it("should create a column with date type", () => { - const testTable = mysqlTable("test_table", { - id: int("id").primaryKey(), - dateField: forgeDateString("date_field"), - }); - - expect(testTable).toBeDefined(); - expect(testTable.dateField).toBeDefined(); - }); - - it("should convert Date to MySQL date string format", () => { - const date = new Date("2024-01-15T14:30:45.123Z"); - // Test the formatDateTime function directly (used by toDriver) - const result = formatDateTime(date, "yyyy-MM-dd", false); - // Format: yyyy-MM-dd - expect(result).toMatch(/^\d{4}-\d{2}-\d{2}$/); - expect(result).toBe("2024-01-15"); - }); - - it("should parse MySQL date string to Date", () => { - const dateString = "2024-01-15"; - // Test the parseDateTime function directly (used by fromDriver) - const result = parseDateTime(dateString, "yyyy-MM-dd"); - expect(result).toBeInstanceOf(Date); - expect(result.getUTCFullYear()).toBe(2024); - expect(result.getUTCMonth()).toBe(0); - expect(result.getUTCDate()).toBe(15); - }); - - it("should handle different dates", () => { - const date = new Date("2023-12-25T10:15:30.456Z"); - const result = formatDateTime(date, "yyyy-MM-dd", false); - expect(result).toBe("2023-12-25"); - }); - - it("should handle leap year dates", () => { - const date = new Date("2024-02-29T00:00:00.000Z"); - const result = formatDateTime(date, "yyyy-MM-dd", false); - expect(result).toBe("2024-02-29"); - }); - }); - - describe("forgeTimeString", () => { - it("should create a column with time type", () => { - const testTable = mysqlTable("test_table", { - id: int("id").primaryKey(), - timeField: forgeTimeString("time_field"), - }); - - expect(testTable).toBeDefined(); - expect(testTable.timeField).toBeDefined(); - }); - - it("should convert Date to MySQL time string format", () => { - const date = new Date("2024-01-15T14:30:45.123Z"); - // Test the formatDateTime function directly (used by toDriver) - const result = formatDateTime(date, "HH:mm:ss.SSS", false); - // Format: HH:mm:ss.SSS - expect(result).toMatch(/^\d{2}:\d{2}:\d{2}\.\d{3}$/); - }); - - it("should parse MySQL time string to Date", () => { - const timeString = "14:30:45.123"; - // Test the parseDateTime function directly (used by fromDriver) - const result = parseDateTime(timeString, "HH:mm:ss.SSS"); - expect(result).toBeInstanceOf(Date); - }); - - it("should handle different times", () => { - const date = new Date("2024-01-15T23:59:59.999Z"); - const result = formatDateTime(date, "HH:mm:ss.SSS", false); - expect(result).toMatch(/^\d{2}:\d{2}:\d{2}\.\d{3}$/); - }); - - it("should handle midnight time", () => { - const date = new Date("2024-01-15T00:00:00.000Z"); - const result = formatDateTime(date, "HH:mm:ss.SSS", false); - expect(result).toMatch(/^\d{2}:\d{2}:\d{2}\.\d{3}$/); - }); - }); - - describe("Edge cases", () => { - it("should handle invalid date strings gracefully in parseDateTime", () => { - expect(() => { - parseDateTime("invalid-date", "yyyy-MM-dd' 'HH:mm:ss.SSS"); - }).not.toThrow(); - }); - - it("should handle null/undefined values in formatDateTime", () => { - // formatDateTime throws error for null/undefined, which is expected behavior - expect(() => { - formatDateTime(null as any, "yyyy-MM-dd' 'HH:mm:ss.SSS", false); - }).toThrow(); - }); - - it("should handle empty strings in parseDateTime", () => { - expect(() => { - parseDateTime("", "yyyy-MM-dd"); - }).not.toThrow(); - }); - - it("should handle very old dates", () => { - const oldDate = new Date("1900-01-01T00:00:00.000Z"); - const result = formatDateTime(oldDate, "yyyy-MM-dd", false); - expect(result).toBe("1900-01-01"); - }); - - it("should handle future dates", () => { - // Use a date that won't be affected by timezone conversion - const futureDate = new Date("2100-12-31T12:00:00.000Z"); - const result = formatDateTime(futureDate, "yyyy-MM-dd", false); - // The result might vary by timezone, so just check the format - expect(result).toMatch(/^\d{4}-\d{2}-\d{2}$/); - // Check that it's either 2100-12-31 or 2101-01-01 depending on timezone - expect(result === "2100-12-31" || result === "2101-01-01").toBe(true); - }); - }); -}); diff --git a/__tests__/src/core/ForgeSQLSelectOperations.test.ts b/__tests__/src/core/ForgeSQLSelectOperations.test.ts deleted file mode 100644 index 069f52a36..000000000 --- a/__tests__/src/core/ForgeSQLSelectOperations.test.ts +++ /dev/null @@ -1,1399 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { sql } from "@forge/sql"; -import { beforeEach, describe, expect, it, vi } from "vitest"; -import { eq, sql as rawSql } from "drizzle-orm"; -import { drizzle } from "drizzle-orm/mysql-proxy"; -import { forgeDriver, ForgeSqlOperation, patchDbWithSelectAliased } from "../../../src"; -import ForgeSQLORM from "../../../src/core/ForgeSQLORM"; -import { testEntity } from "../../entities/TestEntity"; -import { testDataEntity } from "../../entities/TestDataEntity"; -import { testEntityDateVersion } from "../../entities/TestEntityDateVersion"; -import { testEntityJoin1 } from "../../entities/TestEntityJoin1"; -import { testEntityJoin2 } from "../../entities/TestEntityJoin2"; -import { testEntityVersionDifferentDateField } from "../../entities/TestEntityVersionDifferentFieldDate"; -import { testEntityVector } from "../../entities/TestEntityVector"; -import { customTypeEntity } from "../../entities/CustomTypeEntity"; -import { DateTime } from "luxon"; -import { - vecAsText, - vecCosineDistance, - vecDims, - vecFromText, - vecL1Distance, - vecL2Distance, - vecL2Norm, - vecNegativeInnerProduct, -} from "../../../src/core/functions/VectorTiDB"; - -vi.mock("../../../src/utils/cacheUtils", () => ({ - getFromCache: async () => { - return undefined; - }, - setCacheResult: async () => {}, - hashKey: () => "key", -})); - -const mockGetOperationType = vi.fn().mockResolvedValue("QUERY"); -vi.mock("../../../src/utils/requestTypeContextUtils", async (importOriginal) => { - const actual = - await importOriginal(); - return { - ...actual, - getOperationType: (...args: any[]) => mockGetOperationType(...args), - }; -}); - -const mockWithTimeout = vi.fn((promise) => promise); -vi.mock("../../../src/utils/sqlUtils", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - withTimeout: (...args: any[]) => mockWithTimeout(...args), - }; -}); - -const mockSaveMetaDataToContext = vi.fn().mockResolvedValue(undefined); -vi.mock("../../../src/utils/metadataContextUtils", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - saveMetaDataToContext: (...args: any[]) => mockSaveMetaDataToContext(...args), - }; -}); - -vi.useFakeTimers(); -vi.setSystemTime(new Date("2023-04-12 00:00:01")); -vi.mock("@forge/sql", () => ({ - sql: { - prepare: vi.fn((query: string, endpoint?: string) => { - let procedureMock = vi.fn().mockResolvedValue({ - rows: [{ id: 1, data: "t", name: "Test" }], - metadata: { - dbExecutionTime: 1234, - responseSize: 525, - }, - }); - if ( - query === - "select `test_data_entity`.`id` as `ID1`, `test_entity`.`id` as ID2, `test_data_entity`.`data`, `test_entity`.`name` from `test_data_entity` inner join `test_entity` on `test_data_entity`.`id` = `test_entity`.`id`" - ) { - procedureMock = vi.fn().mockResolvedValue({ - rows: [{ ID1: 1, ID2: 2, data: "t", name: "Test" }], - metadata: { - dbExecutionTime: 1234, - responseSize: 525, - }, - }); - } else if (query.includes("`test_entity_vector`")) { - procedureMock = vi.fn().mockResolvedValue({ - rows: [ - { - id: 1, - name: "doc", - embedding: "[0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]", - }, - ], - metadata: { - dbExecutionTime: 1234, - responseSize: 525, - }, - }); - } else if (query.includes("`custom_Type_Entity`")) { - procedureMock = vi.fn().mockResolvedValue({ - rows: [ - { - a_id_id: 1, - a_blob_blob: { type: "Buffer", data: [1, 2, 3] }, - a_tinyblob_tinyblob: { type: "Buffer", data: [4, 5] }, - a_mediumblob_mediumblob: { type: "Buffer", data: [6] }, - a_binary_binary: { type: "Buffer", data: [7, 8, 9, 10] }, - a_varbinary_varbinary: { type: "Buffer", data: [11] }, - }, - ], - metadata: { - dbExecutionTime: 1234, - responseSize: 525, - }, - }); - } else if (query.includes("`custom_type` as `a_customtype_custom_type`")) { - // Covers `uuidBinary` custom type mapping on a dedicated select. - procedureMock = vi.fn().mockResolvedValue({ - rows: [ - { - a_customtype_custom_type: { - type: "Buffer", - data: Array.from(Buffer.from("00112233445566778899aabbccddeeff", "hex")), - }, - }, - ], - metadata: { - dbExecutionTime: 1234, - responseSize: 525, - }, - }); - } - const executeMock = procedureMock; - const mockBindParams = vi.fn(); - const mockStatement = { - query: query || "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: mockBindParams, - execute: executeMock, - }; - mockBindParams.mockReturnValue(mockStatement); - return mockStatement; - }), - }, -})); - -vi.mock("@forge/sql/out/sql", () => ({ - SQL_API_ENDPOINTS: { - EXECUTE_DDL: "EXECUTE_DDL", - }, -})); - -describe("ForgeSQLSelectOperations", () => { - let forgeSqlOperation: ForgeSqlOperation; - - beforeEach(() => { - forgeSqlOperation = new ForgeSQLORM({ logRawSqlQuery: true, cacheEntityName: "cache" }); - }); - - it("test analyses", async () => { - let schemaAnalyzeForgeSql = forgeSqlOperation.analyze(); - expect(schemaAnalyzeForgeSql).toBeDefined(); - }); - it("should call SQL prepare and execute on executeRawSQL", async () => { - const result = await forgeSqlOperation.fetch().executeRawSQL("SELECT * FROM test_entity"); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - - expect(sql.prepare).toHaveBeenCalledWith("SELECT * FROM test_entity"); - expect(preparedStatement.execute).toHaveBeenCalled(); - expect(result).toEqual([{ id: 1, name: "Test", data: "t" }]); - }); - - it("test drizzle executeQuery", async () => { - const result = await forgeSqlOperation.execute<{ id: number; name: string; data: "t" }>( - rawSql`select * from 1`, - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(sql.prepare).toHaveBeenCalledWith("select * from 1"); - - expect(preparedStatement.execute).toHaveBeenCalled(); - expect(result).toEqual([[{ id: 1, name: "Test", data: "t" }]]); - }); - - it("test drizzle executeDDL", async () => { - mockGetOperationType.mockResolvedValueOnce("DDL"); - const mockExecute = vi.fn().mockResolvedValue({ - rows: { - affectedRows: 0, - fieldCount: 0, - info: "", - insertId: 0, - serverStatus: 1, - warningStatus: 1, - }, - metadata: { - dbExecutionTime: 1234, - responseSize: 525, - }, - }); - const mockBindParams = vi.fn(); - const mockStatement = { - query: "MOCK_QUERY", - params: [], - bindParams: mockBindParams, - execute: mockExecute, - }; - mockBindParams.mockReturnValue(mockStatement); - vi.mocked(sql.prepare).mockImplementationOnce(() => mockStatement); - - const result = await forgeSqlOperation.executeDDL<{ affectedRows: number }>( - rawSql`CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255));`, - ); - expect(sql.prepare).toHaveBeenCalledWith( - `CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255));`, - "EXECUTE_DDL", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith([]); - expect(result).toEqual([ - { - affectedRows: 0, - fieldCount: 0, - info: "", - insertId: 0, - serverStatus: 1, - warningStatus: 1, - }, - ]); - }); - - it("test drizzle executeDDL string", async () => { - mockGetOperationType.mockResolvedValueOnce("DDL"); - const mockExecute = vi.fn().mockResolvedValue({ - rows: { - affectedRows: 0, - fieldCount: 0, - info: "", - insertId: 0, - serverStatus: 1, - warningStatus: 1, - }, - metadata: { - dbExecutionTime: 1234, - responseSize: 525, - }, - }); - const mockBindParams = vi.fn(); - const mockStatement = { - query: "MOCK_QUERY", - params: [], - bindParams: mockBindParams, - execute: mockExecute, - }; - mockBindParams.mockReturnValue(mockStatement); - vi.mocked(sql.prepare).mockImplementationOnce(() => mockStatement); - - const result = await forgeSqlOperation.executeDDL<{ affectedRows: number }>( - `CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255));`, - ); - expect(sql.prepare).toHaveBeenCalledWith( - `CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255));`, - "EXECUTE_DDL", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith([]); - expect(result).toEqual([ - { - affectedRows: 0, - fieldCount: 0, - info: "", - insertId: 0, - serverStatus: 1, - warningStatus: 1, - }, - ]); - }); - - it("test drizzle selectFrom", async () => { - const result = await forgeSqlOperation.selectFrom(testEntity); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - - expect(sql.prepare).toHaveBeenCalledWith( - "select `id` as `a_id_id`, `name` as `a_name_name` from `test_entity`", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - expect(result).toEqual([{ id: 1, name: "t" }]); - }); - it("test drizzle selectAndTakeMetadata", async () => { - const result = await forgeSqlOperation.executeWithMetadata( - async () => await forgeSqlOperation.select({ id: testEntity.id }).from(testEntity), - async ( - totalDbExecutionTime: number, - totalResponseSize: number, - printQueriesWithPlan: () => Promise, - ) => { - expect(totalDbExecutionTime).toEqual(1234); - expect(totalResponseSize).toEqual(525); - printQueriesWithPlan().then(); - }, - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - - expect(sql.prepare).toHaveBeenCalledWith("select `id` as `a_id_id` from `test_entity`"); - expect(preparedStatement.execute).toHaveBeenCalled(); - expect(result).toEqual([{ id: 1 }]); - }); - - it("test drizzle selectDistinctFrom", async () => { - const result = await forgeSqlOperation.selectDistinctFrom(testEntity); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - - expect(sql.prepare).toHaveBeenCalledWith( - "select distinct `id` as `a_id_id`, `name` as `a_name_name` from `test_entity`", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - expect(result).toEqual([{ id: 1, name: "t" }]); - }); - - it("should map forge binary customTypes (BLOB/BINARY/VARBINARY) from driver", async () => { - const result = await forgeSqlOperation.selectFrom(customTypeEntity); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - - expect(sql.prepare).toHaveBeenCalledWith( - "select `id` as `a_id_id`, `blob` as `a_blob_blob`, `tinyBlob` as `a_tinyblob_tinyblob`, `mediumBlob` as `a_mediumblob_mediumblob`, `binary` as `a_binary_binary`, `varBinary` as `a_varbinary_varbinary` from `custom_Type_Entity`", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - expect(result).toEqual([ - { - id: 1, - blob: Buffer.from([1, 2, 3]), - tinyBlob: Buffer.from([4, 5]), - mediumBlob: Buffer.from([6]), - binary: Buffer.from([7, 8, 9, 10]), - varBinary: Buffer.from([11]), - }, - ]); - }); - - it("should map uuidBinary (VARBINARY(16)) from driver", async () => { - const result = await forgeSqlOperation - .select({ customType: testEntityJoin1.customType }) - .from(testEntityJoin1); - - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(sql.prepare).toHaveBeenCalledWith( - "select `custom_type` as `a_customtype_custom_type` from `test_entity_join1`", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - expect(result).toEqual([{ customType: "00112233-4455-6677-8899-aabbccddeeff" }]); - }); - - it("test drizzle $with Query", async () => { - const withQuery = forgeSqlOperation.$with("withQuery").as( - forgeSqlOperation - .select({ - id: rawSql`${testEntity.id}`.as("id"), - }) - .from(testEntity), - ); - const with1 = forgeSqlOperation.with(withQuery); - const result = await with1.select({ id: withQuery.id }).from(withQuery); - - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - - expect(sql.prepare).toHaveBeenCalledWith( - "with `withQuery` as (select `id` as `id` from `test_entity`) select `id` from `withQuery`", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - expect(result).toEqual([{ id: 1 }]); - }); - - it("should call SQL for complex query SQL using Drizzle Query Builder", async () => { - const drizzle = forgeSqlOperation.getDrizzleQueryBuilder(); - - const query = drizzle - .select({ - ID1: rawSql`${testDataEntity.id} as \`ID1\``, - ID2: rawSql`${testEntity.id} as ID2`, - dataField: testDataEntity.data, - name: testEntity.name, - }) - .from(testDataEntity) - .innerJoin(testEntity, eq(testDataEntity.id, testEntity.id)); - const result = await query; - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(sql.prepare).toHaveBeenCalledWith( - "select `test_data_entity`.`id` as `ID1`, `test_entity`.`id` as ID2, `test_data_entity`.`data`, `test_entity`.`name` from `test_data_entity` inner join `test_entity` on `test_data_entity`.`id` = `test_entity`.`id`", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - expect(result).toEqual([ - { - ID1: 1, - ID2: 2, - dataField: "t", - name: "Test", - }, - ]); - }); - - it("should execute query and return single result", async () => { - const drizzle = forgeSqlOperation.getDrizzleQueryBuilder(); - - const query = drizzle - .select({ - ID1: rawSql`${testDataEntity.id} as \`ID1\``, - ID2: rawSql`${testEntity.id} as ID2`, - dataField: testDataEntity.data, - name: testEntity.name, - }) - .from(testDataEntity) - .innerJoin(testEntity, eq(testDataEntity.id, testEntity.id)); - - const result = await forgeSqlOperation.fetch().executeQueryOnlyOne(query); - - expect(result).toEqual({ - ID1: 1, - ID2: 2, - dataField: "t", - name: "Test", - }); - }); - - it("should return undefined when no results found", async () => { - const drizzle = forgeSqlOperation.getDrizzleQueryBuilder(); - - // Mock empty result - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ rows: [] }), - }) as any, - ); - - const query = drizzle - .select({ - ID1: rawSql`${testDataEntity.id} as \`ID1\``, - ID2: rawSql`${testEntity.id} as ID2`, - dataField: testDataEntity.data, - name: testEntity.name, - }) - .from(testDataEntity) - .innerJoin(testEntity, eq(testDataEntity.id, testEntity.id)); - - const result = await forgeSqlOperation.fetch().executeQueryOnlyOne(query); - - expect(result).toBeUndefined(); - }); - - it("should throw error when multiple results found", async () => { - const drizzle = forgeSqlOperation.getDrizzleQueryBuilder(); - - // Mock multiple results - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { ID1: 1, ID2: 2, data: "t", name: "Test1" }, - { ID1: 3, ID2: 4, data: "t", name: "Test2" }, - ], - }), - }) as any, - ); - - const query = drizzle - .select({ - ID1: rawSql`${testDataEntity.id} as \`ID1\``, - ID2: rawSql`${testEntity.id} as ID2`, - dataField: testDataEntity.data, - name: testEntity.name, - }) - .from(testDataEntity) - .innerJoin(testEntity, eq(testDataEntity.id, testEntity.id)); - - await expect(forgeSqlOperation.fetch().executeQueryOnlyOne(query)).rejects.toThrow( - "Expected 1 record but returned 2", - ); - }); - - it("should call SQL prepare and execute on executeRawUpdateSQL", async () => { - await forgeSqlOperation - .fetch() - .executeRawUpdateSQL("UPDATE test_entity SET name = 'Updated' WHERE id = 1"); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(sql.prepare).toHaveBeenCalledWith( - "UPDATE test_entity SET name = 'Updated' WHERE id = 1", - ); - expect(preparedStatement.execute).toHaveBeenCalled(); - }); - - it("should find duplicates in testEntity", async () => { - const drizzle = forgeSqlOperation.getDrizzleQueryBuilder(); - - // Mock multiple results with duplicates - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { name: "Test1", count: 2 }, - { name: "Test2", count: 1 }, - { name: "Test3", count: 3 }, - ], - }), - }) as any, - ); - - const query = drizzle - .select({ - name: testEntity.name, - count: rawSql`COUNT(*) as count`, - }) - .from(testEntity) - .groupBy(testEntity.name) - .having(rawSql`COUNT(*) > 1`); - - const result = await query; - - expect(result).toEqual([ - { - name: "Test1", - count: 2, - }, - { - count: 1, - name: "Test2", - }, - { name: "Test3", count: 3 }, - ]); - }); - - it("should find duplicates in testEntity2", async () => { - const drizzle = forgeSqlOperation.getDrizzleQueryBuilder(); - - // Mock multiple results with duplicates - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { - name: "Test1", - version: DateTime.fromJSDate( - DateTime.fromISO("2024-09-19T06:40:34.999999", { zone: "utc" }).toJSDate(), - ).toFormat("yyyy-LL-dd'T'HH:mm:ss.SSS"), - count: "0", - }, - { - name: "Test2", - version: DateTime.fromJSDate( - DateTime.fromISO("2023-09-19T06:40:34.999999", { zone: "utc" }).toJSDate(), - ).toFormat("yyyy-LL-dd'T'HH:mm:ss.SSS"), - count: "1", - }, - { - name: "Test3", - version: DateTime.fromISO("2022-09-19T06:40:34.999999", { zone: "utc" }).toJSDate(), - count: "2", - }, - ], - }), - }) as any, - ); - - const result = await drizzle - .select({ - name: testEntityDateVersion.name, - version: testEntityDateVersion.version, - count: rawSql`COUNT(*) as count`, - }) - .from(testEntityDateVersion) - .groupBy(testEntityDateVersion.name, testEntityDateVersion.version); - expect(result).toEqual([ - { - count: "0", - name: "Test1", - version: DateTime.fromISO("2024-09-19T06:40:34.999Z", { zone: "utc" }).toJSDate(), - }, - { - count: "1", - name: "Test2", - version: DateTime.fromISO("2023-09-19T06:40:34.999Z", { zone: "utc" }).toJSDate(), - }, - { - count: "2", - name: "Test3", - version: DateTime.fromISO("2022-09-19T06:40:34.999Z", { zone: "utc" }).toJSDate(), - }, - ]); - }); - - it("should find duplicates in testEntity without aliases", async () => { - const drizzle = forgeSqlOperation.getDrizzleQueryBuilder(); - - // Mock multiple results with duplicates - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { name: "Test1", "COUNT(*)": 2 }, - { name: "Test2", "COUNT(*)": 1 }, - { name: "Test3", "COUNT(*)": 3 }, - ], - }), - }) as any, - ); - - const query = drizzle - .select({ - name: testEntity.name, - count: rawSql`COUNT(*)`, - }) - .from(testEntity) - .groupBy(testEntity.name) - .having(rawSql`COUNT(*) > 1`); - - const result = await query; - - expect(result).toEqual([ - { name: "Test1", count: 2 }, - { name: "Test2", count: 1 }, - { name: "Test3", count: 3 }, - ]); - }); - - it("should execute query without aliases", async () => { - const drizzle = forgeSqlOperation.getDrizzleQueryBuilder(); - - // Mock result without aliases - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { id: 1, name: "Test1", data: "t" }, - { id: 2, name: "Test2", data: "t" }, - ], - }), - }) as any, - ); - - const query = drizzle - .select({ - id: testEntity.id, - name: testEntity.name, - data: testDataEntity.data, - }) - .from(testEntity) - .innerJoin(testDataEntity, eq(testEntity.id, testDataEntity.id)); - - const result = await query; - - expect(result).toEqual([ - { id: 1, name: "Test1", data: "t" }, - { id: 2, name: "Test2", data: "t" }, - ]); - }); - - it("should execute inner join with the same fields", async () => { - // Mock result without aliases - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { - test_entity_join1_id: 1, - name: "Test1", - data: "t1", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test21", - data2: "t21", - count: 1, - }, - { - test_entity_join1_id: 2, - name: "Test2", - data: "t2", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test22", - data2: "t22", - count: 2, - }, - ], - }), - }) as any, - ); - - const query = forgeSqlOperation - .select({ - table1: testEntityJoin1, - table2: { name: testEntityJoin2.name, email: testEntityJoin2.email }, - count: rawSql`COUNT(*)`, - }) - .from(testEntityJoin1) - .innerJoin(testEntityJoin2, eq(testEntityJoin1.id, testEntityJoin2.id)); - - const result = await query; - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "select `test_entity_join1`.`id` as `a_table1_test_entity_join1_id`, `test_entity_join1`.`name` as `a_table1_test_entity_join1_name`, `test_entity_join1`.`email` as `a_table1_test_entity_join1_email`, `test_entity_join1`.`custom_type` as `a_table1_test_entity_join1_custom_type`, `test_entity_join2`.`name` as `a_table2_name_name`, `test_entity_join2`.`email` as `a_table2_email_email`, COUNT(*) from `test_entity_join1` inner join `test_entity_join2` on `test_entity_join1`.`id` = `test_entity_join2`.`id`", - ); - expect(result).toEqual([ - { - table1: { - id: 1, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test1", - email: "t1", - }, - table2: { name: "Test21", email: "t21" }, - count: 1, - }, - { - table1: { - id: 2, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test2", - email: "t2", - }, - table2: { name: "Test22", email: "t22" }, - count: 2, - }, - ]); - }); - - it("run inside local cache context and Return Value", async () => { - // Mock result without aliases - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { - test_entity_join1_id: 1, - name: "Test1", - data: "t1", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test21", - data2: "t21", - count: 1, - }, - { - test_entity_join1_id: 2, - name: "Test2", - data: "t2", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test22", - data2: "t22", - count: 2, - }, - ], - }), - }) as any, - ); - const query = forgeSqlOperation - .select({ - table1: testEntityJoin1, - table2: { name: testEntityJoin2.name, email: testEntityJoin2.email }, - count: rawSql`COUNT(*)`, - }) - .from(testEntityJoin1) - .innerJoin(testEntityJoin2, eq(testEntityJoin1.id, testEntityJoin2.id)); - const result = await forgeSqlOperation.executeWithLocalCacheContextAndReturnValue(async () => { - await query; - await query; - return await query; - }); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledTimes(1); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "select `test_entity_join1`.`id` as `a_table1_test_entity_join1_id`, `test_entity_join1`.`name` as `a_table1_test_entity_join1_name`, `test_entity_join1`.`email` as `a_table1_test_entity_join1_email`, `test_entity_join1`.`custom_type` as `a_table1_test_entity_join1_custom_type`, `test_entity_join2`.`name` as `a_table2_name_name`, `test_entity_join2`.`email` as `a_table2_email_email`, COUNT(*) from `test_entity_join1` inner join `test_entity_join2` on `test_entity_join1`.`id` = `test_entity_join2`.`id`", - ); - expect(result).toEqual([ - { - table1: { - id: 1, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test1", - email: "t1", - }, - table2: { name: "Test21", email: "t21" }, - count: 1, - }, - { - table1: { - id: 2, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test2", - email: "t2", - }, - table2: { name: "Test22", email: "t22" }, - count: 2, - }, - ]); - }); - - it("run inside local cache context", async () => { - // Mock result without aliases - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { - test_entity_join1_id: 1, - name: "Test1", - data: "t1", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test21", - data2: "t21", - count: 1, - }, - { - test_entity_join1_id: 2, - name: "Test2", - data: "t2", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test22", - data2: "t22", - count: 2, - }, - ], - }), - }) as any, - ); - const query = forgeSqlOperation - .select({ - table1: testEntityJoin1, - table2: { name: testEntityJoin2.name, email: testEntityJoin2.email }, - count: rawSql`COUNT(*)`, - }) - .from(testEntityJoin1) - .innerJoin(testEntityJoin2, eq(testEntityJoin1.id, testEntityJoin2.id)); - await forgeSqlOperation.executeWithLocalContext(async () => { - await query; - const result = await query; - expect(vi.mocked(sql.prepare)).toHaveBeenCalledTimes(1); - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "select `test_entity_join1`.`id` as `a_table1_test_entity_join1_id`, `test_entity_join1`.`name` as `a_table1_test_entity_join1_name`, `test_entity_join1`.`email` as `a_table1_test_entity_join1_email`, `test_entity_join1`.`custom_type` as `a_table1_test_entity_join1_custom_type`, `test_entity_join2`.`name` as `a_table2_name_name`, `test_entity_join2`.`email` as `a_table2_email_email`, COUNT(*) from `test_entity_join1` inner join `test_entity_join2` on `test_entity_join1`.`id` = `test_entity_join2`.`id`", - ); - expect(result).toEqual([ - { - table1: { - id: 1, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test1", - email: "t1", - }, - table2: { name: "Test21", email: "t21" }, - count: 1, - }, - { - table1: { - id: 2, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test2", - email: "t2", - }, - table2: { name: "Test22", email: "t22" }, - count: 2, - }, - ]); - }); - - expect(vi.mocked(sql.prepare)).toHaveBeenCalledTimes(1); - }); - - it("should execute inner join with the same diff fields", async () => { - // Mock result without aliases - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { - id: 1, - name: "Test1", - date: DateTime.fromSQL("2025-04-07 18:06:21").toFormat("yyyy-LL-dd HH:mm:ss"), - date2: DateTime.fromSQL("2025-04-07 18:06:21").toFormat("yyyy-LL-dd HH:mm:ss"), - }, - { - id: 1, - name: "Test2", - date: DateTime.fromSQL("2025-04-07 18:06:21").toFormat("yyyy-LL-dd HH:mm:ss"), - date2: DateTime.fromSQL("2025-04-07 18:06:21").toFormat("yyyy-LL-dd HH:mm:ss"), - }, - ], - }), - }) as any, - ); - - const query = forgeSqlOperation - .select({ - table1: testEntityVersionDifferentDateField, - table2: { - column: testEntityVersionDifferentDateField.versionField, - }, - }) - .from(testEntityJoin1) - .innerJoin(testEntityJoin2, eq(testEntityJoin1.id, testEntityVersionDifferentDateField.id)); - - const result = await query; - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "select `test_entity_diff_date_version`.`id` as `a_table1_test_entity_diff_date_version_id`, `test_entity_diff_date_version`.`name` as `a_table1_test_entity_diff_date_version_name`, `test_entity_diff_date_version`.`version_different_date_field` as `a_table1_test_entity_diff_date_version_version_different_date_field`, `test_entity_diff_date_version`.`version_different_date_field` as `a_table2_column_version_different_date_field` from `test_entity_join1` inner join `test_entity_join2` on `test_entity_join1`.`id` = `test_entity_diff_date_version`.`id`", - ); - expect(result).toEqual([ - { - table1: { - id: 1, - name: "Test1", - versionField: DateTime.fromSQL("2025-04-07 18:06:21").toJSDate(), - }, - table2: { - column: DateTime.fromSQL("2025-04-07 18:06:21").toJSDate(), - }, - }, - { - table1: { - id: 1, - name: "Test2", - versionField: DateTime.fromSQL("2025-04-07 18:06:21").toJSDate(), - }, - table2: { - column: DateTime.fromSQL("2025-04-07 18:06:21").toJSDate(), - }, - }, - ]); - }); - - it("should execute inner join with the same fields distinct", async () => { - // Mock result without aliases - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { - test_entity_join1_id: 1, - name: "Test1", - data: "t1", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test21", - data2: "t21", - count: 1, - }, - { - test_entity_join1_id: 2, - name: "Test2", - data: "t2", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test22", - data2: "t22", - count: 2, - }, - ], - }), - }) as any, - ); - - const query = forgeSqlOperation - .selectDistinct({ - table1: testEntityJoin1, - table2: { name: testEntityJoin2.name, email: testEntityJoin2.email }, - count: rawSql`COUNT(*)`, - }) - .from(testEntityJoin1) - .innerJoin(testEntityJoin2, eq(testEntityJoin1.id, testEntityJoin2.id)); - - const result = await query; - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "select distinct `test_entity_join1`.`id` as `a_table1_test_entity_join1_id`, `test_entity_join1`.`name` as `a_table1_test_entity_join1_name`, `test_entity_join1`.`email` as `a_table1_test_entity_join1_email`, `test_entity_join1`.`custom_type` as `a_table1_test_entity_join1_custom_type`, `test_entity_join2`.`name` as `a_table2_name_name`, `test_entity_join2`.`email` as `a_table2_email_email`, COUNT(*) from `test_entity_join1` inner join `test_entity_join2` on `test_entity_join1`.`id` = `test_entity_join2`.`id`", - ); - expect(result).toEqual([ - { - table1: { - id: 1, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test1", - email: "t1", - }, - table2: { name: "Test21", email: "t21" }, - count: 1, - }, - { - table1: { - id: 2, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test2", - email: "t2", - }, - table2: { name: "Test22", email: "t22" }, - count: 2, - }, - ]); - }); - - it("should execute inner join with the same fields dirrect drizzle", async () => { - // Mock result without aliases - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { - test_entity_join1_id: 1, - name: "Test1", - data: "t1", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test21", - data2: "t21", - count: 1, - }, - { - test_entity_join1_id: 2, - name: "Test2", - data: "t2", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test22", - data2: "t22", - count: 2, - }, - ], - }), - }) as any, - ); - - const db = patchDbWithSelectAliased(drizzle(forgeDriver, { logger: true })); - const query = db - .selectAliased({ - table1: testEntityJoin1, - table2: { name: testEntityJoin2.name, email: testEntityJoin2.email }, - count: rawSql`COUNT(*)`, - }) - .from(testEntityJoin1) - .innerJoin(testEntityJoin2, eq(testEntityJoin1.id, testEntityJoin2.id)); - - const result = await query; - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "select `test_entity_join1`.`id` as `a_table1_test_entity_join1_id`, `test_entity_join1`.`name` as `a_table1_test_entity_join1_name`, `test_entity_join1`.`email` as `a_table1_test_entity_join1_email`, `test_entity_join1`.`custom_type` as `a_table1_test_entity_join1_custom_type`, `test_entity_join2`.`name` as `a_table2_name_name`, `test_entity_join2`.`email` as `a_table2_email_email`, COUNT(*) from `test_entity_join1` inner join `test_entity_join2` on `test_entity_join1`.`id` = `test_entity_join2`.`id`", - ); - expect(result).toEqual([ - { - table1: { - id: 1, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test1", - email: "t1", - }, - table2: { name: "Test21", email: "t21" }, - count: 1, - }, - { - table1: { - id: 2, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test2", - email: "t2", - }, - table2: { name: "Test22", email: "t22" }, - count: 2, - }, - ]); - }); - - it("should execute inner join with the same fields dirrect drizzle distinct", async () => { - // Mock result without aliases - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { - test_entity_join1_id: 1, - name: "Test1", - data: "t1", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test21", - data2: "t21", - count: 1, - }, - { - test_entity_join1_id: 2, - name: "Test2", - data: "t2", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test22", - data2: "t22", - count: 2, - }, - ], - }), - }) as any, - ); - - const db = patchDbWithSelectAliased(drizzle(forgeDriver, { logger: true })); - const query = db - .selectAliasedDistinct({ - table1: testEntityJoin1, - table2: { name: testEntityJoin2.name, email: testEntityJoin2.email }, - count: rawSql`COUNT(*)`, - }) - .from(testEntityJoin1) - .innerJoin(testEntityJoin2, eq(testEntityJoin1.id, testEntityJoin2.id)); - - const result = await query; - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "select distinct `test_entity_join1`.`id` as `a_table1_test_entity_join1_id`, `test_entity_join1`.`name` as `a_table1_test_entity_join1_name`, `test_entity_join1`.`email` as `a_table1_test_entity_join1_email`, `test_entity_join1`.`custom_type` as `a_table1_test_entity_join1_custom_type`, `test_entity_join2`.`name` as `a_table2_name_name`, `test_entity_join2`.`email` as `a_table2_email_email`, COUNT(*) from `test_entity_join1` inner join `test_entity_join2` on `test_entity_join1`.`id` = `test_entity_join2`.`id`", - ); - expect(result).toEqual([ - { - table1: { - id: 1, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test1", - email: "t1", - }, - table2: { name: "Test21", email: "t21" }, - count: 1, - }, - { - table1: { - id: 2, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test2", - email: "t2", - }, - table2: { name: "Test22", email: "t22" }, - count: 2, - }, - ]); - }); - - it("should execute inner join Null Check", async () => { - // Mock result without aliases - vi.mocked(sql.prepare).mockImplementationOnce( - () => - ({ - query: "MOCK_QUERY", - params: [], - bindParams: vi.fn(), - execute: vi.fn().mockResolvedValue({ - rows: [ - { - test_entity_join1_id: 1, - name: "Test1", - data: "t1", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test21", - data2: "t21", - count: 1, - }, - { - test_entity_join1_id: 2, - name: "Test2", - data: "t2", - uuid: { - type: "Buffer", - data: [30, 99, 207, 161, 17, 125, 64, 225, 184, 232, 63, 77, 155, 199, 209, 184], - }, - name2: "Test22", - data2: "t22", - count: 2, - table3_table12: "name", - table3_table22: null, - }, - ], - }), - }) as any, - ); - - const query = forgeSqlOperation - .select({ - table1: testEntityJoin1, - table2: { name: testEntityJoin2.name, email: testEntityJoin2.email }, - count: rawSql`COUNT(*)`, - table3: { - table12: testEntityJoin1.name, - table22: testEntityJoin2.email, - table32: testEntity.id, - }, - }) - .from(testEntityJoin1) - .innerJoin(testEntityJoin2, eq(testEntityJoin1.id, testEntityJoin2.id)); - - const result = await query; - expect(vi.mocked(sql.prepare)).toHaveBeenCalledWith( - "select `test_entity_join1`.`id` as `a_table1_test_entity_join1_id`, `test_entity_join1`.`name` as `a_table1_test_entity_join1_name`, `test_entity_join1`.`email` as `a_table1_test_entity_join1_email`, `test_entity_join1`.`custom_type` as `a_table1_test_entity_join1_custom_type`, `test_entity_join2`.`name` as `a_table2_name_name`, `test_entity_join2`.`email` as `a_table2_email_email`, COUNT(*), `test_entity_join1`.`name` as `a_table3_table12_name`, `test_entity_join2`.`email` as `a_table3_table22_email`, `test_entity`.`id` as `a_table3_table32_id` from `test_entity_join1` inner join `test_entity_join2` on `test_entity_join1`.`id` = `test_entity_join2`.`id`", - ); - expect(result).toEqual([ - { - table1: { - id: 1, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test1", - email: "t1", - }, - table2: { name: "Test21", email: "t21" }, - count: 1, - table3: null, - }, - { - table1: { - id: 2, - customType: "1e63cfa1-117d-40e1-b8e8-3f4d9bc7d1b8", - name: "Test2", - email: "t2", - }, - table2: { name: "Test22", email: "t22" }, - count: 2, - table3: { table12: "name", table22: null, table32: null }, - }, - ]); - }); - - describe("VectorTiDB — SQL emitted for TiDB vector helpers", () => { - /** Matches `VECTOR(10)` column `test_entity_vector.embedding` */ - const QUERY_VECTOR_10 = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]; - - beforeEach(() => { - vi.mocked(sql.prepare).mockClear(); - }); - - it("selectFrom includes VECTOR column (vectorTiDBType)", async () => { - await forgeSqlOperation.selectFrom(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith( - "select `id` as `a_id_id`, `name` as `a_name_name`, `embedding` as `a_embedding_embedding` from `test_entity_vector`", - ); - }); - - it("vecAsText(column)", async () => { - await forgeSqlOperation - .select({ x: vecAsText(testEntityVector.embedding) }) - .from(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith( - "select VEC_AS_TEXT(`test_entity_vector`.`embedding`) from `test_entity_vector`", - ); - }); - - it("vecDims(column)", async () => { - await forgeSqlOperation - .select({ x: vecDims(testEntityVector.embedding) }) - .from(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith( - "select VEC_DIMS(`test_entity_vector`.`embedding`) from `test_entity_vector`", - ); - }); - - it("vecDims(number[]) uses placeholder in VEC_FROM_TEXT", async () => { - await forgeSqlOperation.select({ x: vecDims(QUERY_VECTOR_10) }).from(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith( - "select VEC_DIMS(VEC_FROM_TEXT(?)) from `test_entity_vector`", - ); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith( - "[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1]", - ); - }); - - it("vecL2Norm(column)", async () => { - await forgeSqlOperation - .select({ x: vecL2Norm(testEntityVector.embedding) }) - .from(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith( - "select VEC_L2_NORM(`test_entity_vector`.`embedding`) from `test_entity_vector`", - ); - }); - - it("vecL2Distance(column, number[])", async () => { - await forgeSqlOperation - .select({ x: vecL2Distance(testEntityVector.embedding, QUERY_VECTOR_10) }) - .from(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith( - "select VEC_L2_DISTANCE(`test_entity_vector`.`embedding`, VEC_FROM_TEXT(?)) from `test_entity_vector`", - ); - }); - - it("vecCosineDistance(column, number[])", async () => { - await forgeSqlOperation - .select({ x: vecCosineDistance(testEntityVector.embedding, QUERY_VECTOR_10) }) - .from(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith( - "select VEC_COSINE_DISTANCE(`test_entity_vector`.`embedding`, VEC_FROM_TEXT(?)) from `test_entity_vector`", - ); - }); - - it("vecNegativeInnerProduct(column, number[])", async () => { - await forgeSqlOperation - .select({ x: vecNegativeInnerProduct(testEntityVector.embedding, QUERY_VECTOR_10) }) - .from(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith( - "select VEC_NEGATIVE_INNER_PRODUCT(`test_entity_vector`.`embedding`, VEC_FROM_TEXT(?)) from `test_entity_vector`", - ); - }); - - it("vecL1Distance(column, number[])", async () => { - await forgeSqlOperation - .select({ x: vecL1Distance(testEntityVector.embedding, QUERY_VECTOR_10) }) - .from(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith( - "select VEC_L1_DISTANCE(`test_entity_vector`.`embedding`, VEC_FROM_TEXT(?)) from `test_entity_vector`", - ); - }); - - it("vecFromText(text) uses parameter placeholder", async () => { - await forgeSqlOperation - .select({ x: vecFromText("[1,2,3,4,5,6,7,8,9,10]") }) - .from(testEntityVector); - expect(sql.prepare).toHaveBeenCalledWith("select VEC_FROM_TEXT(?) from `test_entity_vector`"); - const preparedStatement = vi.mocked(sql.prepare).mock.results[0].value; - expect(preparedStatement.bindParams).toHaveBeenCalledWith("[1,2,3,4,5,6,7,8,9,10]"); - }); - }); -}); diff --git a/__tests__/src/core/SystemTables.test.ts b/__tests__/src/core/SystemTables.test.ts deleted file mode 100644 index a48bc2317..000000000 --- a/__tests__/src/core/SystemTables.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, vi, beforeEach } from "vitest"; -import { sql } from "@forge/sql"; -import { getTables, forgeSystemTables, migrations } from "../../../src/core/SystemTables"; -import { Table } from "drizzle-orm"; - -vi.mock("@forge/sql", () => ({ - sql: { - executeDDL: vi.fn(), - }, -})); - -describe("SystemTables", () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - - describe("forgeSystemTables", () => { - it("should contain the migrations table", () => { - expect(forgeSystemTables).toHaveLength(1); - expect(forgeSystemTables[0]).toBe(migrations); - }); - - it("should have correct migrations table structure", () => { - const table = forgeSystemTables[0] as Table; - expect(table).toBeDefined(); - expect(table).toBe(migrations); - }); - }); - - describe("getTables", () => { - it("should return array of table names", async () => { - const mockTables = { - rows: [ - { Tables_in_database: "table1" }, - { Tables_in_database: "table2" }, - { Tables_in_database: "table3" }, - ], - }; - - vi.mocked(sql.executeDDL).mockResolvedValueOnce(mockTables); - - const result = await getTables(); - expect(result).toEqual(["table1", "table2", "table3"]); - expect(sql.executeDDL).toHaveBeenCalledWith("SHOW TABLES"); - }); - - it("should handle empty result set", async () => { - const mockTables = { - rows: [], - }; - - vi.mocked(sql.executeDDL).mockResolvedValueOnce(mockTables); - - const result = await getTables(); - expect(result).toEqual([]); - expect(sql.executeDDL).toHaveBeenCalledWith("SHOW TABLES"); - }); - - it("should handle error from executeDDL", async () => { - const error = new Error("Database error"); - vi.mocked(sql.executeDDL).mockRejectedValueOnce(error); - - await expect(getTables()).rejects.toThrow("Database error"); - expect(sql.executeDDL).toHaveBeenCalledWith("SHOW TABLES"); - }); - - it("should handle unexpected response format", async () => { - const mockTables = { - rows: [ - { unexpected_key: "table1" }, - { Tables_in_database: "table2" }, - { another_key: "table3" }, - ], - }; - - vi.mocked(sql.executeDDL).mockResolvedValueOnce(mockTables); - - const result = await getTables(); - expect(result).toEqual(["table1", "table2", "table3"]); - expect(sql.executeDDL).toHaveBeenCalledWith("SHOW TABLES"); - }); - }); -}); diff --git a/__tests__/src/core/customTypes.test.ts b/__tests__/src/core/customTypes.test.ts deleted file mode 100644 index 6ce8f1d81..000000000 --- a/__tests__/src/core/customTypes.test.ts +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable } from "drizzle-orm/mysql-core"; -import { - forgeBinary, - forgeBLOB, - forgeMediumBLOB, - forgeTinyBLOB, - forgeVarBinary, - uuidBinary, - vectorTiDBType, -} from "../../../src"; - -const t = mysqlTable("custom_types_t", { - id: int("id").primaryKey(), - uuid: uuidBinary("uuid_col"), - vec3: vectorTiDBType("vec3", { dimension: 3 }), - vb: forgeVarBinary("vb", { length: 32 }), - b: forgeBinary("b", { length: 8 }), - blob: forgeBLOB("blob"), - tiny: forgeTinyBLOB("tiny"), - medium: forgeMediumBLOB("medium"), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("customTypes", () => { - describe("uuidBinary", () => { - it("uses varbinary(16) and UUID_TO_BIN on write", () => { - expect(cols.uuid.getSQLType()).toBe("varbinary(16)"); - const built = cols.uuid - .mapToDriverValue("00112233-4455-6677-8899-aabbccddeeff") - .toQuery(mysqlQueryConfig); - expect(built.sql).toBe("UUID_TO_BIN(?)"); - expect(built.params).toEqual(["00112233-4455-6677-8899-aabbccddeeff"]); - }); - - it("converts 16-byte driver buffer back to UUID string", () => { - const value = cols.uuid.mapFromDriverValue({ - type: "Buffer", - data: Array.from(Buffer.from("00112233445566778899aabbccddeeff", "hex")), - }); - expect(value).toBe("00112233-4455-6677-8899-aabbccddeeff"); - }); - - it("throws on invalid UUID buffer length", () => { - expect(() => - cols.uuid.mapFromDriverValue({ - type: "Buffer", - data: [1, 2, 3], - } as any), - ).toThrow("Invalid UUID buffer length: 3"); - }); - }); - - describe("vectorTiDBType", () => { - it("builds VECTOR ddl and serializes arrays", () => { - expect(cols.vec3.getSQLType()).toBe("vector(3)"); - expect(cols.vec3.mapToDriverValue([1, 2, 3])).toBe("[1,2,3]"); - }); - - it("parses vector text and passes nullish values through", () => { - expect(cols.vec3.mapFromDriverValue("[1,2,3]")).toEqual([1, 2, 3]); - expect(cols.vec3.mapFromDriverValue(null as any)).toBeNull(); - expect(cols.vec3.mapFromDriverValue(undefined as any)).toBeUndefined(); - }); - - it("rejects invalid vector values", () => { - expect(() => cols.vec3.mapToDriverValue([1, Number.NaN, 3])).toThrow( - "TiDB vector contains invalid number", - ); - expect(() => cols.vec3.mapFromDriverValue(42 as any)).toThrow( - "Invalid TiDB vector driver value type: number", - ); - expect(() => cols.vec3.mapFromDriverValue("{}" as any)).toThrow("Invalid TiDB vector text"); - }); - }); - - describe("forge binary/blob types", () => { - it("build correct SQL types", () => { - expect(cols.vb.getSQLType()).toBe("varbinary(32)"); - expect(cols.b.getSQLType()).toBe("binary(8)"); - expect(cols.blob.getSQLType()).toBe("BLOB"); - expect(cols.tiny.getSQLType()).toBe("TINYBLOB"); - expect(cols.medium.getSQLType()).toBe("MEDIUMBLOB"); - }); - - it("writes Buffer / Uint8Array / string via FROM_BASE64", () => { - const bufferBuilt = cols.vb - .mapToDriverValue(Buffer.from([1, 2, 3])) - .toQuery(mysqlQueryConfig); - expect(bufferBuilt.sql).toBe("FROM_BASE64(?)"); - expect(bufferBuilt.params).toEqual([Buffer.from([1, 2, 3]).toString("base64")]); - - const uint8Built = cols.b - .mapToDriverValue(new Uint8Array([4, 5]) as any) - .toQuery(mysqlQueryConfig); - expect(uint8Built.sql).toBe("FROM_BASE64(?)"); - expect(uint8Built.params).toEqual([Buffer.from([4, 5]).toString("base64")]); - - const stringBuilt = cols.blob.mapToDriverValue("hello" as any).toQuery(mysqlQueryConfig); - expect(stringBuilt.sql).toBe("FROM_BASE64(?)"); - expect(stringBuilt.params).toEqual([Buffer.from("hello").toString("base64")]); - }); - - it("serializes object/number with JSON.stringify before FROM_BASE64", () => { - const objectBuilt = cols.tiny.mapToDriverValue({ a: 1 } as any).toQuery(mysqlQueryConfig); - expect(objectBuilt.sql).toBe("FROM_BASE64(?)"); - expect(objectBuilt.params).toEqual([ - Buffer.from(JSON.stringify({ a: 1 })).toString("base64"), - ]); - - const numberBuilt = cols.medium.mapToDriverValue(123 as any).toQuery(mysqlQueryConfig); - expect(numberBuilt.sql).toBe("FROM_BASE64(?)"); - expect(numberBuilt.params).toEqual([Buffer.from(JSON.stringify(123)).toString("base64")]); - }); - - it("handles nullish writes and empty-buffer reads", () => { - expect(cols.vb.mapToDriverValue(null as any).toQuery(mysqlQueryConfig).sql).toBe("null"); - expect(cols.vb.mapToDriverValue(undefined as any).toQuery(mysqlQueryConfig).sql).toBe("null"); - expect(cols.vb.mapFromDriverValue(null as any)).toEqual(Buffer.from([])); - expect(cols.vb.mapFromDriverValue(undefined as any)).toEqual(Buffer.from([])); - }); - - it("restores Buffer from driver buffer object", () => { - expect(cols.vb.mapFromDriverValue({ type: "Buffer", data: [9, 8, 7] } as any)).toEqual( - Buffer.from([9, 8, 7]), - ); - }); - }); -}); diff --git a/__tests__/src/core/functions/AggregateTiDB.test.ts b/__tests__/src/core/functions/AggregateTiDB.test.ts deleted file mode 100644 index a7de7786c..000000000 --- a/__tests__/src/core/functions/AggregateTiDB.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable, varchar } from "drizzle-orm/mysql-core"; -import { - approxCountDistinct, - approxPercentile, - groupConcat, - groupConcatDistinct, - std, - stddev, - stddevPop, - stddevSamp, - varPop, - varSamp, - variance, -} from "../../../../src/core/functions/AggregateTiDB"; - -const t = mysqlTable("agg_t", { - id: int("id").primaryKey(), - n: int("n"), - s: varchar("s", { length: 64 }), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("AggregateTiDB SQL fragments (toQuery)", () => { - it("GROUP_CONCAT variants", () => { - expect(groupConcat(cols.s).toQuery(mysqlQueryConfig).sql).toBe("GROUP_CONCAT(`agg_t`.`s`)"); - expect(groupConcat(cols.s, "|").toQuery(mysqlQueryConfig).sql).toBe( - "GROUP_CONCAT(`agg_t`.`s` SEPARATOR ?)", - ); - expect(groupConcatDistinct(cols.s).toQuery(mysqlQueryConfig).sql).toBe( - "GROUP_CONCAT(DISTINCT `agg_t`.`s`)", - ); - expect(groupConcatDistinct(cols.s, ",").toQuery(mysqlQueryConfig).sql).toBe( - "GROUP_CONCAT(DISTINCT `agg_t`.`s` SEPARATOR ?)", - ); - }); - - it("variance/stddev family", () => { - expect(variance(cols.n).toQuery(mysqlQueryConfig).sql).toBe("VARIANCE(`agg_t`.`n`)"); - expect(varPop(cols.n).toQuery(mysqlQueryConfig).sql).toBe("VAR_POP(`agg_t`.`n`)"); - expect(std(cols.n).toQuery(mysqlQueryConfig).sql).toBe("STD(`agg_t`.`n`)"); - expect(stddev(cols.n).toQuery(mysqlQueryConfig).sql).toBe("STDDEV(`agg_t`.`n`)"); - expect(stddevPop(cols.n).toQuery(mysqlQueryConfig).sql).toBe("STDDEV_POP(`agg_t`.`n`)"); - expect(varSamp(cols.n).toQuery(mysqlQueryConfig).sql).toBe("VAR_SAMP(`agg_t`.`n`)"); - expect(stddevSamp(cols.n).toQuery(mysqlQueryConfig).sql).toBe("STDDEV_SAMP(`agg_t`.`n`)"); - }); - - it("TiDB approximate aggregates", () => { - const p = approxPercentile(cols.n, 50).toQuery(mysqlQueryConfig); - expect(p.sql).toBe("APPROX_PERCENTILE(`agg_t`.`n`, ?)"); - expect(p.params).toEqual([50]); - - const c = approxCountDistinct(cols.n, cols.s).toQuery(mysqlQueryConfig); - expect(c.sql).toBe("APPROX_COUNT_DISTINCT(`agg_t`.`n`, `agg_t`.`s`)"); - }); -}); diff --git a/__tests__/src/core/functions/BitTiDB.test.ts b/__tests__/src/core/functions/BitTiDB.test.ts deleted file mode 100644 index a136a5101..000000000 --- a/__tests__/src/core/functions/BitTiDB.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns, sql as dsql } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable } from "drizzle-orm/mysql-core"; -import { - bitAnd, - bitCount, - bitNot, - bitOr, - bitShl, - bitShr, - bitXor, -} from "../../../../src/core/functions/BitTiDB"; - -const t = mysqlTable("bit_t", { - id: int("id").primaryKey(), - flags: int("flags"), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("BitTiDB SQL fragments (toQuery)", () => { - it("BIT_COUNT", () => { - const q = bitCount(dsql`b'00101001'`).toQuery(mysqlQueryConfig); - expect(q.sql).toBe("BIT_COUNT(b'00101001')"); - }); - - it("bitwise operators with column and literals", () => { - expect(bitAnd(cols.flags, 15).toQuery(mysqlQueryConfig).sql).toBe("(`bit_t`.`flags` & ?)"); - expect(bitOr(cols.flags, 1).toQuery(mysqlQueryConfig).sql).toBe("(`bit_t`.`flags` | ?)"); - expect(bitXor(cols.flags, cols.flags).toQuery(mysqlQueryConfig).sql).toBe( - "(`bit_t`.`flags` ^ `bit_t`.`flags`)", - ); - expect(bitNot(cols.flags).toQuery(mysqlQueryConfig).sql).toBe("(~`bit_t`.`flags`)"); - }); - - it("shifts", () => { - expect(bitShl(1, cols.id).toQuery(mysqlQueryConfig).sql).toBe("(? << `bit_t`.`id`)"); - expect(bitShr(1024, 4).toQuery(mysqlQueryConfig).sql).toBe("(? >> ?)"); - expect(bitShr(1024, 4).toQuery(mysqlQueryConfig).params).toEqual([1024, 4]); - }); -}); diff --git a/__tests__/src/core/functions/CastTiDB.test.ts b/__tests__/src/core/functions/CastTiDB.test.ts deleted file mode 100644 index 97b0b7110..000000000 --- a/__tests__/src/core/functions/CastTiDB.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable, text } from "drizzle-orm/mysql-core"; -import { - castTargetArray, - castTargetBinary, - castTargetChar, - castTargetDate, - castTargetDateTime, - castTargetDecimal, - castTargetDouble, - castTargetFloat, - castTargetJson, - castTargetReal, - castTargetSigned, - castTargetSignedInteger, - castTargetTime, - castTargetUnsigned, - castTargetUnsignedInteger, - castTargetVector, - castTargetYear, - sqlBinary, - sqlCast, - sqlConvert, - sqlConvertUsing, -} from "../../../../src"; - -const t = mysqlTable("cast_t", { - id: int("id").primaryKey(), - body: text("body"), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("CastTiDB SQL fragments (toQuery)", () => { - it("sqlCast with castTarget helpers", () => { - const q = sqlCast(0x54694442, castTargetChar()).toQuery(mysqlQueryConfig); - expect(q.sql).toBe("CAST(? AS CHAR)"); - expect(q.params?.[0]).toBe(0x54694442); - - expect(sqlCast(cols.body, castTargetDateTime(3)).toQuery(mysqlQueryConfig).sql).toBe( - "CAST(`cast_t`.`body` AS DATETIME(3))", - ); - - expect(sqlCast(cols.id, castTargetDecimal(12, 2)).toQuery(mysqlQueryConfig).sql).toBe( - "CAST(`cast_t`.`id` AS DECIMAL(12, 2))", - ); - }); - - it("sqlCast ARRAY target for multi-valued index style", () => { - const inner = castTargetArray(castTargetUnsigned()); - expect(inner).toBe("UNSIGNED ARRAY"); - const q = sqlCast(cols.body, inner).toQuery(mysqlQueryConfig); - expect(q.sql).toBe("CAST(`cast_t`.`body` AS UNSIGNED ARRAY)"); - }); - - it("sqlConvert and sqlConvertUsing", () => { - expect(sqlConvert(0x616263, castTargetChar()).toQuery(mysqlQueryConfig).sql).toBe( - "CONVERT(?, CHAR)", - ); - expect(sqlConvertUsing(0x616263, "utf8mb4").toQuery(mysqlQueryConfig).sql).toBe( - "CONVERT(? USING utf8mb4)", - ); - }); - - it("sqlBinary (deprecated operator)", () => { - expect(sqlBinary(cols.body).toQuery(mysqlQueryConfig).sql).toBe("BINARY `cast_t`.`body`"); - }); - - it("castTarget helpers cover optional branches via sqlCast / sqlConvert", () => { - const q = mysqlQueryConfig; - const id = cols.id; - - expect(sqlCast(id, castTargetBinary()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS BINARY)"); - expect(sqlCast(id, castTargetBinary(16)).toQuery(q).sql).toBe( - "CAST(`cast_t`.`id` AS BINARY(16))", - ); - expect(sqlCast(id, castTargetChar()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS CHAR)"); - expect(sqlCast(id, castTargetChar(10)).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS CHAR(10))"); - expect(sqlCast(id, castTargetDate()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS DATE)"); - expect(sqlCast(id, castTargetDateTime()).toQuery(q).sql).toBe( - "CAST(`cast_t`.`id` AS DATETIME)", - ); - expect(sqlCast(id, castTargetDecimal()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS DECIMAL)"); - expect(sqlCast(id, castTargetDecimal(10)).toQuery(q).sql).toBe( - "CAST(`cast_t`.`id` AS DECIMAL(10))", - ); - expect(sqlCast(id, castTargetDouble()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS DOUBLE)"); - expect(sqlCast(id, castTargetFloat()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS FLOAT)"); - expect(sqlCast(id, castTargetFloat(24)).toQuery(q).sql).toBe( - "CAST(`cast_t`.`id` AS FLOAT(24))", - ); - expect(sqlCast(id, castTargetJson()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS JSON)"); - expect(sqlCast(id, castTargetReal()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS REAL)"); - expect(sqlCast(id, castTargetSigned()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS SIGNED)"); - expect(sqlCast(id, castTargetSignedInteger()).toQuery(q).sql).toBe( - "CAST(`cast_t`.`id` AS SIGNED INTEGER)", - ); - expect(sqlCast(id, castTargetUnsignedInteger()).toQuery(q).sql).toBe( - "CAST(`cast_t`.`id` AS UNSIGNED INTEGER)", - ); - expect(sqlCast(id, castTargetTime()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS TIME)"); - expect(sqlCast(id, castTargetTime(3)).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS TIME(3))"); - expect(sqlCast(id, castTargetVector()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS VECTOR)"); - expect(sqlCast(id, castTargetYear()).toQuery(q).sql).toBe("CAST(`cast_t`.`id` AS YEAR)"); - - expect(sqlConvert(id, castTargetBinary(8)).toQuery(q).sql).toBe( - "CONVERT(`cast_t`.`id`, BINARY(8))", - ); - }); -}); diff --git a/__tests__/src/core/functions/DateTiDB.test.ts b/__tests__/src/core/functions/DateTiDB.test.ts deleted file mode 100644 index f0e26524e..000000000 --- a/__tests__/src/core/functions/DateTiDB.test.ts +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns, type SQL } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable, timestamp } from "drizzle-orm/mysql-core"; -import { - addDate, - addTime, - convertTz, - curdate, - currentDate, - currentTime, - currentTimestamp, - curtime, - dateAdd, - dateDiff, - dateFormat, - dateOf, - dateSub, - day, - dayName, - dayOfMonth, - dayOfWeek, - dayOfYear, - extract, - fromDays, - fromUnixtime, - getFormat, - hour, - interval, - lastDay, - localTime, - localTimestamp, - makeDate, - makeTime, - microsecond, - minute, - month, - monthName, - now, - periodAdd, - periodDiff, - quarter, - secToTime, - second, - strToDate, - subDate, - subTime, - sysdate, - timeDiff, - timeFormat, - timeOf, - timeToSec, - timestampAdd, - timestampDiff, - timestampExpr, - toDays, - toSeconds, - unixTimestamp, - utcDate, - utcTime, - utcTimestamp, - week, - weekDay, - weekOfYear, - year, - yearWeek, -} from "../../../../src"; - -const t = mysqlTable("date_t", { - id: int("id").primaryKey(), - created: timestamp("created"), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("DateTiDB SQL fragments (toQuery)", () => { - it("no-arg and optional-fsp datetime functions", () => { - expect(curdate().toQuery(mysqlQueryConfig).sql).toBe("CURDATE()"); - expect(now().toQuery(mysqlQueryConfig).sql).toBe("NOW()"); - expect(now(3).toQuery(mysqlQueryConfig).sql).toBe("NOW(?)"); - expect(unixTimestamp().toQuery(mysqlQueryConfig).sql).toBe("UNIX_TIMESTAMP()"); - expect(unixTimestamp(cols.created).toQuery(mysqlQueryConfig).sql).toBe( - "UNIX_TIMESTAMP(`date_t`.`created`)", - ); - }); - - it("DATE_ADD / ADDDATE / SUBDATE overloads", () => { - const da = dateAdd(cols.created, 1, "DAY").toQuery(mysqlQueryConfig); - expect(da.sql).toBe("DATE_ADD(`date_t`.`created`, INTERVAL ? DAY)"); - expect(da.params).toEqual([1]); - - const ad = addDate(cols.created, 7).toQuery(mysqlQueryConfig); - expect(ad.sql).toBe("ADDDATE(`date_t`.`created`, ?)"); - expect(ad.params).toEqual([7]); - - const adi = addDate(cols.created, 2, "HOUR").toQuery(mysqlQueryConfig); - expect(adi.sql).toBe("ADDDATE(`date_t`.`created`, INTERVAL ? HOUR)"); - - const sd = subDate(cols.created, 1, "MONTH").toQuery(mysqlQueryConfig); - expect(sd.sql).toBe("SUBDATE(`date_t`.`created`, INTERVAL ? MONTH)"); - - const sdDays = subDate(cols.created, 7).toQuery(mysqlQueryConfig); - expect(sdDays.sql).toBe("SUBDATE(`date_t`.`created`, ?)"); - expect(sdDays.params).toEqual([7]); - }); - - it("TIMESTAMPADD / TIMESTAMPDIFF / EXTRACT", () => { - expect( - timestampAdd("DAY", 1, cols.created).toQuery(mysqlQueryConfig).sql.replace(/\s+/g, " "), - ).toBe("TIMESTAMPADD(DAY, ?, `date_t`.`created`)"); - - expect(timestampDiff("HOUR", cols.created, cols.created).toQuery(mysqlQueryConfig).sql).toMatch( - /TIMESTAMPDIFF\(HOUR/, - ); - - const ex = extract("YEAR", cols.created).toQuery(mysqlQueryConfig); - expect(ex.sql).toBe("EXTRACT(YEAR FROM `date_t`.`created`)"); - }); - - it("TIMESTAMP one and two arguments", () => { - expect(timestampExpr("2024-01-01").toQuery(mysqlQueryConfig).sql).toBe("TIMESTAMP(?)"); - expect(timestampExpr("2024-01-01", "12:00:00").toQuery(mysqlQueryConfig).sql).toBe( - "TIMESTAMP(?, ?)", - ); - }); - - it("STR_TO_DATE / DATE_FORMAT", () => { - expect(strToDate("2024-01-15", "%Y-%m-%d").toQuery(mysqlQueryConfig).sql).toBe( - "STR_TO_DATE(?, ?)", - ); - expect(dateFormat(cols.created, "%Y").toQuery(mysqlQueryConfig).sql).toBe( - "DATE_FORMAT(`date_t`.`created`, ?)", - ); - }); - - it("smoke: invokes each DateTiDB export for coverage", () => { - const d = cols.created; - const q = mysqlQueryConfig; - const run = (s: SQL) => expect(s.toQuery(q).sql.length).toBeGreaterThan(0); - - run(interval(1, "DAY")); - run(addTime(d, "01:00:00")); - run(convertTz(d, "UTC", "+00:00")); - run(currentDate()); - run(currentTime()); - run(currentTime(3)); - run(currentTimestamp()); - run(currentTimestamp(3)); - run(curtime()); - run(curtime(3)); - run(dateOf(d)); - run(dateSub(d, 1, "DAY")); - run(dateDiff(d, d)); - run(day(d)); - run(dayName(d)); - run(dayOfMonth(d)); - run(dayOfWeek(d)); - run(dayOfYear(d)); - run(fromDays(738156)); - run(fromUnixtime(1)); - run(fromUnixtime(1, "%Y")); - run(getFormat("USA", "DATE")); - run(hour(d)); - run(lastDay(d)); - run(localTime()); - run(localTime(3)); - run(localTimestamp()); - run(localTimestamp(3)); - run(makeDate(2024, 32)); - run(makeTime(12, 30, 45)); - run(microsecond(d)); - run(minute(d)); - run(month(d)); - run(monthName(d)); - run(periodAdd(202401, 1)); - run(periodDiff(202401, 202402)); - run(quarter(d)); - run(secToTime(3600)); - run(second(d)); - run(subTime(d, "01:00:00")); - run(sysdate()); - run(sysdate(3)); - run(timeOf(d)); - run(timeFormat(d, "%H")); - run(timeToSec(d)); - run(timeDiff(d, d)); - run(toDays(d)); - run(toSeconds(d)); - run(utcDate()); - run(utcTime()); - run(utcTime(3)); - run(utcTimestamp()); - run(utcTimestamp(3)); - run(week(d)); - run(week(d, 0)); - run(weekDay(d)); - run(weekOfYear(d)); - run(year(d)); - run(yearWeek(d)); - run(yearWeek(d, 0)); - }); -}); diff --git a/__tests__/src/core/functions/EncryptTiDB.test.ts b/__tests__/src/core/functions/EncryptTiDB.test.ts deleted file mode 100644 index aeecda661..000000000 --- a/__tests__/src/core/functions/EncryptTiDB.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable, text } from "drizzle-orm/mysql-core"; -import { - aesDecrypt, - aesEncrypt, - compress, - md5, - randomBytes, - sha, - sha1, - sha2, - sm3, - sqlPassword, - uncompress, - uncompressedLength, - validatePasswordStrength, -} from "../../../../src/core/functions/EncryptTiDB"; - -const t = mysqlTable("enc_t", { - id: int("id").primaryKey(), - blob: text("blob_col"), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("EncryptTiDB SQL fragments (toQuery)", () => { - it("AES_ENCRYPT / AES_DECRYPT with optional iv", () => { - const enc2 = aesEncrypt(0x616263, "secret").toQuery(mysqlQueryConfig); - expect(enc2.sql).toBe("AES_ENCRYPT(?, ?)"); - - const enc3 = aesEncrypt(0x616263, "secret", 0).toQuery(mysqlQueryConfig); - expect(enc3.sql).toBe("AES_ENCRYPT(?, ?, ?)"); - - const dec = aesDecrypt(cols.blob, "k").toQuery(mysqlQueryConfig); - expect(dec.sql).toBe("AES_DECRYPT(`enc_t`.`blob_col`, ?)"); - - const decIv = aesDecrypt(cols.blob, "k", 0).toQuery(mysqlQueryConfig); - expect(decIv.sql).toBe("AES_DECRYPT(`enc_t`.`blob_col`, ?, ?)"); - }); - - it("hash and digest functions", () => { - expect(md5("abc").toQuery(mysqlQueryConfig).sql).toBe("MD5(?)"); - expect(sha("abc").toQuery(mysqlQueryConfig).sql).toBe("SHA(?)"); - expect(sha1("abc").toQuery(mysqlQueryConfig).sql).toBe("SHA1(?)"); - expect(sha2("abc", 256).toQuery(mysqlQueryConfig).sql).toBe("SHA2(?, ?)"); - expect(sm3("abc").toQuery(mysqlQueryConfig).sql).toBe("SM3(?)"); - }); - - it("compress helpers", () => { - expect(compress("x").toQuery(mysqlQueryConfig).sql).toBe("COMPRESS(?)"); - expect(uncompress(cols.blob).toQuery(mysqlQueryConfig).sql).toBe( - "UNCOMPRESS(`enc_t`.`blob_col`)", - ); - expect(uncompressedLength(cols.blob).toQuery(mysqlQueryConfig).sql).toBe( - "UNCOMPRESSED_LENGTH(`enc_t`.`blob_col`)", - ); - }); - - it("RANDOM_BYTES and VALIDATE_PASSWORD_STRENGTH", () => { - expect(randomBytes(16).toQuery(mysqlQueryConfig).sql).toBe("RANDOM_BYTES(?)"); - expect(validatePasswordStrength("x").toQuery(mysqlQueryConfig).sql).toBe( - "VALIDATE_PASSWORD_STRENGTH(?)", - ); - }); - - it("PASSWORD (deprecated alias)", () => { - expect(sqlPassword("secret").toQuery(mysqlQueryConfig).sql).toBe("PASSWORD(?)"); - }); -}); diff --git a/__tests__/src/core/functions/InformationTiDB.test.ts b/__tests__/src/core/functions/InformationTiDB.test.ts deleted file mode 100644 index db6730e0e..000000000 --- a/__tests__/src/core/functions/InformationTiDB.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { sql as dsql } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { - connectionId, - currentResourceGroup, - currentRole, - currentUser, - database, - foundRows, - lastInsertId, - rowCount, - schema, - sessionUser, - sqlBenchmark, - systemUser, - tidbVersion, - user, - version, -} from "../../../../src/core/functions/InformationTiDB"; - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("InformationTiDB SQL fragments (toQuery)", () => { - it("zero-argument session functions", () => { - expect(connectionId().toQuery(mysqlQueryConfig).sql).toBe("CONNECTION_ID()"); - expect(currentRole().toQuery(mysqlQueryConfig).sql).toBe("CURRENT_ROLE()"); - expect(currentUser().toQuery(mysqlQueryConfig).sql).toBe("CURRENT_USER()"); - expect(database().toQuery(mysqlQueryConfig).sql).toBe("DATABASE()"); - expect(foundRows().toQuery(mysqlQueryConfig).sql).toBe("FOUND_ROWS()"); - expect(rowCount().toQuery(mysqlQueryConfig).sql).toBe("ROW_COUNT()"); - expect(schema().toQuery(mysqlQueryConfig).sql).toBe("SCHEMA()"); - expect(sessionUser().toQuery(mysqlQueryConfig).sql).toBe("SESSION_USER()"); - expect(systemUser().toQuery(mysqlQueryConfig).sql).toBe("SYSTEM_USER()"); - expect(user().toQuery(mysqlQueryConfig).sql).toBe("USER()"); - expect(version().toQuery(mysqlQueryConfig).sql).toBe("VERSION()"); - }); - - it("LAST_INSERT_ID optional expression", () => { - expect(lastInsertId().toQuery(mysqlQueryConfig).sql).toBe("LAST_INSERT_ID()"); - expect(lastInsertId(1).toQuery(mysqlQueryConfig).sql).toBe("LAST_INSERT_ID(?)"); - }); - - it("BENCHMARK embeds expression", () => { - const q = sqlBenchmark(5, dsql`SLEEP(2)`).toQuery(mysqlQueryConfig); - expect(q.sql).toBe("BENCHMARK(?, SLEEP(2))"); - expect(q.params).toEqual([5]); - }); - - it("TiDB-only functions", () => { - expect(tidbVersion().toQuery(mysqlQueryConfig).sql).toBe("TIDB_VERSION()"); - expect(currentResourceGroup().toQuery(mysqlQueryConfig).sql).toBe("CURRENT_RESOURCE_GROUP()"); - }); -}); diff --git a/__tests__/src/core/functions/JsonTiDB.test.ts b/__tests__/src/core/functions/JsonTiDB.test.ts deleted file mode 100644 index d772a81b4..000000000 --- a/__tests__/src/core/functions/JsonTiDB.test.ts +++ /dev/null @@ -1,208 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, json, mysqlTable } from "drizzle-orm/mysql-core"; -import { - jsonArray, - jsonAppend, - jsonArrayAppend, - jsonArrayInsert, - jsonContains, - jsonContainsPath, - jsonExtract, - jsonGet, - jsonGetUnquote, - jsonInsert, - jsonKeys, - jsonMerge, - jsonMergePatch, - jsonMergePreserve, - jsonObject, - jsonOverlaps, - jsonQuote, - jsonDepth, - jsonLength, - jsonPretty, - jsonRemove, - jsonReplace, - jsonSearch, - jsonSet, - jsonStorageFree, - jsonStorageSize, - jsonType, - jsonUnquote, - jsonValid, - jsonArrayAgg, - jsonObjectAgg, - jsonSchemaValid, - memberOf, -} from "../../../../src/core/functions/JsonTiDB"; - -const t = mysqlTable("json_t", { - id: int("id").primaryKey(), - j: json("j").$type>(), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("JsonTiDB SQL fragments (toQuery)", () => { - it("JSON_ARRAY", () => { - expect(jsonArray().toQuery(mysqlQueryConfig).sql).toBe("JSON_ARRAY()"); - const q = jsonArray(1, 2, "foo").toQuery(mysqlQueryConfig); - expect(q.sql).toBe("JSON_ARRAY(?, ?, ?)"); - expect(q.params).toEqual([1, 2, "foo"]); - }); - - it("JSON_OBJECT", () => { - expect(jsonObject().toQuery(mysqlQueryConfig).sql).toBe("JSON_OBJECT()"); - const q = jsonObject("database", "TiDB", "distributed", true).toQuery(mysqlQueryConfig); - expect(q.sql).toBe("JSON_OBJECT(?, ?, ?, ?)"); - expect(q.params).toEqual(["database", "TiDB", "distributed", true]); - }); - - it("JSON_OBJECT rejects odd argument count", () => { - expect(() => jsonObject("a")).toThrow(/even number/); - }); - - it("JSON_QUOTE and column ref", () => { - expect(jsonQuote("x").toQuery(mysqlQueryConfig).sql).toBe("JSON_QUOTE(?)"); - expect(jsonQuote(cols.j).toQuery(mysqlQueryConfig).sql).toBe("JSON_QUOTE(`json_t`.`j`)"); - }); - - it("JSON_CONTAINS and JSON_CONTAINS_PATH", () => { - expect(jsonContains(cols.j, '"bar"').toQuery(mysqlQueryConfig).sql).toBe( - "JSON_CONTAINS(`json_t`.`j`, ?)", - ); - expect(jsonContains(cols.j, '"bar"', "$.foo").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_CONTAINS(`json_t`.`j`, ?, ?)", - ); - - expect(jsonContainsPath(cols.j, "all", "$.foo", "$.aaa").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_CONTAINS_PATH(`json_t`.`j`, ?, ?, ?)", - ); - expect(() => jsonContainsPath(cols.j, "one")).toThrow(/at least one JSON path/); - }); - - it("JSON_EXTRACT and arrow aliases", () => { - expect(jsonExtract(cols.j, "$.foo").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_EXTRACT(`json_t`.`j`, ?)", - ); - expect(jsonExtract(cols.j, "$.foo", "$.aaa").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_EXTRACT(`json_t`.`j`, ?, ?)", - ); - expect(() => jsonExtract(cols.j)).toThrow(/at least one JSON path/); - - expect(jsonGet(cols.j, "$.foo").toQuery(mysqlQueryConfig).sql).toBe("`json_t`.`j` -> ?"); - expect(jsonGetUnquote(cols.j, "$.foo").toQuery(mysqlQueryConfig).sql).toBe( - "`json_t`.`j` ->> ?", - ); - }); - - it("JSON_KEYS / JSON_SEARCH / MEMBER OF / JSON_OVERLAPS", () => { - expect(jsonKeys(cols.j).toQuery(mysqlQueryConfig).sql).toBe("JSON_KEYS(`json_t`.`j`)"); - expect(jsonKeys(cols.j, "$.name").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_KEYS(`json_t`.`j`, ?)", - ); - - expect(jsonSearch(cols.j, "one", "cc").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_SEARCH(`json_t`.`j`, ?, ?)", - ); - expect(jsonSearch(cols.j, "all", "cc", "\\\\", "$.a").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_SEARCH(`json_t`.`j`, ?, ?, ?, ?)", - ); - expect(jsonSearch(cols.j, "all", "cc", undefined, "$.a").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_SEARCH(`json_t`.`j`, ?, ?, NULL, ?)", - ); - - expect(memberOf("🍍", cols.j).toQuery(mysqlQueryConfig).sql).toBe("? MEMBER OF (`json_t`.`j`)"); - expect(jsonOverlaps(cols.j, cols.j).toQuery(mysqlQueryConfig).sql).toBe( - "JSON_OVERLAPS(`json_t`.`j`, `json_t`.`j`)", - ); - }); - - it("JSON modify functions with path/value pairs", () => { - expect(jsonArrayAppend(cols.j, "$.a", 1).toQuery(mysqlQueryConfig).sql).toBe( - "JSON_ARRAY_APPEND(`json_t`.`j`, ?, ?)", - ); - expect(jsonAppend(cols.j, "$.a", 1).toQuery(mysqlQueryConfig).sql).toBe( - "JSON_ARRAY_APPEND(`json_t`.`j`, ?, ?)", - ); - expect(jsonArrayInsert(cols.j, "$[0]", "x").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_ARRAY_INSERT(`json_t`.`j`, ?, ?)", - ); - expect(jsonInsert(cols.j, "$.branch", "main").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_INSERT(`json_t`.`j`, ?, ?)", - ); - expect(jsonReplace(cols.j, "$.version", 2).toQuery(mysqlQueryConfig).sql).toBe( - "JSON_REPLACE(`json_t`.`j`, ?, ?)", - ); - expect(jsonSet(cols.j, "$.version", 2).toQuery(mysqlQueryConfig).sql).toBe( - "JSON_SET(`json_t`.`j`, ?, ?)", - ); - expect(() => jsonSet(cols.j, "$.a")).toThrow(/path\/value pairs/); - }); - - it("JSON merge and remove/unquote", () => { - expect(jsonMergePatch('{"a":1}', '{"b":2}').toQuery(mysqlQueryConfig).sql).toBe( - "JSON_MERGE_PATCH(?, ?)", - ); - expect(jsonMergePreserve('{"a":1}', '{"a":2}').toQuery(mysqlQueryConfig).sql).toBe( - "JSON_MERGE_PRESERVE(?, ?)", - ); - expect(jsonMerge('{"a":1}', '{"a":2}').toQuery(mysqlQueryConfig).sql).toBe( - "JSON_MERGE_PRESERVE(?, ?)", - ); - expect(() => jsonMergePatch('{"a":1}')).toThrow(/at least two JSON documents/); - expect(() => jsonMergePreserve('{"a":1}')).toThrow(/at least two JSON documents/); - - expect(jsonRemove(cols.j, "$.b", "$.c").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_REMOVE(`json_t`.`j`, ?, ?)", - ); - expect(() => jsonRemove(cols.j)).toThrow(/at least one JSON path/); - - expect(jsonUnquote('"foo"').toQuery(mysqlQueryConfig).sql).toBe("JSON_UNQUOTE(?)"); - }); - - it("JSON return/validate functions", () => { - expect(jsonDepth(cols.j).toQuery(mysqlQueryConfig).sql).toBe("JSON_DEPTH(`json_t`.`j`)"); - expect(jsonLength(cols.j).toQuery(mysqlQueryConfig).sql).toBe("JSON_LENGTH(`json_t`.`j`)"); - expect(jsonLength(cols.j, "$.weather").toQuery(mysqlQueryConfig).sql).toBe( - "JSON_LENGTH(`json_t`.`j`, ?)", - ); - expect(jsonType(cols.j).toQuery(mysqlQueryConfig).sql).toBe("JSON_TYPE(`json_t`.`j`)"); - expect(jsonValid('{"foo":"bar"}').toQuery(mysqlQueryConfig).sql).toBe("JSON_VALID(?)"); - }); - - it("JSON utility functions", () => { - expect(jsonPretty(cols.j).toQuery(mysqlQueryConfig).sql).toBe("JSON_PRETTY(`json_t`.`j`)"); - expect(jsonStorageFree(cols.j).toQuery(mysqlQueryConfig).sql).toBe( - "JSON_STORAGE_FREE(`json_t`.`j`)", - ); - expect(jsonStorageSize(cols.j).toQuery(mysqlQueryConfig).sql).toBe( - "JSON_STORAGE_SIZE(`json_t`.`j`)", - ); - }); - - it("JSON aggregate functions", () => { - expect(jsonArrayAgg(cols.j).toQuery(mysqlQueryConfig).sql).toBe("JSON_ARRAYAGG(`json_t`.`j`)"); - expect(jsonObjectAgg("k", cols.j).toQuery(mysqlQueryConfig).sql).toBe( - "JSON_OBJECTAGG(?, `json_t`.`j`)", - ); - }); - - it("JSON schema validation function", () => { - const q = jsonSchemaValid('{"type":"object"}', cols.j).toQuery(mysqlQueryConfig); - expect(q.sql).toBe("JSON_SCHEMA_VALID(?, `json_t`.`j`)"); - expect(q.params).toEqual(['{"type":"object"}']); - }); -}); diff --git a/__tests__/src/core/functions/MiscellaneousTiDB.test.ts b/__tests__/src/core/functions/MiscellaneousTiDB.test.ts deleted file mode 100644 index 91e2ab577..000000000 --- a/__tests__/src/core/functions/MiscellaneousTiDB.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable, varchar } from "drizzle-orm/mysql-core"; -import { - anyValue, - binToUuid, - defaultValue, - grouping, - inet6Aton, - inet6Ntoa, - inetAton, - inetNtoa, - isIpv4, - isIpv4Compat, - isIpv4Mapped, - isIpv6, - isUuid, - nameConst, - sleep, - uuid, - uuidToBin, - valuesFn, -} from "../../../../src/core/functions/MiscellaneousTiDB"; - -const t = mysqlTable("misc_t", { - id: int("id").primaryKey(), - c1: int("c1"), - s: varchar("s", { length: 64 }), -}); -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("MiscellaneousTiDB SQL fragments (toQuery)", () => { - it("uuid/bin conversion functions", () => { - expect(uuid().toQuery(mysqlQueryConfig).sql).toBe("UUID()"); - expect(uuidToBin("a").toQuery(mysqlQueryConfig).sql).toBe("UUID_TO_BIN(?)"); - expect(uuidToBin("a", 1).toQuery(mysqlQueryConfig).sql).toBe("UUID_TO_BIN(?, ?)"); - expect(binToUuid(cols.s).toQuery(mysqlQueryConfig).sql).toBe("BIN_TO_UUID(`misc_t`.`s`)"); - expect(binToUuid(cols.s, 1).toQuery(mysqlQueryConfig).sql).toBe("BIN_TO_UUID(`misc_t`.`s`, ?)"); - }); - - it("IP helper functions", () => { - expect(inetAton("127.0.0.1").toQuery(mysqlQueryConfig).sql).toBe("INET_ATON(?)"); - expect(inetNtoa(2130706433).toQuery(mysqlQueryConfig).sql).toBe("INET_NTOA(?)"); - expect(inet6Aton("::1").toQuery(mysqlQueryConfig).sql).toBe("INET6_ATON(?)"); - expect(inet6Ntoa("x").toQuery(mysqlQueryConfig).sql).toBe("INET6_NTOA(?)"); - expect(isIpv4("127.0.0.1").toQuery(mysqlQueryConfig).sql).toBe("IS_IPV4(?)"); - expect(isIpv4Compat(cols.s).toQuery(mysqlQueryConfig).sql).toBe("IS_IPV4_COMPAT(`misc_t`.`s`)"); - expect(isIpv4Mapped(cols.s).toQuery(mysqlQueryConfig).sql).toBe("IS_IPV4_MAPPED(`misc_t`.`s`)"); - expect(isIpv6("::1").toQuery(mysqlQueryConfig).sql).toBe("IS_IPV6(?)"); - expect(isUuid("u").toQuery(mysqlQueryConfig).sql).toBe("IS_UUID(?)"); - }); - - it("other miscellaneous functions", () => { - expect(anyValue(cols.c1).toQuery(mysqlQueryConfig).sql).toBe("ANY_VALUE(`misc_t`.`c1`)"); - expect(defaultValue(cols.c1).toQuery(mysqlQueryConfig).sql).toBe("DEFAULT(`misc_t`.`c1`)"); - expect(grouping(cols.c1, cols.id).toQuery(mysqlQueryConfig).sql).toBe( - "GROUPING(`misc_t`.`c1`, `misc_t`.`id`)", - ); - expect(nameConst("column", "value").toQuery(mysqlQueryConfig).sql).toBe("NAME_CONST(?, ?)"); - expect(sleep(1.5).toQuery(mysqlQueryConfig).sql).toBe("SLEEP(?)"); - expect(valuesFn(cols.id).toQuery(mysqlQueryConfig).sql).toBe("VALUES(`misc_t`.`id`)"); - }); -}); diff --git a/__tests__/src/core/functions/NumericTiDB.test.ts b/__tests__/src/core/functions/NumericTiDB.test.ts deleted file mode 100644 index ba3fd3c51..000000000 --- a/__tests__/src/core/functions/NumericTiDB.test.ts +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns, type SQL } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable } from "drizzle-orm/mysql-core"; -import { - abs, - acos, - asin, - atan, - atan2, - ceil, - ceiling, - conv, - cos, - cot, - crc32, - degrees, - exp, - floor, - ln, - log, - log10, - logBase, - logBase2, - mod, - numAdd, - numDiv, - numDivInt, - numModOp, - numMul, - numNeg, - numSub, - pi, - pow, - power, - radians, - rand, - round, - sign, - sin, - sqrt, - tan, - truncateTo, -} from "../../../../src"; - -const t = mysqlTable("num_t", { - id: int("id").primaryKey(), - n: int("n"), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("NumericTiDB SQL fragments (toQuery)", () => { - it("arithmetic helpers compile", () => { - const d = numDiv(cols.n, 2).toQuery(mysqlQueryConfig); - expect(d.sql).toBe("(`num_t`.`n` / ?)"); - expect(d.params).toEqual([2]); - - const di = numDivInt(cols.n, 2).toQuery(mysqlQueryConfig); - expect(di.sql).toBe("(`num_t`.`n` DIV ?)"); - }); - - it("pi / rand / round / truncate", () => { - expect(pi().toQuery(mysqlQueryConfig).sql).toBe("PI()"); - expect(rand().toQuery(mysqlQueryConfig).sql).toBe("RAND()"); - expect(rand(42).toQuery(mysqlQueryConfig).sql).toBe("RAND(?)"); - expect(rand(42).toQuery(mysqlQueryConfig).params).toEqual([42]); - - expect(round(1.234, 2).toQuery(mysqlQueryConfig).sql).toBe("ROUND(?, ?)"); - expect(round(cols.n).toQuery(mysqlQueryConfig).sql).toBe("ROUND(`num_t`.`n`)"); - - expect(truncateTo(1.239, 2).toQuery(mysqlQueryConfig).sql).toBe("TRUNCATE(?, ?)"); - }); - - it("logBase and pow", () => { - expect(logBase(2, 8).toQuery(mysqlQueryConfig).sql).toBe("LOG(?, ?)"); - expect(logBase(2, 8).toQuery(mysqlQueryConfig).params).toEqual([2, 8]); - expect(pow(cols.n, 3).toQuery(mysqlQueryConfig).sql).toBe("POW(`num_t`.`n`, ?)"); - }); - - it("ceil", () => { - expect(ceil(-1.23).toQuery(mysqlQueryConfig).sql).toBe("CEIL(?)"); - }); - - it("smoke: invokes each NumericTiDB export for coverage", () => { - const n = cols.n; - const q = mysqlQueryConfig; - const run = (s: SQL) => expect(s.toQuery(q).sql.length).toBeGreaterThan(0); - - run(numAdd(n, 1)); - run(numSub(n, 1)); - run(numMul(n, 2)); - run(numModOp(n, 3)); - run(numNeg(n)); - run(abs(-1)); - run(acos(0)); - run(asin(0)); - run(atan(0)); - run(atan2(1, 2)); - run(ceiling(1.1)); - run(conv(10, 10, 16)); - run(cos(0)); - run(cot(1)); - run(crc32("x")); - run(degrees(3.14)); - run(exp(1)); - run(floor(1.9)); - run(ln(2)); - run(log(2)); - run(log10(100)); - run(logBase2(8)); - run(mod(7, 3)); - run(power(n, 2)); - run(radians(180)); - run(sign(-3)); - run(sin(0)); - run(sqrt(4)); - run(tan(0)); - }); -}); diff --git a/__tests__/src/core/functions/SequenceTiDB.test.ts b/__tests__/src/core/functions/SequenceTiDB.test.ts deleted file mode 100644 index 4b43adfba..000000000 --- a/__tests__/src/core/functions/SequenceTiDB.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { sql as dsql } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { - lastVal, - nextVal, - nextValueFor, - setVal, -} from "../../../../src/core/functions/SequenceTiDB"; - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("SequenceTiDB SQL fragments (toQuery)", () => { - it("NEXTVAL / LASTVAL with sequence name", () => { - expect(nextVal("s1").toQuery(mysqlQueryConfig).sql).toBe("NEXTVAL(s1)"); - expect(lastVal("s1").toQuery(mysqlQueryConfig).sql).toBe("LASTVAL(s1)"); - }); - - it("NEXT VALUE FOR alias", () => { - expect(nextValueFor("s1").toQuery(mysqlQueryConfig).sql).toBe("NEXT VALUE FOR s1"); - }); - - it("SETVAL binds numeric value", () => { - const q = setVal("s1", 10).toQuery(mysqlQueryConfig); - expect(q.sql).toBe("SETVAL(s1, ?)"); - expect(q.params).toEqual([10]); - }); - - it("supports SQL expression for sequence argument", () => { - expect(nextVal(dsql`my_seq`).toQuery(mysqlQueryConfig).sql).toBe("NEXTVAL(my_seq)"); - }); -}); diff --git a/__tests__/src/core/functions/StringTiDB.test.ts b/__tests__/src/core/functions/StringTiDB.test.ts deleted file mode 100644 index a0cd11367..000000000 --- a/__tests__/src/core/functions/StringTiDB.test.ts +++ /dev/null @@ -1,237 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns, sql as dsql, type SQL } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable, varchar } from "drizzle-orm/mysql-core"; -import { - ascii, - bin, - bitLength, - charCodes, - charLength, - characterLength, - concat, - concatWs, - elt, - exportSet, - field, - findInSet, - formatSql, - fromBase64, - hex, - insert, - instr, - lcase, - left, - length, - locate, - lower, - lpad, - ltrim, - makeSet, - mid, - oct, - octetLength, - ord, - position, - quote, - regexpInstr, - regexpLike, - regexpReplace, - regexpSubstr, - repeat, - replace, - reverse, - right, - rpad, - rtrim, - space, - strcmp, - sqlLike, - sqlLikeEscape, - sqlNotLike, - sqlNotLikeEscape, - sqlNotRegExp, - sqlRegExp, - sqlRLike, - substr, - substring, - substringIndex, - toBase64, - translate, - trim, - trimBoth, - trimLeadingFrom, - trimTrailingFrom, - ucase, - unhex, - upper, - weightString, - weightStringAsBinary, - weightStringAsChar, -} from "../../../../src"; - -const t = mysqlTable("str_t", { - id: int("id").primaryKey(), - name: varchar("name", { length: 64 }), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("StringTiDB SQL fragments (toQuery)", () => { - it("ascii / charCodes / concat / concatWs compile with placeholders", () => { - expect(ascii("A").toQuery(mysqlQueryConfig).sql).toBe("ASCII(?)"); - expect(ascii("A").toQuery(mysqlQueryConfig).params).toEqual(["A"]); - - const ch = charCodes(65, 66).toQuery(mysqlQueryConfig); - expect(ch.sql).toBe("CHAR(?, ?)"); - expect(ch.params).toEqual([65, 66]); - - const c = concat("Ti", cols.name).toQuery(mysqlQueryConfig); - expect(c.sql).toBe("CONCAT(?, `str_t`.`name`)"); - expect(c.params).toEqual(["Ti"]); - - const ws = concatWs(",", "a", "b").toQuery(mysqlQueryConfig); - expect(ws.sql).toBe("CONCAT_WS(?, ?, ?)"); - expect(ws.params).toEqual([",", "a", "b"]); - }); - - it("exportSet optional arguments", () => { - const a = exportSet(dsql`b'101'`, "ON", "off").toQuery(mysqlQueryConfig); - expect(a.sql).toBe("EXPORT_SET(b'101', ?, ?)"); - expect(a.params).toEqual(["ON", "off"]); - - const b = exportSet(5, "x", "_", "|", 8).toQuery(mysqlQueryConfig); - expect(b.sql).toBe("EXPORT_SET(?, ?, ?, ?, ?)"); - expect(b.params).toEqual([5, "x", "_", "|", 8]); - }); - - it("locate with optional position", () => { - expect(locate("bar", "foobar").toQuery(mysqlQueryConfig).sql).toBe("LOCATE(?, ?)"); - expect(locate("bar", "foobar", 5).toQuery(mysqlQueryConfig).sql).toBe("LOCATE(?, ?, ?)"); - }); - - it("substring two- and three-argument forms", () => { - expect(substring("abcdef", 2).toQuery(mysqlQueryConfig).sql).toBe("SUBSTRING(?, ?)"); - expect(substring("abcdef", 2, 3).toQuery(mysqlQueryConfig).sql).toBe("SUBSTRING(?, ?, ?)"); - }); - - it("substr emits SUBSTR", () => { - expect(substr("abcdef", 2).toQuery(mysqlQueryConfig).sql).toBe("SUBSTR(?, ?)"); - expect(substr("abcdef", 2, 3).toQuery(mysqlQueryConfig).sql).toBe("SUBSTR(?, ?, ?)"); - }); - - it("regexp helpers compile", () => { - expect(regexpInstr("abc", "^a").toQuery(mysqlQueryConfig).sql).toBe("REGEXP_INSTR(?, ?)"); - expect( - regexpInstr("abc", "^a", { - start: 1, - occurrence: 2, - returnOption: 0, - matchType: "i", - }).toQuery(mysqlQueryConfig).sql, - ).toBe("REGEXP_INSTR(?, ?, ?, ?, ?, ?)"); - - expect(regexpReplace("TooDB", "o{2}", "i").toQuery(mysqlQueryConfig).sql).toBe( - "REGEXP_REPLACE(?, ?, ?)", - ); - expect( - regexpReplace("TooDB", "o", "i", { - start: 1, - occurrence: 2, - matchType: "i", - }).toQuery(mysqlQueryConfig).sql, - ).toBe("REGEXP_REPLACE(?, ?, ?, ?, ?, ?)"); - }); - - it("LIKE and REGEXP infix operators", () => { - const likeQ = sqlLike(cols.name, "%tidb%").toQuery(mysqlQueryConfig); - expect(likeQ.sql).toBe("`str_t`.`name` LIKE ?"); - expect(likeQ.params).toEqual(["%tidb%"]); - - const re = sqlRegExp(cols.name, "^Ti").toQuery(mysqlQueryConfig); - expect(re.sql).toBe("`str_t`.`name` REGEXP ?"); - expect(re.params).toEqual(["^Ti"]); - }); - - it("weightStringAsChar embeds AS CHAR", () => { - const w = weightStringAsChar("ab", 3).toQuery(mysqlQueryConfig); - expect(w.sql).toBe("WEIGHT_STRING(? AS CHAR(?))"); - expect(w.params).toEqual(["ab", 3]); - }); - - it("smoke: invokes each StringTiDB export for coverage", () => { - const s = cols.name; - const q = mysqlQueryConfig; - const run = (x: SQL) => expect(x.toQuery(q).sql.length).toBeGreaterThan(0); - - run(bin(3)); - run(bitLength("x")); - run(charLength("x")); - run(characterLength("x")); - run(elt(1, "a", "b")); - run(exportSet(1, "a", "b", ",")); - run(field("a", "b", "a")); - run(findInSet("a", "a,b")); - expect(formatSql("1.2", "2").toQuery(q).sql).toBe("FORMAT(?, ?)"); - run(formatSql("1.2", "2", "en_US")); - run(fromBase64("YWI=")); - run(hex("ab")); - run(insert("abcd", 2, 2, "xx")); - run(instr("foobar", "bar")); - run(lcase("X")); - run(left("abc", 2)); - run(length("x")); - run(lower("X")); - run(lpad("a", 5, ".")); - run(ltrim(" x")); - run(makeSet(3, "a", "b", "c")); - run(mid("abcdef", 2)); - run(mid("abcdef", 2, 3)); - run(oct(8)); - run(octetLength("x")); - run(ord("A")); - run(position("b", "abc")); - run(quote("a'b")); - run(regexpLike("a", "^a")); - run(regexpLike("a", "^a", "c")); - run(regexpSubstr("abc", "a")); - run(regexpSubstr("abc", "a", 1)); - run(regexpSubstr("abc", "a", 1, 1)); - run(regexpSubstr("abc", "a", 1, 1, "c")); - run(repeat("a", 3)); - run(replace("aba", "a", "b")); - run(reverse("ab")); - run(right("abc", 2)); - run(rpad("a", 5, ".")); - run(rtrim("x ")); - run(space(2)); - run(strcmp("a", "b")); - run(sqlLikeEscape(s, "a%", "\\")); - run(sqlNotLike(s, "x")); - run(sqlNotLikeEscape(s, "x", "\\")); - run(sqlNotRegExp(s, "^z")); - run(sqlRLike(s, ".*")); - run(substringIndex("a.b.c", ".", 2)); - run(toBase64("ab")); - run(translate("abc", "a", "z")); - run(trim(" x ")); - run(trimBoth("xxabcxx", "x")); - run(trimLeadingFrom("xxabc", "x")); - run(trimTrailingFrom("abcxx", "x")); - run(ucase("x")); - run(unhex("6162")); - run(upper("x")); - run(weightString("ab")); - run(weightStringAsBinary("ab", 4)); - }); -}); diff --git a/__tests__/src/core/functions/TiDBSpecificTiDB.test.ts b/__tests__/src/core/functions/TiDBSpecificTiDB.test.ts deleted file mode 100644 index a5e70a2ad..000000000 --- a/__tests__/src/core/functions/TiDBSpecificTiDB.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { CasingCache } from "drizzle-orm/casing"; -import { - tidbBoundedStaleness, - tidbCurrentResourceGroup, - tidbCurrentTso, - tidbDecodeBinaryPlan, - tidbDecodeKey, - tidbDecodePlan, - tidbDecodeSqlDigests, - tidbEncodeIndexKey, - tidbEncodeRecordKey, - tidbEncodeSqlDigest, - tidbIsDdlOwner, - tidbMvccInfo, - tidbParseTso, - tidbParseTsoLogical, - tidbRowChecksum, - tidbShard, - tidbVersionInfo, - vitessHash, -} from "../../../../src/core/functions/TiDBSpecificTiDB"; - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("TiDBSpecificTiDB SQL fragments (toQuery)", () => { - it("zero-arg helpers", () => { - expect(tidbCurrentResourceGroup().toQuery(mysqlQueryConfig).sql).toBe( - "CURRENT_RESOURCE_GROUP()", - ); - expect(tidbCurrentTso().toQuery(mysqlQueryConfig).sql).toBe("TIDB_CURRENT_TSO()"); - expect(tidbIsDdlOwner().toQuery(mysqlQueryConfig).sql).toBe("TIDB_IS_DDL_OWNER()"); - expect(tidbRowChecksum().toQuery(mysqlQueryConfig).sql).toBe("TIDB_ROW_CHECKSUM()"); - expect(tidbVersionInfo().toQuery(mysqlQueryConfig).sql).toBe("TIDB_VERSION()"); - }); - - it("single-arg helpers", () => { - expect(tidbDecodeBinaryPlan("x").toQuery(mysqlQueryConfig).sql).toBe( - "TIDB_DECODE_BINARY_PLAN(?)", - ); - expect(tidbDecodeKey("x").toQuery(mysqlQueryConfig).sql).toBe("TIDB_DECODE_KEY(?)"); - expect(tidbDecodePlan("x").toQuery(mysqlQueryConfig).sql).toBe("TIDB_DECODE_PLAN(?)"); - expect(tidbEncodeSqlDigest("SELECT 1").toQuery(mysqlQueryConfig).sql).toBe( - "TIDB_ENCODE_SQL_DIGEST(?)", - ); - expect(tidbParseTso(1).toQuery(mysqlQueryConfig).sql).toBe("TIDB_PARSE_TSO(?)"); - expect(tidbParseTsoLogical(1).toQuery(mysqlQueryConfig).sql).toBe("TIDB_PARSE_TSO_LOGICAL(?)"); - expect(tidbShard(123).toQuery(mysqlQueryConfig).sql).toBe("TIDB_SHARD(?)"); - expect(vitessHash(123).toQuery(mysqlQueryConfig).sql).toBe("VITESS_HASH(?)"); - expect(tidbMvccInfo("k").toQuery(mysqlQueryConfig).sql).toBe("TIDB_MVCC_INFO(?)"); - }); - - it("multi-arg helpers", () => { - expect(tidbBoundedStaleness("a", "b").toQuery(mysqlQueryConfig).sql).toBe( - "TIDB_BOUNDED_STALENESS(?, ?)", - ); - expect(tidbDecodeSqlDigests("[]").toQuery(mysqlQueryConfig).sql).toBe( - "TIDB_DECODE_SQL_DIGESTS(?)", - ); - expect(tidbDecodeSqlDigests("[]", 10).toQuery(mysqlQueryConfig).sql).toBe( - "TIDB_DECODE_SQL_DIGESTS(?, ?)", - ); - expect(tidbEncodeIndexKey("test", "t", "idx", 2, 1).toQuery(mysqlQueryConfig).sql).toBe( - "TIDB_ENCODE_INDEX_KEY(?, ?, ?, ?, ?)", - ); - expect(tidbEncodeRecordKey("test", "t", 1).toQuery(mysqlQueryConfig).sql).toBe( - "TIDB_ENCODE_RECORD_KEY(?, ?, ?)", - ); - }); -}); diff --git a/__tests__/src/core/functions/UtilityTiDB.test.ts b/__tests__/src/core/functions/UtilityTiDB.test.ts deleted file mode 100644 index 1c5c742aa..000000000 --- a/__tests__/src/core/functions/UtilityTiDB.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { CasingCache } from "drizzle-orm/casing"; -import { formatBytes, formatNanoTime } from "../../../../src/core/functions/UtilityTiDB"; - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("UtilityTiDB SQL fragments (toQuery)", () => { - it("FORMAT_BYTES", () => { - const q = formatBytes(10 * 1024 * 1024).toQuery(mysqlQueryConfig); - expect(q.sql).toBe("FORMAT_BYTES(?)"); - expect(q.params).toEqual([10 * 1024 * 1024]); - }); - - it("FORMAT_NANO_TIME", () => { - const q = formatNanoTime(1_000_000).toQuery(mysqlQueryConfig); - expect(q.sql).toBe("FORMAT_NANO_TIME(?)"); - expect(q.params).toEqual([1_000_000]); - }); -}); diff --git a/__tests__/src/core/functions/VectorTiDB.test.ts b/__tests__/src/core/functions/VectorTiDB.test.ts deleted file mode 100644 index 25e63f5e9..000000000 --- a/__tests__/src/core/functions/VectorTiDB.test.ts +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns } from "drizzle-orm"; -import { sql as dsql } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable } from "drizzle-orm/mysql-core"; -import { - vecAsText, - vecCosineDistance, - vecDims, - vecFromText, - vecL1Distance, - vecL2Distance, - vecL2Norm, - vecNegativeInnerProduct, - vectorTiDBType, -} from "../../../../src/core/functions/VectorTiDB"; - -const vectorTable = mysqlTable("vector_test_t", { - id: int("id").primaryKey(), - v3: vectorTiDBType("emb", { dimension: 3 }), - vAny: vectorTiDBType("loose"), -}); - -const cols = getTableColumns(vectorTable); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("VectorTiDB vectorTiDBType (driver mapping)", () => { - it("getSQLType: VECTOR(n) and unbounded VECTOR", () => { - expect(cols.v3.getSQLType()).toBe("vector(3)"); - expect(cols.vAny.getSQLType()).toBe("vector"); - }); - - it("mapToDriverValue serializes number[]", () => { - expect(cols.v3.mapToDriverValue([1, 2, 3])).toBe("[1,2,3]"); - }); - - it("mapToDriverValue throws when value is not an array", () => { - expect(() => cols.v3.mapToDriverValue(null as unknown as number[])).toThrow( - "TiDB vector value must be an array of numbers", - ); - }); - - it("mapToDriverValue throws on non-finite number", () => { - expect(() => cols.v3.mapToDriverValue([1, Number.NaN, 3])).toThrow( - "TiDB vector contains invalid number", - ); - expect(() => cols.v3.mapToDriverValue([1, Number.POSITIVE_INFINITY, 3])).toThrow( - "TiDB vector contains invalid number", - ); - }); - - it("mapFromDriverValue returns null and undefined as-is", () => { - expect(cols.v3.mapFromDriverValue(null)).toBeNull(); - expect(cols.v3.mapFromDriverValue(undefined)).toBeUndefined(); - }); - - it("mapFromDriverValue parses TiDB vector text", () => { - expect(cols.v3.mapFromDriverValue("[1,2,3]")).toEqual([1, 2, 3]); - }); - - it("mapFromDriverValue throws on non-string driver value", () => { - expect(() => cols.v3.mapFromDriverValue(42 as unknown as string)).toThrow( - "Invalid TiDB vector driver value type: number", - ); - }); - - it("mapFromDriverValue throws when text is not bracketed like a vector", () => { - expect(() => cols.v3.mapFromDriverValue("1,2,3")).toThrow("Invalid TiDB vector text"); - }); - - it("mapFromDriverValue throws when JSON is not an array", () => { - expect(() => cols.v3.mapFromDriverValue("{}")).toThrow("Invalid TiDB vector text"); - }); - - it("mapFromDriverValue throws on invalid vector element after JSON parse", () => { - expect(() => cols.v3.mapFromDriverValue('["x",2,3]')).toThrow("Invalid TiDB vector element"); - }); -}); - -describe("VectorTiDB SQL fragments (toQuery)", () => { - it("vecFromText uses placeholder and passes raw text as bind param (no SQL escaping)", () => { - const q = vecFromText("a'b"); - const built = q.toQuery(mysqlQueryConfig); - expect(built.sql).toMatch(/VEC_FROM_TEXT\(\?\)/); - expect(built.params).toContain("a'b"); - }); - - it("vecFromText preserves backslashes in param value", () => { - const q = vecFromText("a\\b"); - const built = q.toQuery(mysqlQueryConfig); - expect(built.params?.[0]).toBe("a\\b"); - }); - - it("vecAsText / vecDims / vecL2Norm / distance helpers compile", () => { - const v = cols.v3; - const qVec = [1, 2, 3]; - expect(vecAsText(v).toQuery(mysqlQueryConfig).sql).toContain("VEC_AS_TEXT"); - expect(vecDims(v).toQuery(mysqlQueryConfig).sql).toContain("VEC_DIMS"); - const dimsBuilt = vecDims(qVec).toQuery(mysqlQueryConfig); - expect(dimsBuilt.sql).toContain("VEC_FROM_TEXT(?)"); - expect(dimsBuilt.params).toContain("[1,2,3]"); - expect(vecL2Norm(v).toQuery(mysqlQueryConfig).sql).toContain("VEC_L2_NORM"); - expect(vecL2Distance(v, qVec).toQuery(mysqlQueryConfig).sql).toContain("VEC_L2_DISTANCE"); - expect(vecCosineDistance(v, qVec).toQuery(mysqlQueryConfig).sql).toContain( - "VEC_COSINE_DISTANCE", - ); - expect(vecNegativeInnerProduct(v, qVec).toQuery(mysqlQueryConfig).sql).toContain( - "VEC_NEGATIVE_INNER_PRODUCT", - ); - expect(vecL1Distance(v, qVec).toQuery(mysqlQueryConfig).sql).toContain("VEC_L1_DISTANCE"); - }); - - it("vectorExpr: raw SQL string is passed through (vecDims)", () => { - const raw = "CAST('[1,2,3]' AS VECTOR)"; - const { sql: text } = vecDims(raw).toQuery(mysqlQueryConfig); - expect(text).toBe(`VEC_DIMS(${raw})`); - }); - - it("vectorExpr: SQL template is embedded (vecDims)", () => { - const expr = dsql`CAST('[1,2,3]' AS VECTOR)`; - const { sql: text } = vecDims(expr).toQuery(mysqlQueryConfig); - expect(text).toContain("VEC_DIMS"); - expect(text).toContain("CAST"); - }); - - it("vectorExpr validates finite numbers in number[] inputs", () => { - expect(() => vecDims([1, Number.NaN, 3])).toThrow("TiDB vector contains invalid number"); - expect(() => vecL2Distance([1, 2], [3, Number.POSITIVE_INFINITY])).toThrow( - "TiDB vector contains invalid number", - ); - }); -}); diff --git a/__tests__/src/core/functions/WindowTiDB.test.ts b/__tests__/src/core/functions/WindowTiDB.test.ts deleted file mode 100644 index 383c996d9..000000000 --- a/__tests__/src/core/functions/WindowTiDB.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it } from "vitest"; -import { getTableColumns } from "drizzle-orm"; -import { CasingCache } from "drizzle-orm/casing"; -import { int, mysqlTable } from "drizzle-orm/mysql-core"; -import { - cumeDist, - denseRank, - firstValue, - lag, - lastValue, - lead, - nthValue, - ntile, - percentRank, - rank, - rowNumber, -} from "../../../../src/core/functions/WindowTiDB"; - -const t = mysqlTable("win_t", { - id: int("id").primaryKey(), - n: int("n"), -}); - -const cols = getTableColumns(t); - -const mysqlQueryConfig = { - casing: new CasingCache(undefined), - escapeName: (name: string) => `\`${name.replace(/`/g, "``")}\``, - escapeParam: (_num: number) => `?`, - escapeString: (str: string) => `'${str.replace(/'/g, "''")}'`, -}; - -describe("WindowTiDB SQL fragments (toQuery)", () => { - it("rank-like functions", () => { - expect(cumeDist().toQuery(mysqlQueryConfig).sql).toBe("CUME_DIST()"); - expect(denseRank().toQuery(mysqlQueryConfig).sql).toBe("DENSE_RANK()"); - expect(percentRank().toQuery(mysqlQueryConfig).sql).toBe("PERCENT_RANK()"); - expect(rank().toQuery(mysqlQueryConfig).sql).toBe("RANK()"); - expect(rowNumber().toQuery(mysqlQueryConfig).sql).toBe("ROW_NUMBER()"); - }); - - it("value functions", () => { - expect(firstValue(cols.n).toQuery(mysqlQueryConfig).sql).toBe("FIRST_VALUE(`win_t`.`n`)"); - expect(lastValue(cols.n).toQuery(mysqlQueryConfig).sql).toBe("LAST_VALUE(`win_t`.`n`)"); - expect(nthValue(cols.n, 2).toQuery(mysqlQueryConfig).sql).toBe("NTH_VALUE(`win_t`.`n`, ?)"); - expect(ntile(5).toQuery(mysqlQueryConfig).sql).toBe("NTILE(?)"); - }); - - it("lag/lead optional arguments", () => { - expect(lag(cols.n).toQuery(mysqlQueryConfig).sql).toBe("LAG(`win_t`.`n`)"); - expect(lag(cols.n, 2).toQuery(mysqlQueryConfig).sql).toBe("LAG(`win_t`.`n`, ?)"); - expect(lag(cols.n, 2, 0).toQuery(mysqlQueryConfig).sql).toBe("LAG(`win_t`.`n`, ?, ?)"); - - expect(lead(cols.n).toQuery(mysqlQueryConfig).sql).toBe("LEAD(`win_t`.`n`)"); - expect(lead(cols.n, 3).toQuery(mysqlQueryConfig).sql).toBe("LEAD(`win_t`.`n`, ?)"); - expect(lead(cols.n, 3, -1).toQuery(mysqlQueryConfig).sql).toBe("LEAD(`win_t`.`n`, ?, ?)"); - }); -}); diff --git a/__tests__/src/lib/cache/NopCache.test.ts b/__tests__/src/lib/cache/NopCache.test.ts deleted file mode 100644 index 19058fa2d..000000000 --- a/__tests__/src/lib/cache/NopCache.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; -import { NopCache } from "../../../../src"; - -describe("NopCache", () => { - let cache: NopCache; - let warnSpy: ReturnType; - - const query = { - toSQL: () => ({ sql: "SELECT * FROM `users`", params: [] }), - } as any; - - beforeEach(() => { - cache = new NopCache(); - warnSpy = vi.spyOn(console, "warn").mockImplementation(() => undefined); - }); - - afterEach(() => { - warnSpy.mockRestore(); - }); - - it("getQueryResultsFromCache reports a cache miss and warns", async () => { - const result = await cache.getQueryResultsFromCache(query); - - expect(result).toBeUndefined(); - expect(warnSpy).toHaveBeenCalledWith( - expect.stringContaining("NopCache.getQueryResultsFromCache is invoked"), - ); - expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("SELECT * FROM `users`")); - }); - - it("setQueryResult is a no-op that resolves and warns", async () => { - await expect(cache.setQueryResult()).resolves.toBeUndefined(); - expect(warnSpy).toHaveBeenCalledWith( - expect.stringContaining("NopCache.setQueryResult is invoked"), - ); - }); - - it("clearExpiredCache is a no-op that resolves and warns", async () => { - await expect(cache.clearExpiredCache()).resolves.toBeUndefined(); - expect(warnSpy).toHaveBeenCalledWith( - expect.stringContaining("NopCache.clearExpiredCache is invoked"), - ); - }); - - it("clearTablesCache is a no-op that resolves and warns with the table names", async () => { - await expect(cache.clearTablesCache(["users", "orders"])).resolves.toBeUndefined(); - expect(warnSpy).toHaveBeenCalledWith( - expect.stringContaining("NopCache.clearTablesCache is invoked for tables: users, orders"), - ); - }); -}); diff --git a/__tests__/src/lib/drizzle/extensions/additionalActions.test.ts b/__tests__/src/lib/drizzle/extensions/additionalActions.test.ts deleted file mode 100644 index 4f87489aa..000000000 --- a/__tests__/src/lib/drizzle/extensions/additionalActions.test.ts +++ /dev/null @@ -1,740 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeEach, vi } from "vitest"; -import { drizzle } from "drizzle-orm/mysql-proxy"; -import { sql } from "drizzle-orm"; -import { eq } from "drizzle-orm"; -import { mysqlTable, int, varchar } from "drizzle-orm/mysql-core"; -import { patchDbWithSelectAliased, forgeDriver, ForgeSqlOrmOptions } from "../../../../../src"; - -// Mock @forge/sql -vi.mock("@forge/sql", () => ({ - sql: { - prepare: vi.fn((query: string) => { - const executeMock = vi.fn().mockResolvedValue({ - rows: [{ id: 1, name: "Test", email: "test@example.com" }], - metadata: { - dbExecutionTime: 100, - responseSize: 100, - }, - }); - return { - query: query || "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn(), - execute: executeMock, - }; - }), - executeDDL: vi.fn(), - }, -})); - -// Mock @forge/kvs to prevent real API calls -const mockKvsEntity = { - get: vi.fn().mockResolvedValue(undefined), - set: vi.fn().mockResolvedValue(undefined), - delete: vi.fn().mockResolvedValue(undefined), -}; - -// Create a factory function to always return a new object with execute method -const createMockKvsTransactSet = () => ({ - execute: vi.fn().mockResolvedValue(undefined), -}); - -const mockKvsTransact = { - set: vi.fn(() => createMockKvsTransactSet()), - delete: vi.fn(() => createMockKvsTransactSet()), -}; - -vi.mock("@forge/kvs", () => ({ - kvs: { - entity: vi.fn(() => mockKvsEntity), - transact: vi.fn(() => mockKvsTransact), - }, -})); - -// Create mock functions that we can access later -const mockGetFromCache = vi.fn().mockResolvedValue(undefined); -const mockSetCacheResult = vi.fn().mockResolvedValue(undefined); -const mockClearCache = vi.fn().mockResolvedValue(undefined); -const mockHashKey = vi.fn(() => "test-key"); - -// Ensure mocks are reset before each test -const resetCacheMocks = () => { - mockGetFromCache.mockClear(); - mockSetCacheResult.mockClear(); - mockClearCache.mockClear(); - mockGetFromCache.mockResolvedValue(undefined); - mockSetCacheResult.mockResolvedValue(undefined); - mockClearCache.mockResolvedValue(undefined); -}; - -const mockCacheApplicationContextGetStore = vi.fn(() => null); -const mockEvictLocalCacheQuery = vi.fn().mockResolvedValue(undefined); -const mockGetQueryLocalCacheQuery = vi.fn().mockResolvedValue(undefined); -const mockSaveQueryLocalCacheQuery = vi.fn().mockResolvedValue(undefined); -const mockSaveTableIfInsideCacheContext = vi.fn().mockResolvedValue(undefined); - -// Mock cache utilities -vi.mock("../../../src/utils/cacheUtils", () => ({ - getFromCache: mockGetFromCache, - setCacheResult: mockSetCacheResult, - clearCache: mockClearCache, - hashKey: mockHashKey, -})); - -// Mock cache context utilities -const mockLocalCacheApplicationContextGetStore = vi.fn(() => null); -vi.mock("../../../src/utils/cacheContextUtils", () => ({ - cacheApplicationContext: { - getStore: mockCacheApplicationContextGetStore, - }, - localCacheApplicationContext: { - getStore: mockLocalCacheApplicationContextGetStore, - }, - evictLocalCacheQuery: mockEvictLocalCacheQuery, - getQueryLocalCacheQuery: mockGetQueryLocalCacheQuery, - saveQueryLocalCacheQuery: mockSaveQueryLocalCacheQuery, - saveTableIfInsideCacheContext: mockSaveTableIfInsideCacheContext, -})); - -// Mock mapSelectFieldsWithAlias and applyFromDriverTransform -vi.mock("../../../src/utils/sqlUtils", () => ({ - mapSelectFieldsWithAlias: vi.fn((fields) => ({ - selections: fields, - aliasMap: {}, - })), - applyFromDriverTransform: vi.fn((rows) => rows), -})); - -describe("additionalActions", () => { - let db: any; - const testTable = mysqlTable("test_users", { - id: int("id").primaryKey(), - name: varchar("name", { length: 255 }), - email: varchar("email", { length: 255 }), - }); - - const defaultOptions: ForgeSqlOrmOptions = { - cacheEntityName: "cache", - cacheTTL: 120, - logRawSqlQuery: false, - disableOptimisticLocking: false, - }; - - beforeEach(async () => { - vi.clearAllMocks(); - resetCacheMocks(); - // Reset cache query mocks - use mockImplementation to ensure it works correctly - // Don't reset the implementation here - let each test set it up as needed - mockGetQueryLocalCacheQuery.mockClear(); - mockSaveQueryLocalCacheQuery.mockClear(); - mockSaveQueryLocalCacheQuery.mockResolvedValue(undefined); - // Provide a fake cache SPI: reads miss (so queries execute), writes/evicts are no-ops. - defaultOptions.cacheImplementation = { - getQueryResultsFromCache: vi.fn().mockResolvedValue(undefined), - setQueryResult: vi.fn().mockResolvedValue(undefined), - clearTablesCache: vi.fn().mockResolvedValue(undefined), - clearExpiredCache: vi.fn().mockResolvedValue(undefined), - }; - const baseDb = drizzle(forgeDriver); - db = patchDbWithSelectAliased(baseDb, defaultOptions); - }); - - describe("patchDbWithSelectAliased", () => { - it("should add all required methods to database", () => { - expect(db).toHaveProperty("selectAliased"); - expect(db).toHaveProperty("selectAliasedDistinct"); - expect(db).toHaveProperty("selectAliasedCacheable"); - expect(db).toHaveProperty("selectAliasedDistinctCacheable"); - expect(db).toHaveProperty("selectFrom"); - expect(db).toHaveProperty("selectDistinctFrom"); - expect(db).toHaveProperty("selectFromCacheable"); - expect(db).toHaveProperty("selectDistinctFromCacheable"); - expect(db).toHaveProperty("insertAndEvictCache"); - expect(db).toHaveProperty("updateAndEvictCache"); - expect(db).toHaveProperty("deleteAndEvictCache"); - expect(db).toHaveProperty("insertWithCacheContext"); - expect(db).toHaveProperty("updateWithCacheContext"); - expect(db).toHaveProperty("deleteWithCacheContext"); - expect(db).toHaveProperty("executeQuery"); - expect(db).toHaveProperty("executeQueryCacheable"); - }); - - it("should use default options when none provided", () => { - const dbWithoutOptions = drizzle(forgeDriver); - const patchedDb = patchDbWithSelectAliased(dbWithoutOptions); - - expect(patchedDb).toBeDefined(); - expect(patchedDb).toHaveProperty("selectFrom"); - }); - - it("should use provided options", () => { - const customOptions: ForgeSqlOrmOptions = { - cacheEntityName: "custom_cache", - cacheTTL: 300, - logRawSqlQuery: true, - }; - - const dbWithOptions = drizzle(forgeDriver); - const patchedDb = patchDbWithSelectAliased(dbWithOptions, customOptions); - - expect(patchedDb).toBeDefined(); - expect(patchedDb).toHaveProperty("selectFrom"); - }); - }); - - describe("selectFrom", () => { - it("should create a select query builder from table", async () => { - const query = db.selectFrom(testTable).where(eq(testTable.id, 1)); - - expect(query).toBeDefined(); - expect(query).toHaveProperty("then"); - }); - - it("should execute selectFrom query and return results", async () => { - const results = await db.selectFrom(testTable).where(eq(testTable.id, 1)); - - expect(results).toBeDefined(); - expect(Array.isArray(results)).toBe(true); - }); - - it("should support method chaining", () => { - const query = db.selectFrom(testTable).where(eq(testTable.id, 1)).limit(10); - - expect(query).toBeDefined(); - }); - }); - - describe("selectDistinctFrom", () => { - it("should create a select distinct query builder from table", async () => { - const query = db.selectDistinctFrom(testTable).where(eq(testTable.id, 1)); - - expect(query).toBeDefined(); - expect(query).toHaveProperty("then"); - }); - }); - - describe("selectFromCacheable", () => { - it("should create a cached select query builder from table", async () => { - const query = db.selectFromCacheable(testTable, 300).where(eq(testTable.id, 1)); - - expect(query).toBeDefined(); - expect(query).toHaveProperty("then"); - }); - - it("should execute cached query successfully", async () => { - const query = db.selectFromCacheable(testTable, 300).where(eq(testTable.id, 1)); - const result = await query; - - expect(result).toBeDefined(); - expect(Array.isArray(result)).toBe(true); - }); - - it("should support custom cache TTL", async () => { - const query = db.selectFromCacheable(testTable, 600).where(eq(testTable.id, 1)); - const result = await query; - - expect(result).toBeDefined(); - }); - }); - - describe("selectDistinctFromCacheable", () => { - it("should create a cached select distinct query builder from table", async () => { - const query = db.selectDistinctFromCacheable(testTable, 300).where(eq(testTable.id, 1)); - - expect(query).toBeDefined(); - expect(query).toHaveProperty("then"); - }); - }); - - describe("selectAliased", () => { - it("should create a select query with field aliasing", async () => { - const query = db - .selectAliased({ - userId: testTable.id, - userName: testTable.name, - }) - .from(testTable) - .where(eq(testTable.id, 1)); - - expect(query).toBeDefined(); - const results = await query; - expect(results).toBeDefined(); - }); - - it("should handle nested field selections", async () => { - const query = db - .selectAliased({ - user: { - id: testTable.id, - name: testTable.name, - }, - }) - .from(testTable); - - expect(query).toBeDefined(); - const results = await query; - expect(results).toBeDefined(); - }); - - it("should support method chaining", () => { - const query = db - .selectAliased({ - id: testTable.id, - name: testTable.name, - }) - .from(testTable) - .where(eq(testTable.id, 1)) - .limit(10); - - expect(query).toBeDefined(); - }); - }); - - describe("selectAliasedCacheable", () => { - it("should create a cached select query with field aliasing", async () => { - const query = db - .selectAliasedCacheable( - { - userId: testTable.id, - userName: testTable.name, - }, - 300, - ) - .from(testTable) - .where(eq(testTable.id, 1)); - - expect(query).toBeDefined(); - const results = await query; - expect(results).toBeDefined(); - }); - }); - - describe("selectAliasedDistinct", () => { - it("should create a select distinct query with field aliasing", async () => { - const query = db - .selectAliasedDistinct({ - userId: testTable.id, - userName: testTable.name, - }) - .from(testTable); - - expect(query).toBeDefined(); - const results = await query; - expect(results).toBeDefined(); - }); - }); - - describe("selectAliasedDistinctCacheable", () => { - it("should create a cached select distinct query with field aliasing", async () => { - const query = db - .selectAliasedDistinctCacheable( - { - userId: testTable.id, - userName: testTable.name, - }, - 300, - ) - .from(testTable); - - expect(query).toBeDefined(); - const results = await query; - expect(results).toBeDefined(); - }); - }); - - describe("cached query execution - global cache", () => { - it("should handle cache set errors gracefully", async () => { - mockGetQueryLocalCacheQuery.mockResolvedValue(undefined); - mockGetFromCache.mockResolvedValue(undefined); - mockSetCacheResult.mockRejectedValueOnce(new Error("Cache set failed")); - - const query = db.selectFromCacheable(testTable, 300).where(eq(testTable.id, 1)); - const result = await query; - - // Should still return result even if cache set fails - expect(result).toBeDefined(); - }); - }); - - describe("executeQuery", () => { - it("should execute raw SQL query with local cache", async () => { - const result = await db.executeQuery(sql`SELECT * FROM test_users WHERE id = 1`); - - expect(result).toBeDefined(); - expect(Array.isArray(result) || typeof result === "object").toBe(true); - }); - - it("should execute string SQL query", async () => { - const result = await db.executeQuery("SELECT * FROM test_users WHERE id = 1"); - - expect(result).toBeDefined(); - expect(Array.isArray(result) || typeof result === "object").toBe(true); - }); - }); - - describe("executeQueryCacheable", () => { - it("should execute raw SQL query with local and global cache", async () => { - const result = await db.executeQueryCacheable( - sql`SELECT * FROM test_users WHERE id = 1`, - 300, - ); - - expect(result).toBeDefined(); - expect(Array.isArray(result) || typeof result === "object").toBe(true); - }); - - it("should execute string SQL query with caching", async () => { - const result = await db.executeQueryCacheable("SELECT * FROM test_users WHERE id = 1", 300); - - expect(result).toBeDefined(); - expect(Array.isArray(result) || typeof result === "object").toBe(true); - }); - }); - - describe("insertAndEvictCache", () => { - it("should create insert builder that evicts cache", async () => { - const insertBuilder = db.insertAndEvictCache(testTable); - - expect(insertBuilder).toBeDefined(); - expect(insertBuilder).toHaveProperty("values"); - const builderWithValues = insertBuilder.values({ name: "Test", email: "test@example.com" }); - expect(builderWithValues).toHaveProperty("then"); - }); - - it("should execute insert and evict cache", async () => { - const insertBuilder = db.insertAndEvictCache(testTable).values({ - name: "New User", - email: "new@example.com", - }); - - expect(insertBuilder).toBeDefined(); - }); - - it("should clear cache when cache context is not available", async () => { - mockCacheApplicationContextGetStore.mockReturnValueOnce(null); - - const insertBuilder = db.insertAndEvictCache(testTable).values({ - name: "Test", - email: "test@example.com", - }); - - expect(insertBuilder).toBeDefined(); - }); - - it("should handle cache errors gracefully", async () => { - mockEvictLocalCacheQuery.mockRejectedValueOnce(new Error("Cache error")); - - const insertBuilder = db.insertAndEvictCache(testTable).values({ - name: "Test", - email: "test@example.com", - }); - - expect(insertBuilder).toBeDefined(); - }); - }); - - describe("updateAndEvictCache", () => { - it("should create update builder that evicts cache", async () => { - const updateBuilder = db.updateAndEvictCache(testTable); - - expect(updateBuilder).toBeDefined(); - expect(updateBuilder).toHaveProperty("set"); - const builderWithSet = updateBuilder.set({ name: "Updated" }); - expect(builderWithSet).toHaveProperty("where"); - expect(builderWithSet).toHaveProperty("then"); - }); - - it("should handle cache errors gracefully", async () => { - mockEvictLocalCacheQuery.mockRejectedValueOnce(new Error("Cache error")); - - const updateBuilder = db.updateAndEvictCache(testTable).set({ name: "Updated" }); - - expect(updateBuilder).toBeDefined(); - }); - }); - - describe("deleteAndEvictCache", () => { - it("should create delete builder that evicts cache", async () => { - const deleteBuilder = db.deleteAndEvictCache(testTable); - - expect(deleteBuilder).toBeDefined(); - expect(deleteBuilder).toHaveProperty("where"); - expect(deleteBuilder).toHaveProperty("then"); - }); - - it("should handle cache errors gracefully", async () => { - mockEvictLocalCacheQuery.mockRejectedValueOnce(new Error("Cache error")); - - const deleteBuilder = db.deleteAndEvictCache(testTable).where(eq(testTable.id, 1)); - - expect(deleteBuilder).toBeDefined(); - }); - }); - - describe("insertWithCacheContext", () => { - it("should create insert builder that participates in cache context", async () => { - const insertBuilder = db.insertWithCacheContext(testTable); - - expect(insertBuilder).toBeDefined(); - expect(insertBuilder).toHaveProperty("values"); - }); - - it("should use cache context when available", async () => { - mockCacheApplicationContextGetStore.mockReturnValueOnce({} as any); - - const insertBuilder = db.insertWithCacheContext(testTable).values({ - name: "Test", - email: "test@example.com", - }); - - expect(insertBuilder).toBeDefined(); - }); - }); - - describe("updateWithCacheContext", () => { - it("should create update builder that participates in cache context", async () => { - const updateBuilder = db.updateWithCacheContext(testTable); - - expect(updateBuilder).toBeDefined(); - expect(updateBuilder).toHaveProperty("set"); - }); - }); - - describe("deleteWithCacheContext", () => { - it("should create delete builder that participates in cache context", async () => { - const deleteBuilder = db.deleteWithCacheContext(testTable); - - expect(deleteBuilder).toBeDefined(); - expect(deleteBuilder).toHaveProperty("where"); - }); - }); - - describe("error handling in query execution", () => { - it("should handle errors in query execution", async () => { - mockGetQueryLocalCacheQuery.mockResolvedValue(undefined); - - // Mock execute to throw error - const forgeSql = await import("@forge/sql"); - const testError = new Error("Query failed"); - vi.mocked(forgeSql.sql.prepare).mockImplementationOnce(() => { - const executeMock = vi.fn().mockRejectedValue(testError); - return { - query: "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn(), - execute: executeMock, - } as any; - }); - - const query = db.selectFrom(testTable).where(eq(testTable.id, 1)); - - try { - await query; - expect.fail("Expected query to throw an error"); - } catch (error: any) { - // Error might be wrapped by drizzle-orm, so check if the original error message is present - // The error might be formatted as "Failed query: ..." by drizzle-orm, so we check for the original message - const errorMessage = error?.message || error?.toString() || ""; - // Check if either the original message or a formatted version is present - expect( - errorMessage.includes("Query failed") || - errorMessage.includes("Failed query") || - error?.cause?.message?.includes("Query failed"), - ).toBe(true); - } - }); - - it("should handle errors in cached query execution", async () => { - mockGetQueryLocalCacheQuery.mockResolvedValue(undefined); - mockGetFromCache.mockResolvedValue(undefined); - - // Mock execute to throw error - const forgeSql = await import("@forge/sql"); - const testError = new Error("Cached query failed"); - vi.mocked(forgeSql.sql.prepare).mockImplementationOnce(() => { - const executeMock = vi.fn().mockRejectedValue(testError); - return { - query: "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn(), - execute: executeMock, - } as any; - }); - - const query = db.selectFromCacheable(testTable, 300).where(eq(testTable.id, 1)); - - try { - await query; - expect.fail("Expected query to throw an error"); - } catch (error: any) { - // Error might be wrapped by drizzle-orm, so check if the original error message is present - // The error might be formatted as "Failed query: ..." by drizzle-orm, so we check for the original message - const errorMessage = error?.message || error?.toString() || ""; - // Check if either the original message or a formatted version is present - expect( - errorMessage.includes("Cached query failed") || - errorMessage.includes("Failed query") || - error?.cause?.message?.includes("Cached query failed"), - ).toBe(true); - } - }); - - it("should handle errors with onrejected callback", async () => { - mockGetQueryLocalCacheQuery.mockResolvedValue(undefined); - mockGetFromCache.mockResolvedValue(undefined); - - const forgeSql = await import("@forge/sql"); - vi.mocked(forgeSql.sql.prepare).mockImplementationOnce(() => { - const executeMock = vi.fn().mockRejectedValue(new Error("Query failed")); - return { - query: "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn(), - execute: executeMock, - } as any; - }); - - const query = db.selectFromCacheable(testTable, 300).where(eq(testTable.id, 1)); - const onRejected = vi.fn(); - - await query.catch(onRejected); - - expect(onRejected).toHaveBeenCalled(); - }); - }); - - describe("query builder properties", () => { - it("should maintain drizzle query builder properties", () => { - const query = db.selectFrom(testTable); - - expect(query).toBeDefined(); - expect(typeof (query as any).where).toBe("function"); - expect(typeof (query as any).limit).toBe("function"); - expect(typeof (query as any).offset).toBe("function"); - }); - - it("should support complex query building", () => { - const query = db - .selectAliased({ - userId: testTable.id, - userName: testTable.name, - userEmail: testTable.email, - }) - .from(testTable) - .where(eq(testTable.id, 1)) - .limit(10); - - expect(query).toBeDefined(); - }); - }); - - describe("cache context behavior", () => { - it("should save table if inside cache context", async () => { - mockCacheApplicationContextGetStore.mockReturnValueOnce({} as any); - - const insertBuilder = db.insertWithCacheContext(testTable).values({ - name: "Test", - email: "test@example.com", - }); - - expect(insertBuilder).toBeDefined(); - }); - - it("should clear cache when cache context is not available and isCached is true", async () => { - mockCacheApplicationContextGetStore.mockReturnValueOnce(null); - - const insertBuilder = db.insertAndEvictCache(testTable).values({ - name: "Test", - email: "test@example.com", - }); - - expect(insertBuilder).toBeDefined(); - }); - }); - - describe("handleSuccessfulExecution error handling", () => { - it("should handle errors in handleSuccessfulExecution and clear cache for cache clearing errors", async () => { - mockEvictLocalCacheQuery.mockRejectedValueOnce(new Error("DEADLOCK")); - mockCacheApplicationContextGetStore.mockReturnValueOnce(null); - mockClearCache.mockResolvedValueOnce(undefined); - - const insertBuilder = db.insertAndEvictCache(testTable).values({ - name: "Test", - email: "test@example.com", - }); - - expect(insertBuilder).toBeDefined(); - }); - - it("should handle errors in handleSuccessfulExecution and not clear cache for validation errors", async () => { - mockEvictLocalCacheQuery.mockRejectedValueOnce(new Error("VALIDATION_ERROR")); - - const insertBuilder = db.insertAndEvictCache(testTable).values({ - name: "Test", - email: "test@example.com", - }); - - expect(insertBuilder).toBeDefined(); - }); - - it("should handle cache clear errors gracefully", async () => { - mockEvictLocalCacheQuery.mockRejectedValueOnce(new Error("LOCK_WAIT_TIMEOUT")); - mockCacheApplicationContextGetStore.mockReturnValueOnce(null); - mockClearCache.mockRejectedValueOnce(new Error("Cache clear failed")); - - const insertBuilder = db.insertAndEvictCache(testTable).values({ - name: "Test", - email: "test@example.com", - }); - - expect(insertBuilder).toBeDefined(); - }); - }); - - describe("handleFunctionCall", () => { - it("should wrap result if it has execute method", () => { - const query = db.selectFrom(testTable).where(eq(testTable.id, 1)); - - expect(query).toBeDefined(); - // Method chaining should work - const chained = (query as any).limit(10); - expect(chained).toBeDefined(); - }); - }); - - describe("onfulfilled callback", () => { - it("should call onfulfilled callback when provided", async () => { - const onFulfilled = vi.fn((rows) => rows); - mockGetQueryLocalCacheQuery.mockResolvedValue(undefined); - - const query = db.selectFrom(testTable).where(eq(testTable.id, 1)); - const result = await query.then(onFulfilled); - - expect(onFulfilled).toHaveBeenCalled(); - expect(result).toBeDefined(); - }); - - it("should call onfulfilled callback for cached queries", async () => { - const onFulfilled = vi.fn((rows) => rows); - mockGetQueryLocalCacheQuery.mockResolvedValue(undefined); - mockGetFromCache.mockResolvedValue(undefined); - - const query = db.selectFromCacheable(testTable, 300).where(eq(testTable.id, 1)); - const result = await query.then(onFulfilled); - - expect(onFulfilled).toHaveBeenCalled(); - expect(result).toBeDefined(); - }); - }); -}); diff --git a/__tests__/src/utils/cacheContextUtils.test.ts b/__tests__/src/utils/cacheContextUtils.test.ts deleted file mode 100644 index 715bb22fc..000000000 --- a/__tests__/src/utils/cacheContextUtils.test.ts +++ /dev/null @@ -1,261 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, vi } from "vitest"; -import { - cacheApplicationContext, - saveTableIfInsideCacheContext, - isTableContainsTableInCacheContext, - CacheApplicationContext, -} from "../../../src/utils/cacheContextUtils"; -import { ForgeSqlOrmOptions } from "../../../src/core/ForgeSQLQueryBuilder"; - -// Mock Drizzle table -const mockTable = { - _: { - name: "users", - schema: undefined, - columns: {}, - indexes: [], - foreignKeys: [], - primaryKeys: [], - uniqueConstraints: [], - checkConstraints: [], - _: { - name: "users", - schema: undefined, - columns: {}, - indexes: [], - foreignKeys: [], - primaryKeys: [], - uniqueConstraints: [], - checkConstraints: [], - }, - }, -} as any; - -// Mock getTableName function -vi.mock("drizzle-orm/table", () => ({ - getTableName: vi.fn((table: any) => table._.name), -})); - -describe("cacheContextUtils", () => { - const defaultOptions: ForgeSqlOrmOptions = { - cacheEntityName: "cache", - cacheTTL: 120, - cacheWrapTable: true, - logRawSqlQuery: false, - disableOptimisticLocking: false, - }; - - describe("saveTableIfInsideCacheContext", () => { - it("should add table to context when inside cache context", async () => { - const context: CacheApplicationContext = { tables: new Set() }; - - await cacheApplicationContext.run(context, async () => { - await saveTableIfInsideCacheContext(mockTable); - - expect(context.tables.has("users")).toBe(true); - }); - }); - - it("should not add table to context when outside cache context", async () => { - const context: CacheApplicationContext = { tables: new Set() }; - - await saveTableIfInsideCacheContext(mockTable); - - expect(context.tables.has("users")).toBe(false); - }); - - it("should add multiple tables to the same context", async () => { - const context: CacheApplicationContext = { tables: new Set() }; - const mockTable2 = { ...mockTable, _: { ...mockTable._, name: "orders" } } as any; - - await cacheApplicationContext.run(context, async () => { - await saveTableIfInsideCacheContext(mockTable); - await saveTableIfInsideCacheContext(mockTable2); - - expect(context.tables.has("users")).toBe(true); - expect(context.tables.has("orders")).toBe(true); - expect(context.tables.size).toBe(2); - }); - }); - - it("should convert table name to lowercase", async () => { - const context: CacheApplicationContext = { tables: new Set() }; - const mockTableUpperCase = { ...mockTable, _: { ...mockTable._, name: "USERS" } } as any; - - await cacheApplicationContext.run(context, async () => { - await saveTableIfInsideCacheContext(mockTableUpperCase); - - expect(context.tables.has("users")).toBe(true); - expect(context.tables.has("USERS")).toBe(false); - }); - }); - }); - - describe("isTableContainsTableInCacheContext", () => { - it("should return false when no cache context exists", async () => { - const result = await isTableContainsTableInCacheContext( - "SELECT * FROM users WHERE id = 1", - defaultOptions, - ); - - expect(result).toBe(false); - }); - - it("should return false when context exists but no tables are tracked", async () => { - const context: CacheApplicationContext = { tables: new Set() }; - - await cacheApplicationContext.run(context, async () => { - const result = await isTableContainsTableInCacheContext( - "SELECT * FROM users WHERE id = 1", - defaultOptions, - ); - - expect(result).toBe(false); - }); - }); - - it("should return true when SQL contains tracked table with cacheWrapTable enabled", async () => { - const context: CacheApplicationContext = { tables: new Set(["users"]) }; - - await cacheApplicationContext.run(context, async () => { - const result = await isTableContainsTableInCacheContext( - "SELECT * FROM `users` WHERE id = 1", - defaultOptions, - ); - - expect(result).toBe(true); - }); - }); - - it("should return true when SQL contains tracked table with cacheWrapTable disabled", async () => { - const options = { ...defaultOptions, cacheWrapTable: false }; - const context: CacheApplicationContext = { tables: new Set(["users"]) }; - - await cacheApplicationContext.run(context, async () => { - const result = await isTableContainsTableInCacheContext( - "SELECT * FROM users WHERE id = 1", - options, - ); - - expect(result).toBe(true); - }); - }); - - it("should return false when SQL does not contain tracked table", async () => { - const context: CacheApplicationContext = { tables: new Set(["orders"]) }; - - await cacheApplicationContext.run(context, async () => { - const result = await isTableContainsTableInCacheContext( - "SELECT * FROM users WHERE id = 1", - defaultOptions, - ); - - expect(result).toBe(false); - }); - }); - - it("should handle case-insensitive table name matching", async () => { - const context: CacheApplicationContext = { tables: new Set(["users"]) }; - - await cacheApplicationContext.run(context, async () => { - const result = await isTableContainsTableInCacheContext( - "SELECT * FROM USERS WHERE id = 1", - { ...defaultOptions, cacheWrapTable: false }, - ); - - expect(result).toBe(true); - }); - }); - - it("should return true when SQL contains any of multiple tracked tables", async () => { - const context: CacheApplicationContext = { tables: new Set(["users", "orders", "products"]) }; - - await cacheApplicationContext.run(context, async () => { - const result = await isTableContainsTableInCacheContext( - "SELECT * FROM orders WHERE user_id = 1", - { ...defaultOptions, cacheWrapTable: false }, - ); - - expect(result).toBe(true); - }); - }); - - it("should return false when SQL contains none of the tracked tables", async () => { - const context: CacheApplicationContext = { tables: new Set(["users", "orders"]) }; - - await cacheApplicationContext.run(context, async () => { - const result = await isTableContainsTableInCacheContext( - "SELECT * FROM products WHERE id = 1", - { ...defaultOptions, cacheWrapTable: false }, - ); - - expect(result).toBe(false); - }); - }); - - it("should handle complex SQL queries with joins", async () => { - const context: CacheApplicationContext = { tables: new Set(["users", "orders"]) }; - - await cacheApplicationContext.run(context, async () => { - const result = await isTableContainsTableInCacheContext( - "SELECT u.*, o.* FROM `users` u INNER JOIN `orders` o ON u.id = o.user_id", - defaultOptions, - ); - - expect(result).toBe(true); - }); - }); - - it("should handle SQL with table names in different positions", async () => { - const context: CacheApplicationContext = { tables: new Set(["users"]) }; - - await cacheApplicationContext.run(context, async () => { - const result = await isTableContainsTableInCacheContext( - 'UPDATE `users` SET name = "test" WHERE id = 1', - defaultOptions, - ); - - expect(result).toBe(true); - }); - }); - }); - - describe("cacheApplicationContext", () => { - it("should maintain context across async operations", async () => { - const context: CacheApplicationContext = { tables: new Set() }; - let capturedContext: CacheApplicationContext | undefined; - - await cacheApplicationContext.run(context, async () => { - await new Promise((resolve) => setTimeout(resolve, 10)); - capturedContext = cacheApplicationContext.getStore(); - }); - - expect(capturedContext).toBe(context); - }); - - it("should isolate contexts between different runs", async () => { - const context1: CacheApplicationContext = { tables: new Set(["users"]) }; - const context2: CacheApplicationContext = { tables: new Set(["orders"]) }; - - await cacheApplicationContext.run(context1, async () => { - const store1 = cacheApplicationContext.getStore(); - expect(store1?.tables.has("users")).toBe(true); - expect(store1?.tables.has("orders")).toBe(false); - }); - - await cacheApplicationContext.run(context2, async () => { - const store2 = cacheApplicationContext.getStore(); - expect(store2?.tables.has("users")).toBe(false); - expect(store2?.tables.has("orders")).toBe(true); - }); - }); - - it("should return undefined when no context is set", () => { - const store = cacheApplicationContext.getStore(); - expect(store).toBeUndefined(); - }); - }); -}); diff --git a/__tests__/src/utils/cacheUtils.test.ts b/__tests__/src/utils/cacheUtils.test.ts deleted file mode 100644 index d49f24452..000000000 --- a/__tests__/src/utils/cacheUtils.test.ts +++ /dev/null @@ -1,247 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeEach, vi } from "vitest"; -import type { ForgeSqlOrmOptions } from "../../../src/core/ForgeSQLQueryBuilder"; -import type { Cache } from "../../../src"; - -// cacheUtils is a thin SPI-delegation layer over options.cacheImplementation; the actual -// KVS-backed behaviour lives in forge-sql-orm-extra (see KVSCache tests there). -vi.mock("../../../src/utils/cacheContextUtils", () => ({ - cacheApplicationContext: { getStore: vi.fn() }, - isTableContainsTableInCacheContext: vi.fn().mockResolvedValue(false), -})); - -const mockTable = { _: { name: "users" } } as any; - -vi.mock("drizzle-orm/table", () => ({ - getTableName: vi.fn((table: any) => table._.name), -})); - -describe("cacheUtils", () => { - const fakeCache = { - getQueryResultsFromCache: vi.fn(), - setQueryResult: vi.fn(), - clearTablesCache: vi.fn(), - clearExpiredCache: vi.fn(), - } satisfies Cache; - - const defaultOptions: ForgeSqlOrmOptions = { - cacheEntityName: "cache", - cacheTTL: 120, - logCache: true, - cacheWrapTable: true, - cacheImplementation: fakeCache, - }; - - const mockQuery = { - toSQL: vi.fn(() => ({ sql: "SELECT * FROM `users` WHERE id = ?", params: [1] })), - }; - - beforeEach(() => { - vi.clearAllMocks(); - }); - - describe("clearCache", () => { - it("adds the table to the cache context when one is active", async () => { - const { clearCache } = await import("../../../src/utils/cacheUtils"); - const { cacheApplicationContext } = await import("../../../src/utils/cacheContextUtils"); - const store = { tables: new Set() }; - (cacheApplicationContext.getStore as any).mockReturnValue(store); - - await clearCache(mockTable, defaultOptions); - - expect(store.tables.has("users")).toBe(true); - expect(fakeCache.clearTablesCache).not.toHaveBeenCalled(); - }); - - it("clears the table immediately when there is no cache context", async () => { - const { clearCache } = await import("../../../src/utils/cacheUtils"); - const { cacheApplicationContext } = await import("../../../src/utils/cacheContextUtils"); - (cacheApplicationContext.getStore as any).mockReturnValue(undefined); - - await clearCache(mockTable, defaultOptions); - - expect(fakeCache.clearTablesCache).toHaveBeenCalledWith(["users"], defaultOptions); - }); - }); - - describe("getFromCache", () => { - it("throws when cacheImplementation is not configured", async () => { - const { getFromCache } = await import("../../../src/utils/cacheUtils"); - await expect( - getFromCache(mockQuery, { ...defaultOptions, cacheImplementation: undefined }), - ).rejects.toThrow("cacheImplementation is not configured"); - }); - - it("delegates to the cache implementation and returns its value", async () => { - const { getFromCache } = await import("../../../src/utils/cacheUtils"); - fakeCache.getQueryResultsFromCache.mockResolvedValue({ id: 1 }); - - const result = await getFromCache(mockQuery, defaultOptions); - - expect(fakeCache.getQueryResultsFromCache).toHaveBeenCalledWith(mockQuery, defaultOptions); - expect(result).toEqual({ id: 1 }); - }); - - it("swallows implementation errors and returns undefined", async () => { - const { getFromCache } = await import("../../../src/utils/cacheUtils"); - const errorSpy = vi.spyOn(console, "error").mockImplementation(() => undefined); - fakeCache.getQueryResultsFromCache.mockRejectedValue(new Error("boom")); - - const result = await getFromCache(mockQuery, defaultOptions); - - expect(result).toBeUndefined(); - expect(errorSpy).toHaveBeenCalled(); - errorSpy.mockRestore(); - }); - }); - - describe("setCacheResult", () => { - it("throws when cacheImplementation is not configured", async () => { - const { setCacheResult } = await import("../../../src/utils/cacheUtils"); - await expect( - setCacheResult( - mockQuery, - { ...defaultOptions, cacheImplementation: undefined }, - { id: 1 }, - 300, - ), - ).rejects.toThrow("cacheImplementation is not configured"); - }); - - it("delegates to the cache implementation with the TTL", async () => { - const { setCacheResult } = await import("../../../src/utils/cacheUtils"); - const data = { id: 1 }; - - await setCacheResult(mockQuery, defaultOptions, data, 300); - - expect(fakeCache.setQueryResult).toHaveBeenCalledWith(defaultOptions, mockQuery, data, 300); - }); - - it("swallows implementation errors", async () => { - const { setCacheResult } = await import("../../../src/utils/cacheUtils"); - const errorSpy = vi.spyOn(console, "error").mockImplementation(() => undefined); - fakeCache.setQueryResult.mockRejectedValue(new Error("boom")); - - await expect( - setCacheResult(mockQuery, defaultOptions, { id: 1 }, 300), - ).resolves.toBeUndefined(); - expect(errorSpy).toHaveBeenCalled(); - errorSpy.mockRestore(); - }); - }); - - describe("clearTablesCache", () => { - it("throws when cacheImplementation is not configured", async () => { - const { clearTablesCache } = await import("../../../src/utils/cacheUtils"); - await expect( - clearTablesCache(["users"], { ...defaultOptions, cacheImplementation: undefined }), - ).rejects.toThrow("cacheImplementation is not configured"); - }); - - it("delegates to the cache implementation", async () => { - const { clearTablesCache } = await import("../../../src/utils/cacheUtils"); - - await clearTablesCache(["users", "orders"], defaultOptions); - - expect(fakeCache.clearTablesCache).toHaveBeenCalledWith(["users", "orders"], defaultOptions); - }); - - it("swallows implementation errors", async () => { - const { clearTablesCache } = await import("../../../src/utils/cacheUtils"); - const errorSpy = vi.spyOn(console, "error").mockImplementation(() => undefined); - fakeCache.clearTablesCache.mockRejectedValue(new Error("boom")); - - await expect(clearTablesCache(["users"], defaultOptions)).resolves.toBeUndefined(); - expect(errorSpy).toHaveBeenCalled(); - errorSpy.mockRestore(); - }); - }); - - describe("clearExpiredCache", () => { - it("throws when cacheImplementation is not configured", async () => { - const { clearExpiredCache } = await import("../../../src/utils/cacheUtils"); - await expect( - clearExpiredCache({ ...defaultOptions, cacheImplementation: undefined }), - ).rejects.toThrow("cacheImplementation is not configured"); - }); - - it("delegates to the cache implementation", async () => { - const { clearExpiredCache } = await import("../../../src/utils/cacheUtils"); - - await clearExpiredCache(defaultOptions); - - expect(fakeCache.clearExpiredCache).toHaveBeenCalledWith(defaultOptions); - }); - - it("swallows implementation errors", async () => { - const { clearExpiredCache } = await import("../../../src/utils/cacheUtils"); - const errorSpy = vi.spyOn(console, "error").mockImplementation(() => undefined); - fakeCache.clearExpiredCache.mockRejectedValue(new Error("boom")); - - await expect(clearExpiredCache(defaultOptions)).resolves.toBeUndefined(); - expect(errorSpy).toHaveBeenCalled(); - errorSpy.mockRestore(); - }); - }); - - describe("logging", () => { - it("debugCacheLog logs only when logCache is enabled", async () => { - const { debugCacheLog } = await import("../../../src/utils/cacheUtils"); - const debugSpy = vi.spyOn(console, "debug").mockImplementation(() => undefined); - - debugCacheLog("hello", { ...defaultOptions, logCache: false }); - expect(debugSpy).not.toHaveBeenCalled(); - - debugCacheLog("hello", { ...defaultOptions, logCache: true }); - expect(debugSpy).toHaveBeenCalledWith("hello"); - debugSpy.mockRestore(); - }); - - it("warnCacheLog logs only when logCache is enabled", async () => { - const { warnCacheLog } = await import("../../../src/utils/cacheUtils"); - const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => undefined); - - warnCacheLog("careful", { ...defaultOptions, logCache: false }); - expect(warnSpy).not.toHaveBeenCalled(); - - warnCacheLog("careful", { ...defaultOptions, logCache: true }); - expect(warnSpy).toHaveBeenCalledWith("careful"); - warnSpy.mockRestore(); - }); - }); - - describe("hashKey", () => { - it("generates a consistent hash for the same query", async () => { - const { hashKey } = await import("../../../src/utils/cacheUtils"); - const query = { sql: "SELECT * FROM users WHERE id = ?", params: [1] }; - - expect(hashKey(query)).toBe(hashKey({ ...query })); - expect(hashKey(query)).toMatch(/^CachedQuery_[a-f0-9]{32}$/); - }); - - it("generates different hashes for different params", async () => { - const { hashKey } = await import("../../../src/utils/cacheUtils"); - const sql = "SELECT * FROM users WHERE id = ?"; - - expect(hashKey({ sql, params: [1] })).not.toBe(hashKey({ sql, params: [2] })); - }); - - it("generates different hashes for different SQL", async () => { - const { hashKey } = await import("../../../src/utils/cacheUtils"); - - expect(hashKey({ sql: "SELECT * FROM users WHERE id = ?", params: [1] })).not.toBe( - hashKey({ sql: "SELECT * FROM users WHERE name = ?", params: [1] }), - ); - }); - - it("is case-insensitive on the SQL", async () => { - const { hashKey } = await import("../../../src/utils/cacheUtils"); - - expect(hashKey({ sql: "SELECT * FROM users", params: [] })).toBe( - hashKey({ sql: "select * from users", params: [] }), - ); - }); - }); -}); diff --git a/__tests__/src/utils/errorUtils.test.ts b/__tests__/src/utils/errorUtils.test.ts deleted file mode 100644 index 84e3079d6..000000000 --- a/__tests__/src/utils/errorUtils.test.ts +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect } from "vitest"; -import { extractSqlErrorMessage, getErrorMessage } from "../../../src/utils/errorUtils"; - -describe("errorUtils", () => { - describe("getErrorMessage", () => { - it("returns Error.message for Error instances", () => { - expect(getErrorMessage(new Error("boom"))).toBe("boom"); - }); - - it("returns subclass Error.message", () => { - class CustomError extends Error {} - expect(getErrorMessage(new CustomError("derived"))).toBe("derived"); - }); - - it("returns the value as-is when given a string", () => { - expect(getErrorMessage("plain text")).toBe("plain text"); - }); - - it("returns the empty string when an Error has an empty message", () => { - expect(getErrorMessage(new Error(""))).toBe(""); - }); - - it("returns the fallback for null", () => { - expect(getErrorMessage(null)).toBe("Unknown error"); - }); - - it("returns the fallback for undefined", () => { - expect(getErrorMessage(undefined)).toBe("Unknown error"); - }); - - it("honours a custom fallback for null", () => { - expect(getErrorMessage(null, "missing")).toBe("missing"); - }); - - it("JSON-stringifies plain objects instead of returning [object Object]", () => { - expect(getErrorMessage({ code: 42, info: "x" })).toBe('{"code":42,"info":"x"}'); - }); - - it("returns the fallback when JSON.stringify throws on a circular object", () => { - const cyclic: Record = {}; - cyclic.self = cyclic; - expect(getErrorMessage(cyclic, "ring")).toBe("ring"); - }); - - it("converts numbers via String()", () => { - expect(getErrorMessage(404)).toBe("404"); - }); - - it("converts booleans via String()", () => { - expect(getErrorMessage(false)).toBe("false"); - }); - - it("converts symbols via String()", () => { - expect(getErrorMessage(Symbol("tag"))).toBe("Symbol(tag)"); - }); - }); - - describe("extractSqlErrorMessage", () => { - it("picks cause.context.debug.sqlMessage with highest priority", () => { - const err = { - message: "low", - debug: { sqlMessage: "mid", message: "lower-mid" }, - cause: { context: { debug: { sqlMessage: "top", message: "alt" } } }, - }; - expect(extractSqlErrorMessage(err)).toBe("top"); - }); - - it("falls through to cause.context.debug.message when sqlMessage is missing", () => { - const err = { - message: "fallback", - cause: { context: { debug: { message: "via cause.message" } } }, - }; - expect(extractSqlErrorMessage(err)).toBe("via cause.message"); - }); - - it("falls through to debug.context.sqlMessage", () => { - const err = { - message: "fallback", - debug: { context: { sqlMessage: "deep" } }, - }; - expect(extractSqlErrorMessage(err)).toBe("deep"); - }); - - it("falls through to debug.context.message", () => { - const err = { - message: "fallback", - debug: { context: { message: "ctx-msg" } }, - }; - expect(extractSqlErrorMessage(err)).toBe("ctx-msg"); - }); - - it("falls through to debug.sqlMessage", () => { - const err = { message: "fallback", debug: { sqlMessage: "direct-sql" } }; - expect(extractSqlErrorMessage(err)).toBe("direct-sql"); - }); - - it("falls through to debug.message", () => { - const err = { message: "fallback", debug: { message: "direct-debug" } }; - expect(extractSqlErrorMessage(err)).toBe("direct-debug"); - }); - - it("falls through to error.message when no debug info is present", () => { - expect(extractSqlErrorMessage(new Error("just message"))).toBe("just message"); - }); - - it("returns the default fallback for null", () => { - expect(extractSqlErrorMessage(null)).toBe("Unknown error occurred"); - }); - - it("returns the default fallback for undefined", () => { - expect(extractSqlErrorMessage(undefined)).toBe("Unknown error occurred"); - }); - - it("returns the default fallback for strings (no traversable shape)", () => { - expect(extractSqlErrorMessage("oops")).toBe("Unknown error occurred"); - }); - - it("returns the default fallback for objects without any known field", () => { - expect(extractSqlErrorMessage({ unrelated: true })).toBe("Unknown error occurred"); - }); - - it("honours a custom fallback", () => { - expect(extractSqlErrorMessage({}, "custom")).toBe("custom"); - }); - - it("ignores non-string values along the path", () => { - const err = { message: 42 as unknown as string }; - expect(extractSqlErrorMessage(err, "fb")).toBe("fb"); - }); - - it("ignores null intermediate nodes without throwing", () => { - const err = { debug: null, message: "after-null" }; - expect(extractSqlErrorMessage(err)).toBe("after-null"); - }); - }); -}); diff --git a/__tests__/src/utils/forgeDriver.test.ts b/__tests__/src/utils/forgeDriver.test.ts deleted file mode 100644 index 76c34fa11..000000000 --- a/__tests__/src/utils/forgeDriver.test.ts +++ /dev/null @@ -1,524 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeEach, vi } from "vitest"; -import { - forgeDriver, - isUpdateQueryResponse, - ForgeSQLMetadata, -} from "../../../src/utils/forgeDriver"; - -// Mock dependencies -const mockSaveMetaDataToContext = vi.fn(); -const mockGetOperationType = vi.fn(); -const mockWithTimeout = vi.fn(); - -// Mock @forge/sql -const mockSqlPrepare = vi.fn(); -const mockBindParams = vi.fn(); -const mockExecute = vi.fn(); - -const createMockSqlStatement = () => ({ - bindParams: mockBindParams, - execute: mockExecute, -}); - -vi.mock("../../../src/utils/metadataContextUtils", () => ({ - saveMetaDataToContext: (...args: any[]) => mockSaveMetaDataToContext(...args), -})); - -vi.mock("../../../src/utils/requestTypeContextUtils", () => ({ - getOperationType: (...args: any[]) => mockGetOperationType(...args), -})); - -vi.mock("../../../src/utils/sqlUtils", () => ({ - withTimeout: (...args: any[]) => mockWithTimeout(...args), -})); - -vi.mock("@forge/sql", () => ({ - sql: { - prepare: (...args: any[]) => mockSqlPrepare(...args), - }, -})); - -vi.mock("@forge/sql/out/sql", () => ({ - SQL_API_ENDPOINTS: { - EXECUTE_DDL: "EXECUTE_DDL", - }, -})); - -describe("forgeDriver", () => { - const mockMetadata: ForgeSQLMetadata = { - dbExecutionTime: 100, - responseSize: 1024, - fields: [ - { - catalog: "def", - name: "id", - schema: "", - characterSet: 63, - decimals: 0, - table: "users", - orgTable: "users", - orgName: "id", - flags: 0, - columnType: 3, - columnLength: 11, - }, - ], - }; - - beforeEach(() => { - vi.clearAllMocks(); - mockGetOperationType.mockResolvedValue("QUERY"); - mockWithTimeout.mockImplementation(async (promise) => promise); - // For execute method: sql.prepare returns synchronously - // For all method: sql.prepare returns a promise - // For DDL: sql.prepare(query, SQL_API_ENDPOINTS.EXECUTE_DDL) returns object with bindParams and execute - mockSqlPrepare.mockImplementation((query: string, endpoint?: string) => { - // DDL operations use sql.prepare(query, SQL_API_ENDPOINTS.EXECUTE_DDL) - if (endpoint === "EXECUTE_DDL") { - return createMockSqlStatement(); - } - // Check if it's a SELECT query (all method) - return promise - if (query.trim().toUpperCase().startsWith("SELECT")) { - return createMockSqlStatement(); - } - // For execute method (UPDATE/INSERT/DELETE) - return synchronously - return createMockSqlStatement(); - }); - mockBindParams.mockReturnValue(createMockSqlStatement()); - mockExecute.mockResolvedValue({ - rows: [{ id: 1, name: "Test" }], - metadata: mockMetadata, - }); - mockSaveMetaDataToContext.mockResolvedValue(undefined); - }); - - describe("isUpdateQueryResponse", () => { - it("should return true for valid UpdateQueryResponse", () => { - const obj = { affectedRows: 1, insertId: 123 }; - expect(isUpdateQueryResponse(obj)).toBe(true); - }); - - it("should return false for null", () => { - expect(isUpdateQueryResponse(null)).toBe(false); - }); - - it("should return false for non-object", () => { - expect(isUpdateQueryResponse("string")).toBe(false); - expect(isUpdateQueryResponse(123)).toBe(false); - expect(isUpdateQueryResponse(true)).toBe(false); - }); - - it("should return false for object without affectedRows", () => { - const obj = { insertId: 123 }; - expect(isUpdateQueryResponse(obj)).toBe(false); - }); - - it("should return false for object without insertId", () => { - const obj = { affectedRows: 1 }; - expect(isUpdateQueryResponse(obj)).toBe(false); - }); - - it("should return false for object with non-number affectedRows", () => { - const obj = { affectedRows: "1", insertId: 123 }; - expect(isUpdateQueryResponse(obj)).toBe(false); - }); - - it("should return false for object with non-number insertId", () => { - const obj = { affectedRows: 1, insertId: "123" }; - expect(isUpdateQueryResponse(obj)).toBe(false); - }); - }); - - describe("forgeDriver - DDL operations", () => { - it("should handle DDL operations with executeDDL", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [], - metadata: mockMetadata, - }); - - const result = await forgeDriver("CREATE TABLE users (id INT)", [], "all"); - - expect(result).toEqual({ rows: [] }); - expect(mockGetOperationType).toHaveBeenCalled(); - expect(mockSqlPrepare).toHaveBeenCalledWith("CREATE TABLE users (id INT)", "EXECUTE_DDL"); - expect(mockBindParams).toHaveBeenCalledWith([]); - expect(mockExecute).toHaveBeenCalled(); - expect(mockSaveMetaDataToContext).toHaveBeenCalledWith( - "CREATE TABLE users (id INT)", - [], - mockMetadata, - ); - }); - - it("should handle params for DDL operations", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [], - metadata: mockMetadata, - }); - - await forgeDriver("CREATE TABLE users (id INT, name VARCHAR(?))", ["255"], "all"); - - expect(mockSqlPrepare).toHaveBeenCalledWith( - "CREATE TABLE users (id INT, name VARCHAR(?))", - "EXECUTE_DDL", - ); - expect(mockBindParams).toHaveBeenCalledWith(["255"]); - }); - - it("should handle null params in DDL operations", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [], - metadata: mockMetadata, - }); - - await forgeDriver("CREATE TABLE users (id INT, name VARCHAR(?))", [null], "all"); - - expect(mockSqlPrepare).toHaveBeenCalledWith( - "CREATE TABLE users (id INT, name VARCHAR(?))", - "EXECUTE_DDL", - ); - expect(mockBindParams).toHaveBeenCalledWith([null]); - }); - - it("should handle string params with quotes in DDL operations", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [], - metadata: mockMetadata, - }); - - await forgeDriver("CREATE TABLE users (name VARCHAR(?))", ["O'Brien"], "all"); - - expect(mockSqlPrepare).toHaveBeenCalledWith( - "CREATE TABLE users (name VARCHAR(?))", - "EXECUTE_DDL", - ); - expect(mockBindParams).toHaveBeenCalledWith(["O'Brien"]); - }); - - it("should handle DDL result with UpdateQueryResponse rows", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - const updateResponse = { affectedRows: 1, insertId: 123 }; - mockExecute.mockResolvedValue({ - rows: updateResponse, - metadata: mockMetadata, - }); - - const result = await forgeDriver("CREATE TABLE users (id INT)", [], "all"); - - expect(result).toEqual({ - rows: [updateResponse], - affectedRows: 1, - insertId: 123, - }); - }); - - it("should handle DDL result with array rows and execute method", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [{ id: 1 }], - metadata: mockMetadata, - }); - - const result = await forgeDriver("CREATE TABLE users (id INT)", [], "execute"); - - expect(result).toEqual({ rows: [[{ id: 1 }]] }); - }); - - it("should handle DDL result with array rows and all method", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [{ id: 1, name: "Test" }], - metadata: mockMetadata, - }); - - const result = await forgeDriver("CREATE TABLE users (id INT)", [], "all"); - - expect(result).toEqual({ rows: [[1, "Test"]] }); - }); - - it("should handle DDL result without rows", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - metadata: mockMetadata, - }); - - const result = await forgeDriver("CREATE TABLE users (id INT)", [], "all"); - - expect(result).toEqual({ rows: [] }); - }); - - it("should handle DDL result without metadata", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [], - }); - - const result = await forgeDriver("CREATE TABLE users (id INT)", [], "all"); - - expect(result).toEqual({ rows: [] }); - expect(mockSaveMetaDataToContext).not.toHaveBeenCalled(); - }); - }); - - describe("forgeDriver - execute method (UPDATE/INSERT/DELETE)", () => { - it("should handle execute method with parameters", async () => { - const updateResponse = { affectedRows: 1, insertId: 123 }; - mockExecute.mockResolvedValue({ - rows: updateResponse, - metadata: mockMetadata, - }); - - const result = await forgeDriver( - "UPDATE users SET name = ? WHERE id = ?", - ["John", 1], - "execute", - ); - - expect(result).toEqual({ rows: [updateResponse] }); - expect(mockSqlPrepare).toHaveBeenCalledWith("UPDATE users SET name = ? WHERE id = ?"); - expect(mockBindParams).toHaveBeenCalledWith("John", 1); - expect(mockSaveMetaDataToContext).toHaveBeenCalledWith( - "UPDATE users SET name = ? WHERE id = ?", - ["John", 1], - mockMetadata, - ); - }); - - it("should handle execute method without parameters", async () => { - const updateResponse = { affectedRows: 1, insertId: 123 }; - mockExecute.mockResolvedValue({ - rows: updateResponse, - metadata: mockMetadata, - }); - - const result = await forgeDriver("DELETE FROM users", undefined, "execute"); - - expect(result).toEqual({ rows: [updateResponse] }); - expect(mockBindParams).not.toHaveBeenCalled(); - expect(mockSaveMetaDataToContext).toHaveBeenCalledWith("DELETE FROM users", [], mockMetadata); - }); - - it("should handle execute method with empty params array", async () => { - const updateResponse = { affectedRows: 1, insertId: 123 }; - mockExecute.mockResolvedValue({ - rows: updateResponse, - metadata: mockMetadata, - }); - - const result = await forgeDriver("DELETE FROM users", [], "execute"); - - expect(result).toEqual({ rows: [updateResponse] }); - expect(mockBindParams).toHaveBeenCalledWith(); - }); - - it("should handle execute method without rows", async () => { - mockExecute.mockResolvedValue({ - metadata: mockMetadata, - }); - - const result = await forgeDriver("UPDATE users SET name = ?", ["John"], "execute"); - - expect(result).toEqual({ rows: [[]] }); - }); - - it("should use withTimeout for execute method", async () => { - const updateResponse = { affectedRows: 1, insertId: 123 }; - const executePromise = Promise.resolve({ - rows: updateResponse, - metadata: mockMetadata, - }); - mockExecute.mockReturnValue(executePromise); - mockWithTimeout.mockResolvedValue({ - rows: updateResponse, - metadata: mockMetadata, - }); - - await forgeDriver("UPDATE users SET name = ?", ["John"], "execute"); - - expect(mockWithTimeout).toHaveBeenCalledWith( - executePromise, - expect.stringContaining("Atlassian @forge/sql did not return"), - 10000, - ); - }); - }); - - describe("forgeDriver - all method (SELECT)", () => { - it("should handle all method with parameters", async () => { - mockExecute.mockResolvedValue({ - rows: [{ id: 1, name: "Test" }], - metadata: mockMetadata, - }); - - const result = await forgeDriver("SELECT * FROM users WHERE id = ?", [1], "all"); - - expect(result).toEqual({ rows: [[1, "Test"]] }); - expect(mockSqlPrepare).toHaveBeenCalledWith("SELECT * FROM users WHERE id = ?"); - expect(mockBindParams).toHaveBeenCalledWith(1); - expect(mockSaveMetaDataToContext).toHaveBeenCalledWith( - "SELECT * FROM users WHERE id = ?", - [1], - mockMetadata, - ); - }); - - it("should handle all method without parameters", async () => { - mockExecute.mockResolvedValue({ - rows: [{ id: 1, name: "Test" }], - metadata: mockMetadata, - }); - - const result = await forgeDriver("SELECT * FROM users", undefined, "all"); - - expect(result).toEqual({ rows: [[1, "Test"]] }); - expect(mockBindParams).not.toHaveBeenCalled(); - expect(mockSaveMetaDataToContext).toHaveBeenCalledWith( - "SELECT * FROM users", - [], - mockMetadata, - ); - }); - - it("should handle all method with empty params array", async () => { - mockExecute.mockResolvedValue({ - rows: [{ id: 1, name: "Test" }], - metadata: mockMetadata, - }); - - const result = await forgeDriver("SELECT * FROM users", [], "all"); - - expect(result).toEqual({ rows: [[1, "Test"]] }); - expect(mockBindParams).toHaveBeenCalledWith(); - }); - - it("should handle all method without rows", async () => { - mockExecute.mockResolvedValue({ - metadata: mockMetadata, - }); - - const result = await forgeDriver("SELECT * FROM users WHERE id = ?", [999], "all"); - - expect(result).toEqual({ rows: [] }); - }); - - it("should transform rows to array of values", async () => { - mockExecute.mockResolvedValue({ - rows: [ - { id: 1, name: "Test1", email: "test1@example.com" }, - { id: 2, name: "Test2", email: "test2@example.com" }, - ], - metadata: mockMetadata, - }); - - const result = await forgeDriver("SELECT * FROM users", [], "all"); - - expect(result).toEqual({ - rows: [ - [1, "Test1", "test1@example.com"], - [2, "Test2", "test2@example.com"], - ], - }); - }); - - it("should use withTimeout for all method", async () => { - const executePromise = Promise.resolve({ - rows: [{ id: 1, name: "Test" }], - metadata: mockMetadata, - }); - mockExecute.mockReturnValue(executePromise); - mockWithTimeout.mockResolvedValue({ - rows: [{ id: 1, name: "Test" }], - metadata: mockMetadata, - }); - - await forgeDriver("SELECT * FROM users", [], "all"); - - expect(mockWithTimeout).toHaveBeenCalledWith( - executePromise, - expect.stringContaining("Atlassian @forge/sql did not return"), - 10000, - ); - }); - - it("should handle single row result", async () => { - mockExecute.mockResolvedValue({ - rows: [{ id: 1, name: "Test" }], - metadata: mockMetadata, - }); - - const result = await forgeDriver("SELECT * FROM users WHERE id = ?", [1], "all"); - - expect(result).toEqual({ rows: [[1, "Test"]] }); - }); - }); - - describe("edge cases", () => { - it("should handle undefined params for DDL", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [], - metadata: mockMetadata, - }); - - await forgeDriver("CREATE TABLE users (id INT)", undefined, "all"); - - expect(mockSqlPrepare).toHaveBeenCalledWith("CREATE TABLE users (id INT)", "EXECUTE_DDL"); - expect(mockBindParams).toHaveBeenCalledWith([]); - }); - - it("should handle numeric params in DDL", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [], - metadata: mockMetadata, - }); - - await forgeDriver("CREATE TABLE users (id INT, count INT(?))", [100], "all"); - - expect(mockSqlPrepare).toHaveBeenCalledWith( - "CREATE TABLE users (id INT, count INT(?))", - "EXECUTE_DDL", - ); - expect(mockBindParams).toHaveBeenCalledWith([100]); - }); - - it("should handle multiple params in DDL", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: [], - metadata: mockMetadata, - }); - - await forgeDriver( - "CREATE TABLE users (id INT, name VARCHAR(?), age INT(?))", - ["255", 50], - "all", - ); - - expect(mockSqlPrepare).toHaveBeenCalledWith( - "CREATE TABLE users (id INT, name VARCHAR(?), age INT(?))", - "EXECUTE_DDL", - ); - expect(mockBindParams).toHaveBeenCalledWith(["255", 50]); - }); - - it("should handle DDL result with non-array, non-UpdateQueryResponse rows", async () => { - mockGetOperationType.mockResolvedValue("DDL"); - mockExecute.mockResolvedValue({ - rows: "some string" as any, - metadata: mockMetadata, - }); - - const result = await forgeDriver("CREATE TABLE users (id INT)", [], "all"); - - expect(result).toEqual({ rows: [] }); - }); - }); -}); diff --git a/__tests__/src/utils/forgeDriverProxy.test.ts b/__tests__/src/utils/forgeDriverProxy.test.ts deleted file mode 100644 index 5ed7a27cb..000000000 --- a/__tests__/src/utils/forgeDriverProxy.test.ts +++ /dev/null @@ -1,366 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeEach, vi } from "vitest"; -import { createForgeDriverProxy } from "../../../src/utils/forgeDriverProxy"; -import { ForgeSqlOperation } from "../../../src/core/ForgeSQLQueryBuilder"; -import { SqlHints } from "../../../src/utils/sqlHints"; - -// Mock dependencies -const mockForgeDriver = vi.fn(); -const mockInjectSqlHints = vi.fn(); -const mockPrintQueriesWithPlan = vi.fn(); -const mockHandleErrorsWithPlan = vi.fn(); - -vi.mock("../../../src/utils/forgeDriver", () => ({ - forgeDriver: (...args: any[]) => mockForgeDriver(...args), -})); - -vi.mock("../../../src/utils/sqlHints", () => ({ - injectSqlHints: (...args: any[]) => mockInjectSqlHints(...args), -})); - -vi.mock("../../../src/utils/sqlUtils", () => ({ - printQueriesWithPlan: (...args: any[]) => mockPrintQueriesWithPlan(...args), - handleErrorsWithPlan: (...args: any[]) => mockHandleErrorsWithPlan(...args), -})); - -describe("forgeDriverProxy", () => { - let mockForgeSqlOperation: ForgeSqlOperation; - let proxiedDriver: ReturnType; - const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - const consoleDebugSpy = vi.spyOn(console, "debug").mockImplementation(() => {}); - - // Track promises to ensure they're handled - const trackedPromises: Promise[] = []; - - beforeEach(() => { - vi.clearAllMocks(); - mockForgeSqlOperation = {} as ForgeSqlOperation; - mockInjectSqlHints.mockImplementation((query: string) => query); - mockForgeDriver.mockResolvedValue({ rows: [{ id: 1, name: "Test" }] }); - mockPrintQueriesWithPlan.mockResolvedValue(undefined); - mockHandleErrorsWithPlan.mockResolvedValue(undefined); - trackedPromises.length = 0; - }); - - afterEach(async () => { - consoleErrorSpy.mockClear(); - consoleDebugSpy.mockClear(); - // Wait for all tracked promises to complete - await Promise.allSettled(trackedPromises); - // Wait for any pending async operations to complete - await new Promise((resolve) => setTimeout(resolve, 100)); - }); - - describe("createForgeDriverProxy", () => { - it("should create a proxy function", () => { - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - expect(typeof proxiedDriver).toBe("function"); - }); - - it("should execute query successfully", async () => { - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - const result = await proxiedDriver("SELECT * FROM users", [], "all"); - - expect(result).toEqual({ rows: [{ id: 1, name: "Test" }] }); - expect(mockForgeDriver).toHaveBeenCalledWith("SELECT * FROM users", [], "all"); - }); - - it("should inject SQL hints when options provided", async () => { - const hints: SqlHints = { maxExecutionTime: 5000 }; - mockInjectSqlHints.mockReturnValue("SELECT /*+ MAX_EXECUTION_TIME(5000) */ * FROM users"); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation, hints); - await proxiedDriver("SELECT * FROM users", [], "all"); - - expect(mockInjectSqlHints).toHaveBeenCalledWith("SELECT * FROM users", hints); - expect(mockForgeDriver).toHaveBeenCalledWith( - "SELECT /*+ MAX_EXECUTION_TIME(5000) */ * FROM users", - [], - "all", - ); - }); - - it("should log SQL hints when logRawSqlQuery is true and query is modified", async () => { - const hints: SqlHints = { maxExecutionTime: 5000 }; - mockInjectSqlHints.mockReturnValue("SELECT /*+ MAX_EXECUTION_TIME(5000) */ * FROM users"); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation, hints, true); - await proxiedDriver("SELECT * FROM users", [], "all"); - - expect(consoleDebugSpy).toHaveBeenCalledWith( - "SQL Hints injected: SELECT /*+ MAX_EXECUTION_TIME(5000) */ * FROM users", - ); - }); - - it("should not log SQL hints when query is not modified", async () => { - const hints: SqlHints = { maxExecutionTime: 5000 }; - mockInjectSqlHints.mockReturnValue("SELECT * FROM users"); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation, hints, true); - await proxiedDriver("SELECT * FROM users", [], "all"); - - expect(consoleDebugSpy).not.toHaveBeenCalledWith( - expect.stringContaining("SQL Hints injected"), - ); - }); - - it("should not log SQL hints when logRawSqlQuery is false", async () => { - const hints: SqlHints = { maxExecutionTime: 5000 }; - mockInjectSqlHints.mockReturnValue("SELECT /*+ MAX_EXECUTION_TIME(5000) */ * FROM users"); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation, hints, false); - await proxiedDriver("SELECT * FROM users", [], "all"); - - expect(consoleDebugSpy).not.toHaveBeenCalledWith( - expect.stringContaining("SQL Hints injected"), - ); - }); - - it("should handle timeout errors and analyze query", async () => { - const timeoutError = { - code: "SQL_QUERY_TIMEOUT", - message: "Query timeout", - }; - mockForgeDriver.mockRejectedValueOnce(timeoutError); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - vi.useFakeTimers(); - - const promise = proxiedDriver("SELECT * FROM users", [], "all"); - // Track the promise to ensure it's handled - trackedPromises.push(promise.catch(() => {})); - - // Fast-forward time to skip the delay - await vi.advanceTimersByTimeAsync(200); - - try { - await promise; - expect.fail("Expected promise to reject"); - } catch (error) { - expect(error).toEqual(timeoutError); - } - - expect(consoleErrorSpy).toHaveBeenCalledWith(" TIMEOUT detected - Query exceeded time limit"); - expect(mockHandleErrorsWithPlan).toHaveBeenCalledWith( - mockForgeSqlOperation, - expect.any(Number), - "TIMEOUT", - ); - - vi.useRealTimers(); - // Wait for all async operations to complete - await new Promise((resolve) => setTimeout(resolve, 50)); - }); - - it("should handle out of memory errors and analyze query", async () => { - const outOfMemoryError = { - code: "OTHER_ERROR", - context: { - debug: { - errno: 8175, - }, - }, - message: "Out of memory", - }; - mockForgeDriver.mockRejectedValueOnce(outOfMemoryError); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - vi.useFakeTimers(); - - const promise = proxiedDriver("SELECT * FROM users", [], "all"); - // Track the promise to ensure it's handled - trackedPromises.push(promise.catch(() => {})); - - // Fast-forward time to skip the delay - await vi.advanceTimersByTimeAsync(200); - - try { - await promise; - expect.fail("Expected promise to reject"); - } catch (error) { - expect(error).toEqual(outOfMemoryError); - } - - expect(consoleErrorSpy).toHaveBeenCalledWith( - "OUT OF MEMORY detected - Query exceeded memory limit", - ); - expect(mockHandleErrorsWithPlan).toHaveBeenCalledWith( - mockForgeSqlOperation, - expect.any(Number), - "OOM", - ); - - vi.useRealTimers(); - // Wait for all async operations to complete - await new Promise((resolve) => setTimeout(resolve, 50)); - }); - - it("should log SQL error details when logRawSqlQuery is true", async () => { - const error = { - code: "SOME_ERROR", - message: "Some error", - }; - mockForgeDriver.mockRejectedValueOnce(error); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation, undefined, true); - - await expect(proxiedDriver("SELECT * FROM users", [], "all")).rejects.toEqual(error); - - expect(consoleDebugSpy).toHaveBeenCalledWith( - "SQL Error Details:", - JSON.stringify(error, null, 2), - ); - }); - - it("should not log SQL error details when logRawSqlQuery is false", async () => { - const error = { - code: "SOME_ERROR", - message: "Some error", - }; - mockForgeDriver.mockRejectedValueOnce(error); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation, undefined, false); - - await expect(proxiedDriver("SELECT * FROM users", [], "all")).rejects.toEqual(error); - - expect(consoleDebugSpy).not.toHaveBeenCalledWith( - expect.stringContaining("SQL Error Details"), - ); - }); - - it("should re-throw original error after handling", async () => { - const error = { - code: "SOME_ERROR", - message: "Some error", - }; - mockForgeDriver.mockRejectedValueOnce(error); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - - await expect(proxiedDriver("SELECT * FROM users", [], "all")).rejects.toEqual(error); - }); - - it("should handle execute method", async () => { - mockForgeDriver.mockResolvedValueOnce({ - rows: [], - affectedRows: 1, - insertId: 123, - }); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - const result = await proxiedDriver("UPDATE users SET name = ?", ["John"], "execute"); - - expect(result).toEqual({ - rows: [], - affectedRows: 1, - insertId: 123, - }); - expect(mockForgeDriver).toHaveBeenCalledWith( - "UPDATE users SET name = ?", - ["John"], - "execute", - ); - }); - - it("should not analyze query for non-timeout, non-memory errors", async () => { - const error = { - code: "OTHER_ERROR", - message: "Some other error", - }; - mockForgeDriver.mockRejectedValueOnce(error); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - - await expect(proxiedDriver("SELECT * FROM users", [], "all")).rejects.toEqual(error); - - expect(mockHandleErrorsWithPlan).not.toHaveBeenCalled(); - expect(consoleErrorSpy).not.toHaveBeenCalled(); - }); - - it("should calculate query duration correctly", async () => { - const timeoutError = { - code: "SQL_QUERY_TIMEOUT", - message: "Query timeout", - }; - mockForgeDriver.mockRejectedValueOnce(timeoutError); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - vi.useFakeTimers(); - - const startTime = Date.now(); - const promise = proxiedDriver("SELECT * FROM users", [], "all"); - // Track the promise to ensure it's handled - trackedPromises.push(promise.catch(() => {})); - - // Fast-forward time - await vi.advanceTimersByTimeAsync(200); - - try { - await promise; - expect.fail("Expected promise to reject"); - } catch (error) { - expect(error).toEqual(timeoutError); - } - - // Verify that handleErrorsWithPlan was called with a duration - expect(mockHandleErrorsWithPlan).toHaveBeenCalled(); - const callArgs = mockHandleErrorsWithPlan.mock.calls[0]; - expect(callArgs[1]).toBeGreaterThanOrEqual(0); - expect(callArgs[2]).toBe("TIMEOUT"); - - vi.useRealTimers(); - // Wait for all async operations to complete - await new Promise((resolve) => setTimeout(resolve, 50)); - }); - - it("should handle errors without context.debug", async () => { - const error = { - code: "OTHER_ERROR", - message: "Error without context", - }; - mockForgeDriver.mockRejectedValueOnce(error); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - - await expect(proxiedDriver("SELECT * FROM users", [], "all")).rejects.toEqual(error); - - expect(mockHandleErrorsWithPlan).not.toHaveBeenCalled(); - }); - - it("should handle errors with context but without debug", async () => { - const error = { - code: "OTHER_ERROR", - context: {}, - message: "Error with context but no debug", - }; - mockForgeDriver.mockRejectedValueOnce(error); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - - await expect(proxiedDriver("SELECT * FROM users", [], "all")).rejects.toEqual(error); - - expect(mockHandleErrorsWithPlan).not.toHaveBeenCalled(); - }); - - it("should handle errors with context.debug but wrong errno", async () => { - const error = { - code: "OTHER_ERROR", - context: { - debug: { - errno: 1234, // Not the OUT_OF_MEMORY_ERRNO - }, - }, - message: "Error with wrong errno", - }; - mockForgeDriver.mockRejectedValueOnce(error); - - proxiedDriver = createForgeDriverProxy(mockForgeSqlOperation); - - await expect(proxiedDriver("SELECT * FROM users", [], "all")).rejects.toEqual(error); - - expect(mockHandleErrorsWithPlan).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/__tests__/src/utils/metadataContextUtils.test.ts b/__tests__/src/utils/metadataContextUtils.test.ts deleted file mode 100644 index 88ddc40de..000000000 --- a/__tests__/src/utils/metadataContextUtils.test.ts +++ /dev/null @@ -1,841 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; -import { - saveMetaDataToContext, - getLastestMetadata, - metadataQueryContext, - MetadataQueryContext, - normalizeSqlForLoggingRegex, -} from "../../../src/utils/metadataContextUtils"; -import { ForgeSQLMetadata } from "../../../src/utils/forgeDriver"; -import { ForgeSqlOperation } from "../../../src/core/ForgeSQLQueryBuilder"; -import { ExplainAnalyzeRow } from "../../../src/core/SystemTables"; -import { printQueriesWithPlan } from "../../../src/utils/sqlUtils"; -import { Queue, PushResult } from "@forge/events"; - -// Mock dependencies -const mockWithTimeout = vi.fn(); -vi.mock("../../../src/utils/sqlUtils", () => ({ - printQueriesWithPlan: vi.fn(), - withTimeout: (...args: any[]) => mockWithTimeout(...args), -})); - -const mockQueuePush = vi.fn(); -vi.mock("@forge/events", () => ({ - Queue: vi.fn().mockImplementation(() => { - const pushFn = vi.fn().mockResolvedValue({ jobId: "test-id" }); - // Store reference to the push function - (globalThis as any).__lastQueuePush = pushFn; - return { - push: pushFn, - }; - }), - PushResult: {}, -})); - -const mockSetTimeout = vi.fn((callback: any) => { - callback(); - return 1 as any; -}); -vi.stubGlobal("setTimeout", mockSetTimeout); - -describe("metadataContextUtils", () => { - let mockForgeSQLORM: ForgeSqlOperation; - let mockAnalyze: { - explainAnalyzeRaw: ReturnType; - }; - let mockContext: MetadataQueryContext; - let consoleWarnSpy: ReturnType; - let consoleLogSpy: ReturnType; - - beforeEach(() => { - // Mock console methods - consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - consoleLogSpy = vi.spyOn(console, "log").mockImplementation(() => {}); - - // Mock ForgeSQLORM - mockAnalyze = { - explainAnalyzeRaw: vi.fn(), - }; - mockForgeSQLORM = { - analyze: vi.fn().mockReturnValue(mockAnalyze), - normalizationSQL: vi.fn((sql: string) => normalizeSqlForLoggingRegex(sql)), - } as unknown as ForgeSqlOperation; - - // Create mock context - mockContext = { - totalDbExecutionTime: 0, - totalResponseSize: 0, - beginTime: new Date(), - statistics: [], - printQueriesWithPlan: vi.fn(), - forgeSQLORM: mockForgeSQLORM, - }; - - // Mock metadataQueryContext.getStore - vi.spyOn(metadataQueryContext, "getStore").mockReturnValue(mockContext); - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe("getLastestMetadata", () => { - it("should return context when available", async () => { - const result = await getLastestMetadata(); - expect(result).toBe(mockContext); - }); - - it("should return undefined when no context is set", async () => { - vi.spyOn(metadataQueryContext, "getStore").mockReturnValue(undefined); - const result = await getLastestMetadata(); - expect(result).toBeUndefined(); - }); - }); - - describe("saveMetaDataToContext", () => { - const mockMetadata: ForgeSQLMetadata = { - dbExecutionTime: 100, - responseSize: 1024, - fields: [], - }; - - it("should return early when no context is available", async () => { - vi.spyOn(metadataQueryContext, "getStore").mockReturnValue(undefined); - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.statistics).toHaveLength(0); - }); - - it("should initialize statistics array if undefined", async () => { - mockContext.statistics = undefined as any; - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.statistics).toBeDefined(); - expect(Array.isArray(mockContext.statistics)).toBe(true); - }); - - it("should add query statistics to context", async () => { - await saveMetaDataToContext("SELECT * FROM users", ["param1"], mockMetadata); - expect(mockContext.statistics).toHaveLength(1); - expect(mockContext.statistics[0]).toEqual({ - query: "SELECT * FROM users", - params: ["param1"], - metadata: mockMetadata, - }); - }); - - it("should update aggregated metrics", async () => { - mockContext.totalDbExecutionTime = 50; - mockContext.totalResponseSize = 512; - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.totalDbExecutionTime).toBe(150); - expect(mockContext.totalResponseSize).toBe(1536); - }); - - it("should set default options when options are undefined", async () => { - mockContext.options = undefined; - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.options).toEqual({ - mode: "TopSlowest", - topQueries: 1, - summaryTableWindowTime: 15000, - showSlowestPlans: true, - normalizeQuery: true, - asyncQueueName: "", - }); - }); - - it("should merge partial options with defaults", async () => { - mockContext.options = { - mode: "SummaryTable", - topQueries: 3, - }; - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.options).toEqual({ - mode: "SummaryTable", - topQueries: 3, - summaryTableWindowTime: 15000, - showSlowestPlans: true, - normalizeQuery: true, - asyncQueueName: "", - }); - }); - - it("should set up printQueriesWithPlan function", async () => { - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.printQueriesWithPlan).toBeDefined(); - expect(typeof mockContext.printQueriesWithPlan).toBe("function"); - }); - - it("should not update metrics when metadata is null", async () => { - mockContext.totalDbExecutionTime = 50; - mockContext.totalResponseSize = 512; - await saveMetaDataToContext("SELECT 1", [], null as any); - expect(mockContext.totalDbExecutionTime).toBe(50); - expect(mockContext.totalResponseSize).toBe(512); - }); - }); - - describe("printQueriesWithPlan - TopSlowest mode", () => { - const mockMetadata1: ForgeSQLMetadata = { - dbExecutionTime: 200, - responseSize: 2048, - fields: [], - }; - const mockMetadata2: ForgeSQLMetadata = { - dbExecutionTime: 100, - responseSize: 1024, - fields: [], - }; - const mockMetadata3: ForgeSQLMetadata = { - dbExecutionTime: 300, - responseSize: 3072, - fields: [], - }; - - const mockExplainPlan: ExplainAnalyzeRow[] = [ - { - id: "1", - task: "root", - operatorInfo: "TableReader", - estRows: 1000, - actRows: 1000, - executionInfo: "time:100ms", - memory: "1MB", - disk: "0B", - accessObject: "table:users", - }, - ]; - - beforeEach(() => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue(mockExplainPlan); - }); - - it("should print top slowest query plan", async () => { - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata1); - await saveMetaDataToContext("SELECT * FROM orders", [], mockMetadata2); - await saveMetaDataToContext("SELECT * FROM products", [], mockMetadata3); - - await mockContext.printQueriesWithPlan(); - - // Should call explainAnalyzeRaw for the slowest query (300ms) - expect(mockForgeSQLORM.analyze).toHaveBeenCalled(); - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalledWith("SELECT * FROM products", []); - expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringContaining("SQL: SELECT * FROM products | Time: 300 ms"), - ); - }); - - it("should print top N slowest queries when topQueries > 1", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 2, - }; - - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata1); - await saveMetaDataToContext("SELECT * FROM orders", [], mockMetadata2); - await saveMetaDataToContext("SELECT * FROM products", [], mockMetadata3); - - await mockContext.printQueriesWithPlan(); - - // Should call explainAnalyzeRaw for top 2 slowest queries (300ms and 200ms) - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalledTimes(2); - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalledWith("SELECT * FROM products", []); - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalledWith("SELECT * FROM users", []); - expect(consoleWarnSpy).toHaveBeenCalledTimes(2); - }); - - it("should format execution plan correctly", async () => { - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata1); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("SQL: SELECT * FROM users | Time: 200 ms"); - expect(warnCall).toContain("Plan:"); - expect(warnCall).toContain("1 | task:root | TableReader"); - expect(warnCall).toContain("estRows:1000, actRows:1000"); - expect(warnCall).toContain("execution info:time:100ms"); - expect(warnCall).toContain("memory:1MB, disk:0B"); - expect(warnCall).toContain("access object:table:users"); - }); - - it("should handle empty execution plan", async () => { - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata1); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("No execution plan available"); - }); - - it("should handle execution plan with missing fields", async () => { - const partialPlan: ExplainAnalyzeRow[] = [ - { - id: "1", - operatorInfo: "TableReader", - }, - ]; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue(partialPlan); - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata1); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("1 | TableReader"); - }); - - it("should handle execution plan with missing id and operatorInfo", async () => { - const planWithoutIdAndOperator: ExplainAnalyzeRow[] = [ - { - task: "root", - estRows: 1000, - actRows: 1000, - }, - ]; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue(planWithoutIdAndOperator); - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata1); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("task:root"); - expect(warnCall).toContain("estRows:1000, actRows:1000"); - // Should not contain id or operatorInfo since they are missing - expect(warnCall).not.toContain("1 |"); - expect(warnCall).not.toContain("TableReader"); - }); - - it("should not show execution plans when showSlowestPlans is false", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - }; - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata1); - - await mockContext.printQueriesWithPlan(); - - // Should not call explainAnalyzeRaw - expect(mockAnalyze.explainAnalyzeRaw).not.toHaveBeenCalled(); - // Should only print SQL and time - expect(consoleWarnSpy).toHaveBeenCalledWith("SQL: SELECT * FROM users | Time: 200 ms"); - }); - - it("should show execution plans when showSlowestPlans is true (default)", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: true, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([ - { - id: "1", - operatorInfo: "TableReader", - }, - ]); - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata1); - - await mockContext.printQueriesWithPlan(); - - // Should call explainAnalyzeRaw - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalled(); - // Should print SQL, time, and plan - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("SQL: SELECT * FROM users | Time: 200 ms"); - expect(warnCall).toContain("Plan:"); - }); - }); - - describe("printQueriesWithPlan - SummaryTable mode", () => { - const mockMetadata: ForgeSQLMetadata = { - dbExecutionTime: 100, - responseSize: 1024, - fields: [], - }; - - beforeEach(() => { - vi.useFakeTimers(); - mockContext.beginTime = new Date("2023-01-01T00:00:00Z"); - vi.setSystemTime(new Date("2023-01-01T00:00:00Z")); - mockContext.options = { - mode: "SummaryTable", - summaryTableWindowTime: 15000, - }; - }); - - afterEach(() => { - vi.useRealTimers(); - }); - - it("should use summary tables when within time window", async () => { - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata); - - // Advance time by 5 seconds (within 15 second window) - vi.advanceTimersByTime(5000); - - const printPromise = mockContext.printQueriesWithPlan(); - - // Advance timers to trigger the setTimeout(200) inside printPlansUsingSummaryTables - vi.advanceTimersByTime(200); - - await printPromise; - - expect(printQueriesWithPlan).toHaveBeenCalledWith(mockForgeSQLORM, expect.any(Number)); - expect(mockAnalyze.explainAnalyzeRaw).not.toHaveBeenCalled(); - }); - - it("should fall back to top queries when time window expires", async () => { - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([ - { - id: "1", - operatorInfo: "TableReader", - }, - ]); - - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata); - - // Advance time by 20 seconds (beyond 15 second window) - vi.advanceTimersByTime(20000); - - await mockContext.printQueriesWithPlan(); - - expect(consoleWarnSpy).toHaveBeenCalledWith( - "Summary table window expired — showing query plans instead", - ); - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalled(); - }); - - it("should not use summary tables when mode is TopSlowest", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([ - { - id: "1", - operatorInfo: "TableReader", - }, - ]); - - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata); - - await mockContext.printQueriesWithPlan(); - - expect(printQueriesWithPlan).not.toHaveBeenCalled(); - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalled(); - }); - - it("should wait 200ms before calling printQueriesWithPlan", async () => { - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata); - - const printPromise = mockContext.printQueriesWithPlan(); - - // Should not be called immediately - expect(printQueriesWithPlan).not.toHaveBeenCalled(); - - // Advance by 200ms - vi.advanceTimersByTime(200); - - await printPromise; - - expect(printQueriesWithPlan).toHaveBeenCalled(); - }); - }); - - describe("options merging", () => { - const mockMetadata: ForgeSQLMetadata = { - dbExecutionTime: 100, - responseSize: 1024, - fields: [], - }; - - it("should use default mode when mode is undefined", async () => { - mockContext.options = { - topQueries: 3, - }; - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.options?.mode).toBe("TopSlowest"); - }); - - it("should use default topQueries when topQueries is undefined", async () => { - mockContext.options = { - mode: "TopSlowest", - }; - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.options?.topQueries).toBe(1); - }); - - it("should use default summaryTableWindowTime when undefined", async () => { - mockContext.options = { - mode: "SummaryTable", - }; - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.options?.summaryTableWindowTime).toBe(15000); - }); - - it("should use default showSlowestPlans when undefined", async () => { - mockContext.options = { - mode: "TopSlowest", - }; - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.options?.showSlowestPlans).toBe(true); - }); - - it("should preserve provided values", async () => { - mockContext.options = { - mode: "SummaryTable", - topQueries: 5, - summaryTableWindowTime: 20000, - showSlowestPlans: false, - }; - await saveMetaDataToContext("SELECT 1", [], mockMetadata); - expect(mockContext.options).toEqual({ - mode: "SummaryTable", - topQueries: 5, - summaryTableWindowTime: 20000, - showSlowestPlans: false, - normalizeQuery: true, - asyncQueueName: "", - }); - }); - }); - - describe("multiple queries accumulation", () => { - it("should accumulate multiple queries in statistics", async () => { - const metadata1: ForgeSQLMetadata = { - dbExecutionTime: 100, - responseSize: 1024, - fields: [], - }; - const metadata2: ForgeSQLMetadata = { - dbExecutionTime: 200, - responseSize: 2048, - fields: [], - }; - const metadata3: ForgeSQLMetadata = { - dbExecutionTime: 300, - responseSize: 3072, - fields: [], - }; - - await saveMetaDataToContext("SELECT * FROM users", [], metadata1); - await saveMetaDataToContext("SELECT * FROM orders", [], metadata2); - await saveMetaDataToContext("SELECT * FROM products", [], metadata3); - - expect(mockContext.statistics).toHaveLength(3); - expect(mockContext.totalDbExecutionTime).toBe(600); - expect(mockContext.totalResponseSize).toBe(6144); - }); - }); - - describe("SQL normalization for logging", () => { - const mockMetadata: ForgeSQLMetadata = { - dbExecutionTime: 100, - responseSize: 1024, - fields: [], - }; - - it("should normalize SQL with string literals", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - - await saveMetaDataToContext("SELECT * FROM users WHERE name = 'John'", [], mockMetadata); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("SELECT * FROM users WHERE name = ?"); - expect(warnCall).not.toContain("John"); - }); - - it("should normalize SQL with numeric literals", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - - await saveMetaDataToContext("SELECT sleep(4) FROM users WHERE id = 123", [], mockMetadata); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("SELECT sleep(?) FROM users WHERE id = ?"); - expect(warnCall).not.toContain("4"); - expect(warnCall).not.toContain("123"); - }); - - it("should normalize SQL with boolean literals", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - - await saveMetaDataToContext("SELECT * FROM users WHERE active = true", [], mockMetadata); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("SELECT * FROM users WHERE active = ?"); - expect(warnCall).not.toContain("true"); - }); - - it("should normalize SQL with NULL values", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - - await saveMetaDataToContext("SELECT * FROM users WHERE deleted_at IS NULL", [], mockMetadata); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("SELECT * FROM users WHERE deleted_at IS ?"); - }); - - it("should normalize SQL with multiple parameter types", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - - await saveMetaDataToContext( - "SELECT * FROM users WHERE name = 'John' AND age = 25 AND active = true AND deleted_at IS NULL", - [], - mockMetadata, - ); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain( - "SELECT * FROM users WHERE name = ? AND age = ? AND active = ? AND deleted_at IS ?", - ); - expect(warnCall).not.toContain("John"); - expect(warnCall).not.toContain("25"); - expect(warnCall).not.toContain("true"); - }); - - it("should normalize SQL with double-quoted strings", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - - await saveMetaDataToContext('SELECT * FROM users WHERE name = "John"', [], mockMetadata); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("SELECT * FROM users WHERE name = ?"); - expect(warnCall).not.toContain("John"); - }); - - it("should normalize SQL with decimal numbers", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - - await saveMetaDataToContext("SELECT * FROM products WHERE price = 19.99", [], mockMetadata); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("SELECT * FROM products WHERE price = ?"); - expect(warnCall).not.toContain("19.99"); - }); - - it("should fall back to regex normalization when parser fails", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - vi.mocked(mockForgeSQLORM.normalizationSQL).mockImplementationOnce(() => { - throw new Error("parse error"); - }); - - await saveMetaDataToContext( - "SELECT * FROM users WHERE name = 'John' AND invalid syntax", - [], - mockMetadata, - ); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - expect(warnCall).toContain("SELECT * FROM users WHERE name = ?"); - expect(warnCall).not.toContain("John"); - }); - - it("should not normalize SQL when normalizeQuery is false", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - showSlowestPlans: false, - normalizeQuery: false, - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - - const originalQuery = "SELECT * FROM users WHERE name = 'John' AND id = 123"; - await saveMetaDataToContext(originalQuery, [], mockMetadata); - - await mockContext.printQueriesWithPlan(); - - const warnCall = consoleWarnSpy.mock.calls[0][0] as string; - // Should contain original query with parameters - expect(warnCall).toContain(originalQuery); - expect(warnCall).toContain("John"); - expect(warnCall).toContain("123"); - // Should not contain normalized version - expect(warnCall).not.toContain("name = ?"); - }); - }); - - describe("async queue processing", () => { - const mockMetadata: ForgeSQLMetadata = { - dbExecutionTime: 100, - responseSize: 1024, - fields: [], - }; - - beforeEach(() => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - asyncQueueName: "testQueue", - }; - mockAnalyze.explainAnalyzeRaw.mockResolvedValue([]); - mockQueuePush.mockClear(); - mockWithTimeout.mockClear(); - vi.clearAllMocks(); - // Reset Queue mock - vi.mocked(Queue).mockClear(); - }); - - it("should queue event for async processing when asyncQueueName is set", async () => { - const mockJobId = "test-job-id-123"; - const mockPushResult: PushResult = { jobId: mockJobId } as PushResult; - - // Setup mocks before calling saveMetaDataToContext - mockWithTimeout.mockImplementation(async (promise) => { - return await promise; - }); - - // Setup the queue push mock to return the result - vi.mocked(Queue).mockImplementation(function () { - const pushFn = vi.fn().mockResolvedValue(mockPushResult); - return { - push: pushFn, - } as any; - }); - - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata); - await mockContext.printQueriesWithPlan(); - - // Verify Queue was instantiated - expect(vi.mocked(Queue)).toHaveBeenCalledWith({ key: "testQueue" }); - // Verify that async queue processing was attempted (withTimeout should be called) - expect(mockWithTimeout).toHaveBeenCalled(); - // Verify success message was logged - expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringContaining( - "[Performance Analysis] Query degradation event queued for async processing", - ), - ); - expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining(`Job ID: ${mockJobId}`)); - // Should not call printDegradationQueries directly when queue succeeds - expect(mockAnalyze.explainAnalyzeRaw).not.toHaveBeenCalled(); - }); - - it("should fall back to synchronous execution when queue push fails", async () => { - const mockError = new Error("Queue push failed"); - mockQueuePush.mockRejectedValue(mockError); - mockWithTimeout.mockImplementation(async (promise) => { - return await promise; - }); - - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata); - await mockContext.printQueriesWithPlan(); - - expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringContaining("Async printing failed — falling back to synchronous execution"), - expect.any(Error), - ); - // Should fall back to synchronous execution - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalled(); - }); - - it("should fall back to synchronous execution when withTimeout fails", async () => { - const mockError = new Error("Timeout exceeded"); - mockQueuePush.mockResolvedValue({ jobId: "test-id" }); - mockWithTimeout.mockRejectedValue(mockError); - - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata); - await mockContext.printQueriesWithPlan(); - - expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringContaining("Async printing failed — falling back to synchronous execution"), - expect.any(Error), - ); - // Should fall back to synchronous execution - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalled(); - }); - - it("should use synchronous execution when asyncQueueName is empty", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - asyncQueueName: "", - }; - - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata); - await mockContext.printQueriesWithPlan(); - - expect(vi.mocked(Queue)).not.toHaveBeenCalled(); - expect(mockQueuePush).not.toHaveBeenCalled(); - // Should use synchronous execution - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalled(); - }); - - it("should use synchronous execution when asyncQueueName is not set", async () => { - mockContext.options = { - mode: "TopSlowest", - topQueries: 1, - }; - - await saveMetaDataToContext("SELECT * FROM users", [], mockMetadata); - await mockContext.printQueriesWithPlan(); - - expect(vi.mocked(Queue)).not.toHaveBeenCalled(); - expect(mockQueuePush).not.toHaveBeenCalled(); - // Should use synchronous execution - expect(mockAnalyze.explainAnalyzeRaw).toHaveBeenCalled(); - }); - }); -}); diff --git a/__tests__/src/utils/sqlHints.test.ts b/__tests__/src/utils/sqlHints.test.ts deleted file mode 100644 index bab92f248..000000000 --- a/__tests__/src/utils/sqlHints.test.ts +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect } from "vitest"; -import { injectSqlHints, SqlHints } from "../../../src/utils/sqlHints"; - -describe("SQL Hints", () => { - describe("injectSqlHints", () => { - it("should return original query when no hints provided", () => { - const query = "SELECT * FROM users"; - const result = injectSqlHints(query); - expect(result).toBe(query); - }); - - it("should inject SELECT hints correctly", () => { - const query = "SELECT * FROM users"; - const hints: SqlHints = { - select: ["MEMORY_QUOTA(1 GB)", "MAX_EXECUTION_TIME(1000)"], - }; - const expected = "SELECT /*+ MEMORY_QUOTA(1 GB) MAX_EXECUTION_TIME(1000) */ * FROM users"; - expect(injectSqlHints(query, hints)).toBe(expected); - }); - - it("should inject INSERT hints correctly", () => { - const query = 'INSERT INTO users (name) VALUES ("John")'; - const hints: SqlHints = { - insert: ["IGNORE_DUP_KEY"], - }; - const expected = 'INSERT /*+ IGNORE_DUP_KEY */ INTO users (name) VALUES ("John")'; - expect(injectSqlHints(query, hints)).toBe(expected); - }); - - it("should inject UPDATE hints correctly", () => { - const query = 'UPDATE users SET name = "John"'; - const hints: SqlHints = { - update: ["MAX_EXECUTION_TIME(500)"], - }; - const expected = 'UPDATE /*+ MAX_EXECUTION_TIME(500) */ users SET name = "John"'; - expect(injectSqlHints(query, hints)).toBe(expected); - }); - - it("should inject DELETE hints correctly", () => { - const query = "DELETE FROM users"; - const hints: SqlHints = { - delete: ["MAX_EXECUTION_TIME(200)"], - }; - const expected = "DELETE /*+ MAX_EXECUTION_TIME(200) */ FROM users"; - expect(injectSqlHints(query, hints)).toBe(expected); - }); - - it("should handle case-insensitive query detection", () => { - const query = "select * from users"; - const hints: SqlHints = { - select: ["MEMORY_QUOTA(1 GB)"], - }; - const expected = "SELECT /*+ MEMORY_QUOTA(1 GB) */ * from users"; - expect(injectSqlHints(query, hints)).toBe(expected); - }); - - it("should handle multiple hints for different query types", () => { - const hints: SqlHints = { - select: ["MEMORY_QUOTA(1 GB)"], - insert: ["IGNORE_DUP_KEY"], - update: ["MAX_EXECUTION_TIME(500)"], - delete: ["MAX_EXECUTION_TIME(200)"], - }; - - const selectQuery = "SELECT * FROM users"; - const insertQuery = 'INSERT INTO users (name) VALUES ("John")'; - const updateQuery = 'UPDATE users SET name = "John"'; - const deleteQuery = "DELETE FROM users"; - - expect(injectSqlHints(selectQuery, hints)).toBe( - "SELECT /*+ MEMORY_QUOTA(1 GB) */ * FROM users", - ); - expect(injectSqlHints(insertQuery, hints)).toBe( - 'INSERT /*+ IGNORE_DUP_KEY */ INTO users (name) VALUES ("John")', - ); - expect(injectSqlHints(updateQuery, hints)).toBe( - 'UPDATE /*+ MAX_EXECUTION_TIME(500) */ users SET name = "John"', - ); - expect(injectSqlHints(deleteQuery, hints)).toBe( - "DELETE /*+ MAX_EXECUTION_TIME(200) */ FROM users", - ); - }); - - it("should handle empty hints array", () => { - const query = "SELECT * FROM users"; - const hints: SqlHints = { - select: [], - }; - expect(injectSqlHints(query, hints)).toBe(query); - }); - - it("should return original query for unsupported query type", () => { - const query = "CREATE TABLE users (id INT)"; - const hints: SqlHints = { - select: ["MEMORY_QUOTA(1 GB)"], - }; - expect(injectSqlHints(query, hints)).toBe(query); - }); - }); -}); diff --git a/__tests__/src/utils/sqlUtils.test.ts b/__tests__/src/utils/sqlUtils.test.ts deleted file mode 100644 index 7da08ddb8..000000000 --- a/__tests__/src/utils/sqlUtils.test.ts +++ /dev/null @@ -1,1070 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, expect, it, vi, beforeEach, afterEach, beforeAll, afterAll } from "vitest"; -import { - formatLimitOffset, - generateDropTableStatements, - parseDateTime, - formatDateTime, - withTimeout, - withTidbHint, - getPrimaryKeys, - getTableMetadata, - mapSelectFieldsWithAlias, - applyFromDriverTransform, - printQueriesWithPlan, - handleErrorsWithPlan, - slowQueryPerHours, - checkProductionEnvironment, -} from "../../../src"; -import { DateTime, Settings } from "luxon"; -import { int, mysqlTable, varchar, text, primaryKey } from "drizzle-orm/mysql-core"; -import { sql } from "drizzle-orm"; -import { ForgeSqlOperation } from "../../../src"; - -// Mock @forge/api -const mockGetAppContext = vi.fn(); -vi.mock("@forge/api", () => ({ - getAppContext: () => mockGetAppContext(), -})); - -beforeAll(() => { - Settings.defaultZone = "utc"; -}); - -afterAll(() => { - Settings.defaultZone = "system"; -}); - -// Test suite for transformValue function -describe("transformValue", () => { - // Test suite for parseDateTime function - describe("parseDateTime", () => { - it("should correctly parse a datetime string", () => { - const dateString = "2024-03-03T12:34:56.789"; - const format = "yyyy-LL-dd'T'HH:mm:ss.SSS"; - const parsedDate = parseDateTime(dateString, format); - expect(DateTime.fromJSDate(parsedDate).toFormat(format)).toBe(dateString); - }); - - it("should correctly parse a date string", () => { - const dateString = "2024-03-03"; - const format = "yyyy-LL-dd"; - const parsedDate = parseDateTime(dateString, format); - expect(DateTime.fromJSDate(parsedDate).toFormat(format)).toBe(dateString); - }); - - it("should handle Date object input", () => { - const date = new Date("2024-03-03T12:34:56.789Z"); - const format = "yyyy-LL-dd'T'HH:mm:ss.SSS"; - const parsedDate = parseDateTime(date, format); - expect(parsedDate).toBeInstanceOf(Date); - expect(parsedDate.getTime()).toBe(date.getTime()); - }); - - it("should fallback to SQL format parsing", () => { - const dateString = "2024-03-03 12:34:56"; - const format = "yyyy-LL-dd HH:mm:ss"; - const parsedDate = parseDateTime(dateString, format); - expect(parsedDate).toBeInstanceOf(Date); - expect(DateTime.fromJSDate(parsedDate).isValid).toBe(true); - }); - - it("should fallback to RFC2822 format parsing", () => { - const dateString = "Mon, 03 Mar 2024 12:34:56 GMT"; - const format = "yyyy-LL-dd"; - const parsedDate = parseDateTime(dateString, format); - expect(parsedDate).toBeInstanceOf(Date); - expect(DateTime.fromJSDate(parsedDate).isValid).toBe(true); - }); - - it("should handle invalid date with fallback", () => { - const dateString = "invalid-date"; - const format = "yyyy-LL-dd"; - const parsedDate = parseDateTime(dateString, format); - expect(parsedDate).toBeInstanceOf(Date); - }); - }); - - describe("formatLimitOffset", () => { - it("should return a valid SQL raw number for valid input", () => { - const result = formatLimitOffset(10); - expect(result).toBeDefined(); - expect(JSON.stringify(result)).toBe( - JSON.stringify({ - decoder: {}, - shouldInlineParams: false, - usedTables: [], - queryChunks: [{ value: ["10"] }], - }), - ); - }); - - it("should throw error for NaN input", () => { - expect(() => formatLimitOffset(NaN)).toThrow("limitOrOffset must be a valid number"); - }); - - it("should throw error for non-number input", () => { - // @ts-expect-error Testing invalid input type - expect(() => formatLimitOffset("10")).toThrow("limitOrOffset must be a valid number"); - }); - - it("should handle zero value", () => { - const result = formatLimitOffset(0); - expect(result).toBeDefined(); - expect(JSON.stringify(result)).toBe( - JSON.stringify({ - decoder: {}, - shouldInlineParams: false, - usedTables: [], - queryChunks: [{ value: ["0"] }], - }), - ); - }); - - it("should handle negative values", () => { - const result = formatLimitOffset(-5); - expect(result).toBeDefined(); - expect(JSON.stringify(result)).toBe( - JSON.stringify({ - decoder: {}, - shouldInlineParams: false, - usedTables: [], - queryChunks: [{ value: ["-5"] }], - }), - ); - }); - }); - - describe("generateDropTableStatements", () => { - it("should generate correct DROP TABLE statements for single table", () => { - const tables = ["users"]; - const expected = ["DROP TABLE IF EXISTS `users`;", "DROP SEQUENCE IF EXISTS `users`;"]; - expect(generateDropTableStatements(tables)).toEqual(expected); - }); - - it("should generate correct DROP TABLE statements for multiple tables", () => { - const tables = ["users", "orders", "products"]; - const expected = [ - "DROP TABLE IF EXISTS `users`;", - "DROP SEQUENCE IF EXISTS `users`;", - "DROP TABLE IF EXISTS `orders`;", - "DROP SEQUENCE IF EXISTS `orders`;", - "DROP TABLE IF EXISTS `products`;", - "DROP SEQUENCE IF EXISTS `products`;", - ]; - expect(generateDropTableStatements(tables)).toEqual(expected); - }); - - it("should handle table names with special characters", () => { - const tables = ["user-profiles", "order_items"]; - const expected = [ - "DROP TABLE IF EXISTS `user-profiles`;", - "DROP SEQUENCE IF EXISTS `user-profiles`;", - "DROP TABLE IF EXISTS `order_items`;", - "DROP SEQUENCE IF EXISTS `order_items`;", - ]; - expect(generateDropTableStatements(tables)).toEqual(expected); - }); - - it("should return empty array for empty input", () => { - expect(generateDropTableStatements([])).toEqual([]); - }); - - it("should generate only table drop statements when sequence option is false", () => { - const tables = ["users"]; - const expected = ["DROP TABLE IF EXISTS `users`;"]; - expect(generateDropTableStatements(tables, { sequence: false, table: true })).toEqual( - expected, - ); - }); - - it("should generate only sequence drop statements when table option is false", () => { - const tables = ["users"]; - const expected = ["DROP SEQUENCE IF EXISTS `users`;"]; - expect(generateDropTableStatements(tables, { sequence: true, table: false })).toEqual( - expected, - ); - }); - - it("should return empty array when both options are false", () => { - const tables = ["users"]; - expect(generateDropTableStatements(tables, { sequence: false, table: false })).toEqual([]); - }); - - it("should handle empty table name", () => { - const tables = [""]; - const expected = ["DROP TABLE IF EXISTS ``;", "DROP SEQUENCE IF EXISTS ``;"]; - expect(generateDropTableStatements(tables)).toEqual(expected); - }); - - it("should handle table names with backticks", () => { - const tables = ["`users`"]; - // The function wraps table names in backticks, so `users` becomes ``users`` - const expected = ["DROP TABLE IF EXISTS ``users``;", "DROP SEQUENCE IF EXISTS ``users``;"]; - expect(generateDropTableStatements(tables)).toEqual(expected); - }); - - it("should warn when both options are false", () => { - const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - const tables = ["users"]; - generateDropTableStatements(tables, { sequence: false, table: false }); - expect(consoleWarnSpy).toHaveBeenCalledWith( - 'No drop operations requested: both "table" and "sequence" options are false', - ); - consoleWarnSpy.mockRestore(); - }); - }); - - describe("formatDateTime", () => { - it("should format Date object correctly", () => { - const date = new Date("2024-03-03T12:34:56.789Z"); - const result = formatDateTime(date, "yyyy-LL-dd'T'HH:mm:ss.SSS", false); - expect(result).toBe("2024-03-03T12:34:56.789"); - }); - - it("should format ISO string correctly", () => { - const dateString = "2024-03-03T12:34:56.789Z"; - const result = formatDateTime(dateString, "yyyy-LL-dd'T'HH:mm:ss.SSS", false); - // Result may differ based on timezone, so just check it's a valid formatted date - expect(result).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}$/); - expect(result).toContain("2024-03-03"); - }); - - it("should format SQL string correctly", () => { - const dateString = "2024-03-03 12:34:56"; - const result = formatDateTime(dateString, "yyyy-LL-dd HH:mm:ss", false); - expect(result).toBe("2024-03-03 12:34:56"); - }); - - it("should format number timestamp correctly", () => { - const timestamp = new Date("2024-03-03T12:34:56.789").getTime(); - const result = formatDateTime(timestamp, "yyyy-LL-dd", false); - expect(result).toBe("2024-03-03"); - }); - - it("should validate timestamp range for timestamps", () => { - const minDate = new Date("1970-01-01T00:00:01.000Z"); - const result = formatDateTime(minDate, "yyyy-LL-dd", true); - expect(result).toBe("1970-01-01"); - }); - - it("should throw error for timestamp before 1970-01-01 00:00:01", () => { - const date = new Date("1970-01-01T00:00:00.000Z"); - expect(() => formatDateTime(date, "yyyy-LL-dd", true)).toThrow( - "Atlassian Forge does not support zero or negative timestamps", - ); - }); - - it("should throw error for timestamp after 2038-01-19 03:14:07.999", () => { - const date = new Date("2038-01-19T03:14:08.000Z"); - expect(() => formatDateTime(date, "yyyy-LL-dd", true)).toThrow( - "Atlassian Forge does not support timestamps beyond 2038-01-19", - ); - }); - - it("should throw error for invalid date string", () => { - expect(() => formatDateTime("invalid-date", "yyyy-LL-dd", false)).toThrow("Invalid Date"); - }); - - it("should throw error for unsupported type", () => { - // @ts-expect-error Testing invalid input type - expect(() => formatDateTime(null, "yyyy-LL-dd", false)).toThrow("Unsupported type"); - }); - - it("should handle ISO string format", () => { - // ISO format is supported by parseStringToDateTime - const dateString = "2024-03-03T12:34:56.789Z"; - const result = formatDateTime(dateString, "yyyy-LL-dd", false); - expect(result).toBe("2024-03-03"); - }); - - it("should handle SQL string format", () => { - // SQL format is supported by parseStringToDateTime - const dateString = "2024-03-03 12:34:56"; - const result = formatDateTime(dateString, "yyyy-LL-dd", false); - expect(result).toBe("2024-03-03"); - }); - - it("should handle number string as timestamp", () => { - const timestamp = new Date("2024-03-03T12:34:56.789").getTime(); - const result = formatDateTime(String(timestamp), "yyyy-LL-dd", false); - expect(result).toBe("2024-03-03"); - }); - - it("should validate timestamp at minimum boundary", () => { - const minDate = new Date("1970-01-01T00:00:01.000Z"); - const result = formatDateTime(minDate, "yyyy-LL-dd", true); - expect(result).toBe("1970-01-01"); - }); - - it("should validate timestamp at maximum boundary", () => { - // Maximum date is 2038-01-19 03:14:07.000 UTC (2147483647 * 1000 milliseconds) - // Using a date slightly before the maximum to avoid boundary issues - const maxDate = new Date(2147483647 * 1000 - 1000); // 1 second before maximum - const result = formatDateTime(maxDate, "yyyy-LL-dd", true); - expect(result).toBe("2038-01-19"); - }); - }); - - describe("withTimeout", () => { - it("should resolve promise before timeout", async () => { - const promise = Promise.resolve("success"); - const result = await withTimeout(promise, "Test timeout", 1000); - expect(result).toBe("success"); - }); - - it("should reject promise on timeout", async () => { - const promise = new Promise(() => { - // Never resolves - will timeout - }); - - const resultPromise = withTimeout(promise, "Test timeout", 50); - - await expect(resultPromise).rejects.toThrow("Test timeout"); - }, 200); - - it("should handle promise rejection", async () => { - const promise = Promise.reject(new Error("Test error")); - const resultPromise = withTimeout(promise, "Test timeout", 1000); - - await expect(resultPromise).rejects.toThrow("Test error"); - }); - - it("should clear timeout when promise resolves", async () => { - const clearTimeoutSpy = vi.spyOn(global, "clearTimeout"); - const promise = Promise.resolve("success"); - const resultPromise = withTimeout(promise, "Test timeout", 1000); - - await resultPromise; - - // Give a small delay to ensure clearTimeout is called - await new Promise((resolve) => setTimeout(resolve, 10)); - - expect(clearTimeoutSpy).toHaveBeenCalled(); - clearTimeoutSpy.mockRestore(); - }); - - it("should clear timeout when promise rejects", async () => { - const clearTimeoutSpy = vi.spyOn(global, "clearTimeout"); - const promise = Promise.reject(new Error("Test error")); - const resultPromise = withTimeout(promise, "Test timeout", 1000); - - await expect(resultPromise).rejects.toThrow("Test error"); - - // Give a small delay to ensure clearTimeout is called - await new Promise((resolve) => setTimeout(resolve, 10)); - - expect(clearTimeoutSpy).toHaveBeenCalled(); - clearTimeoutSpy.mockRestore(); - }); - - it("should handle very short timeout", async () => { - const promise = new Promise(() => { - // Never resolves - }); - - const resultPromise = withTimeout(promise, "Very short timeout", 10); - - await expect(resultPromise).rejects.toThrow("Very short timeout"); - }, 200); - - it("should handle zero timeout", async () => { - const promise = new Promise(() => { - // Never resolves - }); - - const resultPromise = withTimeout(promise, "Zero timeout", 0); - - await expect(resultPromise).rejects.toThrow("Zero timeout"); - }, 200); - }); - - describe("withTidbHint", () => { - it("should wrap column with TiDB session alias hint", () => { - const testTable = mysqlTable("test", { - id: int("id").primaryKey(), - }); - - const result = withTidbHint(testTable.id); - - expect(result).toBeDefined(); - // Check that result is a SQL object with queryChunks - expect(result).toHaveProperty("queryChunks"); - // Check that the result has the expected SQL structure - // The function wraps the column with a TiDB hint, so we verify the structure exists - expect(result).toHaveProperty("decoder"); - expect(result).toHaveProperty("queryChunks"); - }); - - it("should return SQL wrapper object", () => { - const testTable = mysqlTable("test", { - id: int("id").primaryKey(), - }); - - const result = withTidbHint(testTable.id); - - expect(result).toBeDefined(); - // The result should be a SQL wrapper object - expect(result).toHaveProperty("queryChunks"); - expect(result).toHaveProperty("decoder"); - }); - }); - - describe("getTableMetadata", () => { - it("should extract table metadata with primary key", () => { - const testTable = mysqlTable("users", { - id: int("id").primaryKey(), - name: varchar("name", { length: 255 }), - }); - - const metadata = getTableMetadata(testTable); - - expect(metadata).toBeDefined(); - expect(metadata.tableName).toBe("users"); - expect(metadata.columns).toBeDefined(); - expect(metadata.columns.id).toBeDefined(); - expect(metadata.columns.name).toBeDefined(); - expect(metadata.indexes).toBeInstanceOf(Array); - expect(metadata.checks).toBeInstanceOf(Array); - expect(metadata.foreignKeys).toBeInstanceOf(Array); - expect(metadata.primaryKeys).toBeInstanceOf(Array); - expect(metadata.uniqueConstraints).toBeInstanceOf(Array); - expect(metadata.extras).toBeInstanceOf(Array); - }); - - it("should extract table metadata without primary key", () => { - const testTable = mysqlTable("posts", { - id: int("id"), - title: varchar("title", { length: 255 }), - }); - - const metadata = getTableMetadata(testTable); - - expect(metadata).toBeDefined(); - expect(metadata.tableName).toBe("posts"); - expect(metadata.columns).toBeDefined(); - expect(metadata.columns.id).toBeDefined(); - expect(metadata.columns.title).toBeDefined(); - }); - - it("should handle table with multiple columns", () => { - const testTable = mysqlTable("products", { - id: int("id").primaryKey(), - name: varchar("name", { length: 255 }), - description: text("description"), - price: int("price"), - }); - - const metadata = getTableMetadata(testTable); - - expect(metadata.columns).toHaveProperty("id"); - expect(metadata.columns).toHaveProperty("name"); - expect(metadata.columns).toHaveProperty("description"); - expect(metadata.columns).toHaveProperty("price"); - }); - }); - - describe("getPrimaryKeys", () => { - it("should return primary key from column", () => { - const testTable = mysqlTable("users", { - id: int("id").primaryKey(), - name: varchar("name", { length: 255 }), - }); - - const primaryKeys = getPrimaryKeys(testTable); - - expect(primaryKeys).toBeDefined(); - expect(primaryKeys.length).toBe(1); - expect(primaryKeys[0][0]).toBe("id"); - expect(primaryKeys[0][1]).toBeDefined(); - }); - - it("should return empty array when no primary key", () => { - const testTable = mysqlTable("posts", { - id: int("id"), - title: varchar("title", { length: 255 }), - }); - - const primaryKeys = getPrimaryKeys(testTable); - - expect(primaryKeys).toBeDefined(); - expect(primaryKeys).toEqual([]); - }); - - it("should handle table with composite primary key using primaryKey builder", () => { - const testTable = mysqlTable( - "order_items", - { - orderId: int("order_id"), - itemId: int("item_id"), - }, - (table) => ({ - pk: primaryKey({ columns: [table.orderId, table.itemId] }), - }), - ); - - const primaryKeys = getPrimaryKeys(testTable); - - // Note: This test may return empty array if primary keys are only in builders - // The actual behavior depends on how drizzle-orm stores primary keys - expect(primaryKeys).toBeDefined(); - expect(Array.isArray(primaryKeys)).toBe(true); - }); - }); - - describe("mapSelectFieldsWithAlias", () => { - it("should map table fields to aliases", () => { - const testTable = mysqlTable("users", { - id: int("id").primaryKey(), - name: varchar("name", { length: 255 }), - }); - - const fields = { - id: testTable.id, - name: testTable.name, - }; - - const result = mapSelectFieldsWithAlias(fields); - - expect(result).toBeDefined(); - expect(result.selections).toBeDefined(); - expect(result.aliasMap).toBeDefined(); - expect(Object.keys(result.aliasMap).length).toBeGreaterThan(0); - }); - - it("should map nested fields to aliases", () => { - const usersTable = mysqlTable("users", { - id: int("id").primaryKey(), - name: varchar("name", { length: 255 }), - }); - - const ordersTable = mysqlTable("orders", { - id: int("id").primaryKey(), - userId: int("user_id"), - }); - - const fields = { - user: { - id: usersTable.id, - name: usersTable.name, - }, - order: { - id: ordersTable.id, - }, - }; - - const result = mapSelectFieldsWithAlias(fields); - - expect(result).toBeDefined(); - expect(result.selections).toBeDefined(); - expect(result.selections.user).toBeDefined(); - expect(result.selections.order).toBeDefined(); - expect(result.aliasMap).toBeDefined(); - }); - - it("should throw error for empty fields", () => { - expect(() => mapSelectFieldsWithAlias({} as any)).not.toThrow(); - // @ts-expect-error Testing invalid input - expect(() => mapSelectFieldsWithAlias(null)).toThrow("fields is empty"); - // @ts-expect-error Testing invalid input - expect(() => mapSelectFieldsWithAlias(undefined)).toThrow("fields is empty"); - }); - - it("should handle SQL wrapper fields", () => { - const testTable = mysqlTable("users", { - id: int("id").primaryKey(), - name: varchar("name", { length: 255 }), - }); - - const fields = { - id: testTable.id, - count: sql`COUNT(*)`, - }; - - const result = mapSelectFieldsWithAlias(fields); - - expect(result).toBeDefined(); - expect(result.selections).toBeDefined(); - expect(result.selections.count).toBeDefined(); - }); - }); - - describe("applyFromDriverTransform", () => { - it("should transform rows without custom mapFrom", () => { - const testTable = mysqlTable("users", { - id: int("id").primaryKey(), - name: varchar("name", { length: 255 }), - }); - - const fields = { - id: testTable.id, - name: testTable.name, - }; - - const { selections, aliasMap } = mapSelectFieldsWithAlias(fields); - const rows = [ - { id: 1, name: "John" }, - { id: 2, name: "Jane" }, - ]; - - const result = applyFromDriverTransform(rows, selections, aliasMap); - - expect(result).toBeDefined(); - expect(result.length).toBe(2); - expect(result[0]).toEqual({ id: 1, name: "John" }); - expect(result[1]).toEqual({ id: 2, name: "Jane" }); - }); - - it("should transform rows with null branches", () => { - const usersTable = mysqlTable("users", { - id: int("id").primaryKey(), - name: varchar("name", { length: 255 }), - }); - - const ordersTable = mysqlTable("orders", { - id: int("id").primaryKey(), - userId: int("user_id"), - }); - - const fields = { - user: { - id: usersTable.id, - name: usersTable.name, - }, - order: { - id: ordersTable.id, - }, - }; - - const { selections, aliasMap } = mapSelectFieldsWithAlias(fields); - // Note: transformObject expects objects, not null. Null values are handled by processNullBranches - // after transformation. So we pass empty objects that will be converted to null. - const rows = [ - { - user: { id: 1, name: "John" }, - order: {}, // Empty object will be converted to null by processNullBranches - }, - { - user: { id: 2, name: "Jane" }, - order: { id: 10 }, - }, - ]; - - const result = applyFromDriverTransform(rows, selections, aliasMap); - - expect(result).toBeDefined(); - expect(result.length).toBe(2); - expect(result[0].user).toBeDefined(); - expect(result[0].order).toBeNull(); // Empty object becomes null - expect(result[1].user).toBeDefined(); - expect(result[1].order).toBeDefined(); - }); - - it("should handle empty rows array", () => { - const testTable = mysqlTable("users", { - id: int("id").primaryKey(), - }); - - const fields = { id: testTable.id }; - const { selections, aliasMap } = mapSelectFieldsWithAlias(fields); - - const result = applyFromDriverTransform([], selections, aliasMap); - - expect(result).toBeDefined(); - expect(result).toEqual([]); - }); - - it("should handle rows with all null nested objects", () => { - const usersTable = mysqlTable("users", { - id: int("id").primaryKey(), - }); - - const ordersTable = mysqlTable("orders", { - id: int("id").primaryKey(), - }); - - const fields = { - user: { id: usersTable.id }, - order: { id: ordersTable.id }, - }; - - const { selections, aliasMap } = mapSelectFieldsWithAlias(fields); - // Empty object will be converted to null by processNullBranches - const rows = [ - { - user: { id: 1 }, - order: {}, // Empty object becomes null - }, - ]; - - const result = applyFromDriverTransform(rows, selections, aliasMap); - - expect(result).toBeDefined(); - expect(result.length).toBe(1); - expect(result[0].user).toBeDefined(); - expect(result[0].order).toBeNull(); - }); - }); - - describe("printQueriesWithPlan", () => { - let mockForgeSQLORM: ForgeSqlOperation; - let consoleWarnSpy: ReturnType; - let consoleDebugSpy: ReturnType; - - beforeEach(() => { - consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - consoleDebugSpy = vi.spyOn(console, "debug").mockImplementation(() => {}); - - const mockQueryBuilder = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnThis(), - }; - - mockForgeSQLORM = { - getDrizzleQueryBuilder: vi.fn().mockReturnValue(mockQueryBuilder), - } as unknown as ForgeSqlOperation; - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - consoleDebugSpy.mockRestore(); - }); - - it("should handle successful query execution", async () => { - const mockResults = [ - { - digestText: "SELECT * FROM users", - avgLatency: "1000000", // 1ms in nanoseconds - avgMem: "2000000", // 2MB in bytes - execCount: "5", - plan: "Index Scan", - stmtType: "Select", - }, - ]; - - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnValue(Promise.resolve(mockResults)), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - await printQueriesWithPlan(mockForgeSQLORM, 1000, 100); - - expect(mockForgeSQLORM.getDrizzleQueryBuilder).toHaveBeenCalled(); - expect(consoleWarnSpy).toHaveBeenCalled(); - }); - - it("should handle query errors gracefully", async () => { - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockRejectedValue(new Error("Query failed")), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - await printQueriesWithPlan(mockForgeSQLORM, 1000, 100); - - expect(consoleDebugSpy).toHaveBeenCalled(); - }); - - it("should use default timeout when not provided", async () => { - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnValue(Promise.resolve([])), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - await printQueriesWithPlan(mockForgeSQLORM, 1000); - - expect(mockForgeSQLORM.getDrizzleQueryBuilder).toHaveBeenCalled(); - }); - }); - - describe("handleErrorsWithPlan", () => { - let mockForgeSQLORM: ForgeSqlOperation; - let consoleWarnSpy: ReturnType; - let consoleDebugSpy: ReturnType; - - beforeEach(() => { - consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - consoleDebugSpy = vi.spyOn(console, "debug").mockImplementation(() => {}); - - mockForgeSQLORM = { - getDrizzleQueryBuilder: vi.fn(), - } as unknown as ForgeSqlOperation; - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - consoleDebugSpy.mockRestore(); - }); - - it("should handle OOM errors", async () => { - const mockResults = [ - { - digestText: "SELECT * FROM large_table", - avgLatency: "5000000", - avgMem: "100000000", // 100MB - execCount: "1", - plan: "Full Table Scan", - stmtType: "Select", - }, - ]; - - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnThis(), - orderBy: vi.fn().mockReturnThis(), - limit: vi.fn().mockReturnValue(Promise.resolve(mockResults)), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - await handleErrorsWithPlan(mockForgeSQLORM, 1000, "OOM"); - - expect(mockForgeSQLORM.getDrizzleQueryBuilder).toHaveBeenCalled(); - expect(mockQuery.orderBy).toHaveBeenCalled(); - expect(mockQuery.limit).toHaveBeenCalled(); - }); - - it("should handle TIMEOUT errors", async () => { - const mockResults = [ - { - digestText: "SELECT * FROM slow_table", - avgLatency: "10000000000", // 10 seconds - avgMem: "5000000", - execCount: "1", - plan: "Nested Loop", - stmtType: "Select", - }, - ]; - - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnThis(), - orderBy: vi.fn().mockReturnThis(), - limit: vi.fn().mockReturnValue(Promise.resolve(mockResults)), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - await handleErrorsWithPlan(mockForgeSQLORM, 1000, "TIMEOUT"); - - expect(mockForgeSQLORM.getDrizzleQueryBuilder).toHaveBeenCalled(); - expect(mockQuery.orderBy).toHaveBeenCalled(); - }); - - it("should handle query errors gracefully", async () => { - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnThis(), - orderBy: vi.fn().mockReturnThis(), - limit: vi.fn().mockRejectedValue(new Error("Query failed")), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - await handleErrorsWithPlan(mockForgeSQLORM, 1000, "OOM"); - - expect(consoleDebugSpy).toHaveBeenCalled(); - }); - }); - - describe("slowQueryPerHours", () => { - let mockForgeSQLORM: ForgeSqlOperation; - let consoleWarnSpy: ReturnType; - let consoleDebugSpy: ReturnType; - - beforeEach(() => { - consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - consoleDebugSpy = vi.spyOn(console, "debug").mockImplementation(() => {}); - - mockForgeSQLORM = { - getDrizzleQueryBuilder: vi.fn(), - } as unknown as ForgeSqlOperation; - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - consoleDebugSpy.mockRestore(); - }); - - it("should return slow query results", async () => { - const mockResults = [ - { - query: "SELECT * FROM users WHERE id = ?", - queryTime: "5000", - memMax: "10000000", // 10MB - plan: "Index Scan", - }, - ]; - - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnValue(Promise.resolve(mockResults)), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - const result = await slowQueryPerHours(mockForgeSQLORM, 1); - - expect(result).toBeDefined(); - expect(Array.isArray(result)).toBe(true); - expect(result.length).toBeGreaterThan(0); - expect(consoleWarnSpy).toHaveBeenCalled(); - }); - - it("should handle null memMax values", async () => { - const mockResults = [ - { - query: "SELECT * FROM users", - queryTime: "3000", - memMax: null, - plan: "Table Scan", - }, - ]; - - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnValue(Promise.resolve(mockResults)), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - const result = await slowQueryPerHours(mockForgeSQLORM, 1); - - expect(result).toBeDefined(); - expect(result.length).toBeGreaterThan(0); - }); - - it("should handle query errors and return error message", async () => { - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockRejectedValue(new Error("Query failed")), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - const result = await slowQueryPerHours(mockForgeSQLORM, 1); - - expect(result).toBeDefined(); - expect(Array.isArray(result)).toBe(true); - expect(result[0]).toContain("Error occurred"); - expect(consoleDebugSpy).toHaveBeenCalled(); - }); - - it("should use default timeout when not provided", async () => { - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnValue(Promise.resolve([])), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - await slowQueryPerHours(mockForgeSQLORM, 1); - - expect(mockForgeSQLORM.getDrizzleQueryBuilder).toHaveBeenCalled(); - }); - - it("should use custom timeout when provided", async () => { - const mockQuery = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnValue(Promise.resolve([])), - }; - - (mockForgeSQLORM.getDrizzleQueryBuilder as any).mockReturnValue(mockQuery); - - await slowQueryPerHours(mockForgeSQLORM, 1, 5000); - - expect(mockForgeSQLORM.getDrizzleQueryBuilder).toHaveBeenCalled(); - }); - }); - - describe("checkProductionEnvironment", () => { - let consoleLogSpy: ReturnType; - - beforeEach(() => { - consoleLogSpy = vi.spyOn(console, "log").mockImplementation(() => {}); - vi.clearAllMocks(); - }); - - afterEach(() => { - consoleLogSpy.mockRestore(); - vi.clearAllMocks(); - }); - - it("should return error response when in production environment", () => { - mockGetAppContext.mockReturnValue({ environmentType: "PRODUCTION" }); - - const result = checkProductionEnvironment("testFunction"); - - expect(result).toBeDefined(); - expect(result?.statusCode).toBe(500); - expect(result?.body).toBe("testFunction is disabled in production environment"); - expect(consoleLogSpy).toHaveBeenCalledWith( - "testFunction is disabled in production environment", - ); - }); - - it("should return null when not in production environment", () => { - mockGetAppContext.mockReturnValue({ environmentType: "DEVELOPMENT" }); - - const result = checkProductionEnvironment("testFunction"); - - expect(result).toBeNull(); - expect(consoleLogSpy).toHaveBeenCalledWith("testFunction triggered in DEVELOPMENT"); - }); - - it("should return null when environment type is STAGING", () => { - mockGetAppContext.mockReturnValue({ environmentType: "STAGING" }); - - const result = checkProductionEnvironment("testFunction"); - - expect(result).toBeNull(); - expect(consoleLogSpy).toHaveBeenCalledWith("testFunction triggered in STAGING"); - }); - - it("should handle undefined app context", () => { - mockGetAppContext.mockReturnValue(undefined); - - const result = checkProductionEnvironment("testFunction"); - - expect(result).toBeNull(); - expect(consoleLogSpy).toHaveBeenCalledWith("testFunction triggered in undefined"); - }); - - it("should handle null app context", () => { - mockGetAppContext.mockReturnValue(null); - - const result = checkProductionEnvironment("testFunction"); - - expect(result).toBeNull(); - expect(consoleLogSpy).toHaveBeenCalledWith("testFunction triggered in undefined"); - }); - - it("should handle app context without environmentType", () => { - mockGetAppContext.mockReturnValue({}); - - const result = checkProductionEnvironment("testFunction"); - - expect(result).toBeNull(); - expect(consoleLogSpy).toHaveBeenCalledWith("testFunction triggered in undefined"); - }); - }); -}); diff --git a/__tests__/src/webtriggers/applyMigrationsWebTrigger.test.ts b/__tests__/src/webtriggers/applyMigrationsWebTrigger.test.ts deleted file mode 100644 index d1e37c04b..000000000 --- a/__tests__/src/webtriggers/applyMigrationsWebTrigger.test.ts +++ /dev/null @@ -1,420 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeEach, vi } from "vitest"; -import { applySchemaMigrations } from "../../../src/webtriggers/applyMigrationsWebTrigger"; -import { MigrationRunner } from "@forge/sql/out/migration"; - -// Mock dependencies - defined before vi.mock -const mockProvision = vi.fn(); -const mockEnqueue = vi.fn().mockReturnThis(); -const mockRun = vi.fn(); -const mockList = vi.fn(); - -const consoleDebugSpy = vi.spyOn(console, "debug").mockImplementation(() => {}); -const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - -vi.mock("@forge/sql", () => ({ - sql: { - _provision: (...args: any[]) => mockProvision(...args), - }, - migrationRunner: { - enqueue: (...args: any[]) => mockEnqueue(...args), - run: (...args: any[]) => mockRun(...args), - list: (...args: any[]) => mockList(...args), - }, -})); - -describe("applySchemaMigrations", () => { - let mockMigrationRunner: MigrationRunner; - - beforeEach(() => { - vi.clearAllMocks(); - mockProvision.mockResolvedValue(undefined); - mockRun.mockResolvedValue(["migration1", "migration2"]); - mockList.mockResolvedValue([ - { - id: 1, - name: "test_migration", - migratedAt: new Date("2023-01-01T00:00:00Z"), - }, - { - id: 2, - name: "another_migration", - migratedAt: new Date("2023-01-02T00:00:00Z"), - }, - ]); - // Create a mock migration runner that uses the mocked functions - mockMigrationRunner = { - enqueue: mockEnqueue, - run: mockRun, - list: mockList, - } as any; - }); - - it("should successfully apply migrations with history", async () => { - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(mockMigration).toHaveBeenCalled(); - expect(mockProvision).toHaveBeenCalled(); - expect(mockRun).toHaveBeenCalled(); - expect(mockList).toHaveBeenCalled(); - expect(consoleDebugSpy).toHaveBeenCalledWith("Provisioning the database"); - expect(consoleDebugSpy).toHaveBeenCalledWith("Running schema migrations"); - expect(consoleDebugSpy).toHaveBeenCalledWith("Migrations applied:", [ - "migration1", - "migration2", - ]); - expect(consoleDebugSpy).toHaveBeenCalledWith( - "Migrations history:\nid, name, migrated_at\n", - expect.stringContaining("1, test_migration"), - ); - expect(result.statusCode).toBe(200); - expect(result.statusText).toBe("OK"); - expect(result.body).toBe("Migrations successfully executed"); - expect(result.headers).toEqual({ "Content-Type": ["application/json"] }); - }); - - it("should handle empty migration history", async () => { - mockList.mockResolvedValue([]); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleDebugSpy).toHaveBeenCalledWith( - "Migrations history:\nid, name, migrated_at\n", - "No migrations found", - ); - expect(result.statusCode).toBe(200); - expect(result.body).toBe("Migrations successfully executed"); - }); - - it("should handle null migration history", async () => { - mockList.mockResolvedValue(null); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleDebugSpy).toHaveBeenCalledWith( - "Migrations history:\nid, name, migrated_at\n", - "No migrations found", - ); - expect(result.statusCode).toBe(200); - }); - - it("should handle non-array migration history", async () => { - mockList.mockResolvedValue({} as any); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleDebugSpy).toHaveBeenCalledWith( - "Migrations history:\nid, name, migrated_at\n", - "No migrations found", - ); - expect(result.statusCode).toBe(200); - }); - - it("should sort migrations by migratedAt", async () => { - mockList.mockResolvedValue([ - { - id: 2, - name: "later_migration", - migratedAt: new Date("2023-01-02T00:00:00Z"), - }, - { - id: 1, - name: "earlier_migration", - migratedAt: new Date("2023-01-01T00:00:00Z"), - }, - ]); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleDebugSpy).toHaveBeenCalledWith( - "Migrations history:\nid, name, migrated_at\n", - expect.stringContaining("1, earlier_migration"), - ); - expect(consoleDebugSpy).toHaveBeenCalledWith( - "Migrations history:\nid, name, migrated_at\n", - expect.stringContaining("2, later_migration"), - ); - expect(result.statusCode).toBe(200); - }); - - it("should handle single migration in history", async () => { - mockList.mockResolvedValue([ - { - id: 1, - name: "single_migration", - migratedAt: new Date("2023-01-01T00:00:00Z"), - }, - ]); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleDebugSpy).toHaveBeenCalledWith( - "Migrations history:\nid, name, migrated_at\n", - expect.stringContaining("1, single_migration"), - ); - expect(result.statusCode).toBe(200); - }); - - it("should handle invalid migration parameter (null)", async () => { - const result = await applySchemaMigrations(null as any); - - expect(mockProvision).not.toHaveBeenCalled(); - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "migration is not a function", - ); - expect(result.statusCode).toBe(500); - expect(result.statusText).toBe("Internal Server Error"); - expect(result.body).toBe("migration is not a function"); - }); - - it("should handle invalid migration parameter (undefined)", async () => { - const result = await applySchemaMigrations(undefined as any); - - expect(mockProvision).not.toHaveBeenCalled(); - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "migration is not a function", - ); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("migration is not a function"); - }); - - it("should handle invalid migration parameter (string)", async () => { - const result = await applySchemaMigrations("not a function" as any); - - expect(mockProvision).not.toHaveBeenCalled(); - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "migration is not a function", - ); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("migration is not a function"); - }); - - it("should handle error during provisioning", async () => { - const error = new Error("Provisioning failed"); - mockProvision.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Error during migration:", "Provisioning failed"); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Provisioning failed"); - }); - - it("should handle error during migration execution", async () => { - const error = new Error("Migration execution failed"); - const mockMigration = vi.fn().mockRejectedValue(error); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "Migration execution failed", - ); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Migration execution failed"); - }); - - it("should handle error during run", async () => { - const error = new Error("Run failed"); - mockRun.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Error during migration:", "Run failed"); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Run failed"); - }); - - it("should handle error with cause.context.debug.sqlMessage", async () => { - const error = new Error("Base error"); - (error as any).cause = { - context: { - debug: { - sqlMessage: "SQL error message", - }, - }, - }; - mockProvision.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Error during migration:", "SQL error message"); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("SQL error message"); - }); - - it("should handle error with cause.context.debug.message", async () => { - const error = new Error("Base error"); - (error as any).cause = { - context: { - debug: { - message: "Context debug message", - }, - }, - }; - mockProvision.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "Context debug message", - ); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Context debug message"); - }); - - it("should handle error with debug.context.sqlMessage", async () => { - const error = new Error("Base error"); - (error as any).debug = { - context: { - sqlMessage: "Debug context SQL message", - }, - }; - mockProvision.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "Debug context SQL message", - ); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Debug context SQL message"); - }); - - it("should handle error with debug.context.message", async () => { - const error = new Error("Base error"); - (error as any).debug = { - context: { - message: "Debug context message", - }, - }; - mockProvision.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "Debug context message", - ); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Debug context message"); - }); - - it("should handle error with error.message", async () => { - const error = new Error("Standard error message"); - mockProvision.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "Standard error message", - ); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Standard error message"); - }); - - it("should handle error without message", async () => { - const error = {}; - mockProvision.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "Unknown error occurred", - ); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Unknown error during migration"); - }); - - it("should prioritize cause.context.debug.sqlMessage", async () => { - const error = new Error("Standard message"); - (error as any).cause = { - context: { - debug: { - sqlMessage: "SQL message", - message: "Generic message", - }, - }, - }; - (error as any).debug = { - context: { - sqlMessage: "Other SQL message", - }, - }; - mockProvision.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Error during migration:", "SQL message"); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("SQL message"); - }); - - it("should handle error during list", async () => { - const error = new Error("List failed"); - mockList.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Error during migration:", "List failed"); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("List failed"); - }); - - it("should handle non-Error object", async () => { - const error = { someProperty: "value" }; - mockProvision.mockRejectedValue(error); - - const mockMigration = vi.fn().mockResolvedValue(mockMigrationRunner); - - const result = await applySchemaMigrations(mockMigration); - - expect(consoleErrorSpy).toHaveBeenCalledWith( - "Error during migration:", - "Unknown error occurred", - ); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Unknown error during migration"); - }); -}); diff --git a/__tests__/src/webtriggers/dropTablesMigrationWebTrigger.test.ts b/__tests__/src/webtriggers/dropTablesMigrationWebTrigger.test.ts deleted file mode 100644 index 3734800b1..000000000 --- a/__tests__/src/webtriggers/dropTablesMigrationWebTrigger.test.ts +++ /dev/null @@ -1,219 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeEach, vi } from "vitest"; -import { dropTableSchemaMigrations } from "../../../src/webtriggers/dropTablesMigrationWebTrigger"; - -// Mock dependencies -const mockGetTables = vi.fn(); -const mockGenerateStatements = vi.fn(); -const mockExecuteDDL = vi.fn(); -const mockGetHttpResponse = vi.fn(); -const consoleDebugSpy = vi.spyOn(console, "debug").mockImplementation(() => {}); -const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - -vi.mock("../../../src/core/SystemTables", () => ({ - getTables: (...args: any[]) => mockGetTables(...args), -})); - -vi.mock("../../../src/utils/sqlUtils", () => ({ - generateDropTableStatements: (...args: any[]) => mockGenerateStatements(...args), - checkProductionEnvironment: vi.fn().mockResolvedValue(null), -})); - -vi.mock("@forge/sql", () => ({ - sql: { - executeDDL: (...args: any[]) => mockExecuteDDL(...args), - }, -})); - -vi.mock("../../../src/webtriggers/index", () => ({ - getHttpResponse: (...args: any[]) => mockGetHttpResponse(...args), -})); - -describe("dropTableSchemaMigrations", () => { - beforeEach(() => { - vi.clearAllMocks(); - mockGetTables.mockResolvedValue(["users", "orders"]); - mockGenerateStatements.mockReturnValue([ - "DROP TABLE IF EXISTS users", - "DROP TABLE IF EXISTS orders", - ]); - mockExecuteDDL.mockResolvedValue(undefined); - mockGetHttpResponse.mockImplementation((statusCode: number, body: string) => ({ - statusCode, - body, - headers: { "Content-Type": ["application/json"] }, - statusText: statusCode === 200 ? "Ok" : "Bad Request", - })); - }); - - it("should successfully drop tables", async () => { - const result = await dropTableSchemaMigrations(); - - expect(mockGetTables).toHaveBeenCalled(); - expect(mockGenerateStatements).toHaveBeenCalledWith(["users", "orders"], { - sequence: false, - table: true, - }); - expect(mockExecuteDDL).toHaveBeenCalledTimes(2); - expect(mockExecuteDDL).toHaveBeenNthCalledWith(1, "DROP TABLE IF EXISTS users"); - expect(mockExecuteDDL).toHaveBeenNthCalledWith(2, "DROP TABLE IF EXISTS orders"); - expect(consoleDebugSpy).toHaveBeenCalledTimes(2); - expect(consoleDebugSpy).toHaveBeenNthCalledWith(1, "execute DDL: DROP TABLE IF EXISTS users"); - expect(consoleDebugSpy).toHaveBeenNthCalledWith(2, "execute DDL: DROP TABLE IF EXISTS orders"); - expect(mockGetHttpResponse).toHaveBeenCalledWith( - 200, - "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.", - ); - expect(result.statusCode).toBe(200); - expect(result.body).toBe( - "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.", - ); - }); - - it("should handle empty tables list", async () => { - mockGetTables.mockResolvedValue([]); - mockGenerateStatements.mockReturnValue([]); - - const result = await dropTableSchemaMigrations(); - - expect(mockGetTables).toHaveBeenCalled(); - expect(mockGenerateStatements).toHaveBeenCalledWith([], { sequence: false, table: true }); - expect(mockExecuteDDL).not.toHaveBeenCalled(); - expect(consoleDebugSpy).not.toHaveBeenCalled(); - expect(mockGetHttpResponse).toHaveBeenCalledWith( - 200, - "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.", - ); - expect(result.statusCode).toBe(200); - }); - - it("should handle single table", async () => { - mockGetTables.mockResolvedValue(["users"]); - mockGenerateStatements.mockReturnValue(["DROP TABLE IF EXISTS users"]); - - const result = await dropTableSchemaMigrations(); - - expect(mockExecuteDDL).toHaveBeenCalledTimes(1); - expect(mockExecuteDDL).toHaveBeenCalledWith("DROP TABLE IF EXISTS users"); - expect(consoleDebugSpy).toHaveBeenCalledTimes(1); - expect(result.statusCode).toBe(200); - }); - - it("should handle error with debug.sqlMessage", async () => { - const error = { - debug: { - sqlMessage: "Table does not exist", - }, - }; - mockGetTables.mockRejectedValue(error); - - const result = await dropTableSchemaMigrations(); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Table does not exist"); - expect(mockGetHttpResponse).toHaveBeenCalledWith(500, "Table does not exist"); - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Table does not exist"); - }); - - it("should handle error with debug.message", async () => { - const error = { - debug: { - message: "Database connection failed", - }, - }; - mockGetTables.mockRejectedValue(error); - - const result = await dropTableSchemaMigrations(); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Database connection failed"); - expect(mockGetHttpResponse).toHaveBeenCalledWith(500, "Database connection failed"); - expect(result.statusCode).toBe(500); - }); - - it("should handle error with error.message", async () => { - const error = new Error("Generic error message"); - mockGetTables.mockRejectedValue(error); - - const result = await dropTableSchemaMigrations(); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Generic error message"); - expect(mockGetHttpResponse).toHaveBeenCalledWith(500, "Generic error message"); - expect(result.statusCode).toBe(500); - }); - - it("should handle error without message", async () => { - const error = {}; - mockGetTables.mockRejectedValue(error); - - const result = await dropTableSchemaMigrations(); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Unknown error occurred"); - expect(mockGetHttpResponse).toHaveBeenCalledWith(500, "Unknown error occurred"); - expect(result.statusCode).toBe(500); - }); - - it("should handle error during executeDDL", async () => { - const error = { - debug: { - sqlMessage: "Cannot drop table: foreign key constraint", - }, - }; - mockExecuteDDL.mockRejectedValueOnce(error); - - const result = await dropTableSchemaMigrations(); - - expect(mockExecuteDDL).toHaveBeenCalledTimes(1); - expect(consoleErrorSpy).toHaveBeenCalledWith("Cannot drop table: foreign key constraint"); - expect(mockGetHttpResponse).toHaveBeenCalledWith( - 500, - "Cannot drop table: foreign key constraint", - ); - expect(result.statusCode).toBe(500); - }); - - it("should handle error during generateStatements", async () => { - const error = new Error("Failed to generate statements"); - mockGenerateStatements.mockImplementation(() => { - throw error; - }); - - const result = await dropTableSchemaMigrations(); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Failed to generate statements"); - expect(mockGetHttpResponse).toHaveBeenCalledWith(500, "Failed to generate statements"); - expect(result.statusCode).toBe(500); - }); - - it("should prioritize debug.sqlMessage over debug.message", async () => { - const error = { - debug: { - sqlMessage: "SQL error message", - message: "Generic message", - }, - }; - mockGetTables.mockRejectedValue(error); - - const result = await dropTableSchemaMigrations(); - - expect(consoleErrorSpy).toHaveBeenCalledWith("SQL error message"); - expect(mockGetHttpResponse).toHaveBeenCalledWith(500, "SQL error message"); - expect(result.statusCode).toBe(500); - }); - - it("should handle multiple statements execution", async () => { - mockGetTables.mockResolvedValue(["table1", "table2", "table3"]); - mockGenerateStatements.mockReturnValue([ - "DROP TABLE IF EXISTS table1", - "DROP TABLE IF EXISTS table2", - "DROP TABLE IF EXISTS table3", - ]); - - const result = await dropTableSchemaMigrations(); - - expect(mockExecuteDDL).toHaveBeenCalledTimes(3); - expect(consoleDebugSpy).toHaveBeenCalledTimes(3); - expect(result.statusCode).toBe(200); - }); -}); diff --git a/__tests__/src/webtriggers/topSlowestStatementLastHourTrigger.test.ts b/__tests__/src/webtriggers/topSlowestStatementLastHourTrigger.test.ts deleted file mode 100644 index 7d7544edf..000000000 --- a/__tests__/src/webtriggers/topSlowestStatementLastHourTrigger.test.ts +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, beforeEach, vi } from "vitest"; -import { topSlowestStatementLastHourTrigger } from "../../../src/webtriggers/topSlowestStatementLastHourTrigger"; -import { ForgeSqlOperation } from "../../../src/core/ForgeSQLQueryBuilder"; -import { TriggerResponse } from "../../../src/webtriggers/index"; - -// Mock dependencies -const mockSlowQuerySchedulerTrigger = vi.fn(); - -vi.mock("../../../src/webtriggers/index", async () => { - const actual = await vi.importActual("../../../src/webtriggers/index"); - return { - ...actual, - slowQuerySchedulerTrigger: (...args: any[]) => mockSlowQuerySchedulerTrigger(...args), - }; -}); - -describe("topSlowestStatementLastHourTrigger", () => { - let mockOrm: ForgeSqlOperation; - - beforeEach(() => { - vi.clearAllMocks(); - mockOrm = {} as ForgeSqlOperation; - mockSlowQuerySchedulerTrigger.mockResolvedValue({ - statusCode: 200, - body: "Success", - headers: { "Content-Type": ["application/json"] }, - statusText: "Ok", - }); - }); - - it("should call slowQuerySchedulerTrigger with default options when no options provided", async () => { - const result = await topSlowestStatementLastHourTrigger(mockOrm); - - expect(mockSlowQuerySchedulerTrigger).toHaveBeenCalledTimes(1); - expect(mockSlowQuerySchedulerTrigger).toHaveBeenCalledWith(mockOrm, { - timeout: 3000, - hours: 1, - }); - expect(result.statusCode).toBe(200); - expect(result.body).toBe("Success"); - }); - - it("should call slowQuerySchedulerTrigger with custom hours when provided", async () => { - const result = await topSlowestStatementLastHourTrigger(mockOrm, { hours: 6 }); - - expect(mockSlowQuerySchedulerTrigger).toHaveBeenCalledWith(mockOrm, { - timeout: 3000, - hours: 6, - }); - expect(result.statusCode).toBe(200); - }); - - it("should call slowQuerySchedulerTrigger with default hours when options provided but hours is undefined", async () => { - const result = await topSlowestStatementLastHourTrigger(mockOrm, { - warnThresholdMs: 500, - }); - - expect(mockSlowQuerySchedulerTrigger).toHaveBeenCalledWith(mockOrm, { - timeout: 3000, - hours: 1, - }); - expect(result.statusCode).toBe(200); - }); - - it("should call slowQuerySchedulerTrigger with hours set to null converted to default", async () => { - const result = await topSlowestStatementLastHourTrigger(mockOrm, { hours: null as any }); - - expect(mockSlowQuerySchedulerTrigger).toHaveBeenCalledWith(mockOrm, { - timeout: 3000, - hours: 1, - }); - expect(result.statusCode).toBe(200); - }); - - it("should call slowQuerySchedulerTrigger with hours set to 0", async () => { - const result = await topSlowestStatementLastHourTrigger(mockOrm, { hours: 0 }); - - expect(mockSlowQuerySchedulerTrigger).toHaveBeenCalledWith(mockOrm, { - timeout: 3000, - hours: 0, - }); - expect(result.statusCode).toBe(200); - }); - - it("should call slowQuerySchedulerTrigger with hours set to 24", async () => { - const result = await topSlowestStatementLastHourTrigger(mockOrm, { hours: 24 }); - - expect(mockSlowQuerySchedulerTrigger).toHaveBeenCalledWith(mockOrm, { - timeout: 3000, - hours: 24, - }); - expect(result.statusCode).toBe(200); - }); - - it("should ignore other options and only pass hours", async () => { - const result = await topSlowestStatementLastHourTrigger(mockOrm, { - hours: 2, - warnThresholdMs: 500, - memoryThresholdBytes: 1024, - showPlan: true, - operationType: "DDL", - topN: 5, - tables: "CLUSTER_SUMMARY_AND_HISTORY", - }); - - expect(mockSlowQuerySchedulerTrigger).toHaveBeenCalledWith(mockOrm, { - timeout: 3000, - hours: 2, - }); - expect(result.statusCode).toBe(200); - }); - - it("should return error response when slowQuerySchedulerTrigger fails", async () => { - const errorResponse: TriggerResponse = { - statusCode: 500, - body: "Error occurred", - headers: { "Content-Type": ["application/json"] }, - statusText: "Internal Server Error", - }; - mockSlowQuerySchedulerTrigger.mockResolvedValue(errorResponse); - - const result = await topSlowestStatementLastHourTrigger(mockOrm); - - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Error occurred"); - expect(result.statusText).toBe("Internal Server Error"); - }); - - it("should propagate the response from slowQuerySchedulerTrigger", async () => { - const customResponse: TriggerResponse = { - statusCode: 200, - body: "Custom response body", - headers: { "Content-Type": ["application/json"], "X-Custom": ["value"] }, - statusText: "Custom Status", - }; - mockSlowQuerySchedulerTrigger.mockResolvedValue(customResponse); - - const result = await topSlowestStatementLastHourTrigger(mockOrm); - - expect(result).toEqual(customResponse); - expect(result.statusCode).toBe(200); - expect(result.body).toBe("Custom response body"); - expect(result.headers).toEqual({ - "Content-Type": ["application/json"], - "X-Custom": ["value"], - }); - expect(result.statusText).toBe("Custom Status"); - }); - - it("should handle empty options object", async () => { - const result = await topSlowestStatementLastHourTrigger(mockOrm, {}); - - expect(mockSlowQuerySchedulerTrigger).toHaveBeenCalledWith(mockOrm, { - timeout: 3000, - hours: 1, - }); - expect(result.statusCode).toBe(200); - }); -}); diff --git a/__tests__/src/webtriggers/webtriggers.test.ts b/__tests__/src/webtriggers/webtriggers.test.ts deleted file mode 100644 index 9aa79d5a2..000000000 --- a/__tests__/src/webtriggers/webtriggers.test.ts +++ /dev/null @@ -1,701 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { describe, it, expect, vi, beforeEach } from "vitest"; -import { - fetchSchemaWebTrigger, - dropSchemaMigrations, - applySchemaMigrations, - dropTableSchemaMigrations, - slowQuerySchedulerTrigger, -} from "../../../src/webtriggers"; -import { getTables } from "../../../src/core/SystemTables"; -import { generateDropTableStatements, slowQueryPerHours } from "../../../src/utils/sqlUtils"; -import { sql } from "@forge/sql"; -import { MigrationRunner } from "@forge/sql/out/migration"; -import { getTableName } from "drizzle-orm/table"; - -vi.useFakeTimers(); -vi.setSystemTime(new Date("2023-04-12 00:00:01")); - -interface MockMigrationRunner extends MigrationRunner { - enqueue: ReturnType; - run: ReturnType; - list: ReturnType; -} - -// Mock sql -vi.mock("@forge/sql", () => { - const mockMigrationRunner = { - enqueue: vi.fn().mockReturnThis(), - run: vi.fn().mockResolvedValue(["migration1"]), - list: vi.fn().mockResolvedValue([{ id: 1, name: "test_migration", migratedAt: new Date() }]), - } as MockMigrationRunner; - - return { - sql: { - prepare: vi.fn((query: string) => { - let procedureMock = vi - .fn() - .mockResolvedValue({ rows: [{ id: 1, data: "t", name: "Test" }] }); - if ( - query === - "select `test_data_entity`.`id` as `ID1`, `test_entity`.`id` as ID2, `test_data_entity`.`data`, `test_entity`.`name` from `test_data_entity` inner join `test_entity` on `test_data_entity`.`id` = `test_entity`.`id`" - ) { - procedureMock = vi - .fn() - .mockResolvedValue({ rows: [{ ID1: 1, ID2: 2, data: "t", name: "Test" }] }); - } - const executeMock = procedureMock; - return { - query: query || "MOCK_QUERY", - _params: [], - remoteSqlApi: "", - params: [], - bindParams: vi.fn(), - execute: executeMock, - }; - }), - executeRaw: vi.fn(), - _provision: vi.fn().mockResolvedValue(undefined), - executeDDL: vi.fn().mockResolvedValue({ rows: [] }), - }, - migrationRunner: mockMigrationRunner, - }; -}); - -// Mock drizzle-orm/table -vi.mock("drizzle-orm/table", () => ({ - getTableName: vi.fn((table: any) => table?._?.name || table?.name || "unknown"), -})); - -// Mock SystemTables -const mockForgeSystemTables: any[] = []; -vi.mock("../../../src/core/SystemTables", () => ({ - getTables: vi.fn().mockResolvedValue([]), - get forgeSystemTables() { - return mockForgeSystemTables; - }, - clusterStatementsSummary: { - digest: "digest", - stmtType: "stmtType", - schemaName: "schemaName", - execCount: "execCount", - avgLatency: "avgLatency", - maxLatency: "maxLatency", - minLatency: "minLatency", - avgProcessTime: "avgProcessTime", - avgWaitTime: "avgWaitTime", - avgBackoffTime: "avgBackoffTime", - avgTotalKeys: "avgTotalKeys", - firstSeen: "firstSeen", - lastSeen: "lastSeen", - planInCache: "planInCache", - planCacheHits: "planCacheHits", - digestText: "digestText", - plan: "plan", - summaryEndTime: "summaryEndTime", - }, - clusterStatementsSummaryHistory: { - digest: "digest", - stmtType: "stmtType", - schemaName: "schemaName", - execCount: "execCount", - avgLatency: "avgLatency", - maxLatency: "maxLatency", - minLatency: "minLatency", - avgProcessTime: "avgProcessTime", - avgWaitTime: "avgWaitTime", - avgBackoffTime: "avgBackoffTime", - avgTotalKeys: "avgTotalKeys", - firstSeen: "firstSeen", - lastSeen: "lastSeen", - planInCache: "planInCache", - planCacheHits: "planCacheHits", - digestText: "digestText", - plan: "plan", - summaryEndTime: "summaryEndTime", - }, -})); - -// Mock sqlUtils -vi.mock("../../../src/utils/sqlUtils", () => ({ - generateDropTableStatements: vi.fn().mockReturnValue([]), - formatLimitOffset: vi.fn().mockReturnValue(1), - slowQueryPerHours: vi - .fn() - .mockResolvedValue([ - "Found SlowQuery SQL: SELECT * FROM users | Memory: 2.50 MB | Time: 150.00 ms\n Plan:IndexScan(users)", - ]), - checkProductionEnvironment: vi.fn().mockResolvedValue(null), -})); - -// Mock cacheUtils -vi.mock("../../../src/utils/cacheUtils", () => ({ - clearExpiredCache: vi.fn().mockResolvedValue(undefined), -})); - -// Mock ForgeSQLORM -vi.mock("../../../src/core/ForgeSQLORM", () => { - const mockQueryBuilder = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnThis(), - orderBy: vi.fn().mockReturnThis(), - limit: vi.fn().mockReturnThis(), - groupBy: vi.fn().mockReturnThis(), - getSelectedFields: vi.fn().mockReturnValue({}), - addSetOperators: vi.fn().mockReturnThis(), - }; - - return { - default: vi.fn().mockImplementation(() => ({ - getDrizzleQueryBuilder: vi.fn().mockReturnValue(mockQueryBuilder), - })), - }; -}); - -describe("WebTriggers", () => { - let mockMigrationRunner: MockMigrationRunner; - - beforeEach(() => { - // Reset mocks - vi.clearAllMocks(); - mockMigrationRunner = (vi.mocked(sql) as any).migrationRunner; - // Reset mockForgeSystemTables - mockForgeSystemTables.length = 0; - // Reset getTableName mock - vi.mocked(getTableName).mockImplementation( - (table: any) => table?._?.name || table?.name || "unknown", - ); - }); - - describe("fetchSchemaWebTrigger", () => { - it("should return SQL statements for recreating database structure", async () => { - // Mock getTables to return some table names - (getTables as any).mockResolvedValue(["table1", "table2"]); - - // Mock executeDDL to return create table statements - vi.mocked(sql.executeDDL).mockImplementation(() => - Promise.resolve({ - rows: [ - { "Create Table": "CREATE TABLE table1 (...)", Table: "table1" }, - { "Create Table": "CREATE TABLE table2 (...)", Table: "table2" }, - ], - }), - ); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(200); - expect(result.body).toContain("CREATE TABLE IF NOT EXISTS table1"); - expect(result.body).toContain("CREATE TABLE IF NOT EXISTS table2"); - expect(result.body).toContain("SET foreign_key_checks = 0"); - expect(result.body).toContain("SET foreign_key_checks = 1"); - }); - - it("should filter out system tables", async () => { - // Mock getTables to return table names including a system table - (getTables as any).mockResolvedValue(["table1", "__migrations", "table2"]); - - // Mock forgeSystemTables to include __migrations - const mockSystemTable = { _: { name: "__migrations" } }; - mockForgeSystemTables.push(mockSystemTable); - - // Mock getTableName to return the table name - vi.mocked(getTableName).mockImplementation((table: any) => { - if (table === mockSystemTable || table?._?.name === "__migrations") { - return "__migrations"; - } - return table?._?.name || table?.name || "unknown"; - }); - - // Mock executeDDL to return create table statements - vi.mocked(sql.executeDDL).mockImplementation((query: string) => { - if (query.includes("table1")) { - return Promise.resolve({ - rows: [{ "Create Table": "CREATE TABLE table1 (...)", Table: "table1" }], - }); - } - if (query.includes("__migrations")) { - return Promise.resolve({ - rows: [{ "Create Table": "CREATE TABLE __migrations (...)", Table: "__migrations" }], - }); - } - if (query.includes("table2")) { - return Promise.resolve({ - rows: [{ "Create Table": "CREATE TABLE table2 (...)", Table: "table2" }], - }); - } - return Promise.resolve({ rows: [] }); - }); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(200); - expect(result.body).toContain("CREATE TABLE IF NOT EXISTS table1"); - expect(result.body).toContain("CREATE TABLE IF NOT EXISTS table2"); - expect(result.body).not.toContain("__migrations"); - }); - - it("should filter out rows with empty Create Table", async () => { - (getTables as any).mockResolvedValue(["table1", "table2"]); - - vi.mocked(sql.executeDDL).mockImplementation(() => - Promise.resolve({ - rows: [ - { "Create Table": "CREATE TABLE table1 (...)", Table: "table1" }, - { "Create Table": "", Table: "table2" }, - { "Create Table": null, Table: "table3" }, - ], - }), - ); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(200); - expect(result.body).toContain("CREATE TABLE IF NOT EXISTS table1"); - expect(result.body).not.toContain("table2"); - expect(result.body).not.toContain("table3"); - }); - - it("should format CREATE TABLE statements correctly (remove quotes, add IF NOT EXISTS)", async () => { - (getTables as any).mockResolvedValue(["table1"]); - - vi.mocked(sql.executeDDL).mockImplementation(() => - Promise.resolve({ - rows: [ - { - "Create Table": 'CREATE TABLE "table1" (`id` int)', - Table: "table1", - }, - ], - }), - ); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(200); - expect(result.body).toContain("CREATE TABLE IF NOT EXISTS table1"); - expect(result.body).not.toContain('"'); - // Note: formatCreateTableStatement only removes double quotes, not backticks - // Backticks are valid MySQL syntax for identifiers - }); - - it("should handle empty table list", async () => { - (getTables as any).mockResolvedValue([]); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(200); - expect(result.body).toContain("SET foreign_key_checks = 0"); - expect(result.body).toContain("SET foreign_key_checks = 1"); - // Should only contain the foreign key check statements - const statements = result.body.split(";\n"); - expect(statements.length).toBe(2); - }); - - it("should handle case when all tables are system tables", async () => { - const mockSystemTable = { _: { name: "__migrations" } }; - mockForgeSystemTables.push(mockSystemTable); - - vi.mocked(getTableName).mockImplementation((table: any) => { - if (table === mockSystemTable || table?._?.name === "__migrations") { - return "__migrations"; - } - return table?._?.name || table?.name || "unknown"; - }); - - (getTables as any).mockResolvedValue(["__migrations"]); - - vi.mocked(sql.executeDDL).mockImplementation(() => - Promise.resolve({ - rows: [{ "Create Table": "CREATE TABLE __migrations (...)", Table: "__migrations" }], - }), - ); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(200); - expect(result.body).not.toContain("__migrations"); - expect(result.body).toContain("SET foreign_key_checks = 0"); - expect(result.body).toContain("SET foreign_key_checks = 1"); - }); - - it("should handle errors with debug.sqlMessage", async () => { - const error: any = new Error("Database error"); - error.debug = { sqlMessage: "SQL syntax error" }; - (getTables as any).mockRejectedValue(error); - - const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(500); - expect(result.body).toBe("SQL syntax error"); - expect(consoleErrorSpy).toHaveBeenCalledWith("SQL syntax error"); - - consoleErrorSpy.mockRestore(); - }); - - it("should handle errors with debug.message", async () => { - const error: any = new Error("Database error"); - error.debug = { message: "Connection failed" }; - (getTables as any).mockRejectedValue(error); - - const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Connection failed"); - expect(consoleErrorSpy).toHaveBeenCalledWith("Connection failed"); - - consoleErrorSpy.mockRestore(); - }); - - it("should handle errors with only error.message", async () => { - (getTables as any).mockRejectedValue(new Error("Failed to get tables")); - - const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(500); - expect(result.body).toContain("Failed to get tables"); - expect(consoleErrorSpy).toHaveBeenCalledWith("Failed to get tables"); - - consoleErrorSpy.mockRestore(); - }); - - it("should handle errors with unknown error format", async () => { - const error = { unknown: "property" }; - (getTables as any).mockRejectedValue(error); - - const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Unknown error occurred"); - expect(consoleErrorSpy).toHaveBeenCalledWith("Unknown error occurred"); - - consoleErrorSpy.mockRestore(); - }); - - it("should handle errors during executeDDL", async () => { - (getTables as any).mockResolvedValue(["table1"]); - - const error: any = new Error("DDL execution failed"); - error.debug = { sqlMessage: "Table does not exist" }; - vi.mocked(sql.executeDDL).mockRejectedValue(error); - - const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Table does not exist"); - expect(consoleErrorSpy).toHaveBeenCalledWith("Table does not exist"); - - consoleErrorSpy.mockRestore(); - }); - - it("should properly format SQL statements with semicolons", async () => { - (getTables as any).mockResolvedValue(["table1", "table2"]); - - vi.mocked(sql.executeDDL).mockImplementation(() => - Promise.resolve({ - rows: [ - { "Create Table": "CREATE TABLE table1 (...)", Table: "table1" }, - { "Create Table": "CREATE TABLE table2 (...)", Table: "table2" }, - ], - }), - ); - - const result = await fetchSchemaWebTrigger(); - - expect(result.statusCode).toBe(200); - const statements = result.body.split(";\n"); - expect(statements.length).toBeGreaterThanOrEqual(4); - expect(statements[0]).toBe("SET foreign_key_checks = 0"); - expect(statements[1]).toContain("CREATE TABLE IF NOT EXISTS table1"); - expect(statements[2]).toContain("CREATE TABLE IF NOT EXISTS table2"); - expect(statements[statements.length - 1]).toBe("SET foreign_key_checks = 1"); - }); - }); - - describe("dropSchemaMigrations", () => { - it("should drop all tables successfully", async () => { - // Mock getTables to return some table names - (getTables as any).mockResolvedValue(["table1", "table2"]); - - // Mock generateDropTableStatements to return drop statements - (generateDropTableStatements as any).mockReturnValue([ - "DROP TABLE IF EXISTS table1", - "DROP TABLE IF EXISTS table2", - ]); - - // Mock executeDDL to succeed - (sql.executeDDL as any).mockResolvedValue({ rows: [] }); - - const result = await dropSchemaMigrations(); - - expect(result.statusCode).toBe(200); - expect(result.body).toBe( - "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.", - ); - expect(sql.executeDDL).toHaveBeenCalledTimes(2); - }); - - it("should handle errors during table dropping", async () => { - (getTables as any).mockResolvedValue(["table1"]); - (generateDropTableStatements as any).mockReturnValue(["DROP TABLE IF EXISTS table1"]); - (sql.executeDDL as any).mockRejectedValue(new Error("Failed to drop table")); - - const result = await dropSchemaMigrations(); - - expect(result.statusCode).toBe(500); - expect(result.body).toContain("Failed to drop table"); - }); - }); - describe("dropTableSchemaMigrations", () => { - it("should drop all tables/squence successfully", async () => { - // Mock getTables to return some table names - (getTables as any).mockResolvedValue(["table1", "table2"]); - - // Mock generateDropTableStatements to return drop statements - (generateDropTableStatements as any).mockReturnValue([ - "DROP TABLE IF EXISTS table1", - "DROP TABLE IF EXISTS table2", - ]); - - // Mock executeDDL to succeed - (sql.executeDDL as any).mockResolvedValue({ rows: [] }); - - const result = await dropTableSchemaMigrations(); - - expect(result.statusCode).toBe(200); - expect(result.body).toBe( - "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.", - ); - expect(sql.executeDDL).toHaveBeenCalledTimes(2); - }); - - it("should handle errors during table dropping", async () => { - (getTables as any).mockResolvedValue(["table1"]); - (generateDropTableStatements as any).mockReturnValue(["DROP TABLE IF EXISTS table1"]); - (sql.executeDDL as any).mockRejectedValue(new Error("Failed to drop table")); - - const result = await dropSchemaMigrations(); - - expect(result.statusCode).toBe(500); - expect(result.body).toContain("Failed to drop table"); - }); - }); - - describe("applySchemaMigrations", () => { - it("should apply migrations successfully", async () => { - const mockMigration = async (runner: MigrationRunner) => { - runner.enqueue("test_migration", "CREATE TABLE test (id INT)"); - return runner; - }; - - const result = await applySchemaMigrations(mockMigration); - - expect(result.statusCode).toBe(200); - expect(result.body).toBe("Migrations successfully executed"); - }); - - it("should handle errors during migration", async () => { - const mockMigration = async (runner: MigrationRunner) => { - runner.enqueue("test_migration", "CREATE TABLE test (id INT)"); - throw new Error("Failed to apply migration"); - }; - - const result = await applySchemaMigrations(mockMigration); - - expect(result.statusCode).toBe(500); - expect(result.body).toContain("Failed to apply migration"); - }); - - it("should handle invalid migration object", async () => { - const result = await applySchemaMigrations(null as any); - - expect(result.statusCode).toBe(500); - expect(result.body).toContain("migration is not a function"); - }); - }); - - describe("slowQuerySchedulerTrigger", () => { - let mockForgeSQLORM: any; - - beforeEach(() => { - vi.clearAllMocks(); - mockForgeSQLORM = { - getDrizzleQueryBuilder: vi.fn().mockReturnValue({ - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnThis(), - }), - }; - }); - - it("should successfully analyze slow queries with default options", async () => { - const mockResults = [ - "Found SlowQuery SQL: SELECT * FROM users | Memory: 2.50 MB | Time: 150.00 ms\n Plan:IndexScan(users)", - ]; - (slowQueryPerHours as any).mockResolvedValue(mockResults); - - const result = await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: 1, - timeout: 3000, - }); - - expect(slowQueryPerHours).toHaveBeenCalledWith(mockForgeSQLORM, 1, 3000); - expect(result.statusCode).toBe(200); - expect(result.statusText).toBe("Ok"); - expect(result.headers).toEqual({ "Content-Type": ["application/json"] }); - expect(result.body).toBe(JSON.stringify(mockResults)); - }); - - it("should use default values when options are not provided", async () => { - const mockResults = ["Found SlowQuery SQL: SELECT * FROM orders"]; - (slowQueryPerHours as any).mockResolvedValue(mockResults); - - const result = await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: undefined as any, - timeout: undefined as any, - }); - - expect(slowQueryPerHours).toHaveBeenCalledWith(mockForgeSQLORM, 1, 3000); - expect(result.statusCode).toBe(200); - expect(result.body).toBe(JSON.stringify(mockResults)); - }); - - it("should handle custom hours and timeout options", async () => { - const mockResults = [ - "Found SlowQuery SQL: SELECT * FROM products | Memory: 5.00 MB | Time: 300.00 ms\n Plan:FullScan(products)", - ]; - (slowQueryPerHours as any).mockResolvedValue(mockResults); - - const result = await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: 6, - timeout: 5000, - }); - - expect(slowQueryPerHours).toHaveBeenCalledWith(mockForgeSQLORM, 6, 5000); - expect(result.statusCode).toBe(200); - expect(result.body).toBe(JSON.stringify(mockResults)); - }); - - it("should handle errors with sqlMessage in debug context", async () => { - const error = { - debug: { - sqlMessage: "Query timeout exceeded", - }, - }; - (slowQueryPerHours as any).mockRejectedValue(error); - - const result = await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: 1, - timeout: 3000, - }); - - expect(result.statusCode).toBe(500); - expect(result.statusText).toBe("Bad Request"); - expect(result.body).toBe("Query timeout exceeded"); - }); - - it("should handle errors with message in debug context", async () => { - const error = { - debug: { - message: "Database connection failed", - }, - }; - (slowQueryPerHours as any).mockRejectedValue(error); - - const result = await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: 1, - timeout: 3000, - }); - - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Database connection failed"); - }); - - it("should handle errors with direct message property", async () => { - const error = { - message: "Network error occurred", - }; - (slowQueryPerHours as any).mockRejectedValue(error); - - const result = await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: 1, - timeout: 3000, - }); - - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Network error occurred"); - }); - - it("should handle errors with unknown error structure", async () => { - const error = {}; - (slowQueryPerHours as any).mockRejectedValue(error); - - const result = await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: 1, - timeout: 3000, - }); - - expect(result.statusCode).toBe(500); - expect(result.body).toBe("Unknown error occurred"); - }); - - it("should handle empty results array", async () => { - (slowQueryPerHours as any).mockResolvedValue([]); - - const result = await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: 24, - timeout: 2000, - }); - - expect(result.statusCode).toBe(200); - expect(result.body).toBe(JSON.stringify([])); - }); - - it("should handle multiple slow query results", async () => { - const mockResults = [ - "Found SlowQuery SQL: SELECT * FROM users | Memory: 2.50 MB | Time: 150.00 ms\n Plan:IndexScan(users)", - "Found SlowQuery SQL: SELECT * FROM orders | Memory: 3.75 MB | Time: 200.00 ms\n Plan:FullScan(orders)", - "Found SlowQuery SQL: SELECT * FROM products | Memory: 1.25 MB | Time: 100.00 ms\n Plan:IndexLookup(products)", - ]; - (slowQueryPerHours as any).mockResolvedValue(mockResults); - - const result = await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: 1, - timeout: 3000, - }); - - expect(result.statusCode).toBe(200); - expect(result.body).toBe(JSON.stringify(mockResults)); - expect(JSON.parse(result.body as string)).toHaveLength(3); - }); - - it("should log error to console when error occurs", async () => { - const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - const error = { - message: "Test error", - }; - (slowQueryPerHours as any).mockRejectedValue(error); - - await slowQuerySchedulerTrigger(mockForgeSQLORM, { - hours: 1, - timeout: 3000, - }); - - expect(consoleErrorSpy).toHaveBeenCalledWith("Test error"); - consoleErrorSpy.mockRestore(); - }); - }); -}); diff --git a/autoupdate.sh b/autoupdate.sh deleted file mode 100755 index a3f44ac50..000000000 --- a/autoupdate.sh +++ /dev/null @@ -1,439 +0,0 @@ -#!/bin/bash -set -e - -# Colors (disabled when not a TTY so pipes work) -if [[ -t 1 ]]; then - RED='\033[0;31m' - GREEN='\033[0;32m' - YELLOW='\033[1;33m' - BLUE='\033[0;34m' - CYAN='\033[0;36m' - BOLD='\033[1m' - RESET='\033[0m' -else - RED= GREEN= YELLOW= BLUE= CYAN= BOLD= RESET= -fi - -STEP=0 -step() { STEP=$((STEP + 1)); echo -e "${CYAN}[Step ${STEP}]${RESET} ${*}"; } -section() { echo -e "\n${BOLD}${BLUE}══════════════════════════════════════════════════════════${RESET}\n${BOLD}${BLUE} ${*}${RESET}\n${BOLD}${BLUE}══════════════════════════════════════════════════════════${RESET}"; } -run() { echo -e "${YELLOW} →${RESET} $*"; "$@"; } - -section "Root package (forge-sql-orm)" -step "Updating dependencies (ncu -u)..." -run ncu -u --dep prod,dev,peer,optional -step "Removing node_modules and package-lock.json..." -run rm -rf node_modules package-lock.json -step "Installing dependencies (npm i)..." -run npm i -step "Running knip..." -run npm run knip -step "Running lint:fix..." -run npm run lint:fix -step "Building..." -run npm run build -step "Staging package.json and package-lock.json..." -run git add package.json package-lock.json -( -section "forge-sql-orm-cli" -step "Updating dependencies (ncu -u)..." -cd forge-sql-orm-cli -run ncu -u --dep prod,dev,peer,optional -step "Removing node_modules and package-lock.json..." -run rm -rf node_modules package-lock.json -step "Installing dependencies (npm i)..." -run npm i -step "Running knip..." -run npm run knip -step "Running lint:fix..." -run npm run lint:fix -step "Building CLI..." -run npm run build -) -( -section "forge-sql-orm-extra" -step "Updating dependencies (ncu -u)..." -cd forge-sql-orm-extra -run ncu -u --dep prod,dev,peer,optional -step "Removing node_modules and package-lock.json..." -run rm -rf node_modules package-lock.json -step "Installing dependencies (npm i)..." -run npm i -step "Running knip..." -run npm run knip -step "Building EXTRA..." -run npm run build -) -section "Examples" -cd examples - -section "forge-sql-orm-example-drizzle-driver-simple" -cd forge-sql-orm-example-drizzle-driver-simple -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-dynamic" -cd forge-sql-orm-example-dynamic -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-optimistic-locking" -cd forge-sql-orm-example-optimistic-locking -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-query-analyses" -cd forge-sql-orm-example-query-analyses -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-simple" -cd forge-sql-orm-example-simple -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-checklist" -cd forge-sql-orm-example-checklist -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-org-tracker" -cd forge-sql-orm-example-org-tracker -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-sql-executor" -cd forge-sql-orm-example-sql-executor -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-cache" -cd forge-sql-orm-example-cache -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - - -section "forge-sql-orm-example-atlascamp" -cd forge-sql-orm-example-atlascamp -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-vector" -cd forge-sql-orm-example-vector -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-ai" -cd forge-sql-orm-example-ai -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-backend-ai" -cd forge-sql-orm-example-backend-ai -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Staging package files..." -run git add package.json package-lock.json -step "Static UI: removing and updating deps..." -cd ai-lib -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -step "AI-LIB: installing..." -run npm i -step "AI-LIB: building..." -run npm run build:arm64 -step "Staging static build..." -sleep 2 -run git add package.json package-lock.json -cd ../static/forge-orm-example -run rm -rf node_modules package-lock.json -run ncu -u --dep prod,dev,peer,optional -run rm -rf package-lock.json -step "Static UI: installing and knip..." -run npm i -run npm run knip -step "Static UI: building..." -run npm run build -step "Staging package files..." -run git add package.json package-lock.json -cd ../../.. - -section "forge-sql-orm-example-ui-kit" -cd forge-sql-orm-example-ui-kit -step "Removing node_modules and lock file..." -run rm -rf node_modules package-lock.json -step "Updating dependencies (ncu)..." -run ncu -u --dep prod,dev,peer,optional -step "Installing dependencies..." -run npm i -step "Running knip..." -run npm run knip -step "Building (build:ci)..." -run npm run build:ci -step "Staging package files..." -run git add package.json package-lock.json -cd .. - -section "Format" -cd .. -step "Running format..." -run npm run format -echo -e "\n${GREEN}${BOLD}Done.${RESET}\n" \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index 398034b12..000000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,43 +0,0 @@ -import js from "@eslint/js"; -import tseslint from "@typescript-eslint/eslint-plugin"; -import tsparser from "@typescript-eslint/parser"; -import prettierConfig from "eslint-config-prettier"; -import vitest from '@vitest/eslint-plugin' -import globals from "globals"; -export default [ - js.configs.recommended, - { - languageOptions: { - parser: tsparser, - sourceType: "module", - ecmaVersion: "latest", - globals: globals.node, - }, - plugins: { - "@typescript-eslint": tseslint, - vitest: vitest, - }, - rules: { - ...prettierConfig.rules, - "no-console": "error", - "@typescript-eslint/no-unused-vars": ["error"], - "no-unused-vars": ["off"], - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/explicit-function-return-type": "off", - "vitest/no-disabled-tests": "warn", - "vitest/no-focused-tests": "error", - "no-undef": "error", - "vitest/valid-expect": "error", - "preserve-caught-error": "warn" - }, - }, - { - ignores: [ - "examples/**", - "forge-sql-orm-cli/**", - "node_modules/**", - "dist/**", - "coverage/**", - ], - }, -]; diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 9329e596a..000000000 --- a/examples/README.md +++ /dev/null @@ -1,139 +0,0 @@ -# Forge SQL ORM Examples - -This directory contains different examples demonstrating various ways to use Forge SQL ORM. - -## Available Examples - -### [forge-sql-orm-example-drizzle-driver-simple](forge-sql-orm-example-drizzle-driver-simple) - -Minimal example showing how to use Drizzle ORM directly with Forge SQL using our custom driver. Perfect for projects that need only basic database operations without additional ORM features. - -- Direct Drizzle ORM usage -- Custom Forge SQL driver -- Basic CRUD operations -- Type-safe queries - -### [forge-sql-orm-example-simple](forge-sql-orm-example-simple) - -Basic example demonstrating core Forge SQL ORM features. Good starting point for new projects. - -- Full ORM functionality -- Basic CRUD operations -- Query builder usage -- Simple database operations - -### [forge-sql-orm-example-ui-kit](forge-sql-orm-example-ui-kit) - -Jira global page example using **Forge UI Kit** (`@forge/react`) with Forge SQL ORM and Drizzle. Demonstrates CRUD on a `users` table with native Forge components (no Custom UI). - -- Forge UI Kit only (Form, DynamicTable, Textfield, Button, etc.) -- Create, list, and update users via resolvers -- Drizzle schema and migrations (apply on install and hourly) -- Resolvers: `createUser`, `fetchUsers`, `updateUsers` - -### [forge-sql-orm-example-optimistic-locking](forge-sql-orm-example-optimistic-locking) - -Demonstrates how to use optimistic locking to prevent data conflicts in concurrent operations. - -- Optimistic locking implementation -- Version field handling -- Conflict prevention -- Safe data updates - -### [forge-sql-orm-example-dynamic](forge-sql-orm-example-dynamic) - -Shows how to work with dynamic queries and complex database operations. - -- Dynamic query building -- Complex joins -- Advanced filtering -- Runtime query construction - -### [forge-sql-orm-example-query-analyses](forge-sql-orm-example-query-analyses) - -Demonstrates query analysis capabilities for performance optimization and debugging. This example shows how to analyze and optimize database queries using TiDB's system schemas. - -- Query plan analysis -- Slow query analysis -- Query history tracking -- Performance optimization tools -- Experimental features for development and troubleshooting - -### [forge-sql-orm-example-org-tracker](forge-sql-orm-example-org-tracker) - -A practical example demonstrating how to work with complex database relationships and sequences. This example shows how to build an organization tracking system with user management. - -- Joining tables with overlapping columns -- Using sequences for ID generation -- Complex queries with filtering -- User and organization management -- Search and filtering capabilities - -### [forge-sql-orm-example-checklist](forge-sql-orm-example-checklist) - -A practical example demonstrating optimistic locking implementation in a real-world scenario. This example shows how to handle concurrent modifications in a checklist feature for Jira issues. - -- Optimistic locking in a real application -- Concurrent modification handling -- Automatic conflict resolution -- User-friendly conflict notifications -- Default checklist initialization -- Two update modes comparison (with/without locking) - -### [forge-sql-orm-example-cache](forge-sql-orm-example-cache) - -Advanced example demonstrating comprehensive caching capabilities and performance monitoring. This example showcases both local and global caching, automatic cache management, and detailed performance analysis. - -- Query performance testing (cached vs non-cached) -- User & order management with automatic cache clearing -- Performance analysis with detailed monitoring -- Memory usage tracking and slow query detection -- Cache management and automatic invalidation -- Real-time performance metrics and execution plans -- Optional ID fields with auto-generation -- Modern React UI with detailed analytics - -### [forge-sql-orm-example-vector](forge-sql-orm-example-vector) - -Example for **TiDB `VECTOR`** columns and vector SQL helpers (`vecCosineDistance`, etc.) in Forge SQL ORM—storage and similarity search for **AI** workloads (embeddings), aligned with PingCAP’s [vector search SQL tutorial](https://docs.pingcap.com/tidb/stable/vector-search-get-started-using-sql). - -- Drizzle schema with `vectorTiDBType({ dimension: n })` -- Migrations creating `embedded_documents` and seed data (`dog`, `fish`, `tree`) -- Resolvers: insert, fetch all, cosine-distance search -- Custom UI (Atlaskit) for 3D demo vectors - -### [forge-sql-orm-example-ai](forge-sql-orm-example-ai) - -Custom UI example for **AI semantic search** with embeddings computed **on the frontend** (Custom UI / browser) and vector search in Forge SQL/TiDB. - -- **Embeddings on the frontend:** `@huggingface/transformers` (`all-MiniLM-L6-v2`) in the browser before `invoke` -- Store `title`, `document`, and vector embedding in `embedded_documents` -- Search by free-text query (query embedding is computed in the browser, then sent to the resolver) -- Cosine-distance ranking with similarity shown as percentage - -### [forge-sql-orm-example-backend-ai](forge-sql-orm-example-backend-ai) - -Same **AI semantic search** flow, but embeddings are computed **on the Forge backend** (resolver runtime), not in Custom UI. - -- **Embeddings on the backend:** sidecar bundle in `ai-lib/` (see `manifest.yml` → `extraFiles`), loaded from resolver code; Custom UI sends plain `title` / `document` / search `text` only -- `create` and `search` resolvers call the embedding pipeline server-side before SQL -- Requires a separate `ai-lib` build per target (`arm64` / `x86_64` for deploy, `build:tunnel` for `forge tunnel`) -- Cosine-distance ranking with similarity shown as percentage - -### [forge-sql-orm-example-atlascamp](forge-sql-orm-example-atlascamp) - -**Atlas Camp 2026 - February 9, 2026** - -Demonstration application showcasing advanced Forge SQL ORM capabilities for Atlas Camp presentation. Features complex ACL (Access Control List) system, query caching, performance optimization, error handling, and large-scale data operations. - -- Complex ACL system with 12 interconnected tables (users, roles, permissions, documents, ACL) -- Query caching with `selectDistinctCacheable()` for permission lookups -- Performance monitoring with automatic slow query detection (>500ms) -- Error handling for timeout and Out of Memory scenarios -- Automatic schema migrations with async queue processing -- Database seeding (300 users, 30,000 documents, 300,000 ACL entries) -- Scheduled triggers for migrations, slow query analysis, and cache cleanup -- Async queues for degradation monitoring and long-running migrations -- React-based frontend with interactive query execution - -Each example includes its own README with detailed setup instructions and usage examples. diff --git a/examples/forge-sql-orm-example-ai/.gitignore b/examples/forge-sql-orm-example-ai/.gitignore deleted file mode 100644 index df38833fe..000000000 --- a/examples/forge-sql-orm-example-ai/.gitignore +++ /dev/null @@ -1,52 +0,0 @@ -# These are some examples of commonly ignored file patterns. -# You should customize this list as applicable to your project. -# Learn more about .gitignore: -# https://www.atlassian.com/git/tutorials/saving-changes/gitignore - -# Node artifact files -node_modules/ -dist/ - -# Compiled Java class files -*.class - -# Compiled Python bytecode -*.py[cod] - -# Log files -*.log - -# Package files -*.jar - -# Maven -target/ -dist/ - -# JetBrains IDE -.idea/ - -# Unit test reports -TEST*.xml - -# Generated by MacOS -.DS_Store - -# Generated by Windows -Thumbs.db - -# Applications -*.app -*.exe -*.war - -# Large media files -*.mp4 -*.tiff -*.avi -*.flv -*.mov -*.wmv - - -/.forge/ diff --git a/examples/forge-sql-orm-example-ai/README.md b/examples/forge-sql-orm-example-ai/README.md deleted file mode 100644 index c81e2f6f5..000000000 --- a/examples/forge-sql-orm-example-ai/README.md +++ /dev/null @@ -1,171 +0,0 @@ -# Forge SQL ORM — AI Semantic Search Example - -This example demonstrates **AI semantic search** with Forge SQL ORM: - -- Frontend computes embeddings with local model `all-MiniLM-L6-v2` (`@huggingface/transformers`). -- Backend stores vectors in TiDB/Forge SQL. -- Search uses cosine distance (`vecCosineDistance`) and returns the closest documents. - -## What this example does - -1. In **Add documents**, you enter: - - `Title` - - `Document` (up to 2048 chars) -2. Before insert, frontend generates embedding from `Document`. -3. Backend `create` resolver saves: - - `title` - - `document` - - `embedding` -4. In **AI(Vector) search**, you enter query text. -5. Frontend generates query embedding and calls backend `search`. -6. Results are sorted by cosine distance and shown as: - - `id` - - `title` - - document open button - - similarity percent: `(1 - distance) * 100` - -## Project structure - -- Backend resolvers: [`src/index.ts`](./src/index.ts) -- Schema: [`src/entities/schema.ts`](./src/entities/schema.ts) -- Frontend app: [`static/forge-orm-example/src/App.tsx`](./static/forge-orm-example/src/App.tsx) -- Embedding code: [`static/forge-orm-example/src/ai.ts`](./static/forge-orm-example/src/ai.ts) - -## Requirements - -- [Forge CLI](https://developer.atlassian.com/platform/forge/) -- Atlassian site for `forge install` -- Node.js compatible with your Forge app runtime - -## Quick start - -### 1) Install backend dependencies - -```sh -cd examples/forge-sql-orm-example-ai -npm install -``` - -### 2) Install and build frontend - -```sh -cd static/forge-orm-example -npm install -npm run build -``` - -### 3) Deploy and install app - -```sh -cd .. -forge register # once -forge deploy -forge install --site .atlassian.net -``` - -## Important note about vector dimension - -The embedding model `all-MiniLM-L6-v2` returns vectors with a fixed dimension. -`embedding` column dimension in [`src/entities/schema.ts`](./src/entities/schema.ts) must match that model output exactly. - -If dimensions do not match, insert/search will fail at DB level. - -## How to use in UI - -### Add documents - -Open tab **Add documents** and add these records one by one. - -#### 1) Dogs - -**Title:** `Dogs` -**Document:** - -```text -The Unwavering Bond: A Comprehensive Look at Domestic Dogs -Domestic dogs, scientifically known as Canis lupus familiaris, have shared a unique evolutionary journey with humans for over fifteen thousand years. Originally descended from ancient wolves, these resilient mammals have transitioned from wild predators to beloved family members, earning their reputation as "man's best friend." Their primary role has shifted significantly through history; while they were once valued strictly for their hunting prowess and guarding abilities, modern canines are now primarily cherished for their companionship and emotional support. -Physically, dogs exhibit an incredible diversity in size, coat texture, and temperament. From the tiny Chihuahua to the massive Great Dane, every breed possesses specific traits developed through centuries of selective breeding. Beyond their physical attributes, dogs are highly intelligent social animals capable of understanding human emotions and complex commands. They communicate through a sophisticated range of vocalizations, including barks and whines, alongside subtle body language like tail wagging or ear positioning. -Furthermore, the working capabilities of dogs remain vital to society today. Specialized service animals assist individuals with visual impairments, while brave search-and-rescue teams navigate treacherous terrain to save lives. Their acute sense of smell, which is thousands of times more sensitive than a human's, allows them to detect specific scents with remarkable precision. Whether they are performing a high-stakes job or simply waiting patiently for their owner to return home, dogs continue to demonstrate an unparalleled level of loyalty, devotion, and unconditional love that enriches human lives across every culture. -``` - -#### 2) Tree - -**Title:** `Tree` -**Document:** - -```text -The Silent Giants: Understanding the Life of Trees -Trees are the fundamental pillars of our planet's terrestrial ecosystems, serving as complex biological organisms that sustain life on Earth. As perennial plants with an elongated stem or trunk, they are uniquely characterized by their woody structure and extensive root systems. Through the remarkable process of photosynthesis, trees convert sunlight, water, and carbon dioxide into life-sustaining oxygen and glucose. This chemical transformation not only supports the tree's own growth but also regulates the global atmospheric balance, making forests the "lungs of our planet." -The internal anatomy of a tree is a marvel of natural engineering. Beneath the protective outer bark lies the cambium layer, which facilitates the growth of new cells, and the xylem, a sophisticated vascular system that transports nutrients from the earth to the highest leaves. Throughout the seasons, deciduous trees undergo dramatic transformations, shedding their foliage in autumn to conserve energy before the harsh winter months. In contrast, evergreens maintain their needles year-round, showcasing the diverse evolutionary strategies plants use to survive in varying climates. -Beyond their biological functions, trees provide critical habitats for countless species of insects, birds, and fungi. They stabilize the soil against erosion, offer cooling shade during intense heat, and contribute to the water cycle by releasing moisture through transpiration. For humanity, trees have been an essential resource for millennia, providing timber for construction, fruit for sustenance, and a profound sense of tranquility. Protecting these ancient, towering organisms is vital for maintaining biodiversity and ensuring the environmental health of future generations. -``` - -#### 3) Fish - -**Title:** `Fish` -**Document:** - -```text -The Aquatic Realm: Exploring the World of Fish -Fish represent a diverse group of craniate organisms that have mastered life in the world's oceans, rivers, and lakes for over five hundred million years. As cold-blooded vertebrates, they are perfectly adapted to their underwater environments, utilizing specialized organs called gills to extract life-sustaining oxygen directly from the water. Unlike land-dwelling mammals, fish possess streamlined bodies covered in protective scales and use various fins for propulsion, stability, and precise maneuvering through dense aquatic currents. -The biological variety among fish is staggering, ranging from the tiny, colorful inhabitants of tropical coral reefs to the colossal whale sharks that roam the open sea. Many species have evolved incredible sensory capabilities, such as the lateral line system, which detects minute vibrations and pressure changes in the surrounding water. This "sixth sense" allows them to navigate in complete darkness, avoid predators, and hunt with remarkable accuracy. Additionally, some fish exhibit complex social behaviors, forming massive schools that move in perfect unison to confuse attackers or increase foraging efficiency. -Reproduction and survival strategies in the aquatic world are equally fascinating. While some fish lay thousands of delicate eggs in hidden nests, others, like certain sharks, give birth to fully formed live young. Their role in the global food web is indispensable, as they serve as a primary protein source for billions of humans and countless other predators. From the deepest abyssal trenches to the shallowest mountain streams, fish continue to thrive as a testament to evolutionary resilience, playing a vital role in maintaining the delicate ecological balance of our blue planet's hydrosphere. -``` - -#### 4) Cat - -**Title:** `Cat` -**Document:** - -```text -The Enigmatic Grace: Understanding the Domestic Cat -The domestic cat, or Felis catus, is a small carnivorous mammal celebrated for its agility, independent spirit, and mysterious demeanor. Having lived alongside humans for nearly ten thousand years, cats were originally revered in ancient societies—most notably in Egypt—for their ability to protect grain stores from rodents. Unlike dogs, which were bred for cooperation, cats have largely retained their solitary hunting instincts, making them fascinatingly self-sufficient companions in modern households. -Physically, cats are marvels of biological engineering. Their skeletons are incredibly flexible, allowing them to squeeze through tight spaces and always land on their feet thanks to a highly developed righting reflex. They possess extraordinary sensory perceptions; their night vision is far superior to that of humans, and their retractable claws allow for silent stalking and efficient climbing. A cat’s communication is equally nuanced, ranging from the gentle vibration of a purr, which often signals contentment or self-healing, to the sharp hiss used for territorial defense. -Behaviorally, cats are known for their fastidious grooming habits and complex social signals. While they are often labeled as aloof, many cats form deep emotional bonds with their owners, expressing affection through "kneading" or gentle head-butts. Their predatory prowess remains intact, even in indoor environments, where they often treat toys as "prey" to satisfy their instinctive need to hunt. As one of the world's most popular pets, cats continue to captivate us with their blend of wild heritage and domestic charm, offering a quiet, observant presence that has inspired artists and thinkers for millennia. -``` - -#### 5) Mice - -**Title:** `Mice` -**Document:** - -```text -The Smallest Survivors: The World of Mice -Mice are small rodents belonging to the family Muridae, known for their incredible adaptability and presence in nearly every corner of the globe. Characterized by their pointed snouts, large rounded ears, and long, thin tails, these tiny mammals have successfully thrived alongside human civilizations for thousands of years. While often viewed as mere pests in granaries, mice are highly complex creatures with sophisticated social structures and remarkable survival instincts that allow them to inhabit diverse environments ranging from dense forests to urban households. -Biologically, mice are built for stealth and speed. Their whiskers, or vibrissae, are highly sensitive tactile organs that allow them to navigate in total darkness by sensing air currents and physical obstacles. They possess an extraordinary reproductive rate, a necessary evolutionary strategy to counter their role as a primary food source for numerous predators, including owls, snakes, and felines. Despite their small stature, mice are surprisingly intelligent; they exhibit problem-solving abilities and can communicate with one another using ultrasonic vocalizations that are completely inaudible to the human ear. -In the realm of science and history, the mouse has played an indispensable role. Due to their genetic similarity to humans, mice are the most commonly studied model organisms in medical research, contributing to countless breakthroughs in genetics and pharmacology. Whether they are scurrying through a field or living in a controlled laboratory setting, mice demonstrate a level of resilience and biological efficiency that far outweighs their size. Their ability to find food in the most difficult conditions and their cautious, nocturnal nature continue to make them one of the most successful mammalian species on Earth. -``` - -### AI search examples - -Open tab **AI(Vector) search** and test: - -1. **Test: extract main topic** (Target: `Tree`) - - ```text - I am looking for information about large organisms that live for hundreds of years, have a woody trunk, and use their leaves to turn sunlight into energy while providing shade and stabilized soil for the ecosystem. - ``` - - Expected top match: **Tree** (clear lead due to "woody trunk" and photosynthesis context). - -2. **Test: behavioral description** (Target: `Cat`) - - ```text - Small domestic predators that were respected in ancient history, known for being very independent, having great vision in the dark, and the ability to land on their feet when they jump from high places. - ``` - - Expected top match: **Cat** (ancient history + landing on feet + night vision). - -3. **Test: mixed long query** (Target: `Mice`) - - ```text - Tell me about tiny mammals that are often found in houses or fields, which scientists use in laboratories to study genetics and develop new medicines because they breed very fast and are biologically similar to humans. - ``` - - Expected top match: **Mice** (strong medical research and rodent traits signal). - -## References - -- [Forge SQL ORM README](https://github.com/forge-sql-orm/forge-sql-orm/blob/master/README.md) -- [TiDB Vector Search overview](https://docs.pingcap.com/ai/vector-search-overview/) -- [TiDB Vector functions and operators](https://docs.pingcap.com/ai/vector-search-functions-and-operators/) diff --git a/examples/forge-sql-orm-example-ai/knip.config.ts b/examples/forge-sql-orm-example-ai/knip.config.ts deleted file mode 100644 index 30a778b0e..000000000 --- a/examples/forge-sql-orm-example-ai/knip.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import type { KnipConfig } from "knip"; -import { exampleConfig } from "../knip.config"; - -const config: KnipConfig = { - ...exampleConfig, - project: ["src/**/*.ts"], -}; - -export default config; diff --git a/examples/forge-sql-orm-example-ai/manifest.yml b/examples/forge-sql-orm-example-ai/manifest.yml deleted file mode 100644 index 7bc204698..000000000 --- a/examples/forge-sql-orm-example-ai/manifest.yml +++ /dev/null @@ -1,56 +0,0 @@ -modules: - jira:globalPage: - - key: forge-sql-orm-example-hello-world-page - resource: main - resolver: - function: resolver - title: Forge SQL ORM SEMANTIC SEARCH DEMO - scheduledTrigger: - - key: scheduled-schema-migration - function: runSchemaMigration - interval: hour - trigger: - - key: post-install-schema-migration - function: runSchemaMigration - events: - - avi:forge:installed:app - # webtrigger: - # - key: invoke-schema-migration - # function: runSchemaMigration - # security: - # egress: - # allowDataEgress: false - # allowedResponses: - # - statusCode: 200 - # body: '{"body": "Migrations successfully executed"}' - # - key: drop-schema-migration - # function: dropMigrations - # - key: fetch-schema - # function: fetchSchema - sql: - - key: main - engine: mysql - function: - - key: resolver - handler: index.handler - - key: runSchemaMigration - handler: index.handlerMigration - - key: dropMigrations - handler: index.dropMigrations - - key: fetchSchema - handler: index.fetchMigrations -resources: - - key: main - path: static/forge-orm-example/build-static - tunnel: - port: 3099 -app: - runtime: - name: nodejs24.x - id: ari:cloud:ecosystem::app/bdcff621-38b5-4e94-9919-ba5e81f277ca -permissions: - content: - styles: - - "unsafe-inline" - scripts: - - "unsafe-eval" diff --git a/examples/forge-sql-orm-example-ai/package-lock.json b/examples/forge-sql-orm-example-ai/package-lock.json deleted file mode 100644 index 8751bd540..000000000 --- a/examples/forge-sql-orm-example-ai/package-lock.json +++ /dev/null @@ -1,1869 +0,0 @@ -{ - "name": "jira-global-page-custom-ui", - "version": "1.1.4", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "jira-global-page-custom-ui", - "version": "1.1.4", - "license": "MIT", - "dependencies": { - "@forge/resolver": "1.8.0", - "@forge/sql": "^3.0.25", - "drizzle-orm": "^0.45.2", - "forge-sql-orm": "^2.2.0" - }, - "devDependencies": { - "@types/node": "^25.9.2", - "knip": "^6.16.1", - "typescript": "^6.0.3" - } - }, - "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@forge/api": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@forge/api/-/api-7.2.1.tgz", - "integrity": "sha512-7bW8+D1dWO7p3YohCXcxhp/8DYcI2zsXYfbCTueaMgfxGLd3p3x0AwVbSYVQF6UjLIJerhtNk7FB+fKtt5bYwA==", - "license": "SEE LICENSE IN LICENSE.txt", - "dependencies": { - "@forge/auth": "0.0.9", - "@forge/egress": "2.3.2", - "@forge/i18n": "0.0.7", - "@forge/manifest": "^12.8.0", - "@forge/storage": "2.0.3", - "headers-utils": "^3.0.2" - } - }, - "node_modules/@forge/auth": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@forge/auth/-/auth-0.0.9.tgz", - "integrity": "sha512-3qZZNknFprzDkrXzBVKHqVD12r/b2K9cu/RJh9TP3QLiF18v7bdoD1fgZZbVavKJUmCNdQERk6NTVQLmmEszhg==", - "license": "SEE LICENSE IN LICENSE.txt", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@forge/egress": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@forge/egress/-/egress-2.3.2.tgz", - "integrity": "sha512-p8ioX4qnAlRFln+hyH9kO0MmVCSOUg0bsIG9RAYK8KM2YaJb6EnKqbCvPMBTwegiua3vixBsnZmWDgPegSZh9Q==", - "license": "SEE LICENSE IN LICENSE.txt" - }, - "node_modules/@forge/events": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@forge/events/-/events-2.1.6.tgz", - "integrity": "sha512-tVtkXdKYN2pbHDjA5GcPt4Ny4mdi2Ee7Z93ECOUeJXL25NahbnoZSROMMWwF8hakmC4m6iGcID1rP1d8CMUJrQ==", - "license": "SEE LICENSE IN LICENSE.txt", - "optional": true, - "dependencies": { - "@forge/api": "7.2.1" - } - }, - "node_modules/@forge/i18n": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@forge/i18n/-/i18n-0.0.7.tgz", - "integrity": "sha512-EKrQApcuI4k4AkUSeERkZv1dQaGjWsmB8i7ciDPtpDARPRH1sOrU+FSEOoA7b9FQ15++7Q144m94w/aMLCg5Gg==", - "license": "SEE LICENSE IN LICENSE.txt", - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/@forge/manifest": { - "version": "12.8.0", - "resolved": "https://registry.npmjs.org/@forge/manifest/-/manifest-12.8.0.tgz", - "integrity": "sha512-BiJC1jQSKxF/4if9jaKSy/6BhIVkbV6yo9MPs+2CSAS/RuKn2qG4z4i48hKxpHj1acS0pM8MUq82xXGNINimBA==", - "license": "SEE LICENSE IN LICENSE.txt", - "dependencies": { - "@forge/i18n": "0.0.7", - "@sentry/node": "7.106.0", - "ajv": "^8.18.0", - "ajv-formats": "2.1.1", - "cheerio": "^1.1.0", - "glob": "^13.0.0", - "lodash": "^4.17.21", - "mime-types": "^2.1.35", - "yaml": "^2.3.4" - } - }, - "node_modules/@forge/resolver": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@forge/resolver/-/resolver-1.8.0.tgz", - "integrity": "sha512-n9u8zAijT+MQLogo72xplFLZzcM7BDhQ9tW7qYZFS58/ZHtju76rVupBzSReeCxvo5lL2JTXB9mnFh2N8p2xyw==", - "license": "SEE LICENSE IN LICENSE.txt" - }, - "node_modules/@forge/sql": { - "version": "3.0.25", - "resolved": "https://registry.npmjs.org/@forge/sql/-/sql-3.0.25.tgz", - "integrity": "sha512-3t9Hg28ILfBN243HNF4DYc0iyn8t6rbUf6umvCR+YmyPwKgb0lpbA7qxd0AgSXl3zuSzjxtaSEl+7GLjpd7XPg==", - "license": "SEE LICENSE IN LICENSE.txt", - "dependencies": { - "@forge/api": "^7.2.1" - } - }, - "node_modules/@forge/storage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@forge/storage/-/storage-2.0.3.tgz", - "integrity": "sha512-DvliHUgr9AYPslpFWBB4LufS8yzvJisqfpP+CCAwo76xBWNlXWFd3PRFA/DaZeGz+Vb4vmBYP7qFMqM1oijIrQ==", - "license": "SEE LICENSE IN LICENSE.txt" - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" - } - }, - "node_modules/@oxc-parser/binding-android-arm-eabi": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.133.0.tgz", - "integrity": "sha512-l/44caGse+VpnY9gx0yvvc5QnnG3yG1FO3KZgYvNL1GZrfK86zIwAOgGEVlxDyRymzrU/KHiblPFpevKOmJmUA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-android-arm64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.133.0.tgz", - "integrity": "sha512-KUHmPMziLBp4u+zbrLdB7iWS7KshuZe+RAp7ELnY9SI9nNXBZ+dp8fiBqWOxhXqn+FQg3a4UcQhwmsJOKV8Jjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-darwin-arm64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.133.0.tgz", - "integrity": "sha512-q8dWmnU/8ea2tga9w2f1PinQ5rcMPDUGkF64T189b65YMjUomET4oy5oRldOr4AwOQkneOG/Zttnz1Dvrc62wg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-darwin-x64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.133.0.tgz", - "integrity": "sha512-cOKeIELIB2bJnCKwqx4Rdj+1Lss/U6uCbLxRySZrhyOOQa1flKhwZFjEHRHxk8fU1NKmhK5OnTdPQ4CpjuFuVw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-freebsd-x64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.133.0.tgz", - "integrity": "sha512-OpaSv4pW3KgFrMYQxTaS0aOE4T1DQF3qZE/4B6uqqv1KgPWWd4UQhJALi8PJPX1RRV5K7ThKXRfF7qGg2+3l1A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.133.0.tgz", - "integrity": "sha512-JGK1wlGrGwxBIlVSF7KWTX1/ru6BEtf28fRROztDRkLfiW+Kxa4onnriezMIiogfn9hVw2KzYcKiLjkLR2ns8A==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.133.0.tgz", - "integrity": "sha512-yuZO533Ftonxn/iyoqQzURzLQHMspvsIyfiCSNi1t/ER4eIQaR0SsmUOUm5b/lmSig7IWIUa5/BrbEkAPwcilQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm64-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.133.0.tgz", - "integrity": "sha512-hvpbqT5pN2rR+3+xtWeizwfR/aZ0vGceg6TqYMl+ToxMpk9/tmnX7kSvQnfEUkoua8mhogzvIKsAkn0wxgblBA==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm64-musl": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.133.0.tgz", - "integrity": "sha512-wJQGamIosQBoJHW9+S5XxrtKRo3eyJxsnS1XCPrqN0LHi8uw1pTqqTfn3t/NVuvbBg7Pumn4ez9Eidgcn0xbEg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-ppc64-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.133.0.tgz", - "integrity": "sha512-Koaz32/O5+abIfrNGdyndgRvdOZ9jEf5/z3Ep9h3h2QWpdDiUQpVwgH0OcMXCs+l9aXxPLtkupqyVig9W6FDKw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.133.0.tgz", - "integrity": "sha512-R4vOjWzxhnNWHnVLeiB6jNuIifdy9vcMXZGPc7StXcxBovI+U2zg1QhZ9o8OjV80oGivs1lX5NfPLzk4IPqlRA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-riscv64-musl": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.133.0.tgz", - "integrity": "sha512-iwgBNUTHiMdxARLYuM0SBlnYeb19iw1Ea5M+4ERZupCsBMLArti6FyZ6UfFjJxIiTDr2oW2DGQFxlQVQ/dW9rA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-s390x-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.133.0.tgz", - "integrity": "sha512-ZwZNo8FZmB/gVfboQl+wXilBigGl+6nQQs+nITOeAP/HcAOjiHl6XZJL9F/KXNEspODQcbjAiyjUbeCJd9a0fA==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-x64-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.133.0.tgz", - "integrity": "sha512-govCvWx1dBlED3uu4qXctxpRcouu9I8Kn+DBktGCl760JtlGJzc9l/OmPJKlYWSbrRqKkMZehNeZ/4Wfma7uSA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-x64-musl": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.133.0.tgz", - "integrity": "sha512-ssTlpXD5Mq9uCssDJPzlRWqBt4Y7Zzd9i+XZhWmK/9Y6KUIuAxVYTYiI8lxcGWi0+3/Cz4A8q9UrD4NK9Y2j7g==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-openharmony-arm64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.133.0.tgz", - "integrity": "sha512-51aByfXhPtLEdWG4a2Ihdw6cPWV1ei1AarALpFdDP8MLWDLE2NuUMgbo3DERR2Kt8fT/ok1GUvBiLxVGke9uUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-wasm32-wasi": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.133.0.tgz", - "integrity": "sha512-2e16tkKp+wDO2GTAmXfxbBcCmGEaFPIJEIRBBmVKNVXSc8/fJsSIaBGyFTPHM9ST5GNWgJcYIt94rDTks+PLwA==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-win32-arm64-msvc": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.133.0.tgz", - "integrity": "sha512-KPTNDKbxH1cglrqTyVeXHb4Pk4oksz8EcE1/v8zqU7N4UXbiHfA/IwtXZ2U77fnRAWBbgVkl/lZbL7o3hRdejg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-win32-ia32-msvc": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.133.0.tgz", - "integrity": "sha512-Una1bNYv9zCavQrfnDR9wuZVB3itLjCEH4Oz7i6CwAJN/Xq9b+zbbcxmvdkKvvJt4Ngc/MBmIYlbLo3zS4TQ0A==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-win32-x64-msvc": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.133.0.tgz", - "integrity": "sha512-kjBhCiOGSYTwDJQuuZa7a94JbP8htWu7J0X1KwH74kV2K5eYf6eyJRYmkpCDvr0XEL8tMxYI4WU1VekblFCLgg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-project/types": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", - "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/@oxc-resolver/binding-android-arm-eabi": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm-eabi/-/binding-android-arm-eabi-11.20.0.tgz", - "integrity": "sha512-IjfWOXRgJFNdORDl+Uf1aibNgZY2guOD3zmOhx1BGVb/MIiqlFTdmjpQNplSN58lhWehnX4UNqC3QwpUo8pjJg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@oxc-resolver/binding-android-arm64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm64/-/binding-android-arm64-11.20.0.tgz", - "integrity": "sha512-QqslZAuFQG8Q9xm7JuIn8JUbvywhSBMVhuQHtYW+auirZJloS41oxUUaBXk7uUhZJgp44c5zQLeVvmFaDQB+2Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@oxc-resolver/binding-darwin-arm64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-11.20.0.tgz", - "integrity": "sha512-MUcavykj2ewlR+kc5arpg4tC2RvzJkUxWtNv74pf7lcNk00GpIpN43vXMj+j6r4eMmfZhlb8hueKoIb8e9kAGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oxc-resolver/binding-darwin-x64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-11.20.0.tgz", - "integrity": "sha512-BGB16nRUK5Etiv//ihPyzj8Lj1px0mhh4YIfe0FDf045ywknfSm0GEbiRESpr6Q4K82AvnyaRIhhluHByvS4bg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oxc-resolver/binding-freebsd-x64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-11.20.0.tgz", - "integrity": "sha512-JZgtePaqj3qmD5XFHJaSLWzHRxQu0LaPkdoM1KJXYADvAaa83ijXHclV3ej3CueeW0wxfIAbGCZVP45J0CA7uQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-11.20.0.tgz", - "integrity": "sha512-hOQ/p3ry3v3SchUBXicrrnszaI/UmYzM4wtS4RGfwgVUX7a+HbyQSzJ5aOzu+o6XZkFkS3ZXN4PZAzhOb77OSg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm-musleabihf": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-11.20.0.tgz", - "integrity": "sha512-2ArPksaw0AqeuGBfoS715VF+JvJQAhD2niWgjE5hVO+L+nAfikVQopvngCMX9x4BD8itWoQ3dnikrQyl5Ho5Jg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm64-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-11.20.0.tgz", - "integrity": "sha512-0bJnmYFp62JdZ4nVMDUZ/C58BCZOCcqgKtnUlp7L9Ojf/czIN+3j72YlLPeWLkzlr6SlYvIQA4SGV/HyO0d+qg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm64-musl": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-11.20.0.tgz", - "integrity": "sha512-wKHHzPKZo7Ufhv/Bt6yxT7FOgnIgW4gwXcJUipkShGp68W3wGVqvr1Sr0fY65lN0Oy6y41+g2kIDvkgZaMMUkw==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-ppc64-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-11.20.0.tgz", - "integrity": "sha512-RN8goF7Ie0B79L4i4G6OeBocTgSC56vJbQ65VJje+oXnldVpLnOU7j/AQ/dP94TcCS+Yh6WG8u3Qt4ETteXFNQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-riscv64-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-11.20.0.tgz", - "integrity": "sha512-5l1yU6/xQEqLZRzxqmMxJfWPslpwCmBsdDGaBvABPehxquCXDC7dd7oraNdKSJUMDXSM7VvVj8H2D2FTjU7oWw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-riscv64-musl": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-11.20.0.tgz", - "integrity": "sha512-xHEvkbgz6UC+A3JOyDQy76LkUaxsNSfIr3/GV8slwZsnuooJiIB34gzJfsyvR4JdCYNUUPsRJc/w/oWkODu+hg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-s390x-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-11.20.0.tgz", - "integrity": "sha512-aWPDUUmSeyHvlW+SoEUd+JIJsQhVhu6a5tBpDRMu058naPAchTgAVGCFy35zjbnFlt0i8hLWziff6HX0D3LU4g==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-x64-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-11.20.0.tgz", - "integrity": "sha512-x2YeSimvhJjKLVD8KSu8f/rqU1potcdEMkApIPJqjZWN7c2Fpt4g2X32WDg1p+XDAmyT7nuQGe0vnhvXeLbH+g==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-x64-musl": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-11.20.0.tgz", - "integrity": "sha512-kcRLEIxpZefeYfLChjpgFf3ilBzRDZ+yobMrpRsQlSrxuFGtm3U6PMU7AaEpMqo3NfDGVyJJseAjnRLzMFHjwQ==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-openharmony-arm64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-openharmony-arm64/-/binding-openharmony-arm64-11.20.0.tgz", - "integrity": "sha512-HHcfnApSZGtKhTiHqe8OZruOZe5XuFQH5/E0Yhj3u8fnFvzkM4/k6WjacUf4SvA0SPEAbfbgYmVPuo0VX/fIBQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@oxc-resolver/binding-wasm32-wasi": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-11.20.0.tgz", - "integrity": "sha512-Tn0y1XOFYHNfK1wp1Z5QK8Rcld/bsOwRISQXfqAZ5IBpv8Gz1IvV39fUWNprqNdRizgcvFhOzWwFun2zkJsyBg==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@oxc-resolver/binding-win32-arm64-msvc": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-11.20.0.tgz", - "integrity": "sha512-qPi25YNPe4YenS8MgsQU2+bIFHxxpLx1LVna2444cEHqNPhNjvWf9zqj4aWE43H9LpAsTmkkAlA3eL5ElBU3mA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@oxc-resolver/binding-win32-x64-msvc": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.20.0.tgz", - "integrity": "sha512-Wb14jWEW8huH6It9F6sXd9vrYmIS7pMrgkU6sxpLxkP+9z+wRgs71hUEhRpcn8FOXAFa27FVWfY2tRpbfTzfLw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sentry-internal/tracing": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.106.0.tgz", - "integrity": "sha512-O8Es6Sa/tP80nfl+8soNfWzeRNFcT484SvjLR8BS3pHM9KDAlwNXyoQhFr2BKNYL1irbq6UF6eku4xCnUKVmqA==", - "license": "MIT", - "dependencies": { - "@sentry/core": "7.106.0", - "@sentry/types": "7.106.0", - "@sentry/utils": "7.106.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/core": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.106.0.tgz", - "integrity": "sha512-Dc13XtnyFaXup2E4vCbzuG0QKAVjrJBk4qfGwvSJaTuopEaEWBs2MpK6hRzFhsz9S3T0La7c1F/62NptvTUWsQ==", - "license": "MIT", - "dependencies": { - "@sentry/types": "7.106.0", - "@sentry/utils": "7.106.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/node": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.106.0.tgz", - "integrity": "sha512-4DIqbu5K7//lK/k2nV8lqKeGQzhu2T1OpJFmiUrjN6fUKWivGFjZrcmQDS7tvhAAyJezkL3LlrNU4tjPHUElPA==", - "license": "MIT", - "dependencies": { - "@sentry-internal/tracing": "7.106.0", - "@sentry/core": "7.106.0", - "@sentry/types": "7.106.0", - "@sentry/utils": "7.106.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/types": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.106.0.tgz", - "integrity": "sha512-oKTkDaL6P9xJC5/zHLRemHTWboUqRYjkJNaZCN63j4kJqGy56wee4vDtDese/NWWn4U4C1QV1h+Mifm2HmDcQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/utils": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.106.0.tgz", - "integrity": "sha512-bVsePsXLpFu/1sH4rpJrPcnVxW2fXXfGfGxKs6Bm+dkOMbuVTlk/KAzIbdjCDIpVlrMDJmMNEv5xgTFjgWDkjw==", - "license": "MIT", - "dependencies": { - "@sentry/types": "7.106.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/node": { - "version": "25.9.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.2.tgz", - "integrity": "sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": ">=7.24.0 <7.24.7" - } - }, - "node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/cheerio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", - "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.2.2", - "encoding-sniffer": "^0.2.1", - "htmlparser2": "^10.1.0", - "parse5": "^7.3.0", - "parse5-htmlparser2-tree-adapter": "^7.1.0", - "parse5-parser-stream": "^7.1.2", - "undici": "^7.19.0", - "whatwg-mimetype": "^4.0.0" - }, - "engines": { - "node": ">=20.18.1" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/drizzle-orm": { - "version": "0.45.2", - "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.2.tgz", - "integrity": "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==", - "license": "Apache-2.0", - "peerDependencies": { - "@aws-sdk/client-rds-data": ">=3", - "@cloudflare/workers-types": ">=4", - "@electric-sql/pglite": ">=0.2.0", - "@libsql/client": ">=0.10.0", - "@libsql/client-wasm": ">=0.10.0", - "@neondatabase/serverless": ">=0.10.0", - "@op-engineering/op-sqlite": ">=2", - "@opentelemetry/api": "^1.4.1", - "@planetscale/database": ">=1.13", - "@prisma/client": "*", - "@tidbcloud/serverless": "*", - "@types/better-sqlite3": "*", - "@types/pg": "*", - "@types/sql.js": "*", - "@upstash/redis": ">=1.34.7", - "@vercel/postgres": ">=0.8.0", - "@xata.io/client": "*", - "better-sqlite3": ">=7", - "bun-types": "*", - "expo-sqlite": ">=14.0.0", - "gel": ">=2", - "knex": "*", - "kysely": "*", - "mysql2": ">=2", - "pg": ">=8", - "postgres": ">=3", - "sql.js": ">=1", - "sqlite3": ">=5" - }, - "peerDependenciesMeta": { - "@aws-sdk/client-rds-data": { - "optional": true - }, - "@cloudflare/workers-types": { - "optional": true - }, - "@electric-sql/pglite": { - "optional": true - }, - "@libsql/client": { - "optional": true - }, - "@libsql/client-wasm": { - "optional": true - }, - "@neondatabase/serverless": { - "optional": true - }, - "@op-engineering/op-sqlite": { - "optional": true - }, - "@opentelemetry/api": { - "optional": true - }, - "@planetscale/database": { - "optional": true - }, - "@prisma/client": { - "optional": true - }, - "@tidbcloud/serverless": { - "optional": true - }, - "@types/better-sqlite3": { - "optional": true - }, - "@types/pg": { - "optional": true - }, - "@types/sql.js": { - "optional": true - }, - "@upstash/redis": { - "optional": true - }, - "@vercel/postgres": { - "optional": true - }, - "@xata.io/client": { - "optional": true - }, - "better-sqlite3": { - "optional": true - }, - "bun-types": { - "optional": true - }, - "expo-sqlite": { - "optional": true - }, - "gel": { - "optional": true - }, - "knex": { - "optional": true - }, - "kysely": { - "optional": true - }, - "mysql2": { - "optional": true - }, - "pg": { - "optional": true - }, - "postgres": { - "optional": true - }, - "prisma": { - "optional": true - }, - "sql.js": { - "optional": true - }, - "sqlite3": { - "optional": true - } - } - }, - "node_modules/encoding-sniffer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", - "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", - "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.3", - "whatwg-encoding": "^3.1.1" - }, - "funding": { - "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fd-package-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fd-package-json/-/fd-package-json-2.0.0.tgz", - "integrity": "sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "walk-up-path": "^4.0.0" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/forge-sql-orm": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/forge-sql-orm/-/forge-sql-orm-2.2.0.tgz", - "integrity": "sha512-Mqoty0Y5XZ07VWlTdg+D29++I4KDUSjRUQMLV8KsyjFcRNbe6s6yYvTmg4/pQYJLZBKyqiCMXLjQuxJFHjYLqA==", - "license": "MIT", - "dependencies": { - "@forge/api": "^7.2.1", - "luxon": "^3.7.2" - }, - "optionalDependencies": { - "@forge/events": "^2.1.6" - }, - "peerDependencies": { - "@forge/sql": "^3.0.25", - "drizzle-orm": "^0.45.2" - } - }, - "node_modules/formatly": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/formatly/-/formatly-0.3.0.tgz", - "integrity": "sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fd-package-json": "^2.0.0" - }, - "bin": { - "formatly": "bin/index.mjs" - }, - "engines": { - "node": ">=18.3.0" - } - }, - "node_modules/get-tsconfig": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", - "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/headers-utils": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/headers-utils/-/headers-utils-3.0.2.tgz", - "integrity": "sha512-xAxZkM1dRyGV2Ou5bzMxBPNLoRCjcX+ya7KSWybQD2KwLphxsapUVK6x/02o7f4VU6GPSXch9vNY2+gkU8tYWQ==", - "license": "MIT" - }, - "node_modules/htmlparser2": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", - "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.2.2", - "entities": "^7.0.1" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", - "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jiti": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", - "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/knip": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/knip/-/knip-6.16.1.tgz", - "integrity": "sha512-TKMn1rxgH6h9vXR9Y0B+Cq7AdPTr9EI02IwoT65NzqYUkvoDQAaJ/aPybiFpAhZ1px6cNYYwXf86iHkBgzCo9w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/webpro" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/knip" - } - ], - "license": "ISC", - "dependencies": { - "fdir": "^6.5.0", - "formatly": "^0.3.0", - "get-tsconfig": "4.14.0", - "jiti": "^2.7.0", - "oxc-parser": "^0.133.0", - "oxc-resolver": "^11.20.0", - "picomatch": "^4.0.4", - "smol-toml": "^1.6.1", - "strip-json-comments": "5.0.3", - "tinyglobby": "^0.2.16", - "unbash": "^3.0.0", - "yaml": "^2.9.0", - "zod": "^4.1.11" - }, - "bin": { - "knip": "bin/knip.js", - "knip-bun": "bin/knip-bun.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/lodash": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "11.5.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", - "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/luxon": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", - "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/oxc-parser": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.133.0.tgz", - "integrity": "sha512-661RSx+ZcjBmjBYid+Fpp/2F5EbtildpeoZh5HdgnGs+jZ03nqQEQW8yGkt4BGyOC3OMPDQQRl8M5kqD2/g6jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@oxc-project/types": "^0.133.0" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxc-parser/binding-android-arm-eabi": "0.133.0", - "@oxc-parser/binding-android-arm64": "0.133.0", - "@oxc-parser/binding-darwin-arm64": "0.133.0", - "@oxc-parser/binding-darwin-x64": "0.133.0", - "@oxc-parser/binding-freebsd-x64": "0.133.0", - "@oxc-parser/binding-linux-arm-gnueabihf": "0.133.0", - "@oxc-parser/binding-linux-arm-musleabihf": "0.133.0", - "@oxc-parser/binding-linux-arm64-gnu": "0.133.0", - "@oxc-parser/binding-linux-arm64-musl": "0.133.0", - "@oxc-parser/binding-linux-ppc64-gnu": "0.133.0", - "@oxc-parser/binding-linux-riscv64-gnu": "0.133.0", - "@oxc-parser/binding-linux-riscv64-musl": "0.133.0", - "@oxc-parser/binding-linux-s390x-gnu": "0.133.0", - "@oxc-parser/binding-linux-x64-gnu": "0.133.0", - "@oxc-parser/binding-linux-x64-musl": "0.133.0", - "@oxc-parser/binding-openharmony-arm64": "0.133.0", - "@oxc-parser/binding-wasm32-wasi": "0.133.0", - "@oxc-parser/binding-win32-arm64-msvc": "0.133.0", - "@oxc-parser/binding-win32-ia32-msvc": "0.133.0", - "@oxc-parser/binding-win32-x64-msvc": "0.133.0" - } - }, - "node_modules/oxc-resolver": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.20.0.tgz", - "integrity": "sha512-CblytBiV/a/ZXY34dsVU2NxhIOxMXst8CvDCtyBelVITgd7PLrKzbEbA6oKLdPjvDKDzCiW48qzmzZ+mYaqn+g==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxc-resolver/binding-android-arm-eabi": "11.20.0", - "@oxc-resolver/binding-android-arm64": "11.20.0", - "@oxc-resolver/binding-darwin-arm64": "11.20.0", - "@oxc-resolver/binding-darwin-x64": "11.20.0", - "@oxc-resolver/binding-freebsd-x64": "11.20.0", - "@oxc-resolver/binding-linux-arm-gnueabihf": "11.20.0", - "@oxc-resolver/binding-linux-arm-musleabihf": "11.20.0", - "@oxc-resolver/binding-linux-arm64-gnu": "11.20.0", - "@oxc-resolver/binding-linux-arm64-musl": "11.20.0", - "@oxc-resolver/binding-linux-ppc64-gnu": "11.20.0", - "@oxc-resolver/binding-linux-riscv64-gnu": "11.20.0", - "@oxc-resolver/binding-linux-riscv64-musl": "11.20.0", - "@oxc-resolver/binding-linux-s390x-gnu": "11.20.0", - "@oxc-resolver/binding-linux-x64-gnu": "11.20.0", - "@oxc-resolver/binding-linux-x64-musl": "11.20.0", - "@oxc-resolver/binding-openharmony-arm64": "11.20.0", - "@oxc-resolver/binding-wasm32-wasi": "11.20.0", - "@oxc-resolver/binding-win32-arm64-msvc": "11.20.0", - "@oxc-resolver/binding-win32-x64-msvc": "11.20.0" - } - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-parser-stream": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", - "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", - "license": "MIT", - "dependencies": { - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/smol-toml": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz", - "integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 18" - }, - "funding": { - "url": "https://github.com/sponsors/cyyynthia" - } - }, - "node_modules/strip-json-comments": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", - "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", - "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/typescript": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", - "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/unbash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unbash/-/unbash-3.0.0.tgz", - "integrity": "sha512-FeFPZ/WFT0mbRCuydiZzpPFlrYN8ZUpphQKoq4EeElVIYjYyGzPMxQR/simUwCOJIyVhpFk4RbtyO7RuMpMnHA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - } - }, - "node_modules/undici": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.27.2.tgz", - "integrity": "sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==", - "license": "MIT", - "engines": { - "node": ">=20.18.1" - } - }, - "node_modules/undici-types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", - "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", - "dev": true, - "license": "MIT" - }, - "node_modules/walk-up-path": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-4.0.0.tgz", - "integrity": "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, - "node_modules/zod": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", - "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/examples/forge-sql-orm-example-ai/package.json b/examples/forge-sql-orm-example-ai/package.json deleted file mode 100644 index 4d7d10666..000000000 --- a/examples/forge-sql-orm-example-ai/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "jira-global-page-custom-ui", - "version": "1.1.4", - "main": "index.js", - "license": "MIT", - "private": true, - "dependencies": { - "@forge/resolver": "1.8.0", - "@forge/sql": "^3.0.25", - "drizzle-orm": "^0.45.2", - "forge-sql-orm": "^2.2.0" - }, - "scripts": { - "build:ci": "tsc --target esnext --project tsconfig.json --ignoreDeprecations 6.0 --outDir dist && rm -rf dist", - "forge:debug": "forge tunnel -d -f index.handler", - "build:husky": "tsc --project tsconfig.json --outDir ./dist && rm -rf ./dist", - "knip": "knip" - }, - "devDependencies": { - "@types/node": "^25.9.2", - "knip": "^6.16.1", - "typescript": "^6.0.3" - }, - "overrides": { - "package-json": "npm:package-json@latest", - "esbuild": "npm:esbuild@latest", - "parse-url": "npm:parsed-url@latest", - "gry": "npm:gry@latest" - } -} diff --git a/examples/forge-sql-orm-example-ai/src/entities/index.ts b/examples/forge-sql-orm-example-ai/src/entities/index.ts deleted file mode 100644 index 5203a1e8b..000000000 --- a/examples/forge-sql-orm-example-ai/src/entities/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -/** - * This file was auto-generated by forge-sql-orm - * Generated at: 2025-09-01T11:44:32.546Z - * - * DO NOT EDIT THIS FILE MANUALLY - * Any changes will be overwritten on next generation - */ - -export * from "./schema"; - -export interface VersionFieldMetadata { - fieldName: string; -} - -export interface TableMetadata { - tableName: string; - versionField: VersionFieldMetadata; -} - -export type AdditionalMetadata = Record; - -export const additionalMetadata: AdditionalMetadata = {}; diff --git a/examples/forge-sql-orm-example-ai/src/entities/schema.ts b/examples/forge-sql-orm-example-ai/src/entities/schema.ts deleted file mode 100644 index 545b7838e..000000000 --- a/examples/forge-sql-orm-example-ai/src/entities/schema.ts +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { int, mysqlTable, primaryKey, text, varchar } from "drizzle-orm/mysql-core"; -import { vectorTiDBType } from "forge-sql-orm"; - -export const embeddedDocuments = mysqlTable( - "embedded_documents", - { - id: int().autoincrement().notNull(), - document: text().notNull(), - title: varchar({ length: 255 }).notNull(), - embedding: vectorTiDBType("embedding", { dimension: 384 }).notNull(), - }, - (table) => [primaryKey({ columns: [table.id], name: "id" })], -); diff --git a/examples/forge-sql-orm-example-ai/src/index.ts b/examples/forge-sql-orm-example-ai/src/index.ts deleted file mode 100644 index 10ad0699c..000000000 --- a/examples/forge-sql-orm-example-ai/src/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import Resolver, { Request } from "@forge/resolver"; -import ForgeSQL, { formatLimitOffset } from "forge-sql-orm"; -import { dropSchemaMigrations, applySchemaMigrations, fetchSchemaWebTrigger } from "forge-sql-orm"; -import migration from "./migration"; -import { asc, InferInsertModel, InferSelectModel, sql } from "drizzle-orm"; -import { embeddedDocuments } from "./entities"; -import { vecCosineDistance } from "forge-sql-orm"; - -const resolver = new Resolver(); -const forgeSQL = new ForgeSQL({ logRawSqlQuery: false }); - -resolver.define( - "create", - async (req: Request<{ data: InferInsertModel }>): Promise => { - const payload = req.payload.data; - const res = await forgeSQL.insert(embeddedDocuments).values([payload]); - return res[0].insertId; - }, -); - -resolver.define("fetch", async (): Promise[]> => { - return await forgeSQL.selectFrom(embeddedDocuments); -}); - -resolver.define( - "search", - async ( - req: Request<{ vector: number[] }>, - ): Promise<{ id: number; title: string; document: string; distance: number }[]> => { - const vector = req.payload.vector; - const fieldAlias = sql.raw("distance"); - const distance = sql`${vecCosineDistance(embeddedDocuments.embedding, vector)} as \`${fieldAlias}\``; - return forgeSQL - .select({ - id: embeddedDocuments.id, - document: embeddedDocuments.document, - title: embeddedDocuments.title, - distance: distance, - }) - .from(embeddedDocuments) - .orderBy(asc(fieldAlias)) - .limit(formatLimitOffset(5)); - }, -); - -export const handler = resolver.getDefinitions(); - -export const handlerMigration = async () => { - return applySchemaMigrations(migration); -}; - -export const dropMigrations = () => { - return dropSchemaMigrations(); -}; - -export const fetchMigrations = () => { - return fetchSchemaWebTrigger(); -}; diff --git a/examples/forge-sql-orm-example-ai/src/migration/index.ts b/examples/forge-sql-orm-example-ai/src/migration/index.ts deleted file mode 100644 index e75a54004..000000000 --- a/examples/forge-sql-orm-example-ai/src/migration/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { MigrationRunner } from "@forge/sql/out/migration"; -import v1 from "./migrationV1"; - -export type MigrationType = (migrationRunner: MigrationRunner) => MigrationRunner; - -export default async (migrationRunner: MigrationRunner): Promise => { - v1(migrationRunner); - return migrationRunner; -}; diff --git a/examples/forge-sql-orm-example-ai/src/migration/migrationCount.ts b/examples/forge-sql-orm-example-ai/src/migration/migrationCount.ts deleted file mode 100644 index 474b88862..000000000 --- a/examples/forge-sql-orm-example-ai/src/migration/migrationCount.ts +++ /dev/null @@ -1,4 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -export const MIGRATION_VERSION = 1; diff --git a/examples/forge-sql-orm-example-ai/src/migration/migrationV1.ts b/examples/forge-sql-orm-example-ai/src/migration/migrationV1.ts deleted file mode 100644 index 48c976db6..000000000 --- a/examples/forge-sql-orm-example-ai/src/migration/migrationV1.ts +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import { MigrationRunner } from "@forge/sql/out/migration"; - -export default (migrationRunner: MigrationRunner): MigrationRunner => { - return migrationRunner.enqueue( - "v1_MIGRATION0", - "CREATE TABLE `embedded_documents` ( `id` int AUTO_INCREMENT NOT NULL, `document` text NOT NULL, `title` VARCHAR(255) NOT NULL, `embedding` VECTOR(384) NOT NULL, CONSTRAINT `id` PRIMARY KEY(`id`) )", - ); -}; diff --git a/examples/forge-sql-orm-example-ai/src/utils/Constants.ts b/examples/forge-sql-orm-example-ai/src/utils/Constants.ts deleted file mode 100644 index 172c972cb..000000000 --- a/examples/forge-sql-orm-example-ai/src/utils/Constants.ts +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -export interface UserResponse { - id: number; - name?: string | null; - email?: string | null; -} - -export interface DuplicateResponse { - count: number; - name: string; - email: string; -} - -export type SortType = { - name: string; - sortType: "ASC" | "DESC"; -}; diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/.env b/examples/forge-sql-orm-example-ai/static/forge-orm-example/.env deleted file mode 100644 index 39f757f47..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/.env +++ /dev/null @@ -1,2 +0,0 @@ -DISABLE_ESLINT_PLUGIN=true -BUILD_PATH='./build-static' diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/.gitignore b/examples/forge-sql-orm-example-ai/static/forge-orm-example/.gitignore deleted file mode 100644 index 3a606e231..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# dependencies -/node_modules - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/.ncurc.json b/examples/forge-sql-orm-example-ai/static/forge-orm-example/.ncurc.json deleted file mode 100644 index 732b93fcf..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/.ncurc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "reject": ["react", "react-dom", "@types/react", "@types/react-dom"] -} diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/index.html b/examples/forge-sql-orm-example-ai/static/forge-orm-example/index.html deleted file mode 100644 index d28549a43..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - forge-sql-orm example - - - - -
- - diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/knip.config.ts b/examples/forge-sql-orm-example-ai/static/forge-orm-example/knip.config.ts deleted file mode 100644 index 595f650dc..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/knip.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import type { KnipConfig } from "knip"; -import { exampleConfig as defaultConfig } from "../../../knip.config"; -const config: KnipConfig = { - ...defaultConfig, - project: ["src/*.{ts,tsx}"], - ignoreDependencies: ["prettier-plugin-pkg"], -}; - -export default config; diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/package-lock.json b/examples/forge-sql-orm-example-ai/static/forge-orm-example/package-lock.json deleted file mode 100644 index 0a3995999..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/package-lock.json +++ /dev/null @@ -1,5768 +0,0 @@ -{ - "name": "forge_sql_orm_example_frontend", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "forge_sql_orm_example_frontend", - "version": "1.0.0", - "dependencies": { - "@atlaskit/button": "^23.11.8", - "@atlaskit/css-reset": "^7.4.5", - "@atlaskit/dynamic-table": "^18.4.2", - "@atlaskit/primitives": "^19.0.2", - "@atlaskit/section-message": "^8.13.0", - "@atlaskit/spinner": "^19.1.2", - "@atlaskit/tabs": "^19.1.0", - "@atlaskit/textarea": "^8.3.2", - "@atlaskit/textfield": "^8.3.2", - "@forge/bridge": "^5.16.2", - "@huggingface/transformers": "^4.2.0", - "react": "^18.3.1", - "react-dom": "^18.3.1" - }, - "devDependencies": { - "@types/jest": "^30.0.0", - "@types/node": "^25.9.2", - "@types/react": "^18.3.1", - "@types/react-dom": "^18.3.1", - "@vitejs/plugin-react": "^6.0.2", - "dotenv": "17.4.2", - "knip": "^6.16.1", - "prettier": "^3.8.3", - "prettier-plugin-pkg": "^0.22.1", - "typescript": "^6.0.3", - "vite": "^8.0.16" - } - }, - "node_modules/@atlaskit/adf-schema": { - "version": "48.0.0", - "resolved": "https://registry.npmjs.org/@atlaskit/adf-schema/-/adf-schema-48.0.0.tgz", - "integrity": "sha512-zzPhx1zsiAL2zSR9APrw6CMNxAGMerjjNgc0AeqQWZjSuh4U18THv77o4buS9QPdUn2S8BztBNiEbB7bP9wNRw==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/editor-prosemirror": "*", - "@atlaskit/feature-gate-js-client": "^4.26.4", - "@babel/runtime": "^7.0.0", - "css-color-names": "0.0.4", - "linkify-it": "^2.0.3", - "memoize-one": "^6.0.0" - } - }, - "node_modules/@atlaskit/adf-schema/node_modules/@atlaskit/atlassian-context": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@atlaskit/atlassian-context/-/atlassian-context-0.2.0.tgz", - "integrity": "sha512-msLRSp0qck6eflkShplgyIoOogNKxKRc6QIWGQlSvKGxHQNEbLEkRGcDzdh8PuBxSs1gda7OqYrdtQYQiPbpTQ==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/adf-schema/node_modules/@atlaskit/feature-gate-js-client": { - "version": "4.26.5", - "resolved": "https://registry.npmjs.org/@atlaskit/feature-gate-js-client/-/feature-gate-js-client-4.26.5.tgz", - "integrity": "sha512-ZCcw7GP6WapqfP18Hr4q5+AZuI1k6pJECL9tyIw64JwG0GntMa3tTj/T8c5aqBIOagRQTw24lkM+Nt+agrRcnA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/atlassian-context": "^0.2.0", - "@babel/runtime": "^7.0.0", - "@statsig/client-core": "^3.10.0", - "@statsig/js-client": "^3.10.0", - "eventemitter2": "^4.1.0" - } - }, - "node_modules/@atlaskit/analytics-next": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@atlaskit/analytics-next/-/analytics-next-11.3.0.tgz", - "integrity": "sha512-UDTl1YSRz7QCFXxTXctgsbVjXMVIIaoyqpH7SAZw2CRjKeTuihljtxBuv0C2EX5hocPS6b2KZKCwA4yEXHWozQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/analytics-next-stable-react-context": "1.0.1", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@babel/runtime": "^7.0.0", - "prop-types": "^15.5.10", - "use-memo-one": "^1.1.1" - }, - "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, - "node_modules/@atlaskit/analytics-next-stable-react-context": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@atlaskit/analytics-next-stable-react-context/-/analytics-next-stable-react-context-1.0.1.tgz", - "integrity": "sha512-iO6+hIp09dF4iAZQarVz3vKY1kM5Ij5CExYcK9jgc2q+OH8nv8n+BPFeJTdzGOGopmbUZn5Opj9pYQvge1Gr4Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.0.0" - }, - "peerDependencies": { - "react": "^16.8.0" - } - }, - "node_modules/@atlaskit/app-provider": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@atlaskit/app-provider/-/app-provider-4.3.3.tgz", - "integrity": "sha512-hVOEl1VqwgUGVZOMfQsKIyg3DH7rYh/8qY5BXJuRKqw8Vn3ybexnkyeduQbfCP4rzLUnUUQCVhMxvTZhe+mDOw==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/browser-apis": "^0.0.2", - "@atlaskit/css": "^0.19.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "bind-event-listener": "^3.0.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/atlassian-context": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@atlaskit/atlassian-context/-/atlassian-context-0.10.0.tgz", - "integrity": "sha512-4/cWFp+mxIYqPmcn3NSHf/JNL/8bRx0/+lpFTsc1C5nfjyyeuFG18pDQBtNn6kMDjGLAt06TSXEgwZV+P4zmGg==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0" - }, - "peerDependencies": { - "react": "^18.2.0 || ^19.0.0" - } - }, - "node_modules/@atlaskit/browser-apis": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@atlaskit/browser-apis/-/browser-apis-0.0.2.tgz", - "integrity": "sha512-3mfBAVBx8ReUlILUGdsc+G1JlrA0DvFAbOMorJfsIvsOqJViABxjQyW05psbnLoLZD/CT3+9jCHSHOIY8Gwtyw==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/button": { - "version": "23.11.8", - "resolved": "https://registry.npmjs.org/@atlaskit/button/-/button-23.11.8.tgz", - "integrity": "sha512-ptEGHRfBLmEigbD2t0PkrZkQxMPtyuS6rtfW6htGQo3c+nilap85qNxZtkdOVfO3oPYTssVnOD663rnbd/CHnA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/analytics-next": "^11.2.0", - "@atlaskit/css": "^0.19.0", - "@atlaskit/ds-lib": "^7.0.0", - "@atlaskit/focus-ring": "^3.1.0", - "@atlaskit/icon": "^35.1.0", - "@atlaskit/interaction-context": "^3.1.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/primitives": "^19.0.0", - "@atlaskit/spinner": "^19.1.0", - "@atlaskit/theme": "^25.0.0", - "@atlaskit/tokens": "^13.0.0", - "@atlaskit/tooltip": "^22.3.0", - "@atlaskit/visually-hidden": "^3.1.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0", - "@emotion/react": "^11.7.1" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/css": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@atlaskit/css/-/css-0.19.4.tgz", - "integrity": "sha512-OBacSDD/XBkuu4R2FFMgOoVifSbs7E4LRwqUJFolPurxnsc88/cDrwf9C3obMwDh+64O3a5OyzuUPLVQTfMXYQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/css-reset": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@atlaskit/css-reset/-/css-reset-7.4.5.tgz", - "integrity": "sha512-EhjZCQwobc/u56l68abWFmvyg2T2ImbsUdqtBj78oQA3qI4As159ilX6Vxr20bR26OYL6unN8Dk9K5uJRKRiBQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/ds-lib": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@atlaskit/ds-lib/-/ds-lib-7.0.0.tgz", - "integrity": "sha512-Uqywr6YMi6uBpD0BtbRmG8f81fteRT7NBf62J8zzWPSs7u3Jq9G3Oruwm3y+57Dxv6IqfRwrS10WJARlCJdBLw==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0", - "bind-event-listener": "^3.0.0", - "tiny-invariant": "^1.2.0" - }, - "peerDependencies": { - "react": "^18.2.0 || ^19.0.0" - } - }, - "node_modules/@atlaskit/dynamic-table": { - "version": "18.4.2", - "resolved": "https://registry.npmjs.org/@atlaskit/dynamic-table/-/dynamic-table-18.4.2.tgz", - "integrity": "sha512-RkiMCuJ6tjhKhU8GYc/n+EyMR7mwF7zTY96bMXcQTwy+sVQufcDzwwwT1NZHOubCPxrNlURcqDpDVhNMEuEDnw==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/analytics-next": "^11.2.0", - "@atlaskit/css": "^0.19.0", - "@atlaskit/ds-lib": "^7.0.0", - "@atlaskit/icon": "^35.0.0", - "@atlaskit/pagination": "^16.3.0", - "@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-migration": "^2.1.0", - "@atlaskit/primitives": "^19.0.0", - "@atlaskit/spinner": "^19.1.0", - "@atlaskit/tokens": "^13.0.0", - "@atlaskit/tooltip": "^22.2.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, - "node_modules/@atlaskit/editor-prosemirror": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@atlaskit/editor-prosemirror/-/editor-prosemirror-7.3.0.tgz", - "integrity": "sha512-6KB4CuURZ+fU1DJMlmCox6q8T5ooVaCE+eZVrAlcODIfTyLu/wCvJfPJLOJUPZBvzCHqoWCebFmpu39uwUUleg==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0", - "prosemirror-commands": "1.7.1", - "prosemirror-dropcursor": "1.8.2", - "prosemirror-history": "1.5.0", - "prosemirror-keymap": "1.2.3", - "prosemirror-markdown": "1.13.2", - "prosemirror-model": "1.25.4", - "prosemirror-state": "1.4.4", - "prosemirror-transform": "1.10.5", - "prosemirror-utils": "1.2.2", - "prosemirror-view": "1.41.5" - } - }, - "node_modules/@atlaskit/feature-gate-js-client": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@atlaskit/feature-gate-js-client/-/feature-gate-js-client-5.7.2.tgz", - "integrity": "sha512-82ItxZN7aVftw2AVV/JY8wU7Z4Zmmv4rquSEWNTzsjh3/5vjPi2Rfo6iCzRqJjpg/8eNQWOZ5Pq3oL9IPfz2vA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/atlassian-context": "^0.10.0", - "@babel/runtime": "^7.0.0", - "@statsig/client-core": "^3.27.0", - "@statsig/js-client": "^3.27.0", - "eventemitter3": "^4.0.0" - } - }, - "node_modules/@atlaskit/focus-ring": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@atlaskit/focus-ring/-/focus-ring-3.1.0.tgz", - "integrity": "sha512-mrXeeqrV0wVnru59ZfRBG9VitjQA13roEiwU4efOHM/mHGrkWsFiCTdmwJAJklyBddiemUTM08I/+Av+QHHBag==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@emotion/react": "^11.7.1" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/heading": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@atlaskit/heading/-/heading-5.4.2.tgz", - "integrity": "sha512-B4SMRq9sq3WWJYLo8Nx5731LvAjiev6dT3SbK1/dqSM+HXnrAy6GwEhW3oDJefeWYO7eZ9xPfuC3jpjdNBgxoA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/primitives": "^19.0.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/icon": { - "version": "35.4.0", - "resolved": "https://registry.npmjs.org/@atlaskit/icon/-/icon-35.4.0.tgz", - "integrity": "sha512-zE8DtQVaPTL3H6OSOwtgDihal0d5As/J3f4W2gzVLn9gOv24sFMlFC/GEEuotyYOFFwS7+NeT2pVqOi2IRv17g==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/tile": "^1.1.0", - "@atlaskit/tokens": "^13.1.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/interaction-context": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@atlaskit/interaction-context/-/interaction-context-3.1.0.tgz", - "integrity": "sha512-LB3T0ATpJ5y7/IVBndNbcjtaNmPcz/8k7+smMibzphmV7xB3HaIyJFEu2JoSmgps66qLXo0ia8Hj7v4dF9zJZw==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/layering": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@atlaskit/layering/-/layering-3.8.0.tgz", - "integrity": "sha512-PmwwvOuj2VhHU+LLsAwFl2VptWNn1aSuSoTXwsC0ZedV4M2WDr0yn0Z3ex0JGq7Za+6VOZsVhiBVW2jXW9a+0A==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0", - "bind-event-listener": "^3.0.0", - "tiny-invariant": "^1.2.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/link": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@atlaskit/link/-/link-3.4.2.tgz", - "integrity": "sha512-Y2aItT5nfxQhJu7RzgwKQImMp50aq58M3ccbTuqElnNNK7QHde37Hrvtxpia7WLwvJOpKYmxJnaM9yxbkDsYKQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/css": "^0.19.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/primitives": "^19.0.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/motion": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@atlaskit/motion/-/motion-6.2.5.tgz", - "integrity": "sha512-cYKzj5cS6nxF0lmfxXBRvYmmTys3SAYkLIl29z6/hFNELs4LpU+13CGtJz/0+lDl7X4Lnt5QWjrCJdoeoACKGA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/browser-apis": "^0.0.2", - "@atlaskit/css": "^0.19.0", - "@atlaskit/ds-lib": "^7.0.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/tokens": "^13.1.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0", - "bind-event-listener": "^3.0.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/pagination": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@atlaskit/pagination/-/pagination-16.3.1.tgz", - "integrity": "sha512-lAJUAhD0TEKII+5bv6WOb3ysSrXzhmNcQ6JblnqhrkfQ3lKwfvtE3LBu4soj4AqflYoSSZFZ3CGXntnpMgbugQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/analytics-next": "^11.2.0", - "@atlaskit/button": "^23.11.0", - "@atlaskit/css": "^0.19.0", - "@atlaskit/ds-lib": "^7.0.0", - "@atlaskit/icon": "^35.0.0", - "@atlaskit/primitives": "^19.0.0", - "@atlaskit/tokens": "^13.0.0", - "@atlaskit/visually-hidden": "^3.1.0", - "@babel/runtime": "^7.0.0", - "memoize-one": "^6.0.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/platform-feature-flags": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@atlaskit/platform-feature-flags/-/platform-feature-flags-1.1.3.tgz", - "integrity": "sha512-dRn6UvVmMF5+WXnv7ZlxKTV2rVQncI2TgM0KTGSqpHdD9LnogITWC/rFjzUuF/W8MBCEvpouGilukqhq6rASnw==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/feature-gate-js-client": "^5.5.0", - "@babel/runtime": "^7.0.0" - } - }, - "node_modules/@atlaskit/popper": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@atlaskit/popper/-/popper-7.2.0.tgz", - "integrity": "sha512-Uw2dzPblwwfYxs5VYIKhOCkwG1tSbmw+sALylsdCTXlVqKWHVxaNzZ24RCglol2BO5QUAT+YAZh1jbjgXyH8mQ==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0", - "@popperjs/core": "^2.11.8", - "react-popper": "^2.3.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/portal": { - "version": "5.5.6", - "resolved": "https://registry.npmjs.org/@atlaskit/portal/-/portal-5.5.6.tgz", - "integrity": "sha512-sB+31TrDA/r6daytYawF1zGJoVG/hbfhosGIu2gKmg/8KM/waNGVYd2HlUPGmhbuFKxT5P+NbIAbOF/zHffnaQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/app-provider": "^4.3.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/theme": "^25.0.0", - "@babel/runtime": "^7.0.0" - }, - "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, - "node_modules/@atlaskit/pragmatic-drag-and-drop": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop/-/pragmatic-drag-and-drop-1.8.1.tgz", - "integrity": "sha512-uXWNPpL8n4OmTVbduH7nq8pk8htqGo/prR5cYEE8sVCPJGAUMWn6lzvWTfI+4VCeQvHiDRODVz4YzH06OVAxhw==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0", - "bind-event-listener": "^3.0.0", - "raf-schd": "^4.0.3" - } - }, - "node_modules/@atlaskit/pragmatic-drag-and-drop-hitbox": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop-hitbox/-/pragmatic-drag-and-drop-hitbox-1.2.0.tgz", - "integrity": "sha512-eWJvvuHZOC4Yk+Li7QpS+JM2F/I50/3PhMvEcyvcHbXI0FP0kCDD1MiF8Hv7uSOxpk5JNqKoOmK8e1ncOzTgqA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/pragmatic-drag-and-drop": "^1.8.0", - "@babel/runtime": "^7.0.0" - } - }, - "node_modules/@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll/-/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll-2.0.2.tgz", - "integrity": "sha512-lo4x9p7DAq3WeCknHXqkCNmzSMvyKfucl1BFF6K22BjdiRd+DavBwt4aGUQBGnIPGwZgNKrjmwAFj9xuYdLZDQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/pragmatic-drag-and-drop": "^1.7.0", - "@babel/runtime": "^7.0.0", - "css-box-model": "^1.2.0" - } - }, - "node_modules/@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-migration": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-migration/-/pragmatic-drag-and-drop-react-beautiful-dnd-migration-2.1.1.tgz", - "integrity": "sha512-l/NIcq2VPbYyy78MMCsfuG3EoHynHytoXm6gB6/O42Y1npcDn1SkxAtblAF0vf3aw1G1rx6TioDBI26KvRg0RQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/pragmatic-drag-and-drop": "^1.8.0", - "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0", - "@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll": "^2.0.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@emotion/react": "^11.7.1", - "bind-event-listener": "^3.0.0", - "tiny-invariant": "^1.2.0" - }, - "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, - "node_modules/@atlaskit/primitives": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/@atlaskit/primitives/-/primitives-19.0.2.tgz", - "integrity": "sha512-vMp2L8NhNeEkDj26GtVeynx8yC//uhfzVgxgI06dpHQ2gTV/jZidaNGOWjXslCrOpfgZckAAG3x2JamT/95XGw==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/analytics-next": "^11.3.0", - "@atlaskit/app-provider": "^4.3.0", - "@atlaskit/css": "^0.19.0", - "@atlaskit/ds-lib": "^7.0.0", - "@atlaskit/interaction-context": "^3.1.0", - "@atlaskit/tokens": "^13.2.0", - "@atlaskit/visually-hidden": "^3.1.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0", - "@emotion/react": "^11.7.1", - "@emotion/serialize": "^1.1.0", - "bind-event-listener": "^3.0.0", - "tiny-invariant": "^1.2.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/section-message": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@atlaskit/section-message/-/section-message-8.13.0.tgz", - "integrity": "sha512-tibMfW9dY1IcFnupBIP1UIkVwaud3A5mwfHHrSxyFBV1fVhhvccS0WlLvMXceu3cui20Y6tB1CQzCR4mB8f+og==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/button": "^23.11.0", - "@atlaskit/css": "^0.19.0", - "@atlaskit/heading": "^5.4.0", - "@atlaskit/icon": "^35.0.0", - "@atlaskit/link": "^3.4.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/primitives": "^19.0.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/skeleton": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/@atlaskit/skeleton/-/skeleton-2.1.10.tgz", - "integrity": "sha512-VisOKpPhJfbixdZIoc8P2/yFR8qwmLr2F7oQqXc8cwOmJ9JZ+foyggp2+y++vVyvVKZFU194OGNzoI3Z1B/FfQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/spinner": { - "version": "19.1.2", - "resolved": "https://registry.npmjs.org/@atlaskit/spinner/-/spinner-19.1.2.tgz", - "integrity": "sha512-Z2zOdi+zNd2qn8BrKOcxmHdlhcA1mNi3gGPklqW2MY+Ch/zL8WBTLia8KL5dIFwLjLG9C2J1u8OTYvtrZrhDhA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/interaction-context": "^3.1.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/tabs": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@atlaskit/tabs/-/tabs-19.1.0.tgz", - "integrity": "sha512-Pzxg6lZWnXFq8kt++qA5zIznEAfgf9zyQU0mSuDN4O5hDcsfhs9rwGAxgjCszxuVOJNnh+DfBd+mjB1847SF3A==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/analytics-next": "^11.2.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/primitives": "^19.0.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/textarea": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@atlaskit/textarea/-/textarea-8.3.2.tgz", - "integrity": "sha512-HeVjb0ur18Go29fKMBZJpUFYwjUUVrxvBxsuvA/wwYvgzvr9DDwDS5Wx6vBDIiBOwND8YHYHC8cr+fmaSPBZ7w==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/analytics-next": "^11.2.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/primitives": "^19.0.0", - "@atlaskit/theme": "^25.0.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/textfield": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@atlaskit/textfield/-/textfield-8.3.2.tgz", - "integrity": "sha512-rj+XIWl1mh8CEj8DeVlEiMBaAnUTeCgtLiNfqsQxzvsaeLI+/YgIQqTsVpslLKhhiAyCI/bDW076PreNywpCiQ==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/analytics-next": "^11.2.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/theme": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/@atlaskit/theme/-/theme-25.0.0.tgz", - "integrity": "sha512-zZFJla2cDQg9hM87L1AiSy6SvgYWyZQ2uw/bWLV6Cb/anat2/NVtQ9fxlOpVrCiq8yVZEnJNaY97gFQ8mL9lzA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/ds-lib": "^7.0.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/tile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@atlaskit/tile/-/tile-1.1.0.tgz", - "integrity": "sha512-ZvFITAzYx4IUV+V7OsLrdM1Hic9WQfK4nIebG4dHasssBjsJfdVQmLDsR/lHbop24cFENI4x/D75LcMtr+kQew==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/skeleton": "^2.1.0", - "@atlaskit/tokens": "^13.0.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@atlaskit/tokens": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@atlaskit/tokens/-/tokens-13.2.0.tgz", - "integrity": "sha512-yvLe1Pl7zDMuchE9/taZ7mKnACoktDeKMkwItvQUK1bQOlsKWVj3nMTFM3bZX4Aihmolq2Te1pdEiMuW0/pO7w==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/ds-lib": "^7.0.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@babel/runtime": "^7.0.0", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.20.0", - "bind-event-listener": "^3.0.0" - }, - "peerDependencies": { - "react": "^18.2.0 || ^19.0.0" - } - }, - "node_modules/@atlaskit/tooltip": { - "version": "22.6.0", - "resolved": "https://registry.npmjs.org/@atlaskit/tooltip/-/tooltip-22.6.0.tgz", - "integrity": "sha512-lZyzAPk0S6H9HHBN7GclSXq7oh9suDFbaGdDUfXd4sT+4Gqqh15ceY0g0/qzCL8PHrpff8wIc38koampKoDXaw==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/analytics-next": "^11.2.0", - "@atlaskit/ds-lib": "^7.0.0", - "@atlaskit/layering": "^3.7.0", - "@atlaskit/motion": "^6.2.0", - "@atlaskit/platform-feature-flags": "^1.1.0", - "@atlaskit/popper": "^7.2.0", - "@atlaskit/portal": "^5.5.0", - "@atlaskit/theme": "^25.0.0", - "@atlaskit/tokens": "^13.1.0", - "@atlaskit/top-layer": "^0.13.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0", - "bind-event-listener": "^3.0.0" - }, - "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, - "node_modules/@atlaskit/top-layer": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@atlaskit/top-layer/-/top-layer-0.13.0.tgz", - "integrity": "sha512-fza/XD2ndYUlpmxS7t3i+qrh/TgsCpEGDyeD+tTlMtHySuZYmja91xjnzSUY+sNkYjTgKXf5YB8+rz8bkxsHrA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/browser-apis": "^0.0.2", - "@atlaskit/css": "^0.19.0", - "@atlaskit/ds-lib": "^7.0.0", - "@atlaskit/layering": "^3.7.0", - "@atlaskit/tokens": "^13.1.0", - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0", - "bind-event-listener": "^3.0.0", - "raf-schd": "^4.0.3" - }, - "peerDependencies": { - "react": "^18.2.0 || ^19.0.0", - "react-dom": "^18.2.0 || ^19.0.0" - } - }, - "node_modules/@atlaskit/visually-hidden": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@atlaskit/visually-hidden/-/visually-hidden-3.1.0.tgz", - "integrity": "sha512-OpwLmUZhbbo3NHKDjLl9JzKdHroeLPzRS1HTyHubJkC5DUWoOAH4cXStMpoesZ/Fqmbyz8O0Wb4K8RzpNZ7Jmw==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0", - "@compiled/react": "^0.20.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", - "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.29.7", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", - "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.7", - "@babel/types": "^7.29.7", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", - "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", - "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.29.7", - "@babel/types": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", - "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", - "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", - "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.7" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", - "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/parser": "^7.29.7", - "@babel/types": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", - "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.7", - "@babel/helper-globals": "^7.29.7", - "@babel/parser": "^7.29.7", - "@babel/template": "^7.29.7", - "@babel/types": "^7.29.7", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", - "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.29.7", - "@babel/helper-validator-identifier": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@compiled/react": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@compiled/react/-/react-0.20.0.tgz", - "integrity": "sha512-mEJuYGFxIDST1H7CpksyE6a3HRVRQmeDal26O+bCHTEZlPp7iKvs5KD1FOmd2palng+S60dPFFG+UuoZDRILwA==", - "license": "Apache-2.0", - "dependencies": { - "csstype": "^3.2.3" - }, - "peerDependencies": { - "react": ">=18.0.0" - } - }, - "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emotion/babel-plugin": { - "version": "11.13.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", - "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/serialize": "^1.3.3", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", - "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", - "license": "MIT", - "dependencies": { - "@emotion/memoize": "^0.9.0", - "@emotion/sheet": "^1.4.0", - "@emotion/utils": "^1.4.2", - "@emotion/weak-memoize": "^0.4.0", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", - "license": "MIT" - }, - "node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", - "license": "MIT" - }, - "node_modules/@emotion/react": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", - "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.13.5", - "@emotion/cache": "^11.14.0", - "@emotion/serialize": "^1.3.3", - "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", - "@emotion/utils": "^1.4.2", - "@emotion/weak-memoize": "^0.4.0", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/serialize": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", - "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", - "license": "MIT", - "dependencies": { - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.10.0", - "@emotion/utils": "^1.4.2", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/sheet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", - "license": "MIT" - }, - "node_modules/@emotion/unitless": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", - "license": "MIT" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", - "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", - "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", - "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", - "license": "MIT" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", - "license": "MIT" - }, - "node_modules/@forge/bridge": { - "version": "5.16.2", - "resolved": "https://registry.npmjs.org/@forge/bridge/-/bridge-5.16.2.tgz", - "integrity": "sha512-WJsoIKCHL0ew+3itbiRnrgJVR2+a1EfiJoXYf9yH/Jg0qqHqUDhOk7Pgy3S2WLO7cIvOzgx7Uk8PLLb7GeIpfA==", - "license": "SEE LICENSE IN LICENSE.txt", - "dependencies": { - "@atlaskit/adf-schema": "^48.0.0", - "@atlaskit/tokens": "^1.58.0", - "@forge/egress": "^2.3.2", - "@forge/i18n": "0.0.7", - "@forge/manifest": "12.8.0", - "@forge/resolver": "1.8.0", - "@types/history": "^4.7.11", - "@types/iframe-resizer": "^3.5.8", - "iframe-resizer": "^4.4.5" - } - }, - "node_modules/@forge/bridge/node_modules/@atlaskit/ds-lib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@atlaskit/ds-lib/-/ds-lib-2.7.0.tgz", - "integrity": "sha512-+U4aPE2dBRFUBYWCM9vkrwJGrLAYVcK30ZpEiQDNpM2D7K41223TfEijC8azaN4VM3tsCgwSKBWwniloNxqYbA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/platform-feature-flags": "^0.3.0", - "@babel/runtime": "^7.0.0", - "bind-event-listener": "^3.0.0", - "react-uid": "^2.2.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@forge/bridge/node_modules/@atlaskit/platform-feature-flags": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@atlaskit/platform-feature-flags/-/platform-feature-flags-0.3.0.tgz", - "integrity": "sha512-/0u5fFJ0Rw2j4M5wzsXgaHO6Ey12oekPCDTRvmmAIp4GO9T2Swbl80bavLAPSOmSHMhHTSuvRxiJveZXfQ21IQ==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.0.0" - } - }, - "node_modules/@forge/bridge/node_modules/@atlaskit/tokens": { - "version": "1.61.0", - "resolved": "https://registry.npmjs.org/@atlaskit/tokens/-/tokens-1.61.0.tgz", - "integrity": "sha512-gRkBDZOaQffJHg9g+hYFgPjQ0Hz4XIDaK5WEttIGyhi2USsGsvDvUeED8liqcQNwssH/5UFxIFp3FmEwo0DoFA==", - "license": "Apache-2.0", - "dependencies": { - "@atlaskit/ds-lib": "^2.6.0", - "@atlaskit/platform-feature-flags": "^0.3.0", - "@babel/runtime": "^7.0.0", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.20.0", - "bind-event-listener": "^3.0.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@forge/egress": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@forge/egress/-/egress-2.3.2.tgz", - "integrity": "sha512-p8ioX4qnAlRFln+hyH9kO0MmVCSOUg0bsIG9RAYK8KM2YaJb6EnKqbCvPMBTwegiua3vixBsnZmWDgPegSZh9Q==", - "license": "SEE LICENSE IN LICENSE.txt" - }, - "node_modules/@forge/i18n": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@forge/i18n/-/i18n-0.0.7.tgz", - "integrity": "sha512-EKrQApcuI4k4AkUSeERkZv1dQaGjWsmB8i7ciDPtpDARPRH1sOrU+FSEOoA7b9FQ15++7Q144m94w/aMLCg5Gg==", - "license": "SEE LICENSE IN LICENSE.txt", - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/@forge/manifest": { - "version": "12.8.0", - "resolved": "https://registry.npmjs.org/@forge/manifest/-/manifest-12.8.0.tgz", - "integrity": "sha512-BiJC1jQSKxF/4if9jaKSy/6BhIVkbV6yo9MPs+2CSAS/RuKn2qG4z4i48hKxpHj1acS0pM8MUq82xXGNINimBA==", - "license": "SEE LICENSE IN LICENSE.txt", - "dependencies": { - "@forge/i18n": "0.0.7", - "@sentry/node": "7.106.0", - "ajv": "^8.18.0", - "ajv-formats": "2.1.1", - "cheerio": "^1.1.0", - "glob": "^13.0.0", - "lodash": "^4.17.21", - "mime-types": "^2.1.35", - "yaml": "^2.3.4" - } - }, - "node_modules/@forge/resolver": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@forge/resolver/-/resolver-1.8.0.tgz", - "integrity": "sha512-n9u8zAijT+MQLogo72xplFLZzcM7BDhQ9tW7qYZFS58/ZHtju76rVupBzSReeCxvo5lL2JTXB9mnFh2N8p2xyw==", - "license": "SEE LICENSE IN LICENSE.txt" - }, - "node_modules/@huggingface/jinja": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.5.9.tgz", - "integrity": "sha512-uWTG+l3VJRsl7EXxYizuL3P+cCPoc3cRqbWWRcQN0FhejRfbdq0RNhCmbY/YDtnTcz9icdLYuLDjsnz4d8JMuw==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@huggingface/tokenizers": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@huggingface/tokenizers/-/tokenizers-0.1.3.tgz", - "integrity": "sha512-8rF/RRT10u+kn7YuUbUg0OF30K8rjTc78aHpxT+qJ1uWSqxT1MHi8+9ltwYfkFYJzT/oS+qw3JVfHtNMGAdqyA==", - "license": "Apache-2.0" - }, - "node_modules/@huggingface/transformers": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@huggingface/transformers/-/transformers-4.2.0.tgz", - "integrity": "sha512-8BRCoBMH0XsWaEIamuR0LrJGAfftgHAfb2Vrffy0VKlSAE/MnUJ5/h/zTfEP3fDIft+nk7TqB8xXEyABGitBjQ==", - "license": "Apache-2.0", - "dependencies": { - "@huggingface/jinja": "^0.5.6", - "@huggingface/tokenizers": "^0.1.3", - "onnxruntime-node": "1.24.3", - "onnxruntime-web": "1.26.0-dev.20260416-b7804b056c", - "sharp": "^0.34.5" - } - }, - "node_modules/@img/colour": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", - "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", - "cpu": [ - "arm" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", - "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", - "cpu": [ - "arm" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", - "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.7.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@jest/diff-sequences": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", - "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", - "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" - } - }, - "node_modules/@oxc-parser/binding-android-arm-eabi": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.133.0.tgz", - "integrity": "sha512-l/44caGse+VpnY9gx0yvvc5QnnG3yG1FO3KZgYvNL1GZrfK86zIwAOgGEVlxDyRymzrU/KHiblPFpevKOmJmUA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-android-arm64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.133.0.tgz", - "integrity": "sha512-KUHmPMziLBp4u+zbrLdB7iWS7KshuZe+RAp7ELnY9SI9nNXBZ+dp8fiBqWOxhXqn+FQg3a4UcQhwmsJOKV8Jjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-darwin-arm64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.133.0.tgz", - "integrity": "sha512-q8dWmnU/8ea2tga9w2f1PinQ5rcMPDUGkF64T189b65YMjUomET4oy5oRldOr4AwOQkneOG/Zttnz1Dvrc62wg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-darwin-x64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.133.0.tgz", - "integrity": "sha512-cOKeIELIB2bJnCKwqx4Rdj+1Lss/U6uCbLxRySZrhyOOQa1flKhwZFjEHRHxk8fU1NKmhK5OnTdPQ4CpjuFuVw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-freebsd-x64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.133.0.tgz", - "integrity": "sha512-OpaSv4pW3KgFrMYQxTaS0aOE4T1DQF3qZE/4B6uqqv1KgPWWd4UQhJALi8PJPX1RRV5K7ThKXRfF7qGg2+3l1A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.133.0.tgz", - "integrity": "sha512-JGK1wlGrGwxBIlVSF7KWTX1/ru6BEtf28fRROztDRkLfiW+Kxa4onnriezMIiogfn9hVw2KzYcKiLjkLR2ns8A==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.133.0.tgz", - "integrity": "sha512-yuZO533Ftonxn/iyoqQzURzLQHMspvsIyfiCSNi1t/ER4eIQaR0SsmUOUm5b/lmSig7IWIUa5/BrbEkAPwcilQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm64-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.133.0.tgz", - "integrity": "sha512-hvpbqT5pN2rR+3+xtWeizwfR/aZ0vGceg6TqYMl+ToxMpk9/tmnX7kSvQnfEUkoua8mhogzvIKsAkn0wxgblBA==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm64-musl": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.133.0.tgz", - "integrity": "sha512-wJQGamIosQBoJHW9+S5XxrtKRo3eyJxsnS1XCPrqN0LHi8uw1pTqqTfn3t/NVuvbBg7Pumn4ez9Eidgcn0xbEg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-ppc64-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.133.0.tgz", - "integrity": "sha512-Koaz32/O5+abIfrNGdyndgRvdOZ9jEf5/z3Ep9h3h2QWpdDiUQpVwgH0OcMXCs+l9aXxPLtkupqyVig9W6FDKw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.133.0.tgz", - "integrity": "sha512-R4vOjWzxhnNWHnVLeiB6jNuIifdy9vcMXZGPc7StXcxBovI+U2zg1QhZ9o8OjV80oGivs1lX5NfPLzk4IPqlRA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-riscv64-musl": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.133.0.tgz", - "integrity": "sha512-iwgBNUTHiMdxARLYuM0SBlnYeb19iw1Ea5M+4ERZupCsBMLArti6FyZ6UfFjJxIiTDr2oW2DGQFxlQVQ/dW9rA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-s390x-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.133.0.tgz", - "integrity": "sha512-ZwZNo8FZmB/gVfboQl+wXilBigGl+6nQQs+nITOeAP/HcAOjiHl6XZJL9F/KXNEspODQcbjAiyjUbeCJd9a0fA==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-x64-gnu": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.133.0.tgz", - "integrity": "sha512-govCvWx1dBlED3uu4qXctxpRcouu9I8Kn+DBktGCl760JtlGJzc9l/OmPJKlYWSbrRqKkMZehNeZ/4Wfma7uSA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-x64-musl": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.133.0.tgz", - "integrity": "sha512-ssTlpXD5Mq9uCssDJPzlRWqBt4Y7Zzd9i+XZhWmK/9Y6KUIuAxVYTYiI8lxcGWi0+3/Cz4A8q9UrD4NK9Y2j7g==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-openharmony-arm64": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.133.0.tgz", - "integrity": "sha512-51aByfXhPtLEdWG4a2Ihdw6cPWV1ei1AarALpFdDP8MLWDLE2NuUMgbo3DERR2Kt8fT/ok1GUvBiLxVGke9uUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-wasm32-wasi": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.133.0.tgz", - "integrity": "sha512-2e16tkKp+wDO2GTAmXfxbBcCmGEaFPIJEIRBBmVKNVXSc8/fJsSIaBGyFTPHM9ST5GNWgJcYIt94rDTks+PLwA==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-win32-arm64-msvc": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.133.0.tgz", - "integrity": "sha512-KPTNDKbxH1cglrqTyVeXHb4Pk4oksz8EcE1/v8zqU7N4UXbiHfA/IwtXZ2U77fnRAWBbgVkl/lZbL7o3hRdejg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-win32-ia32-msvc": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.133.0.tgz", - "integrity": "sha512-Una1bNYv9zCavQrfnDR9wuZVB3itLjCEH4Oz7i6CwAJN/Xq9b+zbbcxmvdkKvvJt4Ngc/MBmIYlbLo3zS4TQ0A==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-win32-x64-msvc": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.133.0.tgz", - "integrity": "sha512-kjBhCiOGSYTwDJQuuZa7a94JbP8htWu7J0X1KwH74kV2K5eYf6eyJRYmkpCDvr0XEL8tMxYI4WU1VekblFCLgg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-project/types": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", - "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/@oxc-resolver/binding-android-arm-eabi": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm-eabi/-/binding-android-arm-eabi-11.20.0.tgz", - "integrity": "sha512-IjfWOXRgJFNdORDl+Uf1aibNgZY2guOD3zmOhx1BGVb/MIiqlFTdmjpQNplSN58lhWehnX4UNqC3QwpUo8pjJg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@oxc-resolver/binding-android-arm64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm64/-/binding-android-arm64-11.20.0.tgz", - "integrity": "sha512-QqslZAuFQG8Q9xm7JuIn8JUbvywhSBMVhuQHtYW+auirZJloS41oxUUaBXk7uUhZJgp44c5zQLeVvmFaDQB+2Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@oxc-resolver/binding-darwin-arm64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-11.20.0.tgz", - "integrity": "sha512-MUcavykj2ewlR+kc5arpg4tC2RvzJkUxWtNv74pf7lcNk00GpIpN43vXMj+j6r4eMmfZhlb8hueKoIb8e9kAGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oxc-resolver/binding-darwin-x64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-11.20.0.tgz", - "integrity": "sha512-BGB16nRUK5Etiv//ihPyzj8Lj1px0mhh4YIfe0FDf045ywknfSm0GEbiRESpr6Q4K82AvnyaRIhhluHByvS4bg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oxc-resolver/binding-freebsd-x64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-11.20.0.tgz", - "integrity": "sha512-JZgtePaqj3qmD5XFHJaSLWzHRxQu0LaPkdoM1KJXYADvAaa83ijXHclV3ej3CueeW0wxfIAbGCZVP45J0CA7uQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-11.20.0.tgz", - "integrity": "sha512-hOQ/p3ry3v3SchUBXicrrnszaI/UmYzM4wtS4RGfwgVUX7a+HbyQSzJ5aOzu+o6XZkFkS3ZXN4PZAzhOb77OSg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm-musleabihf": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-11.20.0.tgz", - "integrity": "sha512-2ArPksaw0AqeuGBfoS715VF+JvJQAhD2niWgjE5hVO+L+nAfikVQopvngCMX9x4BD8itWoQ3dnikrQyl5Ho5Jg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm64-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-11.20.0.tgz", - "integrity": "sha512-0bJnmYFp62JdZ4nVMDUZ/C58BCZOCcqgKtnUlp7L9Ojf/czIN+3j72YlLPeWLkzlr6SlYvIQA4SGV/HyO0d+qg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm64-musl": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-11.20.0.tgz", - "integrity": "sha512-wKHHzPKZo7Ufhv/Bt6yxT7FOgnIgW4gwXcJUipkShGp68W3wGVqvr1Sr0fY65lN0Oy6y41+g2kIDvkgZaMMUkw==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-ppc64-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-11.20.0.tgz", - "integrity": "sha512-RN8goF7Ie0B79L4i4G6OeBocTgSC56vJbQ65VJje+oXnldVpLnOU7j/AQ/dP94TcCS+Yh6WG8u3Qt4ETteXFNQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-riscv64-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-11.20.0.tgz", - "integrity": "sha512-5l1yU6/xQEqLZRzxqmMxJfWPslpwCmBsdDGaBvABPehxquCXDC7dd7oraNdKSJUMDXSM7VvVj8H2D2FTjU7oWw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-riscv64-musl": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-11.20.0.tgz", - "integrity": "sha512-xHEvkbgz6UC+A3JOyDQy76LkUaxsNSfIr3/GV8slwZsnuooJiIB34gzJfsyvR4JdCYNUUPsRJc/w/oWkODu+hg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-s390x-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-11.20.0.tgz", - "integrity": "sha512-aWPDUUmSeyHvlW+SoEUd+JIJsQhVhu6a5tBpDRMu058naPAchTgAVGCFy35zjbnFlt0i8hLWziff6HX0D3LU4g==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-x64-gnu": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-11.20.0.tgz", - "integrity": "sha512-x2YeSimvhJjKLVD8KSu8f/rqU1potcdEMkApIPJqjZWN7c2Fpt4g2X32WDg1p+XDAmyT7nuQGe0vnhvXeLbH+g==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-x64-musl": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-11.20.0.tgz", - "integrity": "sha512-kcRLEIxpZefeYfLChjpgFf3ilBzRDZ+yobMrpRsQlSrxuFGtm3U6PMU7AaEpMqo3NfDGVyJJseAjnRLzMFHjwQ==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-openharmony-arm64": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-openharmony-arm64/-/binding-openharmony-arm64-11.20.0.tgz", - "integrity": "sha512-HHcfnApSZGtKhTiHqe8OZruOZe5XuFQH5/E0Yhj3u8fnFvzkM4/k6WjacUf4SvA0SPEAbfbgYmVPuo0VX/fIBQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@oxc-resolver/binding-wasm32-wasi": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-11.20.0.tgz", - "integrity": "sha512-Tn0y1XOFYHNfK1wp1Z5QK8Rcld/bsOwRISQXfqAZ5IBpv8Gz1IvV39fUWNprqNdRizgcvFhOzWwFun2zkJsyBg==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@oxc-resolver/binding-win32-arm64-msvc": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-11.20.0.tgz", - "integrity": "sha512-qPi25YNPe4YenS8MgsQU2+bIFHxxpLx1LVna2444cEHqNPhNjvWf9zqj4aWE43H9LpAsTmkkAlA3eL5ElBU3mA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@oxc-resolver/binding-win32-x64-msvc": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.20.0.tgz", - "integrity": "sha512-Wb14jWEW8huH6It9F6sXd9vrYmIS7pMrgkU6sxpLxkP+9z+wRgs71hUEhRpcn8FOXAFa27FVWfY2tRpbfTzfLw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", - "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", - "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", - "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz", - "integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz", - "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==", - "license": "BSD-3-Clause" - }, - "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", - "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", - "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", - "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", - "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", - "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", - "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", - "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", - "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", - "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", - "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", - "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", - "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", - "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", - "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", - "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", - "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sentry-internal/tracing": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.106.0.tgz", - "integrity": "sha512-O8Es6Sa/tP80nfl+8soNfWzeRNFcT484SvjLR8BS3pHM9KDAlwNXyoQhFr2BKNYL1irbq6UF6eku4xCnUKVmqA==", - "license": "MIT", - "dependencies": { - "@sentry/core": "7.106.0", - "@sentry/types": "7.106.0", - "@sentry/utils": "7.106.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/core": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.106.0.tgz", - "integrity": "sha512-Dc13XtnyFaXup2E4vCbzuG0QKAVjrJBk4qfGwvSJaTuopEaEWBs2MpK6hRzFhsz9S3T0La7c1F/62NptvTUWsQ==", - "license": "MIT", - "dependencies": { - "@sentry/types": "7.106.0", - "@sentry/utils": "7.106.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/node": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.106.0.tgz", - "integrity": "sha512-4DIqbu5K7//lK/k2nV8lqKeGQzhu2T1OpJFmiUrjN6fUKWivGFjZrcmQDS7tvhAAyJezkL3LlrNU4tjPHUElPA==", - "license": "MIT", - "dependencies": { - "@sentry-internal/tracing": "7.106.0", - "@sentry/core": "7.106.0", - "@sentry/types": "7.106.0", - "@sentry/utils": "7.106.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/types": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.106.0.tgz", - "integrity": "sha512-oKTkDaL6P9xJC5/zHLRemHTWboUqRYjkJNaZCN63j4kJqGy56wee4vDtDese/NWWn4U4C1QV1h+Mifm2HmDcQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/utils": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.106.0.tgz", - "integrity": "sha512-bVsePsXLpFu/1sH4rpJrPcnVxW2fXXfGfGxKs6Bm+dkOMbuVTlk/KAzIbdjCDIpVlrMDJmMNEv5xgTFjgWDkjw==", - "license": "MIT", - "dependencies": { - "@sentry/types": "7.106.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@statsig/client-core": { - "version": "3.33.2", - "resolved": "https://registry.npmjs.org/@statsig/client-core/-/client-core-3.33.2.tgz", - "integrity": "sha512-TKZ546NfK2oShe1sHhgn+TaCoAWZ/bs0soK+gAjB/y5UAqWVhCcORAd/8eRUyor8Lz2VfL3V4Ze/zr1CCM2/5g==", - "license": "ISC" - }, - "node_modules/@statsig/js-client": { - "version": "3.33.2", - "resolved": "https://registry.npmjs.org/@statsig/js-client/-/js-client-3.33.2.tgz", - "integrity": "sha512-FgAnaN0d8X/OEZS/HEGI2D3CdbZzsbw3BHlSGvaqUcnwu45aXejFFUCCw96/NTH4lEvSMj1S1RBsrnQ2pVErgQ==", - "license": "ISC", - "dependencies": { - "@statsig/client-core": "3.33.2" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "license": "MIT" - }, - "node_modules/@types/iframe-resizer": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/iframe-resizer/-/iframe-resizer-3.5.13.tgz", - "integrity": "sha512-/Np2ntlOWd/NOHs23Mj7QlNEnZ6SL02AWWdYZLm4RQNukDdpqpagfMAdin5FvQDLngR8LWfh/qUnYxuDmR8BCg==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "30.0.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", - "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^30.0.0", - "pretty-format": "^30.0.0" - } - }, - "node_modules/@types/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "license": "MIT" - }, - "node_modules/@types/markdown-it": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", - "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", - "license": "MIT", - "dependencies": { - "@types/linkify-it": "^5", - "@types/mdurl": "^2" - } - }, - "node_modules/@types/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "25.9.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.2.tgz", - "integrity": "sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==", - "license": "MIT", - "dependencies": { - "undici-types": ">=7.24.0 <7.24.7" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "license": "MIT" - }, - "node_modules/@types/prop-types": { - "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "18.3.31", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz", - "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.3.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", - "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^18.0.0" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", - "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vitejs/plugin-react": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz", - "integrity": "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rolldown/pluginutils": "^1.0.0" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", - "babel-plugin-react-compiler": "^1.0.0", - "vite": "^8.0.0" - }, - "peerDependenciesMeta": { - "@rolldown/plugin-babel": { - "optional": true - }, - "babel-plugin-react-compiler": { - "optional": true - } - } - }, - "node_modules/adm-zip": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.17.tgz", - "integrity": "sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==", - "license": "MIT", - "engines": { - "node": ">=12.0" - } - }, - "node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/bind-event-listener": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-3.0.0.tgz", - "integrity": "sha512-PJvH288AWQhKs2v9zyfYdPzlPqf5bXbGMmhmUIY9x4dAUGIWgomO771oBQNwJnMQSnUIXhKu6sgzpBRXTlvb8Q==", - "license": "MIT" - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/cheerio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", - "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.2.2", - "encoding-sniffer": "^0.2.1", - "htmlparser2": "^10.1.0", - "parse5": "^7.3.0", - "parse5-htmlparser2-tree-adapter": "^7.1.0", - "parse5-parser-stream": "^7.1.2", - "undici": "^7.19.0", - "whatwg-mimetype": "^4.0.0" - }, - "engines": { - "node": ">=20.18.1" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "license": "MIT" - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cosmiconfig/node_modules/yaml": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", - "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/css-box-model": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", - "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", - "license": "MIT", - "dependencies": { - "tiny-invariant": "^1.0.6" - } - }, - "node_modules/css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/css-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "license": "MIT" - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dotenv": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", - "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/encoding-sniffer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", - "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", - "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.3", - "whatwg-encoding": "^3.1.1" - }, - "funding": { - "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eventemitter2": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-4.1.2.tgz", - "integrity": "sha512-erx0niBaTi8B7ywjGAcg8ilGNRl/xs/o4MO2ZMpRlpZ62mYzjGTBlOpxxRIrPQqBs9mbXkEux6aR+Sc5vQ/wUw==", - "license": "MIT" - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "license": "MIT" - }, - "node_modules/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fd-package-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fd-package-json/-/fd-package-json-2.0.0.tgz", - "integrity": "sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "walk-up-path": "^4.0.0" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "license": "MIT" - }, - "node_modules/flatbuffers": { - "version": "25.9.23", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", - "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", - "license": "Apache-2.0" - }, - "node_modules/formatly": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/formatly/-/formatly-0.3.0.tgz", - "integrity": "sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fd-package-json": "^2.0.0" - }, - "bin": { - "formatly": "bin/index.mjs" - }, - "engines": { - "node": ">=18.3.0" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-tsconfig": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", - "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "license": "BSD-3-Clause", - "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/guid-typescript": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", - "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==", - "license": "ISC" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", - "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/htmlparser2": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", - "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.2.2", - "entities": "^7.0.1" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", - "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/iframe-resizer": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/iframe-resizer/-/iframe-resizer-4.4.5.tgz", - "integrity": "sha512-U8bCywf/Gh07O69RXo6dXAzTtODQrxaHGHRI7Nt4ipXsuq6EMxVsOP/jjaP43YtXz/ibESS0uSVDN3sOGCzSmw==", - "hasInstallScript": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - }, - "funding": { - "type": "individual", - "url": "https://iframe-resizer.com//pricing" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, - "node_modules/is-core-module": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", - "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/jest-diff": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", - "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.4.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", - "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.4.1", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", - "picomatch": "^4.0.3", - "pretty-format": "30.4.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-mock": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.3" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jiti": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", - "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "license": "ISC" - }, - "node_modules/knip": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/knip/-/knip-6.16.1.tgz", - "integrity": "sha512-TKMn1rxgH6h9vXR9Y0B+Cq7AdPTr9EI02IwoT65NzqYUkvoDQAaJ/aPybiFpAhZ1px6cNYYwXf86iHkBgzCo9w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/webpro" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/knip" - } - ], - "license": "ISC", - "dependencies": { - "fdir": "^6.5.0", - "formatly": "^0.3.0", - "get-tsconfig": "4.14.0", - "jiti": "^2.7.0", - "oxc-parser": "^0.133.0", - "oxc-resolver": "^11.20.0", - "picomatch": "^4.0.4", - "smol-toml": "^1.6.1", - "strip-json-comments": "5.0.3", - "tinyglobby": "^0.2.16", - "unbash": "^3.0.0", - "yaml": "^2.9.0", - "zod": "^4.1.11" - }, - "bin": { - "knip": "bin/knip.js", - "knip-bun": "bin/knip-bun.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" - } - }, - "node_modules/lightningcss-android-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", - "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "license": "MIT", - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/lodash": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", - "license": "MIT" - }, - "node_modules/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "11.5.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", - "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/markdown-it": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz", - "integrity": "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/markdown-it" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.1", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.1.0" - }, - "bin": { - "markdown-it": "bin/markdown-it.mjs" - } - }, - "node_modules/markdown-it/node_modules/linkify-it": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz", - "integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/markdown-it" - } - ], - "license": "MIT", - "dependencies": { - "uc.micro": "^2.0.0" - } - }, - "node_modules/markdown-it/node_modules/uc.micro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "license": "MIT" - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "license": "MIT" - }, - "node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", - "license": "MIT" - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/onnxruntime-common": { - "version": "1.24.3", - "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.3.tgz", - "integrity": "sha512-GeuPZO6U/LBJXvwdaqHbuUmoXiEdeCjWi/EG7Y1HNnDwJYuk6WUbNXpF6luSUY8yASul3cmUlLGrCCL1ZgVXqA==", - "license": "MIT" - }, - "node_modules/onnxruntime-node": { - "version": "1.24.3", - "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.24.3.tgz", - "integrity": "sha512-JH7+czbc8ALA819vlTgcV+Q214/+VjGeBHDjX81+ZCD0PCVCIFGFNtT0V4sXG/1JXypKPgScQcB3ij/hk3YnTg==", - "hasInstallScript": true, - "license": "MIT", - "os": [ - "win32", - "darwin", - "linux" - ], - "dependencies": { - "adm-zip": "^0.5.16", - "global-agent": "^3.0.0", - "onnxruntime-common": "1.24.3" - } - }, - "node_modules/onnxruntime-web": { - "version": "1.26.0-dev.20260416-b7804b056c", - "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.26.0-dev.20260416-b7804b056c.tgz", - "integrity": "sha512-MD6Ss4GSpQBo6zqoJzyT9LRbKYs7x/JVN23FT24EcEvlqF4VuzPOeH6X38orZPKHQDbprn7K+SBpu0/mj2CQiw==", - "license": "MIT", - "dependencies": { - "flatbuffers": "^25.1.24", - "guid-typescript": "^1.0.9", - "long": "^5.2.3", - "onnxruntime-common": "1.24.0-dev.20251116-b39e144322", - "platform": "^1.3.6", - "protobufjs": "^7.2.4" - } - }, - "node_modules/onnxruntime-web/node_modules/onnxruntime-common": { - "version": "1.24.0-dev.20251116-b39e144322", - "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.0-dev.20251116-b39e144322.tgz", - "integrity": "sha512-BOoomdHYmNRL5r4iQ4bMvsl2t0/hzVQ3OM3PHD0gxeXu1PmggqBv3puZicEUVOA3AtHHYmqZtjMj9FOfGrATTw==", - "license": "MIT" - }, - "node_modules/orderedmap": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", - "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", - "license": "MIT" - }, - "node_modules/oxc-parser": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.133.0.tgz", - "integrity": "sha512-661RSx+ZcjBmjBYid+Fpp/2F5EbtildpeoZh5HdgnGs+jZ03nqQEQW8yGkt4BGyOC3OMPDQQRl8M5kqD2/g6jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@oxc-project/types": "^0.133.0" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxc-parser/binding-android-arm-eabi": "0.133.0", - "@oxc-parser/binding-android-arm64": "0.133.0", - "@oxc-parser/binding-darwin-arm64": "0.133.0", - "@oxc-parser/binding-darwin-x64": "0.133.0", - "@oxc-parser/binding-freebsd-x64": "0.133.0", - "@oxc-parser/binding-linux-arm-gnueabihf": "0.133.0", - "@oxc-parser/binding-linux-arm-musleabihf": "0.133.0", - "@oxc-parser/binding-linux-arm64-gnu": "0.133.0", - "@oxc-parser/binding-linux-arm64-musl": "0.133.0", - "@oxc-parser/binding-linux-ppc64-gnu": "0.133.0", - "@oxc-parser/binding-linux-riscv64-gnu": "0.133.0", - "@oxc-parser/binding-linux-riscv64-musl": "0.133.0", - "@oxc-parser/binding-linux-s390x-gnu": "0.133.0", - "@oxc-parser/binding-linux-x64-gnu": "0.133.0", - "@oxc-parser/binding-linux-x64-musl": "0.133.0", - "@oxc-parser/binding-openharmony-arm64": "0.133.0", - "@oxc-parser/binding-wasm32-wasi": "0.133.0", - "@oxc-parser/binding-win32-arm64-msvc": "0.133.0", - "@oxc-parser/binding-win32-ia32-msvc": "0.133.0", - "@oxc-parser/binding-win32-x64-msvc": "0.133.0" - } - }, - "node_modules/oxc-resolver": { - "version": "11.20.0", - "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.20.0.tgz", - "integrity": "sha512-CblytBiV/a/ZXY34dsVU2NxhIOxMXst8CvDCtyBelVITgd7PLrKzbEbA6oKLdPjvDKDzCiW48qzmzZ+mYaqn+g==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxc-resolver/binding-android-arm-eabi": "11.20.0", - "@oxc-resolver/binding-android-arm64": "11.20.0", - "@oxc-resolver/binding-darwin-arm64": "11.20.0", - "@oxc-resolver/binding-darwin-x64": "11.20.0", - "@oxc-resolver/binding-freebsd-x64": "11.20.0", - "@oxc-resolver/binding-linux-arm-gnueabihf": "11.20.0", - "@oxc-resolver/binding-linux-arm-musleabihf": "11.20.0", - "@oxc-resolver/binding-linux-arm64-gnu": "11.20.0", - "@oxc-resolver/binding-linux-arm64-musl": "11.20.0", - "@oxc-resolver/binding-linux-ppc64-gnu": "11.20.0", - "@oxc-resolver/binding-linux-riscv64-gnu": "11.20.0", - "@oxc-resolver/binding-linux-riscv64-musl": "11.20.0", - "@oxc-resolver/binding-linux-s390x-gnu": "11.20.0", - "@oxc-resolver/binding-linux-x64-gnu": "11.20.0", - "@oxc-resolver/binding-linux-x64-musl": "11.20.0", - "@oxc-resolver/binding-openharmony-arm64": "11.20.0", - "@oxc-resolver/binding-wasm32-wasi": "11.20.0", - "@oxc-resolver/binding-win32-arm64-msvc": "11.20.0", - "@oxc-resolver/binding-win32-x64-msvc": "11.20.0" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-parser-stream": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", - "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", - "license": "MIT", - "dependencies": { - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/platform": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", - "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", - "license": "MIT" - }, - "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.12", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/prettier": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", - "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-plugin-pkg": { - "version": "0.22.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-pkg/-/prettier-plugin-pkg-0.22.1.tgz", - "integrity": "sha512-l9qnxic48hgTXsvXi9yWWWzovpqkEYo/Ljf8Af7zSkDTNVmLwscXW63IEVMJXH94DyloO8YkogeLheJUzJh/ZQ==", - "dev": true, - "license": "MPL-2.0", - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - }, - "peerDependencies": { - "prettier": "^3.0.3" - } - }, - "node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/prosemirror-commands": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz", - "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==", - "license": "MIT", - "dependencies": { - "prosemirror-model": "^1.0.0", - "prosemirror-state": "^1.0.0", - "prosemirror-transform": "^1.10.2" - } - }, - "node_modules/prosemirror-dropcursor": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz", - "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==", - "license": "MIT", - "dependencies": { - "prosemirror-state": "^1.0.0", - "prosemirror-transform": "^1.1.0", - "prosemirror-view": "^1.1.0" - } - }, - "node_modules/prosemirror-history": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz", - "integrity": "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==", - "license": "MIT", - "dependencies": { - "prosemirror-state": "^1.2.2", - "prosemirror-transform": "^1.0.0", - "prosemirror-view": "^1.31.0", - "rope-sequence": "^1.3.0" - } - }, - "node_modules/prosemirror-keymap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz", - "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==", - "license": "MIT", - "dependencies": { - "prosemirror-state": "^1.0.0", - "w3c-keyname": "^2.2.0" - } - }, - "node_modules/prosemirror-markdown": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.2.tgz", - "integrity": "sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==", - "license": "MIT", - "dependencies": { - "@types/markdown-it": "^14.0.0", - "markdown-it": "^14.0.0", - "prosemirror-model": "^1.25.0" - } - }, - "node_modules/prosemirror-model": { - "version": "1.25.4", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz", - "integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==", - "license": "MIT", - "dependencies": { - "orderedmap": "^2.0.0" - } - }, - "node_modules/prosemirror-state": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz", - "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==", - "license": "MIT", - "dependencies": { - "prosemirror-model": "^1.0.0", - "prosemirror-transform": "^1.0.0", - "prosemirror-view": "^1.27.0" - } - }, - "node_modules/prosemirror-transform": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.5.tgz", - "integrity": "sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==", - "license": "MIT", - "dependencies": { - "prosemirror-model": "^1.21.0" - } - }, - "node_modules/prosemirror-utils": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/prosemirror-utils/-/prosemirror-utils-1.2.2.tgz", - "integrity": "sha512-7a2MPf99oCW8/587rQYI1/snX71Ban40+apr1hLkY8TmU9YXd7JeR6QsmktcTisJURO3WRjxIia4lTMsYgZVOw==", - "license": "Apache-2.0", - "peerDependencies": { - "prosemirror-model": "^1.19.2", - "prosemirror-state": "^1.4.3" - } - }, - "node_modules/prosemirror-view": { - "version": "1.41.5", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.5.tgz", - "integrity": "sha512-UDQbIPnDrjE8tqUBbPmCOZgtd75htE6W3r0JCmY9bL6W1iemDM37MZEKC49d+tdQ0v/CKx4gjxLoLsfkD2NiZA==", - "license": "MIT", - "dependencies": { - "prosemirror-model": "^1.20.0", - "prosemirror-state": "^1.0.0", - "prosemirror-transform": "^1.1.0" - } - }, - "node_modules/protobufjs": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.2.tgz", - "integrity": "sha512-N9EiLovGEQOJSPF26Ij7qUGvahfEnq0eeYZ02aigIedkmz1qZSwjnP9SBITHJuF/6MYbIW4HDN8zdYjsjqJKXQ==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.5", - "@protobufjs/eventemitter": "^1.1.1", - "@protobufjs/fetch": "^1.1.1", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.2", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.1", - "@types/node": ">=13.7.0", - "long": "^5.3.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/raf-schd": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", - "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==", - "license": "MIT" - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", - "license": "MIT" - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, - "node_modules/react-is-18": { - "name": "react-is", - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/react-is-19": { - "name": "react-is", - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz", - "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/react-popper": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", - "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", - "license": "MIT", - "dependencies": { - "react-fast-compare": "^3.0.1", - "warning": "^4.0.2" - }, - "peerDependencies": { - "@popperjs/core": "^2.0.0", - "react": "^16.8.0 || ^17 || ^18", - "react-dom": "^16.8.0 || ^17 || ^18" - } - }, - "node_modules/react-uid": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/react-uid/-/react-uid-2.4.0.tgz", - "integrity": "sha512-+MVs/25NrcZuGrmlVRWPOSsbS8y72GJOBsR7d68j3/wqOrRBF52U29XAw4+XSelw0Vm6s5VmGH5mCbTCPGVCVg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "license": "BSD-3-Clause", - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/rolldown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", - "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@oxc-project/types": "=0.133.0", - "@rolldown/pluginutils": "^1.0.0" - }, - "bin": { - "rolldown": "bin/cli.mjs" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.3", - "@rolldown/binding-darwin-arm64": "1.0.3", - "@rolldown/binding-darwin-x64": "1.0.3", - "@rolldown/binding-freebsd-x64": "1.0.3", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", - "@rolldown/binding-linux-arm64-gnu": "1.0.3", - "@rolldown/binding-linux-arm64-musl": "1.0.3", - "@rolldown/binding-linux-ppc64-gnu": "1.0.3", - "@rolldown/binding-linux-s390x-gnu": "1.0.3", - "@rolldown/binding-linux-x64-gnu": "1.0.3", - "@rolldown/binding-linux-x64-musl": "1.0.3", - "@rolldown/binding-openharmony-arm64": "1.0.3", - "@rolldown/binding-wasm32-wasi": "1.0.3", - "@rolldown/binding-win32-arm64-msvc": "1.0.3", - "@rolldown/binding-win32-x64-msvc": "1.0.3" - } - }, - "node_modules/rope-sequence": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", - "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/semver": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.3.tgz", - "integrity": "sha512-wnilbGyMxzbY7dNOl7jpKbLSjcfeweJWU5j4+u5qW+6/wuGD9KzIGOyZnQVSBM9E7DtWaaH3CyHkppYrKYoxwg==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "license": "MIT" - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@img/colour": "^1.0.0", - "detect-libc": "^2.1.2", - "semver": "^7.7.3" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.5", - "@img/sharp-darwin-x64": "0.34.5", - "@img/sharp-libvips-darwin-arm64": "1.2.4", - "@img/sharp-libvips-darwin-x64": "1.2.4", - "@img/sharp-libvips-linux-arm": "1.2.4", - "@img/sharp-libvips-linux-arm64": "1.2.4", - "@img/sharp-libvips-linux-ppc64": "1.2.4", - "@img/sharp-libvips-linux-riscv64": "1.2.4", - "@img/sharp-libvips-linux-s390x": "1.2.4", - "@img/sharp-libvips-linux-x64": "1.2.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", - "@img/sharp-libvips-linuxmusl-x64": "1.2.4", - "@img/sharp-linux-arm": "0.34.5", - "@img/sharp-linux-arm64": "0.34.5", - "@img/sharp-linux-ppc64": "0.34.5", - "@img/sharp-linux-riscv64": "0.34.5", - "@img/sharp-linux-s390x": "0.34.5", - "@img/sharp-linux-x64": "0.34.5", - "@img/sharp-linuxmusl-arm64": "0.34.5", - "@img/sharp-linuxmusl-x64": "0.34.5", - "@img/sharp-wasm32": "0.34.5", - "@img/sharp-win32-arm64": "0.34.5", - "@img/sharp-win32-ia32": "0.34.5", - "@img/sharp-win32-x64": "0.34.5" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/smol-toml": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz", - "integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 18" - }, - "funding": { - "url": "https://github.com/sponsors/cyyynthia" - } - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", - "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", - "license": "MIT" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", - "license": "MIT" - }, - "node_modules/tinyglobby": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", - "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", - "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "license": "MIT" - }, - "node_modules/unbash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unbash/-/unbash-3.0.0.tgz", - "integrity": "sha512-FeFPZ/WFT0mbRCuydiZzpPFlrYN8ZUpphQKoq4EeElVIYjYyGzPMxQR/simUwCOJIyVhpFk4RbtyO7RuMpMnHA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - } - }, - "node_modules/undici": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.27.2.tgz", - "integrity": "sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==", - "license": "MIT", - "engines": { - "node": ">=20.18.1" - } - }, - "node_modules/undici-types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", - "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", - "license": "MIT" - }, - "node_modules/use-memo-one": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz", - "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/vite": { - "version": "8.0.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", - "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "lightningcss": "^1.32.0", - "picomatch": "^4.0.4", - "postcss": "^8.5.15", - "rolldown": "1.0.3", - "tinyglobby": "^0.2.17" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.1.18", - "esbuild": "^0.27.0 || ^0.28.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "@vitejs/devtools": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/w3c-keyname": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", - "license": "MIT" - }, - "node_modules/walk-up-path": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-4.0.0.tgz", - "integrity": "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, - "node_modules/zod": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", - "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/package.json b/examples/forge-sql-orm-example-ai/static/forge-orm-example/package.json deleted file mode 100644 index 4739300a7..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "forge_sql_orm_example_frontend", - "version": "1.0.0", - "description": "", - "main": "index.js", - "dependencies": { - "@atlaskit/button": "^23.11.8", - "@atlaskit/css-reset": "^7.4.5", - "@atlaskit/dynamic-table": "^18.4.2", - "@atlaskit/primitives": "^19.0.2", - "@atlaskit/section-message": "^8.13.0", - "@atlaskit/spinner": "^19.1.2", - "@atlaskit/tabs": "^19.1.0", - "@atlaskit/textarea": "^8.3.2", - "@atlaskit/textfield": "^8.3.2", - "@forge/bridge": "^5.16.2", - "@huggingface/transformers": "^4.2.0", - "react": "^18.3.1", - "react-dom": "^18.3.1" - }, - "devDependencies": { - "@types/jest": "^30.0.0", - "@types/node": "^25.9.2", - "@types/react": "^18.3.1", - "@types/react-dom": "^18.3.1", - "@vitejs/plugin-react": "^6.0.2", - "dotenv": "17.4.2", - "knip": "^6.16.1", - "prettier": "^3.8.3", - "prettier-plugin-pkg": "^0.22.1", - "typescript": "^6.0.3", - "vite": "^8.0.16" - }, - "scripts": { - "build": "vite build", - "build:husky": "vite build", - "build:deploy": "vite build && cd .. && ./deploy.sh ", - "build:tunnel": "cd .. && forge tunnel", - "start": "PORT=3099 vite serve", - "prettier": "prettier src vite.config.ts --write", - "knip": "knip" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "overrides": { - "parse-url": "npm:parse-url@latest", - "gry": "npm:gry@latest", - "got": "npm:got@latest" - } -} diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/index.html b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/index.html deleted file mode 100644 index 38c0bfab0..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - React App - - - -
- - diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/config.json b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/config.json deleted file mode 100644 index 30ade1ab4..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/config.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "_name_or_path": "sentence-transformers/all-MiniLM-L6-v2", - "architectures": ["BertModel"], - "attention_probs_dropout_prob": 0.1, - "classifier_dropout": null, - "gradient_checkpointing": false, - "hidden_act": "gelu", - "hidden_dropout_prob": 0.1, - "hidden_size": 384, - "initializer_range": 0.02, - "intermediate_size": 1536, - "layer_norm_eps": 1e-12, - "max_position_embeddings": 512, - "model_type": "bert", - "num_attention_heads": 12, - "num_hidden_layers": 6, - "pad_token_id": 0, - "position_embedding_type": "absolute", - "transformers_version": "4.29.2", - "type_vocab_size": 2, - "use_cache": true, - "vocab_size": 30522 -} diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/onnx/model_quantized.onnx b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/onnx/model_quantized.onnx deleted file mode 100644 index 712e070a9..000000000 Binary files a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/onnx/model_quantized.onnx and /dev/null differ diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/special_tokens_map.json b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/special_tokens_map.json deleted file mode 100644 index a8b3208c2..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/special_tokens_map.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "cls_token": "[CLS]", - "mask_token": "[MASK]", - "pad_token": "[PAD]", - "sep_token": "[SEP]", - "unk_token": "[UNK]" -} diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/tokenizer.json b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/tokenizer.json deleted file mode 100644 index 619288fb6..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/tokenizer.json +++ /dev/null @@ -1,30678 +0,0 @@ -{ - "version": "1.0", - "truncation": { - "direction": "Right", - "max_length": 128, - "strategy": "LongestFirst", - "stride": 0 - }, - "padding": { - "strategy": { - "Fixed": 128 - }, - "direction": "Right", - "pad_to_multiple_of": null, - "pad_id": 0, - "pad_type_id": 0, - "pad_token": "[PAD]" - }, - "added_tokens": [ - { - "id": 0, - "content": "[PAD]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false, - "special": true - }, - { - "id": 100, - "content": "[UNK]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false, - "special": true - }, - { - "id": 101, - "content": "[CLS]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false, - "special": true - }, - { - "id": 102, - "content": "[SEP]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false, - "special": true - }, - { - "id": 103, - "content": "[MASK]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false, - "special": true - } - ], - "normalizer": { - "type": "BertNormalizer", - "clean_text": true, - "handle_chinese_chars": true, - "strip_accents": null, - "lowercase": true - }, - "pre_tokenizer": { - "type": "BertPreTokenizer" - }, - "post_processor": { - "type": "TemplateProcessing", - "single": [ - { - "SpecialToken": { - "id": "[CLS]", - "type_id": 0 - } - }, - { - "Sequence": { - "id": "A", - "type_id": 0 - } - }, - { - "SpecialToken": { - "id": "[SEP]", - "type_id": 0 - } - } - ], - "pair": [ - { - "SpecialToken": { - "id": "[CLS]", - "type_id": 0 - } - }, - { - "Sequence": { - "id": "A", - "type_id": 0 - } - }, - { - "SpecialToken": { - "id": "[SEP]", - "type_id": 0 - } - }, - { - "Sequence": { - "id": "B", - "type_id": 1 - } - }, - { - "SpecialToken": { - "id": "[SEP]", - "type_id": 1 - } - } - ], - "special_tokens": { - "[CLS]": { - "id": "[CLS]", - "ids": [101], - "tokens": ["[CLS]"] - }, - "[SEP]": { - "id": "[SEP]", - "ids": [102], - "tokens": ["[SEP]"] - } - } - }, - "decoder": { - "type": "WordPiece", - "prefix": "##", - "cleanup": true - }, - "model": { - "type": "WordPiece", - "unk_token": "[UNK]", - "continuing_subword_prefix": "##", - "max_input_chars_per_word": 100, - "vocab": { - "[PAD]": 0, - "[unused0]": 1, - "[unused1]": 2, - "[unused2]": 3, - "[unused3]": 4, - "[unused4]": 5, - "[unused5]": 6, - "[unused6]": 7, - "[unused7]": 8, - "[unused8]": 9, - "[unused9]": 10, - "[unused10]": 11, - "[unused11]": 12, - "[unused12]": 13, - "[unused13]": 14, - "[unused14]": 15, - "[unused15]": 16, - "[unused16]": 17, - "[unused17]": 18, - "[unused18]": 19, - "[unused19]": 20, - "[unused20]": 21, - "[unused21]": 22, - "[unused22]": 23, - "[unused23]": 24, - "[unused24]": 25, - "[unused25]": 26, - "[unused26]": 27, - "[unused27]": 28, - "[unused28]": 29, - "[unused29]": 30, - "[unused30]": 31, - "[unused31]": 32, - "[unused32]": 33, - "[unused33]": 34, - "[unused34]": 35, - "[unused35]": 36, - "[unused36]": 37, - "[unused37]": 38, - "[unused38]": 39, - "[unused39]": 40, - "[unused40]": 41, - "[unused41]": 42, - "[unused42]": 43, - "[unused43]": 44, - "[unused44]": 45, - "[unused45]": 46, - "[unused46]": 47, - "[unused47]": 48, - "[unused48]": 49, - "[unused49]": 50, - "[unused50]": 51, - "[unused51]": 52, - "[unused52]": 53, - "[unused53]": 54, - "[unused54]": 55, - "[unused55]": 56, - "[unused56]": 57, - "[unused57]": 58, - "[unused58]": 59, - "[unused59]": 60, - "[unused60]": 61, - "[unused61]": 62, - "[unused62]": 63, - "[unused63]": 64, - "[unused64]": 65, - "[unused65]": 66, - "[unused66]": 67, - "[unused67]": 68, - "[unused68]": 69, - "[unused69]": 70, - "[unused70]": 71, - "[unused71]": 72, - "[unused72]": 73, - "[unused73]": 74, - "[unused74]": 75, - "[unused75]": 76, - "[unused76]": 77, - "[unused77]": 78, - "[unused78]": 79, - "[unused79]": 80, - "[unused80]": 81, - "[unused81]": 82, - "[unused82]": 83, - "[unused83]": 84, - "[unused84]": 85, - "[unused85]": 86, - "[unused86]": 87, - "[unused87]": 88, - "[unused88]": 89, - "[unused89]": 90, - "[unused90]": 91, - "[unused91]": 92, - "[unused92]": 93, - "[unused93]": 94, - "[unused94]": 95, - "[unused95]": 96, - "[unused96]": 97, - "[unused97]": 98, - "[unused98]": 99, - "[UNK]": 100, - "[CLS]": 101, - "[SEP]": 102, - "[MASK]": 103, - "[unused99]": 104, - "[unused100]": 105, - "[unused101]": 106, - "[unused102]": 107, - "[unused103]": 108, - "[unused104]": 109, - "[unused105]": 110, - "[unused106]": 111, - "[unused107]": 112, - "[unused108]": 113, - "[unused109]": 114, - "[unused110]": 115, - "[unused111]": 116, - "[unused112]": 117, - "[unused113]": 118, - "[unused114]": 119, - "[unused115]": 120, - "[unused116]": 121, - "[unused117]": 122, - "[unused118]": 123, - "[unused119]": 124, - "[unused120]": 125, - "[unused121]": 126, - "[unused122]": 127, - "[unused123]": 128, - "[unused124]": 129, - "[unused125]": 130, - "[unused126]": 131, - "[unused127]": 132, - "[unused128]": 133, - "[unused129]": 134, - "[unused130]": 135, - "[unused131]": 136, - "[unused132]": 137, - "[unused133]": 138, - "[unused134]": 139, - "[unused135]": 140, - "[unused136]": 141, - "[unused137]": 142, - "[unused138]": 143, - "[unused139]": 144, - "[unused140]": 145, - "[unused141]": 146, - "[unused142]": 147, - "[unused143]": 148, - "[unused144]": 149, - "[unused145]": 150, - "[unused146]": 151, - "[unused147]": 152, - "[unused148]": 153, - "[unused149]": 154, - "[unused150]": 155, - "[unused151]": 156, - "[unused152]": 157, - "[unused153]": 158, - "[unused154]": 159, - "[unused155]": 160, - "[unused156]": 161, - "[unused157]": 162, - "[unused158]": 163, - "[unused159]": 164, - "[unused160]": 165, - "[unused161]": 166, - "[unused162]": 167, - "[unused163]": 168, - "[unused164]": 169, - "[unused165]": 170, - "[unused166]": 171, - "[unused167]": 172, - "[unused168]": 173, - "[unused169]": 174, - "[unused170]": 175, - "[unused171]": 176, - "[unused172]": 177, - "[unused173]": 178, - "[unused174]": 179, - "[unused175]": 180, - "[unused176]": 181, - "[unused177]": 182, - "[unused178]": 183, - "[unused179]": 184, - "[unused180]": 185, - "[unused181]": 186, - "[unused182]": 187, - "[unused183]": 188, - "[unused184]": 189, - "[unused185]": 190, - "[unused186]": 191, - "[unused187]": 192, - "[unused188]": 193, - "[unused189]": 194, - "[unused190]": 195, - "[unused191]": 196, - "[unused192]": 197, - "[unused193]": 198, - "[unused194]": 199, - "[unused195]": 200, - "[unused196]": 201, - "[unused197]": 202, - "[unused198]": 203, - "[unused199]": 204, - "[unused200]": 205, - "[unused201]": 206, - "[unused202]": 207, - "[unused203]": 208, - "[unused204]": 209, - "[unused205]": 210, - "[unused206]": 211, - "[unused207]": 212, - "[unused208]": 213, - "[unused209]": 214, - "[unused210]": 215, - "[unused211]": 216, - "[unused212]": 217, - "[unused213]": 218, - "[unused214]": 219, - "[unused215]": 220, - "[unused216]": 221, - "[unused217]": 222, - "[unused218]": 223, - "[unused219]": 224, - "[unused220]": 225, - "[unused221]": 226, - "[unused222]": 227, - "[unused223]": 228, - "[unused224]": 229, - "[unused225]": 230, - "[unused226]": 231, - "[unused227]": 232, - "[unused228]": 233, - "[unused229]": 234, - "[unused230]": 235, - "[unused231]": 236, - "[unused232]": 237, - "[unused233]": 238, - "[unused234]": 239, - "[unused235]": 240, - "[unused236]": 241, - "[unused237]": 242, - "[unused238]": 243, - "[unused239]": 244, - "[unused240]": 245, - "[unused241]": 246, - "[unused242]": 247, - "[unused243]": 248, - "[unused244]": 249, - "[unused245]": 250, - "[unused246]": 251, - "[unused247]": 252, - "[unused248]": 253, - "[unused249]": 254, - "[unused250]": 255, - "[unused251]": 256, - "[unused252]": 257, - "[unused253]": 258, - "[unused254]": 259, - "[unused255]": 260, - "[unused256]": 261, - "[unused257]": 262, - "[unused258]": 263, - "[unused259]": 264, - "[unused260]": 265, - "[unused261]": 266, - "[unused262]": 267, - "[unused263]": 268, - "[unused264]": 269, - "[unused265]": 270, - "[unused266]": 271, - "[unused267]": 272, - "[unused268]": 273, - "[unused269]": 274, - "[unused270]": 275, - "[unused271]": 276, - "[unused272]": 277, - "[unused273]": 278, - "[unused274]": 279, - "[unused275]": 280, - "[unused276]": 281, - "[unused277]": 282, - "[unused278]": 283, - "[unused279]": 284, - "[unused280]": 285, - "[unused281]": 286, - "[unused282]": 287, - "[unused283]": 288, - "[unused284]": 289, - "[unused285]": 290, - "[unused286]": 291, - "[unused287]": 292, - "[unused288]": 293, - "[unused289]": 294, - "[unused290]": 295, - "[unused291]": 296, - "[unused292]": 297, - "[unused293]": 298, - "[unused294]": 299, - "[unused295]": 300, - "[unused296]": 301, - "[unused297]": 302, - "[unused298]": 303, - "[unused299]": 304, - "[unused300]": 305, - "[unused301]": 306, - "[unused302]": 307, - "[unused303]": 308, - "[unused304]": 309, - "[unused305]": 310, - "[unused306]": 311, - "[unused307]": 312, - "[unused308]": 313, - "[unused309]": 314, - "[unused310]": 315, - "[unused311]": 316, - "[unused312]": 317, - "[unused313]": 318, - "[unused314]": 319, - "[unused315]": 320, - "[unused316]": 321, - "[unused317]": 322, - "[unused318]": 323, - "[unused319]": 324, - "[unused320]": 325, - "[unused321]": 326, - "[unused322]": 327, - "[unused323]": 328, - "[unused324]": 329, - "[unused325]": 330, - "[unused326]": 331, - "[unused327]": 332, - "[unused328]": 333, - "[unused329]": 334, - "[unused330]": 335, - "[unused331]": 336, - "[unused332]": 337, - "[unused333]": 338, - "[unused334]": 339, - "[unused335]": 340, - "[unused336]": 341, - "[unused337]": 342, - "[unused338]": 343, - "[unused339]": 344, - "[unused340]": 345, - "[unused341]": 346, - "[unused342]": 347, - "[unused343]": 348, - "[unused344]": 349, - "[unused345]": 350, - "[unused346]": 351, - "[unused347]": 352, - "[unused348]": 353, - "[unused349]": 354, - "[unused350]": 355, - "[unused351]": 356, - "[unused352]": 357, - "[unused353]": 358, - "[unused354]": 359, - "[unused355]": 360, - "[unused356]": 361, - "[unused357]": 362, - "[unused358]": 363, - "[unused359]": 364, - "[unused360]": 365, - "[unused361]": 366, - "[unused362]": 367, - "[unused363]": 368, - "[unused364]": 369, - "[unused365]": 370, - "[unused366]": 371, - "[unused367]": 372, - "[unused368]": 373, - "[unused369]": 374, - "[unused370]": 375, - "[unused371]": 376, - "[unused372]": 377, - "[unused373]": 378, - "[unused374]": 379, - "[unused375]": 380, - "[unused376]": 381, - "[unused377]": 382, - "[unused378]": 383, - "[unused379]": 384, - "[unused380]": 385, - "[unused381]": 386, - "[unused382]": 387, - "[unused383]": 388, - "[unused384]": 389, - "[unused385]": 390, - "[unused386]": 391, - "[unused387]": 392, - "[unused388]": 393, - "[unused389]": 394, - "[unused390]": 395, - "[unused391]": 396, - "[unused392]": 397, - "[unused393]": 398, - "[unused394]": 399, - "[unused395]": 400, - "[unused396]": 401, - "[unused397]": 402, - "[unused398]": 403, - "[unused399]": 404, - "[unused400]": 405, - "[unused401]": 406, - "[unused402]": 407, - "[unused403]": 408, - "[unused404]": 409, - "[unused405]": 410, - "[unused406]": 411, - "[unused407]": 412, - "[unused408]": 413, - "[unused409]": 414, - "[unused410]": 415, - "[unused411]": 416, - "[unused412]": 417, - "[unused413]": 418, - "[unused414]": 419, - "[unused415]": 420, - "[unused416]": 421, - "[unused417]": 422, - "[unused418]": 423, - "[unused419]": 424, - "[unused420]": 425, - "[unused421]": 426, - "[unused422]": 427, - "[unused423]": 428, - "[unused424]": 429, - "[unused425]": 430, - "[unused426]": 431, - "[unused427]": 432, - "[unused428]": 433, - "[unused429]": 434, - "[unused430]": 435, - "[unused431]": 436, - "[unused432]": 437, - "[unused433]": 438, - "[unused434]": 439, - "[unused435]": 440, - "[unused436]": 441, - "[unused437]": 442, - "[unused438]": 443, - "[unused439]": 444, - "[unused440]": 445, - "[unused441]": 446, - "[unused442]": 447, - "[unused443]": 448, - "[unused444]": 449, - "[unused445]": 450, - "[unused446]": 451, - "[unused447]": 452, - "[unused448]": 453, - "[unused449]": 454, - "[unused450]": 455, - "[unused451]": 456, - "[unused452]": 457, - "[unused453]": 458, - "[unused454]": 459, - "[unused455]": 460, - "[unused456]": 461, - "[unused457]": 462, - "[unused458]": 463, - "[unused459]": 464, - "[unused460]": 465, - "[unused461]": 466, - "[unused462]": 467, - "[unused463]": 468, - "[unused464]": 469, - "[unused465]": 470, - "[unused466]": 471, - "[unused467]": 472, - "[unused468]": 473, - "[unused469]": 474, - "[unused470]": 475, - "[unused471]": 476, - "[unused472]": 477, - "[unused473]": 478, - "[unused474]": 479, - "[unused475]": 480, - "[unused476]": 481, - "[unused477]": 482, - "[unused478]": 483, - "[unused479]": 484, - "[unused480]": 485, - "[unused481]": 486, - "[unused482]": 487, - "[unused483]": 488, - "[unused484]": 489, - "[unused485]": 490, - "[unused486]": 491, - "[unused487]": 492, - "[unused488]": 493, - "[unused489]": 494, - "[unused490]": 495, - "[unused491]": 496, - "[unused492]": 497, - "[unused493]": 498, - "[unused494]": 499, - "[unused495]": 500, - "[unused496]": 501, - "[unused497]": 502, - "[unused498]": 503, - "[unused499]": 504, - "[unused500]": 505, - "[unused501]": 506, - "[unused502]": 507, - "[unused503]": 508, - "[unused504]": 509, - "[unused505]": 510, - "[unused506]": 511, - "[unused507]": 512, - "[unused508]": 513, - "[unused509]": 514, - "[unused510]": 515, - "[unused511]": 516, - "[unused512]": 517, - "[unused513]": 518, - "[unused514]": 519, - "[unused515]": 520, - "[unused516]": 521, - "[unused517]": 522, - "[unused518]": 523, - "[unused519]": 524, - "[unused520]": 525, - "[unused521]": 526, - "[unused522]": 527, - "[unused523]": 528, - "[unused524]": 529, - "[unused525]": 530, - "[unused526]": 531, - "[unused527]": 532, - "[unused528]": 533, - "[unused529]": 534, - "[unused530]": 535, - "[unused531]": 536, - "[unused532]": 537, - "[unused533]": 538, - "[unused534]": 539, - "[unused535]": 540, - "[unused536]": 541, - "[unused537]": 542, - "[unused538]": 543, - "[unused539]": 544, - "[unused540]": 545, - "[unused541]": 546, - "[unused542]": 547, - "[unused543]": 548, - "[unused544]": 549, - "[unused545]": 550, - "[unused546]": 551, - "[unused547]": 552, - "[unused548]": 553, - "[unused549]": 554, - "[unused550]": 555, - "[unused551]": 556, - "[unused552]": 557, - "[unused553]": 558, - "[unused554]": 559, - "[unused555]": 560, - "[unused556]": 561, - "[unused557]": 562, - "[unused558]": 563, - "[unused559]": 564, - "[unused560]": 565, - "[unused561]": 566, - "[unused562]": 567, - "[unused563]": 568, - "[unused564]": 569, - "[unused565]": 570, - "[unused566]": 571, - "[unused567]": 572, - "[unused568]": 573, - "[unused569]": 574, - "[unused570]": 575, - "[unused571]": 576, - "[unused572]": 577, - "[unused573]": 578, - "[unused574]": 579, - "[unused575]": 580, - "[unused576]": 581, - "[unused577]": 582, - "[unused578]": 583, - "[unused579]": 584, - "[unused580]": 585, - "[unused581]": 586, - "[unused582]": 587, - "[unused583]": 588, - "[unused584]": 589, - "[unused585]": 590, - "[unused586]": 591, - "[unused587]": 592, - "[unused588]": 593, - "[unused589]": 594, - "[unused590]": 595, - "[unused591]": 596, - "[unused592]": 597, - "[unused593]": 598, - "[unused594]": 599, - "[unused595]": 600, - "[unused596]": 601, - "[unused597]": 602, - "[unused598]": 603, - "[unused599]": 604, - "[unused600]": 605, - "[unused601]": 606, - "[unused602]": 607, - "[unused603]": 608, - "[unused604]": 609, - "[unused605]": 610, - "[unused606]": 611, - "[unused607]": 612, - "[unused608]": 613, - "[unused609]": 614, - "[unused610]": 615, - "[unused611]": 616, - "[unused612]": 617, - "[unused613]": 618, - "[unused614]": 619, - "[unused615]": 620, - "[unused616]": 621, - "[unused617]": 622, - "[unused618]": 623, - "[unused619]": 624, - "[unused620]": 625, - "[unused621]": 626, - "[unused622]": 627, - "[unused623]": 628, - "[unused624]": 629, - "[unused625]": 630, - "[unused626]": 631, - "[unused627]": 632, - "[unused628]": 633, - "[unused629]": 634, - "[unused630]": 635, - "[unused631]": 636, - "[unused632]": 637, - "[unused633]": 638, - "[unused634]": 639, - "[unused635]": 640, - "[unused636]": 641, - "[unused637]": 642, - "[unused638]": 643, - "[unused639]": 644, - "[unused640]": 645, - "[unused641]": 646, - "[unused642]": 647, - "[unused643]": 648, - "[unused644]": 649, - "[unused645]": 650, - "[unused646]": 651, - "[unused647]": 652, - "[unused648]": 653, - "[unused649]": 654, - "[unused650]": 655, - "[unused651]": 656, - "[unused652]": 657, - "[unused653]": 658, - "[unused654]": 659, - "[unused655]": 660, - "[unused656]": 661, - "[unused657]": 662, - "[unused658]": 663, - "[unused659]": 664, - "[unused660]": 665, - "[unused661]": 666, - "[unused662]": 667, - "[unused663]": 668, - "[unused664]": 669, - "[unused665]": 670, - "[unused666]": 671, - "[unused667]": 672, - "[unused668]": 673, - "[unused669]": 674, - "[unused670]": 675, - "[unused671]": 676, - "[unused672]": 677, - "[unused673]": 678, - "[unused674]": 679, - "[unused675]": 680, - "[unused676]": 681, - "[unused677]": 682, - "[unused678]": 683, - "[unused679]": 684, - "[unused680]": 685, - "[unused681]": 686, - "[unused682]": 687, - "[unused683]": 688, - "[unused684]": 689, - "[unused685]": 690, - "[unused686]": 691, - "[unused687]": 692, - "[unused688]": 693, - "[unused689]": 694, - "[unused690]": 695, - "[unused691]": 696, - "[unused692]": 697, - "[unused693]": 698, - "[unused694]": 699, - "[unused695]": 700, - "[unused696]": 701, - "[unused697]": 702, - "[unused698]": 703, - "[unused699]": 704, - "[unused700]": 705, - "[unused701]": 706, - "[unused702]": 707, - "[unused703]": 708, - "[unused704]": 709, - "[unused705]": 710, - "[unused706]": 711, - "[unused707]": 712, - "[unused708]": 713, - "[unused709]": 714, - "[unused710]": 715, - "[unused711]": 716, - "[unused712]": 717, - "[unused713]": 718, - "[unused714]": 719, - "[unused715]": 720, - "[unused716]": 721, - "[unused717]": 722, - "[unused718]": 723, - "[unused719]": 724, - "[unused720]": 725, - "[unused721]": 726, - "[unused722]": 727, - "[unused723]": 728, - "[unused724]": 729, - "[unused725]": 730, - "[unused726]": 731, - "[unused727]": 732, - "[unused728]": 733, - "[unused729]": 734, - "[unused730]": 735, - "[unused731]": 736, - "[unused732]": 737, - "[unused733]": 738, - "[unused734]": 739, - "[unused735]": 740, - "[unused736]": 741, - "[unused737]": 742, - "[unused738]": 743, - "[unused739]": 744, - "[unused740]": 745, - "[unused741]": 746, - "[unused742]": 747, - "[unused743]": 748, - "[unused744]": 749, - "[unused745]": 750, - "[unused746]": 751, - "[unused747]": 752, - "[unused748]": 753, - "[unused749]": 754, - "[unused750]": 755, - "[unused751]": 756, - "[unused752]": 757, - "[unused753]": 758, - "[unused754]": 759, - "[unused755]": 760, - "[unused756]": 761, - "[unused757]": 762, - "[unused758]": 763, - "[unused759]": 764, - "[unused760]": 765, - "[unused761]": 766, - "[unused762]": 767, - "[unused763]": 768, - "[unused764]": 769, - "[unused765]": 770, - "[unused766]": 771, - "[unused767]": 772, - "[unused768]": 773, - "[unused769]": 774, - "[unused770]": 775, - "[unused771]": 776, - "[unused772]": 777, - "[unused773]": 778, - "[unused774]": 779, - "[unused775]": 780, - "[unused776]": 781, - "[unused777]": 782, - "[unused778]": 783, - "[unused779]": 784, - "[unused780]": 785, - "[unused781]": 786, - "[unused782]": 787, - "[unused783]": 788, - "[unused784]": 789, - "[unused785]": 790, - "[unused786]": 791, - "[unused787]": 792, - "[unused788]": 793, - "[unused789]": 794, - "[unused790]": 795, - "[unused791]": 796, - "[unused792]": 797, - "[unused793]": 798, - "[unused794]": 799, - "[unused795]": 800, - "[unused796]": 801, - "[unused797]": 802, - "[unused798]": 803, - "[unused799]": 804, - "[unused800]": 805, - "[unused801]": 806, - "[unused802]": 807, - "[unused803]": 808, - "[unused804]": 809, - "[unused805]": 810, - "[unused806]": 811, - "[unused807]": 812, - "[unused808]": 813, - "[unused809]": 814, - "[unused810]": 815, - "[unused811]": 816, - "[unused812]": 817, - "[unused813]": 818, - "[unused814]": 819, - "[unused815]": 820, - "[unused816]": 821, - "[unused817]": 822, - "[unused818]": 823, - "[unused819]": 824, - "[unused820]": 825, - "[unused821]": 826, - "[unused822]": 827, - "[unused823]": 828, - "[unused824]": 829, - "[unused825]": 830, - "[unused826]": 831, - "[unused827]": 832, - "[unused828]": 833, - "[unused829]": 834, - "[unused830]": 835, - "[unused831]": 836, - "[unused832]": 837, - "[unused833]": 838, - "[unused834]": 839, - "[unused835]": 840, - "[unused836]": 841, - "[unused837]": 842, - "[unused838]": 843, - "[unused839]": 844, - "[unused840]": 845, - "[unused841]": 846, - "[unused842]": 847, - "[unused843]": 848, - "[unused844]": 849, - "[unused845]": 850, - "[unused846]": 851, - "[unused847]": 852, - "[unused848]": 853, - "[unused849]": 854, - "[unused850]": 855, - "[unused851]": 856, - "[unused852]": 857, - "[unused853]": 858, - "[unused854]": 859, - "[unused855]": 860, - "[unused856]": 861, - "[unused857]": 862, - "[unused858]": 863, - "[unused859]": 864, - "[unused860]": 865, - "[unused861]": 866, - "[unused862]": 867, - "[unused863]": 868, - "[unused864]": 869, - "[unused865]": 870, - "[unused866]": 871, - "[unused867]": 872, - "[unused868]": 873, - "[unused869]": 874, - "[unused870]": 875, - "[unused871]": 876, - "[unused872]": 877, - "[unused873]": 878, - "[unused874]": 879, - "[unused875]": 880, - "[unused876]": 881, - "[unused877]": 882, - "[unused878]": 883, - "[unused879]": 884, - "[unused880]": 885, - "[unused881]": 886, - "[unused882]": 887, - "[unused883]": 888, - "[unused884]": 889, - "[unused885]": 890, - "[unused886]": 891, - "[unused887]": 892, - "[unused888]": 893, - "[unused889]": 894, - "[unused890]": 895, - "[unused891]": 896, - "[unused892]": 897, - "[unused893]": 898, - "[unused894]": 899, - "[unused895]": 900, - "[unused896]": 901, - "[unused897]": 902, - "[unused898]": 903, - "[unused899]": 904, - "[unused900]": 905, - "[unused901]": 906, - "[unused902]": 907, - "[unused903]": 908, - "[unused904]": 909, - "[unused905]": 910, - "[unused906]": 911, - "[unused907]": 912, - "[unused908]": 913, - "[unused909]": 914, - "[unused910]": 915, - "[unused911]": 916, - "[unused912]": 917, - "[unused913]": 918, - "[unused914]": 919, - "[unused915]": 920, - "[unused916]": 921, - "[unused917]": 922, - "[unused918]": 923, - "[unused919]": 924, - "[unused920]": 925, - "[unused921]": 926, - "[unused922]": 927, - "[unused923]": 928, - "[unused924]": 929, - "[unused925]": 930, - "[unused926]": 931, - "[unused927]": 932, - "[unused928]": 933, - "[unused929]": 934, - "[unused930]": 935, - "[unused931]": 936, - "[unused932]": 937, - "[unused933]": 938, - "[unused934]": 939, - "[unused935]": 940, - "[unused936]": 941, - "[unused937]": 942, - "[unused938]": 943, - "[unused939]": 944, - "[unused940]": 945, - "[unused941]": 946, - "[unused942]": 947, - "[unused943]": 948, - "[unused944]": 949, - "[unused945]": 950, - "[unused946]": 951, - "[unused947]": 952, - "[unused948]": 953, - "[unused949]": 954, - "[unused950]": 955, - "[unused951]": 956, - "[unused952]": 957, - "[unused953]": 958, - "[unused954]": 959, - "[unused955]": 960, - "[unused956]": 961, - "[unused957]": 962, - "[unused958]": 963, - "[unused959]": 964, - "[unused960]": 965, - "[unused961]": 966, - "[unused962]": 967, - "[unused963]": 968, - "[unused964]": 969, - "[unused965]": 970, - "[unused966]": 971, - "[unused967]": 972, - "[unused968]": 973, - "[unused969]": 974, - "[unused970]": 975, - "[unused971]": 976, - "[unused972]": 977, - "[unused973]": 978, - "[unused974]": 979, - "[unused975]": 980, - "[unused976]": 981, - "[unused977]": 982, - "[unused978]": 983, - "[unused979]": 984, - "[unused980]": 985, - "[unused981]": 986, - "[unused982]": 987, - "[unused983]": 988, - "[unused984]": 989, - "[unused985]": 990, - "[unused986]": 991, - "[unused987]": 992, - "[unused988]": 993, - "[unused989]": 994, - "[unused990]": 995, - "[unused991]": 996, - "[unused992]": 997, - "[unused993]": 998, - "!": 999, - "\"": 1000, - "#": 1001, - "$": 1002, - "%": 1003, - "&": 1004, - "'": 1005, - "(": 1006, - ")": 1007, - "*": 1008, - "+": 1009, - ",": 1010, - "-": 1011, - ".": 1012, - "/": 1013, - "0": 1014, - "1": 1015, - "2": 1016, - "3": 1017, - "4": 1018, - "5": 1019, - "6": 1020, - "7": 1021, - "8": 1022, - "9": 1023, - ":": 1024, - ";": 1025, - "<": 1026, - "=": 1027, - ">": 1028, - "?": 1029, - "@": 1030, - "[": 1031, - "\\": 1032, - "]": 1033, - "^": 1034, - "_": 1035, - "`": 1036, - "a": 1037, - "b": 1038, - "c": 1039, - "d": 1040, - "e": 1041, - "f": 1042, - "g": 1043, - "h": 1044, - "i": 1045, - "j": 1046, - "k": 1047, - "l": 1048, - "m": 1049, - "n": 1050, - "o": 1051, - "p": 1052, - "q": 1053, - "r": 1054, - "s": 1055, - "t": 1056, - "u": 1057, - "v": 1058, - "w": 1059, - "x": 1060, - "y": 1061, - "z": 1062, - "{": 1063, - "|": 1064, - "}": 1065, - "~": 1066, - "¡": 1067, - "¢": 1068, - "£": 1069, - "¤": 1070, - "¥": 1071, - "¦": 1072, - "§": 1073, - "¨": 1074, - "©": 1075, - "ª": 1076, - "«": 1077, - "¬": 1078, - "®": 1079, - "°": 1080, - "±": 1081, - "²": 1082, - "³": 1083, - "´": 1084, - "µ": 1085, - "¶": 1086, - "·": 1087, - "¹": 1088, - "º": 1089, - "»": 1090, - "¼": 1091, - "½": 1092, - "¾": 1093, - "¿": 1094, - "×": 1095, - "ß": 1096, - "æ": 1097, - "ð": 1098, - "÷": 1099, - "ø": 1100, - "þ": 1101, - "đ": 1102, - "ħ": 1103, - "ı": 1104, - "ł": 1105, - "ŋ": 1106, - "œ": 1107, - "ƒ": 1108, - "ɐ": 1109, - "ɑ": 1110, - "ɒ": 1111, - "ɔ": 1112, - "ɕ": 1113, - "ə": 1114, - "ɛ": 1115, - "ɡ": 1116, - "ɣ": 1117, - "ɨ": 1118, - "ɪ": 1119, - "ɫ": 1120, - "ɬ": 1121, - "ɯ": 1122, - "ɲ": 1123, - "ɴ": 1124, - "ɹ": 1125, - "ɾ": 1126, - "ʀ": 1127, - "ʁ": 1128, - "ʂ": 1129, - "ʃ": 1130, - "ʉ": 1131, - "ʊ": 1132, - "ʋ": 1133, - "ʌ": 1134, - "ʎ": 1135, - "ʐ": 1136, - "ʑ": 1137, - "ʒ": 1138, - "ʔ": 1139, - "ʰ": 1140, - "ʲ": 1141, - "ʳ": 1142, - "ʷ": 1143, - "ʸ": 1144, - "ʻ": 1145, - "ʼ": 1146, - "ʾ": 1147, - "ʿ": 1148, - "ˈ": 1149, - "ː": 1150, - "ˡ": 1151, - "ˢ": 1152, - "ˣ": 1153, - "ˤ": 1154, - "α": 1155, - "β": 1156, - "γ": 1157, - "δ": 1158, - "ε": 1159, - "ζ": 1160, - "η": 1161, - "θ": 1162, - "ι": 1163, - "κ": 1164, - "λ": 1165, - "μ": 1166, - "ν": 1167, - "ξ": 1168, - "ο": 1169, - "π": 1170, - "ρ": 1171, - "ς": 1172, - "σ": 1173, - "τ": 1174, - "υ": 1175, - "φ": 1176, - "χ": 1177, - "ψ": 1178, - "ω": 1179, - "а": 1180, - "б": 1181, - "в": 1182, - "г": 1183, - "д": 1184, - "е": 1185, - "ж": 1186, - "з": 1187, - "и": 1188, - "к": 1189, - "л": 1190, - "м": 1191, - "н": 1192, - "о": 1193, - "п": 1194, - "р": 1195, - "с": 1196, - "т": 1197, - "у": 1198, - "ф": 1199, - "х": 1200, - "ц": 1201, - "ч": 1202, - "ш": 1203, - "щ": 1204, - "ъ": 1205, - "ы": 1206, - "ь": 1207, - "э": 1208, - "ю": 1209, - "я": 1210, - "ђ": 1211, - "є": 1212, - "і": 1213, - "ј": 1214, - "љ": 1215, - "њ": 1216, - "ћ": 1217, - "ӏ": 1218, - "ա": 1219, - "բ": 1220, - "գ": 1221, - "դ": 1222, - "ե": 1223, - "թ": 1224, - "ի": 1225, - "լ": 1226, - "կ": 1227, - "հ": 1228, - "մ": 1229, - "յ": 1230, - "ն": 1231, - "ո": 1232, - "պ": 1233, - "ս": 1234, - "վ": 1235, - "տ": 1236, - "ր": 1237, - "ւ": 1238, - "ք": 1239, - "־": 1240, - "א": 1241, - "ב": 1242, - "ג": 1243, - "ד": 1244, - "ה": 1245, - "ו": 1246, - "ז": 1247, - "ח": 1248, - "ט": 1249, - "י": 1250, - "ך": 1251, - "כ": 1252, - "ל": 1253, - "ם": 1254, - "מ": 1255, - "ן": 1256, - "נ": 1257, - "ס": 1258, - "ע": 1259, - "ף": 1260, - "פ": 1261, - "ץ": 1262, - "צ": 1263, - "ק": 1264, - "ר": 1265, - "ש": 1266, - "ת": 1267, - "،": 1268, - "ء": 1269, - "ا": 1270, - "ب": 1271, - "ة": 1272, - "ت": 1273, - "ث": 1274, - "ج": 1275, - "ح": 1276, - "خ": 1277, - "د": 1278, - "ذ": 1279, - "ر": 1280, - "ز": 1281, - "س": 1282, - "ش": 1283, - "ص": 1284, - "ض": 1285, - "ط": 1286, - "ظ": 1287, - "ع": 1288, - "غ": 1289, - "ـ": 1290, - "ف": 1291, - "ق": 1292, - "ك": 1293, - "ل": 1294, - "م": 1295, - "ن": 1296, - "ه": 1297, - "و": 1298, - "ى": 1299, - "ي": 1300, - "ٹ": 1301, - "پ": 1302, - "چ": 1303, - "ک": 1304, - "گ": 1305, - "ں": 1306, - "ھ": 1307, - "ہ": 1308, - "ی": 1309, - "ے": 1310, - "अ": 1311, - "आ": 1312, - "उ": 1313, - "ए": 1314, - "क": 1315, - "ख": 1316, - "ग": 1317, - "च": 1318, - "ज": 1319, - "ट": 1320, - "ड": 1321, - "ण": 1322, - "त": 1323, - "थ": 1324, - "द": 1325, - "ध": 1326, - "न": 1327, - "प": 1328, - "ब": 1329, - "भ": 1330, - "म": 1331, - "य": 1332, - "र": 1333, - "ल": 1334, - "व": 1335, - "श": 1336, - "ष": 1337, - "स": 1338, - "ह": 1339, - "ा": 1340, - "ि": 1341, - "ी": 1342, - "ो": 1343, - "।": 1344, - "॥": 1345, - "ং": 1346, - "অ": 1347, - "আ": 1348, - "ই": 1349, - "উ": 1350, - "এ": 1351, - "ও": 1352, - "ক": 1353, - "খ": 1354, - "গ": 1355, - "চ": 1356, - "ছ": 1357, - "জ": 1358, - "ট": 1359, - "ড": 1360, - "ণ": 1361, - "ত": 1362, - "থ": 1363, - "দ": 1364, - "ধ": 1365, - "ন": 1366, - "প": 1367, - "ব": 1368, - "ভ": 1369, - "ম": 1370, - "য": 1371, - "র": 1372, - "ল": 1373, - "শ": 1374, - "ষ": 1375, - "স": 1376, - "হ": 1377, - "া": 1378, - "ি": 1379, - "ী": 1380, - "ে": 1381, - "க": 1382, - "ச": 1383, - "ட": 1384, - "த": 1385, - "ந": 1386, - "ன": 1387, - "ப": 1388, - "ம": 1389, - "ய": 1390, - "ர": 1391, - "ல": 1392, - "ள": 1393, - "வ": 1394, - "ா": 1395, - "ி": 1396, - "ு": 1397, - "ே": 1398, - "ை": 1399, - "ನ": 1400, - "ರ": 1401, - "ಾ": 1402, - "ක": 1403, - "ය": 1404, - "ර": 1405, - "ල": 1406, - "ව": 1407, - "ා": 1408, - "ก": 1409, - "ง": 1410, - "ต": 1411, - "ท": 1412, - "น": 1413, - "พ": 1414, - "ม": 1415, - "ย": 1416, - "ร": 1417, - "ล": 1418, - "ว": 1419, - "ส": 1420, - "อ": 1421, - "า": 1422, - "เ": 1423, - "་": 1424, - "།": 1425, - "ག": 1426, - "ང": 1427, - "ད": 1428, - "ན": 1429, - "པ": 1430, - "བ": 1431, - "མ": 1432, - "འ": 1433, - "ར": 1434, - "ལ": 1435, - "ས": 1436, - "မ": 1437, - "ა": 1438, - "ბ": 1439, - "გ": 1440, - "დ": 1441, - "ე": 1442, - "ვ": 1443, - "თ": 1444, - "ი": 1445, - "კ": 1446, - "ლ": 1447, - "მ": 1448, - "ნ": 1449, - "ო": 1450, - "რ": 1451, - "ს": 1452, - "ტ": 1453, - "უ": 1454, - "ᄀ": 1455, - "ᄂ": 1456, - "ᄃ": 1457, - "ᄅ": 1458, - "ᄆ": 1459, - "ᄇ": 1460, - "ᄉ": 1461, - "ᄊ": 1462, - "ᄋ": 1463, - "ᄌ": 1464, - "ᄎ": 1465, - "ᄏ": 1466, - "ᄐ": 1467, - "ᄑ": 1468, - "ᄒ": 1469, - "ᅡ": 1470, - "ᅢ": 1471, - "ᅥ": 1472, - "ᅦ": 1473, - "ᅧ": 1474, - "ᅩ": 1475, - "ᅪ": 1476, - "ᅭ": 1477, - "ᅮ": 1478, - "ᅯ": 1479, - "ᅲ": 1480, - "ᅳ": 1481, - "ᅴ": 1482, - "ᅵ": 1483, - "ᆨ": 1484, - "ᆫ": 1485, - "ᆯ": 1486, - "ᆷ": 1487, - "ᆸ": 1488, - "ᆼ": 1489, - "ᴬ": 1490, - "ᴮ": 1491, - "ᴰ": 1492, - "ᴵ": 1493, - "ᴺ": 1494, - "ᵀ": 1495, - "ᵃ": 1496, - "ᵇ": 1497, - "ᵈ": 1498, - "ᵉ": 1499, - "ᵍ": 1500, - "ᵏ": 1501, - "ᵐ": 1502, - "ᵒ": 1503, - "ᵖ": 1504, - "ᵗ": 1505, - "ᵘ": 1506, - "ᵢ": 1507, - "ᵣ": 1508, - "ᵤ": 1509, - "ᵥ": 1510, - "ᶜ": 1511, - "ᶠ": 1512, - "‐": 1513, - "‑": 1514, - "‒": 1515, - "–": 1516, - "—": 1517, - "―": 1518, - "‖": 1519, - "‘": 1520, - "’": 1521, - "‚": 1522, - "“": 1523, - "”": 1524, - "„": 1525, - "†": 1526, - "‡": 1527, - "•": 1528, - "…": 1529, - "‰": 1530, - "′": 1531, - "″": 1532, - "›": 1533, - "‿": 1534, - "⁄": 1535, - "⁰": 1536, - "ⁱ": 1537, - "⁴": 1538, - "⁵": 1539, - "⁶": 1540, - "⁷": 1541, - "⁸": 1542, - "⁹": 1543, - "⁺": 1544, - "⁻": 1545, - "ⁿ": 1546, - "₀": 1547, - "₁": 1548, - "₂": 1549, - "₃": 1550, - "₄": 1551, - "₅": 1552, - "₆": 1553, - "₇": 1554, - "₈": 1555, - "₉": 1556, - "₊": 1557, - "₍": 1558, - "₎": 1559, - "ₐ": 1560, - "ₑ": 1561, - "ₒ": 1562, - "ₓ": 1563, - "ₕ": 1564, - "ₖ": 1565, - "ₗ": 1566, - "ₘ": 1567, - "ₙ": 1568, - "ₚ": 1569, - "ₛ": 1570, - "ₜ": 1571, - "₤": 1572, - "₩": 1573, - "€": 1574, - "₱": 1575, - "₹": 1576, - "ℓ": 1577, - "№": 1578, - "ℝ": 1579, - "™": 1580, - "⅓": 1581, - "⅔": 1582, - "←": 1583, - "↑": 1584, - "→": 1585, - "↓": 1586, - "↔": 1587, - "↦": 1588, - "⇄": 1589, - "⇌": 1590, - "⇒": 1591, - "∂": 1592, - "∅": 1593, - "∆": 1594, - "∇": 1595, - "∈": 1596, - "−": 1597, - "∗": 1598, - "∘": 1599, - "√": 1600, - "∞": 1601, - "∧": 1602, - "∨": 1603, - "∩": 1604, - "∪": 1605, - "≈": 1606, - "≡": 1607, - "≤": 1608, - "≥": 1609, - "⊂": 1610, - "⊆": 1611, - "⊕": 1612, - "⊗": 1613, - "⋅": 1614, - "─": 1615, - "│": 1616, - "■": 1617, - "▪": 1618, - "●": 1619, - "★": 1620, - "☆": 1621, - "☉": 1622, - "♠": 1623, - "♣": 1624, - "♥": 1625, - "♦": 1626, - "♭": 1627, - "♯": 1628, - "⟨": 1629, - "⟩": 1630, - "ⱼ": 1631, - "⺩": 1632, - "⺼": 1633, - "⽥": 1634, - "、": 1635, - "。": 1636, - "〈": 1637, - "〉": 1638, - "《": 1639, - "》": 1640, - "「": 1641, - "」": 1642, - "『": 1643, - "』": 1644, - "〜": 1645, - "あ": 1646, - "い": 1647, - "う": 1648, - "え": 1649, - "お": 1650, - "か": 1651, - "き": 1652, - "く": 1653, - "け": 1654, - "こ": 1655, - "さ": 1656, - "し": 1657, - "す": 1658, - "せ": 1659, - "そ": 1660, - "た": 1661, - "ち": 1662, - "っ": 1663, - "つ": 1664, - "て": 1665, - "と": 1666, - "な": 1667, - "に": 1668, - "ぬ": 1669, - "ね": 1670, - "の": 1671, - "は": 1672, - "ひ": 1673, - "ふ": 1674, - "へ": 1675, - "ほ": 1676, - "ま": 1677, - "み": 1678, - "む": 1679, - "め": 1680, - "も": 1681, - "や": 1682, - "ゆ": 1683, - "よ": 1684, - "ら": 1685, - "り": 1686, - "る": 1687, - "れ": 1688, - "ろ": 1689, - "を": 1690, - "ん": 1691, - "ァ": 1692, - "ア": 1693, - "ィ": 1694, - "イ": 1695, - "ウ": 1696, - "ェ": 1697, - "エ": 1698, - "オ": 1699, - "カ": 1700, - "キ": 1701, - "ク": 1702, - "ケ": 1703, - "コ": 1704, - "サ": 1705, - "シ": 1706, - "ス": 1707, - "セ": 1708, - "タ": 1709, - "チ": 1710, - "ッ": 1711, - "ツ": 1712, - "テ": 1713, - "ト": 1714, - "ナ": 1715, - "ニ": 1716, - "ノ": 1717, - "ハ": 1718, - "ヒ": 1719, - "フ": 1720, - "ヘ": 1721, - "ホ": 1722, - "マ": 1723, - "ミ": 1724, - "ム": 1725, - "メ": 1726, - "モ": 1727, - "ャ": 1728, - "ュ": 1729, - "ョ": 1730, - "ラ": 1731, - "リ": 1732, - "ル": 1733, - "レ": 1734, - "ロ": 1735, - "ワ": 1736, - "ン": 1737, - "・": 1738, - "ー": 1739, - "一": 1740, - "三": 1741, - "上": 1742, - "下": 1743, - "不": 1744, - "世": 1745, - "中": 1746, - "主": 1747, - "久": 1748, - "之": 1749, - "也": 1750, - "事": 1751, - "二": 1752, - "五": 1753, - "井": 1754, - "京": 1755, - "人": 1756, - "亻": 1757, - "仁": 1758, - "介": 1759, - "代": 1760, - "仮": 1761, - "伊": 1762, - "会": 1763, - "佐": 1764, - "侍": 1765, - "保": 1766, - "信": 1767, - "健": 1768, - "元": 1769, - "光": 1770, - "八": 1771, - "公": 1772, - "内": 1773, - "出": 1774, - "分": 1775, - "前": 1776, - "劉": 1777, - "力": 1778, - "加": 1779, - "勝": 1780, - "北": 1781, - "区": 1782, - "十": 1783, - "千": 1784, - "南": 1785, - "博": 1786, - "原": 1787, - "口": 1788, - "古": 1789, - "史": 1790, - "司": 1791, - "合": 1792, - "吉": 1793, - "同": 1794, - "名": 1795, - "和": 1796, - "囗": 1797, - "四": 1798, - "国": 1799, - "國": 1800, - "土": 1801, - "地": 1802, - "坂": 1803, - "城": 1804, - "堂": 1805, - "場": 1806, - "士": 1807, - "夏": 1808, - "外": 1809, - "大": 1810, - "天": 1811, - "太": 1812, - "夫": 1813, - "奈": 1814, - "女": 1815, - "子": 1816, - "学": 1817, - "宀": 1818, - "宇": 1819, - "安": 1820, - "宗": 1821, - "定": 1822, - "宣": 1823, - "宮": 1824, - "家": 1825, - "宿": 1826, - "寺": 1827, - "將": 1828, - "小": 1829, - "尚": 1830, - "山": 1831, - "岡": 1832, - "島": 1833, - "崎": 1834, - "川": 1835, - "州": 1836, - "巿": 1837, - "帝": 1838, - "平": 1839, - "年": 1840, - "幸": 1841, - "广": 1842, - "弘": 1843, - "張": 1844, - "彳": 1845, - "後": 1846, - "御": 1847, - "德": 1848, - "心": 1849, - "忄": 1850, - "志": 1851, - "忠": 1852, - "愛": 1853, - "成": 1854, - "我": 1855, - "戦": 1856, - "戸": 1857, - "手": 1858, - "扌": 1859, - "政": 1860, - "文": 1861, - "新": 1862, - "方": 1863, - "日": 1864, - "明": 1865, - "星": 1866, - "春": 1867, - "昭": 1868, - "智": 1869, - "曲": 1870, - "書": 1871, - "月": 1872, - "有": 1873, - "朝": 1874, - "木": 1875, - "本": 1876, - "李": 1877, - "村": 1878, - "東": 1879, - "松": 1880, - "林": 1881, - "森": 1882, - "楊": 1883, - "樹": 1884, - "橋": 1885, - "歌": 1886, - "止": 1887, - "正": 1888, - "武": 1889, - "比": 1890, - "氏": 1891, - "民": 1892, - "水": 1893, - "氵": 1894, - "氷": 1895, - "永": 1896, - "江": 1897, - "沢": 1898, - "河": 1899, - "治": 1900, - "法": 1901, - "海": 1902, - "清": 1903, - "漢": 1904, - "瀬": 1905, - "火": 1906, - "版": 1907, - "犬": 1908, - "王": 1909, - "生": 1910, - "田": 1911, - "男": 1912, - "疒": 1913, - "発": 1914, - "白": 1915, - "的": 1916, - "皇": 1917, - "目": 1918, - "相": 1919, - "省": 1920, - "真": 1921, - "石": 1922, - "示": 1923, - "社": 1924, - "神": 1925, - "福": 1926, - "禾": 1927, - "秀": 1928, - "秋": 1929, - "空": 1930, - "立": 1931, - "章": 1932, - "竹": 1933, - "糹": 1934, - "美": 1935, - "義": 1936, - "耳": 1937, - "良": 1938, - "艹": 1939, - "花": 1940, - "英": 1941, - "華": 1942, - "葉": 1943, - "藤": 1944, - "行": 1945, - "街": 1946, - "西": 1947, - "見": 1948, - "訁": 1949, - "語": 1950, - "谷": 1951, - "貝": 1952, - "貴": 1953, - "車": 1954, - "軍": 1955, - "辶": 1956, - "道": 1957, - "郎": 1958, - "郡": 1959, - "部": 1960, - "都": 1961, - "里": 1962, - "野": 1963, - "金": 1964, - "鈴": 1965, - "镇": 1966, - "長": 1967, - "門": 1968, - "間": 1969, - "阝": 1970, - "阿": 1971, - "陳": 1972, - "陽": 1973, - "雄": 1974, - "青": 1975, - "面": 1976, - "風": 1977, - "食": 1978, - "香": 1979, - "馬": 1980, - "高": 1981, - "龍": 1982, - "龸": 1983, - "fi": 1984, - "fl": 1985, - "!": 1986, - "(": 1987, - ")": 1988, - ",": 1989, - "-": 1990, - ".": 1991, - "/": 1992, - ":": 1993, - "?": 1994, - "~": 1995, - "the": 1996, - "of": 1997, - "and": 1998, - "in": 1999, - "to": 2000, - "was": 2001, - "he": 2002, - "is": 2003, - "as": 2004, - "for": 2005, - "on": 2006, - "with": 2007, - "that": 2008, - "it": 2009, - "his": 2010, - "by": 2011, - "at": 2012, - "from": 2013, - "her": 2014, - "##s": 2015, - "she": 2016, - "you": 2017, - "had": 2018, - "an": 2019, - "were": 2020, - "but": 2021, - "be": 2022, - "this": 2023, - "are": 2024, - "not": 2025, - "my": 2026, - "they": 2027, - "one": 2028, - "which": 2029, - "or": 2030, - "have": 2031, - "him": 2032, - "me": 2033, - "first": 2034, - "all": 2035, - "also": 2036, - "their": 2037, - "has": 2038, - "up": 2039, - "who": 2040, - "out": 2041, - "been": 2042, - "when": 2043, - "after": 2044, - "there": 2045, - "into": 2046, - "new": 2047, - "two": 2048, - "its": 2049, - "##a": 2050, - "time": 2051, - "would": 2052, - "no": 2053, - "what": 2054, - "about": 2055, - "said": 2056, - "we": 2057, - "over": 2058, - "then": 2059, - "other": 2060, - "so": 2061, - "more": 2062, - "##e": 2063, - "can": 2064, - "if": 2065, - "like": 2066, - "back": 2067, - "them": 2068, - "only": 2069, - "some": 2070, - "could": 2071, - "##i": 2072, - "where": 2073, - "just": 2074, - "##ing": 2075, - "during": 2076, - "before": 2077, - "##n": 2078, - "do": 2079, - "##o": 2080, - "made": 2081, - "school": 2082, - "through": 2083, - "than": 2084, - "now": 2085, - "years": 2086, - "most": 2087, - "world": 2088, - "may": 2089, - "between": 2090, - "down": 2091, - "well": 2092, - "three": 2093, - "##d": 2094, - "year": 2095, - "while": 2096, - "will": 2097, - "##ed": 2098, - "##r": 2099, - "##y": 2100, - "later": 2101, - "##t": 2102, - "city": 2103, - "under": 2104, - "around": 2105, - "did": 2106, - "such": 2107, - "being": 2108, - "used": 2109, - "state": 2110, - "people": 2111, - "part": 2112, - "know": 2113, - "against": 2114, - "your": 2115, - "many": 2116, - "second": 2117, - "university": 2118, - "both": 2119, - "national": 2120, - "##er": 2121, - "these": 2122, - "don": 2123, - "known": 2124, - "off": 2125, - "way": 2126, - "until": 2127, - "re": 2128, - "how": 2129, - "even": 2130, - "get": 2131, - "head": 2132, - "...": 2133, - "didn": 2134, - "##ly": 2135, - "team": 2136, - "american": 2137, - "because": 2138, - "de": 2139, - "##l": 2140, - "born": 2141, - "united": 2142, - "film": 2143, - "since": 2144, - "still": 2145, - "long": 2146, - "work": 2147, - "south": 2148, - "us": 2149, - "became": 2150, - "any": 2151, - "high": 2152, - "again": 2153, - "day": 2154, - "family": 2155, - "see": 2156, - "right": 2157, - "man": 2158, - "eyes": 2159, - "house": 2160, - "season": 2161, - "war": 2162, - "states": 2163, - "including": 2164, - "took": 2165, - "life": 2166, - "north": 2167, - "same": 2168, - "each": 2169, - "called": 2170, - "name": 2171, - "much": 2172, - "place": 2173, - "however": 2174, - "go": 2175, - "four": 2176, - "group": 2177, - "another": 2178, - "found": 2179, - "won": 2180, - "area": 2181, - "here": 2182, - "going": 2183, - "10": 2184, - "away": 2185, - "series": 2186, - "left": 2187, - "home": 2188, - "music": 2189, - "best": 2190, - "make": 2191, - "hand": 2192, - "number": 2193, - "company": 2194, - "several": 2195, - "never": 2196, - "last": 2197, - "john": 2198, - "000": 2199, - "very": 2200, - "album": 2201, - "take": 2202, - "end": 2203, - "good": 2204, - "too": 2205, - "following": 2206, - "released": 2207, - "game": 2208, - "played": 2209, - "little": 2210, - "began": 2211, - "district": 2212, - "##m": 2213, - "old": 2214, - "want": 2215, - "those": 2216, - "side": 2217, - "held": 2218, - "own": 2219, - "early": 2220, - "county": 2221, - "ll": 2222, - "league": 2223, - "use": 2224, - "west": 2225, - "##u": 2226, - "face": 2227, - "think": 2228, - "##es": 2229, - "2010": 2230, - "government": 2231, - "##h": 2232, - "march": 2233, - "came": 2234, - "small": 2235, - "general": 2236, - "town": 2237, - "june": 2238, - "##on": 2239, - "line": 2240, - "based": 2241, - "something": 2242, - "##k": 2243, - "september": 2244, - "thought": 2245, - "looked": 2246, - "along": 2247, - "international": 2248, - "2011": 2249, - "air": 2250, - "july": 2251, - "club": 2252, - "went": 2253, - "january": 2254, - "october": 2255, - "our": 2256, - "august": 2257, - "april": 2258, - "york": 2259, - "12": 2260, - "few": 2261, - "2012": 2262, - "2008": 2263, - "east": 2264, - "show": 2265, - "member": 2266, - "college": 2267, - "2009": 2268, - "father": 2269, - "public": 2270, - "##us": 2271, - "come": 2272, - "men": 2273, - "five": 2274, - "set": 2275, - "station": 2276, - "church": 2277, - "##c": 2278, - "next": 2279, - "former": 2280, - "november": 2281, - "room": 2282, - "party": 2283, - "located": 2284, - "december": 2285, - "2013": 2286, - "age": 2287, - "got": 2288, - "2007": 2289, - "##g": 2290, - "system": 2291, - "let": 2292, - "love": 2293, - "2006": 2294, - "though": 2295, - "every": 2296, - "2014": 2297, - "look": 2298, - "song": 2299, - "water": 2300, - "century": 2301, - "without": 2302, - "body": 2303, - "black": 2304, - "night": 2305, - "within": 2306, - "great": 2307, - "women": 2308, - "single": 2309, - "ve": 2310, - "building": 2311, - "large": 2312, - "population": 2313, - "river": 2314, - "named": 2315, - "band": 2316, - "white": 2317, - "started": 2318, - "##an": 2319, - "once": 2320, - "15": 2321, - "20": 2322, - "should": 2323, - "18": 2324, - "2015": 2325, - "service": 2326, - "top": 2327, - "built": 2328, - "british": 2329, - "open": 2330, - "death": 2331, - "king": 2332, - "moved": 2333, - "local": 2334, - "times": 2335, - "children": 2336, - "february": 2337, - "book": 2338, - "why": 2339, - "11": 2340, - "door": 2341, - "need": 2342, - "president": 2343, - "order": 2344, - "final": 2345, - "road": 2346, - "wasn": 2347, - "although": 2348, - "due": 2349, - "major": 2350, - "died": 2351, - "village": 2352, - "third": 2353, - "knew": 2354, - "2016": 2355, - "asked": 2356, - "turned": 2357, - "st": 2358, - "wanted": 2359, - "say": 2360, - "##p": 2361, - "together": 2362, - "received": 2363, - "main": 2364, - "son": 2365, - "served": 2366, - "different": 2367, - "##en": 2368, - "behind": 2369, - "himself": 2370, - "felt": 2371, - "members": 2372, - "power": 2373, - "football": 2374, - "law": 2375, - "voice": 2376, - "play": 2377, - "##in": 2378, - "near": 2379, - "park": 2380, - "history": 2381, - "30": 2382, - "having": 2383, - "2005": 2384, - "16": 2385, - "##man": 2386, - "saw": 2387, - "mother": 2388, - "##al": 2389, - "army": 2390, - "point": 2391, - "front": 2392, - "help": 2393, - "english": 2394, - "street": 2395, - "art": 2396, - "late": 2397, - "hands": 2398, - "games": 2399, - "award": 2400, - "##ia": 2401, - "young": 2402, - "14": 2403, - "put": 2404, - "published": 2405, - "country": 2406, - "division": 2407, - "across": 2408, - "told": 2409, - "13": 2410, - "often": 2411, - "ever": 2412, - "french": 2413, - "london": 2414, - "center": 2415, - "six": 2416, - "red": 2417, - "2017": 2418, - "led": 2419, - "days": 2420, - "include": 2421, - "light": 2422, - "25": 2423, - "find": 2424, - "tell": 2425, - "among": 2426, - "species": 2427, - "really": 2428, - "according": 2429, - "central": 2430, - "half": 2431, - "2004": 2432, - "form": 2433, - "original": 2434, - "gave": 2435, - "office": 2436, - "making": 2437, - "enough": 2438, - "lost": 2439, - "full": 2440, - "opened": 2441, - "must": 2442, - "included": 2443, - "live": 2444, - "given": 2445, - "german": 2446, - "player": 2447, - "run": 2448, - "business": 2449, - "woman": 2450, - "community": 2451, - "cup": 2452, - "might": 2453, - "million": 2454, - "land": 2455, - "2000": 2456, - "court": 2457, - "development": 2458, - "17": 2459, - "short": 2460, - "round": 2461, - "ii": 2462, - "km": 2463, - "seen": 2464, - "class": 2465, - "story": 2466, - "always": 2467, - "become": 2468, - "sure": 2469, - "research": 2470, - "almost": 2471, - "director": 2472, - "council": 2473, - "la": 2474, - "##2": 2475, - "career": 2476, - "things": 2477, - "using": 2478, - "island": 2479, - "##z": 2480, - "couldn": 2481, - "car": 2482, - "##is": 2483, - "24": 2484, - "close": 2485, - "force": 2486, - "##1": 2487, - "better": 2488, - "free": 2489, - "support": 2490, - "control": 2491, - "field": 2492, - "students": 2493, - "2003": 2494, - "education": 2495, - "married": 2496, - "##b": 2497, - "nothing": 2498, - "worked": 2499, - "others": 2500, - "record": 2501, - "big": 2502, - "inside": 2503, - "level": 2504, - "anything": 2505, - "continued": 2506, - "give": 2507, - "james": 2508, - "##3": 2509, - "military": 2510, - "established": 2511, - "non": 2512, - "returned": 2513, - "feel": 2514, - "does": 2515, - "title": 2516, - "written": 2517, - "thing": 2518, - "feet": 2519, - "william": 2520, - "far": 2521, - "co": 2522, - "association": 2523, - "hard": 2524, - "already": 2525, - "2002": 2526, - "##ra": 2527, - "championship": 2528, - "human": 2529, - "western": 2530, - "100": 2531, - "##na": 2532, - "department": 2533, - "hall": 2534, - "role": 2535, - "various": 2536, - "production": 2537, - "21": 2538, - "19": 2539, - "heart": 2540, - "2001": 2541, - "living": 2542, - "fire": 2543, - "version": 2544, - "##ers": 2545, - "##f": 2546, - "television": 2547, - "royal": 2548, - "##4": 2549, - "produced": 2550, - "working": 2551, - "act": 2552, - "case": 2553, - "society": 2554, - "region": 2555, - "present": 2556, - "radio": 2557, - "period": 2558, - "looking": 2559, - "least": 2560, - "total": 2561, - "keep": 2562, - "england": 2563, - "wife": 2564, - "program": 2565, - "per": 2566, - "brother": 2567, - "mind": 2568, - "special": 2569, - "22": 2570, - "##le": 2571, - "am": 2572, - "works": 2573, - "soon": 2574, - "##6": 2575, - "political": 2576, - "george": 2577, - "services": 2578, - "taken": 2579, - "created": 2580, - "##7": 2581, - "further": 2582, - "able": 2583, - "reached": 2584, - "david": 2585, - "union": 2586, - "joined": 2587, - "upon": 2588, - "done": 2589, - "important": 2590, - "social": 2591, - "information": 2592, - "either": 2593, - "##ic": 2594, - "##x": 2595, - "appeared": 2596, - "position": 2597, - "ground": 2598, - "lead": 2599, - "rock": 2600, - "dark": 2601, - "election": 2602, - "23": 2603, - "board": 2604, - "france": 2605, - "hair": 2606, - "course": 2607, - "arms": 2608, - "site": 2609, - "police": 2610, - "girl": 2611, - "instead": 2612, - "real": 2613, - "sound": 2614, - "##v": 2615, - "words": 2616, - "moment": 2617, - "##te": 2618, - "someone": 2619, - "##8": 2620, - "summer": 2621, - "project": 2622, - "announced": 2623, - "san": 2624, - "less": 2625, - "wrote": 2626, - "past": 2627, - "followed": 2628, - "##5": 2629, - "blue": 2630, - "founded": 2631, - "al": 2632, - "finally": 2633, - "india": 2634, - "taking": 2635, - "records": 2636, - "america": 2637, - "##ne": 2638, - "1999": 2639, - "design": 2640, - "considered": 2641, - "northern": 2642, - "god": 2643, - "stop": 2644, - "battle": 2645, - "toward": 2646, - "european": 2647, - "outside": 2648, - "described": 2649, - "track": 2650, - "today": 2651, - "playing": 2652, - "language": 2653, - "28": 2654, - "call": 2655, - "26": 2656, - "heard": 2657, - "professional": 2658, - "low": 2659, - "australia": 2660, - "miles": 2661, - "california": 2662, - "win": 2663, - "yet": 2664, - "green": 2665, - "##ie": 2666, - "trying": 2667, - "blood": 2668, - "##ton": 2669, - "southern": 2670, - "science": 2671, - "maybe": 2672, - "everything": 2673, - "match": 2674, - "square": 2675, - "27": 2676, - "mouth": 2677, - "video": 2678, - "race": 2679, - "recorded": 2680, - "leave": 2681, - "above": 2682, - "##9": 2683, - "daughter": 2684, - "points": 2685, - "space": 2686, - "1998": 2687, - "museum": 2688, - "change": 2689, - "middle": 2690, - "common": 2691, - "##0": 2692, - "move": 2693, - "tv": 2694, - "post": 2695, - "##ta": 2696, - "lake": 2697, - "seven": 2698, - "tried": 2699, - "elected": 2700, - "closed": 2701, - "ten": 2702, - "paul": 2703, - "minister": 2704, - "##th": 2705, - "months": 2706, - "start": 2707, - "chief": 2708, - "return": 2709, - "canada": 2710, - "person": 2711, - "sea": 2712, - "release": 2713, - "similar": 2714, - "modern": 2715, - "brought": 2716, - "rest": 2717, - "hit": 2718, - "formed": 2719, - "mr": 2720, - "##la": 2721, - "1997": 2722, - "floor": 2723, - "event": 2724, - "doing": 2725, - "thomas": 2726, - "1996": 2727, - "robert": 2728, - "care": 2729, - "killed": 2730, - "training": 2731, - "star": 2732, - "week": 2733, - "needed": 2734, - "turn": 2735, - "finished": 2736, - "railway": 2737, - "rather": 2738, - "news": 2739, - "health": 2740, - "sent": 2741, - "example": 2742, - "ran": 2743, - "term": 2744, - "michael": 2745, - "coming": 2746, - "currently": 2747, - "yes": 2748, - "forces": 2749, - "despite": 2750, - "gold": 2751, - "areas": 2752, - "50": 2753, - "stage": 2754, - "fact": 2755, - "29": 2756, - "dead": 2757, - "says": 2758, - "popular": 2759, - "2018": 2760, - "originally": 2761, - "germany": 2762, - "probably": 2763, - "developed": 2764, - "result": 2765, - "pulled": 2766, - "friend": 2767, - "stood": 2768, - "money": 2769, - "running": 2770, - "mi": 2771, - "signed": 2772, - "word": 2773, - "songs": 2774, - "child": 2775, - "eventually": 2776, - "met": 2777, - "tour": 2778, - "average": 2779, - "teams": 2780, - "minutes": 2781, - "festival": 2782, - "current": 2783, - "deep": 2784, - "kind": 2785, - "1995": 2786, - "decided": 2787, - "usually": 2788, - "eastern": 2789, - "seemed": 2790, - "##ness": 2791, - "episode": 2792, - "bed": 2793, - "added": 2794, - "table": 2795, - "indian": 2796, - "private": 2797, - "charles": 2798, - "route": 2799, - "available": 2800, - "idea": 2801, - "throughout": 2802, - "centre": 2803, - "addition": 2804, - "appointed": 2805, - "style": 2806, - "1994": 2807, - "books": 2808, - "eight": 2809, - "construction": 2810, - "press": 2811, - "mean": 2812, - "wall": 2813, - "friends": 2814, - "remained": 2815, - "schools": 2816, - "study": 2817, - "##ch": 2818, - "##um": 2819, - "institute": 2820, - "oh": 2821, - "chinese": 2822, - "sometimes": 2823, - "events": 2824, - "possible": 2825, - "1992": 2826, - "australian": 2827, - "type": 2828, - "brown": 2829, - "forward": 2830, - "talk": 2831, - "process": 2832, - "food": 2833, - "debut": 2834, - "seat": 2835, - "performance": 2836, - "committee": 2837, - "features": 2838, - "character": 2839, - "arts": 2840, - "herself": 2841, - "else": 2842, - "lot": 2843, - "strong": 2844, - "russian": 2845, - "range": 2846, - "hours": 2847, - "peter": 2848, - "arm": 2849, - "##da": 2850, - "morning": 2851, - "dr": 2852, - "sold": 2853, - "##ry": 2854, - "quickly": 2855, - "directed": 2856, - "1993": 2857, - "guitar": 2858, - "china": 2859, - "##w": 2860, - "31": 2861, - "list": 2862, - "##ma": 2863, - "performed": 2864, - "media": 2865, - "uk": 2866, - "players": 2867, - "smile": 2868, - "##rs": 2869, - "myself": 2870, - "40": 2871, - "placed": 2872, - "coach": 2873, - "province": 2874, - "towards": 2875, - "wouldn": 2876, - "leading": 2877, - "whole": 2878, - "boy": 2879, - "official": 2880, - "designed": 2881, - "grand": 2882, - "census": 2883, - "##el": 2884, - "europe": 2885, - "attack": 2886, - "japanese": 2887, - "henry": 2888, - "1991": 2889, - "##re": 2890, - "##os": 2891, - "cross": 2892, - "getting": 2893, - "alone": 2894, - "action": 2895, - "lower": 2896, - "network": 2897, - "wide": 2898, - "washington": 2899, - "japan": 2900, - "1990": 2901, - "hospital": 2902, - "believe": 2903, - "changed": 2904, - "sister": 2905, - "##ar": 2906, - "hold": 2907, - "gone": 2908, - "sir": 2909, - "hadn": 2910, - "ship": 2911, - "##ka": 2912, - "studies": 2913, - "academy": 2914, - "shot": 2915, - "rights": 2916, - "below": 2917, - "base": 2918, - "bad": 2919, - "involved": 2920, - "kept": 2921, - "largest": 2922, - "##ist": 2923, - "bank": 2924, - "future": 2925, - "especially": 2926, - "beginning": 2927, - "mark": 2928, - "movement": 2929, - "section": 2930, - "female": 2931, - "magazine": 2932, - "plan": 2933, - "professor": 2934, - "lord": 2935, - "longer": 2936, - "##ian": 2937, - "sat": 2938, - "walked": 2939, - "hill": 2940, - "actually": 2941, - "civil": 2942, - "energy": 2943, - "model": 2944, - "families": 2945, - "size": 2946, - "thus": 2947, - "aircraft": 2948, - "completed": 2949, - "includes": 2950, - "data": 2951, - "captain": 2952, - "##or": 2953, - "fight": 2954, - "vocals": 2955, - "featured": 2956, - "richard": 2957, - "bridge": 2958, - "fourth": 2959, - "1989": 2960, - "officer": 2961, - "stone": 2962, - "hear": 2963, - "##ism": 2964, - "means": 2965, - "medical": 2966, - "groups": 2967, - "management": 2968, - "self": 2969, - "lips": 2970, - "competition": 2971, - "entire": 2972, - "lived": 2973, - "technology": 2974, - "leaving": 2975, - "federal": 2976, - "tournament": 2977, - "bit": 2978, - "passed": 2979, - "hot": 2980, - "independent": 2981, - "awards": 2982, - "kingdom": 2983, - "mary": 2984, - "spent": 2985, - "fine": 2986, - "doesn": 2987, - "reported": 2988, - "##ling": 2989, - "jack": 2990, - "fall": 2991, - "raised": 2992, - "itself": 2993, - "stay": 2994, - "true": 2995, - "studio": 2996, - "1988": 2997, - "sports": 2998, - "replaced": 2999, - "paris": 3000, - "systems": 3001, - "saint": 3002, - "leader": 3003, - "theatre": 3004, - "whose": 3005, - "market": 3006, - "capital": 3007, - "parents": 3008, - "spanish": 3009, - "canadian": 3010, - "earth": 3011, - "##ity": 3012, - "cut": 3013, - "degree": 3014, - "writing": 3015, - "bay": 3016, - "christian": 3017, - "awarded": 3018, - "natural": 3019, - "higher": 3020, - "bill": 3021, - "##as": 3022, - "coast": 3023, - "provided": 3024, - "previous": 3025, - "senior": 3026, - "ft": 3027, - "valley": 3028, - "organization": 3029, - "stopped": 3030, - "onto": 3031, - "countries": 3032, - "parts": 3033, - "conference": 3034, - "queen": 3035, - "security": 3036, - "interest": 3037, - "saying": 3038, - "allowed": 3039, - "master": 3040, - "earlier": 3041, - "phone": 3042, - "matter": 3043, - "smith": 3044, - "winning": 3045, - "try": 3046, - "happened": 3047, - "moving": 3048, - "campaign": 3049, - "los": 3050, - "##ley": 3051, - "breath": 3052, - "nearly": 3053, - "mid": 3054, - "1987": 3055, - "certain": 3056, - "girls": 3057, - "date": 3058, - "italian": 3059, - "african": 3060, - "standing": 3061, - "fell": 3062, - "artist": 3063, - "##ted": 3064, - "shows": 3065, - "deal": 3066, - "mine": 3067, - "industry": 3068, - "1986": 3069, - "##ng": 3070, - "everyone": 3071, - "republic": 3072, - "provide": 3073, - "collection": 3074, - "library": 3075, - "student": 3076, - "##ville": 3077, - "primary": 3078, - "owned": 3079, - "older": 3080, - "via": 3081, - "heavy": 3082, - "1st": 3083, - "makes": 3084, - "##able": 3085, - "attention": 3086, - "anyone": 3087, - "africa": 3088, - "##ri": 3089, - "stated": 3090, - "length": 3091, - "ended": 3092, - "fingers": 3093, - "command": 3094, - "staff": 3095, - "skin": 3096, - "foreign": 3097, - "opening": 3098, - "governor": 3099, - "okay": 3100, - "medal": 3101, - "kill": 3102, - "sun": 3103, - "cover": 3104, - "job": 3105, - "1985": 3106, - "introduced": 3107, - "chest": 3108, - "hell": 3109, - "feeling": 3110, - "##ies": 3111, - "success": 3112, - "meet": 3113, - "reason": 3114, - "standard": 3115, - "meeting": 3116, - "novel": 3117, - "1984": 3118, - "trade": 3119, - "source": 3120, - "buildings": 3121, - "##land": 3122, - "rose": 3123, - "guy": 3124, - "goal": 3125, - "##ur": 3126, - "chapter": 3127, - "native": 3128, - "husband": 3129, - "previously": 3130, - "unit": 3131, - "limited": 3132, - "entered": 3133, - "weeks": 3134, - "producer": 3135, - "operations": 3136, - "mountain": 3137, - "takes": 3138, - "covered": 3139, - "forced": 3140, - "related": 3141, - "roman": 3142, - "complete": 3143, - "successful": 3144, - "key": 3145, - "texas": 3146, - "cold": 3147, - "##ya": 3148, - "channel": 3149, - "1980": 3150, - "traditional": 3151, - "films": 3152, - "dance": 3153, - "clear": 3154, - "approximately": 3155, - "500": 3156, - "nine": 3157, - "van": 3158, - "prince": 3159, - "question": 3160, - "active": 3161, - "tracks": 3162, - "ireland": 3163, - "regional": 3164, - "silver": 3165, - "author": 3166, - "personal": 3167, - "sense": 3168, - "operation": 3169, - "##ine": 3170, - "economic": 3171, - "1983": 3172, - "holding": 3173, - "twenty": 3174, - "isbn": 3175, - "additional": 3176, - "speed": 3177, - "hour": 3178, - "edition": 3179, - "regular": 3180, - "historic": 3181, - "places": 3182, - "whom": 3183, - "shook": 3184, - "movie": 3185, - "km²": 3186, - "secretary": 3187, - "prior": 3188, - "report": 3189, - "chicago": 3190, - "read": 3191, - "foundation": 3192, - "view": 3193, - "engine": 3194, - "scored": 3195, - "1982": 3196, - "units": 3197, - "ask": 3198, - "airport": 3199, - "property": 3200, - "ready": 3201, - "immediately": 3202, - "lady": 3203, - "month": 3204, - "listed": 3205, - "contract": 3206, - "##de": 3207, - "manager": 3208, - "themselves": 3209, - "lines": 3210, - "##ki": 3211, - "navy": 3212, - "writer": 3213, - "meant": 3214, - "##ts": 3215, - "runs": 3216, - "##ro": 3217, - "practice": 3218, - "championships": 3219, - "singer": 3220, - "glass": 3221, - "commission": 3222, - "required": 3223, - "forest": 3224, - "starting": 3225, - "culture": 3226, - "generally": 3227, - "giving": 3228, - "access": 3229, - "attended": 3230, - "test": 3231, - "couple": 3232, - "stand": 3233, - "catholic": 3234, - "martin": 3235, - "caught": 3236, - "executive": 3237, - "##less": 3238, - "eye": 3239, - "##ey": 3240, - "thinking": 3241, - "chair": 3242, - "quite": 3243, - "shoulder": 3244, - "1979": 3245, - "hope": 3246, - "decision": 3247, - "plays": 3248, - "defeated": 3249, - "municipality": 3250, - "whether": 3251, - "structure": 3252, - "offered": 3253, - "slowly": 3254, - "pain": 3255, - "ice": 3256, - "direction": 3257, - "##ion": 3258, - "paper": 3259, - "mission": 3260, - "1981": 3261, - "mostly": 3262, - "200": 3263, - "noted": 3264, - "individual": 3265, - "managed": 3266, - "nature": 3267, - "lives": 3268, - "plant": 3269, - "##ha": 3270, - "helped": 3271, - "except": 3272, - "studied": 3273, - "computer": 3274, - "figure": 3275, - "relationship": 3276, - "issue": 3277, - "significant": 3278, - "loss": 3279, - "die": 3280, - "smiled": 3281, - "gun": 3282, - "ago": 3283, - "highest": 3284, - "1972": 3285, - "##am": 3286, - "male": 3287, - "bring": 3288, - "goals": 3289, - "mexico": 3290, - "problem": 3291, - "distance": 3292, - "commercial": 3293, - "completely": 3294, - "location": 3295, - "annual": 3296, - "famous": 3297, - "drive": 3298, - "1976": 3299, - "neck": 3300, - "1978": 3301, - "surface": 3302, - "caused": 3303, - "italy": 3304, - "understand": 3305, - "greek": 3306, - "highway": 3307, - "wrong": 3308, - "hotel": 3309, - "comes": 3310, - "appearance": 3311, - "joseph": 3312, - "double": 3313, - "issues": 3314, - "musical": 3315, - "companies": 3316, - "castle": 3317, - "income": 3318, - "review": 3319, - "assembly": 3320, - "bass": 3321, - "initially": 3322, - "parliament": 3323, - "artists": 3324, - "experience": 3325, - "1974": 3326, - "particular": 3327, - "walk": 3328, - "foot": 3329, - "engineering": 3330, - "talking": 3331, - "window": 3332, - "dropped": 3333, - "##ter": 3334, - "miss": 3335, - "baby": 3336, - "boys": 3337, - "break": 3338, - "1975": 3339, - "stars": 3340, - "edge": 3341, - "remember": 3342, - "policy": 3343, - "carried": 3344, - "train": 3345, - "stadium": 3346, - "bar": 3347, - "sex": 3348, - "angeles": 3349, - "evidence": 3350, - "##ge": 3351, - "becoming": 3352, - "assistant": 3353, - "soviet": 3354, - "1977": 3355, - "upper": 3356, - "step": 3357, - "wing": 3358, - "1970": 3359, - "youth": 3360, - "financial": 3361, - "reach": 3362, - "##ll": 3363, - "actor": 3364, - "numerous": 3365, - "##se": 3366, - "##st": 3367, - "nodded": 3368, - "arrived": 3369, - "##ation": 3370, - "minute": 3371, - "##nt": 3372, - "believed": 3373, - "sorry": 3374, - "complex": 3375, - "beautiful": 3376, - "victory": 3377, - "associated": 3378, - "temple": 3379, - "1968": 3380, - "1973": 3381, - "chance": 3382, - "perhaps": 3383, - "metal": 3384, - "##son": 3385, - "1945": 3386, - "bishop": 3387, - "##et": 3388, - "lee": 3389, - "launched": 3390, - "particularly": 3391, - "tree": 3392, - "le": 3393, - "retired": 3394, - "subject": 3395, - "prize": 3396, - "contains": 3397, - "yeah": 3398, - "theory": 3399, - "empire": 3400, - "##ce": 3401, - "suddenly": 3402, - "waiting": 3403, - "trust": 3404, - "recording": 3405, - "##to": 3406, - "happy": 3407, - "terms": 3408, - "camp": 3409, - "champion": 3410, - "1971": 3411, - "religious": 3412, - "pass": 3413, - "zealand": 3414, - "names": 3415, - "2nd": 3416, - "port": 3417, - "ancient": 3418, - "tom": 3419, - "corner": 3420, - "represented": 3421, - "watch": 3422, - "legal": 3423, - "anti": 3424, - "justice": 3425, - "cause": 3426, - "watched": 3427, - "brothers": 3428, - "45": 3429, - "material": 3430, - "changes": 3431, - "simply": 3432, - "response": 3433, - "louis": 3434, - "fast": 3435, - "##ting": 3436, - "answer": 3437, - "60": 3438, - "historical": 3439, - "1969": 3440, - "stories": 3441, - "straight": 3442, - "create": 3443, - "feature": 3444, - "increased": 3445, - "rate": 3446, - "administration": 3447, - "virginia": 3448, - "el": 3449, - "activities": 3450, - "cultural": 3451, - "overall": 3452, - "winner": 3453, - "programs": 3454, - "basketball": 3455, - "legs": 3456, - "guard": 3457, - "beyond": 3458, - "cast": 3459, - "doctor": 3460, - "mm": 3461, - "flight": 3462, - "results": 3463, - "remains": 3464, - "cost": 3465, - "effect": 3466, - "winter": 3467, - "##ble": 3468, - "larger": 3469, - "islands": 3470, - "problems": 3471, - "chairman": 3472, - "grew": 3473, - "commander": 3474, - "isn": 3475, - "1967": 3476, - "pay": 3477, - "failed": 3478, - "selected": 3479, - "hurt": 3480, - "fort": 3481, - "box": 3482, - "regiment": 3483, - "majority": 3484, - "journal": 3485, - "35": 3486, - "edward": 3487, - "plans": 3488, - "##ke": 3489, - "##ni": 3490, - "shown": 3491, - "pretty": 3492, - "irish": 3493, - "characters": 3494, - "directly": 3495, - "scene": 3496, - "likely": 3497, - "operated": 3498, - "allow": 3499, - "spring": 3500, - "##j": 3501, - "junior": 3502, - "matches": 3503, - "looks": 3504, - "mike": 3505, - "houses": 3506, - "fellow": 3507, - "##tion": 3508, - "beach": 3509, - "marriage": 3510, - "##ham": 3511, - "##ive": 3512, - "rules": 3513, - "oil": 3514, - "65": 3515, - "florida": 3516, - "expected": 3517, - "nearby": 3518, - "congress": 3519, - "sam": 3520, - "peace": 3521, - "recent": 3522, - "iii": 3523, - "wait": 3524, - "subsequently": 3525, - "cell": 3526, - "##do": 3527, - "variety": 3528, - "serving": 3529, - "agreed": 3530, - "please": 3531, - "poor": 3532, - "joe": 3533, - "pacific": 3534, - "attempt": 3535, - "wood": 3536, - "democratic": 3537, - "piece": 3538, - "prime": 3539, - "##ca": 3540, - "rural": 3541, - "mile": 3542, - "touch": 3543, - "appears": 3544, - "township": 3545, - "1964": 3546, - "1966": 3547, - "soldiers": 3548, - "##men": 3549, - "##ized": 3550, - "1965": 3551, - "pennsylvania": 3552, - "closer": 3553, - "fighting": 3554, - "claimed": 3555, - "score": 3556, - "jones": 3557, - "physical": 3558, - "editor": 3559, - "##ous": 3560, - "filled": 3561, - "genus": 3562, - "specific": 3563, - "sitting": 3564, - "super": 3565, - "mom": 3566, - "##va": 3567, - "therefore": 3568, - "supported": 3569, - "status": 3570, - "fear": 3571, - "cases": 3572, - "store": 3573, - "meaning": 3574, - "wales": 3575, - "minor": 3576, - "spain": 3577, - "tower": 3578, - "focus": 3579, - "vice": 3580, - "frank": 3581, - "follow": 3582, - "parish": 3583, - "separate": 3584, - "golden": 3585, - "horse": 3586, - "fifth": 3587, - "remaining": 3588, - "branch": 3589, - "32": 3590, - "presented": 3591, - "stared": 3592, - "##id": 3593, - "uses": 3594, - "secret": 3595, - "forms": 3596, - "##co": 3597, - "baseball": 3598, - "exactly": 3599, - "##ck": 3600, - "choice": 3601, - "note": 3602, - "discovered": 3603, - "travel": 3604, - "composed": 3605, - "truth": 3606, - "russia": 3607, - "ball": 3608, - "color": 3609, - "kiss": 3610, - "dad": 3611, - "wind": 3612, - "continue": 3613, - "ring": 3614, - "referred": 3615, - "numbers": 3616, - "digital": 3617, - "greater": 3618, - "##ns": 3619, - "metres": 3620, - "slightly": 3621, - "direct": 3622, - "increase": 3623, - "1960": 3624, - "responsible": 3625, - "crew": 3626, - "rule": 3627, - "trees": 3628, - "troops": 3629, - "##no": 3630, - "broke": 3631, - "goes": 3632, - "individuals": 3633, - "hundred": 3634, - "weight": 3635, - "creek": 3636, - "sleep": 3637, - "memory": 3638, - "defense": 3639, - "provides": 3640, - "ordered": 3641, - "code": 3642, - "value": 3643, - "jewish": 3644, - "windows": 3645, - "1944": 3646, - "safe": 3647, - "judge": 3648, - "whatever": 3649, - "corps": 3650, - "realized": 3651, - "growing": 3652, - "pre": 3653, - "##ga": 3654, - "cities": 3655, - "alexander": 3656, - "gaze": 3657, - "lies": 3658, - "spread": 3659, - "scott": 3660, - "letter": 3661, - "showed": 3662, - "situation": 3663, - "mayor": 3664, - "transport": 3665, - "watching": 3666, - "workers": 3667, - "extended": 3668, - "##li": 3669, - "expression": 3670, - "normal": 3671, - "##ment": 3672, - "chart": 3673, - "multiple": 3674, - "border": 3675, - "##ba": 3676, - "host": 3677, - "##ner": 3678, - "daily": 3679, - "mrs": 3680, - "walls": 3681, - "piano": 3682, - "##ko": 3683, - "heat": 3684, - "cannot": 3685, - "##ate": 3686, - "earned": 3687, - "products": 3688, - "drama": 3689, - "era": 3690, - "authority": 3691, - "seasons": 3692, - "join": 3693, - "grade": 3694, - "##io": 3695, - "sign": 3696, - "difficult": 3697, - "machine": 3698, - "1963": 3699, - "territory": 3700, - "mainly": 3701, - "##wood": 3702, - "stations": 3703, - "squadron": 3704, - "1962": 3705, - "stepped": 3706, - "iron": 3707, - "19th": 3708, - "##led": 3709, - "serve": 3710, - "appear": 3711, - "sky": 3712, - "speak": 3713, - "broken": 3714, - "charge": 3715, - "knowledge": 3716, - "kilometres": 3717, - "removed": 3718, - "ships": 3719, - "article": 3720, - "campus": 3721, - "simple": 3722, - "##ty": 3723, - "pushed": 3724, - "britain": 3725, - "##ve": 3726, - "leaves": 3727, - "recently": 3728, - "cd": 3729, - "soft": 3730, - "boston": 3731, - "latter": 3732, - "easy": 3733, - "acquired": 3734, - "poland": 3735, - "##sa": 3736, - "quality": 3737, - "officers": 3738, - "presence": 3739, - "planned": 3740, - "nations": 3741, - "mass": 3742, - "broadcast": 3743, - "jean": 3744, - "share": 3745, - "image": 3746, - "influence": 3747, - "wild": 3748, - "offer": 3749, - "emperor": 3750, - "electric": 3751, - "reading": 3752, - "headed": 3753, - "ability": 3754, - "promoted": 3755, - "yellow": 3756, - "ministry": 3757, - "1942": 3758, - "throat": 3759, - "smaller": 3760, - "politician": 3761, - "##by": 3762, - "latin": 3763, - "spoke": 3764, - "cars": 3765, - "williams": 3766, - "males": 3767, - "lack": 3768, - "pop": 3769, - "80": 3770, - "##ier": 3771, - "acting": 3772, - "seeing": 3773, - "consists": 3774, - "##ti": 3775, - "estate": 3776, - "1961": 3777, - "pressure": 3778, - "johnson": 3779, - "newspaper": 3780, - "jr": 3781, - "chris": 3782, - "olympics": 3783, - "online": 3784, - "conditions": 3785, - "beat": 3786, - "elements": 3787, - "walking": 3788, - "vote": 3789, - "##field": 3790, - "needs": 3791, - "carolina": 3792, - "text": 3793, - "featuring": 3794, - "global": 3795, - "block": 3796, - "shirt": 3797, - "levels": 3798, - "francisco": 3799, - "purpose": 3800, - "females": 3801, - "et": 3802, - "dutch": 3803, - "duke": 3804, - "ahead": 3805, - "gas": 3806, - "twice": 3807, - "safety": 3808, - "serious": 3809, - "turning": 3810, - "highly": 3811, - "lieutenant": 3812, - "firm": 3813, - "maria": 3814, - "amount": 3815, - "mixed": 3816, - "daniel": 3817, - "proposed": 3818, - "perfect": 3819, - "agreement": 3820, - "affairs": 3821, - "3rd": 3822, - "seconds": 3823, - "contemporary": 3824, - "paid": 3825, - "1943": 3826, - "prison": 3827, - "save": 3828, - "kitchen": 3829, - "label": 3830, - "administrative": 3831, - "intended": 3832, - "constructed": 3833, - "academic": 3834, - "nice": 3835, - "teacher": 3836, - "races": 3837, - "1956": 3838, - "formerly": 3839, - "corporation": 3840, - "ben": 3841, - "nation": 3842, - "issued": 3843, - "shut": 3844, - "1958": 3845, - "drums": 3846, - "housing": 3847, - "victoria": 3848, - "seems": 3849, - "opera": 3850, - "1959": 3851, - "graduated": 3852, - "function": 3853, - "von": 3854, - "mentioned": 3855, - "picked": 3856, - "build": 3857, - "recognized": 3858, - "shortly": 3859, - "protection": 3860, - "picture": 3861, - "notable": 3862, - "exchange": 3863, - "elections": 3864, - "1980s": 3865, - "loved": 3866, - "percent": 3867, - "racing": 3868, - "fish": 3869, - "elizabeth": 3870, - "garden": 3871, - "volume": 3872, - "hockey": 3873, - "1941": 3874, - "beside": 3875, - "settled": 3876, - "##ford": 3877, - "1940": 3878, - "competed": 3879, - "replied": 3880, - "drew": 3881, - "1948": 3882, - "actress": 3883, - "marine": 3884, - "scotland": 3885, - "steel": 3886, - "glanced": 3887, - "farm": 3888, - "steve": 3889, - "1957": 3890, - "risk": 3891, - "tonight": 3892, - "positive": 3893, - "magic": 3894, - "singles": 3895, - "effects": 3896, - "gray": 3897, - "screen": 3898, - "dog": 3899, - "##ja": 3900, - "residents": 3901, - "bus": 3902, - "sides": 3903, - "none": 3904, - "secondary": 3905, - "literature": 3906, - "polish": 3907, - "destroyed": 3908, - "flying": 3909, - "founder": 3910, - "households": 3911, - "1939": 3912, - "lay": 3913, - "reserve": 3914, - "usa": 3915, - "gallery": 3916, - "##ler": 3917, - "1946": 3918, - "industrial": 3919, - "younger": 3920, - "approach": 3921, - "appearances": 3922, - "urban": 3923, - "ones": 3924, - "1950": 3925, - "finish": 3926, - "avenue": 3927, - "powerful": 3928, - "fully": 3929, - "growth": 3930, - "page": 3931, - "honor": 3932, - "jersey": 3933, - "projects": 3934, - "advanced": 3935, - "revealed": 3936, - "basic": 3937, - "90": 3938, - "infantry": 3939, - "pair": 3940, - "equipment": 3941, - "visit": 3942, - "33": 3943, - "evening": 3944, - "search": 3945, - "grant": 3946, - "effort": 3947, - "solo": 3948, - "treatment": 3949, - "buried": 3950, - "republican": 3951, - "primarily": 3952, - "bottom": 3953, - "owner": 3954, - "1970s": 3955, - "israel": 3956, - "gives": 3957, - "jim": 3958, - "dream": 3959, - "bob": 3960, - "remain": 3961, - "spot": 3962, - "70": 3963, - "notes": 3964, - "produce": 3965, - "champions": 3966, - "contact": 3967, - "ed": 3968, - "soul": 3969, - "accepted": 3970, - "ways": 3971, - "del": 3972, - "##ally": 3973, - "losing": 3974, - "split": 3975, - "price": 3976, - "capacity": 3977, - "basis": 3978, - "trial": 3979, - "questions": 3980, - "##ina": 3981, - "1955": 3982, - "20th": 3983, - "guess": 3984, - "officially": 3985, - "memorial": 3986, - "naval": 3987, - "initial": 3988, - "##ization": 3989, - "whispered": 3990, - "median": 3991, - "engineer": 3992, - "##ful": 3993, - "sydney": 3994, - "##go": 3995, - "columbia": 3996, - "strength": 3997, - "300": 3998, - "1952": 3999, - "tears": 4000, - "senate": 4001, - "00": 4002, - "card": 4003, - "asian": 4004, - "agent": 4005, - "1947": 4006, - "software": 4007, - "44": 4008, - "draw": 4009, - "warm": 4010, - "supposed": 4011, - "com": 4012, - "pro": 4013, - "##il": 4014, - "transferred": 4015, - "leaned": 4016, - "##at": 4017, - "candidate": 4018, - "escape": 4019, - "mountains": 4020, - "asia": 4021, - "potential": 4022, - "activity": 4023, - "entertainment": 4024, - "seem": 4025, - "traffic": 4026, - "jackson": 4027, - "murder": 4028, - "36": 4029, - "slow": 4030, - "product": 4031, - "orchestra": 4032, - "haven": 4033, - "agency": 4034, - "bbc": 4035, - "taught": 4036, - "website": 4037, - "comedy": 4038, - "unable": 4039, - "storm": 4040, - "planning": 4041, - "albums": 4042, - "rugby": 4043, - "environment": 4044, - "scientific": 4045, - "grabbed": 4046, - "protect": 4047, - "##hi": 4048, - "boat": 4049, - "typically": 4050, - "1954": 4051, - "1953": 4052, - "damage": 4053, - "principal": 4054, - "divided": 4055, - "dedicated": 4056, - "mount": 4057, - "ohio": 4058, - "##berg": 4059, - "pick": 4060, - "fought": 4061, - "driver": 4062, - "##der": 4063, - "empty": 4064, - "shoulders": 4065, - "sort": 4066, - "thank": 4067, - "berlin": 4068, - "prominent": 4069, - "account": 4070, - "freedom": 4071, - "necessary": 4072, - "efforts": 4073, - "alex": 4074, - "headquarters": 4075, - "follows": 4076, - "alongside": 4077, - "des": 4078, - "simon": 4079, - "andrew": 4080, - "suggested": 4081, - "operating": 4082, - "learning": 4083, - "steps": 4084, - "1949": 4085, - "sweet": 4086, - "technical": 4087, - "begin": 4088, - "easily": 4089, - "34": 4090, - "teeth": 4091, - "speaking": 4092, - "settlement": 4093, - "scale": 4094, - "##sh": 4095, - "renamed": 4096, - "ray": 4097, - "max": 4098, - "enemy": 4099, - "semi": 4100, - "joint": 4101, - "compared": 4102, - "##rd": 4103, - "scottish": 4104, - "leadership": 4105, - "analysis": 4106, - "offers": 4107, - "georgia": 4108, - "pieces": 4109, - "captured": 4110, - "animal": 4111, - "deputy": 4112, - "guest": 4113, - "organized": 4114, - "##lin": 4115, - "tony": 4116, - "combined": 4117, - "method": 4118, - "challenge": 4119, - "1960s": 4120, - "huge": 4121, - "wants": 4122, - "battalion": 4123, - "sons": 4124, - "rise": 4125, - "crime": 4126, - "types": 4127, - "facilities": 4128, - "telling": 4129, - "path": 4130, - "1951": 4131, - "platform": 4132, - "sit": 4133, - "1990s": 4134, - "##lo": 4135, - "tells": 4136, - "assigned": 4137, - "rich": 4138, - "pull": 4139, - "##ot": 4140, - "commonly": 4141, - "alive": 4142, - "##za": 4143, - "letters": 4144, - "concept": 4145, - "conducted": 4146, - "wearing": 4147, - "happen": 4148, - "bought": 4149, - "becomes": 4150, - "holy": 4151, - "gets": 4152, - "ocean": 4153, - "defeat": 4154, - "languages": 4155, - "purchased": 4156, - "coffee": 4157, - "occurred": 4158, - "titled": 4159, - "##q": 4160, - "declared": 4161, - "applied": 4162, - "sciences": 4163, - "concert": 4164, - "sounds": 4165, - "jazz": 4166, - "brain": 4167, - "##me": 4168, - "painting": 4169, - "fleet": 4170, - "tax": 4171, - "nick": 4172, - "##ius": 4173, - "michigan": 4174, - "count": 4175, - "animals": 4176, - "leaders": 4177, - "episodes": 4178, - "##line": 4179, - "content": 4180, - "##den": 4181, - "birth": 4182, - "##it": 4183, - "clubs": 4184, - "64": 4185, - "palace": 4186, - "critical": 4187, - "refused": 4188, - "fair": 4189, - "leg": 4190, - "laughed": 4191, - "returning": 4192, - "surrounding": 4193, - "participated": 4194, - "formation": 4195, - "lifted": 4196, - "pointed": 4197, - "connected": 4198, - "rome": 4199, - "medicine": 4200, - "laid": 4201, - "taylor": 4202, - "santa": 4203, - "powers": 4204, - "adam": 4205, - "tall": 4206, - "shared": 4207, - "focused": 4208, - "knowing": 4209, - "yards": 4210, - "entrance": 4211, - "falls": 4212, - "##wa": 4213, - "calling": 4214, - "##ad": 4215, - "sources": 4216, - "chosen": 4217, - "beneath": 4218, - "resources": 4219, - "yard": 4220, - "##ite": 4221, - "nominated": 4222, - "silence": 4223, - "zone": 4224, - "defined": 4225, - "##que": 4226, - "gained": 4227, - "thirty": 4228, - "38": 4229, - "bodies": 4230, - "moon": 4231, - "##ard": 4232, - "adopted": 4233, - "christmas": 4234, - "widely": 4235, - "register": 4236, - "apart": 4237, - "iran": 4238, - "premier": 4239, - "serves": 4240, - "du": 4241, - "unknown": 4242, - "parties": 4243, - "##les": 4244, - "generation": 4245, - "##ff": 4246, - "continues": 4247, - "quick": 4248, - "fields": 4249, - "brigade": 4250, - "quiet": 4251, - "teaching": 4252, - "clothes": 4253, - "impact": 4254, - "weapons": 4255, - "partner": 4256, - "flat": 4257, - "theater": 4258, - "supreme": 4259, - "1938": 4260, - "37": 4261, - "relations": 4262, - "##tor": 4263, - "plants": 4264, - "suffered": 4265, - "1936": 4266, - "wilson": 4267, - "kids": 4268, - "begins": 4269, - "##age": 4270, - "1918": 4271, - "seats": 4272, - "armed": 4273, - "internet": 4274, - "models": 4275, - "worth": 4276, - "laws": 4277, - "400": 4278, - "communities": 4279, - "classes": 4280, - "background": 4281, - "knows": 4282, - "thanks": 4283, - "quarter": 4284, - "reaching": 4285, - "humans": 4286, - "carry": 4287, - "killing": 4288, - "format": 4289, - "kong": 4290, - "hong": 4291, - "setting": 4292, - "75": 4293, - "architecture": 4294, - "disease": 4295, - "railroad": 4296, - "inc": 4297, - "possibly": 4298, - "wish": 4299, - "arthur": 4300, - "thoughts": 4301, - "harry": 4302, - "doors": 4303, - "density": 4304, - "##di": 4305, - "crowd": 4306, - "illinois": 4307, - "stomach": 4308, - "tone": 4309, - "unique": 4310, - "reports": 4311, - "anyway": 4312, - "##ir": 4313, - "liberal": 4314, - "der": 4315, - "vehicle": 4316, - "thick": 4317, - "dry": 4318, - "drug": 4319, - "faced": 4320, - "largely": 4321, - "facility": 4322, - "theme": 4323, - "holds": 4324, - "creation": 4325, - "strange": 4326, - "colonel": 4327, - "##mi": 4328, - "revolution": 4329, - "bell": 4330, - "politics": 4331, - "turns": 4332, - "silent": 4333, - "rail": 4334, - "relief": 4335, - "independence": 4336, - "combat": 4337, - "shape": 4338, - "write": 4339, - "determined": 4340, - "sales": 4341, - "learned": 4342, - "4th": 4343, - "finger": 4344, - "oxford": 4345, - "providing": 4346, - "1937": 4347, - "heritage": 4348, - "fiction": 4349, - "situated": 4350, - "designated": 4351, - "allowing": 4352, - "distribution": 4353, - "hosted": 4354, - "##est": 4355, - "sight": 4356, - "interview": 4357, - "estimated": 4358, - "reduced": 4359, - "##ria": 4360, - "toronto": 4361, - "footballer": 4362, - "keeping": 4363, - "guys": 4364, - "damn": 4365, - "claim": 4366, - "motion": 4367, - "sport": 4368, - "sixth": 4369, - "stayed": 4370, - "##ze": 4371, - "en": 4372, - "rear": 4373, - "receive": 4374, - "handed": 4375, - "twelve": 4376, - "dress": 4377, - "audience": 4378, - "granted": 4379, - "brazil": 4380, - "##well": 4381, - "spirit": 4382, - "##ated": 4383, - "noticed": 4384, - "etc": 4385, - "olympic": 4386, - "representative": 4387, - "eric": 4388, - "tight": 4389, - "trouble": 4390, - "reviews": 4391, - "drink": 4392, - "vampire": 4393, - "missing": 4394, - "roles": 4395, - "ranked": 4396, - "newly": 4397, - "household": 4398, - "finals": 4399, - "wave": 4400, - "critics": 4401, - "##ee": 4402, - "phase": 4403, - "massachusetts": 4404, - "pilot": 4405, - "unlike": 4406, - "philadelphia": 4407, - "bright": 4408, - "guns": 4409, - "crown": 4410, - "organizations": 4411, - "roof": 4412, - "42": 4413, - "respectively": 4414, - "clearly": 4415, - "tongue": 4416, - "marked": 4417, - "circle": 4418, - "fox": 4419, - "korea": 4420, - "bronze": 4421, - "brian": 4422, - "expanded": 4423, - "sexual": 4424, - "supply": 4425, - "yourself": 4426, - "inspired": 4427, - "labour": 4428, - "fc": 4429, - "##ah": 4430, - "reference": 4431, - "vision": 4432, - "draft": 4433, - "connection": 4434, - "brand": 4435, - "reasons": 4436, - "1935": 4437, - "classic": 4438, - "driving": 4439, - "trip": 4440, - "jesus": 4441, - "cells": 4442, - "entry": 4443, - "1920": 4444, - "neither": 4445, - "trail": 4446, - "claims": 4447, - "atlantic": 4448, - "orders": 4449, - "labor": 4450, - "nose": 4451, - "afraid": 4452, - "identified": 4453, - "intelligence": 4454, - "calls": 4455, - "cancer": 4456, - "attacked": 4457, - "passing": 4458, - "stephen": 4459, - "positions": 4460, - "imperial": 4461, - "grey": 4462, - "jason": 4463, - "39": 4464, - "sunday": 4465, - "48": 4466, - "swedish": 4467, - "avoid": 4468, - "extra": 4469, - "uncle": 4470, - "message": 4471, - "covers": 4472, - "allows": 4473, - "surprise": 4474, - "materials": 4475, - "fame": 4476, - "hunter": 4477, - "##ji": 4478, - "1930": 4479, - "citizens": 4480, - "figures": 4481, - "davis": 4482, - "environmental": 4483, - "confirmed": 4484, - "shit": 4485, - "titles": 4486, - "di": 4487, - "performing": 4488, - "difference": 4489, - "acts": 4490, - "attacks": 4491, - "##ov": 4492, - "existing": 4493, - "votes": 4494, - "opportunity": 4495, - "nor": 4496, - "shop": 4497, - "entirely": 4498, - "trains": 4499, - "opposite": 4500, - "pakistan": 4501, - "##pa": 4502, - "develop": 4503, - "resulted": 4504, - "representatives": 4505, - "actions": 4506, - "reality": 4507, - "pressed": 4508, - "##ish": 4509, - "barely": 4510, - "wine": 4511, - "conversation": 4512, - "faculty": 4513, - "northwest": 4514, - "ends": 4515, - "documentary": 4516, - "nuclear": 4517, - "stock": 4518, - "grace": 4519, - "sets": 4520, - "eat": 4521, - "alternative": 4522, - "##ps": 4523, - "bag": 4524, - "resulting": 4525, - "creating": 4526, - "surprised": 4527, - "cemetery": 4528, - "1919": 4529, - "drop": 4530, - "finding": 4531, - "sarah": 4532, - "cricket": 4533, - "streets": 4534, - "tradition": 4535, - "ride": 4536, - "1933": 4537, - "exhibition": 4538, - "target": 4539, - "ear": 4540, - "explained": 4541, - "rain": 4542, - "composer": 4543, - "injury": 4544, - "apartment": 4545, - "municipal": 4546, - "educational": 4547, - "occupied": 4548, - "netherlands": 4549, - "clean": 4550, - "billion": 4551, - "constitution": 4552, - "learn": 4553, - "1914": 4554, - "maximum": 4555, - "classical": 4556, - "francis": 4557, - "lose": 4558, - "opposition": 4559, - "jose": 4560, - "ontario": 4561, - "bear": 4562, - "core": 4563, - "hills": 4564, - "rolled": 4565, - "ending": 4566, - "drawn": 4567, - "permanent": 4568, - "fun": 4569, - "##tes": 4570, - "##lla": 4571, - "lewis": 4572, - "sites": 4573, - "chamber": 4574, - "ryan": 4575, - "##way": 4576, - "scoring": 4577, - "height": 4578, - "1934": 4579, - "##house": 4580, - "lyrics": 4581, - "staring": 4582, - "55": 4583, - "officials": 4584, - "1917": 4585, - "snow": 4586, - "oldest": 4587, - "##tic": 4588, - "orange": 4589, - "##ger": 4590, - "qualified": 4591, - "interior": 4592, - "apparently": 4593, - "succeeded": 4594, - "thousand": 4595, - "dinner": 4596, - "lights": 4597, - "existence": 4598, - "fans": 4599, - "heavily": 4600, - "41": 4601, - "greatest": 4602, - "conservative": 4603, - "send": 4604, - "bowl": 4605, - "plus": 4606, - "enter": 4607, - "catch": 4608, - "##un": 4609, - "economy": 4610, - "duty": 4611, - "1929": 4612, - "speech": 4613, - "authorities": 4614, - "princess": 4615, - "performances": 4616, - "versions": 4617, - "shall": 4618, - "graduate": 4619, - "pictures": 4620, - "effective": 4621, - "remembered": 4622, - "poetry": 4623, - "desk": 4624, - "crossed": 4625, - "starring": 4626, - "starts": 4627, - "passenger": 4628, - "sharp": 4629, - "##ant": 4630, - "acres": 4631, - "ass": 4632, - "weather": 4633, - "falling": 4634, - "rank": 4635, - "fund": 4636, - "supporting": 4637, - "check": 4638, - "adult": 4639, - "publishing": 4640, - "heads": 4641, - "cm": 4642, - "southeast": 4643, - "lane": 4644, - "##burg": 4645, - "application": 4646, - "bc": 4647, - "##ura": 4648, - "les": 4649, - "condition": 4650, - "transfer": 4651, - "prevent": 4652, - "display": 4653, - "ex": 4654, - "regions": 4655, - "earl": 4656, - "federation": 4657, - "cool": 4658, - "relatively": 4659, - "answered": 4660, - "besides": 4661, - "1928": 4662, - "obtained": 4663, - "portion": 4664, - "##town": 4665, - "mix": 4666, - "##ding": 4667, - "reaction": 4668, - "liked": 4669, - "dean": 4670, - "express": 4671, - "peak": 4672, - "1932": 4673, - "##tte": 4674, - "counter": 4675, - "religion": 4676, - "chain": 4677, - "rare": 4678, - "miller": 4679, - "convention": 4680, - "aid": 4681, - "lie": 4682, - "vehicles": 4683, - "mobile": 4684, - "perform": 4685, - "squad": 4686, - "wonder": 4687, - "lying": 4688, - "crazy": 4689, - "sword": 4690, - "##ping": 4691, - "attempted": 4692, - "centuries": 4693, - "weren": 4694, - "philosophy": 4695, - "category": 4696, - "##ize": 4697, - "anna": 4698, - "interested": 4699, - "47": 4700, - "sweden": 4701, - "wolf": 4702, - "frequently": 4703, - "abandoned": 4704, - "kg": 4705, - "literary": 4706, - "alliance": 4707, - "task": 4708, - "entitled": 4709, - "##ay": 4710, - "threw": 4711, - "promotion": 4712, - "factory": 4713, - "tiny": 4714, - "soccer": 4715, - "visited": 4716, - "matt": 4717, - "fm": 4718, - "achieved": 4719, - "52": 4720, - "defence": 4721, - "internal": 4722, - "persian": 4723, - "43": 4724, - "methods": 4725, - "##ging": 4726, - "arrested": 4727, - "otherwise": 4728, - "cambridge": 4729, - "programming": 4730, - "villages": 4731, - "elementary": 4732, - "districts": 4733, - "rooms": 4734, - "criminal": 4735, - "conflict": 4736, - "worry": 4737, - "trained": 4738, - "1931": 4739, - "attempts": 4740, - "waited": 4741, - "signal": 4742, - "bird": 4743, - "truck": 4744, - "subsequent": 4745, - "programme": 4746, - "##ol": 4747, - "ad": 4748, - "49": 4749, - "communist": 4750, - "details": 4751, - "faith": 4752, - "sector": 4753, - "patrick": 4754, - "carrying": 4755, - "laugh": 4756, - "##ss": 4757, - "controlled": 4758, - "korean": 4759, - "showing": 4760, - "origin": 4761, - "fuel": 4762, - "evil": 4763, - "1927": 4764, - "##ent": 4765, - "brief": 4766, - "identity": 4767, - "darkness": 4768, - "address": 4769, - "pool": 4770, - "missed": 4771, - "publication": 4772, - "web": 4773, - "planet": 4774, - "ian": 4775, - "anne": 4776, - "wings": 4777, - "invited": 4778, - "##tt": 4779, - "briefly": 4780, - "standards": 4781, - "kissed": 4782, - "##be": 4783, - "ideas": 4784, - "climate": 4785, - "causing": 4786, - "walter": 4787, - "worse": 4788, - "albert": 4789, - "articles": 4790, - "winners": 4791, - "desire": 4792, - "aged": 4793, - "northeast": 4794, - "dangerous": 4795, - "gate": 4796, - "doubt": 4797, - "1922": 4798, - "wooden": 4799, - "multi": 4800, - "##ky": 4801, - "poet": 4802, - "rising": 4803, - "funding": 4804, - "46": 4805, - "communications": 4806, - "communication": 4807, - "violence": 4808, - "copies": 4809, - "prepared": 4810, - "ford": 4811, - "investigation": 4812, - "skills": 4813, - "1924": 4814, - "pulling": 4815, - "electronic": 4816, - "##ak": 4817, - "##ial": 4818, - "##han": 4819, - "containing": 4820, - "ultimately": 4821, - "offices": 4822, - "singing": 4823, - "understanding": 4824, - "restaurant": 4825, - "tomorrow": 4826, - "fashion": 4827, - "christ": 4828, - "ward": 4829, - "da": 4830, - "pope": 4831, - "stands": 4832, - "5th": 4833, - "flow": 4834, - "studios": 4835, - "aired": 4836, - "commissioned": 4837, - "contained": 4838, - "exist": 4839, - "fresh": 4840, - "americans": 4841, - "##per": 4842, - "wrestling": 4843, - "approved": 4844, - "kid": 4845, - "employed": 4846, - "respect": 4847, - "suit": 4848, - "1925": 4849, - "angel": 4850, - "asking": 4851, - "increasing": 4852, - "frame": 4853, - "angry": 4854, - "selling": 4855, - "1950s": 4856, - "thin": 4857, - "finds": 4858, - "##nd": 4859, - "temperature": 4860, - "statement": 4861, - "ali": 4862, - "explain": 4863, - "inhabitants": 4864, - "towns": 4865, - "extensive": 4866, - "narrow": 4867, - "51": 4868, - "jane": 4869, - "flowers": 4870, - "images": 4871, - "promise": 4872, - "somewhere": 4873, - "object": 4874, - "fly": 4875, - "closely": 4876, - "##ls": 4877, - "1912": 4878, - "bureau": 4879, - "cape": 4880, - "1926": 4881, - "weekly": 4882, - "presidential": 4883, - "legislative": 4884, - "1921": 4885, - "##ai": 4886, - "##au": 4887, - "launch": 4888, - "founding": 4889, - "##ny": 4890, - "978": 4891, - "##ring": 4892, - "artillery": 4893, - "strike": 4894, - "un": 4895, - "institutions": 4896, - "roll": 4897, - "writers": 4898, - "landing": 4899, - "chose": 4900, - "kevin": 4901, - "anymore": 4902, - "pp": 4903, - "##ut": 4904, - "attorney": 4905, - "fit": 4906, - "dan": 4907, - "billboard": 4908, - "receiving": 4909, - "agricultural": 4910, - "breaking": 4911, - "sought": 4912, - "dave": 4913, - "admitted": 4914, - "lands": 4915, - "mexican": 4916, - "##bury": 4917, - "charlie": 4918, - "specifically": 4919, - "hole": 4920, - "iv": 4921, - "howard": 4922, - "credit": 4923, - "moscow": 4924, - "roads": 4925, - "accident": 4926, - "1923": 4927, - "proved": 4928, - "wear": 4929, - "struck": 4930, - "hey": 4931, - "guards": 4932, - "stuff": 4933, - "slid": 4934, - "expansion": 4935, - "1915": 4936, - "cat": 4937, - "anthony": 4938, - "##kin": 4939, - "melbourne": 4940, - "opposed": 4941, - "sub": 4942, - "southwest": 4943, - "architect": 4944, - "failure": 4945, - "plane": 4946, - "1916": 4947, - "##ron": 4948, - "map": 4949, - "camera": 4950, - "tank": 4951, - "listen": 4952, - "regarding": 4953, - "wet": 4954, - "introduction": 4955, - "metropolitan": 4956, - "link": 4957, - "ep": 4958, - "fighter": 4959, - "inch": 4960, - "grown": 4961, - "gene": 4962, - "anger": 4963, - "fixed": 4964, - "buy": 4965, - "dvd": 4966, - "khan": 4967, - "domestic": 4968, - "worldwide": 4969, - "chapel": 4970, - "mill": 4971, - "functions": 4972, - "examples": 4973, - "##head": 4974, - "developing": 4975, - "1910": 4976, - "turkey": 4977, - "hits": 4978, - "pocket": 4979, - "antonio": 4980, - "papers": 4981, - "grow": 4982, - "unless": 4983, - "circuit": 4984, - "18th": 4985, - "concerned": 4986, - "attached": 4987, - "journalist": 4988, - "selection": 4989, - "journey": 4990, - "converted": 4991, - "provincial": 4992, - "painted": 4993, - "hearing": 4994, - "aren": 4995, - "bands": 4996, - "negative": 4997, - "aside": 4998, - "wondered": 4999, - "knight": 5000, - "lap": 5001, - "survey": 5002, - "ma": 5003, - "##ow": 5004, - "noise": 5005, - "billy": 5006, - "##ium": 5007, - "shooting": 5008, - "guide": 5009, - "bedroom": 5010, - "priest": 5011, - "resistance": 5012, - "motor": 5013, - "homes": 5014, - "sounded": 5015, - "giant": 5016, - "##mer": 5017, - "150": 5018, - "scenes": 5019, - "equal": 5020, - "comic": 5021, - "patients": 5022, - "hidden": 5023, - "solid": 5024, - "actual": 5025, - "bringing": 5026, - "afternoon": 5027, - "touched": 5028, - "funds": 5029, - "wedding": 5030, - "consisted": 5031, - "marie": 5032, - "canal": 5033, - "sr": 5034, - "kim": 5035, - "treaty": 5036, - "turkish": 5037, - "recognition": 5038, - "residence": 5039, - "cathedral": 5040, - "broad": 5041, - "knees": 5042, - "incident": 5043, - "shaped": 5044, - "fired": 5045, - "norwegian": 5046, - "handle": 5047, - "cheek": 5048, - "contest": 5049, - "represent": 5050, - "##pe": 5051, - "representing": 5052, - "beauty": 5053, - "##sen": 5054, - "birds": 5055, - "advantage": 5056, - "emergency": 5057, - "wrapped": 5058, - "drawing": 5059, - "notice": 5060, - "pink": 5061, - "broadcasting": 5062, - "##ong": 5063, - "somehow": 5064, - "bachelor": 5065, - "seventh": 5066, - "collected": 5067, - "registered": 5068, - "establishment": 5069, - "alan": 5070, - "assumed": 5071, - "chemical": 5072, - "personnel": 5073, - "roger": 5074, - "retirement": 5075, - "jeff": 5076, - "portuguese": 5077, - "wore": 5078, - "tied": 5079, - "device": 5080, - "threat": 5081, - "progress": 5082, - "advance": 5083, - "##ised": 5084, - "banks": 5085, - "hired": 5086, - "manchester": 5087, - "nfl": 5088, - "teachers": 5089, - "structures": 5090, - "forever": 5091, - "##bo": 5092, - "tennis": 5093, - "helping": 5094, - "saturday": 5095, - "sale": 5096, - "applications": 5097, - "junction": 5098, - "hip": 5099, - "incorporated": 5100, - "neighborhood": 5101, - "dressed": 5102, - "ceremony": 5103, - "##ds": 5104, - "influenced": 5105, - "hers": 5106, - "visual": 5107, - "stairs": 5108, - "decades": 5109, - "inner": 5110, - "kansas": 5111, - "hung": 5112, - "hoped": 5113, - "gain": 5114, - "scheduled": 5115, - "downtown": 5116, - "engaged": 5117, - "austria": 5118, - "clock": 5119, - "norway": 5120, - "certainly": 5121, - "pale": 5122, - "protected": 5123, - "1913": 5124, - "victor": 5125, - "employees": 5126, - "plate": 5127, - "putting": 5128, - "surrounded": 5129, - "##ists": 5130, - "finishing": 5131, - "blues": 5132, - "tropical": 5133, - "##ries": 5134, - "minnesota": 5135, - "consider": 5136, - "philippines": 5137, - "accept": 5138, - "54": 5139, - "retrieved": 5140, - "1900": 5141, - "concern": 5142, - "anderson": 5143, - "properties": 5144, - "institution": 5145, - "gordon": 5146, - "successfully": 5147, - "vietnam": 5148, - "##dy": 5149, - "backing": 5150, - "outstanding": 5151, - "muslim": 5152, - "crossing": 5153, - "folk": 5154, - "producing": 5155, - "usual": 5156, - "demand": 5157, - "occurs": 5158, - "observed": 5159, - "lawyer": 5160, - "educated": 5161, - "##ana": 5162, - "kelly": 5163, - "string": 5164, - "pleasure": 5165, - "budget": 5166, - "items": 5167, - "quietly": 5168, - "colorado": 5169, - "philip": 5170, - "typical": 5171, - "##worth": 5172, - "derived": 5173, - "600": 5174, - "survived": 5175, - "asks": 5176, - "mental": 5177, - "##ide": 5178, - "56": 5179, - "jake": 5180, - "jews": 5181, - "distinguished": 5182, - "ltd": 5183, - "1911": 5184, - "sri": 5185, - "extremely": 5186, - "53": 5187, - "athletic": 5188, - "loud": 5189, - "thousands": 5190, - "worried": 5191, - "shadow": 5192, - "transportation": 5193, - "horses": 5194, - "weapon": 5195, - "arena": 5196, - "importance": 5197, - "users": 5198, - "tim": 5199, - "objects": 5200, - "contributed": 5201, - "dragon": 5202, - "douglas": 5203, - "aware": 5204, - "senator": 5205, - "johnny": 5206, - "jordan": 5207, - "sisters": 5208, - "engines": 5209, - "flag": 5210, - "investment": 5211, - "samuel": 5212, - "shock": 5213, - "capable": 5214, - "clark": 5215, - "row": 5216, - "wheel": 5217, - "refers": 5218, - "session": 5219, - "familiar": 5220, - "biggest": 5221, - "wins": 5222, - "hate": 5223, - "maintained": 5224, - "drove": 5225, - "hamilton": 5226, - "request": 5227, - "expressed": 5228, - "injured": 5229, - "underground": 5230, - "churches": 5231, - "walker": 5232, - "wars": 5233, - "tunnel": 5234, - "passes": 5235, - "stupid": 5236, - "agriculture": 5237, - "softly": 5238, - "cabinet": 5239, - "regarded": 5240, - "joining": 5241, - "indiana": 5242, - "##ea": 5243, - "##ms": 5244, - "push": 5245, - "dates": 5246, - "spend": 5247, - "behavior": 5248, - "woods": 5249, - "protein": 5250, - "gently": 5251, - "chase": 5252, - "morgan": 5253, - "mention": 5254, - "burning": 5255, - "wake": 5256, - "combination": 5257, - "occur": 5258, - "mirror": 5259, - "leads": 5260, - "jimmy": 5261, - "indeed": 5262, - "impossible": 5263, - "singapore": 5264, - "paintings": 5265, - "covering": 5266, - "##nes": 5267, - "soldier": 5268, - "locations": 5269, - "attendance": 5270, - "sell": 5271, - "historian": 5272, - "wisconsin": 5273, - "invasion": 5274, - "argued": 5275, - "painter": 5276, - "diego": 5277, - "changing": 5278, - "egypt": 5279, - "##don": 5280, - "experienced": 5281, - "inches": 5282, - "##ku": 5283, - "missouri": 5284, - "vol": 5285, - "grounds": 5286, - "spoken": 5287, - "switzerland": 5288, - "##gan": 5289, - "reform": 5290, - "rolling": 5291, - "ha": 5292, - "forget": 5293, - "massive": 5294, - "resigned": 5295, - "burned": 5296, - "allen": 5297, - "tennessee": 5298, - "locked": 5299, - "values": 5300, - "improved": 5301, - "##mo": 5302, - "wounded": 5303, - "universe": 5304, - "sick": 5305, - "dating": 5306, - "facing": 5307, - "pack": 5308, - "purchase": 5309, - "user": 5310, - "##pur": 5311, - "moments": 5312, - "##ul": 5313, - "merged": 5314, - "anniversary": 5315, - "1908": 5316, - "coal": 5317, - "brick": 5318, - "understood": 5319, - "causes": 5320, - "dynasty": 5321, - "queensland": 5322, - "establish": 5323, - "stores": 5324, - "crisis": 5325, - "promote": 5326, - "hoping": 5327, - "views": 5328, - "cards": 5329, - "referee": 5330, - "extension": 5331, - "##si": 5332, - "raise": 5333, - "arizona": 5334, - "improve": 5335, - "colonial": 5336, - "formal": 5337, - "charged": 5338, - "##rt": 5339, - "palm": 5340, - "lucky": 5341, - "hide": 5342, - "rescue": 5343, - "faces": 5344, - "95": 5345, - "feelings": 5346, - "candidates": 5347, - "juan": 5348, - "##ell": 5349, - "goods": 5350, - "6th": 5351, - "courses": 5352, - "weekend": 5353, - "59": 5354, - "luke": 5355, - "cash": 5356, - "fallen": 5357, - "##om": 5358, - "delivered": 5359, - "affected": 5360, - "installed": 5361, - "carefully": 5362, - "tries": 5363, - "swiss": 5364, - "hollywood": 5365, - "costs": 5366, - "lincoln": 5367, - "responsibility": 5368, - "##he": 5369, - "shore": 5370, - "file": 5371, - "proper": 5372, - "normally": 5373, - "maryland": 5374, - "assistance": 5375, - "jump": 5376, - "constant": 5377, - "offering": 5378, - "friendly": 5379, - "waters": 5380, - "persons": 5381, - "realize": 5382, - "contain": 5383, - "trophy": 5384, - "800": 5385, - "partnership": 5386, - "factor": 5387, - "58": 5388, - "musicians": 5389, - "cry": 5390, - "bound": 5391, - "oregon": 5392, - "indicated": 5393, - "hero": 5394, - "houston": 5395, - "medium": 5396, - "##ure": 5397, - "consisting": 5398, - "somewhat": 5399, - "##ara": 5400, - "57": 5401, - "cycle": 5402, - "##che": 5403, - "beer": 5404, - "moore": 5405, - "frederick": 5406, - "gotten": 5407, - "eleven": 5408, - "worst": 5409, - "weak": 5410, - "approached": 5411, - "arranged": 5412, - "chin": 5413, - "loan": 5414, - "universal": 5415, - "bond": 5416, - "fifteen": 5417, - "pattern": 5418, - "disappeared": 5419, - "##ney": 5420, - "translated": 5421, - "##zed": 5422, - "lip": 5423, - "arab": 5424, - "capture": 5425, - "interests": 5426, - "insurance": 5427, - "##chi": 5428, - "shifted": 5429, - "cave": 5430, - "prix": 5431, - "warning": 5432, - "sections": 5433, - "courts": 5434, - "coat": 5435, - "plot": 5436, - "smell": 5437, - "feed": 5438, - "golf": 5439, - "favorite": 5440, - "maintain": 5441, - "knife": 5442, - "vs": 5443, - "voted": 5444, - "degrees": 5445, - "finance": 5446, - "quebec": 5447, - "opinion": 5448, - "translation": 5449, - "manner": 5450, - "ruled": 5451, - "operate": 5452, - "productions": 5453, - "choose": 5454, - "musician": 5455, - "discovery": 5456, - "confused": 5457, - "tired": 5458, - "separated": 5459, - "stream": 5460, - "techniques": 5461, - "committed": 5462, - "attend": 5463, - "ranking": 5464, - "kings": 5465, - "throw": 5466, - "passengers": 5467, - "measure": 5468, - "horror": 5469, - "fan": 5470, - "mining": 5471, - "sand": 5472, - "danger": 5473, - "salt": 5474, - "calm": 5475, - "decade": 5476, - "dam": 5477, - "require": 5478, - "runner": 5479, - "##ik": 5480, - "rush": 5481, - "associate": 5482, - "greece": 5483, - "##ker": 5484, - "rivers": 5485, - "consecutive": 5486, - "matthew": 5487, - "##ski": 5488, - "sighed": 5489, - "sq": 5490, - "documents": 5491, - "steam": 5492, - "edited": 5493, - "closing": 5494, - "tie": 5495, - "accused": 5496, - "1905": 5497, - "##ini": 5498, - "islamic": 5499, - "distributed": 5500, - "directors": 5501, - "organisation": 5502, - "bruce": 5503, - "7th": 5504, - "breathing": 5505, - "mad": 5506, - "lit": 5507, - "arrival": 5508, - "concrete": 5509, - "taste": 5510, - "08": 5511, - "composition": 5512, - "shaking": 5513, - "faster": 5514, - "amateur": 5515, - "adjacent": 5516, - "stating": 5517, - "1906": 5518, - "twin": 5519, - "flew": 5520, - "##ran": 5521, - "tokyo": 5522, - "publications": 5523, - "##tone": 5524, - "obviously": 5525, - "ridge": 5526, - "storage": 5527, - "1907": 5528, - "carl": 5529, - "pages": 5530, - "concluded": 5531, - "desert": 5532, - "driven": 5533, - "universities": 5534, - "ages": 5535, - "terminal": 5536, - "sequence": 5537, - "borough": 5538, - "250": 5539, - "constituency": 5540, - "creative": 5541, - "cousin": 5542, - "economics": 5543, - "dreams": 5544, - "margaret": 5545, - "notably": 5546, - "reduce": 5547, - "montreal": 5548, - "mode": 5549, - "17th": 5550, - "ears": 5551, - "saved": 5552, - "jan": 5553, - "vocal": 5554, - "##ica": 5555, - "1909": 5556, - "andy": 5557, - "##jo": 5558, - "riding": 5559, - "roughly": 5560, - "threatened": 5561, - "##ise": 5562, - "meters": 5563, - "meanwhile": 5564, - "landed": 5565, - "compete": 5566, - "repeated": 5567, - "grass": 5568, - "czech": 5569, - "regularly": 5570, - "charges": 5571, - "tea": 5572, - "sudden": 5573, - "appeal": 5574, - "##ung": 5575, - "solution": 5576, - "describes": 5577, - "pierre": 5578, - "classification": 5579, - "glad": 5580, - "parking": 5581, - "##ning": 5582, - "belt": 5583, - "physics": 5584, - "99": 5585, - "rachel": 5586, - "add": 5587, - "hungarian": 5588, - "participate": 5589, - "expedition": 5590, - "damaged": 5591, - "gift": 5592, - "childhood": 5593, - "85": 5594, - "fifty": 5595, - "##red": 5596, - "mathematics": 5597, - "jumped": 5598, - "letting": 5599, - "defensive": 5600, - "mph": 5601, - "##ux": 5602, - "##gh": 5603, - "testing": 5604, - "##hip": 5605, - "hundreds": 5606, - "shoot": 5607, - "owners": 5608, - "matters": 5609, - "smoke": 5610, - "israeli": 5611, - "kentucky": 5612, - "dancing": 5613, - "mounted": 5614, - "grandfather": 5615, - "emma": 5616, - "designs": 5617, - "profit": 5618, - "argentina": 5619, - "##gs": 5620, - "truly": 5621, - "li": 5622, - "lawrence": 5623, - "cole": 5624, - "begun": 5625, - "detroit": 5626, - "willing": 5627, - "branches": 5628, - "smiling": 5629, - "decide": 5630, - "miami": 5631, - "enjoyed": 5632, - "recordings": 5633, - "##dale": 5634, - "poverty": 5635, - "ethnic": 5636, - "gay": 5637, - "##bi": 5638, - "gary": 5639, - "arabic": 5640, - "09": 5641, - "accompanied": 5642, - "##one": 5643, - "##ons": 5644, - "fishing": 5645, - "determine": 5646, - "residential": 5647, - "acid": 5648, - "##ary": 5649, - "alice": 5650, - "returns": 5651, - "starred": 5652, - "mail": 5653, - "##ang": 5654, - "jonathan": 5655, - "strategy": 5656, - "##ue": 5657, - "net": 5658, - "forty": 5659, - "cook": 5660, - "businesses": 5661, - "equivalent": 5662, - "commonwealth": 5663, - "distinct": 5664, - "ill": 5665, - "##cy": 5666, - "seriously": 5667, - "##ors": 5668, - "##ped": 5669, - "shift": 5670, - "harris": 5671, - "replace": 5672, - "rio": 5673, - "imagine": 5674, - "formula": 5675, - "ensure": 5676, - "##ber": 5677, - "additionally": 5678, - "scheme": 5679, - "conservation": 5680, - "occasionally": 5681, - "purposes": 5682, - "feels": 5683, - "favor": 5684, - "##and": 5685, - "##ore": 5686, - "1930s": 5687, - "contrast": 5688, - "hanging": 5689, - "hunt": 5690, - "movies": 5691, - "1904": 5692, - "instruments": 5693, - "victims": 5694, - "danish": 5695, - "christopher": 5696, - "busy": 5697, - "demon": 5698, - "sugar": 5699, - "earliest": 5700, - "colony": 5701, - "studying": 5702, - "balance": 5703, - "duties": 5704, - "##ks": 5705, - "belgium": 5706, - "slipped": 5707, - "carter": 5708, - "05": 5709, - "visible": 5710, - "stages": 5711, - "iraq": 5712, - "fifa": 5713, - "##im": 5714, - "commune": 5715, - "forming": 5716, - "zero": 5717, - "07": 5718, - "continuing": 5719, - "talked": 5720, - "counties": 5721, - "legend": 5722, - "bathroom": 5723, - "option": 5724, - "tail": 5725, - "clay": 5726, - "daughters": 5727, - "afterwards": 5728, - "severe": 5729, - "jaw": 5730, - "visitors": 5731, - "##ded": 5732, - "devices": 5733, - "aviation": 5734, - "russell": 5735, - "kate": 5736, - "##vi": 5737, - "entering": 5738, - "subjects": 5739, - "##ino": 5740, - "temporary": 5741, - "swimming": 5742, - "forth": 5743, - "smooth": 5744, - "ghost": 5745, - "audio": 5746, - "bush": 5747, - "operates": 5748, - "rocks": 5749, - "movements": 5750, - "signs": 5751, - "eddie": 5752, - "##tz": 5753, - "ann": 5754, - "voices": 5755, - "honorary": 5756, - "06": 5757, - "memories": 5758, - "dallas": 5759, - "pure": 5760, - "measures": 5761, - "racial": 5762, - "promised": 5763, - "66": 5764, - "harvard": 5765, - "ceo": 5766, - "16th": 5767, - "parliamentary": 5768, - "indicate": 5769, - "benefit": 5770, - "flesh": 5771, - "dublin": 5772, - "louisiana": 5773, - "1902": 5774, - "1901": 5775, - "patient": 5776, - "sleeping": 5777, - "1903": 5778, - "membership": 5779, - "coastal": 5780, - "medieval": 5781, - "wanting": 5782, - "element": 5783, - "scholars": 5784, - "rice": 5785, - "62": 5786, - "limit": 5787, - "survive": 5788, - "makeup": 5789, - "rating": 5790, - "definitely": 5791, - "collaboration": 5792, - "obvious": 5793, - "##tan": 5794, - "boss": 5795, - "ms": 5796, - "baron": 5797, - "birthday": 5798, - "linked": 5799, - "soil": 5800, - "diocese": 5801, - "##lan": 5802, - "ncaa": 5803, - "##mann": 5804, - "offensive": 5805, - "shell": 5806, - "shouldn": 5807, - "waist": 5808, - "##tus": 5809, - "plain": 5810, - "ross": 5811, - "organ": 5812, - "resolution": 5813, - "manufacturing": 5814, - "adding": 5815, - "relative": 5816, - "kennedy": 5817, - "98": 5818, - "whilst": 5819, - "moth": 5820, - "marketing": 5821, - "gardens": 5822, - "crash": 5823, - "72": 5824, - "heading": 5825, - "partners": 5826, - "credited": 5827, - "carlos": 5828, - "moves": 5829, - "cable": 5830, - "##zi": 5831, - "marshall": 5832, - "##out": 5833, - "depending": 5834, - "bottle": 5835, - "represents": 5836, - "rejected": 5837, - "responded": 5838, - "existed": 5839, - "04": 5840, - "jobs": 5841, - "denmark": 5842, - "lock": 5843, - "##ating": 5844, - "treated": 5845, - "graham": 5846, - "routes": 5847, - "talent": 5848, - "commissioner": 5849, - "drugs": 5850, - "secure": 5851, - "tests": 5852, - "reign": 5853, - "restored": 5854, - "photography": 5855, - "##gi": 5856, - "contributions": 5857, - "oklahoma": 5858, - "designer": 5859, - "disc": 5860, - "grin": 5861, - "seattle": 5862, - "robin": 5863, - "paused": 5864, - "atlanta": 5865, - "unusual": 5866, - "##gate": 5867, - "praised": 5868, - "las": 5869, - "laughing": 5870, - "satellite": 5871, - "hungary": 5872, - "visiting": 5873, - "##sky": 5874, - "interesting": 5875, - "factors": 5876, - "deck": 5877, - "poems": 5878, - "norman": 5879, - "##water": 5880, - "stuck": 5881, - "speaker": 5882, - "rifle": 5883, - "domain": 5884, - "premiered": 5885, - "##her": 5886, - "dc": 5887, - "comics": 5888, - "actors": 5889, - "01": 5890, - "reputation": 5891, - "eliminated": 5892, - "8th": 5893, - "ceiling": 5894, - "prisoners": 5895, - "script": 5896, - "##nce": 5897, - "leather": 5898, - "austin": 5899, - "mississippi": 5900, - "rapidly": 5901, - "admiral": 5902, - "parallel": 5903, - "charlotte": 5904, - "guilty": 5905, - "tools": 5906, - "gender": 5907, - "divisions": 5908, - "fruit": 5909, - "##bs": 5910, - "laboratory": 5911, - "nelson": 5912, - "fantasy": 5913, - "marry": 5914, - "rapid": 5915, - "aunt": 5916, - "tribe": 5917, - "requirements": 5918, - "aspects": 5919, - "suicide": 5920, - "amongst": 5921, - "adams": 5922, - "bone": 5923, - "ukraine": 5924, - "abc": 5925, - "kick": 5926, - "sees": 5927, - "edinburgh": 5928, - "clothing": 5929, - "column": 5930, - "rough": 5931, - "gods": 5932, - "hunting": 5933, - "broadway": 5934, - "gathered": 5935, - "concerns": 5936, - "##ek": 5937, - "spending": 5938, - "ty": 5939, - "12th": 5940, - "snapped": 5941, - "requires": 5942, - "solar": 5943, - "bones": 5944, - "cavalry": 5945, - "##tta": 5946, - "iowa": 5947, - "drinking": 5948, - "waste": 5949, - "index": 5950, - "franklin": 5951, - "charity": 5952, - "thompson": 5953, - "stewart": 5954, - "tip": 5955, - "flash": 5956, - "landscape": 5957, - "friday": 5958, - "enjoy": 5959, - "singh": 5960, - "poem": 5961, - "listening": 5962, - "##back": 5963, - "eighth": 5964, - "fred": 5965, - "differences": 5966, - "adapted": 5967, - "bomb": 5968, - "ukrainian": 5969, - "surgery": 5970, - "corporate": 5971, - "masters": 5972, - "anywhere": 5973, - "##more": 5974, - "waves": 5975, - "odd": 5976, - "sean": 5977, - "portugal": 5978, - "orleans": 5979, - "dick": 5980, - "debate": 5981, - "kent": 5982, - "eating": 5983, - "puerto": 5984, - "cleared": 5985, - "96": 5986, - "expect": 5987, - "cinema": 5988, - "97": 5989, - "guitarist": 5990, - "blocks": 5991, - "electrical": 5992, - "agree": 5993, - "involving": 5994, - "depth": 5995, - "dying": 5996, - "panel": 5997, - "struggle": 5998, - "##ged": 5999, - "peninsula": 6000, - "adults": 6001, - "novels": 6002, - "emerged": 6003, - "vienna": 6004, - "metro": 6005, - "debuted": 6006, - "shoes": 6007, - "tamil": 6008, - "songwriter": 6009, - "meets": 6010, - "prove": 6011, - "beating": 6012, - "instance": 6013, - "heaven": 6014, - "scared": 6015, - "sending": 6016, - "marks": 6017, - "artistic": 6018, - "passage": 6019, - "superior": 6020, - "03": 6021, - "significantly": 6022, - "shopping": 6023, - "##tive": 6024, - "retained": 6025, - "##izing": 6026, - "malaysia": 6027, - "technique": 6028, - "cheeks": 6029, - "##ola": 6030, - "warren": 6031, - "maintenance": 6032, - "destroy": 6033, - "extreme": 6034, - "allied": 6035, - "120": 6036, - "appearing": 6037, - "##yn": 6038, - "fill": 6039, - "advice": 6040, - "alabama": 6041, - "qualifying": 6042, - "policies": 6043, - "cleveland": 6044, - "hat": 6045, - "battery": 6046, - "smart": 6047, - "authors": 6048, - "10th": 6049, - "soundtrack": 6050, - "acted": 6051, - "dated": 6052, - "lb": 6053, - "glance": 6054, - "equipped": 6055, - "coalition": 6056, - "funny": 6057, - "outer": 6058, - "ambassador": 6059, - "roy": 6060, - "possibility": 6061, - "couples": 6062, - "campbell": 6063, - "dna": 6064, - "loose": 6065, - "ethan": 6066, - "supplies": 6067, - "1898": 6068, - "gonna": 6069, - "88": 6070, - "monster": 6071, - "##res": 6072, - "shake": 6073, - "agents": 6074, - "frequency": 6075, - "springs": 6076, - "dogs": 6077, - "practices": 6078, - "61": 6079, - "gang": 6080, - "plastic": 6081, - "easier": 6082, - "suggests": 6083, - "gulf": 6084, - "blade": 6085, - "exposed": 6086, - "colors": 6087, - "industries": 6088, - "markets": 6089, - "pan": 6090, - "nervous": 6091, - "electoral": 6092, - "charts": 6093, - "legislation": 6094, - "ownership": 6095, - "##idae": 6096, - "mac": 6097, - "appointment": 6098, - "shield": 6099, - "copy": 6100, - "assault": 6101, - "socialist": 6102, - "abbey": 6103, - "monument": 6104, - "license": 6105, - "throne": 6106, - "employment": 6107, - "jay": 6108, - "93": 6109, - "replacement": 6110, - "charter": 6111, - "cloud": 6112, - "powered": 6113, - "suffering": 6114, - "accounts": 6115, - "oak": 6116, - "connecticut": 6117, - "strongly": 6118, - "wright": 6119, - "colour": 6120, - "crystal": 6121, - "13th": 6122, - "context": 6123, - "welsh": 6124, - "networks": 6125, - "voiced": 6126, - "gabriel": 6127, - "jerry": 6128, - "##cing": 6129, - "forehead": 6130, - "mp": 6131, - "##ens": 6132, - "manage": 6133, - "schedule": 6134, - "totally": 6135, - "remix": 6136, - "##ii": 6137, - "forests": 6138, - "occupation": 6139, - "print": 6140, - "nicholas": 6141, - "brazilian": 6142, - "strategic": 6143, - "vampires": 6144, - "engineers": 6145, - "76": 6146, - "roots": 6147, - "seek": 6148, - "correct": 6149, - "instrumental": 6150, - "und": 6151, - "alfred": 6152, - "backed": 6153, - "hop": 6154, - "##des": 6155, - "stanley": 6156, - "robinson": 6157, - "traveled": 6158, - "wayne": 6159, - "welcome": 6160, - "austrian": 6161, - "achieve": 6162, - "67": 6163, - "exit": 6164, - "rates": 6165, - "1899": 6166, - "strip": 6167, - "whereas": 6168, - "##cs": 6169, - "sing": 6170, - "deeply": 6171, - "adventure": 6172, - "bobby": 6173, - "rick": 6174, - "jamie": 6175, - "careful": 6176, - "components": 6177, - "cap": 6178, - "useful": 6179, - "personality": 6180, - "knee": 6181, - "##shi": 6182, - "pushing": 6183, - "hosts": 6184, - "02": 6185, - "protest": 6186, - "ca": 6187, - "ottoman": 6188, - "symphony": 6189, - "##sis": 6190, - "63": 6191, - "boundary": 6192, - "1890": 6193, - "processes": 6194, - "considering": 6195, - "considerable": 6196, - "tons": 6197, - "##work": 6198, - "##ft": 6199, - "##nia": 6200, - "cooper": 6201, - "trading": 6202, - "dear": 6203, - "conduct": 6204, - "91": 6205, - "illegal": 6206, - "apple": 6207, - "revolutionary": 6208, - "holiday": 6209, - "definition": 6210, - "harder": 6211, - "##van": 6212, - "jacob": 6213, - "circumstances": 6214, - "destruction": 6215, - "##lle": 6216, - "popularity": 6217, - "grip": 6218, - "classified": 6219, - "liverpool": 6220, - "donald": 6221, - "baltimore": 6222, - "flows": 6223, - "seeking": 6224, - "honour": 6225, - "approval": 6226, - "92": 6227, - "mechanical": 6228, - "till": 6229, - "happening": 6230, - "statue": 6231, - "critic": 6232, - "increasingly": 6233, - "immediate": 6234, - "describe": 6235, - "commerce": 6236, - "stare": 6237, - "##ster": 6238, - "indonesia": 6239, - "meat": 6240, - "rounds": 6241, - "boats": 6242, - "baker": 6243, - "orthodox": 6244, - "depression": 6245, - "formally": 6246, - "worn": 6247, - "naked": 6248, - "claire": 6249, - "muttered": 6250, - "sentence": 6251, - "11th": 6252, - "emily": 6253, - "document": 6254, - "77": 6255, - "criticism": 6256, - "wished": 6257, - "vessel": 6258, - "spiritual": 6259, - "bent": 6260, - "virgin": 6261, - "parker": 6262, - "minimum": 6263, - "murray": 6264, - "lunch": 6265, - "danny": 6266, - "printed": 6267, - "compilation": 6268, - "keyboards": 6269, - "false": 6270, - "blow": 6271, - "belonged": 6272, - "68": 6273, - "raising": 6274, - "78": 6275, - "cutting": 6276, - "##board": 6277, - "pittsburgh": 6278, - "##up": 6279, - "9th": 6280, - "shadows": 6281, - "81": 6282, - "hated": 6283, - "indigenous": 6284, - "jon": 6285, - "15th": 6286, - "barry": 6287, - "scholar": 6288, - "ah": 6289, - "##zer": 6290, - "oliver": 6291, - "##gy": 6292, - "stick": 6293, - "susan": 6294, - "meetings": 6295, - "attracted": 6296, - "spell": 6297, - "romantic": 6298, - "##ver": 6299, - "ye": 6300, - "1895": 6301, - "photo": 6302, - "demanded": 6303, - "customers": 6304, - "##ac": 6305, - "1896": 6306, - "logan": 6307, - "revival": 6308, - "keys": 6309, - "modified": 6310, - "commanded": 6311, - "jeans": 6312, - "##ious": 6313, - "upset": 6314, - "raw": 6315, - "phil": 6316, - "detective": 6317, - "hiding": 6318, - "resident": 6319, - "vincent": 6320, - "##bly": 6321, - "experiences": 6322, - "diamond": 6323, - "defeating": 6324, - "coverage": 6325, - "lucas": 6326, - "external": 6327, - "parks": 6328, - "franchise": 6329, - "helen": 6330, - "bible": 6331, - "successor": 6332, - "percussion": 6333, - "celebrated": 6334, - "il": 6335, - "lift": 6336, - "profile": 6337, - "clan": 6338, - "romania": 6339, - "##ied": 6340, - "mills": 6341, - "##su": 6342, - "nobody": 6343, - "achievement": 6344, - "shrugged": 6345, - "fault": 6346, - "1897": 6347, - "rhythm": 6348, - "initiative": 6349, - "breakfast": 6350, - "carbon": 6351, - "700": 6352, - "69": 6353, - "lasted": 6354, - "violent": 6355, - "74": 6356, - "wound": 6357, - "ken": 6358, - "killer": 6359, - "gradually": 6360, - "filmed": 6361, - "°c": 6362, - "dollars": 6363, - "processing": 6364, - "94": 6365, - "remove": 6366, - "criticized": 6367, - "guests": 6368, - "sang": 6369, - "chemistry": 6370, - "##vin": 6371, - "legislature": 6372, - "disney": 6373, - "##bridge": 6374, - "uniform": 6375, - "escaped": 6376, - "integrated": 6377, - "proposal": 6378, - "purple": 6379, - "denied": 6380, - "liquid": 6381, - "karl": 6382, - "influential": 6383, - "morris": 6384, - "nights": 6385, - "stones": 6386, - "intense": 6387, - "experimental": 6388, - "twisted": 6389, - "71": 6390, - "84": 6391, - "##ld": 6392, - "pace": 6393, - "nazi": 6394, - "mitchell": 6395, - "ny": 6396, - "blind": 6397, - "reporter": 6398, - "newspapers": 6399, - "14th": 6400, - "centers": 6401, - "burn": 6402, - "basin": 6403, - "forgotten": 6404, - "surviving": 6405, - "filed": 6406, - "collections": 6407, - "monastery": 6408, - "losses": 6409, - "manual": 6410, - "couch": 6411, - "description": 6412, - "appropriate": 6413, - "merely": 6414, - "tag": 6415, - "missions": 6416, - "sebastian": 6417, - "restoration": 6418, - "replacing": 6419, - "triple": 6420, - "73": 6421, - "elder": 6422, - "julia": 6423, - "warriors": 6424, - "benjamin": 6425, - "julian": 6426, - "convinced": 6427, - "stronger": 6428, - "amazing": 6429, - "declined": 6430, - "versus": 6431, - "merchant": 6432, - "happens": 6433, - "output": 6434, - "finland": 6435, - "bare": 6436, - "barbara": 6437, - "absence": 6438, - "ignored": 6439, - "dawn": 6440, - "injuries": 6441, - "##port": 6442, - "producers": 6443, - "##ram": 6444, - "82": 6445, - "luis": 6446, - "##ities": 6447, - "kw": 6448, - "admit": 6449, - "expensive": 6450, - "electricity": 6451, - "nba": 6452, - "exception": 6453, - "symbol": 6454, - "##ving": 6455, - "ladies": 6456, - "shower": 6457, - "sheriff": 6458, - "characteristics": 6459, - "##je": 6460, - "aimed": 6461, - "button": 6462, - "ratio": 6463, - "effectively": 6464, - "summit": 6465, - "angle": 6466, - "jury": 6467, - "bears": 6468, - "foster": 6469, - "vessels": 6470, - "pants": 6471, - "executed": 6472, - "evans": 6473, - "dozen": 6474, - "advertising": 6475, - "kicked": 6476, - "patrol": 6477, - "1889": 6478, - "competitions": 6479, - "lifetime": 6480, - "principles": 6481, - "athletics": 6482, - "##logy": 6483, - "birmingham": 6484, - "sponsored": 6485, - "89": 6486, - "rob": 6487, - "nomination": 6488, - "1893": 6489, - "acoustic": 6490, - "##sm": 6491, - "creature": 6492, - "longest": 6493, - "##tra": 6494, - "credits": 6495, - "harbor": 6496, - "dust": 6497, - "josh": 6498, - "##so": 6499, - "territories": 6500, - "milk": 6501, - "infrastructure": 6502, - "completion": 6503, - "thailand": 6504, - "indians": 6505, - "leon": 6506, - "archbishop": 6507, - "##sy": 6508, - "assist": 6509, - "pitch": 6510, - "blake": 6511, - "arrangement": 6512, - "girlfriend": 6513, - "serbian": 6514, - "operational": 6515, - "hence": 6516, - "sad": 6517, - "scent": 6518, - "fur": 6519, - "dj": 6520, - "sessions": 6521, - "hp": 6522, - "refer": 6523, - "rarely": 6524, - "##ora": 6525, - "exists": 6526, - "1892": 6527, - "##ten": 6528, - "scientists": 6529, - "dirty": 6530, - "penalty": 6531, - "burst": 6532, - "portrait": 6533, - "seed": 6534, - "79": 6535, - "pole": 6536, - "limits": 6537, - "rival": 6538, - "1894": 6539, - "stable": 6540, - "alpha": 6541, - "grave": 6542, - "constitutional": 6543, - "alcohol": 6544, - "arrest": 6545, - "flower": 6546, - "mystery": 6547, - "devil": 6548, - "architectural": 6549, - "relationships": 6550, - "greatly": 6551, - "habitat": 6552, - "##istic": 6553, - "larry": 6554, - "progressive": 6555, - "remote": 6556, - "cotton": 6557, - "##ics": 6558, - "##ok": 6559, - "preserved": 6560, - "reaches": 6561, - "##ming": 6562, - "cited": 6563, - "86": 6564, - "vast": 6565, - "scholarship": 6566, - "decisions": 6567, - "cbs": 6568, - "joy": 6569, - "teach": 6570, - "1885": 6571, - "editions": 6572, - "knocked": 6573, - "eve": 6574, - "searching": 6575, - "partly": 6576, - "participation": 6577, - "gap": 6578, - "animated": 6579, - "fate": 6580, - "excellent": 6581, - "##ett": 6582, - "na": 6583, - "87": 6584, - "alternate": 6585, - "saints": 6586, - "youngest": 6587, - "##ily": 6588, - "climbed": 6589, - "##ita": 6590, - "##tors": 6591, - "suggest": 6592, - "##ct": 6593, - "discussion": 6594, - "staying": 6595, - "choir": 6596, - "lakes": 6597, - "jacket": 6598, - "revenue": 6599, - "nevertheless": 6600, - "peaked": 6601, - "instrument": 6602, - "wondering": 6603, - "annually": 6604, - "managing": 6605, - "neil": 6606, - "1891": 6607, - "signing": 6608, - "terry": 6609, - "##ice": 6610, - "apply": 6611, - "clinical": 6612, - "brooklyn": 6613, - "aim": 6614, - "catherine": 6615, - "fuck": 6616, - "farmers": 6617, - "figured": 6618, - "ninth": 6619, - "pride": 6620, - "hugh": 6621, - "evolution": 6622, - "ordinary": 6623, - "involvement": 6624, - "comfortable": 6625, - "shouted": 6626, - "tech": 6627, - "encouraged": 6628, - "taiwan": 6629, - "representation": 6630, - "sharing": 6631, - "##lia": 6632, - "##em": 6633, - "panic": 6634, - "exact": 6635, - "cargo": 6636, - "competing": 6637, - "fat": 6638, - "cried": 6639, - "83": 6640, - "1920s": 6641, - "occasions": 6642, - "pa": 6643, - "cabin": 6644, - "borders": 6645, - "utah": 6646, - "marcus": 6647, - "##isation": 6648, - "badly": 6649, - "muscles": 6650, - "##ance": 6651, - "victorian": 6652, - "transition": 6653, - "warner": 6654, - "bet": 6655, - "permission": 6656, - "##rin": 6657, - "slave": 6658, - "terrible": 6659, - "similarly": 6660, - "shares": 6661, - "seth": 6662, - "uefa": 6663, - "possession": 6664, - "medals": 6665, - "benefits": 6666, - "colleges": 6667, - "lowered": 6668, - "perfectly": 6669, - "mall": 6670, - "transit": 6671, - "##ye": 6672, - "##kar": 6673, - "publisher": 6674, - "##ened": 6675, - "harrison": 6676, - "deaths": 6677, - "elevation": 6678, - "##ae": 6679, - "asleep": 6680, - "machines": 6681, - "sigh": 6682, - "ash": 6683, - "hardly": 6684, - "argument": 6685, - "occasion": 6686, - "parent": 6687, - "leo": 6688, - "decline": 6689, - "1888": 6690, - "contribution": 6691, - "##ua": 6692, - "concentration": 6693, - "1000": 6694, - "opportunities": 6695, - "hispanic": 6696, - "guardian": 6697, - "extent": 6698, - "emotions": 6699, - "hips": 6700, - "mason": 6701, - "volumes": 6702, - "bloody": 6703, - "controversy": 6704, - "diameter": 6705, - "steady": 6706, - "mistake": 6707, - "phoenix": 6708, - "identify": 6709, - "violin": 6710, - "##sk": 6711, - "departure": 6712, - "richmond": 6713, - "spin": 6714, - "funeral": 6715, - "enemies": 6716, - "1864": 6717, - "gear": 6718, - "literally": 6719, - "connor": 6720, - "random": 6721, - "sergeant": 6722, - "grab": 6723, - "confusion": 6724, - "1865": 6725, - "transmission": 6726, - "informed": 6727, - "op": 6728, - "leaning": 6729, - "sacred": 6730, - "suspended": 6731, - "thinks": 6732, - "gates": 6733, - "portland": 6734, - "luck": 6735, - "agencies": 6736, - "yours": 6737, - "hull": 6738, - "expert": 6739, - "muscle": 6740, - "layer": 6741, - "practical": 6742, - "sculpture": 6743, - "jerusalem": 6744, - "latest": 6745, - "lloyd": 6746, - "statistics": 6747, - "deeper": 6748, - "recommended": 6749, - "warrior": 6750, - "arkansas": 6751, - "mess": 6752, - "supports": 6753, - "greg": 6754, - "eagle": 6755, - "1880": 6756, - "recovered": 6757, - "rated": 6758, - "concerts": 6759, - "rushed": 6760, - "##ano": 6761, - "stops": 6762, - "eggs": 6763, - "files": 6764, - "premiere": 6765, - "keith": 6766, - "##vo": 6767, - "delhi": 6768, - "turner": 6769, - "pit": 6770, - "affair": 6771, - "belief": 6772, - "paint": 6773, - "##zing": 6774, - "mate": 6775, - "##ach": 6776, - "##ev": 6777, - "victim": 6778, - "##ology": 6779, - "withdrew": 6780, - "bonus": 6781, - "styles": 6782, - "fled": 6783, - "##ud": 6784, - "glasgow": 6785, - "technologies": 6786, - "funded": 6787, - "nbc": 6788, - "adaptation": 6789, - "##ata": 6790, - "portrayed": 6791, - "cooperation": 6792, - "supporters": 6793, - "judges": 6794, - "bernard": 6795, - "justin": 6796, - "hallway": 6797, - "ralph": 6798, - "##ick": 6799, - "graduating": 6800, - "controversial": 6801, - "distant": 6802, - "continental": 6803, - "spider": 6804, - "bite": 6805, - "##ho": 6806, - "recognize": 6807, - "intention": 6808, - "mixing": 6809, - "##ese": 6810, - "egyptian": 6811, - "bow": 6812, - "tourism": 6813, - "suppose": 6814, - "claiming": 6815, - "tiger": 6816, - "dominated": 6817, - "participants": 6818, - "vi": 6819, - "##ru": 6820, - "nurse": 6821, - "partially": 6822, - "tape": 6823, - "##rum": 6824, - "psychology": 6825, - "##rn": 6826, - "essential": 6827, - "touring": 6828, - "duo": 6829, - "voting": 6830, - "civilian": 6831, - "emotional": 6832, - "channels": 6833, - "##king": 6834, - "apparent": 6835, - "hebrew": 6836, - "1887": 6837, - "tommy": 6838, - "carrier": 6839, - "intersection": 6840, - "beast": 6841, - "hudson": 6842, - "##gar": 6843, - "##zo": 6844, - "lab": 6845, - "nova": 6846, - "bench": 6847, - "discuss": 6848, - "costa": 6849, - "##ered": 6850, - "detailed": 6851, - "behalf": 6852, - "drivers": 6853, - "unfortunately": 6854, - "obtain": 6855, - "##lis": 6856, - "rocky": 6857, - "##dae": 6858, - "siege": 6859, - "friendship": 6860, - "honey": 6861, - "##rian": 6862, - "1861": 6863, - "amy": 6864, - "hang": 6865, - "posted": 6866, - "governments": 6867, - "collins": 6868, - "respond": 6869, - "wildlife": 6870, - "preferred": 6871, - "operator": 6872, - "##po": 6873, - "laura": 6874, - "pregnant": 6875, - "videos": 6876, - "dennis": 6877, - "suspected": 6878, - "boots": 6879, - "instantly": 6880, - "weird": 6881, - "automatic": 6882, - "businessman": 6883, - "alleged": 6884, - "placing": 6885, - "throwing": 6886, - "ph": 6887, - "mood": 6888, - "1862": 6889, - "perry": 6890, - "venue": 6891, - "jet": 6892, - "remainder": 6893, - "##lli": 6894, - "##ci": 6895, - "passion": 6896, - "biological": 6897, - "boyfriend": 6898, - "1863": 6899, - "dirt": 6900, - "buffalo": 6901, - "ron": 6902, - "segment": 6903, - "fa": 6904, - "abuse": 6905, - "##era": 6906, - "genre": 6907, - "thrown": 6908, - "stroke": 6909, - "colored": 6910, - "stress": 6911, - "exercise": 6912, - "displayed": 6913, - "##gen": 6914, - "struggled": 6915, - "##tti": 6916, - "abroad": 6917, - "dramatic": 6918, - "wonderful": 6919, - "thereafter": 6920, - "madrid": 6921, - "component": 6922, - "widespread": 6923, - "##sed": 6924, - "tale": 6925, - "citizen": 6926, - "todd": 6927, - "monday": 6928, - "1886": 6929, - "vancouver": 6930, - "overseas": 6931, - "forcing": 6932, - "crying": 6933, - "descent": 6934, - "##ris": 6935, - "discussed": 6936, - "substantial": 6937, - "ranks": 6938, - "regime": 6939, - "1870": 6940, - "provinces": 6941, - "switch": 6942, - "drum": 6943, - "zane": 6944, - "ted": 6945, - "tribes": 6946, - "proof": 6947, - "lp": 6948, - "cream": 6949, - "researchers": 6950, - "volunteer": 6951, - "manor": 6952, - "silk": 6953, - "milan": 6954, - "donated": 6955, - "allies": 6956, - "venture": 6957, - "principle": 6958, - "delivery": 6959, - "enterprise": 6960, - "##ves": 6961, - "##ans": 6962, - "bars": 6963, - "traditionally": 6964, - "witch": 6965, - "reminded": 6966, - "copper": 6967, - "##uk": 6968, - "pete": 6969, - "inter": 6970, - "links": 6971, - "colin": 6972, - "grinned": 6973, - "elsewhere": 6974, - "competitive": 6975, - "frequent": 6976, - "##oy": 6977, - "scream": 6978, - "##hu": 6979, - "tension": 6980, - "texts": 6981, - "submarine": 6982, - "finnish": 6983, - "defending": 6984, - "defend": 6985, - "pat": 6986, - "detail": 6987, - "1884": 6988, - "affiliated": 6989, - "stuart": 6990, - "themes": 6991, - "villa": 6992, - "periods": 6993, - "tool": 6994, - "belgian": 6995, - "ruling": 6996, - "crimes": 6997, - "answers": 6998, - "folded": 6999, - "licensed": 7000, - "resort": 7001, - "demolished": 7002, - "hans": 7003, - "lucy": 7004, - "1881": 7005, - "lion": 7006, - "traded": 7007, - "photographs": 7008, - "writes": 7009, - "craig": 7010, - "##fa": 7011, - "trials": 7012, - "generated": 7013, - "beth": 7014, - "noble": 7015, - "debt": 7016, - "percentage": 7017, - "yorkshire": 7018, - "erected": 7019, - "ss": 7020, - "viewed": 7021, - "grades": 7022, - "confidence": 7023, - "ceased": 7024, - "islam": 7025, - "telephone": 7026, - "retail": 7027, - "##ible": 7028, - "chile": 7029, - "m²": 7030, - "roberts": 7031, - "sixteen": 7032, - "##ich": 7033, - "commented": 7034, - "hampshire": 7035, - "innocent": 7036, - "dual": 7037, - "pounds": 7038, - "checked": 7039, - "regulations": 7040, - "afghanistan": 7041, - "sung": 7042, - "rico": 7043, - "liberty": 7044, - "assets": 7045, - "bigger": 7046, - "options": 7047, - "angels": 7048, - "relegated": 7049, - "tribute": 7050, - "wells": 7051, - "attending": 7052, - "leaf": 7053, - "##yan": 7054, - "butler": 7055, - "romanian": 7056, - "forum": 7057, - "monthly": 7058, - "lisa": 7059, - "patterns": 7060, - "gmina": 7061, - "##tory": 7062, - "madison": 7063, - "hurricane": 7064, - "rev": 7065, - "##ians": 7066, - "bristol": 7067, - "##ula": 7068, - "elite": 7069, - "valuable": 7070, - "disaster": 7071, - "democracy": 7072, - "awareness": 7073, - "germans": 7074, - "freyja": 7075, - "##ins": 7076, - "loop": 7077, - "absolutely": 7078, - "paying": 7079, - "populations": 7080, - "maine": 7081, - "sole": 7082, - "prayer": 7083, - "spencer": 7084, - "releases": 7085, - "doorway": 7086, - "bull": 7087, - "##ani": 7088, - "lover": 7089, - "midnight": 7090, - "conclusion": 7091, - "##sson": 7092, - "thirteen": 7093, - "lily": 7094, - "mediterranean": 7095, - "##lt": 7096, - "nhl": 7097, - "proud": 7098, - "sample": 7099, - "##hill": 7100, - "drummer": 7101, - "guinea": 7102, - "##ova": 7103, - "murphy": 7104, - "climb": 7105, - "##ston": 7106, - "instant": 7107, - "attributed": 7108, - "horn": 7109, - "ain": 7110, - "railways": 7111, - "steven": 7112, - "##ao": 7113, - "autumn": 7114, - "ferry": 7115, - "opponent": 7116, - "root": 7117, - "traveling": 7118, - "secured": 7119, - "corridor": 7120, - "stretched": 7121, - "tales": 7122, - "sheet": 7123, - "trinity": 7124, - "cattle": 7125, - "helps": 7126, - "indicates": 7127, - "manhattan": 7128, - "murdered": 7129, - "fitted": 7130, - "1882": 7131, - "gentle": 7132, - "grandmother": 7133, - "mines": 7134, - "shocked": 7135, - "vegas": 7136, - "produces": 7137, - "##light": 7138, - "caribbean": 7139, - "##ou": 7140, - "belong": 7141, - "continuous": 7142, - "desperate": 7143, - "drunk": 7144, - "historically": 7145, - "trio": 7146, - "waved": 7147, - "raf": 7148, - "dealing": 7149, - "nathan": 7150, - "bat": 7151, - "murmured": 7152, - "interrupted": 7153, - "residing": 7154, - "scientist": 7155, - "pioneer": 7156, - "harold": 7157, - "aaron": 7158, - "##net": 7159, - "delta": 7160, - "attempting": 7161, - "minority": 7162, - "mini": 7163, - "believes": 7164, - "chorus": 7165, - "tend": 7166, - "lots": 7167, - "eyed": 7168, - "indoor": 7169, - "load": 7170, - "shots": 7171, - "updated": 7172, - "jail": 7173, - "##llo": 7174, - "concerning": 7175, - "connecting": 7176, - "wealth": 7177, - "##ved": 7178, - "slaves": 7179, - "arrive": 7180, - "rangers": 7181, - "sufficient": 7182, - "rebuilt": 7183, - "##wick": 7184, - "cardinal": 7185, - "flood": 7186, - "muhammad": 7187, - "whenever": 7188, - "relation": 7189, - "runners": 7190, - "moral": 7191, - "repair": 7192, - "viewers": 7193, - "arriving": 7194, - "revenge": 7195, - "punk": 7196, - "assisted": 7197, - "bath": 7198, - "fairly": 7199, - "breathe": 7200, - "lists": 7201, - "innings": 7202, - "illustrated": 7203, - "whisper": 7204, - "nearest": 7205, - "voters": 7206, - "clinton": 7207, - "ties": 7208, - "ultimate": 7209, - "screamed": 7210, - "beijing": 7211, - "lions": 7212, - "andre": 7213, - "fictional": 7214, - "gathering": 7215, - "comfort": 7216, - "radar": 7217, - "suitable": 7218, - "dismissed": 7219, - "hms": 7220, - "ban": 7221, - "pine": 7222, - "wrist": 7223, - "atmosphere": 7224, - "voivodeship": 7225, - "bid": 7226, - "timber": 7227, - "##ned": 7228, - "##nan": 7229, - "giants": 7230, - "##ane": 7231, - "cameron": 7232, - "recovery": 7233, - "uss": 7234, - "identical": 7235, - "categories": 7236, - "switched": 7237, - "serbia": 7238, - "laughter": 7239, - "noah": 7240, - "ensemble": 7241, - "therapy": 7242, - "peoples": 7243, - "touching": 7244, - "##off": 7245, - "locally": 7246, - "pearl": 7247, - "platforms": 7248, - "everywhere": 7249, - "ballet": 7250, - "tables": 7251, - "lanka": 7252, - "herbert": 7253, - "outdoor": 7254, - "toured": 7255, - "derek": 7256, - "1883": 7257, - "spaces": 7258, - "contested": 7259, - "swept": 7260, - "1878": 7261, - "exclusive": 7262, - "slight": 7263, - "connections": 7264, - "##dra": 7265, - "winds": 7266, - "prisoner": 7267, - "collective": 7268, - "bangladesh": 7269, - "tube": 7270, - "publicly": 7271, - "wealthy": 7272, - "thai": 7273, - "##ys": 7274, - "isolated": 7275, - "select": 7276, - "##ric": 7277, - "insisted": 7278, - "pen": 7279, - "fortune": 7280, - "ticket": 7281, - "spotted": 7282, - "reportedly": 7283, - "animation": 7284, - "enforcement": 7285, - "tanks": 7286, - "110": 7287, - "decides": 7288, - "wider": 7289, - "lowest": 7290, - "owen": 7291, - "##time": 7292, - "nod": 7293, - "hitting": 7294, - "##hn": 7295, - "gregory": 7296, - "furthermore": 7297, - "magazines": 7298, - "fighters": 7299, - "solutions": 7300, - "##ery": 7301, - "pointing": 7302, - "requested": 7303, - "peru": 7304, - "reed": 7305, - "chancellor": 7306, - "knights": 7307, - "mask": 7308, - "worker": 7309, - "eldest": 7310, - "flames": 7311, - "reduction": 7312, - "1860": 7313, - "volunteers": 7314, - "##tis": 7315, - "reporting": 7316, - "##hl": 7317, - "wire": 7318, - "advisory": 7319, - "endemic": 7320, - "origins": 7321, - "settlers": 7322, - "pursue": 7323, - "knock": 7324, - "consumer": 7325, - "1876": 7326, - "eu": 7327, - "compound": 7328, - "creatures": 7329, - "mansion": 7330, - "sentenced": 7331, - "ivan": 7332, - "deployed": 7333, - "guitars": 7334, - "frowned": 7335, - "involves": 7336, - "mechanism": 7337, - "kilometers": 7338, - "perspective": 7339, - "shops": 7340, - "maps": 7341, - "terminus": 7342, - "duncan": 7343, - "alien": 7344, - "fist": 7345, - "bridges": 7346, - "##pers": 7347, - "heroes": 7348, - "fed": 7349, - "derby": 7350, - "swallowed": 7351, - "##ros": 7352, - "patent": 7353, - "sara": 7354, - "illness": 7355, - "characterized": 7356, - "adventures": 7357, - "slide": 7358, - "hawaii": 7359, - "jurisdiction": 7360, - "##op": 7361, - "organised": 7362, - "##side": 7363, - "adelaide": 7364, - "walks": 7365, - "biology": 7366, - "se": 7367, - "##ties": 7368, - "rogers": 7369, - "swing": 7370, - "tightly": 7371, - "boundaries": 7372, - "##rie": 7373, - "prepare": 7374, - "implementation": 7375, - "stolen": 7376, - "##sha": 7377, - "certified": 7378, - "colombia": 7379, - "edwards": 7380, - "garage": 7381, - "##mm": 7382, - "recalled": 7383, - "##ball": 7384, - "rage": 7385, - "harm": 7386, - "nigeria": 7387, - "breast": 7388, - "##ren": 7389, - "furniture": 7390, - "pupils": 7391, - "settle": 7392, - "##lus": 7393, - "cuba": 7394, - "balls": 7395, - "client": 7396, - "alaska": 7397, - "21st": 7398, - "linear": 7399, - "thrust": 7400, - "celebration": 7401, - "latino": 7402, - "genetic": 7403, - "terror": 7404, - "##cia": 7405, - "##ening": 7406, - "lightning": 7407, - "fee": 7408, - "witness": 7409, - "lodge": 7410, - "establishing": 7411, - "skull": 7412, - "##ique": 7413, - "earning": 7414, - "hood": 7415, - "##ei": 7416, - "rebellion": 7417, - "wang": 7418, - "sporting": 7419, - "warned": 7420, - "missile": 7421, - "devoted": 7422, - "activist": 7423, - "porch": 7424, - "worship": 7425, - "fourteen": 7426, - "package": 7427, - "1871": 7428, - "decorated": 7429, - "##shire": 7430, - "housed": 7431, - "##ock": 7432, - "chess": 7433, - "sailed": 7434, - "doctors": 7435, - "oscar": 7436, - "joan": 7437, - "treat": 7438, - "garcia": 7439, - "harbour": 7440, - "jeremy": 7441, - "##ire": 7442, - "traditions": 7443, - "dominant": 7444, - "jacques": 7445, - "##gon": 7446, - "##wan": 7447, - "relocated": 7448, - "1879": 7449, - "amendment": 7450, - "sized": 7451, - "companion": 7452, - "simultaneously": 7453, - "volleyball": 7454, - "spun": 7455, - "acre": 7456, - "increases": 7457, - "stopping": 7458, - "loves": 7459, - "belongs": 7460, - "affect": 7461, - "drafted": 7462, - "tossed": 7463, - "scout": 7464, - "battles": 7465, - "1875": 7466, - "filming": 7467, - "shoved": 7468, - "munich": 7469, - "tenure": 7470, - "vertical": 7471, - "romance": 7472, - "pc": 7473, - "##cher": 7474, - "argue": 7475, - "##ical": 7476, - "craft": 7477, - "ranging": 7478, - "www": 7479, - "opens": 7480, - "honest": 7481, - "tyler": 7482, - "yesterday": 7483, - "virtual": 7484, - "##let": 7485, - "muslims": 7486, - "reveal": 7487, - "snake": 7488, - "immigrants": 7489, - "radical": 7490, - "screaming": 7491, - "speakers": 7492, - "firing": 7493, - "saving": 7494, - "belonging": 7495, - "ease": 7496, - "lighting": 7497, - "prefecture": 7498, - "blame": 7499, - "farmer": 7500, - "hungry": 7501, - "grows": 7502, - "rubbed": 7503, - "beam": 7504, - "sur": 7505, - "subsidiary": 7506, - "##cha": 7507, - "armenian": 7508, - "sao": 7509, - "dropping": 7510, - "conventional": 7511, - "##fer": 7512, - "microsoft": 7513, - "reply": 7514, - "qualify": 7515, - "spots": 7516, - "1867": 7517, - "sweat": 7518, - "festivals": 7519, - "##ken": 7520, - "immigration": 7521, - "physician": 7522, - "discover": 7523, - "exposure": 7524, - "sandy": 7525, - "explanation": 7526, - "isaac": 7527, - "implemented": 7528, - "##fish": 7529, - "hart": 7530, - "initiated": 7531, - "connect": 7532, - "stakes": 7533, - "presents": 7534, - "heights": 7535, - "householder": 7536, - "pleased": 7537, - "tourist": 7538, - "regardless": 7539, - "slip": 7540, - "closest": 7541, - "##ction": 7542, - "surely": 7543, - "sultan": 7544, - "brings": 7545, - "riley": 7546, - "preparation": 7547, - "aboard": 7548, - "slammed": 7549, - "baptist": 7550, - "experiment": 7551, - "ongoing": 7552, - "interstate": 7553, - "organic": 7554, - "playoffs": 7555, - "##ika": 7556, - "1877": 7557, - "130": 7558, - "##tar": 7559, - "hindu": 7560, - "error": 7561, - "tours": 7562, - "tier": 7563, - "plenty": 7564, - "arrangements": 7565, - "talks": 7566, - "trapped": 7567, - "excited": 7568, - "sank": 7569, - "ho": 7570, - "athens": 7571, - "1872": 7572, - "denver": 7573, - "welfare": 7574, - "suburb": 7575, - "athletes": 7576, - "trick": 7577, - "diverse": 7578, - "belly": 7579, - "exclusively": 7580, - "yelled": 7581, - "1868": 7582, - "##med": 7583, - "conversion": 7584, - "##ette": 7585, - "1874": 7586, - "internationally": 7587, - "computers": 7588, - "conductor": 7589, - "abilities": 7590, - "sensitive": 7591, - "hello": 7592, - "dispute": 7593, - "measured": 7594, - "globe": 7595, - "rocket": 7596, - "prices": 7597, - "amsterdam": 7598, - "flights": 7599, - "tigers": 7600, - "inn": 7601, - "municipalities": 7602, - "emotion": 7603, - "references": 7604, - "3d": 7605, - "##mus": 7606, - "explains": 7607, - "airlines": 7608, - "manufactured": 7609, - "pm": 7610, - "archaeological": 7611, - "1873": 7612, - "interpretation": 7613, - "devon": 7614, - "comment": 7615, - "##ites": 7616, - "settlements": 7617, - "kissing": 7618, - "absolute": 7619, - "improvement": 7620, - "suite": 7621, - "impressed": 7622, - "barcelona": 7623, - "sullivan": 7624, - "jefferson": 7625, - "towers": 7626, - "jesse": 7627, - "julie": 7628, - "##tin": 7629, - "##lu": 7630, - "grandson": 7631, - "hi": 7632, - "gauge": 7633, - "regard": 7634, - "rings": 7635, - "interviews": 7636, - "trace": 7637, - "raymond": 7638, - "thumb": 7639, - "departments": 7640, - "burns": 7641, - "serial": 7642, - "bulgarian": 7643, - "scores": 7644, - "demonstrated": 7645, - "##ix": 7646, - "1866": 7647, - "kyle": 7648, - "alberta": 7649, - "underneath": 7650, - "romanized": 7651, - "##ward": 7652, - "relieved": 7653, - "acquisition": 7654, - "phrase": 7655, - "cliff": 7656, - "reveals": 7657, - "han": 7658, - "cuts": 7659, - "merger": 7660, - "custom": 7661, - "##dar": 7662, - "nee": 7663, - "gilbert": 7664, - "graduation": 7665, - "##nts": 7666, - "assessment": 7667, - "cafe": 7668, - "difficulty": 7669, - "demands": 7670, - "swung": 7671, - "democrat": 7672, - "jennifer": 7673, - "commons": 7674, - "1940s": 7675, - "grove": 7676, - "##yo": 7677, - "completing": 7678, - "focuses": 7679, - "sum": 7680, - "substitute": 7681, - "bearing": 7682, - "stretch": 7683, - "reception": 7684, - "##py": 7685, - "reflected": 7686, - "essentially": 7687, - "destination": 7688, - "pairs": 7689, - "##ched": 7690, - "survival": 7691, - "resource": 7692, - "##bach": 7693, - "promoting": 7694, - "doubles": 7695, - "messages": 7696, - "tear": 7697, - "##down": 7698, - "##fully": 7699, - "parade": 7700, - "florence": 7701, - "harvey": 7702, - "incumbent": 7703, - "partial": 7704, - "framework": 7705, - "900": 7706, - "pedro": 7707, - "frozen": 7708, - "procedure": 7709, - "olivia": 7710, - "controls": 7711, - "##mic": 7712, - "shelter": 7713, - "personally": 7714, - "temperatures": 7715, - "##od": 7716, - "brisbane": 7717, - "tested": 7718, - "sits": 7719, - "marble": 7720, - "comprehensive": 7721, - "oxygen": 7722, - "leonard": 7723, - "##kov": 7724, - "inaugural": 7725, - "iranian": 7726, - "referring": 7727, - "quarters": 7728, - "attitude": 7729, - "##ivity": 7730, - "mainstream": 7731, - "lined": 7732, - "mars": 7733, - "dakota": 7734, - "norfolk": 7735, - "unsuccessful": 7736, - "##°": 7737, - "explosion": 7738, - "helicopter": 7739, - "congressional": 7740, - "##sing": 7741, - "inspector": 7742, - "bitch": 7743, - "seal": 7744, - "departed": 7745, - "divine": 7746, - "##ters": 7747, - "coaching": 7748, - "examination": 7749, - "punishment": 7750, - "manufacturer": 7751, - "sink": 7752, - "columns": 7753, - "unincorporated": 7754, - "signals": 7755, - "nevada": 7756, - "squeezed": 7757, - "dylan": 7758, - "dining": 7759, - "photos": 7760, - "martial": 7761, - "manuel": 7762, - "eighteen": 7763, - "elevator": 7764, - "brushed": 7765, - "plates": 7766, - "ministers": 7767, - "ivy": 7768, - "congregation": 7769, - "##len": 7770, - "slept": 7771, - "specialized": 7772, - "taxes": 7773, - "curve": 7774, - "restricted": 7775, - "negotiations": 7776, - "likes": 7777, - "statistical": 7778, - "arnold": 7779, - "inspiration": 7780, - "execution": 7781, - "bold": 7782, - "intermediate": 7783, - "significance": 7784, - "margin": 7785, - "ruler": 7786, - "wheels": 7787, - "gothic": 7788, - "intellectual": 7789, - "dependent": 7790, - "listened": 7791, - "eligible": 7792, - "buses": 7793, - "widow": 7794, - "syria": 7795, - "earn": 7796, - "cincinnati": 7797, - "collapsed": 7798, - "recipient": 7799, - "secrets": 7800, - "accessible": 7801, - "philippine": 7802, - "maritime": 7803, - "goddess": 7804, - "clerk": 7805, - "surrender": 7806, - "breaks": 7807, - "playoff": 7808, - "database": 7809, - "##ified": 7810, - "##lon": 7811, - "ideal": 7812, - "beetle": 7813, - "aspect": 7814, - "soap": 7815, - "regulation": 7816, - "strings": 7817, - "expand": 7818, - "anglo": 7819, - "shorter": 7820, - "crosses": 7821, - "retreat": 7822, - "tough": 7823, - "coins": 7824, - "wallace": 7825, - "directions": 7826, - "pressing": 7827, - "##oon": 7828, - "shipping": 7829, - "locomotives": 7830, - "comparison": 7831, - "topics": 7832, - "nephew": 7833, - "##mes": 7834, - "distinction": 7835, - "honors": 7836, - "travelled": 7837, - "sierra": 7838, - "ibn": 7839, - "##over": 7840, - "fortress": 7841, - "sa": 7842, - "recognised": 7843, - "carved": 7844, - "1869": 7845, - "clients": 7846, - "##dan": 7847, - "intent": 7848, - "##mar": 7849, - "coaches": 7850, - "describing": 7851, - "bread": 7852, - "##ington": 7853, - "beaten": 7854, - "northwestern": 7855, - "##ona": 7856, - "merit": 7857, - "youtube": 7858, - "collapse": 7859, - "challenges": 7860, - "em": 7861, - "historians": 7862, - "objective": 7863, - "submitted": 7864, - "virus": 7865, - "attacking": 7866, - "drake": 7867, - "assume": 7868, - "##ere": 7869, - "diseases": 7870, - "marc": 7871, - "stem": 7872, - "leeds": 7873, - "##cus": 7874, - "##ab": 7875, - "farming": 7876, - "glasses": 7877, - "##lock": 7878, - "visits": 7879, - "nowhere": 7880, - "fellowship": 7881, - "relevant": 7882, - "carries": 7883, - "restaurants": 7884, - "experiments": 7885, - "101": 7886, - "constantly": 7887, - "bases": 7888, - "targets": 7889, - "shah": 7890, - "tenth": 7891, - "opponents": 7892, - "verse": 7893, - "territorial": 7894, - "##ira": 7895, - "writings": 7896, - "corruption": 7897, - "##hs": 7898, - "instruction": 7899, - "inherited": 7900, - "reverse": 7901, - "emphasis": 7902, - "##vic": 7903, - "employee": 7904, - "arch": 7905, - "keeps": 7906, - "rabbi": 7907, - "watson": 7908, - "payment": 7909, - "uh": 7910, - "##ala": 7911, - "nancy": 7912, - "##tre": 7913, - "venice": 7914, - "fastest": 7915, - "sexy": 7916, - "banned": 7917, - "adrian": 7918, - "properly": 7919, - "ruth": 7920, - "touchdown": 7921, - "dollar": 7922, - "boards": 7923, - "metre": 7924, - "circles": 7925, - "edges": 7926, - "favour": 7927, - "comments": 7928, - "ok": 7929, - "travels": 7930, - "liberation": 7931, - "scattered": 7932, - "firmly": 7933, - "##ular": 7934, - "holland": 7935, - "permitted": 7936, - "diesel": 7937, - "kenya": 7938, - "den": 7939, - "originated": 7940, - "##ral": 7941, - "demons": 7942, - "resumed": 7943, - "dragged": 7944, - "rider": 7945, - "##rus": 7946, - "servant": 7947, - "blinked": 7948, - "extend": 7949, - "torn": 7950, - "##ias": 7951, - "##sey": 7952, - "input": 7953, - "meal": 7954, - "everybody": 7955, - "cylinder": 7956, - "kinds": 7957, - "camps": 7958, - "##fe": 7959, - "bullet": 7960, - "logic": 7961, - "##wn": 7962, - "croatian": 7963, - "evolved": 7964, - "healthy": 7965, - "fool": 7966, - "chocolate": 7967, - "wise": 7968, - "preserve": 7969, - "pradesh": 7970, - "##ess": 7971, - "respective": 7972, - "1850": 7973, - "##ew": 7974, - "chicken": 7975, - "artificial": 7976, - "gross": 7977, - "corresponding": 7978, - "convicted": 7979, - "cage": 7980, - "caroline": 7981, - "dialogue": 7982, - "##dor": 7983, - "narrative": 7984, - "stranger": 7985, - "mario": 7986, - "br": 7987, - "christianity": 7988, - "failing": 7989, - "trent": 7990, - "commanding": 7991, - "buddhist": 7992, - "1848": 7993, - "maurice": 7994, - "focusing": 7995, - "yale": 7996, - "bike": 7997, - "altitude": 7998, - "##ering": 7999, - "mouse": 8000, - "revised": 8001, - "##sley": 8002, - "veteran": 8003, - "##ig": 8004, - "pulls": 8005, - "theology": 8006, - "crashed": 8007, - "campaigns": 8008, - "legion": 8009, - "##ability": 8010, - "drag": 8011, - "excellence": 8012, - "customer": 8013, - "cancelled": 8014, - "intensity": 8015, - "excuse": 8016, - "##lar": 8017, - "liga": 8018, - "participating": 8019, - "contributing": 8020, - "printing": 8021, - "##burn": 8022, - "variable": 8023, - "##rk": 8024, - "curious": 8025, - "bin": 8026, - "legacy": 8027, - "renaissance": 8028, - "##my": 8029, - "symptoms": 8030, - "binding": 8031, - "vocalist": 8032, - "dancer": 8033, - "##nie": 8034, - "grammar": 8035, - "gospel": 8036, - "democrats": 8037, - "ya": 8038, - "enters": 8039, - "sc": 8040, - "diplomatic": 8041, - "hitler": 8042, - "##ser": 8043, - "clouds": 8044, - "mathematical": 8045, - "quit": 8046, - "defended": 8047, - "oriented": 8048, - "##heim": 8049, - "fundamental": 8050, - "hardware": 8051, - "impressive": 8052, - "equally": 8053, - "convince": 8054, - "confederate": 8055, - "guilt": 8056, - "chuck": 8057, - "sliding": 8058, - "##ware": 8059, - "magnetic": 8060, - "narrowed": 8061, - "petersburg": 8062, - "bulgaria": 8063, - "otto": 8064, - "phd": 8065, - "skill": 8066, - "##ama": 8067, - "reader": 8068, - "hopes": 8069, - "pitcher": 8070, - "reservoir": 8071, - "hearts": 8072, - "automatically": 8073, - "expecting": 8074, - "mysterious": 8075, - "bennett": 8076, - "extensively": 8077, - "imagined": 8078, - "seeds": 8079, - "monitor": 8080, - "fix": 8081, - "##ative": 8082, - "journalism": 8083, - "struggling": 8084, - "signature": 8085, - "ranch": 8086, - "encounter": 8087, - "photographer": 8088, - "observation": 8089, - "protests": 8090, - "##pin": 8091, - "influences": 8092, - "##hr": 8093, - "calendar": 8094, - "##all": 8095, - "cruz": 8096, - "croatia": 8097, - "locomotive": 8098, - "hughes": 8099, - "naturally": 8100, - "shakespeare": 8101, - "basement": 8102, - "hook": 8103, - "uncredited": 8104, - "faded": 8105, - "theories": 8106, - "approaches": 8107, - "dare": 8108, - "phillips": 8109, - "filling": 8110, - "fury": 8111, - "obama": 8112, - "##ain": 8113, - "efficient": 8114, - "arc": 8115, - "deliver": 8116, - "min": 8117, - "raid": 8118, - "breeding": 8119, - "inducted": 8120, - "leagues": 8121, - "efficiency": 8122, - "axis": 8123, - "montana": 8124, - "eagles": 8125, - "##ked": 8126, - "supplied": 8127, - "instructions": 8128, - "karen": 8129, - "picking": 8130, - "indicating": 8131, - "trap": 8132, - "anchor": 8133, - "practically": 8134, - "christians": 8135, - "tomb": 8136, - "vary": 8137, - "occasional": 8138, - "electronics": 8139, - "lords": 8140, - "readers": 8141, - "newcastle": 8142, - "faint": 8143, - "innovation": 8144, - "collect": 8145, - "situations": 8146, - "engagement": 8147, - "160": 8148, - "claude": 8149, - "mixture": 8150, - "##feld": 8151, - "peer": 8152, - "tissue": 8153, - "logo": 8154, - "lean": 8155, - "##ration": 8156, - "°f": 8157, - "floors": 8158, - "##ven": 8159, - "architects": 8160, - "reducing": 8161, - "##our": 8162, - "##ments": 8163, - "rope": 8164, - "1859": 8165, - "ottawa": 8166, - "##har": 8167, - "samples": 8168, - "banking": 8169, - "declaration": 8170, - "proteins": 8171, - "resignation": 8172, - "francois": 8173, - "saudi": 8174, - "advocate": 8175, - "exhibited": 8176, - "armor": 8177, - "twins": 8178, - "divorce": 8179, - "##ras": 8180, - "abraham": 8181, - "reviewed": 8182, - "jo": 8183, - "temporarily": 8184, - "matrix": 8185, - "physically": 8186, - "pulse": 8187, - "curled": 8188, - "##ena": 8189, - "difficulties": 8190, - "bengal": 8191, - "usage": 8192, - "##ban": 8193, - "annie": 8194, - "riders": 8195, - "certificate": 8196, - "##pi": 8197, - "holes": 8198, - "warsaw": 8199, - "distinctive": 8200, - "jessica": 8201, - "##mon": 8202, - "mutual": 8203, - "1857": 8204, - "customs": 8205, - "circular": 8206, - "eugene": 8207, - "removal": 8208, - "loaded": 8209, - "mere": 8210, - "vulnerable": 8211, - "depicted": 8212, - "generations": 8213, - "dame": 8214, - "heir": 8215, - "enormous": 8216, - "lightly": 8217, - "climbing": 8218, - "pitched": 8219, - "lessons": 8220, - "pilots": 8221, - "nepal": 8222, - "ram": 8223, - "google": 8224, - "preparing": 8225, - "brad": 8226, - "louise": 8227, - "renowned": 8228, - "##₂": 8229, - "liam": 8230, - "##ably": 8231, - "plaza": 8232, - "shaw": 8233, - "sophie": 8234, - "brilliant": 8235, - "bills": 8236, - "##bar": 8237, - "##nik": 8238, - "fucking": 8239, - "mainland": 8240, - "server": 8241, - "pleasant": 8242, - "seized": 8243, - "veterans": 8244, - "jerked": 8245, - "fail": 8246, - "beta": 8247, - "brush": 8248, - "radiation": 8249, - "stored": 8250, - "warmth": 8251, - "southeastern": 8252, - "nate": 8253, - "sin": 8254, - "raced": 8255, - "berkeley": 8256, - "joke": 8257, - "athlete": 8258, - "designation": 8259, - "trunk": 8260, - "##low": 8261, - "roland": 8262, - "qualification": 8263, - "archives": 8264, - "heels": 8265, - "artwork": 8266, - "receives": 8267, - "judicial": 8268, - "reserves": 8269, - "##bed": 8270, - "woke": 8271, - "installation": 8272, - "abu": 8273, - "floating": 8274, - "fake": 8275, - "lesser": 8276, - "excitement": 8277, - "interface": 8278, - "concentrated": 8279, - "addressed": 8280, - "characteristic": 8281, - "amanda": 8282, - "saxophone": 8283, - "monk": 8284, - "auto": 8285, - "##bus": 8286, - "releasing": 8287, - "egg": 8288, - "dies": 8289, - "interaction": 8290, - "defender": 8291, - "ce": 8292, - "outbreak": 8293, - "glory": 8294, - "loving": 8295, - "##bert": 8296, - "sequel": 8297, - "consciousness": 8298, - "http": 8299, - "awake": 8300, - "ski": 8301, - "enrolled": 8302, - "##ress": 8303, - "handling": 8304, - "rookie": 8305, - "brow": 8306, - "somebody": 8307, - "biography": 8308, - "warfare": 8309, - "amounts": 8310, - "contracts": 8311, - "presentation": 8312, - "fabric": 8313, - "dissolved": 8314, - "challenged": 8315, - "meter": 8316, - "psychological": 8317, - "lt": 8318, - "elevated": 8319, - "rally": 8320, - "accurate": 8321, - "##tha": 8322, - "hospitals": 8323, - "undergraduate": 8324, - "specialist": 8325, - "venezuela": 8326, - "exhibit": 8327, - "shed": 8328, - "nursing": 8329, - "protestant": 8330, - "fluid": 8331, - "structural": 8332, - "footage": 8333, - "jared": 8334, - "consistent": 8335, - "prey": 8336, - "##ska": 8337, - "succession": 8338, - "reflect": 8339, - "exile": 8340, - "lebanon": 8341, - "wiped": 8342, - "suspect": 8343, - "shanghai": 8344, - "resting": 8345, - "integration": 8346, - "preservation": 8347, - "marvel": 8348, - "variant": 8349, - "pirates": 8350, - "sheep": 8351, - "rounded": 8352, - "capita": 8353, - "sailing": 8354, - "colonies": 8355, - "manuscript": 8356, - "deemed": 8357, - "variations": 8358, - "clarke": 8359, - "functional": 8360, - "emerging": 8361, - "boxing": 8362, - "relaxed": 8363, - "curse": 8364, - "azerbaijan": 8365, - "heavyweight": 8366, - "nickname": 8367, - "editorial": 8368, - "rang": 8369, - "grid": 8370, - "tightened": 8371, - "earthquake": 8372, - "flashed": 8373, - "miguel": 8374, - "rushing": 8375, - "##ches": 8376, - "improvements": 8377, - "boxes": 8378, - "brooks": 8379, - "180": 8380, - "consumption": 8381, - "molecular": 8382, - "felix": 8383, - "societies": 8384, - "repeatedly": 8385, - "variation": 8386, - "aids": 8387, - "civic": 8388, - "graphics": 8389, - "professionals": 8390, - "realm": 8391, - "autonomous": 8392, - "receiver": 8393, - "delayed": 8394, - "workshop": 8395, - "militia": 8396, - "chairs": 8397, - "trump": 8398, - "canyon": 8399, - "##point": 8400, - "harsh": 8401, - "extending": 8402, - "lovely": 8403, - "happiness": 8404, - "##jan": 8405, - "stake": 8406, - "eyebrows": 8407, - "embassy": 8408, - "wellington": 8409, - "hannah": 8410, - "##ella": 8411, - "sony": 8412, - "corners": 8413, - "bishops": 8414, - "swear": 8415, - "cloth": 8416, - "contents": 8417, - "xi": 8418, - "namely": 8419, - "commenced": 8420, - "1854": 8421, - "stanford": 8422, - "nashville": 8423, - "courage": 8424, - "graphic": 8425, - "commitment": 8426, - "garrison": 8427, - "##bin": 8428, - "hamlet": 8429, - "clearing": 8430, - "rebels": 8431, - "attraction": 8432, - "literacy": 8433, - "cooking": 8434, - "ruins": 8435, - "temples": 8436, - "jenny": 8437, - "humanity": 8438, - "celebrate": 8439, - "hasn": 8440, - "freight": 8441, - "sixty": 8442, - "rebel": 8443, - "bastard": 8444, - "##art": 8445, - "newton": 8446, - "##ada": 8447, - "deer": 8448, - "##ges": 8449, - "##ching": 8450, - "smiles": 8451, - "delaware": 8452, - "singers": 8453, - "##ets": 8454, - "approaching": 8455, - "assists": 8456, - "flame": 8457, - "##ph": 8458, - "boulevard": 8459, - "barrel": 8460, - "planted": 8461, - "##ome": 8462, - "pursuit": 8463, - "##sia": 8464, - "consequences": 8465, - "posts": 8466, - "shallow": 8467, - "invitation": 8468, - "rode": 8469, - "depot": 8470, - "ernest": 8471, - "kane": 8472, - "rod": 8473, - "concepts": 8474, - "preston": 8475, - "topic": 8476, - "chambers": 8477, - "striking": 8478, - "blast": 8479, - "arrives": 8480, - "descendants": 8481, - "montgomery": 8482, - "ranges": 8483, - "worlds": 8484, - "##lay": 8485, - "##ari": 8486, - "span": 8487, - "chaos": 8488, - "praise": 8489, - "##ag": 8490, - "fewer": 8491, - "1855": 8492, - "sanctuary": 8493, - "mud": 8494, - "fbi": 8495, - "##ions": 8496, - "programmes": 8497, - "maintaining": 8498, - "unity": 8499, - "harper": 8500, - "bore": 8501, - "handsome": 8502, - "closure": 8503, - "tournaments": 8504, - "thunder": 8505, - "nebraska": 8506, - "linda": 8507, - "facade": 8508, - "puts": 8509, - "satisfied": 8510, - "argentine": 8511, - "dale": 8512, - "cork": 8513, - "dome": 8514, - "panama": 8515, - "##yl": 8516, - "1858": 8517, - "tasks": 8518, - "experts": 8519, - "##ates": 8520, - "feeding": 8521, - "equation": 8522, - "##las": 8523, - "##ida": 8524, - "##tu": 8525, - "engage": 8526, - "bryan": 8527, - "##ax": 8528, - "um": 8529, - "quartet": 8530, - "melody": 8531, - "disbanded": 8532, - "sheffield": 8533, - "blocked": 8534, - "gasped": 8535, - "delay": 8536, - "kisses": 8537, - "maggie": 8538, - "connects": 8539, - "##non": 8540, - "sts": 8541, - "poured": 8542, - "creator": 8543, - "publishers": 8544, - "##we": 8545, - "guided": 8546, - "ellis": 8547, - "extinct": 8548, - "hug": 8549, - "gaining": 8550, - "##ord": 8551, - "complicated": 8552, - "##bility": 8553, - "poll": 8554, - "clenched": 8555, - "investigate": 8556, - "##use": 8557, - "thereby": 8558, - "quantum": 8559, - "spine": 8560, - "cdp": 8561, - "humor": 8562, - "kills": 8563, - "administered": 8564, - "semifinals": 8565, - "##du": 8566, - "encountered": 8567, - "ignore": 8568, - "##bu": 8569, - "commentary": 8570, - "##maker": 8571, - "bother": 8572, - "roosevelt": 8573, - "140": 8574, - "plains": 8575, - "halfway": 8576, - "flowing": 8577, - "cultures": 8578, - "crack": 8579, - "imprisoned": 8580, - "neighboring": 8581, - "airline": 8582, - "##ses": 8583, - "##view": 8584, - "##mate": 8585, - "##ec": 8586, - "gather": 8587, - "wolves": 8588, - "marathon": 8589, - "transformed": 8590, - "##ill": 8591, - "cruise": 8592, - "organisations": 8593, - "carol": 8594, - "punch": 8595, - "exhibitions": 8596, - "numbered": 8597, - "alarm": 8598, - "ratings": 8599, - "daddy": 8600, - "silently": 8601, - "##stein": 8602, - "queens": 8603, - "colours": 8604, - "impression": 8605, - "guidance": 8606, - "liu": 8607, - "tactical": 8608, - "##rat": 8609, - "marshal": 8610, - "della": 8611, - "arrow": 8612, - "##ings": 8613, - "rested": 8614, - "feared": 8615, - "tender": 8616, - "owns": 8617, - "bitter": 8618, - "advisor": 8619, - "escort": 8620, - "##ides": 8621, - "spare": 8622, - "farms": 8623, - "grants": 8624, - "##ene": 8625, - "dragons": 8626, - "encourage": 8627, - "colleagues": 8628, - "cameras": 8629, - "##und": 8630, - "sucked": 8631, - "pile": 8632, - "spirits": 8633, - "prague": 8634, - "statements": 8635, - "suspension": 8636, - "landmark": 8637, - "fence": 8638, - "torture": 8639, - "recreation": 8640, - "bags": 8641, - "permanently": 8642, - "survivors": 8643, - "pond": 8644, - "spy": 8645, - "predecessor": 8646, - "bombing": 8647, - "coup": 8648, - "##og": 8649, - "protecting": 8650, - "transformation": 8651, - "glow": 8652, - "##lands": 8653, - "##book": 8654, - "dug": 8655, - "priests": 8656, - "andrea": 8657, - "feat": 8658, - "barn": 8659, - "jumping": 8660, - "##chen": 8661, - "##ologist": 8662, - "##con": 8663, - "casualties": 8664, - "stern": 8665, - "auckland": 8666, - "pipe": 8667, - "serie": 8668, - "revealing": 8669, - "ba": 8670, - "##bel": 8671, - "trevor": 8672, - "mercy": 8673, - "spectrum": 8674, - "yang": 8675, - "consist": 8676, - "governing": 8677, - "collaborated": 8678, - "possessed": 8679, - "epic": 8680, - "comprises": 8681, - "blew": 8682, - "shane": 8683, - "##ack": 8684, - "lopez": 8685, - "honored": 8686, - "magical": 8687, - "sacrifice": 8688, - "judgment": 8689, - "perceived": 8690, - "hammer": 8691, - "mtv": 8692, - "baronet": 8693, - "tune": 8694, - "das": 8695, - "missionary": 8696, - "sheets": 8697, - "350": 8698, - "neutral": 8699, - "oral": 8700, - "threatening": 8701, - "attractive": 8702, - "shade": 8703, - "aims": 8704, - "seminary": 8705, - "##master": 8706, - "estates": 8707, - "1856": 8708, - "michel": 8709, - "wounds": 8710, - "refugees": 8711, - "manufacturers": 8712, - "##nic": 8713, - "mercury": 8714, - "syndrome": 8715, - "porter": 8716, - "##iya": 8717, - "##din": 8718, - "hamburg": 8719, - "identification": 8720, - "upstairs": 8721, - "purse": 8722, - "widened": 8723, - "pause": 8724, - "cared": 8725, - "breathed": 8726, - "affiliate": 8727, - "santiago": 8728, - "prevented": 8729, - "celtic": 8730, - "fisher": 8731, - "125": 8732, - "recruited": 8733, - "byzantine": 8734, - "reconstruction": 8735, - "farther": 8736, - "##mp": 8737, - "diet": 8738, - "sake": 8739, - "au": 8740, - "spite": 8741, - "sensation": 8742, - "##ert": 8743, - "blank": 8744, - "separation": 8745, - "105": 8746, - "##hon": 8747, - "vladimir": 8748, - "armies": 8749, - "anime": 8750, - "##lie": 8751, - "accommodate": 8752, - "orbit": 8753, - "cult": 8754, - "sofia": 8755, - "archive": 8756, - "##ify": 8757, - "##box": 8758, - "founders": 8759, - "sustained": 8760, - "disorder": 8761, - "honours": 8762, - "northeastern": 8763, - "mia": 8764, - "crops": 8765, - "violet": 8766, - "threats": 8767, - "blanket": 8768, - "fires": 8769, - "canton": 8770, - "followers": 8771, - "southwestern": 8772, - "prototype": 8773, - "voyage": 8774, - "assignment": 8775, - "altered": 8776, - "moderate": 8777, - "protocol": 8778, - "pistol": 8779, - "##eo": 8780, - "questioned": 8781, - "brass": 8782, - "lifting": 8783, - "1852": 8784, - "math": 8785, - "authored": 8786, - "##ual": 8787, - "doug": 8788, - "dimensional": 8789, - "dynamic": 8790, - "##san": 8791, - "1851": 8792, - "pronounced": 8793, - "grateful": 8794, - "quest": 8795, - "uncomfortable": 8796, - "boom": 8797, - "presidency": 8798, - "stevens": 8799, - "relating": 8800, - "politicians": 8801, - "chen": 8802, - "barrier": 8803, - "quinn": 8804, - "diana": 8805, - "mosque": 8806, - "tribal": 8807, - "cheese": 8808, - "palmer": 8809, - "portions": 8810, - "sometime": 8811, - "chester": 8812, - "treasure": 8813, - "wu": 8814, - "bend": 8815, - "download": 8816, - "millions": 8817, - "reforms": 8818, - "registration": 8819, - "##osa": 8820, - "consequently": 8821, - "monitoring": 8822, - "ate": 8823, - "preliminary": 8824, - "brandon": 8825, - "invented": 8826, - "ps": 8827, - "eaten": 8828, - "exterior": 8829, - "intervention": 8830, - "ports": 8831, - "documented": 8832, - "log": 8833, - "displays": 8834, - "lecture": 8835, - "sally": 8836, - "favourite": 8837, - "##itz": 8838, - "vermont": 8839, - "lo": 8840, - "invisible": 8841, - "isle": 8842, - "breed": 8843, - "##ator": 8844, - "journalists": 8845, - "relay": 8846, - "speaks": 8847, - "backward": 8848, - "explore": 8849, - "midfielder": 8850, - "actively": 8851, - "stefan": 8852, - "procedures": 8853, - "cannon": 8854, - "blond": 8855, - "kenneth": 8856, - "centered": 8857, - "servants": 8858, - "chains": 8859, - "libraries": 8860, - "malcolm": 8861, - "essex": 8862, - "henri": 8863, - "slavery": 8864, - "##hal": 8865, - "facts": 8866, - "fairy": 8867, - "coached": 8868, - "cassie": 8869, - "cats": 8870, - "washed": 8871, - "cop": 8872, - "##fi": 8873, - "announcement": 8874, - "item": 8875, - "2000s": 8876, - "vinyl": 8877, - "activated": 8878, - "marco": 8879, - "frontier": 8880, - "growled": 8881, - "curriculum": 8882, - "##das": 8883, - "loyal": 8884, - "accomplished": 8885, - "leslie": 8886, - "ritual": 8887, - "kenny": 8888, - "##00": 8889, - "vii": 8890, - "napoleon": 8891, - "hollow": 8892, - "hybrid": 8893, - "jungle": 8894, - "stationed": 8895, - "friedrich": 8896, - "counted": 8897, - "##ulated": 8898, - "platinum": 8899, - "theatrical": 8900, - "seated": 8901, - "col": 8902, - "rubber": 8903, - "glen": 8904, - "1840": 8905, - "diversity": 8906, - "healing": 8907, - "extends": 8908, - "id": 8909, - "provisions": 8910, - "administrator": 8911, - "columbus": 8912, - "##oe": 8913, - "tributary": 8914, - "te": 8915, - "assured": 8916, - "org": 8917, - "##uous": 8918, - "prestigious": 8919, - "examined": 8920, - "lectures": 8921, - "grammy": 8922, - "ronald": 8923, - "associations": 8924, - "bailey": 8925, - "allan": 8926, - "essays": 8927, - "flute": 8928, - "believing": 8929, - "consultant": 8930, - "proceedings": 8931, - "travelling": 8932, - "1853": 8933, - "kit": 8934, - "kerala": 8935, - "yugoslavia": 8936, - "buddy": 8937, - "methodist": 8938, - "##ith": 8939, - "burial": 8940, - "centres": 8941, - "batman": 8942, - "##nda": 8943, - "discontinued": 8944, - "bo": 8945, - "dock": 8946, - "stockholm": 8947, - "lungs": 8948, - "severely": 8949, - "##nk": 8950, - "citing": 8951, - "manga": 8952, - "##ugh": 8953, - "steal": 8954, - "mumbai": 8955, - "iraqi": 8956, - "robot": 8957, - "celebrity": 8958, - "bride": 8959, - "broadcasts": 8960, - "abolished": 8961, - "pot": 8962, - "joel": 8963, - "overhead": 8964, - "franz": 8965, - "packed": 8966, - "reconnaissance": 8967, - "johann": 8968, - "acknowledged": 8969, - "introduce": 8970, - "handled": 8971, - "doctorate": 8972, - "developments": 8973, - "drinks": 8974, - "alley": 8975, - "palestine": 8976, - "##nis": 8977, - "##aki": 8978, - "proceeded": 8979, - "recover": 8980, - "bradley": 8981, - "grain": 8982, - "patch": 8983, - "afford": 8984, - "infection": 8985, - "nationalist": 8986, - "legendary": 8987, - "##ath": 8988, - "interchange": 8989, - "virtually": 8990, - "gen": 8991, - "gravity": 8992, - "exploration": 8993, - "amber": 8994, - "vital": 8995, - "wishes": 8996, - "powell": 8997, - "doctrine": 8998, - "elbow": 8999, - "screenplay": 9000, - "##bird": 9001, - "contribute": 9002, - "indonesian": 9003, - "pet": 9004, - "creates": 9005, - "##com": 9006, - "enzyme": 9007, - "kylie": 9008, - "discipline": 9009, - "drops": 9010, - "manila": 9011, - "hunger": 9012, - "##ien": 9013, - "layers": 9014, - "suffer": 9015, - "fever": 9016, - "bits": 9017, - "monica": 9018, - "keyboard": 9019, - "manages": 9020, - "##hood": 9021, - "searched": 9022, - "appeals": 9023, - "##bad": 9024, - "testament": 9025, - "grande": 9026, - "reid": 9027, - "##war": 9028, - "beliefs": 9029, - "congo": 9030, - "##ification": 9031, - "##dia": 9032, - "si": 9033, - "requiring": 9034, - "##via": 9035, - "casey": 9036, - "1849": 9037, - "regret": 9038, - "streak": 9039, - "rape": 9040, - "depends": 9041, - "syrian": 9042, - "sprint": 9043, - "pound": 9044, - "tourists": 9045, - "upcoming": 9046, - "pub": 9047, - "##xi": 9048, - "tense": 9049, - "##els": 9050, - "practiced": 9051, - "echo": 9052, - "nationwide": 9053, - "guild": 9054, - "motorcycle": 9055, - "liz": 9056, - "##zar": 9057, - "chiefs": 9058, - "desired": 9059, - "elena": 9060, - "bye": 9061, - "precious": 9062, - "absorbed": 9063, - "relatives": 9064, - "booth": 9065, - "pianist": 9066, - "##mal": 9067, - "citizenship": 9068, - "exhausted": 9069, - "wilhelm": 9070, - "##ceae": 9071, - "##hed": 9072, - "noting": 9073, - "quarterback": 9074, - "urge": 9075, - "hectares": 9076, - "##gue": 9077, - "ace": 9078, - "holly": 9079, - "##tal": 9080, - "blonde": 9081, - "davies": 9082, - "parked": 9083, - "sustainable": 9084, - "stepping": 9085, - "twentieth": 9086, - "airfield": 9087, - "galaxy": 9088, - "nest": 9089, - "chip": 9090, - "##nell": 9091, - "tan": 9092, - "shaft": 9093, - "paulo": 9094, - "requirement": 9095, - "##zy": 9096, - "paradise": 9097, - "tobacco": 9098, - "trans": 9099, - "renewed": 9100, - "vietnamese": 9101, - "##cker": 9102, - "##ju": 9103, - "suggesting": 9104, - "catching": 9105, - "holmes": 9106, - "enjoying": 9107, - "md": 9108, - "trips": 9109, - "colt": 9110, - "holder": 9111, - "butterfly": 9112, - "nerve": 9113, - "reformed": 9114, - "cherry": 9115, - "bowling": 9116, - "trailer": 9117, - "carriage": 9118, - "goodbye": 9119, - "appreciate": 9120, - "toy": 9121, - "joshua": 9122, - "interactive": 9123, - "enabled": 9124, - "involve": 9125, - "##kan": 9126, - "collar": 9127, - "determination": 9128, - "bunch": 9129, - "facebook": 9130, - "recall": 9131, - "shorts": 9132, - "superintendent": 9133, - "episcopal": 9134, - "frustration": 9135, - "giovanni": 9136, - "nineteenth": 9137, - "laser": 9138, - "privately": 9139, - "array": 9140, - "circulation": 9141, - "##ovic": 9142, - "armstrong": 9143, - "deals": 9144, - "painful": 9145, - "permit": 9146, - "discrimination": 9147, - "##wi": 9148, - "aires": 9149, - "retiring": 9150, - "cottage": 9151, - "ni": 9152, - "##sta": 9153, - "horizon": 9154, - "ellen": 9155, - "jamaica": 9156, - "ripped": 9157, - "fernando": 9158, - "chapters": 9159, - "playstation": 9160, - "patron": 9161, - "lecturer": 9162, - "navigation": 9163, - "behaviour": 9164, - "genes": 9165, - "georgian": 9166, - "export": 9167, - "solomon": 9168, - "rivals": 9169, - "swift": 9170, - "seventeen": 9171, - "rodriguez": 9172, - "princeton": 9173, - "independently": 9174, - "sox": 9175, - "1847": 9176, - "arguing": 9177, - "entity": 9178, - "casting": 9179, - "hank": 9180, - "criteria": 9181, - "oakland": 9182, - "geographic": 9183, - "milwaukee": 9184, - "reflection": 9185, - "expanding": 9186, - "conquest": 9187, - "dubbed": 9188, - "##tv": 9189, - "halt": 9190, - "brave": 9191, - "brunswick": 9192, - "doi": 9193, - "arched": 9194, - "curtis": 9195, - "divorced": 9196, - "predominantly": 9197, - "somerset": 9198, - "streams": 9199, - "ugly": 9200, - "zoo": 9201, - "horrible": 9202, - "curved": 9203, - "buenos": 9204, - "fierce": 9205, - "dictionary": 9206, - "vector": 9207, - "theological": 9208, - "unions": 9209, - "handful": 9210, - "stability": 9211, - "chan": 9212, - "punjab": 9213, - "segments": 9214, - "##lly": 9215, - "altar": 9216, - "ignoring": 9217, - "gesture": 9218, - "monsters": 9219, - "pastor": 9220, - "##stone": 9221, - "thighs": 9222, - "unexpected": 9223, - "operators": 9224, - "abruptly": 9225, - "coin": 9226, - "compiled": 9227, - "associates": 9228, - "improving": 9229, - "migration": 9230, - "pin": 9231, - "##ose": 9232, - "compact": 9233, - "collegiate": 9234, - "reserved": 9235, - "##urs": 9236, - "quarterfinals": 9237, - "roster": 9238, - "restore": 9239, - "assembled": 9240, - "hurry": 9241, - "oval": 9242, - "##cies": 9243, - "1846": 9244, - "flags": 9245, - "martha": 9246, - "##del": 9247, - "victories": 9248, - "sharply": 9249, - "##rated": 9250, - "argues": 9251, - "deadly": 9252, - "neo": 9253, - "drawings": 9254, - "symbols": 9255, - "performer": 9256, - "##iel": 9257, - "griffin": 9258, - "restrictions": 9259, - "editing": 9260, - "andrews": 9261, - "java": 9262, - "journals": 9263, - "arabia": 9264, - "compositions": 9265, - "dee": 9266, - "pierce": 9267, - "removing": 9268, - "hindi": 9269, - "casino": 9270, - "runway": 9271, - "civilians": 9272, - "minds": 9273, - "nasa": 9274, - "hotels": 9275, - "##zation": 9276, - "refuge": 9277, - "rent": 9278, - "retain": 9279, - "potentially": 9280, - "conferences": 9281, - "suburban": 9282, - "conducting": 9283, - "##tto": 9284, - "##tions": 9285, - "##tle": 9286, - "descended": 9287, - "massacre": 9288, - "##cal": 9289, - "ammunition": 9290, - "terrain": 9291, - "fork": 9292, - "souls": 9293, - "counts": 9294, - "chelsea": 9295, - "durham": 9296, - "drives": 9297, - "cab": 9298, - "##bank": 9299, - "perth": 9300, - "realizing": 9301, - "palestinian": 9302, - "finn": 9303, - "simpson": 9304, - "##dal": 9305, - "betty": 9306, - "##ule": 9307, - "moreover": 9308, - "particles": 9309, - "cardinals": 9310, - "tent": 9311, - "evaluation": 9312, - "extraordinary": 9313, - "##oid": 9314, - "inscription": 9315, - "##works": 9316, - "wednesday": 9317, - "chloe": 9318, - "maintains": 9319, - "panels": 9320, - "ashley": 9321, - "trucks": 9322, - "##nation": 9323, - "cluster": 9324, - "sunlight": 9325, - "strikes": 9326, - "zhang": 9327, - "##wing": 9328, - "dialect": 9329, - "canon": 9330, - "##ap": 9331, - "tucked": 9332, - "##ws": 9333, - "collecting": 9334, - "##mas": 9335, - "##can": 9336, - "##sville": 9337, - "maker": 9338, - "quoted": 9339, - "evan": 9340, - "franco": 9341, - "aria": 9342, - "buying": 9343, - "cleaning": 9344, - "eva": 9345, - "closet": 9346, - "provision": 9347, - "apollo": 9348, - "clinic": 9349, - "rat": 9350, - "##ez": 9351, - "necessarily": 9352, - "ac": 9353, - "##gle": 9354, - "##ising": 9355, - "venues": 9356, - "flipped": 9357, - "cent": 9358, - "spreading": 9359, - "trustees": 9360, - "checking": 9361, - "authorized": 9362, - "##sco": 9363, - "disappointed": 9364, - "##ado": 9365, - "notion": 9366, - "duration": 9367, - "trumpet": 9368, - "hesitated": 9369, - "topped": 9370, - "brussels": 9371, - "rolls": 9372, - "theoretical": 9373, - "hint": 9374, - "define": 9375, - "aggressive": 9376, - "repeat": 9377, - "wash": 9378, - "peaceful": 9379, - "optical": 9380, - "width": 9381, - "allegedly": 9382, - "mcdonald": 9383, - "strict": 9384, - "copyright": 9385, - "##illa": 9386, - "investors": 9387, - "mar": 9388, - "jam": 9389, - "witnesses": 9390, - "sounding": 9391, - "miranda": 9392, - "michelle": 9393, - "privacy": 9394, - "hugo": 9395, - "harmony": 9396, - "##pp": 9397, - "valid": 9398, - "lynn": 9399, - "glared": 9400, - "nina": 9401, - "102": 9402, - "headquartered": 9403, - "diving": 9404, - "boarding": 9405, - "gibson": 9406, - "##ncy": 9407, - "albanian": 9408, - "marsh": 9409, - "routine": 9410, - "dealt": 9411, - "enhanced": 9412, - "er": 9413, - "intelligent": 9414, - "substance": 9415, - "targeted": 9416, - "enlisted": 9417, - "discovers": 9418, - "spinning": 9419, - "observations": 9420, - "pissed": 9421, - "smoking": 9422, - "rebecca": 9423, - "capitol": 9424, - "visa": 9425, - "varied": 9426, - "costume": 9427, - "seemingly": 9428, - "indies": 9429, - "compensation": 9430, - "surgeon": 9431, - "thursday": 9432, - "arsenal": 9433, - "westminster": 9434, - "suburbs": 9435, - "rid": 9436, - "anglican": 9437, - "##ridge": 9438, - "knots": 9439, - "foods": 9440, - "alumni": 9441, - "lighter": 9442, - "fraser": 9443, - "whoever": 9444, - "portal": 9445, - "scandal": 9446, - "##ray": 9447, - "gavin": 9448, - "advised": 9449, - "instructor": 9450, - "flooding": 9451, - "terrorist": 9452, - "##ale": 9453, - "teenage": 9454, - "interim": 9455, - "senses": 9456, - "duck": 9457, - "teen": 9458, - "thesis": 9459, - "abby": 9460, - "eager": 9461, - "overcome": 9462, - "##ile": 9463, - "newport": 9464, - "glenn": 9465, - "rises": 9466, - "shame": 9467, - "##cc": 9468, - "prompted": 9469, - "priority": 9470, - "forgot": 9471, - "bomber": 9472, - "nicolas": 9473, - "protective": 9474, - "360": 9475, - "cartoon": 9476, - "katherine": 9477, - "breeze": 9478, - "lonely": 9479, - "trusted": 9480, - "henderson": 9481, - "richardson": 9482, - "relax": 9483, - "banner": 9484, - "candy": 9485, - "palms": 9486, - "remarkable": 9487, - "##rio": 9488, - "legends": 9489, - "cricketer": 9490, - "essay": 9491, - "ordained": 9492, - "edmund": 9493, - "rifles": 9494, - "trigger": 9495, - "##uri": 9496, - "##away": 9497, - "sail": 9498, - "alert": 9499, - "1830": 9500, - "audiences": 9501, - "penn": 9502, - "sussex": 9503, - "siblings": 9504, - "pursued": 9505, - "indianapolis": 9506, - "resist": 9507, - "rosa": 9508, - "consequence": 9509, - "succeed": 9510, - "avoided": 9511, - "1845": 9512, - "##ulation": 9513, - "inland": 9514, - "##tie": 9515, - "##nna": 9516, - "counsel": 9517, - "profession": 9518, - "chronicle": 9519, - "hurried": 9520, - "##una": 9521, - "eyebrow": 9522, - "eventual": 9523, - "bleeding": 9524, - "innovative": 9525, - "cure": 9526, - "##dom": 9527, - "committees": 9528, - "accounting": 9529, - "con": 9530, - "scope": 9531, - "hardy": 9532, - "heather": 9533, - "tenor": 9534, - "gut": 9535, - "herald": 9536, - "codes": 9537, - "tore": 9538, - "scales": 9539, - "wagon": 9540, - "##oo": 9541, - "luxury": 9542, - "tin": 9543, - "prefer": 9544, - "fountain": 9545, - "triangle": 9546, - "bonds": 9547, - "darling": 9548, - "convoy": 9549, - "dried": 9550, - "traced": 9551, - "beings": 9552, - "troy": 9553, - "accidentally": 9554, - "slam": 9555, - "findings": 9556, - "smelled": 9557, - "joey": 9558, - "lawyers": 9559, - "outcome": 9560, - "steep": 9561, - "bosnia": 9562, - "configuration": 9563, - "shifting": 9564, - "toll": 9565, - "brook": 9566, - "performers": 9567, - "lobby": 9568, - "philosophical": 9569, - "construct": 9570, - "shrine": 9571, - "aggregate": 9572, - "boot": 9573, - "cox": 9574, - "phenomenon": 9575, - "savage": 9576, - "insane": 9577, - "solely": 9578, - "reynolds": 9579, - "lifestyle": 9580, - "##ima": 9581, - "nationally": 9582, - "holdings": 9583, - "consideration": 9584, - "enable": 9585, - "edgar": 9586, - "mo": 9587, - "mama": 9588, - "##tein": 9589, - "fights": 9590, - "relegation": 9591, - "chances": 9592, - "atomic": 9593, - "hub": 9594, - "conjunction": 9595, - "awkward": 9596, - "reactions": 9597, - "currency": 9598, - "finale": 9599, - "kumar": 9600, - "underwent": 9601, - "steering": 9602, - "elaborate": 9603, - "gifts": 9604, - "comprising": 9605, - "melissa": 9606, - "veins": 9607, - "reasonable": 9608, - "sunshine": 9609, - "chi": 9610, - "solve": 9611, - "trails": 9612, - "inhabited": 9613, - "elimination": 9614, - "ethics": 9615, - "huh": 9616, - "ana": 9617, - "molly": 9618, - "consent": 9619, - "apartments": 9620, - "layout": 9621, - "marines": 9622, - "##ces": 9623, - "hunters": 9624, - "bulk": 9625, - "##oma": 9626, - "hometown": 9627, - "##wall": 9628, - "##mont": 9629, - "cracked": 9630, - "reads": 9631, - "neighbouring": 9632, - "withdrawn": 9633, - "admission": 9634, - "wingspan": 9635, - "damned": 9636, - "anthology": 9637, - "lancashire": 9638, - "brands": 9639, - "batting": 9640, - "forgive": 9641, - "cuban": 9642, - "awful": 9643, - "##lyn": 9644, - "104": 9645, - "dimensions": 9646, - "imagination": 9647, - "##ade": 9648, - "dante": 9649, - "##ship": 9650, - "tracking": 9651, - "desperately": 9652, - "goalkeeper": 9653, - "##yne": 9654, - "groaned": 9655, - "workshops": 9656, - "confident": 9657, - "burton": 9658, - "gerald": 9659, - "milton": 9660, - "circus": 9661, - "uncertain": 9662, - "slope": 9663, - "copenhagen": 9664, - "sophia": 9665, - "fog": 9666, - "philosopher": 9667, - "portraits": 9668, - "accent": 9669, - "cycling": 9670, - "varying": 9671, - "gripped": 9672, - "larvae": 9673, - "garrett": 9674, - "specified": 9675, - "scotia": 9676, - "mature": 9677, - "luther": 9678, - "kurt": 9679, - "rap": 9680, - "##kes": 9681, - "aerial": 9682, - "750": 9683, - "ferdinand": 9684, - "heated": 9685, - "es": 9686, - "transported": 9687, - "##shan": 9688, - "safely": 9689, - "nonetheless": 9690, - "##orn": 9691, - "##gal": 9692, - "motors": 9693, - "demanding": 9694, - "##sburg": 9695, - "startled": 9696, - "##brook": 9697, - "ally": 9698, - "generate": 9699, - "caps": 9700, - "ghana": 9701, - "stained": 9702, - "demo": 9703, - "mentions": 9704, - "beds": 9705, - "ap": 9706, - "afterward": 9707, - "diary": 9708, - "##bling": 9709, - "utility": 9710, - "##iro": 9711, - "richards": 9712, - "1837": 9713, - "conspiracy": 9714, - "conscious": 9715, - "shining": 9716, - "footsteps": 9717, - "observer": 9718, - "cyprus": 9719, - "urged": 9720, - "loyalty": 9721, - "developer": 9722, - "probability": 9723, - "olive": 9724, - "upgraded": 9725, - "gym": 9726, - "miracle": 9727, - "insects": 9728, - "graves": 9729, - "1844": 9730, - "ourselves": 9731, - "hydrogen": 9732, - "amazon": 9733, - "katie": 9734, - "tickets": 9735, - "poets": 9736, - "##pm": 9737, - "planes": 9738, - "##pan": 9739, - "prevention": 9740, - "witnessed": 9741, - "dense": 9742, - "jin": 9743, - "randy": 9744, - "tang": 9745, - "warehouse": 9746, - "monroe": 9747, - "bang": 9748, - "archived": 9749, - "elderly": 9750, - "investigations": 9751, - "alec": 9752, - "granite": 9753, - "mineral": 9754, - "conflicts": 9755, - "controlling": 9756, - "aboriginal": 9757, - "carlo": 9758, - "##zu": 9759, - "mechanics": 9760, - "stan": 9761, - "stark": 9762, - "rhode": 9763, - "skirt": 9764, - "est": 9765, - "##berry": 9766, - "bombs": 9767, - "respected": 9768, - "##horn": 9769, - "imposed": 9770, - "limestone": 9771, - "deny": 9772, - "nominee": 9773, - "memphis": 9774, - "grabbing": 9775, - "disabled": 9776, - "##als": 9777, - "amusement": 9778, - "aa": 9779, - "frankfurt": 9780, - "corn": 9781, - "referendum": 9782, - "varies": 9783, - "slowed": 9784, - "disk": 9785, - "firms": 9786, - "unconscious": 9787, - "incredible": 9788, - "clue": 9789, - "sue": 9790, - "##zhou": 9791, - "twist": 9792, - "##cio": 9793, - "joins": 9794, - "idaho": 9795, - "chad": 9796, - "developers": 9797, - "computing": 9798, - "destroyer": 9799, - "103": 9800, - "mortal": 9801, - "tucker": 9802, - "kingston": 9803, - "choices": 9804, - "yu": 9805, - "carson": 9806, - "1800": 9807, - "os": 9808, - "whitney": 9809, - "geneva": 9810, - "pretend": 9811, - "dimension": 9812, - "staged": 9813, - "plateau": 9814, - "maya": 9815, - "##une": 9816, - "freestyle": 9817, - "##bc": 9818, - "rovers": 9819, - "hiv": 9820, - "##ids": 9821, - "tristan": 9822, - "classroom": 9823, - "prospect": 9824, - "##hus": 9825, - "honestly": 9826, - "diploma": 9827, - "lied": 9828, - "thermal": 9829, - "auxiliary": 9830, - "feast": 9831, - "unlikely": 9832, - "iata": 9833, - "##tel": 9834, - "morocco": 9835, - "pounding": 9836, - "treasury": 9837, - "lithuania": 9838, - "considerably": 9839, - "1841": 9840, - "dish": 9841, - "1812": 9842, - "geological": 9843, - "matching": 9844, - "stumbled": 9845, - "destroying": 9846, - "marched": 9847, - "brien": 9848, - "advances": 9849, - "cake": 9850, - "nicole": 9851, - "belle": 9852, - "settling": 9853, - "measuring": 9854, - "directing": 9855, - "##mie": 9856, - "tuesday": 9857, - "bassist": 9858, - "capabilities": 9859, - "stunned": 9860, - "fraud": 9861, - "torpedo": 9862, - "##list": 9863, - "##phone": 9864, - "anton": 9865, - "wisdom": 9866, - "surveillance": 9867, - "ruined": 9868, - "##ulate": 9869, - "lawsuit": 9870, - "healthcare": 9871, - "theorem": 9872, - "halls": 9873, - "trend": 9874, - "aka": 9875, - "horizontal": 9876, - "dozens": 9877, - "acquire": 9878, - "lasting": 9879, - "swim": 9880, - "hawk": 9881, - "gorgeous": 9882, - "fees": 9883, - "vicinity": 9884, - "decrease": 9885, - "adoption": 9886, - "tactics": 9887, - "##ography": 9888, - "pakistani": 9889, - "##ole": 9890, - "draws": 9891, - "##hall": 9892, - "willie": 9893, - "burke": 9894, - "heath": 9895, - "algorithm": 9896, - "integral": 9897, - "powder": 9898, - "elliott": 9899, - "brigadier": 9900, - "jackie": 9901, - "tate": 9902, - "varieties": 9903, - "darker": 9904, - "##cho": 9905, - "lately": 9906, - "cigarette": 9907, - "specimens": 9908, - "adds": 9909, - "##ree": 9910, - "##ensis": 9911, - "##inger": 9912, - "exploded": 9913, - "finalist": 9914, - "cia": 9915, - "murders": 9916, - "wilderness": 9917, - "arguments": 9918, - "nicknamed": 9919, - "acceptance": 9920, - "onwards": 9921, - "manufacture": 9922, - "robertson": 9923, - "jets": 9924, - "tampa": 9925, - "enterprises": 9926, - "blog": 9927, - "loudly": 9928, - "composers": 9929, - "nominations": 9930, - "1838": 9931, - "ai": 9932, - "malta": 9933, - "inquiry": 9934, - "automobile": 9935, - "hosting": 9936, - "viii": 9937, - "rays": 9938, - "tilted": 9939, - "grief": 9940, - "museums": 9941, - "strategies": 9942, - "furious": 9943, - "euro": 9944, - "equality": 9945, - "cohen": 9946, - "poison": 9947, - "surrey": 9948, - "wireless": 9949, - "governed": 9950, - "ridiculous": 9951, - "moses": 9952, - "##esh": 9953, - "##room": 9954, - "vanished": 9955, - "##ito": 9956, - "barnes": 9957, - "attract": 9958, - "morrison": 9959, - "istanbul": 9960, - "##iness": 9961, - "absent": 9962, - "rotation": 9963, - "petition": 9964, - "janet": 9965, - "##logical": 9966, - "satisfaction": 9967, - "custody": 9968, - "deliberately": 9969, - "observatory": 9970, - "comedian": 9971, - "surfaces": 9972, - "pinyin": 9973, - "novelist": 9974, - "strictly": 9975, - "canterbury": 9976, - "oslo": 9977, - "monks": 9978, - "embrace": 9979, - "ibm": 9980, - "jealous": 9981, - "photograph": 9982, - "continent": 9983, - "dorothy": 9984, - "marina": 9985, - "doc": 9986, - "excess": 9987, - "holden": 9988, - "allegations": 9989, - "explaining": 9990, - "stack": 9991, - "avoiding": 9992, - "lance": 9993, - "storyline": 9994, - "majesty": 9995, - "poorly": 9996, - "spike": 9997, - "dos": 9998, - "bradford": 9999, - "raven": 10000, - "travis": 10001, - "classics": 10002, - "proven": 10003, - "voltage": 10004, - "pillow": 10005, - "fists": 10006, - "butt": 10007, - "1842": 10008, - "interpreted": 10009, - "##car": 10010, - "1839": 10011, - "gage": 10012, - "telegraph": 10013, - "lens": 10014, - "promising": 10015, - "expelled": 10016, - "casual": 10017, - "collector": 10018, - "zones": 10019, - "##min": 10020, - "silly": 10021, - "nintendo": 10022, - "##kh": 10023, - "##bra": 10024, - "downstairs": 10025, - "chef": 10026, - "suspicious": 10027, - "afl": 10028, - "flies": 10029, - "vacant": 10030, - "uganda": 10031, - "pregnancy": 10032, - "condemned": 10033, - "lutheran": 10034, - "estimates": 10035, - "cheap": 10036, - "decree": 10037, - "saxon": 10038, - "proximity": 10039, - "stripped": 10040, - "idiot": 10041, - "deposits": 10042, - "contrary": 10043, - "presenter": 10044, - "magnus": 10045, - "glacier": 10046, - "im": 10047, - "offense": 10048, - "edwin": 10049, - "##ori": 10050, - "upright": 10051, - "##long": 10052, - "bolt": 10053, - "##ois": 10054, - "toss": 10055, - "geographical": 10056, - "##izes": 10057, - "environments": 10058, - "delicate": 10059, - "marking": 10060, - "abstract": 10061, - "xavier": 10062, - "nails": 10063, - "windsor": 10064, - "plantation": 10065, - "occurring": 10066, - "equity": 10067, - "saskatchewan": 10068, - "fears": 10069, - "drifted": 10070, - "sequences": 10071, - "vegetation": 10072, - "revolt": 10073, - "##stic": 10074, - "1843": 10075, - "sooner": 10076, - "fusion": 10077, - "opposing": 10078, - "nato": 10079, - "skating": 10080, - "1836": 10081, - "secretly": 10082, - "ruin": 10083, - "lease": 10084, - "##oc": 10085, - "edit": 10086, - "##nne": 10087, - "flora": 10088, - "anxiety": 10089, - "ruby": 10090, - "##ological": 10091, - "##mia": 10092, - "tel": 10093, - "bout": 10094, - "taxi": 10095, - "emmy": 10096, - "frost": 10097, - "rainbow": 10098, - "compounds": 10099, - "foundations": 10100, - "rainfall": 10101, - "assassination": 10102, - "nightmare": 10103, - "dominican": 10104, - "##win": 10105, - "achievements": 10106, - "deserve": 10107, - "orlando": 10108, - "intact": 10109, - "armenia": 10110, - "##nte": 10111, - "calgary": 10112, - "valentine": 10113, - "106": 10114, - "marion": 10115, - "proclaimed": 10116, - "theodore": 10117, - "bells": 10118, - "courtyard": 10119, - "thigh": 10120, - "gonzalez": 10121, - "console": 10122, - "troop": 10123, - "minimal": 10124, - "monte": 10125, - "everyday": 10126, - "##ence": 10127, - "##if": 10128, - "supporter": 10129, - "terrorism": 10130, - "buck": 10131, - "openly": 10132, - "presbyterian": 10133, - "activists": 10134, - "carpet": 10135, - "##iers": 10136, - "rubbing": 10137, - "uprising": 10138, - "##yi": 10139, - "cute": 10140, - "conceived": 10141, - "legally": 10142, - "##cht": 10143, - "millennium": 10144, - "cello": 10145, - "velocity": 10146, - "ji": 10147, - "rescued": 10148, - "cardiff": 10149, - "1835": 10150, - "rex": 10151, - "concentrate": 10152, - "senators": 10153, - "beard": 10154, - "rendered": 10155, - "glowing": 10156, - "battalions": 10157, - "scouts": 10158, - "competitors": 10159, - "sculptor": 10160, - "catalogue": 10161, - "arctic": 10162, - "ion": 10163, - "raja": 10164, - "bicycle": 10165, - "wow": 10166, - "glancing": 10167, - "lawn": 10168, - "##woman": 10169, - "gentleman": 10170, - "lighthouse": 10171, - "publish": 10172, - "predicted": 10173, - "calculated": 10174, - "##val": 10175, - "variants": 10176, - "##gne": 10177, - "strain": 10178, - "##ui": 10179, - "winston": 10180, - "deceased": 10181, - "##nus": 10182, - "touchdowns": 10183, - "brady": 10184, - "caleb": 10185, - "sinking": 10186, - "echoed": 10187, - "crush": 10188, - "hon": 10189, - "blessed": 10190, - "protagonist": 10191, - "hayes": 10192, - "endangered": 10193, - "magnitude": 10194, - "editors": 10195, - "##tine": 10196, - "estimate": 10197, - "responsibilities": 10198, - "##mel": 10199, - "backup": 10200, - "laying": 10201, - "consumed": 10202, - "sealed": 10203, - "zurich": 10204, - "lovers": 10205, - "frustrated": 10206, - "##eau": 10207, - "ahmed": 10208, - "kicking": 10209, - "mit": 10210, - "treasurer": 10211, - "1832": 10212, - "biblical": 10213, - "refuse": 10214, - "terrified": 10215, - "pump": 10216, - "agrees": 10217, - "genuine": 10218, - "imprisonment": 10219, - "refuses": 10220, - "plymouth": 10221, - "##hen": 10222, - "lou": 10223, - "##nen": 10224, - "tara": 10225, - "trembling": 10226, - "antarctic": 10227, - "ton": 10228, - "learns": 10229, - "##tas": 10230, - "crap": 10231, - "crucial": 10232, - "faction": 10233, - "atop": 10234, - "##borough": 10235, - "wrap": 10236, - "lancaster": 10237, - "odds": 10238, - "hopkins": 10239, - "erik": 10240, - "lyon": 10241, - "##eon": 10242, - "bros": 10243, - "##ode": 10244, - "snap": 10245, - "locality": 10246, - "tips": 10247, - "empress": 10248, - "crowned": 10249, - "cal": 10250, - "acclaimed": 10251, - "chuckled": 10252, - "##ory": 10253, - "clara": 10254, - "sends": 10255, - "mild": 10256, - "towel": 10257, - "##fl": 10258, - "##day": 10259, - "##а": 10260, - "wishing": 10261, - "assuming": 10262, - "interviewed": 10263, - "##bal": 10264, - "##die": 10265, - "interactions": 10266, - "eden": 10267, - "cups": 10268, - "helena": 10269, - "##lf": 10270, - "indie": 10271, - "beck": 10272, - "##fire": 10273, - "batteries": 10274, - "filipino": 10275, - "wizard": 10276, - "parted": 10277, - "##lam": 10278, - "traces": 10279, - "##born": 10280, - "rows": 10281, - "idol": 10282, - "albany": 10283, - "delegates": 10284, - "##ees": 10285, - "##sar": 10286, - "discussions": 10287, - "##ex": 10288, - "notre": 10289, - "instructed": 10290, - "belgrade": 10291, - "highways": 10292, - "suggestion": 10293, - "lauren": 10294, - "possess": 10295, - "orientation": 10296, - "alexandria": 10297, - "abdul": 10298, - "beats": 10299, - "salary": 10300, - "reunion": 10301, - "ludwig": 10302, - "alright": 10303, - "wagner": 10304, - "intimate": 10305, - "pockets": 10306, - "slovenia": 10307, - "hugged": 10308, - "brighton": 10309, - "merchants": 10310, - "cruel": 10311, - "stole": 10312, - "trek": 10313, - "slopes": 10314, - "repairs": 10315, - "enrollment": 10316, - "politically": 10317, - "underlying": 10318, - "promotional": 10319, - "counting": 10320, - "boeing": 10321, - "##bb": 10322, - "isabella": 10323, - "naming": 10324, - "##и": 10325, - "keen": 10326, - "bacteria": 10327, - "listing": 10328, - "separately": 10329, - "belfast": 10330, - "ussr": 10331, - "450": 10332, - "lithuanian": 10333, - "anybody": 10334, - "ribs": 10335, - "sphere": 10336, - "martinez": 10337, - "cock": 10338, - "embarrassed": 10339, - "proposals": 10340, - "fragments": 10341, - "nationals": 10342, - "##fs": 10343, - "##wski": 10344, - "premises": 10345, - "fin": 10346, - "1500": 10347, - "alpine": 10348, - "matched": 10349, - "freely": 10350, - "bounded": 10351, - "jace": 10352, - "sleeve": 10353, - "##af": 10354, - "gaming": 10355, - "pier": 10356, - "populated": 10357, - "evident": 10358, - "##like": 10359, - "frances": 10360, - "flooded": 10361, - "##dle": 10362, - "frightened": 10363, - "pour": 10364, - "trainer": 10365, - "framed": 10366, - "visitor": 10367, - "challenging": 10368, - "pig": 10369, - "wickets": 10370, - "##fold": 10371, - "infected": 10372, - "email": 10373, - "##pes": 10374, - "arose": 10375, - "##aw": 10376, - "reward": 10377, - "ecuador": 10378, - "oblast": 10379, - "vale": 10380, - "ch": 10381, - "shuttle": 10382, - "##usa": 10383, - "bach": 10384, - "rankings": 10385, - "forbidden": 10386, - "cornwall": 10387, - "accordance": 10388, - "salem": 10389, - "consumers": 10390, - "bruno": 10391, - "fantastic": 10392, - "toes": 10393, - "machinery": 10394, - "resolved": 10395, - "julius": 10396, - "remembering": 10397, - "propaganda": 10398, - "iceland": 10399, - "bombardment": 10400, - "tide": 10401, - "contacts": 10402, - "wives": 10403, - "##rah": 10404, - "concerto": 10405, - "macdonald": 10406, - "albania": 10407, - "implement": 10408, - "daisy": 10409, - "tapped": 10410, - "sudan": 10411, - "helmet": 10412, - "angela": 10413, - "mistress": 10414, - "##lic": 10415, - "crop": 10416, - "sunk": 10417, - "finest": 10418, - "##craft": 10419, - "hostile": 10420, - "##ute": 10421, - "##tsu": 10422, - "boxer": 10423, - "fr": 10424, - "paths": 10425, - "adjusted": 10426, - "habit": 10427, - "ballot": 10428, - "supervision": 10429, - "soprano": 10430, - "##zen": 10431, - "bullets": 10432, - "wicked": 10433, - "sunset": 10434, - "regiments": 10435, - "disappear": 10436, - "lamp": 10437, - "performs": 10438, - "app": 10439, - "##gia": 10440, - "##oa": 10441, - "rabbit": 10442, - "digging": 10443, - "incidents": 10444, - "entries": 10445, - "##cion": 10446, - "dishes": 10447, - "##oi": 10448, - "introducing": 10449, - "##ati": 10450, - "##fied": 10451, - "freshman": 10452, - "slot": 10453, - "jill": 10454, - "tackles": 10455, - "baroque": 10456, - "backs": 10457, - "##iest": 10458, - "lone": 10459, - "sponsor": 10460, - "destiny": 10461, - "altogether": 10462, - "convert": 10463, - "##aro": 10464, - "consensus": 10465, - "shapes": 10466, - "demonstration": 10467, - "basically": 10468, - "feminist": 10469, - "auction": 10470, - "artifacts": 10471, - "##bing": 10472, - "strongest": 10473, - "twitter": 10474, - "halifax": 10475, - "2019": 10476, - "allmusic": 10477, - "mighty": 10478, - "smallest": 10479, - "precise": 10480, - "alexandra": 10481, - "viola": 10482, - "##los": 10483, - "##ille": 10484, - "manuscripts": 10485, - "##illo": 10486, - "dancers": 10487, - "ari": 10488, - "managers": 10489, - "monuments": 10490, - "blades": 10491, - "barracks": 10492, - "springfield": 10493, - "maiden": 10494, - "consolidated": 10495, - "electron": 10496, - "##end": 10497, - "berry": 10498, - "airing": 10499, - "wheat": 10500, - "nobel": 10501, - "inclusion": 10502, - "blair": 10503, - "payments": 10504, - "geography": 10505, - "bee": 10506, - "cc": 10507, - "eleanor": 10508, - "react": 10509, - "##hurst": 10510, - "afc": 10511, - "manitoba": 10512, - "##yu": 10513, - "su": 10514, - "lineup": 10515, - "fitness": 10516, - "recreational": 10517, - "investments": 10518, - "airborne": 10519, - "disappointment": 10520, - "##dis": 10521, - "edmonton": 10522, - "viewing": 10523, - "##row": 10524, - "renovation": 10525, - "##cast": 10526, - "infant": 10527, - "bankruptcy": 10528, - "roses": 10529, - "aftermath": 10530, - "pavilion": 10531, - "##yer": 10532, - "carpenter": 10533, - "withdrawal": 10534, - "ladder": 10535, - "##hy": 10536, - "discussing": 10537, - "popped": 10538, - "reliable": 10539, - "agreements": 10540, - "rochester": 10541, - "##abad": 10542, - "curves": 10543, - "bombers": 10544, - "220": 10545, - "rao": 10546, - "reverend": 10547, - "decreased": 10548, - "choosing": 10549, - "107": 10550, - "stiff": 10551, - "consulting": 10552, - "naples": 10553, - "crawford": 10554, - "tracy": 10555, - "ka": 10556, - "ribbon": 10557, - "cops": 10558, - "##lee": 10559, - "crushed": 10560, - "deciding": 10561, - "unified": 10562, - "teenager": 10563, - "accepting": 10564, - "flagship": 10565, - "explorer": 10566, - "poles": 10567, - "sanchez": 10568, - "inspection": 10569, - "revived": 10570, - "skilled": 10571, - "induced": 10572, - "exchanged": 10573, - "flee": 10574, - "locals": 10575, - "tragedy": 10576, - "swallow": 10577, - "loading": 10578, - "hanna": 10579, - "demonstrate": 10580, - "##ela": 10581, - "salvador": 10582, - "flown": 10583, - "contestants": 10584, - "civilization": 10585, - "##ines": 10586, - "wanna": 10587, - "rhodes": 10588, - "fletcher": 10589, - "hector": 10590, - "knocking": 10591, - "considers": 10592, - "##ough": 10593, - "nash": 10594, - "mechanisms": 10595, - "sensed": 10596, - "mentally": 10597, - "walt": 10598, - "unclear": 10599, - "##eus": 10600, - "renovated": 10601, - "madame": 10602, - "##cks": 10603, - "crews": 10604, - "governmental": 10605, - "##hin": 10606, - "undertaken": 10607, - "monkey": 10608, - "##ben": 10609, - "##ato": 10610, - "fatal": 10611, - "armored": 10612, - "copa": 10613, - "caves": 10614, - "governance": 10615, - "grasp": 10616, - "perception": 10617, - "certification": 10618, - "froze": 10619, - "damp": 10620, - "tugged": 10621, - "wyoming": 10622, - "##rg": 10623, - "##ero": 10624, - "newman": 10625, - "##lor": 10626, - "nerves": 10627, - "curiosity": 10628, - "graph": 10629, - "115": 10630, - "##ami": 10631, - "withdraw": 10632, - "tunnels": 10633, - "dull": 10634, - "meredith": 10635, - "moss": 10636, - "exhibits": 10637, - "neighbors": 10638, - "communicate": 10639, - "accuracy": 10640, - "explored": 10641, - "raiders": 10642, - "republicans": 10643, - "secular": 10644, - "kat": 10645, - "superman": 10646, - "penny": 10647, - "criticised": 10648, - "##tch": 10649, - "freed": 10650, - "update": 10651, - "conviction": 10652, - "wade": 10653, - "ham": 10654, - "likewise": 10655, - "delegation": 10656, - "gotta": 10657, - "doll": 10658, - "promises": 10659, - "technological": 10660, - "myth": 10661, - "nationality": 10662, - "resolve": 10663, - "convent": 10664, - "##mark": 10665, - "sharon": 10666, - "dig": 10667, - "sip": 10668, - "coordinator": 10669, - "entrepreneur": 10670, - "fold": 10671, - "##dine": 10672, - "capability": 10673, - "councillor": 10674, - "synonym": 10675, - "blown": 10676, - "swan": 10677, - "cursed": 10678, - "1815": 10679, - "jonas": 10680, - "haired": 10681, - "sofa": 10682, - "canvas": 10683, - "keeper": 10684, - "rivalry": 10685, - "##hart": 10686, - "rapper": 10687, - "speedway": 10688, - "swords": 10689, - "postal": 10690, - "maxwell": 10691, - "estonia": 10692, - "potter": 10693, - "recurring": 10694, - "##nn": 10695, - "##ave": 10696, - "errors": 10697, - "##oni": 10698, - "cognitive": 10699, - "1834": 10700, - "##²": 10701, - "claws": 10702, - "nadu": 10703, - "roberto": 10704, - "bce": 10705, - "wrestler": 10706, - "ellie": 10707, - "##ations": 10708, - "infinite": 10709, - "ink": 10710, - "##tia": 10711, - "presumably": 10712, - "finite": 10713, - "staircase": 10714, - "108": 10715, - "noel": 10716, - "patricia": 10717, - "nacional": 10718, - "##cation": 10719, - "chill": 10720, - "eternal": 10721, - "tu": 10722, - "preventing": 10723, - "prussia": 10724, - "fossil": 10725, - "limbs": 10726, - "##logist": 10727, - "ernst": 10728, - "frog": 10729, - "perez": 10730, - "rene": 10731, - "##ace": 10732, - "pizza": 10733, - "prussian": 10734, - "##ios": 10735, - "##vy": 10736, - "molecules": 10737, - "regulatory": 10738, - "answering": 10739, - "opinions": 10740, - "sworn": 10741, - "lengths": 10742, - "supposedly": 10743, - "hypothesis": 10744, - "upward": 10745, - "habitats": 10746, - "seating": 10747, - "ancestors": 10748, - "drank": 10749, - "yield": 10750, - "hd": 10751, - "synthesis": 10752, - "researcher": 10753, - "modest": 10754, - "##var": 10755, - "mothers": 10756, - "peered": 10757, - "voluntary": 10758, - "homeland": 10759, - "##the": 10760, - "acclaim": 10761, - "##igan": 10762, - "static": 10763, - "valve": 10764, - "luxembourg": 10765, - "alto": 10766, - "carroll": 10767, - "fe": 10768, - "receptor": 10769, - "norton": 10770, - "ambulance": 10771, - "##tian": 10772, - "johnston": 10773, - "catholics": 10774, - "depicting": 10775, - "jointly": 10776, - "elephant": 10777, - "gloria": 10778, - "mentor": 10779, - "badge": 10780, - "ahmad": 10781, - "distinguish": 10782, - "remarked": 10783, - "councils": 10784, - "precisely": 10785, - "allison": 10786, - "advancing": 10787, - "detection": 10788, - "crowded": 10789, - "##10": 10790, - "cooperative": 10791, - "ankle": 10792, - "mercedes": 10793, - "dagger": 10794, - "surrendered": 10795, - "pollution": 10796, - "commit": 10797, - "subway": 10798, - "jeffrey": 10799, - "lesson": 10800, - "sculptures": 10801, - "provider": 10802, - "##fication": 10803, - "membrane": 10804, - "timothy": 10805, - "rectangular": 10806, - "fiscal": 10807, - "heating": 10808, - "teammate": 10809, - "basket": 10810, - "particle": 10811, - "anonymous": 10812, - "deployment": 10813, - "##ple": 10814, - "missiles": 10815, - "courthouse": 10816, - "proportion": 10817, - "shoe": 10818, - "sec": 10819, - "##ller": 10820, - "complaints": 10821, - "forbes": 10822, - "blacks": 10823, - "abandon": 10824, - "remind": 10825, - "sizes": 10826, - "overwhelming": 10827, - "autobiography": 10828, - "natalie": 10829, - "##awa": 10830, - "risks": 10831, - "contestant": 10832, - "countryside": 10833, - "babies": 10834, - "scorer": 10835, - "invaded": 10836, - "enclosed": 10837, - "proceed": 10838, - "hurling": 10839, - "disorders": 10840, - "##cu": 10841, - "reflecting": 10842, - "continuously": 10843, - "cruiser": 10844, - "graduates": 10845, - "freeway": 10846, - "investigated": 10847, - "ore": 10848, - "deserved": 10849, - "maid": 10850, - "blocking": 10851, - "phillip": 10852, - "jorge": 10853, - "shakes": 10854, - "dove": 10855, - "mann": 10856, - "variables": 10857, - "lacked": 10858, - "burden": 10859, - "accompanying": 10860, - "que": 10861, - "consistently": 10862, - "organizing": 10863, - "provisional": 10864, - "complained": 10865, - "endless": 10866, - "##rm": 10867, - "tubes": 10868, - "juice": 10869, - "georges": 10870, - "krishna": 10871, - "mick": 10872, - "labels": 10873, - "thriller": 10874, - "##uch": 10875, - "laps": 10876, - "arcade": 10877, - "sage": 10878, - "snail": 10879, - "##table": 10880, - "shannon": 10881, - "fi": 10882, - "laurence": 10883, - "seoul": 10884, - "vacation": 10885, - "presenting": 10886, - "hire": 10887, - "churchill": 10888, - "surprisingly": 10889, - "prohibited": 10890, - "savannah": 10891, - "technically": 10892, - "##oli": 10893, - "170": 10894, - "##lessly": 10895, - "testimony": 10896, - "suited": 10897, - "speeds": 10898, - "toys": 10899, - "romans": 10900, - "mlb": 10901, - "flowering": 10902, - "measurement": 10903, - "talented": 10904, - "kay": 10905, - "settings": 10906, - "charleston": 10907, - "expectations": 10908, - "shattered": 10909, - "achieving": 10910, - "triumph": 10911, - "ceremonies": 10912, - "portsmouth": 10913, - "lanes": 10914, - "mandatory": 10915, - "loser": 10916, - "stretching": 10917, - "cologne": 10918, - "realizes": 10919, - "seventy": 10920, - "cornell": 10921, - "careers": 10922, - "webb": 10923, - "##ulating": 10924, - "americas": 10925, - "budapest": 10926, - "ava": 10927, - "suspicion": 10928, - "##ison": 10929, - "yo": 10930, - "conrad": 10931, - "##hai": 10932, - "sterling": 10933, - "jessie": 10934, - "rector": 10935, - "##az": 10936, - "1831": 10937, - "transform": 10938, - "organize": 10939, - "loans": 10940, - "christine": 10941, - "volcanic": 10942, - "warrant": 10943, - "slender": 10944, - "summers": 10945, - "subfamily": 10946, - "newer": 10947, - "danced": 10948, - "dynamics": 10949, - "rhine": 10950, - "proceeds": 10951, - "heinrich": 10952, - "gastropod": 10953, - "commands": 10954, - "sings": 10955, - "facilitate": 10956, - "easter": 10957, - "ra": 10958, - "positioned": 10959, - "responses": 10960, - "expense": 10961, - "fruits": 10962, - "yanked": 10963, - "imported": 10964, - "25th": 10965, - "velvet": 10966, - "vic": 10967, - "primitive": 10968, - "tribune": 10969, - "baldwin": 10970, - "neighbourhood": 10971, - "donna": 10972, - "rip": 10973, - "hay": 10974, - "pr": 10975, - "##uro": 10976, - "1814": 10977, - "espn": 10978, - "welcomed": 10979, - "##aria": 10980, - "qualifier": 10981, - "glare": 10982, - "highland": 10983, - "timing": 10984, - "##cted": 10985, - "shells": 10986, - "eased": 10987, - "geometry": 10988, - "louder": 10989, - "exciting": 10990, - "slovakia": 10991, - "##sion": 10992, - "##iz": 10993, - "##lot": 10994, - "savings": 10995, - "prairie": 10996, - "##ques": 10997, - "marching": 10998, - "rafael": 10999, - "tonnes": 11000, - "##lled": 11001, - "curtain": 11002, - "preceding": 11003, - "shy": 11004, - "heal": 11005, - "greene": 11006, - "worthy": 11007, - "##pot": 11008, - "detachment": 11009, - "bury": 11010, - "sherman": 11011, - "##eck": 11012, - "reinforced": 11013, - "seeks": 11014, - "bottles": 11015, - "contracted": 11016, - "duchess": 11017, - "outfit": 11018, - "walsh": 11019, - "##sc": 11020, - "mickey": 11021, - "##ase": 11022, - "geoffrey": 11023, - "archer": 11024, - "squeeze": 11025, - "dawson": 11026, - "eliminate": 11027, - "invention": 11028, - "##enberg": 11029, - "neal": 11030, - "##eth": 11031, - "stance": 11032, - "dealer": 11033, - "coral": 11034, - "maple": 11035, - "retire": 11036, - "polo": 11037, - "simplified": 11038, - "##ht": 11039, - "1833": 11040, - "hid": 11041, - "watts": 11042, - "backwards": 11043, - "jules": 11044, - "##oke": 11045, - "genesis": 11046, - "mt": 11047, - "frames": 11048, - "rebounds": 11049, - "burma": 11050, - "woodland": 11051, - "moist": 11052, - "santos": 11053, - "whispers": 11054, - "drained": 11055, - "subspecies": 11056, - "##aa": 11057, - "streaming": 11058, - "ulster": 11059, - "burnt": 11060, - "correspondence": 11061, - "maternal": 11062, - "gerard": 11063, - "denis": 11064, - "stealing": 11065, - "##load": 11066, - "genius": 11067, - "duchy": 11068, - "##oria": 11069, - "inaugurated": 11070, - "momentum": 11071, - "suits": 11072, - "placement": 11073, - "sovereign": 11074, - "clause": 11075, - "thames": 11076, - "##hara": 11077, - "confederation": 11078, - "reservation": 11079, - "sketch": 11080, - "yankees": 11081, - "lets": 11082, - "rotten": 11083, - "charm": 11084, - "hal": 11085, - "verses": 11086, - "ultra": 11087, - "commercially": 11088, - "dot": 11089, - "salon": 11090, - "citation": 11091, - "adopt": 11092, - "winnipeg": 11093, - "mist": 11094, - "allocated": 11095, - "cairo": 11096, - "##boy": 11097, - "jenkins": 11098, - "interference": 11099, - "objectives": 11100, - "##wind": 11101, - "1820": 11102, - "portfolio": 11103, - "armoured": 11104, - "sectors": 11105, - "##eh": 11106, - "initiatives": 11107, - "##world": 11108, - "integrity": 11109, - "exercises": 11110, - "robe": 11111, - "tap": 11112, - "ab": 11113, - "gazed": 11114, - "##tones": 11115, - "distracted": 11116, - "rulers": 11117, - "111": 11118, - "favorable": 11119, - "jerome": 11120, - "tended": 11121, - "cart": 11122, - "factories": 11123, - "##eri": 11124, - "diplomat": 11125, - "valued": 11126, - "gravel": 11127, - "charitable": 11128, - "##try": 11129, - "calvin": 11130, - "exploring": 11131, - "chang": 11132, - "shepherd": 11133, - "terrace": 11134, - "pdf": 11135, - "pupil": 11136, - "##ural": 11137, - "reflects": 11138, - "ups": 11139, - "##rch": 11140, - "governors": 11141, - "shelf": 11142, - "depths": 11143, - "##nberg": 11144, - "trailed": 11145, - "crest": 11146, - "tackle": 11147, - "##nian": 11148, - "##ats": 11149, - "hatred": 11150, - "##kai": 11151, - "clare": 11152, - "makers": 11153, - "ethiopia": 11154, - "longtime": 11155, - "detected": 11156, - "embedded": 11157, - "lacking": 11158, - "slapped": 11159, - "rely": 11160, - "thomson": 11161, - "anticipation": 11162, - "iso": 11163, - "morton": 11164, - "successive": 11165, - "agnes": 11166, - "screenwriter": 11167, - "straightened": 11168, - "philippe": 11169, - "playwright": 11170, - "haunted": 11171, - "licence": 11172, - "iris": 11173, - "intentions": 11174, - "sutton": 11175, - "112": 11176, - "logical": 11177, - "correctly": 11178, - "##weight": 11179, - "branded": 11180, - "licked": 11181, - "tipped": 11182, - "silva": 11183, - "ricky": 11184, - "narrator": 11185, - "requests": 11186, - "##ents": 11187, - "greeted": 11188, - "supernatural": 11189, - "cow": 11190, - "##wald": 11191, - "lung": 11192, - "refusing": 11193, - "employer": 11194, - "strait": 11195, - "gaelic": 11196, - "liner": 11197, - "##piece": 11198, - "zoe": 11199, - "sabha": 11200, - "##mba": 11201, - "driveway": 11202, - "harvest": 11203, - "prints": 11204, - "bates": 11205, - "reluctantly": 11206, - "threshold": 11207, - "algebra": 11208, - "ira": 11209, - "wherever": 11210, - "coupled": 11211, - "240": 11212, - "assumption": 11213, - "picks": 11214, - "##air": 11215, - "designers": 11216, - "raids": 11217, - "gentlemen": 11218, - "##ean": 11219, - "roller": 11220, - "blowing": 11221, - "leipzig": 11222, - "locks": 11223, - "screw": 11224, - "dressing": 11225, - "strand": 11226, - "##lings": 11227, - "scar": 11228, - "dwarf": 11229, - "depicts": 11230, - "##nu": 11231, - "nods": 11232, - "##mine": 11233, - "differ": 11234, - "boris": 11235, - "##eur": 11236, - "yuan": 11237, - "flip": 11238, - "##gie": 11239, - "mob": 11240, - "invested": 11241, - "questioning": 11242, - "applying": 11243, - "##ture": 11244, - "shout": 11245, - "##sel": 11246, - "gameplay": 11247, - "blamed": 11248, - "illustrations": 11249, - "bothered": 11250, - "weakness": 11251, - "rehabilitation": 11252, - "##of": 11253, - "##zes": 11254, - "envelope": 11255, - "rumors": 11256, - "miners": 11257, - "leicester": 11258, - "subtle": 11259, - "kerry": 11260, - "##ico": 11261, - "ferguson": 11262, - "##fu": 11263, - "premiership": 11264, - "ne": 11265, - "##cat": 11266, - "bengali": 11267, - "prof": 11268, - "catches": 11269, - "remnants": 11270, - "dana": 11271, - "##rily": 11272, - "shouting": 11273, - "presidents": 11274, - "baltic": 11275, - "ought": 11276, - "ghosts": 11277, - "dances": 11278, - "sailors": 11279, - "shirley": 11280, - "fancy": 11281, - "dominic": 11282, - "##bie": 11283, - "madonna": 11284, - "##rick": 11285, - "bark": 11286, - "buttons": 11287, - "gymnasium": 11288, - "ashes": 11289, - "liver": 11290, - "toby": 11291, - "oath": 11292, - "providence": 11293, - "doyle": 11294, - "evangelical": 11295, - "nixon": 11296, - "cement": 11297, - "carnegie": 11298, - "embarked": 11299, - "hatch": 11300, - "surroundings": 11301, - "guarantee": 11302, - "needing": 11303, - "pirate": 11304, - "essence": 11305, - "##bee": 11306, - "filter": 11307, - "crane": 11308, - "hammond": 11309, - "projected": 11310, - "immune": 11311, - "percy": 11312, - "twelfth": 11313, - "##ult": 11314, - "regent": 11315, - "doctoral": 11316, - "damon": 11317, - "mikhail": 11318, - "##ichi": 11319, - "lu": 11320, - "critically": 11321, - "elect": 11322, - "realised": 11323, - "abortion": 11324, - "acute": 11325, - "screening": 11326, - "mythology": 11327, - "steadily": 11328, - "##fc": 11329, - "frown": 11330, - "nottingham": 11331, - "kirk": 11332, - "wa": 11333, - "minneapolis": 11334, - "##rra": 11335, - "module": 11336, - "algeria": 11337, - "mc": 11338, - "nautical": 11339, - "encounters": 11340, - "surprising": 11341, - "statues": 11342, - "availability": 11343, - "shirts": 11344, - "pie": 11345, - "alma": 11346, - "brows": 11347, - "munster": 11348, - "mack": 11349, - "soup": 11350, - "crater": 11351, - "tornado": 11352, - "sanskrit": 11353, - "cedar": 11354, - "explosive": 11355, - "bordered": 11356, - "dixon": 11357, - "planets": 11358, - "stamp": 11359, - "exam": 11360, - "happily": 11361, - "##bble": 11362, - "carriers": 11363, - "kidnapped": 11364, - "##vis": 11365, - "accommodation": 11366, - "emigrated": 11367, - "##met": 11368, - "knockout": 11369, - "correspondent": 11370, - "violation": 11371, - "profits": 11372, - "peaks": 11373, - "lang": 11374, - "specimen": 11375, - "agenda": 11376, - "ancestry": 11377, - "pottery": 11378, - "spelling": 11379, - "equations": 11380, - "obtaining": 11381, - "ki": 11382, - "linking": 11383, - "1825": 11384, - "debris": 11385, - "asylum": 11386, - "##20": 11387, - "buddhism": 11388, - "teddy": 11389, - "##ants": 11390, - "gazette": 11391, - "##nger": 11392, - "##sse": 11393, - "dental": 11394, - "eligibility": 11395, - "utc": 11396, - "fathers": 11397, - "averaged": 11398, - "zimbabwe": 11399, - "francesco": 11400, - "coloured": 11401, - "hissed": 11402, - "translator": 11403, - "lynch": 11404, - "mandate": 11405, - "humanities": 11406, - "mackenzie": 11407, - "uniforms": 11408, - "lin": 11409, - "##iana": 11410, - "##gio": 11411, - "asset": 11412, - "mhz": 11413, - "fitting": 11414, - "samantha": 11415, - "genera": 11416, - "wei": 11417, - "rim": 11418, - "beloved": 11419, - "shark": 11420, - "riot": 11421, - "entities": 11422, - "expressions": 11423, - "indo": 11424, - "carmen": 11425, - "slipping": 11426, - "owing": 11427, - "abbot": 11428, - "neighbor": 11429, - "sidney": 11430, - "##av": 11431, - "rats": 11432, - "recommendations": 11433, - "encouraging": 11434, - "squadrons": 11435, - "anticipated": 11436, - "commanders": 11437, - "conquered": 11438, - "##oto": 11439, - "donations": 11440, - "diagnosed": 11441, - "##mond": 11442, - "divide": 11443, - "##iva": 11444, - "guessed": 11445, - "decoration": 11446, - "vernon": 11447, - "auditorium": 11448, - "revelation": 11449, - "conversations": 11450, - "##kers": 11451, - "##power": 11452, - "herzegovina": 11453, - "dash": 11454, - "alike": 11455, - "protested": 11456, - "lateral": 11457, - "herman": 11458, - "accredited": 11459, - "mg": 11460, - "##gent": 11461, - "freeman": 11462, - "mel": 11463, - "fiji": 11464, - "crow": 11465, - "crimson": 11466, - "##rine": 11467, - "livestock": 11468, - "##pped": 11469, - "humanitarian": 11470, - "bored": 11471, - "oz": 11472, - "whip": 11473, - "##lene": 11474, - "##ali": 11475, - "legitimate": 11476, - "alter": 11477, - "grinning": 11478, - "spelled": 11479, - "anxious": 11480, - "oriental": 11481, - "wesley": 11482, - "##nin": 11483, - "##hole": 11484, - "carnival": 11485, - "controller": 11486, - "detect": 11487, - "##ssa": 11488, - "bowed": 11489, - "educator": 11490, - "kosovo": 11491, - "macedonia": 11492, - "##sin": 11493, - "occupy": 11494, - "mastering": 11495, - "stephanie": 11496, - "janeiro": 11497, - "para": 11498, - "unaware": 11499, - "nurses": 11500, - "noon": 11501, - "135": 11502, - "cam": 11503, - "hopefully": 11504, - "ranger": 11505, - "combine": 11506, - "sociology": 11507, - "polar": 11508, - "rica": 11509, - "##eer": 11510, - "neill": 11511, - "##sman": 11512, - "holocaust": 11513, - "##ip": 11514, - "doubled": 11515, - "lust": 11516, - "1828": 11517, - "109": 11518, - "decent": 11519, - "cooling": 11520, - "unveiled": 11521, - "##card": 11522, - "1829": 11523, - "nsw": 11524, - "homer": 11525, - "chapman": 11526, - "meyer": 11527, - "##gin": 11528, - "dive": 11529, - "mae": 11530, - "reagan": 11531, - "expertise": 11532, - "##gled": 11533, - "darwin": 11534, - "brooke": 11535, - "sided": 11536, - "prosecution": 11537, - "investigating": 11538, - "comprised": 11539, - "petroleum": 11540, - "genres": 11541, - "reluctant": 11542, - "differently": 11543, - "trilogy": 11544, - "johns": 11545, - "vegetables": 11546, - "corpse": 11547, - "highlighted": 11548, - "lounge": 11549, - "pension": 11550, - "unsuccessfully": 11551, - "elegant": 11552, - "aided": 11553, - "ivory": 11554, - "beatles": 11555, - "amelia": 11556, - "cain": 11557, - "dubai": 11558, - "sunny": 11559, - "immigrant": 11560, - "babe": 11561, - "click": 11562, - "##nder": 11563, - "underwater": 11564, - "pepper": 11565, - "combining": 11566, - "mumbled": 11567, - "atlas": 11568, - "horns": 11569, - "accessed": 11570, - "ballad": 11571, - "physicians": 11572, - "homeless": 11573, - "gestured": 11574, - "rpm": 11575, - "freak": 11576, - "louisville": 11577, - "corporations": 11578, - "patriots": 11579, - "prizes": 11580, - "rational": 11581, - "warn": 11582, - "modes": 11583, - "decorative": 11584, - "overnight": 11585, - "din": 11586, - "troubled": 11587, - "phantom": 11588, - "##ort": 11589, - "monarch": 11590, - "sheer": 11591, - "##dorf": 11592, - "generals": 11593, - "guidelines": 11594, - "organs": 11595, - "addresses": 11596, - "##zon": 11597, - "enhance": 11598, - "curling": 11599, - "parishes": 11600, - "cord": 11601, - "##kie": 11602, - "linux": 11603, - "caesar": 11604, - "deutsche": 11605, - "bavaria": 11606, - "##bia": 11607, - "coleman": 11608, - "cyclone": 11609, - "##eria": 11610, - "bacon": 11611, - "petty": 11612, - "##yama": 11613, - "##old": 11614, - "hampton": 11615, - "diagnosis": 11616, - "1824": 11617, - "throws": 11618, - "complexity": 11619, - "rita": 11620, - "disputed": 11621, - "##₃": 11622, - "pablo": 11623, - "##sch": 11624, - "marketed": 11625, - "trafficking": 11626, - "##ulus": 11627, - "examine": 11628, - "plague": 11629, - "formats": 11630, - "##oh": 11631, - "vault": 11632, - "faithful": 11633, - "##bourne": 11634, - "webster": 11635, - "##ox": 11636, - "highlights": 11637, - "##ient": 11638, - "##ann": 11639, - "phones": 11640, - "vacuum": 11641, - "sandwich": 11642, - "modeling": 11643, - "##gated": 11644, - "bolivia": 11645, - "clergy": 11646, - "qualities": 11647, - "isabel": 11648, - "##nas": 11649, - "##ars": 11650, - "wears": 11651, - "screams": 11652, - "reunited": 11653, - "annoyed": 11654, - "bra": 11655, - "##ancy": 11656, - "##rate": 11657, - "differential": 11658, - "transmitter": 11659, - "tattoo": 11660, - "container": 11661, - "poker": 11662, - "##och": 11663, - "excessive": 11664, - "resides": 11665, - "cowboys": 11666, - "##tum": 11667, - "augustus": 11668, - "trash": 11669, - "providers": 11670, - "statute": 11671, - "retreated": 11672, - "balcony": 11673, - "reversed": 11674, - "void": 11675, - "storey": 11676, - "preceded": 11677, - "masses": 11678, - "leap": 11679, - "laughs": 11680, - "neighborhoods": 11681, - "wards": 11682, - "schemes": 11683, - "falcon": 11684, - "santo": 11685, - "battlefield": 11686, - "pad": 11687, - "ronnie": 11688, - "thread": 11689, - "lesbian": 11690, - "venus": 11691, - "##dian": 11692, - "beg": 11693, - "sandstone": 11694, - "daylight": 11695, - "punched": 11696, - "gwen": 11697, - "analog": 11698, - "stroked": 11699, - "wwe": 11700, - "acceptable": 11701, - "measurements": 11702, - "dec": 11703, - "toxic": 11704, - "##kel": 11705, - "adequate": 11706, - "surgical": 11707, - "economist": 11708, - "parameters": 11709, - "varsity": 11710, - "##sberg": 11711, - "quantity": 11712, - "ella": 11713, - "##chy": 11714, - "##rton": 11715, - "countess": 11716, - "generating": 11717, - "precision": 11718, - "diamonds": 11719, - "expressway": 11720, - "ga": 11721, - "##ı": 11722, - "1821": 11723, - "uruguay": 11724, - "talents": 11725, - "galleries": 11726, - "expenses": 11727, - "scanned": 11728, - "colleague": 11729, - "outlets": 11730, - "ryder": 11731, - "lucien": 11732, - "##ila": 11733, - "paramount": 11734, - "##bon": 11735, - "syracuse": 11736, - "dim": 11737, - "fangs": 11738, - "gown": 11739, - "sweep": 11740, - "##sie": 11741, - "toyota": 11742, - "missionaries": 11743, - "websites": 11744, - "##nsis": 11745, - "sentences": 11746, - "adviser": 11747, - "val": 11748, - "trademark": 11749, - "spells": 11750, - "##plane": 11751, - "patience": 11752, - "starter": 11753, - "slim": 11754, - "##borg": 11755, - "toe": 11756, - "incredibly": 11757, - "shoots": 11758, - "elliot": 11759, - "nobility": 11760, - "##wyn": 11761, - "cowboy": 11762, - "endorsed": 11763, - "gardner": 11764, - "tendency": 11765, - "persuaded": 11766, - "organisms": 11767, - "emissions": 11768, - "kazakhstan": 11769, - "amused": 11770, - "boring": 11771, - "chips": 11772, - "themed": 11773, - "##hand": 11774, - "llc": 11775, - "constantinople": 11776, - "chasing": 11777, - "systematic": 11778, - "guatemala": 11779, - "borrowed": 11780, - "erin": 11781, - "carey": 11782, - "##hard": 11783, - "highlands": 11784, - "struggles": 11785, - "1810": 11786, - "##ifying": 11787, - "##ced": 11788, - "wong": 11789, - "exceptions": 11790, - "develops": 11791, - "enlarged": 11792, - "kindergarten": 11793, - "castro": 11794, - "##ern": 11795, - "##rina": 11796, - "leigh": 11797, - "zombie": 11798, - "juvenile": 11799, - "##most": 11800, - "consul": 11801, - "##nar": 11802, - "sailor": 11803, - "hyde": 11804, - "clarence": 11805, - "intensive": 11806, - "pinned": 11807, - "nasty": 11808, - "useless": 11809, - "jung": 11810, - "clayton": 11811, - "stuffed": 11812, - "exceptional": 11813, - "ix": 11814, - "apostolic": 11815, - "230": 11816, - "transactions": 11817, - "##dge": 11818, - "exempt": 11819, - "swinging": 11820, - "cove": 11821, - "religions": 11822, - "##ash": 11823, - "shields": 11824, - "dairy": 11825, - "bypass": 11826, - "190": 11827, - "pursuing": 11828, - "bug": 11829, - "joyce": 11830, - "bombay": 11831, - "chassis": 11832, - "southampton": 11833, - "chat": 11834, - "interact": 11835, - "redesignated": 11836, - "##pen": 11837, - "nascar": 11838, - "pray": 11839, - "salmon": 11840, - "rigid": 11841, - "regained": 11842, - "malaysian": 11843, - "grim": 11844, - "publicity": 11845, - "constituted": 11846, - "capturing": 11847, - "toilet": 11848, - "delegate": 11849, - "purely": 11850, - "tray": 11851, - "drift": 11852, - "loosely": 11853, - "striker": 11854, - "weakened": 11855, - "trinidad": 11856, - "mitch": 11857, - "itv": 11858, - "defines": 11859, - "transmitted": 11860, - "ming": 11861, - "scarlet": 11862, - "nodding": 11863, - "fitzgerald": 11864, - "fu": 11865, - "narrowly": 11866, - "sp": 11867, - "tooth": 11868, - "standings": 11869, - "virtue": 11870, - "##₁": 11871, - "##wara": 11872, - "##cting": 11873, - "chateau": 11874, - "gloves": 11875, - "lid": 11876, - "##nel": 11877, - "hurting": 11878, - "conservatory": 11879, - "##pel": 11880, - "sinclair": 11881, - "reopened": 11882, - "sympathy": 11883, - "nigerian": 11884, - "strode": 11885, - "advocated": 11886, - "optional": 11887, - "chronic": 11888, - "discharge": 11889, - "##rc": 11890, - "suck": 11891, - "compatible": 11892, - "laurel": 11893, - "stella": 11894, - "shi": 11895, - "fails": 11896, - "wage": 11897, - "dodge": 11898, - "128": 11899, - "informal": 11900, - "sorts": 11901, - "levi": 11902, - "buddha": 11903, - "villagers": 11904, - "##aka": 11905, - "chronicles": 11906, - "heavier": 11907, - "summoned": 11908, - "gateway": 11909, - "3000": 11910, - "eleventh": 11911, - "jewelry": 11912, - "translations": 11913, - "accordingly": 11914, - "seas": 11915, - "##ency": 11916, - "fiber": 11917, - "pyramid": 11918, - "cubic": 11919, - "dragging": 11920, - "##ista": 11921, - "caring": 11922, - "##ops": 11923, - "android": 11924, - "contacted": 11925, - "lunar": 11926, - "##dt": 11927, - "kai": 11928, - "lisbon": 11929, - "patted": 11930, - "1826": 11931, - "sacramento": 11932, - "theft": 11933, - "madagascar": 11934, - "subtropical": 11935, - "disputes": 11936, - "ta": 11937, - "holidays": 11938, - "piper": 11939, - "willow": 11940, - "mare": 11941, - "cane": 11942, - "itunes": 11943, - "newfoundland": 11944, - "benny": 11945, - "companions": 11946, - "dong": 11947, - "raj": 11948, - "observe": 11949, - "roar": 11950, - "charming": 11951, - "plaque": 11952, - "tibetan": 11953, - "fossils": 11954, - "enacted": 11955, - "manning": 11956, - "bubble": 11957, - "tina": 11958, - "tanzania": 11959, - "##eda": 11960, - "##hir": 11961, - "funk": 11962, - "swamp": 11963, - "deputies": 11964, - "cloak": 11965, - "ufc": 11966, - "scenario": 11967, - "par": 11968, - "scratch": 11969, - "metals": 11970, - "anthem": 11971, - "guru": 11972, - "engaging": 11973, - "specially": 11974, - "##boat": 11975, - "dialects": 11976, - "nineteen": 11977, - "cecil": 11978, - "duet": 11979, - "disability": 11980, - "messenger": 11981, - "unofficial": 11982, - "##lies": 11983, - "defunct": 11984, - "eds": 11985, - "moonlight": 11986, - "drainage": 11987, - "surname": 11988, - "puzzle": 11989, - "honda": 11990, - "switching": 11991, - "conservatives": 11992, - "mammals": 11993, - "knox": 11994, - "broadcaster": 11995, - "sidewalk": 11996, - "cope": 11997, - "##ried": 11998, - "benson": 11999, - "princes": 12000, - "peterson": 12001, - "##sal": 12002, - "bedford": 12003, - "sharks": 12004, - "eli": 12005, - "wreck": 12006, - "alberto": 12007, - "gasp": 12008, - "archaeology": 12009, - "lgbt": 12010, - "teaches": 12011, - "securities": 12012, - "madness": 12013, - "compromise": 12014, - "waving": 12015, - "coordination": 12016, - "davidson": 12017, - "visions": 12018, - "leased": 12019, - "possibilities": 12020, - "eighty": 12021, - "jun": 12022, - "fernandez": 12023, - "enthusiasm": 12024, - "assassin": 12025, - "sponsorship": 12026, - "reviewer": 12027, - "kingdoms": 12028, - "estonian": 12029, - "laboratories": 12030, - "##fy": 12031, - "##nal": 12032, - "applies": 12033, - "verb": 12034, - "celebrations": 12035, - "##zzo": 12036, - "rowing": 12037, - "lightweight": 12038, - "sadness": 12039, - "submit": 12040, - "mvp": 12041, - "balanced": 12042, - "dude": 12043, - "##vas": 12044, - "explicitly": 12045, - "metric": 12046, - "magnificent": 12047, - "mound": 12048, - "brett": 12049, - "mohammad": 12050, - "mistakes": 12051, - "irregular": 12052, - "##hing": 12053, - "##ass": 12054, - "sanders": 12055, - "betrayed": 12056, - "shipped": 12057, - "surge": 12058, - "##enburg": 12059, - "reporters": 12060, - "termed": 12061, - "georg": 12062, - "pity": 12063, - "verbal": 12064, - "bulls": 12065, - "abbreviated": 12066, - "enabling": 12067, - "appealed": 12068, - "##are": 12069, - "##atic": 12070, - "sicily": 12071, - "sting": 12072, - "heel": 12073, - "sweetheart": 12074, - "bart": 12075, - "spacecraft": 12076, - "brutal": 12077, - "monarchy": 12078, - "##tter": 12079, - "aberdeen": 12080, - "cameo": 12081, - "diane": 12082, - "##ub": 12083, - "survivor": 12084, - "clyde": 12085, - "##aries": 12086, - "complaint": 12087, - "##makers": 12088, - "clarinet": 12089, - "delicious": 12090, - "chilean": 12091, - "karnataka": 12092, - "coordinates": 12093, - "1818": 12094, - "panties": 12095, - "##rst": 12096, - "pretending": 12097, - "ar": 12098, - "dramatically": 12099, - "kiev": 12100, - "bella": 12101, - "tends": 12102, - "distances": 12103, - "113": 12104, - "catalog": 12105, - "launching": 12106, - "instances": 12107, - "telecommunications": 12108, - "portable": 12109, - "lindsay": 12110, - "vatican": 12111, - "##eim": 12112, - "angles": 12113, - "aliens": 12114, - "marker": 12115, - "stint": 12116, - "screens": 12117, - "bolton": 12118, - "##rne": 12119, - "judy": 12120, - "wool": 12121, - "benedict": 12122, - "plasma": 12123, - "europa": 12124, - "spark": 12125, - "imaging": 12126, - "filmmaker": 12127, - "swiftly": 12128, - "##een": 12129, - "contributor": 12130, - "##nor": 12131, - "opted": 12132, - "stamps": 12133, - "apologize": 12134, - "financing": 12135, - "butter": 12136, - "gideon": 12137, - "sophisticated": 12138, - "alignment": 12139, - "avery": 12140, - "chemicals": 12141, - "yearly": 12142, - "speculation": 12143, - "prominence": 12144, - "professionally": 12145, - "##ils": 12146, - "immortal": 12147, - "institutional": 12148, - "inception": 12149, - "wrists": 12150, - "identifying": 12151, - "tribunal": 12152, - "derives": 12153, - "gains": 12154, - "##wo": 12155, - "papal": 12156, - "preference": 12157, - "linguistic": 12158, - "vince": 12159, - "operative": 12160, - "brewery": 12161, - "##ont": 12162, - "unemployment": 12163, - "boyd": 12164, - "##ured": 12165, - "##outs": 12166, - "albeit": 12167, - "prophet": 12168, - "1813": 12169, - "bi": 12170, - "##rr": 12171, - "##face": 12172, - "##rad": 12173, - "quarterly": 12174, - "asteroid": 12175, - "cleaned": 12176, - "radius": 12177, - "temper": 12178, - "##llen": 12179, - "telugu": 12180, - "jerk": 12181, - "viscount": 12182, - "menu": 12183, - "##ote": 12184, - "glimpse": 12185, - "##aya": 12186, - "yacht": 12187, - "hawaiian": 12188, - "baden": 12189, - "##rl": 12190, - "laptop": 12191, - "readily": 12192, - "##gu": 12193, - "monetary": 12194, - "offshore": 12195, - "scots": 12196, - "watches": 12197, - "##yang": 12198, - "##arian": 12199, - "upgrade": 12200, - "needle": 12201, - "xbox": 12202, - "lea": 12203, - "encyclopedia": 12204, - "flank": 12205, - "fingertips": 12206, - "##pus": 12207, - "delight": 12208, - "teachings": 12209, - "confirm": 12210, - "roth": 12211, - "beaches": 12212, - "midway": 12213, - "winters": 12214, - "##iah": 12215, - "teasing": 12216, - "daytime": 12217, - "beverly": 12218, - "gambling": 12219, - "bonnie": 12220, - "##backs": 12221, - "regulated": 12222, - "clement": 12223, - "hermann": 12224, - "tricks": 12225, - "knot": 12226, - "##shing": 12227, - "##uring": 12228, - "##vre": 12229, - "detached": 12230, - "ecological": 12231, - "owed": 12232, - "specialty": 12233, - "byron": 12234, - "inventor": 12235, - "bats": 12236, - "stays": 12237, - "screened": 12238, - "unesco": 12239, - "midland": 12240, - "trim": 12241, - "affection": 12242, - "##ander": 12243, - "##rry": 12244, - "jess": 12245, - "thoroughly": 12246, - "feedback": 12247, - "##uma": 12248, - "chennai": 12249, - "strained": 12250, - "heartbeat": 12251, - "wrapping": 12252, - "overtime": 12253, - "pleaded": 12254, - "##sworth": 12255, - "mon": 12256, - "leisure": 12257, - "oclc": 12258, - "##tate": 12259, - "##ele": 12260, - "feathers": 12261, - "angelo": 12262, - "thirds": 12263, - "nuts": 12264, - "surveys": 12265, - "clever": 12266, - "gill": 12267, - "commentator": 12268, - "##dos": 12269, - "darren": 12270, - "rides": 12271, - "gibraltar": 12272, - "##nc": 12273, - "##mu": 12274, - "dissolution": 12275, - "dedication": 12276, - "shin": 12277, - "meals": 12278, - "saddle": 12279, - "elvis": 12280, - "reds": 12281, - "chaired": 12282, - "taller": 12283, - "appreciation": 12284, - "functioning": 12285, - "niece": 12286, - "favored": 12287, - "advocacy": 12288, - "robbie": 12289, - "criminals": 12290, - "suffolk": 12291, - "yugoslav": 12292, - "passport": 12293, - "constable": 12294, - "congressman": 12295, - "hastings": 12296, - "vera": 12297, - "##rov": 12298, - "consecrated": 12299, - "sparks": 12300, - "ecclesiastical": 12301, - "confined": 12302, - "##ovich": 12303, - "muller": 12304, - "floyd": 12305, - "nora": 12306, - "1822": 12307, - "paved": 12308, - "1827": 12309, - "cumberland": 12310, - "ned": 12311, - "saga": 12312, - "spiral": 12313, - "##flow": 12314, - "appreciated": 12315, - "yi": 12316, - "collaborative": 12317, - "treating": 12318, - "similarities": 12319, - "feminine": 12320, - "finishes": 12321, - "##ib": 12322, - "jade": 12323, - "import": 12324, - "##nse": 12325, - "##hot": 12326, - "champagne": 12327, - "mice": 12328, - "securing": 12329, - "celebrities": 12330, - "helsinki": 12331, - "attributes": 12332, - "##gos": 12333, - "cousins": 12334, - "phases": 12335, - "ache": 12336, - "lucia": 12337, - "gandhi": 12338, - "submission": 12339, - "vicar": 12340, - "spear": 12341, - "shine": 12342, - "tasmania": 12343, - "biting": 12344, - "detention": 12345, - "constitute": 12346, - "tighter": 12347, - "seasonal": 12348, - "##gus": 12349, - "terrestrial": 12350, - "matthews": 12351, - "##oka": 12352, - "effectiveness": 12353, - "parody": 12354, - "philharmonic": 12355, - "##onic": 12356, - "1816": 12357, - "strangers": 12358, - "encoded": 12359, - "consortium": 12360, - "guaranteed": 12361, - "regards": 12362, - "shifts": 12363, - "tortured": 12364, - "collision": 12365, - "supervisor": 12366, - "inform": 12367, - "broader": 12368, - "insight": 12369, - "theaters": 12370, - "armour": 12371, - "emeritus": 12372, - "blink": 12373, - "incorporates": 12374, - "mapping": 12375, - "##50": 12376, - "##ein": 12377, - "handball": 12378, - "flexible": 12379, - "##nta": 12380, - "substantially": 12381, - "generous": 12382, - "thief": 12383, - "##own": 12384, - "carr": 12385, - "loses": 12386, - "1793": 12387, - "prose": 12388, - "ucla": 12389, - "romeo": 12390, - "generic": 12391, - "metallic": 12392, - "realization": 12393, - "damages": 12394, - "mk": 12395, - "commissioners": 12396, - "zach": 12397, - "default": 12398, - "##ther": 12399, - "helicopters": 12400, - "lengthy": 12401, - "stems": 12402, - "spa": 12403, - "partnered": 12404, - "spectators": 12405, - "rogue": 12406, - "indication": 12407, - "penalties": 12408, - "teresa": 12409, - "1801": 12410, - "sen": 12411, - "##tric": 12412, - "dalton": 12413, - "##wich": 12414, - "irving": 12415, - "photographic": 12416, - "##vey": 12417, - "dell": 12418, - "deaf": 12419, - "peters": 12420, - "excluded": 12421, - "unsure": 12422, - "##vable": 12423, - "patterson": 12424, - "crawled": 12425, - "##zio": 12426, - "resided": 12427, - "whipped": 12428, - "latvia": 12429, - "slower": 12430, - "ecole": 12431, - "pipes": 12432, - "employers": 12433, - "maharashtra": 12434, - "comparable": 12435, - "va": 12436, - "textile": 12437, - "pageant": 12438, - "##gel": 12439, - "alphabet": 12440, - "binary": 12441, - "irrigation": 12442, - "chartered": 12443, - "choked": 12444, - "antoine": 12445, - "offs": 12446, - "waking": 12447, - "supplement": 12448, - "##wen": 12449, - "quantities": 12450, - "demolition": 12451, - "regain": 12452, - "locate": 12453, - "urdu": 12454, - "folks": 12455, - "alt": 12456, - "114": 12457, - "##mc": 12458, - "scary": 12459, - "andreas": 12460, - "whites": 12461, - "##ava": 12462, - "classrooms": 12463, - "mw": 12464, - "aesthetic": 12465, - "publishes": 12466, - "valleys": 12467, - "guides": 12468, - "cubs": 12469, - "johannes": 12470, - "bryant": 12471, - "conventions": 12472, - "affecting": 12473, - "##itt": 12474, - "drain": 12475, - "awesome": 12476, - "isolation": 12477, - "prosecutor": 12478, - "ambitious": 12479, - "apology": 12480, - "captive": 12481, - "downs": 12482, - "atmospheric": 12483, - "lorenzo": 12484, - "aisle": 12485, - "beef": 12486, - "foul": 12487, - "##onia": 12488, - "kidding": 12489, - "composite": 12490, - "disturbed": 12491, - "illusion": 12492, - "natives": 12493, - "##ffer": 12494, - "emi": 12495, - "rockets": 12496, - "riverside": 12497, - "wartime": 12498, - "painters": 12499, - "adolf": 12500, - "melted": 12501, - "##ail": 12502, - "uncertainty": 12503, - "simulation": 12504, - "hawks": 12505, - "progressed": 12506, - "meantime": 12507, - "builder": 12508, - "spray": 12509, - "breach": 12510, - "unhappy": 12511, - "regina": 12512, - "russians": 12513, - "##urg": 12514, - "determining": 12515, - "##tation": 12516, - "tram": 12517, - "1806": 12518, - "##quin": 12519, - "aging": 12520, - "##12": 12521, - "1823": 12522, - "garion": 12523, - "rented": 12524, - "mister": 12525, - "diaz": 12526, - "terminated": 12527, - "clip": 12528, - "1817": 12529, - "depend": 12530, - "nervously": 12531, - "disco": 12532, - "owe": 12533, - "defenders": 12534, - "shiva": 12535, - "notorious": 12536, - "disbelief": 12537, - "shiny": 12538, - "worcester": 12539, - "##gation": 12540, - "##yr": 12541, - "trailing": 12542, - "undertook": 12543, - "islander": 12544, - "belarus": 12545, - "limitations": 12546, - "watershed": 12547, - "fuller": 12548, - "overlooking": 12549, - "utilized": 12550, - "raphael": 12551, - "1819": 12552, - "synthetic": 12553, - "breakdown": 12554, - "klein": 12555, - "##nate": 12556, - "moaned": 12557, - "memoir": 12558, - "lamb": 12559, - "practicing": 12560, - "##erly": 12561, - "cellular": 12562, - "arrows": 12563, - "exotic": 12564, - "##graphy": 12565, - "witches": 12566, - "117": 12567, - "charted": 12568, - "rey": 12569, - "hut": 12570, - "hierarchy": 12571, - "subdivision": 12572, - "freshwater": 12573, - "giuseppe": 12574, - "aloud": 12575, - "reyes": 12576, - "qatar": 12577, - "marty": 12578, - "sideways": 12579, - "utterly": 12580, - "sexually": 12581, - "jude": 12582, - "prayers": 12583, - "mccarthy": 12584, - "softball": 12585, - "blend": 12586, - "damien": 12587, - "##gging": 12588, - "##metric": 12589, - "wholly": 12590, - "erupted": 12591, - "lebanese": 12592, - "negro": 12593, - "revenues": 12594, - "tasted": 12595, - "comparative": 12596, - "teamed": 12597, - "transaction": 12598, - "labeled": 12599, - "maori": 12600, - "sovereignty": 12601, - "parkway": 12602, - "trauma": 12603, - "gran": 12604, - "malay": 12605, - "121": 12606, - "advancement": 12607, - "descendant": 12608, - "2020": 12609, - "buzz": 12610, - "salvation": 12611, - "inventory": 12612, - "symbolic": 12613, - "##making": 12614, - "antarctica": 12615, - "mps": 12616, - "##gas": 12617, - "##bro": 12618, - "mohammed": 12619, - "myanmar": 12620, - "holt": 12621, - "submarines": 12622, - "tones": 12623, - "##lman": 12624, - "locker": 12625, - "patriarch": 12626, - "bangkok": 12627, - "emerson": 12628, - "remarks": 12629, - "predators": 12630, - "kin": 12631, - "afghan": 12632, - "confession": 12633, - "norwich": 12634, - "rental": 12635, - "emerge": 12636, - "advantages": 12637, - "##zel": 12638, - "rca": 12639, - "##hold": 12640, - "shortened": 12641, - "storms": 12642, - "aidan": 12643, - "##matic": 12644, - "autonomy": 12645, - "compliance": 12646, - "##quet": 12647, - "dudley": 12648, - "atp": 12649, - "##osis": 12650, - "1803": 12651, - "motto": 12652, - "documentation": 12653, - "summary": 12654, - "professors": 12655, - "spectacular": 12656, - "christina": 12657, - "archdiocese": 12658, - "flashing": 12659, - "innocence": 12660, - "remake": 12661, - "##dell": 12662, - "psychic": 12663, - "reef": 12664, - "scare": 12665, - "employ": 12666, - "rs": 12667, - "sticks": 12668, - "meg": 12669, - "gus": 12670, - "leans": 12671, - "##ude": 12672, - "accompany": 12673, - "bergen": 12674, - "tomas": 12675, - "##iko": 12676, - "doom": 12677, - "wages": 12678, - "pools": 12679, - "##nch": 12680, - "##bes": 12681, - "breasts": 12682, - "scholarly": 12683, - "alison": 12684, - "outline": 12685, - "brittany": 12686, - "breakthrough": 12687, - "willis": 12688, - "realistic": 12689, - "##cut": 12690, - "##boro": 12691, - "competitor": 12692, - "##stan": 12693, - "pike": 12694, - "picnic": 12695, - "icon": 12696, - "designing": 12697, - "commercials": 12698, - "washing": 12699, - "villain": 12700, - "skiing": 12701, - "micro": 12702, - "costumes": 12703, - "auburn": 12704, - "halted": 12705, - "executives": 12706, - "##hat": 12707, - "logistics": 12708, - "cycles": 12709, - "vowel": 12710, - "applicable": 12711, - "barrett": 12712, - "exclaimed": 12713, - "eurovision": 12714, - "eternity": 12715, - "ramon": 12716, - "##umi": 12717, - "##lls": 12718, - "modifications": 12719, - "sweeping": 12720, - "disgust": 12721, - "##uck": 12722, - "torch": 12723, - "aviv": 12724, - "ensuring": 12725, - "rude": 12726, - "dusty": 12727, - "sonic": 12728, - "donovan": 12729, - "outskirts": 12730, - "cu": 12731, - "pathway": 12732, - "##band": 12733, - "##gun": 12734, - "##lines": 12735, - "disciplines": 12736, - "acids": 12737, - "cadet": 12738, - "paired": 12739, - "##40": 12740, - "sketches": 12741, - "##sive": 12742, - "marriages": 12743, - "##⁺": 12744, - "folding": 12745, - "peers": 12746, - "slovak": 12747, - "implies": 12748, - "admired": 12749, - "##beck": 12750, - "1880s": 12751, - "leopold": 12752, - "instinct": 12753, - "attained": 12754, - "weston": 12755, - "megan": 12756, - "horace": 12757, - "##ination": 12758, - "dorsal": 12759, - "ingredients": 12760, - "evolutionary": 12761, - "##its": 12762, - "complications": 12763, - "deity": 12764, - "lethal": 12765, - "brushing": 12766, - "levy": 12767, - "deserted": 12768, - "institutes": 12769, - "posthumously": 12770, - "delivering": 12771, - "telescope": 12772, - "coronation": 12773, - "motivated": 12774, - "rapids": 12775, - "luc": 12776, - "flicked": 12777, - "pays": 12778, - "volcano": 12779, - "tanner": 12780, - "weighed": 12781, - "##nica": 12782, - "crowds": 12783, - "frankie": 12784, - "gifted": 12785, - "addressing": 12786, - "granddaughter": 12787, - "winding": 12788, - "##rna": 12789, - "constantine": 12790, - "gomez": 12791, - "##front": 12792, - "landscapes": 12793, - "rudolf": 12794, - "anthropology": 12795, - "slate": 12796, - "werewolf": 12797, - "##lio": 12798, - "astronomy": 12799, - "circa": 12800, - "rouge": 12801, - "dreaming": 12802, - "sack": 12803, - "knelt": 12804, - "drowned": 12805, - "naomi": 12806, - "prolific": 12807, - "tracked": 12808, - "freezing": 12809, - "herb": 12810, - "##dium": 12811, - "agony": 12812, - "randall": 12813, - "twisting": 12814, - "wendy": 12815, - "deposit": 12816, - "touches": 12817, - "vein": 12818, - "wheeler": 12819, - "##bbled": 12820, - "##bor": 12821, - "batted": 12822, - "retaining": 12823, - "tire": 12824, - "presently": 12825, - "compare": 12826, - "specification": 12827, - "daemon": 12828, - "nigel": 12829, - "##grave": 12830, - "merry": 12831, - "recommendation": 12832, - "czechoslovakia": 12833, - "sandra": 12834, - "ng": 12835, - "roma": 12836, - "##sts": 12837, - "lambert": 12838, - "inheritance": 12839, - "sheikh": 12840, - "winchester": 12841, - "cries": 12842, - "examining": 12843, - "##yle": 12844, - "comeback": 12845, - "cuisine": 12846, - "nave": 12847, - "##iv": 12848, - "ko": 12849, - "retrieve": 12850, - "tomatoes": 12851, - "barker": 12852, - "polished": 12853, - "defining": 12854, - "irene": 12855, - "lantern": 12856, - "personalities": 12857, - "begging": 12858, - "tract": 12859, - "swore": 12860, - "1809": 12861, - "175": 12862, - "##gic": 12863, - "omaha": 12864, - "brotherhood": 12865, - "##rley": 12866, - "haiti": 12867, - "##ots": 12868, - "exeter": 12869, - "##ete": 12870, - "##zia": 12871, - "steele": 12872, - "dumb": 12873, - "pearson": 12874, - "210": 12875, - "surveyed": 12876, - "elisabeth": 12877, - "trends": 12878, - "##ef": 12879, - "fritz": 12880, - "##rf": 12881, - "premium": 12882, - "bugs": 12883, - "fraction": 12884, - "calmly": 12885, - "viking": 12886, - "##birds": 12887, - "tug": 12888, - "inserted": 12889, - "unusually": 12890, - "##ield": 12891, - "confronted": 12892, - "distress": 12893, - "crashing": 12894, - "brent": 12895, - "turks": 12896, - "resign": 12897, - "##olo": 12898, - "cambodia": 12899, - "gabe": 12900, - "sauce": 12901, - "##kal": 12902, - "evelyn": 12903, - "116": 12904, - "extant": 12905, - "clusters": 12906, - "quarry": 12907, - "teenagers": 12908, - "luna": 12909, - "##lers": 12910, - "##ister": 12911, - "affiliation": 12912, - "drill": 12913, - "##ashi": 12914, - "panthers": 12915, - "scenic": 12916, - "libya": 12917, - "anita": 12918, - "strengthen": 12919, - "inscriptions": 12920, - "##cated": 12921, - "lace": 12922, - "sued": 12923, - "judith": 12924, - "riots": 12925, - "##uted": 12926, - "mint": 12927, - "##eta": 12928, - "preparations": 12929, - "midst": 12930, - "dub": 12931, - "challenger": 12932, - "##vich": 12933, - "mock": 12934, - "cf": 12935, - "displaced": 12936, - "wicket": 12937, - "breaths": 12938, - "enables": 12939, - "schmidt": 12940, - "analyst": 12941, - "##lum": 12942, - "ag": 12943, - "highlight": 12944, - "automotive": 12945, - "axe": 12946, - "josef": 12947, - "newark": 12948, - "sufficiently": 12949, - "resembles": 12950, - "50th": 12951, - "##pal": 12952, - "flushed": 12953, - "mum": 12954, - "traits": 12955, - "##ante": 12956, - "commodore": 12957, - "incomplete": 12958, - "warming": 12959, - "titular": 12960, - "ceremonial": 12961, - "ethical": 12962, - "118": 12963, - "celebrating": 12964, - "eighteenth": 12965, - "cao": 12966, - "lima": 12967, - "medalist": 12968, - "mobility": 12969, - "strips": 12970, - "snakes": 12971, - "##city": 12972, - "miniature": 12973, - "zagreb": 12974, - "barton": 12975, - "escapes": 12976, - "umbrella": 12977, - "automated": 12978, - "doubted": 12979, - "differs": 12980, - "cooled": 12981, - "georgetown": 12982, - "dresden": 12983, - "cooked": 12984, - "fade": 12985, - "wyatt": 12986, - "rna": 12987, - "jacobs": 12988, - "carlton": 12989, - "abundant": 12990, - "stereo": 12991, - "boost": 12992, - "madras": 12993, - "inning": 12994, - "##hia": 12995, - "spur": 12996, - "ip": 12997, - "malayalam": 12998, - "begged": 12999, - "osaka": 13000, - "groan": 13001, - "escaping": 13002, - "charging": 13003, - "dose": 13004, - "vista": 13005, - "##aj": 13006, - "bud": 13007, - "papa": 13008, - "communists": 13009, - "advocates": 13010, - "edged": 13011, - "tri": 13012, - "##cent": 13013, - "resemble": 13014, - "peaking": 13015, - "necklace": 13016, - "fried": 13017, - "montenegro": 13018, - "saxony": 13019, - "goose": 13020, - "glances": 13021, - "stuttgart": 13022, - "curator": 13023, - "recruit": 13024, - "grocery": 13025, - "sympathetic": 13026, - "##tting": 13027, - "##fort": 13028, - "127": 13029, - "lotus": 13030, - "randolph": 13031, - "ancestor": 13032, - "##rand": 13033, - "succeeding": 13034, - "jupiter": 13035, - "1798": 13036, - "macedonian": 13037, - "##heads": 13038, - "hiking": 13039, - "1808": 13040, - "handing": 13041, - "fischer": 13042, - "##itive": 13043, - "garbage": 13044, - "node": 13045, - "##pies": 13046, - "prone": 13047, - "singular": 13048, - "papua": 13049, - "inclined": 13050, - "attractions": 13051, - "italia": 13052, - "pouring": 13053, - "motioned": 13054, - "grandma": 13055, - "garnered": 13056, - "jacksonville": 13057, - "corp": 13058, - "ego": 13059, - "ringing": 13060, - "aluminum": 13061, - "##hausen": 13062, - "ordering": 13063, - "##foot": 13064, - "drawer": 13065, - "traders": 13066, - "synagogue": 13067, - "##play": 13068, - "##kawa": 13069, - "resistant": 13070, - "wandering": 13071, - "fragile": 13072, - "fiona": 13073, - "teased": 13074, - "var": 13075, - "hardcore": 13076, - "soaked": 13077, - "jubilee": 13078, - "decisive": 13079, - "exposition": 13080, - "mercer": 13081, - "poster": 13082, - "valencia": 13083, - "hale": 13084, - "kuwait": 13085, - "1811": 13086, - "##ises": 13087, - "##wr": 13088, - "##eed": 13089, - "tavern": 13090, - "gamma": 13091, - "122": 13092, - "johan": 13093, - "##uer": 13094, - "airways": 13095, - "amino": 13096, - "gil": 13097, - "##ury": 13098, - "vocational": 13099, - "domains": 13100, - "torres": 13101, - "##sp": 13102, - "generator": 13103, - "folklore": 13104, - "outcomes": 13105, - "##keeper": 13106, - "canberra": 13107, - "shooter": 13108, - "fl": 13109, - "beams": 13110, - "confrontation": 13111, - "##lling": 13112, - "##gram": 13113, - "feb": 13114, - "aligned": 13115, - "forestry": 13116, - "pipeline": 13117, - "jax": 13118, - "motorway": 13119, - "conception": 13120, - "decay": 13121, - "##tos": 13122, - "coffin": 13123, - "##cott": 13124, - "stalin": 13125, - "1805": 13126, - "escorted": 13127, - "minded": 13128, - "##nam": 13129, - "sitcom": 13130, - "purchasing": 13131, - "twilight": 13132, - "veronica": 13133, - "additions": 13134, - "passive": 13135, - "tensions": 13136, - "straw": 13137, - "123": 13138, - "frequencies": 13139, - "1804": 13140, - "refugee": 13141, - "cultivation": 13142, - "##iate": 13143, - "christie": 13144, - "clary": 13145, - "bulletin": 13146, - "crept": 13147, - "disposal": 13148, - "##rich": 13149, - "##zong": 13150, - "processor": 13151, - "crescent": 13152, - "##rol": 13153, - "bmw": 13154, - "emphasized": 13155, - "whale": 13156, - "nazis": 13157, - "aurora": 13158, - "##eng": 13159, - "dwelling": 13160, - "hauled": 13161, - "sponsors": 13162, - "toledo": 13163, - "mega": 13164, - "ideology": 13165, - "theatres": 13166, - "tessa": 13167, - "cerambycidae": 13168, - "saves": 13169, - "turtle": 13170, - "cone": 13171, - "suspects": 13172, - "kara": 13173, - "rusty": 13174, - "yelling": 13175, - "greeks": 13176, - "mozart": 13177, - "shades": 13178, - "cocked": 13179, - "participant": 13180, - "##tro": 13181, - "shire": 13182, - "spit": 13183, - "freeze": 13184, - "necessity": 13185, - "##cos": 13186, - "inmates": 13187, - "nielsen": 13188, - "councillors": 13189, - "loaned": 13190, - "uncommon": 13191, - "omar": 13192, - "peasants": 13193, - "botanical": 13194, - "offspring": 13195, - "daniels": 13196, - "formations": 13197, - "jokes": 13198, - "1794": 13199, - "pioneers": 13200, - "sigma": 13201, - "licensing": 13202, - "##sus": 13203, - "wheelchair": 13204, - "polite": 13205, - "1807": 13206, - "liquor": 13207, - "pratt": 13208, - "trustee": 13209, - "##uta": 13210, - "forewings": 13211, - "balloon": 13212, - "##zz": 13213, - "kilometre": 13214, - "camping": 13215, - "explicit": 13216, - "casually": 13217, - "shawn": 13218, - "foolish": 13219, - "teammates": 13220, - "nm": 13221, - "hassan": 13222, - "carrie": 13223, - "judged": 13224, - "satisfy": 13225, - "vanessa": 13226, - "knives": 13227, - "selective": 13228, - "cnn": 13229, - "flowed": 13230, - "##lice": 13231, - "eclipse": 13232, - "stressed": 13233, - "eliza": 13234, - "mathematician": 13235, - "cease": 13236, - "cultivated": 13237, - "##roy": 13238, - "commissions": 13239, - "browns": 13240, - "##ania": 13241, - "destroyers": 13242, - "sheridan": 13243, - "meadow": 13244, - "##rius": 13245, - "minerals": 13246, - "##cial": 13247, - "downstream": 13248, - "clash": 13249, - "gram": 13250, - "memoirs": 13251, - "ventures": 13252, - "baha": 13253, - "seymour": 13254, - "archie": 13255, - "midlands": 13256, - "edith": 13257, - "fare": 13258, - "flynn": 13259, - "invite": 13260, - "canceled": 13261, - "tiles": 13262, - "stabbed": 13263, - "boulder": 13264, - "incorporate": 13265, - "amended": 13266, - "camden": 13267, - "facial": 13268, - "mollusk": 13269, - "unreleased": 13270, - "descriptions": 13271, - "yoga": 13272, - "grabs": 13273, - "550": 13274, - "raises": 13275, - "ramp": 13276, - "shiver": 13277, - "##rose": 13278, - "coined": 13279, - "pioneering": 13280, - "tunes": 13281, - "qing": 13282, - "warwick": 13283, - "tops": 13284, - "119": 13285, - "melanie": 13286, - "giles": 13287, - "##rous": 13288, - "wandered": 13289, - "##inal": 13290, - "annexed": 13291, - "nov": 13292, - "30th": 13293, - "unnamed": 13294, - "##ished": 13295, - "organizational": 13296, - "airplane": 13297, - "normandy": 13298, - "stoke": 13299, - "whistle": 13300, - "blessing": 13301, - "violations": 13302, - "chased": 13303, - "holders": 13304, - "shotgun": 13305, - "##ctic": 13306, - "outlet": 13307, - "reactor": 13308, - "##vik": 13309, - "tires": 13310, - "tearing": 13311, - "shores": 13312, - "fortified": 13313, - "mascot": 13314, - "constituencies": 13315, - "nc": 13316, - "columnist": 13317, - "productive": 13318, - "tibet": 13319, - "##rta": 13320, - "lineage": 13321, - "hooked": 13322, - "oct": 13323, - "tapes": 13324, - "judging": 13325, - "cody": 13326, - "##gger": 13327, - "hansen": 13328, - "kashmir": 13329, - "triggered": 13330, - "##eva": 13331, - "solved": 13332, - "cliffs": 13333, - "##tree": 13334, - "resisted": 13335, - "anatomy": 13336, - "protesters": 13337, - "transparent": 13338, - "implied": 13339, - "##iga": 13340, - "injection": 13341, - "mattress": 13342, - "excluding": 13343, - "##mbo": 13344, - "defenses": 13345, - "helpless": 13346, - "devotion": 13347, - "##elli": 13348, - "growl": 13349, - "liberals": 13350, - "weber": 13351, - "phenomena": 13352, - "atoms": 13353, - "plug": 13354, - "##iff": 13355, - "mortality": 13356, - "apprentice": 13357, - "howe": 13358, - "convincing": 13359, - "aaa": 13360, - "swimmer": 13361, - "barber": 13362, - "leone": 13363, - "promptly": 13364, - "sodium": 13365, - "def": 13366, - "nowadays": 13367, - "arise": 13368, - "##oning": 13369, - "gloucester": 13370, - "corrected": 13371, - "dignity": 13372, - "norm": 13373, - "erie": 13374, - "##ders": 13375, - "elders": 13376, - "evacuated": 13377, - "sylvia": 13378, - "compression": 13379, - "##yar": 13380, - "hartford": 13381, - "pose": 13382, - "backpack": 13383, - "reasoning": 13384, - "accepts": 13385, - "24th": 13386, - "wipe": 13387, - "millimetres": 13388, - "marcel": 13389, - "##oda": 13390, - "dodgers": 13391, - "albion": 13392, - "1790": 13393, - "overwhelmed": 13394, - "aerospace": 13395, - "oaks": 13396, - "1795": 13397, - "showcase": 13398, - "acknowledge": 13399, - "recovering": 13400, - "nolan": 13401, - "ashe": 13402, - "hurts": 13403, - "geology": 13404, - "fashioned": 13405, - "disappearance": 13406, - "farewell": 13407, - "swollen": 13408, - "shrug": 13409, - "marquis": 13410, - "wimbledon": 13411, - "124": 13412, - "rue": 13413, - "1792": 13414, - "commemorate": 13415, - "reduces": 13416, - "experiencing": 13417, - "inevitable": 13418, - "calcutta": 13419, - "intel": 13420, - "##court": 13421, - "murderer": 13422, - "sticking": 13423, - "fisheries": 13424, - "imagery": 13425, - "bloom": 13426, - "280": 13427, - "brake": 13428, - "##inus": 13429, - "gustav": 13430, - "hesitation": 13431, - "memorable": 13432, - "po": 13433, - "viral": 13434, - "beans": 13435, - "accidents": 13436, - "tunisia": 13437, - "antenna": 13438, - "spilled": 13439, - "consort": 13440, - "treatments": 13441, - "aye": 13442, - "perimeter": 13443, - "##gard": 13444, - "donation": 13445, - "hostage": 13446, - "migrated": 13447, - "banker": 13448, - "addiction": 13449, - "apex": 13450, - "lil": 13451, - "trout": 13452, - "##ously": 13453, - "conscience": 13454, - "##nova": 13455, - "rams": 13456, - "sands": 13457, - "genome": 13458, - "passionate": 13459, - "troubles": 13460, - "##lets": 13461, - "##set": 13462, - "amid": 13463, - "##ibility": 13464, - "##ret": 13465, - "higgins": 13466, - "exceed": 13467, - "vikings": 13468, - "##vie": 13469, - "payne": 13470, - "##zan": 13471, - "muscular": 13472, - "##ste": 13473, - "defendant": 13474, - "sucking": 13475, - "##wal": 13476, - "ibrahim": 13477, - "fuselage": 13478, - "claudia": 13479, - "vfl": 13480, - "europeans": 13481, - "snails": 13482, - "interval": 13483, - "##garh": 13484, - "preparatory": 13485, - "statewide": 13486, - "tasked": 13487, - "lacrosse": 13488, - "viktor": 13489, - "##lation": 13490, - "angola": 13491, - "##hra": 13492, - "flint": 13493, - "implications": 13494, - "employs": 13495, - "teens": 13496, - "patrons": 13497, - "stall": 13498, - "weekends": 13499, - "barriers": 13500, - "scrambled": 13501, - "nucleus": 13502, - "tehran": 13503, - "jenna": 13504, - "parsons": 13505, - "lifelong": 13506, - "robots": 13507, - "displacement": 13508, - "5000": 13509, - "##bles": 13510, - "precipitation": 13511, - "##gt": 13512, - "knuckles": 13513, - "clutched": 13514, - "1802": 13515, - "marrying": 13516, - "ecology": 13517, - "marx": 13518, - "accusations": 13519, - "declare": 13520, - "scars": 13521, - "kolkata": 13522, - "mat": 13523, - "meadows": 13524, - "bermuda": 13525, - "skeleton": 13526, - "finalists": 13527, - "vintage": 13528, - "crawl": 13529, - "coordinate": 13530, - "affects": 13531, - "subjected": 13532, - "orchestral": 13533, - "mistaken": 13534, - "##tc": 13535, - "mirrors": 13536, - "dipped": 13537, - "relied": 13538, - "260": 13539, - "arches": 13540, - "candle": 13541, - "##nick": 13542, - "incorporating": 13543, - "wildly": 13544, - "fond": 13545, - "basilica": 13546, - "owl": 13547, - "fringe": 13548, - "rituals": 13549, - "whispering": 13550, - "stirred": 13551, - "feud": 13552, - "tertiary": 13553, - "slick": 13554, - "goat": 13555, - "honorable": 13556, - "whereby": 13557, - "skip": 13558, - "ricardo": 13559, - "stripes": 13560, - "parachute": 13561, - "adjoining": 13562, - "submerged": 13563, - "synthesizer": 13564, - "##gren": 13565, - "intend": 13566, - "positively": 13567, - "ninety": 13568, - "phi": 13569, - "beaver": 13570, - "partition": 13571, - "fellows": 13572, - "alexis": 13573, - "prohibition": 13574, - "carlisle": 13575, - "bizarre": 13576, - "fraternity": 13577, - "##bre": 13578, - "doubts": 13579, - "icy": 13580, - "cbc": 13581, - "aquatic": 13582, - "sneak": 13583, - "sonny": 13584, - "combines": 13585, - "airports": 13586, - "crude": 13587, - "supervised": 13588, - "spatial": 13589, - "merge": 13590, - "alfonso": 13591, - "##bic": 13592, - "corrupt": 13593, - "scan": 13594, - "undergo": 13595, - "##ams": 13596, - "disabilities": 13597, - "colombian": 13598, - "comparing": 13599, - "dolphins": 13600, - "perkins": 13601, - "##lish": 13602, - "reprinted": 13603, - "unanimous": 13604, - "bounced": 13605, - "hairs": 13606, - "underworld": 13607, - "midwest": 13608, - "semester": 13609, - "bucket": 13610, - "paperback": 13611, - "miniseries": 13612, - "coventry": 13613, - "demise": 13614, - "##leigh": 13615, - "demonstrations": 13616, - "sensor": 13617, - "rotating": 13618, - "yan": 13619, - "##hler": 13620, - "arrange": 13621, - "soils": 13622, - "##idge": 13623, - "hyderabad": 13624, - "labs": 13625, - "##dr": 13626, - "brakes": 13627, - "grandchildren": 13628, - "##nde": 13629, - "negotiated": 13630, - "rover": 13631, - "ferrari": 13632, - "continuation": 13633, - "directorate": 13634, - "augusta": 13635, - "stevenson": 13636, - "counterpart": 13637, - "gore": 13638, - "##rda": 13639, - "nursery": 13640, - "rican": 13641, - "ave": 13642, - "collectively": 13643, - "broadly": 13644, - "pastoral": 13645, - "repertoire": 13646, - "asserted": 13647, - "discovering": 13648, - "nordic": 13649, - "styled": 13650, - "fiba": 13651, - "cunningham": 13652, - "harley": 13653, - "middlesex": 13654, - "survives": 13655, - "tumor": 13656, - "tempo": 13657, - "zack": 13658, - "aiming": 13659, - "lok": 13660, - "urgent": 13661, - "##rade": 13662, - "##nto": 13663, - "devils": 13664, - "##ement": 13665, - "contractor": 13666, - "turin": 13667, - "##wl": 13668, - "##ool": 13669, - "bliss": 13670, - "repaired": 13671, - "simmons": 13672, - "moan": 13673, - "astronomical": 13674, - "cr": 13675, - "negotiate": 13676, - "lyric": 13677, - "1890s": 13678, - "lara": 13679, - "bred": 13680, - "clad": 13681, - "angus": 13682, - "pbs": 13683, - "##ience": 13684, - "engineered": 13685, - "posed": 13686, - "##lk": 13687, - "hernandez": 13688, - "possessions": 13689, - "elbows": 13690, - "psychiatric": 13691, - "strokes": 13692, - "confluence": 13693, - "electorate": 13694, - "lifts": 13695, - "campuses": 13696, - "lava": 13697, - "alps": 13698, - "##ep": 13699, - "##ution": 13700, - "##date": 13701, - "physicist": 13702, - "woody": 13703, - "##page": 13704, - "##ographic": 13705, - "##itis": 13706, - "juliet": 13707, - "reformation": 13708, - "sparhawk": 13709, - "320": 13710, - "complement": 13711, - "suppressed": 13712, - "jewel": 13713, - "##½": 13714, - "floated": 13715, - "##kas": 13716, - "continuity": 13717, - "sadly": 13718, - "##ische": 13719, - "inability": 13720, - "melting": 13721, - "scanning": 13722, - "paula": 13723, - "flour": 13724, - "judaism": 13725, - "safer": 13726, - "vague": 13727, - "##lm": 13728, - "solving": 13729, - "curb": 13730, - "##stown": 13731, - "financially": 13732, - "gable": 13733, - "bees": 13734, - "expired": 13735, - "miserable": 13736, - "cassidy": 13737, - "dominion": 13738, - "1789": 13739, - "cupped": 13740, - "145": 13741, - "robbery": 13742, - "facto": 13743, - "amos": 13744, - "warden": 13745, - "resume": 13746, - "tallest": 13747, - "marvin": 13748, - "ing": 13749, - "pounded": 13750, - "usd": 13751, - "declaring": 13752, - "gasoline": 13753, - "##aux": 13754, - "darkened": 13755, - "270": 13756, - "650": 13757, - "sophomore": 13758, - "##mere": 13759, - "erection": 13760, - "gossip": 13761, - "televised": 13762, - "risen": 13763, - "dial": 13764, - "##eu": 13765, - "pillars": 13766, - "##link": 13767, - "passages": 13768, - "profound": 13769, - "##tina": 13770, - "arabian": 13771, - "ashton": 13772, - "silicon": 13773, - "nail": 13774, - "##ead": 13775, - "##lated": 13776, - "##wer": 13777, - "##hardt": 13778, - "fleming": 13779, - "firearms": 13780, - "ducked": 13781, - "circuits": 13782, - "blows": 13783, - "waterloo": 13784, - "titans": 13785, - "##lina": 13786, - "atom": 13787, - "fireplace": 13788, - "cheshire": 13789, - "financed": 13790, - "activation": 13791, - "algorithms": 13792, - "##zzi": 13793, - "constituent": 13794, - "catcher": 13795, - "cherokee": 13796, - "partnerships": 13797, - "sexuality": 13798, - "platoon": 13799, - "tragic": 13800, - "vivian": 13801, - "guarded": 13802, - "whiskey": 13803, - "meditation": 13804, - "poetic": 13805, - "##late": 13806, - "##nga": 13807, - "##ake": 13808, - "porto": 13809, - "listeners": 13810, - "dominance": 13811, - "kendra": 13812, - "mona": 13813, - "chandler": 13814, - "factions": 13815, - "22nd": 13816, - "salisbury": 13817, - "attitudes": 13818, - "derivative": 13819, - "##ido": 13820, - "##haus": 13821, - "intake": 13822, - "paced": 13823, - "javier": 13824, - "illustrator": 13825, - "barrels": 13826, - "bias": 13827, - "cockpit": 13828, - "burnett": 13829, - "dreamed": 13830, - "ensuing": 13831, - "##anda": 13832, - "receptors": 13833, - "someday": 13834, - "hawkins": 13835, - "mattered": 13836, - "##lal": 13837, - "slavic": 13838, - "1799": 13839, - "jesuit": 13840, - "cameroon": 13841, - "wasted": 13842, - "tai": 13843, - "wax": 13844, - "lowering": 13845, - "victorious": 13846, - "freaking": 13847, - "outright": 13848, - "hancock": 13849, - "librarian": 13850, - "sensing": 13851, - "bald": 13852, - "calcium": 13853, - "myers": 13854, - "tablet": 13855, - "announcing": 13856, - "barack": 13857, - "shipyard": 13858, - "pharmaceutical": 13859, - "##uan": 13860, - "greenwich": 13861, - "flush": 13862, - "medley": 13863, - "patches": 13864, - "wolfgang": 13865, - "pt": 13866, - "speeches": 13867, - "acquiring": 13868, - "exams": 13869, - "nikolai": 13870, - "##gg": 13871, - "hayden": 13872, - "kannada": 13873, - "##type": 13874, - "reilly": 13875, - "##pt": 13876, - "waitress": 13877, - "abdomen": 13878, - "devastated": 13879, - "capped": 13880, - "pseudonym": 13881, - "pharmacy": 13882, - "fulfill": 13883, - "paraguay": 13884, - "1796": 13885, - "clicked": 13886, - "##trom": 13887, - "archipelago": 13888, - "syndicated": 13889, - "##hman": 13890, - "lumber": 13891, - "orgasm": 13892, - "rejection": 13893, - "clifford": 13894, - "lorraine": 13895, - "advent": 13896, - "mafia": 13897, - "rodney": 13898, - "brock": 13899, - "##ght": 13900, - "##used": 13901, - "##elia": 13902, - "cassette": 13903, - "chamberlain": 13904, - "despair": 13905, - "mongolia": 13906, - "sensors": 13907, - "developmental": 13908, - "upstream": 13909, - "##eg": 13910, - "##alis": 13911, - "spanning": 13912, - "165": 13913, - "trombone": 13914, - "basque": 13915, - "seeded": 13916, - "interred": 13917, - "renewable": 13918, - "rhys": 13919, - "leapt": 13920, - "revision": 13921, - "molecule": 13922, - "##ages": 13923, - "chord": 13924, - "vicious": 13925, - "nord": 13926, - "shivered": 13927, - "23rd": 13928, - "arlington": 13929, - "debts": 13930, - "corpus": 13931, - "sunrise": 13932, - "bays": 13933, - "blackburn": 13934, - "centimetres": 13935, - "##uded": 13936, - "shuddered": 13937, - "gm": 13938, - "strangely": 13939, - "gripping": 13940, - "cartoons": 13941, - "isabelle": 13942, - "orbital": 13943, - "##ppa": 13944, - "seals": 13945, - "proving": 13946, - "##lton": 13947, - "refusal": 13948, - "strengthened": 13949, - "bust": 13950, - "assisting": 13951, - "baghdad": 13952, - "batsman": 13953, - "portrayal": 13954, - "mara": 13955, - "pushes": 13956, - "spears": 13957, - "og": 13958, - "##cock": 13959, - "reside": 13960, - "nathaniel": 13961, - "brennan": 13962, - "1776": 13963, - "confirmation": 13964, - "caucus": 13965, - "##worthy": 13966, - "markings": 13967, - "yemen": 13968, - "nobles": 13969, - "ku": 13970, - "lazy": 13971, - "viewer": 13972, - "catalan": 13973, - "encompasses": 13974, - "sawyer": 13975, - "##fall": 13976, - "sparked": 13977, - "substances": 13978, - "patents": 13979, - "braves": 13980, - "arranger": 13981, - "evacuation": 13982, - "sergio": 13983, - "persuade": 13984, - "dover": 13985, - "tolerance": 13986, - "penguin": 13987, - "cum": 13988, - "jockey": 13989, - "insufficient": 13990, - "townships": 13991, - "occupying": 13992, - "declining": 13993, - "plural": 13994, - "processed": 13995, - "projection": 13996, - "puppet": 13997, - "flanders": 13998, - "introduces": 13999, - "liability": 14000, - "##yon": 14001, - "gymnastics": 14002, - "antwerp": 14003, - "taipei": 14004, - "hobart": 14005, - "candles": 14006, - "jeep": 14007, - "wes": 14008, - "observers": 14009, - "126": 14010, - "chaplain": 14011, - "bundle": 14012, - "glorious": 14013, - "##hine": 14014, - "hazel": 14015, - "flung": 14016, - "sol": 14017, - "excavations": 14018, - "dumped": 14019, - "stares": 14020, - "sh": 14021, - "bangalore": 14022, - "triangular": 14023, - "icelandic": 14024, - "intervals": 14025, - "expressing": 14026, - "turbine": 14027, - "##vers": 14028, - "songwriting": 14029, - "crafts": 14030, - "##igo": 14031, - "jasmine": 14032, - "ditch": 14033, - "rite": 14034, - "##ways": 14035, - "entertaining": 14036, - "comply": 14037, - "sorrow": 14038, - "wrestlers": 14039, - "basel": 14040, - "emirates": 14041, - "marian": 14042, - "rivera": 14043, - "helpful": 14044, - "##some": 14045, - "caution": 14046, - "downward": 14047, - "networking": 14048, - "##atory": 14049, - "##tered": 14050, - "darted": 14051, - "genocide": 14052, - "emergence": 14053, - "replies": 14054, - "specializing": 14055, - "spokesman": 14056, - "convenient": 14057, - "unlocked": 14058, - "fading": 14059, - "augustine": 14060, - "concentrations": 14061, - "resemblance": 14062, - "elijah": 14063, - "investigator": 14064, - "andhra": 14065, - "##uda": 14066, - "promotes": 14067, - "bean": 14068, - "##rrell": 14069, - "fleeing": 14070, - "wan": 14071, - "simone": 14072, - "announcer": 14073, - "##ame": 14074, - "##bby": 14075, - "lydia": 14076, - "weaver": 14077, - "132": 14078, - "residency": 14079, - "modification": 14080, - "##fest": 14081, - "stretches": 14082, - "##ast": 14083, - "alternatively": 14084, - "nat": 14085, - "lowe": 14086, - "lacks": 14087, - "##ented": 14088, - "pam": 14089, - "tile": 14090, - "concealed": 14091, - "inferior": 14092, - "abdullah": 14093, - "residences": 14094, - "tissues": 14095, - "vengeance": 14096, - "##ided": 14097, - "moisture": 14098, - "peculiar": 14099, - "groove": 14100, - "zip": 14101, - "bologna": 14102, - "jennings": 14103, - "ninja": 14104, - "oversaw": 14105, - "zombies": 14106, - "pumping": 14107, - "batch": 14108, - "livingston": 14109, - "emerald": 14110, - "installations": 14111, - "1797": 14112, - "peel": 14113, - "nitrogen": 14114, - "rama": 14115, - "##fying": 14116, - "##star": 14117, - "schooling": 14118, - "strands": 14119, - "responding": 14120, - "werner": 14121, - "##ost": 14122, - "lime": 14123, - "casa": 14124, - "accurately": 14125, - "targeting": 14126, - "##rod": 14127, - "underway": 14128, - "##uru": 14129, - "hemisphere": 14130, - "lester": 14131, - "##yard": 14132, - "occupies": 14133, - "2d": 14134, - "griffith": 14135, - "angrily": 14136, - "reorganized": 14137, - "##owing": 14138, - "courtney": 14139, - "deposited": 14140, - "##dd": 14141, - "##30": 14142, - "estadio": 14143, - "##ifies": 14144, - "dunn": 14145, - "exiled": 14146, - "##ying": 14147, - "checks": 14148, - "##combe": 14149, - "##о": 14150, - "##fly": 14151, - "successes": 14152, - "unexpectedly": 14153, - "blu": 14154, - "assessed": 14155, - "##flower": 14156, - "##ه": 14157, - "observing": 14158, - "sacked": 14159, - "spiders": 14160, - "kn": 14161, - "##tail": 14162, - "mu": 14163, - "nodes": 14164, - "prosperity": 14165, - "audrey": 14166, - "divisional": 14167, - "155": 14168, - "broncos": 14169, - "tangled": 14170, - "adjust": 14171, - "feeds": 14172, - "erosion": 14173, - "paolo": 14174, - "surf": 14175, - "directory": 14176, - "snatched": 14177, - "humid": 14178, - "admiralty": 14179, - "screwed": 14180, - "gt": 14181, - "reddish": 14182, - "##nese": 14183, - "modules": 14184, - "trench": 14185, - "lamps": 14186, - "bind": 14187, - "leah": 14188, - "bucks": 14189, - "competes": 14190, - "##nz": 14191, - "##form": 14192, - "transcription": 14193, - "##uc": 14194, - "isles": 14195, - "violently": 14196, - "clutching": 14197, - "pga": 14198, - "cyclist": 14199, - "inflation": 14200, - "flats": 14201, - "ragged": 14202, - "unnecessary": 14203, - "##hian": 14204, - "stubborn": 14205, - "coordinated": 14206, - "harriet": 14207, - "baba": 14208, - "disqualified": 14209, - "330": 14210, - "insect": 14211, - "wolfe": 14212, - "##fies": 14213, - "reinforcements": 14214, - "rocked": 14215, - "duel": 14216, - "winked": 14217, - "embraced": 14218, - "bricks": 14219, - "##raj": 14220, - "hiatus": 14221, - "defeats": 14222, - "pending": 14223, - "brightly": 14224, - "jealousy": 14225, - "##xton": 14226, - "##hm": 14227, - "##uki": 14228, - "lena": 14229, - "gdp": 14230, - "colorful": 14231, - "##dley": 14232, - "stein": 14233, - "kidney": 14234, - "##shu": 14235, - "underwear": 14236, - "wanderers": 14237, - "##haw": 14238, - "##icus": 14239, - "guardians": 14240, - "m³": 14241, - "roared": 14242, - "habits": 14243, - "##wise": 14244, - "permits": 14245, - "gp": 14246, - "uranium": 14247, - "punished": 14248, - "disguise": 14249, - "bundesliga": 14250, - "elise": 14251, - "dundee": 14252, - "erotic": 14253, - "partisan": 14254, - "pi": 14255, - "collectors": 14256, - "float": 14257, - "individually": 14258, - "rendering": 14259, - "behavioral": 14260, - "bucharest": 14261, - "ser": 14262, - "hare": 14263, - "valerie": 14264, - "corporal": 14265, - "nutrition": 14266, - "proportional": 14267, - "##isa": 14268, - "immense": 14269, - "##kis": 14270, - "pavement": 14271, - "##zie": 14272, - "##eld": 14273, - "sutherland": 14274, - "crouched": 14275, - "1775": 14276, - "##lp": 14277, - "suzuki": 14278, - "trades": 14279, - "endurance": 14280, - "operas": 14281, - "crosby": 14282, - "prayed": 14283, - "priory": 14284, - "rory": 14285, - "socially": 14286, - "##urn": 14287, - "gujarat": 14288, - "##pu": 14289, - "walton": 14290, - "cube": 14291, - "pasha": 14292, - "privilege": 14293, - "lennon": 14294, - "floods": 14295, - "thorne": 14296, - "waterfall": 14297, - "nipple": 14298, - "scouting": 14299, - "approve": 14300, - "##lov": 14301, - "minorities": 14302, - "voter": 14303, - "dwight": 14304, - "extensions": 14305, - "assure": 14306, - "ballroom": 14307, - "slap": 14308, - "dripping": 14309, - "privileges": 14310, - "rejoined": 14311, - "confessed": 14312, - "demonstrating": 14313, - "patriotic": 14314, - "yell": 14315, - "investor": 14316, - "##uth": 14317, - "pagan": 14318, - "slumped": 14319, - "squares": 14320, - "##cle": 14321, - "##kins": 14322, - "confront": 14323, - "bert": 14324, - "embarrassment": 14325, - "##aid": 14326, - "aston": 14327, - "urging": 14328, - "sweater": 14329, - "starr": 14330, - "yuri": 14331, - "brains": 14332, - "williamson": 14333, - "commuter": 14334, - "mortar": 14335, - "structured": 14336, - "selfish": 14337, - "exports": 14338, - "##jon": 14339, - "cds": 14340, - "##him": 14341, - "unfinished": 14342, - "##rre": 14343, - "mortgage": 14344, - "destinations": 14345, - "##nagar": 14346, - "canoe": 14347, - "solitary": 14348, - "buchanan": 14349, - "delays": 14350, - "magistrate": 14351, - "fk": 14352, - "##pling": 14353, - "motivation": 14354, - "##lier": 14355, - "##vier": 14356, - "recruiting": 14357, - "assess": 14358, - "##mouth": 14359, - "malik": 14360, - "antique": 14361, - "1791": 14362, - "pius": 14363, - "rahman": 14364, - "reich": 14365, - "tub": 14366, - "zhou": 14367, - "smashed": 14368, - "airs": 14369, - "galway": 14370, - "xii": 14371, - "conditioning": 14372, - "honduras": 14373, - "discharged": 14374, - "dexter": 14375, - "##pf": 14376, - "lionel": 14377, - "129": 14378, - "debates": 14379, - "lemon": 14380, - "tiffany": 14381, - "volunteered": 14382, - "dom": 14383, - "dioxide": 14384, - "procession": 14385, - "devi": 14386, - "sic": 14387, - "tremendous": 14388, - "advertisements": 14389, - "colts": 14390, - "transferring": 14391, - "verdict": 14392, - "hanover": 14393, - "decommissioned": 14394, - "utter": 14395, - "relate": 14396, - "pac": 14397, - "racism": 14398, - "##top": 14399, - "beacon": 14400, - "limp": 14401, - "similarity": 14402, - "terra": 14403, - "occurrence": 14404, - "ant": 14405, - "##how": 14406, - "becky": 14407, - "capt": 14408, - "updates": 14409, - "armament": 14410, - "richie": 14411, - "pal": 14412, - "##graph": 14413, - "halloween": 14414, - "mayo": 14415, - "##ssen": 14416, - "##bone": 14417, - "cara": 14418, - "serena": 14419, - "fcc": 14420, - "dolls": 14421, - "obligations": 14422, - "##dling": 14423, - "violated": 14424, - "lafayette": 14425, - "jakarta": 14426, - "exploitation": 14427, - "##ime": 14428, - "infamous": 14429, - "iconic": 14430, - "##lah": 14431, - "##park": 14432, - "kitty": 14433, - "moody": 14434, - "reginald": 14435, - "dread": 14436, - "spill": 14437, - "crystals": 14438, - "olivier": 14439, - "modeled": 14440, - "bluff": 14441, - "equilibrium": 14442, - "separating": 14443, - "notices": 14444, - "ordnance": 14445, - "extinction": 14446, - "onset": 14447, - "cosmic": 14448, - "attachment": 14449, - "sammy": 14450, - "expose": 14451, - "privy": 14452, - "anchored": 14453, - "##bil": 14454, - "abbott": 14455, - "admits": 14456, - "bending": 14457, - "baritone": 14458, - "emmanuel": 14459, - "policeman": 14460, - "vaughan": 14461, - "winged": 14462, - "climax": 14463, - "dresses": 14464, - "denny": 14465, - "polytechnic": 14466, - "mohamed": 14467, - "burmese": 14468, - "authentic": 14469, - "nikki": 14470, - "genetics": 14471, - "grandparents": 14472, - "homestead": 14473, - "gaza": 14474, - "postponed": 14475, - "metacritic": 14476, - "una": 14477, - "##sby": 14478, - "##bat": 14479, - "unstable": 14480, - "dissertation": 14481, - "##rial": 14482, - "##cian": 14483, - "curls": 14484, - "obscure": 14485, - "uncovered": 14486, - "bronx": 14487, - "praying": 14488, - "disappearing": 14489, - "##hoe": 14490, - "prehistoric": 14491, - "coke": 14492, - "turret": 14493, - "mutations": 14494, - "nonprofit": 14495, - "pits": 14496, - "monaco": 14497, - "##ي": 14498, - "##usion": 14499, - "prominently": 14500, - "dispatched": 14501, - "podium": 14502, - "##mir": 14503, - "uci": 14504, - "##uation": 14505, - "133": 14506, - "fortifications": 14507, - "birthplace": 14508, - "kendall": 14509, - "##lby": 14510, - "##oll": 14511, - "preacher": 14512, - "rack": 14513, - "goodman": 14514, - "##rman": 14515, - "persistent": 14516, - "##ott": 14517, - "countless": 14518, - "jaime": 14519, - "recorder": 14520, - "lexington": 14521, - "persecution": 14522, - "jumps": 14523, - "renewal": 14524, - "wagons": 14525, - "##11": 14526, - "crushing": 14527, - "##holder": 14528, - "decorations": 14529, - "##lake": 14530, - "abundance": 14531, - "wrath": 14532, - "laundry": 14533, - "£1": 14534, - "garde": 14535, - "##rp": 14536, - "jeanne": 14537, - "beetles": 14538, - "peasant": 14539, - "##sl": 14540, - "splitting": 14541, - "caste": 14542, - "sergei": 14543, - "##rer": 14544, - "##ema": 14545, - "scripts": 14546, - "##ively": 14547, - "rub": 14548, - "satellites": 14549, - "##vor": 14550, - "inscribed": 14551, - "verlag": 14552, - "scrapped": 14553, - "gale": 14554, - "packages": 14555, - "chick": 14556, - "potato": 14557, - "slogan": 14558, - "kathleen": 14559, - "arabs": 14560, - "##culture": 14561, - "counterparts": 14562, - "reminiscent": 14563, - "choral": 14564, - "##tead": 14565, - "rand": 14566, - "retains": 14567, - "bushes": 14568, - "dane": 14569, - "accomplish": 14570, - "courtesy": 14571, - "closes": 14572, - "##oth": 14573, - "slaughter": 14574, - "hague": 14575, - "krakow": 14576, - "lawson": 14577, - "tailed": 14578, - "elias": 14579, - "ginger": 14580, - "##ttes": 14581, - "canopy": 14582, - "betrayal": 14583, - "rebuilding": 14584, - "turf": 14585, - "##hof": 14586, - "frowning": 14587, - "allegiance": 14588, - "brigades": 14589, - "kicks": 14590, - "rebuild": 14591, - "polls": 14592, - "alias": 14593, - "nationalism": 14594, - "td": 14595, - "rowan": 14596, - "audition": 14597, - "bowie": 14598, - "fortunately": 14599, - "recognizes": 14600, - "harp": 14601, - "dillon": 14602, - "horrified": 14603, - "##oro": 14604, - "renault": 14605, - "##tics": 14606, - "ropes": 14607, - "##α": 14608, - "presumed": 14609, - "rewarded": 14610, - "infrared": 14611, - "wiping": 14612, - "accelerated": 14613, - "illustration": 14614, - "##rid": 14615, - "presses": 14616, - "practitioners": 14617, - "badminton": 14618, - "##iard": 14619, - "detained": 14620, - "##tera": 14621, - "recognizing": 14622, - "relates": 14623, - "misery": 14624, - "##sies": 14625, - "##tly": 14626, - "reproduction": 14627, - "piercing": 14628, - "potatoes": 14629, - "thornton": 14630, - "esther": 14631, - "manners": 14632, - "hbo": 14633, - "##aan": 14634, - "ours": 14635, - "bullshit": 14636, - "ernie": 14637, - "perennial": 14638, - "sensitivity": 14639, - "illuminated": 14640, - "rupert": 14641, - "##jin": 14642, - "##iss": 14643, - "##ear": 14644, - "rfc": 14645, - "nassau": 14646, - "##dock": 14647, - "staggered": 14648, - "socialism": 14649, - "##haven": 14650, - "appointments": 14651, - "nonsense": 14652, - "prestige": 14653, - "sharma": 14654, - "haul": 14655, - "##tical": 14656, - "solidarity": 14657, - "gps": 14658, - "##ook": 14659, - "##rata": 14660, - "igor": 14661, - "pedestrian": 14662, - "##uit": 14663, - "baxter": 14664, - "tenants": 14665, - "wires": 14666, - "medication": 14667, - "unlimited": 14668, - "guiding": 14669, - "impacts": 14670, - "diabetes": 14671, - "##rama": 14672, - "sasha": 14673, - "pas": 14674, - "clive": 14675, - "extraction": 14676, - "131": 14677, - "continually": 14678, - "constraints": 14679, - "##bilities": 14680, - "sonata": 14681, - "hunted": 14682, - "sixteenth": 14683, - "chu": 14684, - "planting": 14685, - "quote": 14686, - "mayer": 14687, - "pretended": 14688, - "abs": 14689, - "spat": 14690, - "##hua": 14691, - "ceramic": 14692, - "##cci": 14693, - "curtains": 14694, - "pigs": 14695, - "pitching": 14696, - "##dad": 14697, - "latvian": 14698, - "sore": 14699, - "dayton": 14700, - "##sted": 14701, - "##qi": 14702, - "patrols": 14703, - "slice": 14704, - "playground": 14705, - "##nted": 14706, - "shone": 14707, - "stool": 14708, - "apparatus": 14709, - "inadequate": 14710, - "mates": 14711, - "treason": 14712, - "##ija": 14713, - "desires": 14714, - "##liga": 14715, - "##croft": 14716, - "somalia": 14717, - "laurent": 14718, - "mir": 14719, - "leonardo": 14720, - "oracle": 14721, - "grape": 14722, - "obliged": 14723, - "chevrolet": 14724, - "thirteenth": 14725, - "stunning": 14726, - "enthusiastic": 14727, - "##ede": 14728, - "accounted": 14729, - "concludes": 14730, - "currents": 14731, - "basil": 14732, - "##kovic": 14733, - "drought": 14734, - "##rica": 14735, - "mai": 14736, - "##aire": 14737, - "shove": 14738, - "posting": 14739, - "##shed": 14740, - "pilgrimage": 14741, - "humorous": 14742, - "packing": 14743, - "fry": 14744, - "pencil": 14745, - "wines": 14746, - "smells": 14747, - "144": 14748, - "marilyn": 14749, - "aching": 14750, - "newest": 14751, - "clung": 14752, - "bon": 14753, - "neighbours": 14754, - "sanctioned": 14755, - "##pie": 14756, - "mug": 14757, - "##stock": 14758, - "drowning": 14759, - "##mma": 14760, - "hydraulic": 14761, - "##vil": 14762, - "hiring": 14763, - "reminder": 14764, - "lilly": 14765, - "investigators": 14766, - "##ncies": 14767, - "sour": 14768, - "##eous": 14769, - "compulsory": 14770, - "packet": 14771, - "##rion": 14772, - "##graphic": 14773, - "##elle": 14774, - "cannes": 14775, - "##inate": 14776, - "depressed": 14777, - "##rit": 14778, - "heroic": 14779, - "importantly": 14780, - "theresa": 14781, - "##tled": 14782, - "conway": 14783, - "saturn": 14784, - "marginal": 14785, - "rae": 14786, - "##xia": 14787, - "corresponds": 14788, - "royce": 14789, - "pact": 14790, - "jasper": 14791, - "explosives": 14792, - "packaging": 14793, - "aluminium": 14794, - "##ttered": 14795, - "denotes": 14796, - "rhythmic": 14797, - "spans": 14798, - "assignments": 14799, - "hereditary": 14800, - "outlined": 14801, - "originating": 14802, - "sundays": 14803, - "lad": 14804, - "reissued": 14805, - "greeting": 14806, - "beatrice": 14807, - "##dic": 14808, - "pillar": 14809, - "marcos": 14810, - "plots": 14811, - "handbook": 14812, - "alcoholic": 14813, - "judiciary": 14814, - "avant": 14815, - "slides": 14816, - "extract": 14817, - "masculine": 14818, - "blur": 14819, - "##eum": 14820, - "##force": 14821, - "homage": 14822, - "trembled": 14823, - "owens": 14824, - "hymn": 14825, - "trey": 14826, - "omega": 14827, - "signaling": 14828, - "socks": 14829, - "accumulated": 14830, - "reacted": 14831, - "attic": 14832, - "theo": 14833, - "lining": 14834, - "angie": 14835, - "distraction": 14836, - "primera": 14837, - "talbot": 14838, - "##key": 14839, - "1200": 14840, - "ti": 14841, - "creativity": 14842, - "billed": 14843, - "##hey": 14844, - "deacon": 14845, - "eduardo": 14846, - "identifies": 14847, - "proposition": 14848, - "dizzy": 14849, - "gunner": 14850, - "hogan": 14851, - "##yam": 14852, - "##pping": 14853, - "##hol": 14854, - "ja": 14855, - "##chan": 14856, - "jensen": 14857, - "reconstructed": 14858, - "##berger": 14859, - "clearance": 14860, - "darius": 14861, - "##nier": 14862, - "abe": 14863, - "harlem": 14864, - "plea": 14865, - "dei": 14866, - "circled": 14867, - "emotionally": 14868, - "notation": 14869, - "fascist": 14870, - "neville": 14871, - "exceeded": 14872, - "upwards": 14873, - "viable": 14874, - "ducks": 14875, - "##fo": 14876, - "workforce": 14877, - "racer": 14878, - "limiting": 14879, - "shri": 14880, - "##lson": 14881, - "possesses": 14882, - "1600": 14883, - "kerr": 14884, - "moths": 14885, - "devastating": 14886, - "laden": 14887, - "disturbing": 14888, - "locking": 14889, - "##cture": 14890, - "gal": 14891, - "fearing": 14892, - "accreditation": 14893, - "flavor": 14894, - "aide": 14895, - "1870s": 14896, - "mountainous": 14897, - "##baum": 14898, - "melt": 14899, - "##ures": 14900, - "motel": 14901, - "texture": 14902, - "servers": 14903, - "soda": 14904, - "##mb": 14905, - "herd": 14906, - "##nium": 14907, - "erect": 14908, - "puzzled": 14909, - "hum": 14910, - "peggy": 14911, - "examinations": 14912, - "gould": 14913, - "testified": 14914, - "geoff": 14915, - "ren": 14916, - "devised": 14917, - "sacks": 14918, - "##law": 14919, - "denial": 14920, - "posters": 14921, - "grunted": 14922, - "cesar": 14923, - "tutor": 14924, - "ec": 14925, - "gerry": 14926, - "offerings": 14927, - "byrne": 14928, - "falcons": 14929, - "combinations": 14930, - "ct": 14931, - "incoming": 14932, - "pardon": 14933, - "rocking": 14934, - "26th": 14935, - "avengers": 14936, - "flared": 14937, - "mankind": 14938, - "seller": 14939, - "uttar": 14940, - "loch": 14941, - "nadia": 14942, - "stroking": 14943, - "exposing": 14944, - "##hd": 14945, - "fertile": 14946, - "ancestral": 14947, - "instituted": 14948, - "##has": 14949, - "noises": 14950, - "prophecy": 14951, - "taxation": 14952, - "eminent": 14953, - "vivid": 14954, - "pol": 14955, - "##bol": 14956, - "dart": 14957, - "indirect": 14958, - "multimedia": 14959, - "notebook": 14960, - "upside": 14961, - "displaying": 14962, - "adrenaline": 14963, - "referenced": 14964, - "geometric": 14965, - "##iving": 14966, - "progression": 14967, - "##ddy": 14968, - "blunt": 14969, - "announce": 14970, - "##far": 14971, - "implementing": 14972, - "##lav": 14973, - "aggression": 14974, - "liaison": 14975, - "cooler": 14976, - "cares": 14977, - "headache": 14978, - "plantations": 14979, - "gorge": 14980, - "dots": 14981, - "impulse": 14982, - "thickness": 14983, - "ashamed": 14984, - "averaging": 14985, - "kathy": 14986, - "obligation": 14987, - "precursor": 14988, - "137": 14989, - "fowler": 14990, - "symmetry": 14991, - "thee": 14992, - "225": 14993, - "hears": 14994, - "##rai": 14995, - "undergoing": 14996, - "ads": 14997, - "butcher": 14998, - "bowler": 14999, - "##lip": 15000, - "cigarettes": 15001, - "subscription": 15002, - "goodness": 15003, - "##ically": 15004, - "browne": 15005, - "##hos": 15006, - "##tech": 15007, - "kyoto": 15008, - "donor": 15009, - "##erty": 15010, - "damaging": 15011, - "friction": 15012, - "drifting": 15013, - "expeditions": 15014, - "hardened": 15015, - "prostitution": 15016, - "152": 15017, - "fauna": 15018, - "blankets": 15019, - "claw": 15020, - "tossing": 15021, - "snarled": 15022, - "butterflies": 15023, - "recruits": 15024, - "investigative": 15025, - "coated": 15026, - "healed": 15027, - "138": 15028, - "communal": 15029, - "hai": 15030, - "xiii": 15031, - "academics": 15032, - "boone": 15033, - "psychologist": 15034, - "restless": 15035, - "lahore": 15036, - "stephens": 15037, - "mba": 15038, - "brendan": 15039, - "foreigners": 15040, - "printer": 15041, - "##pc": 15042, - "ached": 15043, - "explode": 15044, - "27th": 15045, - "deed": 15046, - "scratched": 15047, - "dared": 15048, - "##pole": 15049, - "cardiac": 15050, - "1780": 15051, - "okinawa": 15052, - "proto": 15053, - "commando": 15054, - "compelled": 15055, - "oddly": 15056, - "electrons": 15057, - "##base": 15058, - "replica": 15059, - "thanksgiving": 15060, - "##rist": 15061, - "sheila": 15062, - "deliberate": 15063, - "stafford": 15064, - "tidal": 15065, - "representations": 15066, - "hercules": 15067, - "ou": 15068, - "##path": 15069, - "##iated": 15070, - "kidnapping": 15071, - "lenses": 15072, - "##tling": 15073, - "deficit": 15074, - "samoa": 15075, - "mouths": 15076, - "consuming": 15077, - "computational": 15078, - "maze": 15079, - "granting": 15080, - "smirk": 15081, - "razor": 15082, - "fixture": 15083, - "ideals": 15084, - "inviting": 15085, - "aiden": 15086, - "nominal": 15087, - "##vs": 15088, - "issuing": 15089, - "julio": 15090, - "pitt": 15091, - "ramsey": 15092, - "docks": 15093, - "##oss": 15094, - "exhaust": 15095, - "##owed": 15096, - "bavarian": 15097, - "draped": 15098, - "anterior": 15099, - "mating": 15100, - "ethiopian": 15101, - "explores": 15102, - "noticing": 15103, - "##nton": 15104, - "discarded": 15105, - "convenience": 15106, - "hoffman": 15107, - "endowment": 15108, - "beasts": 15109, - "cartridge": 15110, - "mormon": 15111, - "paternal": 15112, - "probe": 15113, - "sleeves": 15114, - "interfere": 15115, - "lump": 15116, - "deadline": 15117, - "##rail": 15118, - "jenks": 15119, - "bulldogs": 15120, - "scrap": 15121, - "alternating": 15122, - "justified": 15123, - "reproductive": 15124, - "nam": 15125, - "seize": 15126, - "descending": 15127, - "secretariat": 15128, - "kirby": 15129, - "coupe": 15130, - "grouped": 15131, - "smash": 15132, - "panther": 15133, - "sedan": 15134, - "tapping": 15135, - "##18": 15136, - "lola": 15137, - "cheer": 15138, - "germanic": 15139, - "unfortunate": 15140, - "##eter": 15141, - "unrelated": 15142, - "##fan": 15143, - "subordinate": 15144, - "##sdale": 15145, - "suzanne": 15146, - "advertisement": 15147, - "##ility": 15148, - "horsepower": 15149, - "##lda": 15150, - "cautiously": 15151, - "discourse": 15152, - "luigi": 15153, - "##mans": 15154, - "##fields": 15155, - "noun": 15156, - "prevalent": 15157, - "mao": 15158, - "schneider": 15159, - "everett": 15160, - "surround": 15161, - "governorate": 15162, - "kira": 15163, - "##avia": 15164, - "westward": 15165, - "##take": 15166, - "misty": 15167, - "rails": 15168, - "sustainability": 15169, - "134": 15170, - "unused": 15171, - "##rating": 15172, - "packs": 15173, - "toast": 15174, - "unwilling": 15175, - "regulate": 15176, - "thy": 15177, - "suffrage": 15178, - "nile": 15179, - "awe": 15180, - "assam": 15181, - "definitions": 15182, - "travelers": 15183, - "affordable": 15184, - "##rb": 15185, - "conferred": 15186, - "sells": 15187, - "undefeated": 15188, - "beneficial": 15189, - "torso": 15190, - "basal": 15191, - "repeating": 15192, - "remixes": 15193, - "##pass": 15194, - "bahrain": 15195, - "cables": 15196, - "fang": 15197, - "##itated": 15198, - "excavated": 15199, - "numbering": 15200, - "statutory": 15201, - "##rey": 15202, - "deluxe": 15203, - "##lian": 15204, - "forested": 15205, - "ramirez": 15206, - "derbyshire": 15207, - "zeus": 15208, - "slamming": 15209, - "transfers": 15210, - "astronomer": 15211, - "banana": 15212, - "lottery": 15213, - "berg": 15214, - "histories": 15215, - "bamboo": 15216, - "##uchi": 15217, - "resurrection": 15218, - "posterior": 15219, - "bowls": 15220, - "vaguely": 15221, - "##thi": 15222, - "thou": 15223, - "preserving": 15224, - "tensed": 15225, - "offence": 15226, - "##inas": 15227, - "meyrick": 15228, - "callum": 15229, - "ridden": 15230, - "watt": 15231, - "langdon": 15232, - "tying": 15233, - "lowland": 15234, - "snorted": 15235, - "daring": 15236, - "truman": 15237, - "##hale": 15238, - "##girl": 15239, - "aura": 15240, - "overly": 15241, - "filing": 15242, - "weighing": 15243, - "goa": 15244, - "infections": 15245, - "philanthropist": 15246, - "saunders": 15247, - "eponymous": 15248, - "##owski": 15249, - "latitude": 15250, - "perspectives": 15251, - "reviewing": 15252, - "mets": 15253, - "commandant": 15254, - "radial": 15255, - "##kha": 15256, - "flashlight": 15257, - "reliability": 15258, - "koch": 15259, - "vowels": 15260, - "amazed": 15261, - "ada": 15262, - "elaine": 15263, - "supper": 15264, - "##rth": 15265, - "##encies": 15266, - "predator": 15267, - "debated": 15268, - "soviets": 15269, - "cola": 15270, - "##boards": 15271, - "##nah": 15272, - "compartment": 15273, - "crooked": 15274, - "arbitrary": 15275, - "fourteenth": 15276, - "##ctive": 15277, - "havana": 15278, - "majors": 15279, - "steelers": 15280, - "clips": 15281, - "profitable": 15282, - "ambush": 15283, - "exited": 15284, - "packers": 15285, - "##tile": 15286, - "nude": 15287, - "cracks": 15288, - "fungi": 15289, - "##е": 15290, - "limb": 15291, - "trousers": 15292, - "josie": 15293, - "shelby": 15294, - "tens": 15295, - "frederic": 15296, - "##ος": 15297, - "definite": 15298, - "smoothly": 15299, - "constellation": 15300, - "insult": 15301, - "baton": 15302, - "discs": 15303, - "lingering": 15304, - "##nco": 15305, - "conclusions": 15306, - "lent": 15307, - "staging": 15308, - "becker": 15309, - "grandpa": 15310, - "shaky": 15311, - "##tron": 15312, - "einstein": 15313, - "obstacles": 15314, - "sk": 15315, - "adverse": 15316, - "elle": 15317, - "economically": 15318, - "##moto": 15319, - "mccartney": 15320, - "thor": 15321, - "dismissal": 15322, - "motions": 15323, - "readings": 15324, - "nostrils": 15325, - "treatise": 15326, - "##pace": 15327, - "squeezing": 15328, - "evidently": 15329, - "prolonged": 15330, - "1783": 15331, - "venezuelan": 15332, - "je": 15333, - "marguerite": 15334, - "beirut": 15335, - "takeover": 15336, - "shareholders": 15337, - "##vent": 15338, - "denise": 15339, - "digit": 15340, - "airplay": 15341, - "norse": 15342, - "##bbling": 15343, - "imaginary": 15344, - "pills": 15345, - "hubert": 15346, - "blaze": 15347, - "vacated": 15348, - "eliminating": 15349, - "##ello": 15350, - "vine": 15351, - "mansfield": 15352, - "##tty": 15353, - "retrospective": 15354, - "barrow": 15355, - "borne": 15356, - "clutch": 15357, - "bail": 15358, - "forensic": 15359, - "weaving": 15360, - "##nett": 15361, - "##witz": 15362, - "desktop": 15363, - "citadel": 15364, - "promotions": 15365, - "worrying": 15366, - "dorset": 15367, - "ieee": 15368, - "subdivided": 15369, - "##iating": 15370, - "manned": 15371, - "expeditionary": 15372, - "pickup": 15373, - "synod": 15374, - "chuckle": 15375, - "185": 15376, - "barney": 15377, - "##rz": 15378, - "##ffin": 15379, - "functionality": 15380, - "karachi": 15381, - "litigation": 15382, - "meanings": 15383, - "uc": 15384, - "lick": 15385, - "turbo": 15386, - "anders": 15387, - "##ffed": 15388, - "execute": 15389, - "curl": 15390, - "oppose": 15391, - "ankles": 15392, - "typhoon": 15393, - "##د": 15394, - "##ache": 15395, - "##asia": 15396, - "linguistics": 15397, - "compassion": 15398, - "pressures": 15399, - "grazing": 15400, - "perfection": 15401, - "##iting": 15402, - "immunity": 15403, - "monopoly": 15404, - "muddy": 15405, - "backgrounds": 15406, - "136": 15407, - "namibia": 15408, - "francesca": 15409, - "monitors": 15410, - "attracting": 15411, - "stunt": 15412, - "tuition": 15413, - "##ии": 15414, - "vegetable": 15415, - "##mates": 15416, - "##quent": 15417, - "mgm": 15418, - "jen": 15419, - "complexes": 15420, - "forts": 15421, - "##ond": 15422, - "cellar": 15423, - "bites": 15424, - "seventeenth": 15425, - "royals": 15426, - "flemish": 15427, - "failures": 15428, - "mast": 15429, - "charities": 15430, - "##cular": 15431, - "peruvian": 15432, - "capitals": 15433, - "macmillan": 15434, - "ipswich": 15435, - "outward": 15436, - "frigate": 15437, - "postgraduate": 15438, - "folds": 15439, - "employing": 15440, - "##ouse": 15441, - "concurrently": 15442, - "fiery": 15443, - "##tai": 15444, - "contingent": 15445, - "nightmares": 15446, - "monumental": 15447, - "nicaragua": 15448, - "##kowski": 15449, - "lizard": 15450, - "mal": 15451, - "fielding": 15452, - "gig": 15453, - "reject": 15454, - "##pad": 15455, - "harding": 15456, - "##ipe": 15457, - "coastline": 15458, - "##cin": 15459, - "##nos": 15460, - "beethoven": 15461, - "humphrey": 15462, - "innovations": 15463, - "##tam": 15464, - "##nge": 15465, - "norris": 15466, - "doris": 15467, - "solicitor": 15468, - "huang": 15469, - "obey": 15470, - "141": 15471, - "##lc": 15472, - "niagara": 15473, - "##tton": 15474, - "shelves": 15475, - "aug": 15476, - "bourbon": 15477, - "curry": 15478, - "nightclub": 15479, - "specifications": 15480, - "hilton": 15481, - "##ndo": 15482, - "centennial": 15483, - "dispersed": 15484, - "worm": 15485, - "neglected": 15486, - "briggs": 15487, - "sm": 15488, - "font": 15489, - "kuala": 15490, - "uneasy": 15491, - "plc": 15492, - "##nstein": 15493, - "##bound": 15494, - "##aking": 15495, - "##burgh": 15496, - "awaiting": 15497, - "pronunciation": 15498, - "##bbed": 15499, - "##quest": 15500, - "eh": 15501, - "optimal": 15502, - "zhu": 15503, - "raped": 15504, - "greens": 15505, - "presided": 15506, - "brenda": 15507, - "worries": 15508, - "##life": 15509, - "venetian": 15510, - "marxist": 15511, - "turnout": 15512, - "##lius": 15513, - "refined": 15514, - "braced": 15515, - "sins": 15516, - "grasped": 15517, - "sunderland": 15518, - "nickel": 15519, - "speculated": 15520, - "lowell": 15521, - "cyrillic": 15522, - "communism": 15523, - "fundraising": 15524, - "resembling": 15525, - "colonists": 15526, - "mutant": 15527, - "freddie": 15528, - "usc": 15529, - "##mos": 15530, - "gratitude": 15531, - "##run": 15532, - "mural": 15533, - "##lous": 15534, - "chemist": 15535, - "wi": 15536, - "reminds": 15537, - "28th": 15538, - "steals": 15539, - "tess": 15540, - "pietro": 15541, - "##ingen": 15542, - "promoter": 15543, - "ri": 15544, - "microphone": 15545, - "honoured": 15546, - "rai": 15547, - "sant": 15548, - "##qui": 15549, - "feather": 15550, - "##nson": 15551, - "burlington": 15552, - "kurdish": 15553, - "terrorists": 15554, - "deborah": 15555, - "sickness": 15556, - "##wed": 15557, - "##eet": 15558, - "hazard": 15559, - "irritated": 15560, - "desperation": 15561, - "veil": 15562, - "clarity": 15563, - "##rik": 15564, - "jewels": 15565, - "xv": 15566, - "##gged": 15567, - "##ows": 15568, - "##cup": 15569, - "berkshire": 15570, - "unfair": 15571, - "mysteries": 15572, - "orchid": 15573, - "winced": 15574, - "exhaustion": 15575, - "renovations": 15576, - "stranded": 15577, - "obe": 15578, - "infinity": 15579, - "##nies": 15580, - "adapt": 15581, - "redevelopment": 15582, - "thanked": 15583, - "registry": 15584, - "olga": 15585, - "domingo": 15586, - "noir": 15587, - "tudor": 15588, - "ole": 15589, - "##atus": 15590, - "commenting": 15591, - "behaviors": 15592, - "##ais": 15593, - "crisp": 15594, - "pauline": 15595, - "probable": 15596, - "stirling": 15597, - "wigan": 15598, - "##bian": 15599, - "paralympics": 15600, - "panting": 15601, - "surpassed": 15602, - "##rew": 15603, - "luca": 15604, - "barred": 15605, - "pony": 15606, - "famed": 15607, - "##sters": 15608, - "cassandra": 15609, - "waiter": 15610, - "carolyn": 15611, - "exported": 15612, - "##orted": 15613, - "andres": 15614, - "destructive": 15615, - "deeds": 15616, - "jonah": 15617, - "castles": 15618, - "vacancy": 15619, - "suv": 15620, - "##glass": 15621, - "1788": 15622, - "orchard": 15623, - "yep": 15624, - "famine": 15625, - "belarusian": 15626, - "sprang": 15627, - "##forth": 15628, - "skinny": 15629, - "##mis": 15630, - "administrators": 15631, - "rotterdam": 15632, - "zambia": 15633, - "zhao": 15634, - "boiler": 15635, - "discoveries": 15636, - "##ride": 15637, - "##physics": 15638, - "lucius": 15639, - "disappointing": 15640, - "outreach": 15641, - "spoon": 15642, - "##frame": 15643, - "qualifications": 15644, - "unanimously": 15645, - "enjoys": 15646, - "regency": 15647, - "##iidae": 15648, - "stade": 15649, - "realism": 15650, - "veterinary": 15651, - "rodgers": 15652, - "dump": 15653, - "alain": 15654, - "chestnut": 15655, - "castile": 15656, - "censorship": 15657, - "rumble": 15658, - "gibbs": 15659, - "##itor": 15660, - "communion": 15661, - "reggae": 15662, - "inactivated": 15663, - "logs": 15664, - "loads": 15665, - "##houses": 15666, - "homosexual": 15667, - "##iano": 15668, - "ale": 15669, - "informs": 15670, - "##cas": 15671, - "phrases": 15672, - "plaster": 15673, - "linebacker": 15674, - "ambrose": 15675, - "kaiser": 15676, - "fascinated": 15677, - "850": 15678, - "limerick": 15679, - "recruitment": 15680, - "forge": 15681, - "mastered": 15682, - "##nding": 15683, - "leinster": 15684, - "rooted": 15685, - "threaten": 15686, - "##strom": 15687, - "borneo": 15688, - "##hes": 15689, - "suggestions": 15690, - "scholarships": 15691, - "propeller": 15692, - "documentaries": 15693, - "patronage": 15694, - "coats": 15695, - "constructing": 15696, - "invest": 15697, - "neurons": 15698, - "comet": 15699, - "entirety": 15700, - "shouts": 15701, - "identities": 15702, - "annoying": 15703, - "unchanged": 15704, - "wary": 15705, - "##antly": 15706, - "##ogy": 15707, - "neat": 15708, - "oversight": 15709, - "##kos": 15710, - "phillies": 15711, - "replay": 15712, - "constance": 15713, - "##kka": 15714, - "incarnation": 15715, - "humble": 15716, - "skies": 15717, - "minus": 15718, - "##acy": 15719, - "smithsonian": 15720, - "##chel": 15721, - "guerrilla": 15722, - "jar": 15723, - "cadets": 15724, - "##plate": 15725, - "surplus": 15726, - "audit": 15727, - "##aru": 15728, - "cracking": 15729, - "joanna": 15730, - "louisa": 15731, - "pacing": 15732, - "##lights": 15733, - "intentionally": 15734, - "##iri": 15735, - "diner": 15736, - "nwa": 15737, - "imprint": 15738, - "australians": 15739, - "tong": 15740, - "unprecedented": 15741, - "bunker": 15742, - "naive": 15743, - "specialists": 15744, - "ark": 15745, - "nichols": 15746, - "railing": 15747, - "leaked": 15748, - "pedal": 15749, - "##uka": 15750, - "shrub": 15751, - "longing": 15752, - "roofs": 15753, - "v8": 15754, - "captains": 15755, - "neural": 15756, - "tuned": 15757, - "##ntal": 15758, - "##jet": 15759, - "emission": 15760, - "medina": 15761, - "frantic": 15762, - "codex": 15763, - "definitive": 15764, - "sid": 15765, - "abolition": 15766, - "intensified": 15767, - "stocks": 15768, - "enrique": 15769, - "sustain": 15770, - "genoa": 15771, - "oxide": 15772, - "##written": 15773, - "clues": 15774, - "cha": 15775, - "##gers": 15776, - "tributaries": 15777, - "fragment": 15778, - "venom": 15779, - "##rity": 15780, - "##ente": 15781, - "##sca": 15782, - "muffled": 15783, - "vain": 15784, - "sire": 15785, - "laos": 15786, - "##ingly": 15787, - "##hana": 15788, - "hastily": 15789, - "snapping": 15790, - "surfaced": 15791, - "sentiment": 15792, - "motive": 15793, - "##oft": 15794, - "contests": 15795, - "approximate": 15796, - "mesa": 15797, - "luckily": 15798, - "dinosaur": 15799, - "exchanges": 15800, - "propelled": 15801, - "accord": 15802, - "bourne": 15803, - "relieve": 15804, - "tow": 15805, - "masks": 15806, - "offended": 15807, - "##ues": 15808, - "cynthia": 15809, - "##mmer": 15810, - "rains": 15811, - "bartender": 15812, - "zinc": 15813, - "reviewers": 15814, - "lois": 15815, - "##sai": 15816, - "legged": 15817, - "arrogant": 15818, - "rafe": 15819, - "rosie": 15820, - "comprise": 15821, - "handicap": 15822, - "blockade": 15823, - "inlet": 15824, - "lagoon": 15825, - "copied": 15826, - "drilling": 15827, - "shelley": 15828, - "petals": 15829, - "##inian": 15830, - "mandarin": 15831, - "obsolete": 15832, - "##inated": 15833, - "onward": 15834, - "arguably": 15835, - "productivity": 15836, - "cindy": 15837, - "praising": 15838, - "seldom": 15839, - "busch": 15840, - "discusses": 15841, - "raleigh": 15842, - "shortage": 15843, - "ranged": 15844, - "stanton": 15845, - "encouragement": 15846, - "firstly": 15847, - "conceded": 15848, - "overs": 15849, - "temporal": 15850, - "##uke": 15851, - "cbe": 15852, - "##bos": 15853, - "woo": 15854, - "certainty": 15855, - "pumps": 15856, - "##pton": 15857, - "stalked": 15858, - "##uli": 15859, - "lizzie": 15860, - "periodic": 15861, - "thieves": 15862, - "weaker": 15863, - "##night": 15864, - "gases": 15865, - "shoving": 15866, - "chooses": 15867, - "wc": 15868, - "##chemical": 15869, - "prompting": 15870, - "weights": 15871, - "##kill": 15872, - "robust": 15873, - "flanked": 15874, - "sticky": 15875, - "hu": 15876, - "tuberculosis": 15877, - "##eb": 15878, - "##eal": 15879, - "christchurch": 15880, - "resembled": 15881, - "wallet": 15882, - "reese": 15883, - "inappropriate": 15884, - "pictured": 15885, - "distract": 15886, - "fixing": 15887, - "fiddle": 15888, - "giggled": 15889, - "burger": 15890, - "heirs": 15891, - "hairy": 15892, - "mechanic": 15893, - "torque": 15894, - "apache": 15895, - "obsessed": 15896, - "chiefly": 15897, - "cheng": 15898, - "logging": 15899, - "##tag": 15900, - "extracted": 15901, - "meaningful": 15902, - "numb": 15903, - "##vsky": 15904, - "gloucestershire": 15905, - "reminding": 15906, - "##bay": 15907, - "unite": 15908, - "##lit": 15909, - "breeds": 15910, - "diminished": 15911, - "clown": 15912, - "glove": 15913, - "1860s": 15914, - "##ن": 15915, - "##ug": 15916, - "archibald": 15917, - "focal": 15918, - "freelance": 15919, - "sliced": 15920, - "depiction": 15921, - "##yk": 15922, - "organism": 15923, - "switches": 15924, - "sights": 15925, - "stray": 15926, - "crawling": 15927, - "##ril": 15928, - "lever": 15929, - "leningrad": 15930, - "interpretations": 15931, - "loops": 15932, - "anytime": 15933, - "reel": 15934, - "alicia": 15935, - "delighted": 15936, - "##ech": 15937, - "inhaled": 15938, - "xiv": 15939, - "suitcase": 15940, - "bernie": 15941, - "vega": 15942, - "licenses": 15943, - "northampton": 15944, - "exclusion": 15945, - "induction": 15946, - "monasteries": 15947, - "racecourse": 15948, - "homosexuality": 15949, - "##right": 15950, - "##sfield": 15951, - "##rky": 15952, - "dimitri": 15953, - "michele": 15954, - "alternatives": 15955, - "ions": 15956, - "commentators": 15957, - "genuinely": 15958, - "objected": 15959, - "pork": 15960, - "hospitality": 15961, - "fencing": 15962, - "stephan": 15963, - "warships": 15964, - "peripheral": 15965, - "wit": 15966, - "drunken": 15967, - "wrinkled": 15968, - "quentin": 15969, - "spends": 15970, - "departing": 15971, - "chung": 15972, - "numerical": 15973, - "spokesperson": 15974, - "##zone": 15975, - "johannesburg": 15976, - "caliber": 15977, - "killers": 15978, - "##udge": 15979, - "assumes": 15980, - "neatly": 15981, - "demographic": 15982, - "abigail": 15983, - "bloc": 15984, - "##vel": 15985, - "mounting": 15986, - "##lain": 15987, - "bentley": 15988, - "slightest": 15989, - "xu": 15990, - "recipients": 15991, - "##jk": 15992, - "merlin": 15993, - "##writer": 15994, - "seniors": 15995, - "prisons": 15996, - "blinking": 15997, - "hindwings": 15998, - "flickered": 15999, - "kappa": 16000, - "##hel": 16001, - "80s": 16002, - "strengthening": 16003, - "appealing": 16004, - "brewing": 16005, - "gypsy": 16006, - "mali": 16007, - "lashes": 16008, - "hulk": 16009, - "unpleasant": 16010, - "harassment": 16011, - "bio": 16012, - "treaties": 16013, - "predict": 16014, - "instrumentation": 16015, - "pulp": 16016, - "troupe": 16017, - "boiling": 16018, - "mantle": 16019, - "##ffe": 16020, - "ins": 16021, - "##vn": 16022, - "dividing": 16023, - "handles": 16024, - "verbs": 16025, - "##onal": 16026, - "coconut": 16027, - "senegal": 16028, - "340": 16029, - "thorough": 16030, - "gum": 16031, - "momentarily": 16032, - "##sto": 16033, - "cocaine": 16034, - "panicked": 16035, - "destined": 16036, - "##turing": 16037, - "teatro": 16038, - "denying": 16039, - "weary": 16040, - "captained": 16041, - "mans": 16042, - "##hawks": 16043, - "##code": 16044, - "wakefield": 16045, - "bollywood": 16046, - "thankfully": 16047, - "##16": 16048, - "cyril": 16049, - "##wu": 16050, - "amendments": 16051, - "##bahn": 16052, - "consultation": 16053, - "stud": 16054, - "reflections": 16055, - "kindness": 16056, - "1787": 16057, - "internally": 16058, - "##ovo": 16059, - "tex": 16060, - "mosaic": 16061, - "distribute": 16062, - "paddy": 16063, - "seeming": 16064, - "143": 16065, - "##hic": 16066, - "piers": 16067, - "##15": 16068, - "##mura": 16069, - "##verse": 16070, - "popularly": 16071, - "winger": 16072, - "kang": 16073, - "sentinel": 16074, - "mccoy": 16075, - "##anza": 16076, - "covenant": 16077, - "##bag": 16078, - "verge": 16079, - "fireworks": 16080, - "suppress": 16081, - "thrilled": 16082, - "dominate": 16083, - "##jar": 16084, - "swansea": 16085, - "##60": 16086, - "142": 16087, - "reconciliation": 16088, - "##ndi": 16089, - "stiffened": 16090, - "cue": 16091, - "dorian": 16092, - "##uf": 16093, - "damascus": 16094, - "amor": 16095, - "ida": 16096, - "foremost": 16097, - "##aga": 16098, - "porsche": 16099, - "unseen": 16100, - "dir": 16101, - "##had": 16102, - "##azi": 16103, - "stony": 16104, - "lexi": 16105, - "melodies": 16106, - "##nko": 16107, - "angular": 16108, - "integer": 16109, - "podcast": 16110, - "ants": 16111, - "inherent": 16112, - "jaws": 16113, - "justify": 16114, - "persona": 16115, - "##olved": 16116, - "josephine": 16117, - "##nr": 16118, - "##ressed": 16119, - "customary": 16120, - "flashes": 16121, - "gala": 16122, - "cyrus": 16123, - "glaring": 16124, - "backyard": 16125, - "ariel": 16126, - "physiology": 16127, - "greenland": 16128, - "html": 16129, - "stir": 16130, - "avon": 16131, - "atletico": 16132, - "finch": 16133, - "methodology": 16134, - "ked": 16135, - "##lent": 16136, - "mas": 16137, - "catholicism": 16138, - "townsend": 16139, - "branding": 16140, - "quincy": 16141, - "fits": 16142, - "containers": 16143, - "1777": 16144, - "ashore": 16145, - "aragon": 16146, - "##19": 16147, - "forearm": 16148, - "poisoning": 16149, - "##sd": 16150, - "adopting": 16151, - "conquer": 16152, - "grinding": 16153, - "amnesty": 16154, - "keller": 16155, - "finances": 16156, - "evaluate": 16157, - "forged": 16158, - "lankan": 16159, - "instincts": 16160, - "##uto": 16161, - "guam": 16162, - "bosnian": 16163, - "photographed": 16164, - "workplace": 16165, - "desirable": 16166, - "protector": 16167, - "##dog": 16168, - "allocation": 16169, - "intently": 16170, - "encourages": 16171, - "willy": 16172, - "##sten": 16173, - "bodyguard": 16174, - "electro": 16175, - "brighter": 16176, - "##ν": 16177, - "bihar": 16178, - "##chev": 16179, - "lasts": 16180, - "opener": 16181, - "amphibious": 16182, - "sal": 16183, - "verde": 16184, - "arte": 16185, - "##cope": 16186, - "captivity": 16187, - "vocabulary": 16188, - "yields": 16189, - "##tted": 16190, - "agreeing": 16191, - "desmond": 16192, - "pioneered": 16193, - "##chus": 16194, - "strap": 16195, - "campaigned": 16196, - "railroads": 16197, - "##ович": 16198, - "emblem": 16199, - "##dre": 16200, - "stormed": 16201, - "501": 16202, - "##ulous": 16203, - "marijuana": 16204, - "northumberland": 16205, - "##gn": 16206, - "##nath": 16207, - "bowen": 16208, - "landmarks": 16209, - "beaumont": 16210, - "##qua": 16211, - "danube": 16212, - "##bler": 16213, - "attorneys": 16214, - "th": 16215, - "ge": 16216, - "flyers": 16217, - "critique": 16218, - "villains": 16219, - "cass": 16220, - "mutation": 16221, - "acc": 16222, - "##0s": 16223, - "colombo": 16224, - "mckay": 16225, - "motif": 16226, - "sampling": 16227, - "concluding": 16228, - "syndicate": 16229, - "##rell": 16230, - "neon": 16231, - "stables": 16232, - "ds": 16233, - "warnings": 16234, - "clint": 16235, - "mourning": 16236, - "wilkinson": 16237, - "##tated": 16238, - "merrill": 16239, - "leopard": 16240, - "evenings": 16241, - "exhaled": 16242, - "emil": 16243, - "sonia": 16244, - "ezra": 16245, - "discrete": 16246, - "stove": 16247, - "farrell": 16248, - "fifteenth": 16249, - "prescribed": 16250, - "superhero": 16251, - "##rier": 16252, - "worms": 16253, - "helm": 16254, - "wren": 16255, - "##duction": 16256, - "##hc": 16257, - "expo": 16258, - "##rator": 16259, - "hq": 16260, - "unfamiliar": 16261, - "antony": 16262, - "prevents": 16263, - "acceleration": 16264, - "fiercely": 16265, - "mari": 16266, - "painfully": 16267, - "calculations": 16268, - "cheaper": 16269, - "ign": 16270, - "clifton": 16271, - "irvine": 16272, - "davenport": 16273, - "mozambique": 16274, - "##np": 16275, - "pierced": 16276, - "##evich": 16277, - "wonders": 16278, - "##wig": 16279, - "##cate": 16280, - "##iling": 16281, - "crusade": 16282, - "ware": 16283, - "##uel": 16284, - "enzymes": 16285, - "reasonably": 16286, - "mls": 16287, - "##coe": 16288, - "mater": 16289, - "ambition": 16290, - "bunny": 16291, - "eliot": 16292, - "kernel": 16293, - "##fin": 16294, - "asphalt": 16295, - "headmaster": 16296, - "torah": 16297, - "aden": 16298, - "lush": 16299, - "pins": 16300, - "waived": 16301, - "##care": 16302, - "##yas": 16303, - "joao": 16304, - "substrate": 16305, - "enforce": 16306, - "##grad": 16307, - "##ules": 16308, - "alvarez": 16309, - "selections": 16310, - "epidemic": 16311, - "tempted": 16312, - "##bit": 16313, - "bremen": 16314, - "translates": 16315, - "ensured": 16316, - "waterfront": 16317, - "29th": 16318, - "forrest": 16319, - "manny": 16320, - "malone": 16321, - "kramer": 16322, - "reigning": 16323, - "cookies": 16324, - "simpler": 16325, - "absorption": 16326, - "205": 16327, - "engraved": 16328, - "##ffy": 16329, - "evaluated": 16330, - "1778": 16331, - "haze": 16332, - "146": 16333, - "comforting": 16334, - "crossover": 16335, - "##abe": 16336, - "thorn": 16337, - "##rift": 16338, - "##imo": 16339, - "##pop": 16340, - "suppression": 16341, - "fatigue": 16342, - "cutter": 16343, - "##tr": 16344, - "201": 16345, - "wurttemberg": 16346, - "##orf": 16347, - "enforced": 16348, - "hovering": 16349, - "proprietary": 16350, - "gb": 16351, - "samurai": 16352, - "syllable": 16353, - "ascent": 16354, - "lacey": 16355, - "tick": 16356, - "lars": 16357, - "tractor": 16358, - "merchandise": 16359, - "rep": 16360, - "bouncing": 16361, - "defendants": 16362, - "##yre": 16363, - "huntington": 16364, - "##ground": 16365, - "##oko": 16366, - "standardized": 16367, - "##hor": 16368, - "##hima": 16369, - "assassinated": 16370, - "nu": 16371, - "predecessors": 16372, - "rainy": 16373, - "liar": 16374, - "assurance": 16375, - "lyrical": 16376, - "##uga": 16377, - "secondly": 16378, - "flattened": 16379, - "ios": 16380, - "parameter": 16381, - "undercover": 16382, - "##mity": 16383, - "bordeaux": 16384, - "punish": 16385, - "ridges": 16386, - "markers": 16387, - "exodus": 16388, - "inactive": 16389, - "hesitate": 16390, - "debbie": 16391, - "nyc": 16392, - "pledge": 16393, - "savoy": 16394, - "nagar": 16395, - "offset": 16396, - "organist": 16397, - "##tium": 16398, - "hesse": 16399, - "marin": 16400, - "converting": 16401, - "##iver": 16402, - "diagram": 16403, - "propulsion": 16404, - "pu": 16405, - "validity": 16406, - "reverted": 16407, - "supportive": 16408, - "##dc": 16409, - "ministries": 16410, - "clans": 16411, - "responds": 16412, - "proclamation": 16413, - "##inae": 16414, - "##ø": 16415, - "##rea": 16416, - "ein": 16417, - "pleading": 16418, - "patriot": 16419, - "sf": 16420, - "birch": 16421, - "islanders": 16422, - "strauss": 16423, - "hates": 16424, - "##dh": 16425, - "brandenburg": 16426, - "concession": 16427, - "rd": 16428, - "##ob": 16429, - "1900s": 16430, - "killings": 16431, - "textbook": 16432, - "antiquity": 16433, - "cinematography": 16434, - "wharf": 16435, - "embarrassing": 16436, - "setup": 16437, - "creed": 16438, - "farmland": 16439, - "inequality": 16440, - "centred": 16441, - "signatures": 16442, - "fallon": 16443, - "370": 16444, - "##ingham": 16445, - "##uts": 16446, - "ceylon": 16447, - "gazing": 16448, - "directive": 16449, - "laurie": 16450, - "##tern": 16451, - "globally": 16452, - "##uated": 16453, - "##dent": 16454, - "allah": 16455, - "excavation": 16456, - "threads": 16457, - "##cross": 16458, - "148": 16459, - "frantically": 16460, - "icc": 16461, - "utilize": 16462, - "determines": 16463, - "respiratory": 16464, - "thoughtful": 16465, - "receptions": 16466, - "##dicate": 16467, - "merging": 16468, - "chandra": 16469, - "seine": 16470, - "147": 16471, - "builders": 16472, - "builds": 16473, - "diagnostic": 16474, - "dev": 16475, - "visibility": 16476, - "goddamn": 16477, - "analyses": 16478, - "dhaka": 16479, - "cho": 16480, - "proves": 16481, - "chancel": 16482, - "concurrent": 16483, - "curiously": 16484, - "canadians": 16485, - "pumped": 16486, - "restoring": 16487, - "1850s": 16488, - "turtles": 16489, - "jaguar": 16490, - "sinister": 16491, - "spinal": 16492, - "traction": 16493, - "declan": 16494, - "vows": 16495, - "1784": 16496, - "glowed": 16497, - "capitalism": 16498, - "swirling": 16499, - "install": 16500, - "universidad": 16501, - "##lder": 16502, - "##oat": 16503, - "soloist": 16504, - "##genic": 16505, - "##oor": 16506, - "coincidence": 16507, - "beginnings": 16508, - "nissan": 16509, - "dip": 16510, - "resorts": 16511, - "caucasus": 16512, - "combustion": 16513, - "infectious": 16514, - "##eno": 16515, - "pigeon": 16516, - "serpent": 16517, - "##itating": 16518, - "conclude": 16519, - "masked": 16520, - "salad": 16521, - "jew": 16522, - "##gr": 16523, - "surreal": 16524, - "toni": 16525, - "##wc": 16526, - "harmonica": 16527, - "151": 16528, - "##gins": 16529, - "##etic": 16530, - "##coat": 16531, - "fishermen": 16532, - "intending": 16533, - "bravery": 16534, - "##wave": 16535, - "klaus": 16536, - "titan": 16537, - "wembley": 16538, - "taiwanese": 16539, - "ransom": 16540, - "40th": 16541, - "incorrect": 16542, - "hussein": 16543, - "eyelids": 16544, - "jp": 16545, - "cooke": 16546, - "dramas": 16547, - "utilities": 16548, - "##etta": 16549, - "##print": 16550, - "eisenhower": 16551, - "principally": 16552, - "granada": 16553, - "lana": 16554, - "##rak": 16555, - "openings": 16556, - "concord": 16557, - "##bl": 16558, - "bethany": 16559, - "connie": 16560, - "morality": 16561, - "sega": 16562, - "##mons": 16563, - "##nard": 16564, - "earnings": 16565, - "##kara": 16566, - "##cine": 16567, - "wii": 16568, - "communes": 16569, - "##rel": 16570, - "coma": 16571, - "composing": 16572, - "softened": 16573, - "severed": 16574, - "grapes": 16575, - "##17": 16576, - "nguyen": 16577, - "analyzed": 16578, - "warlord": 16579, - "hubbard": 16580, - "heavenly": 16581, - "behave": 16582, - "slovenian": 16583, - "##hit": 16584, - "##ony": 16585, - "hailed": 16586, - "filmmakers": 16587, - "trance": 16588, - "caldwell": 16589, - "skye": 16590, - "unrest": 16591, - "coward": 16592, - "likelihood": 16593, - "##aging": 16594, - "bern": 16595, - "sci": 16596, - "taliban": 16597, - "honolulu": 16598, - "propose": 16599, - "##wang": 16600, - "1700": 16601, - "browser": 16602, - "imagining": 16603, - "cobra": 16604, - "contributes": 16605, - "dukes": 16606, - "instinctively": 16607, - "conan": 16608, - "violinist": 16609, - "##ores": 16610, - "accessories": 16611, - "gradual": 16612, - "##amp": 16613, - "quotes": 16614, - "sioux": 16615, - "##dating": 16616, - "undertake": 16617, - "intercepted": 16618, - "sparkling": 16619, - "compressed": 16620, - "139": 16621, - "fungus": 16622, - "tombs": 16623, - "haley": 16624, - "imposing": 16625, - "rests": 16626, - "degradation": 16627, - "lincolnshire": 16628, - "retailers": 16629, - "wetlands": 16630, - "tulsa": 16631, - "distributor": 16632, - "dungeon": 16633, - "nun": 16634, - "greenhouse": 16635, - "convey": 16636, - "atlantis": 16637, - "aft": 16638, - "exits": 16639, - "oman": 16640, - "dresser": 16641, - "lyons": 16642, - "##sti": 16643, - "joking": 16644, - "eddy": 16645, - "judgement": 16646, - "omitted": 16647, - "digits": 16648, - "##cts": 16649, - "##game": 16650, - "juniors": 16651, - "##rae": 16652, - "cents": 16653, - "stricken": 16654, - "une": 16655, - "##ngo": 16656, - "wizards": 16657, - "weir": 16658, - "breton": 16659, - "nan": 16660, - "technician": 16661, - "fibers": 16662, - "liking": 16663, - "royalty": 16664, - "##cca": 16665, - "154": 16666, - "persia": 16667, - "terribly": 16668, - "magician": 16669, - "##rable": 16670, - "##unt": 16671, - "vance": 16672, - "cafeteria": 16673, - "booker": 16674, - "camille": 16675, - "warmer": 16676, - "##static": 16677, - "consume": 16678, - "cavern": 16679, - "gaps": 16680, - "compass": 16681, - "contemporaries": 16682, - "foyer": 16683, - "soothing": 16684, - "graveyard": 16685, - "maj": 16686, - "plunged": 16687, - "blush": 16688, - "##wear": 16689, - "cascade": 16690, - "demonstrates": 16691, - "ordinance": 16692, - "##nov": 16693, - "boyle": 16694, - "##lana": 16695, - "rockefeller": 16696, - "shaken": 16697, - "banjo": 16698, - "izzy": 16699, - "##ense": 16700, - "breathless": 16701, - "vines": 16702, - "##32": 16703, - "##eman": 16704, - "alterations": 16705, - "chromosome": 16706, - "dwellings": 16707, - "feudal": 16708, - "mole": 16709, - "153": 16710, - "catalonia": 16711, - "relics": 16712, - "tenant": 16713, - "mandated": 16714, - "##fm": 16715, - "fridge": 16716, - "hats": 16717, - "honesty": 16718, - "patented": 16719, - "raul": 16720, - "heap": 16721, - "cruisers": 16722, - "accusing": 16723, - "enlightenment": 16724, - "infants": 16725, - "wherein": 16726, - "chatham": 16727, - "contractors": 16728, - "zen": 16729, - "affinity": 16730, - "hc": 16731, - "osborne": 16732, - "piston": 16733, - "156": 16734, - "traps": 16735, - "maturity": 16736, - "##rana": 16737, - "lagos": 16738, - "##zal": 16739, - "peering": 16740, - "##nay": 16741, - "attendant": 16742, - "dealers": 16743, - "protocols": 16744, - "subset": 16745, - "prospects": 16746, - "biographical": 16747, - "##cre": 16748, - "artery": 16749, - "##zers": 16750, - "insignia": 16751, - "nuns": 16752, - "endured": 16753, - "##eration": 16754, - "recommend": 16755, - "schwartz": 16756, - "serbs": 16757, - "berger": 16758, - "cromwell": 16759, - "crossroads": 16760, - "##ctor": 16761, - "enduring": 16762, - "clasped": 16763, - "grounded": 16764, - "##bine": 16765, - "marseille": 16766, - "twitched": 16767, - "abel": 16768, - "choke": 16769, - "https": 16770, - "catalyst": 16771, - "moldova": 16772, - "italians": 16773, - "##tist": 16774, - "disastrous": 16775, - "wee": 16776, - "##oured": 16777, - "##nti": 16778, - "wwf": 16779, - "nope": 16780, - "##piration": 16781, - "##asa": 16782, - "expresses": 16783, - "thumbs": 16784, - "167": 16785, - "##nza": 16786, - "coca": 16787, - "1781": 16788, - "cheating": 16789, - "##ption": 16790, - "skipped": 16791, - "sensory": 16792, - "heidelberg": 16793, - "spies": 16794, - "satan": 16795, - "dangers": 16796, - "semifinal": 16797, - "202": 16798, - "bohemia": 16799, - "whitish": 16800, - "confusing": 16801, - "shipbuilding": 16802, - "relies": 16803, - "surgeons": 16804, - "landings": 16805, - "ravi": 16806, - "baku": 16807, - "moor": 16808, - "suffix": 16809, - "alejandro": 16810, - "##yana": 16811, - "litre": 16812, - "upheld": 16813, - "##unk": 16814, - "rajasthan": 16815, - "##rek": 16816, - "coaster": 16817, - "insists": 16818, - "posture": 16819, - "scenarios": 16820, - "etienne": 16821, - "favoured": 16822, - "appoint": 16823, - "transgender": 16824, - "elephants": 16825, - "poked": 16826, - "greenwood": 16827, - "defences": 16828, - "fulfilled": 16829, - "militant": 16830, - "somali": 16831, - "1758": 16832, - "chalk": 16833, - "potent": 16834, - "##ucci": 16835, - "migrants": 16836, - "wink": 16837, - "assistants": 16838, - "nos": 16839, - "restriction": 16840, - "activism": 16841, - "niger": 16842, - "##ario": 16843, - "colon": 16844, - "shaun": 16845, - "##sat": 16846, - "daphne": 16847, - "##erated": 16848, - "swam": 16849, - "congregations": 16850, - "reprise": 16851, - "considerations": 16852, - "magnet": 16853, - "playable": 16854, - "xvi": 16855, - "##р": 16856, - "overthrow": 16857, - "tobias": 16858, - "knob": 16859, - "chavez": 16860, - "coding": 16861, - "##mers": 16862, - "propped": 16863, - "katrina": 16864, - "orient": 16865, - "newcomer": 16866, - "##suke": 16867, - "temperate": 16868, - "##pool": 16869, - "farmhouse": 16870, - "interrogation": 16871, - "##vd": 16872, - "committing": 16873, - "##vert": 16874, - "forthcoming": 16875, - "strawberry": 16876, - "joaquin": 16877, - "macau": 16878, - "ponds": 16879, - "shocking": 16880, - "siberia": 16881, - "##cellular": 16882, - "chant": 16883, - "contributors": 16884, - "##nant": 16885, - "##ologists": 16886, - "sped": 16887, - "absorb": 16888, - "hail": 16889, - "1782": 16890, - "spared": 16891, - "##hore": 16892, - "barbados": 16893, - "karate": 16894, - "opus": 16895, - "originates": 16896, - "saul": 16897, - "##xie": 16898, - "evergreen": 16899, - "leaped": 16900, - "##rock": 16901, - "correlation": 16902, - "exaggerated": 16903, - "weekday": 16904, - "unification": 16905, - "bump": 16906, - "tracing": 16907, - "brig": 16908, - "afb": 16909, - "pathways": 16910, - "utilizing": 16911, - "##ners": 16912, - "mod": 16913, - "mb": 16914, - "disturbance": 16915, - "kneeling": 16916, - "##stad": 16917, - "##guchi": 16918, - "100th": 16919, - "pune": 16920, - "##thy": 16921, - "decreasing": 16922, - "168": 16923, - "manipulation": 16924, - "miriam": 16925, - "academia": 16926, - "ecosystem": 16927, - "occupational": 16928, - "rbi": 16929, - "##lem": 16930, - "rift": 16931, - "##14": 16932, - "rotary": 16933, - "stacked": 16934, - "incorporation": 16935, - "awakening": 16936, - "generators": 16937, - "guerrero": 16938, - "racist": 16939, - "##omy": 16940, - "cyber": 16941, - "derivatives": 16942, - "culminated": 16943, - "allie": 16944, - "annals": 16945, - "panzer": 16946, - "sainte": 16947, - "wikipedia": 16948, - "pops": 16949, - "zu": 16950, - "austro": 16951, - "##vate": 16952, - "algerian": 16953, - "politely": 16954, - "nicholson": 16955, - "mornings": 16956, - "educate": 16957, - "tastes": 16958, - "thrill": 16959, - "dartmouth": 16960, - "##gating": 16961, - "db": 16962, - "##jee": 16963, - "regan": 16964, - "differing": 16965, - "concentrating": 16966, - "choreography": 16967, - "divinity": 16968, - "##media": 16969, - "pledged": 16970, - "alexandre": 16971, - "routing": 16972, - "gregor": 16973, - "madeline": 16974, - "##idal": 16975, - "apocalypse": 16976, - "##hora": 16977, - "gunfire": 16978, - "culminating": 16979, - "elves": 16980, - "fined": 16981, - "liang": 16982, - "lam": 16983, - "programmed": 16984, - "tar": 16985, - "guessing": 16986, - "transparency": 16987, - "gabrielle": 16988, - "##gna": 16989, - "cancellation": 16990, - "flexibility": 16991, - "##lining": 16992, - "accession": 16993, - "shea": 16994, - "stronghold": 16995, - "nets": 16996, - "specializes": 16997, - "##rgan": 16998, - "abused": 16999, - "hasan": 17000, - "sgt": 17001, - "ling": 17002, - "exceeding": 17003, - "##₄": 17004, - "admiration": 17005, - "supermarket": 17006, - "##ark": 17007, - "photographers": 17008, - "specialised": 17009, - "tilt": 17010, - "resonance": 17011, - "hmm": 17012, - "perfume": 17013, - "380": 17014, - "sami": 17015, - "threatens": 17016, - "garland": 17017, - "botany": 17018, - "guarding": 17019, - "boiled": 17020, - "greet": 17021, - "puppy": 17022, - "russo": 17023, - "supplier": 17024, - "wilmington": 17025, - "vibrant": 17026, - "vijay": 17027, - "##bius": 17028, - "paralympic": 17029, - "grumbled": 17030, - "paige": 17031, - "faa": 17032, - "licking": 17033, - "margins": 17034, - "hurricanes": 17035, - "##gong": 17036, - "fest": 17037, - "grenade": 17038, - "ripping": 17039, - "##uz": 17040, - "counseling": 17041, - "weigh": 17042, - "##sian": 17043, - "needles": 17044, - "wiltshire": 17045, - "edison": 17046, - "costly": 17047, - "##not": 17048, - "fulton": 17049, - "tramway": 17050, - "redesigned": 17051, - "staffordshire": 17052, - "cache": 17053, - "gasping": 17054, - "watkins": 17055, - "sleepy": 17056, - "candidacy": 17057, - "##group": 17058, - "monkeys": 17059, - "timeline": 17060, - "throbbing": 17061, - "##bid": 17062, - "##sos": 17063, - "berth": 17064, - "uzbekistan": 17065, - "vanderbilt": 17066, - "bothering": 17067, - "overturned": 17068, - "ballots": 17069, - "gem": 17070, - "##iger": 17071, - "sunglasses": 17072, - "subscribers": 17073, - "hooker": 17074, - "compelling": 17075, - "ang": 17076, - "exceptionally": 17077, - "saloon": 17078, - "stab": 17079, - "##rdi": 17080, - "carla": 17081, - "terrifying": 17082, - "rom": 17083, - "##vision": 17084, - "coil": 17085, - "##oids": 17086, - "satisfying": 17087, - "vendors": 17088, - "31st": 17089, - "mackay": 17090, - "deities": 17091, - "overlooked": 17092, - "ambient": 17093, - "bahamas": 17094, - "felipe": 17095, - "olympia": 17096, - "whirled": 17097, - "botanist": 17098, - "advertised": 17099, - "tugging": 17100, - "##dden": 17101, - "disciples": 17102, - "morales": 17103, - "unionist": 17104, - "rites": 17105, - "foley": 17106, - "morse": 17107, - "motives": 17108, - "creepy": 17109, - "##₀": 17110, - "soo": 17111, - "##sz": 17112, - "bargain": 17113, - "highness": 17114, - "frightening": 17115, - "turnpike": 17116, - "tory": 17117, - "reorganization": 17118, - "##cer": 17119, - "depict": 17120, - "biographer": 17121, - "##walk": 17122, - "unopposed": 17123, - "manifesto": 17124, - "##gles": 17125, - "institut": 17126, - "emile": 17127, - "accidental": 17128, - "kapoor": 17129, - "##dam": 17130, - "kilkenny": 17131, - "cortex": 17132, - "lively": 17133, - "##13": 17134, - "romanesque": 17135, - "jain": 17136, - "shan": 17137, - "cannons": 17138, - "##ood": 17139, - "##ske": 17140, - "petrol": 17141, - "echoing": 17142, - "amalgamated": 17143, - "disappears": 17144, - "cautious": 17145, - "proposes": 17146, - "sanctions": 17147, - "trenton": 17148, - "##ر": 17149, - "flotilla": 17150, - "aus": 17151, - "contempt": 17152, - "tor": 17153, - "canary": 17154, - "cote": 17155, - "theirs": 17156, - "##hun": 17157, - "conceptual": 17158, - "deleted": 17159, - "fascinating": 17160, - "paso": 17161, - "blazing": 17162, - "elf": 17163, - "honourable": 17164, - "hutchinson": 17165, - "##eiro": 17166, - "##outh": 17167, - "##zin": 17168, - "surveyor": 17169, - "tee": 17170, - "amidst": 17171, - "wooded": 17172, - "reissue": 17173, - "intro": 17174, - "##ono": 17175, - "cobb": 17176, - "shelters": 17177, - "newsletter": 17178, - "hanson": 17179, - "brace": 17180, - "encoding": 17181, - "confiscated": 17182, - "dem": 17183, - "caravan": 17184, - "marino": 17185, - "scroll": 17186, - "melodic": 17187, - "cows": 17188, - "imam": 17189, - "##adi": 17190, - "##aneous": 17191, - "northward": 17192, - "searches": 17193, - "biodiversity": 17194, - "cora": 17195, - "310": 17196, - "roaring": 17197, - "##bers": 17198, - "connell": 17199, - "theologian": 17200, - "halo": 17201, - "compose": 17202, - "pathetic": 17203, - "unmarried": 17204, - "dynamo": 17205, - "##oot": 17206, - "az": 17207, - "calculation": 17208, - "toulouse": 17209, - "deserves": 17210, - "humour": 17211, - "nr": 17212, - "forgiveness": 17213, - "tam": 17214, - "undergone": 17215, - "martyr": 17216, - "pamela": 17217, - "myths": 17218, - "whore": 17219, - "counselor": 17220, - "hicks": 17221, - "290": 17222, - "heavens": 17223, - "battleship": 17224, - "electromagnetic": 17225, - "##bbs": 17226, - "stellar": 17227, - "establishments": 17228, - "presley": 17229, - "hopped": 17230, - "##chin": 17231, - "temptation": 17232, - "90s": 17233, - "wills": 17234, - "nas": 17235, - "##yuan": 17236, - "nhs": 17237, - "##nya": 17238, - "seminars": 17239, - "##yev": 17240, - "adaptations": 17241, - "gong": 17242, - "asher": 17243, - "lex": 17244, - "indicator": 17245, - "sikh": 17246, - "tobago": 17247, - "cites": 17248, - "goin": 17249, - "##yte": 17250, - "satirical": 17251, - "##gies": 17252, - "characterised": 17253, - "correspond": 17254, - "bubbles": 17255, - "lure": 17256, - "participates": 17257, - "##vid": 17258, - "eruption": 17259, - "skate": 17260, - "therapeutic": 17261, - "1785": 17262, - "canals": 17263, - "wholesale": 17264, - "defaulted": 17265, - "sac": 17266, - "460": 17267, - "petit": 17268, - "##zzled": 17269, - "virgil": 17270, - "leak": 17271, - "ravens": 17272, - "256": 17273, - "portraying": 17274, - "##yx": 17275, - "ghetto": 17276, - "creators": 17277, - "dams": 17278, - "portray": 17279, - "vicente": 17280, - "##rington": 17281, - "fae": 17282, - "namesake": 17283, - "bounty": 17284, - "##arium": 17285, - "joachim": 17286, - "##ota": 17287, - "##iser": 17288, - "aforementioned": 17289, - "axle": 17290, - "snout": 17291, - "depended": 17292, - "dismantled": 17293, - "reuben": 17294, - "480": 17295, - "##ibly": 17296, - "gallagher": 17297, - "##lau": 17298, - "##pd": 17299, - "earnest": 17300, - "##ieu": 17301, - "##iary": 17302, - "inflicted": 17303, - "objections": 17304, - "##llar": 17305, - "asa": 17306, - "gritted": 17307, - "##athy": 17308, - "jericho": 17309, - "##sea": 17310, - "##was": 17311, - "flick": 17312, - "underside": 17313, - "ceramics": 17314, - "undead": 17315, - "substituted": 17316, - "195": 17317, - "eastward": 17318, - "undoubtedly": 17319, - "wheeled": 17320, - "chimney": 17321, - "##iche": 17322, - "guinness": 17323, - "cb": 17324, - "##ager": 17325, - "siding": 17326, - "##bell": 17327, - "traitor": 17328, - "baptiste": 17329, - "disguised": 17330, - "inauguration": 17331, - "149": 17332, - "tipperary": 17333, - "choreographer": 17334, - "perched": 17335, - "warmed": 17336, - "stationary": 17337, - "eco": 17338, - "##ike": 17339, - "##ntes": 17340, - "bacterial": 17341, - "##aurus": 17342, - "flores": 17343, - "phosphate": 17344, - "##core": 17345, - "attacker": 17346, - "invaders": 17347, - "alvin": 17348, - "intersects": 17349, - "a1": 17350, - "indirectly": 17351, - "immigrated": 17352, - "businessmen": 17353, - "cornelius": 17354, - "valves": 17355, - "narrated": 17356, - "pill": 17357, - "sober": 17358, - "ul": 17359, - "nationale": 17360, - "monastic": 17361, - "applicants": 17362, - "scenery": 17363, - "##jack": 17364, - "161": 17365, - "motifs": 17366, - "constitutes": 17367, - "cpu": 17368, - "##osh": 17369, - "jurisdictions": 17370, - "sd": 17371, - "tuning": 17372, - "irritation": 17373, - "woven": 17374, - "##uddin": 17375, - "fertility": 17376, - "gao": 17377, - "##erie": 17378, - "antagonist": 17379, - "impatient": 17380, - "glacial": 17381, - "hides": 17382, - "boarded": 17383, - "denominations": 17384, - "interception": 17385, - "##jas": 17386, - "cookie": 17387, - "nicola": 17388, - "##tee": 17389, - "algebraic": 17390, - "marquess": 17391, - "bahn": 17392, - "parole": 17393, - "buyers": 17394, - "bait": 17395, - "turbines": 17396, - "paperwork": 17397, - "bestowed": 17398, - "natasha": 17399, - "renee": 17400, - "oceans": 17401, - "purchases": 17402, - "157": 17403, - "vaccine": 17404, - "215": 17405, - "##tock": 17406, - "fixtures": 17407, - "playhouse": 17408, - "integrate": 17409, - "jai": 17410, - "oswald": 17411, - "intellectuals": 17412, - "##cky": 17413, - "booked": 17414, - "nests": 17415, - "mortimer": 17416, - "##isi": 17417, - "obsession": 17418, - "sept": 17419, - "##gler": 17420, - "##sum": 17421, - "440": 17422, - "scrutiny": 17423, - "simultaneous": 17424, - "squinted": 17425, - "##shin": 17426, - "collects": 17427, - "oven": 17428, - "shankar": 17429, - "penned": 17430, - "remarkably": 17431, - "##я": 17432, - "slips": 17433, - "luggage": 17434, - "spectral": 17435, - "1786": 17436, - "collaborations": 17437, - "louie": 17438, - "consolidation": 17439, - "##ailed": 17440, - "##ivating": 17441, - "420": 17442, - "hoover": 17443, - "blackpool": 17444, - "harness": 17445, - "ignition": 17446, - "vest": 17447, - "tails": 17448, - "belmont": 17449, - "mongol": 17450, - "skinner": 17451, - "##nae": 17452, - "visually": 17453, - "mage": 17454, - "derry": 17455, - "##tism": 17456, - "##unce": 17457, - "stevie": 17458, - "transitional": 17459, - "##rdy": 17460, - "redskins": 17461, - "drying": 17462, - "prep": 17463, - "prospective": 17464, - "##21": 17465, - "annoyance": 17466, - "oversee": 17467, - "##loaded": 17468, - "fills": 17469, - "##books": 17470, - "##iki": 17471, - "announces": 17472, - "fda": 17473, - "scowled": 17474, - "respects": 17475, - "prasad": 17476, - "mystic": 17477, - "tucson": 17478, - "##vale": 17479, - "revue": 17480, - "springer": 17481, - "bankrupt": 17482, - "1772": 17483, - "aristotle": 17484, - "salvatore": 17485, - "habsburg": 17486, - "##geny": 17487, - "dal": 17488, - "natal": 17489, - "nut": 17490, - "pod": 17491, - "chewing": 17492, - "darts": 17493, - "moroccan": 17494, - "walkover": 17495, - "rosario": 17496, - "lenin": 17497, - "punjabi": 17498, - "##ße": 17499, - "grossed": 17500, - "scattering": 17501, - "wired": 17502, - "invasive": 17503, - "hui": 17504, - "polynomial": 17505, - "corridors": 17506, - "wakes": 17507, - "gina": 17508, - "portrays": 17509, - "##cratic": 17510, - "arid": 17511, - "retreating": 17512, - "erich": 17513, - "irwin": 17514, - "sniper": 17515, - "##dha": 17516, - "linen": 17517, - "lindsey": 17518, - "maneuver": 17519, - "butch": 17520, - "shutting": 17521, - "socio": 17522, - "bounce": 17523, - "commemorative": 17524, - "postseason": 17525, - "jeremiah": 17526, - "pines": 17527, - "275": 17528, - "mystical": 17529, - "beads": 17530, - "bp": 17531, - "abbas": 17532, - "furnace": 17533, - "bidding": 17534, - "consulted": 17535, - "assaulted": 17536, - "empirical": 17537, - "rubble": 17538, - "enclosure": 17539, - "sob": 17540, - "weakly": 17541, - "cancel": 17542, - "polly": 17543, - "yielded": 17544, - "##emann": 17545, - "curly": 17546, - "prediction": 17547, - "battered": 17548, - "70s": 17549, - "vhs": 17550, - "jacqueline": 17551, - "render": 17552, - "sails": 17553, - "barked": 17554, - "detailing": 17555, - "grayson": 17556, - "riga": 17557, - "sloane": 17558, - "raging": 17559, - "##yah": 17560, - "herbs": 17561, - "bravo": 17562, - "##athlon": 17563, - "alloy": 17564, - "giggle": 17565, - "imminent": 17566, - "suffers": 17567, - "assumptions": 17568, - "waltz": 17569, - "##itate": 17570, - "accomplishments": 17571, - "##ited": 17572, - "bathing": 17573, - "remixed": 17574, - "deception": 17575, - "prefix": 17576, - "##emia": 17577, - "deepest": 17578, - "##tier": 17579, - "##eis": 17580, - "balkan": 17581, - "frogs": 17582, - "##rong": 17583, - "slab": 17584, - "##pate": 17585, - "philosophers": 17586, - "peterborough": 17587, - "grains": 17588, - "imports": 17589, - "dickinson": 17590, - "rwanda": 17591, - "##atics": 17592, - "1774": 17593, - "dirk": 17594, - "lan": 17595, - "tablets": 17596, - "##rove": 17597, - "clone": 17598, - "##rice": 17599, - "caretaker": 17600, - "hostilities": 17601, - "mclean": 17602, - "##gre": 17603, - "regimental": 17604, - "treasures": 17605, - "norms": 17606, - "impose": 17607, - "tsar": 17608, - "tango": 17609, - "diplomacy": 17610, - "variously": 17611, - "complain": 17612, - "192": 17613, - "recognise": 17614, - "arrests": 17615, - "1779": 17616, - "celestial": 17617, - "pulitzer": 17618, - "##dus": 17619, - "bing": 17620, - "libretto": 17621, - "##moor": 17622, - "adele": 17623, - "splash": 17624, - "##rite": 17625, - "expectation": 17626, - "lds": 17627, - "confronts": 17628, - "##izer": 17629, - "spontaneous": 17630, - "harmful": 17631, - "wedge": 17632, - "entrepreneurs": 17633, - "buyer": 17634, - "##ope": 17635, - "bilingual": 17636, - "translate": 17637, - "rugged": 17638, - "conner": 17639, - "circulated": 17640, - "uae": 17641, - "eaton": 17642, - "##gra": 17643, - "##zzle": 17644, - "lingered": 17645, - "lockheed": 17646, - "vishnu": 17647, - "reelection": 17648, - "alonso": 17649, - "##oom": 17650, - "joints": 17651, - "yankee": 17652, - "headline": 17653, - "cooperate": 17654, - "heinz": 17655, - "laureate": 17656, - "invading": 17657, - "##sford": 17658, - "echoes": 17659, - "scandinavian": 17660, - "##dham": 17661, - "hugging": 17662, - "vitamin": 17663, - "salute": 17664, - "micah": 17665, - "hind": 17666, - "trader": 17667, - "##sper": 17668, - "radioactive": 17669, - "##ndra": 17670, - "militants": 17671, - "poisoned": 17672, - "ratified": 17673, - "remark": 17674, - "campeonato": 17675, - "deprived": 17676, - "wander": 17677, - "prop": 17678, - "##dong": 17679, - "outlook": 17680, - "##tani": 17681, - "##rix": 17682, - "##eye": 17683, - "chiang": 17684, - "darcy": 17685, - "##oping": 17686, - "mandolin": 17687, - "spice": 17688, - "statesman": 17689, - "babylon": 17690, - "182": 17691, - "walled": 17692, - "forgetting": 17693, - "afro": 17694, - "##cap": 17695, - "158": 17696, - "giorgio": 17697, - "buffer": 17698, - "##polis": 17699, - "planetary": 17700, - "##gis": 17701, - "overlap": 17702, - "terminals": 17703, - "kinda": 17704, - "centenary": 17705, - "##bir": 17706, - "arising": 17707, - "manipulate": 17708, - "elm": 17709, - "ke": 17710, - "1770": 17711, - "ak": 17712, - "##tad": 17713, - "chrysler": 17714, - "mapped": 17715, - "moose": 17716, - "pomeranian": 17717, - "quad": 17718, - "macarthur": 17719, - "assemblies": 17720, - "shoreline": 17721, - "recalls": 17722, - "stratford": 17723, - "##rted": 17724, - "noticeable": 17725, - "##evic": 17726, - "imp": 17727, - "##rita": 17728, - "##sque": 17729, - "accustomed": 17730, - "supplying": 17731, - "tents": 17732, - "disgusted": 17733, - "vogue": 17734, - "sipped": 17735, - "filters": 17736, - "khz": 17737, - "reno": 17738, - "selecting": 17739, - "luftwaffe": 17740, - "mcmahon": 17741, - "tyne": 17742, - "masterpiece": 17743, - "carriages": 17744, - "collided": 17745, - "dunes": 17746, - "exercised": 17747, - "flare": 17748, - "remembers": 17749, - "muzzle": 17750, - "##mobile": 17751, - "heck": 17752, - "##rson": 17753, - "burgess": 17754, - "lunged": 17755, - "middleton": 17756, - "boycott": 17757, - "bilateral": 17758, - "##sity": 17759, - "hazardous": 17760, - "lumpur": 17761, - "multiplayer": 17762, - "spotlight": 17763, - "jackets": 17764, - "goldman": 17765, - "liege": 17766, - "porcelain": 17767, - "rag": 17768, - "waterford": 17769, - "benz": 17770, - "attracts": 17771, - "hopeful": 17772, - "battling": 17773, - "ottomans": 17774, - "kensington": 17775, - "baked": 17776, - "hymns": 17777, - "cheyenne": 17778, - "lattice": 17779, - "levine": 17780, - "borrow": 17781, - "polymer": 17782, - "clashes": 17783, - "michaels": 17784, - "monitored": 17785, - "commitments": 17786, - "denounced": 17787, - "##25": 17788, - "##von": 17789, - "cavity": 17790, - "##oney": 17791, - "hobby": 17792, - "akin": 17793, - "##holders": 17794, - "futures": 17795, - "intricate": 17796, - "cornish": 17797, - "patty": 17798, - "##oned": 17799, - "illegally": 17800, - "dolphin": 17801, - "##lag": 17802, - "barlow": 17803, - "yellowish": 17804, - "maddie": 17805, - "apologized": 17806, - "luton": 17807, - "plagued": 17808, - "##puram": 17809, - "nana": 17810, - "##rds": 17811, - "sway": 17812, - "fanny": 17813, - "łodz": 17814, - "##rino": 17815, - "psi": 17816, - "suspicions": 17817, - "hanged": 17818, - "##eding": 17819, - "initiate": 17820, - "charlton": 17821, - "##por": 17822, - "nak": 17823, - "competent": 17824, - "235": 17825, - "analytical": 17826, - "annex": 17827, - "wardrobe": 17828, - "reservations": 17829, - "##rma": 17830, - "sect": 17831, - "162": 17832, - "fairfax": 17833, - "hedge": 17834, - "piled": 17835, - "buckingham": 17836, - "uneven": 17837, - "bauer": 17838, - "simplicity": 17839, - "snyder": 17840, - "interpret": 17841, - "accountability": 17842, - "donors": 17843, - "moderately": 17844, - "byrd": 17845, - "continents": 17846, - "##cite": 17847, - "##max": 17848, - "disciple": 17849, - "hr": 17850, - "jamaican": 17851, - "ping": 17852, - "nominees": 17853, - "##uss": 17854, - "mongolian": 17855, - "diver": 17856, - "attackers": 17857, - "eagerly": 17858, - "ideological": 17859, - "pillows": 17860, - "miracles": 17861, - "apartheid": 17862, - "revolver": 17863, - "sulfur": 17864, - "clinics": 17865, - "moran": 17866, - "163": 17867, - "##enko": 17868, - "ile": 17869, - "katy": 17870, - "rhetoric": 17871, - "##icated": 17872, - "chronology": 17873, - "recycling": 17874, - "##hrer": 17875, - "elongated": 17876, - "mughal": 17877, - "pascal": 17878, - "profiles": 17879, - "vibration": 17880, - "databases": 17881, - "domination": 17882, - "##fare": 17883, - "##rant": 17884, - "matthias": 17885, - "digest": 17886, - "rehearsal": 17887, - "polling": 17888, - "weiss": 17889, - "initiation": 17890, - "reeves": 17891, - "clinging": 17892, - "flourished": 17893, - "impress": 17894, - "ngo": 17895, - "##hoff": 17896, - "##ume": 17897, - "buckley": 17898, - "symposium": 17899, - "rhythms": 17900, - "weed": 17901, - "emphasize": 17902, - "transforming": 17903, - "##taking": 17904, - "##gence": 17905, - "##yman": 17906, - "accountant": 17907, - "analyze": 17908, - "flicker": 17909, - "foil": 17910, - "priesthood": 17911, - "voluntarily": 17912, - "decreases": 17913, - "##80": 17914, - "##hya": 17915, - "slater": 17916, - "sv": 17917, - "charting": 17918, - "mcgill": 17919, - "##lde": 17920, - "moreno": 17921, - "##iu": 17922, - "besieged": 17923, - "zur": 17924, - "robes": 17925, - "##phic": 17926, - "admitting": 17927, - "api": 17928, - "deported": 17929, - "turmoil": 17930, - "peyton": 17931, - "earthquakes": 17932, - "##ares": 17933, - "nationalists": 17934, - "beau": 17935, - "clair": 17936, - "brethren": 17937, - "interrupt": 17938, - "welch": 17939, - "curated": 17940, - "galerie": 17941, - "requesting": 17942, - "164": 17943, - "##ested": 17944, - "impending": 17945, - "steward": 17946, - "viper": 17947, - "##vina": 17948, - "complaining": 17949, - "beautifully": 17950, - "brandy": 17951, - "foam": 17952, - "nl": 17953, - "1660": 17954, - "##cake": 17955, - "alessandro": 17956, - "punches": 17957, - "laced": 17958, - "explanations": 17959, - "##lim": 17960, - "attribute": 17961, - "clit": 17962, - "reggie": 17963, - "discomfort": 17964, - "##cards": 17965, - "smoothed": 17966, - "whales": 17967, - "##cene": 17968, - "adler": 17969, - "countered": 17970, - "duffy": 17971, - "disciplinary": 17972, - "widening": 17973, - "recipe": 17974, - "reliance": 17975, - "conducts": 17976, - "goats": 17977, - "gradient": 17978, - "preaching": 17979, - "##shaw": 17980, - "matilda": 17981, - "quasi": 17982, - "striped": 17983, - "meridian": 17984, - "cannabis": 17985, - "cordoba": 17986, - "certificates": 17987, - "##agh": 17988, - "##tering": 17989, - "graffiti": 17990, - "hangs": 17991, - "pilgrims": 17992, - "repeats": 17993, - "##ych": 17994, - "revive": 17995, - "urine": 17996, - "etat": 17997, - "##hawk": 17998, - "fueled": 17999, - "belts": 18000, - "fuzzy": 18001, - "susceptible": 18002, - "##hang": 18003, - "mauritius": 18004, - "salle": 18005, - "sincere": 18006, - "beers": 18007, - "hooks": 18008, - "##cki": 18009, - "arbitration": 18010, - "entrusted": 18011, - "advise": 18012, - "sniffed": 18013, - "seminar": 18014, - "junk": 18015, - "donnell": 18016, - "processors": 18017, - "principality": 18018, - "strapped": 18019, - "celia": 18020, - "mendoza": 18021, - "everton": 18022, - "fortunes": 18023, - "prejudice": 18024, - "starving": 18025, - "reassigned": 18026, - "steamer": 18027, - "##lund": 18028, - "tuck": 18029, - "evenly": 18030, - "foreman": 18031, - "##ffen": 18032, - "dans": 18033, - "375": 18034, - "envisioned": 18035, - "slit": 18036, - "##xy": 18037, - "baseman": 18038, - "liberia": 18039, - "rosemary": 18040, - "##weed": 18041, - "electrified": 18042, - "periodically": 18043, - "potassium": 18044, - "stride": 18045, - "contexts": 18046, - "sperm": 18047, - "slade": 18048, - "mariners": 18049, - "influx": 18050, - "bianca": 18051, - "subcommittee": 18052, - "##rane": 18053, - "spilling": 18054, - "icao": 18055, - "estuary": 18056, - "##nock": 18057, - "delivers": 18058, - "iphone": 18059, - "##ulata": 18060, - "isa": 18061, - "mira": 18062, - "bohemian": 18063, - "dessert": 18064, - "##sbury": 18065, - "welcoming": 18066, - "proudly": 18067, - "slowing": 18068, - "##chs": 18069, - "musee": 18070, - "ascension": 18071, - "russ": 18072, - "##vian": 18073, - "waits": 18074, - "##psy": 18075, - "africans": 18076, - "exploit": 18077, - "##morphic": 18078, - "gov": 18079, - "eccentric": 18080, - "crab": 18081, - "peck": 18082, - "##ull": 18083, - "entrances": 18084, - "formidable": 18085, - "marketplace": 18086, - "groom": 18087, - "bolted": 18088, - "metabolism": 18089, - "patton": 18090, - "robbins": 18091, - "courier": 18092, - "payload": 18093, - "endure": 18094, - "##ifier": 18095, - "andes": 18096, - "refrigerator": 18097, - "##pr": 18098, - "ornate": 18099, - "##uca": 18100, - "ruthless": 18101, - "illegitimate": 18102, - "masonry": 18103, - "strasbourg": 18104, - "bikes": 18105, - "adobe": 18106, - "##³": 18107, - "apples": 18108, - "quintet": 18109, - "willingly": 18110, - "niche": 18111, - "bakery": 18112, - "corpses": 18113, - "energetic": 18114, - "##cliffe": 18115, - "##sser": 18116, - "##ards": 18117, - "177": 18118, - "centimeters": 18119, - "centro": 18120, - "fuscous": 18121, - "cretaceous": 18122, - "rancho": 18123, - "##yde": 18124, - "andrei": 18125, - "telecom": 18126, - "tottenham": 18127, - "oasis": 18128, - "ordination": 18129, - "vulnerability": 18130, - "presiding": 18131, - "corey": 18132, - "cp": 18133, - "penguins": 18134, - "sims": 18135, - "##pis": 18136, - "malawi": 18137, - "piss": 18138, - "##48": 18139, - "correction": 18140, - "##cked": 18141, - "##ffle": 18142, - "##ryn": 18143, - "countdown": 18144, - "detectives": 18145, - "psychiatrist": 18146, - "psychedelic": 18147, - "dinosaurs": 18148, - "blouse": 18149, - "##get": 18150, - "choi": 18151, - "vowed": 18152, - "##oz": 18153, - "randomly": 18154, - "##pol": 18155, - "49ers": 18156, - "scrub": 18157, - "blanche": 18158, - "bruins": 18159, - "dusseldorf": 18160, - "##using": 18161, - "unwanted": 18162, - "##ums": 18163, - "212": 18164, - "dominique": 18165, - "elevations": 18166, - "headlights": 18167, - "om": 18168, - "laguna": 18169, - "##oga": 18170, - "1750": 18171, - "famously": 18172, - "ignorance": 18173, - "shrewsbury": 18174, - "##aine": 18175, - "ajax": 18176, - "breuning": 18177, - "che": 18178, - "confederacy": 18179, - "greco": 18180, - "overhaul": 18181, - "##screen": 18182, - "paz": 18183, - "skirts": 18184, - "disagreement": 18185, - "cruelty": 18186, - "jagged": 18187, - "phoebe": 18188, - "shifter": 18189, - "hovered": 18190, - "viruses": 18191, - "##wes": 18192, - "mandy": 18193, - "##lined": 18194, - "##gc": 18195, - "landlord": 18196, - "squirrel": 18197, - "dashed": 18198, - "##ι": 18199, - "ornamental": 18200, - "gag": 18201, - "wally": 18202, - "grange": 18203, - "literal": 18204, - "spurs": 18205, - "undisclosed": 18206, - "proceeding": 18207, - "yin": 18208, - "##text": 18209, - "billie": 18210, - "orphan": 18211, - "spanned": 18212, - "humidity": 18213, - "indy": 18214, - "weighted": 18215, - "presentations": 18216, - "explosions": 18217, - "lucian": 18218, - "##tary": 18219, - "vaughn": 18220, - "hindus": 18221, - "##anga": 18222, - "##hell": 18223, - "psycho": 18224, - "171": 18225, - "daytona": 18226, - "protects": 18227, - "efficiently": 18228, - "rematch": 18229, - "sly": 18230, - "tandem": 18231, - "##oya": 18232, - "rebranded": 18233, - "impaired": 18234, - "hee": 18235, - "metropolis": 18236, - "peach": 18237, - "godfrey": 18238, - "diaspora": 18239, - "ethnicity": 18240, - "prosperous": 18241, - "gleaming": 18242, - "dar": 18243, - "grossing": 18244, - "playback": 18245, - "##rden": 18246, - "stripe": 18247, - "pistols": 18248, - "##tain": 18249, - "births": 18250, - "labelled": 18251, - "##cating": 18252, - "172": 18253, - "rudy": 18254, - "alba": 18255, - "##onne": 18256, - "aquarium": 18257, - "hostility": 18258, - "##gb": 18259, - "##tase": 18260, - "shudder": 18261, - "sumatra": 18262, - "hardest": 18263, - "lakers": 18264, - "consonant": 18265, - "creeping": 18266, - "demos": 18267, - "homicide": 18268, - "capsule": 18269, - "zeke": 18270, - "liberties": 18271, - "expulsion": 18272, - "pueblo": 18273, - "##comb": 18274, - "trait": 18275, - "transporting": 18276, - "##ddin": 18277, - "##neck": 18278, - "##yna": 18279, - "depart": 18280, - "gregg": 18281, - "mold": 18282, - "ledge": 18283, - "hangar": 18284, - "oldham": 18285, - "playboy": 18286, - "termination": 18287, - "analysts": 18288, - "gmbh": 18289, - "romero": 18290, - "##itic": 18291, - "insist": 18292, - "cradle": 18293, - "filthy": 18294, - "brightness": 18295, - "slash": 18296, - "shootout": 18297, - "deposed": 18298, - "bordering": 18299, - "##truct": 18300, - "isis": 18301, - "microwave": 18302, - "tumbled": 18303, - "sheltered": 18304, - "cathy": 18305, - "werewolves": 18306, - "messy": 18307, - "andersen": 18308, - "convex": 18309, - "clapped": 18310, - "clinched": 18311, - "satire": 18312, - "wasting": 18313, - "edo": 18314, - "vc": 18315, - "rufus": 18316, - "##jak": 18317, - "mont": 18318, - "##etti": 18319, - "poznan": 18320, - "##keeping": 18321, - "restructuring": 18322, - "transverse": 18323, - "##rland": 18324, - "azerbaijani": 18325, - "slovene": 18326, - "gestures": 18327, - "roommate": 18328, - "choking": 18329, - "shear": 18330, - "##quist": 18331, - "vanguard": 18332, - "oblivious": 18333, - "##hiro": 18334, - "disagreed": 18335, - "baptism": 18336, - "##lich": 18337, - "coliseum": 18338, - "##aceae": 18339, - "salvage": 18340, - "societe": 18341, - "cory": 18342, - "locke": 18343, - "relocation": 18344, - "relying": 18345, - "versailles": 18346, - "ahl": 18347, - "swelling": 18348, - "##elo": 18349, - "cheerful": 18350, - "##word": 18351, - "##edes": 18352, - "gin": 18353, - "sarajevo": 18354, - "obstacle": 18355, - "diverted": 18356, - "##nac": 18357, - "messed": 18358, - "thoroughbred": 18359, - "fluttered": 18360, - "utrecht": 18361, - "chewed": 18362, - "acquaintance": 18363, - "assassins": 18364, - "dispatch": 18365, - "mirza": 18366, - "##wart": 18367, - "nike": 18368, - "salzburg": 18369, - "swell": 18370, - "yen": 18371, - "##gee": 18372, - "idle": 18373, - "ligue": 18374, - "samson": 18375, - "##nds": 18376, - "##igh": 18377, - "playful": 18378, - "spawned": 18379, - "##cise": 18380, - "tease": 18381, - "##case": 18382, - "burgundy": 18383, - "##bot": 18384, - "stirring": 18385, - "skeptical": 18386, - "interceptions": 18387, - "marathi": 18388, - "##dies": 18389, - "bedrooms": 18390, - "aroused": 18391, - "pinch": 18392, - "##lik": 18393, - "preferences": 18394, - "tattoos": 18395, - "buster": 18396, - "digitally": 18397, - "projecting": 18398, - "rust": 18399, - "##ital": 18400, - "kitten": 18401, - "priorities": 18402, - "addison": 18403, - "pseudo": 18404, - "##guard": 18405, - "dusk": 18406, - "icons": 18407, - "sermon": 18408, - "##psis": 18409, - "##iba": 18410, - "bt": 18411, - "##lift": 18412, - "##xt": 18413, - "ju": 18414, - "truce": 18415, - "rink": 18416, - "##dah": 18417, - "##wy": 18418, - "defects": 18419, - "psychiatry": 18420, - "offences": 18421, - "calculate": 18422, - "glucose": 18423, - "##iful": 18424, - "##rized": 18425, - "##unda": 18426, - "francaise": 18427, - "##hari": 18428, - "richest": 18429, - "warwickshire": 18430, - "carly": 18431, - "1763": 18432, - "purity": 18433, - "redemption": 18434, - "lending": 18435, - "##cious": 18436, - "muse": 18437, - "bruises": 18438, - "cerebral": 18439, - "aero": 18440, - "carving": 18441, - "##name": 18442, - "preface": 18443, - "terminology": 18444, - "invade": 18445, - "monty": 18446, - "##int": 18447, - "anarchist": 18448, - "blurred": 18449, - "##iled": 18450, - "rossi": 18451, - "treats": 18452, - "guts": 18453, - "shu": 18454, - "foothills": 18455, - "ballads": 18456, - "undertaking": 18457, - "premise": 18458, - "cecilia": 18459, - "affiliates": 18460, - "blasted": 18461, - "conditional": 18462, - "wilder": 18463, - "minors": 18464, - "drone": 18465, - "rudolph": 18466, - "buffy": 18467, - "swallowing": 18468, - "horton": 18469, - "attested": 18470, - "##hop": 18471, - "rutherford": 18472, - "howell": 18473, - "primetime": 18474, - "livery": 18475, - "penal": 18476, - "##bis": 18477, - "minimize": 18478, - "hydro": 18479, - "wrecked": 18480, - "wrought": 18481, - "palazzo": 18482, - "##gling": 18483, - "cans": 18484, - "vernacular": 18485, - "friedman": 18486, - "nobleman": 18487, - "shale": 18488, - "walnut": 18489, - "danielle": 18490, - "##ection": 18491, - "##tley": 18492, - "sears": 18493, - "##kumar": 18494, - "chords": 18495, - "lend": 18496, - "flipping": 18497, - "streamed": 18498, - "por": 18499, - "dracula": 18500, - "gallons": 18501, - "sacrifices": 18502, - "gamble": 18503, - "orphanage": 18504, - "##iman": 18505, - "mckenzie": 18506, - "##gible": 18507, - "boxers": 18508, - "daly": 18509, - "##balls": 18510, - "##ان": 18511, - "208": 18512, - "##ific": 18513, - "##rative": 18514, - "##iq": 18515, - "exploited": 18516, - "slated": 18517, - "##uity": 18518, - "circling": 18519, - "hillary": 18520, - "pinched": 18521, - "goldberg": 18522, - "provost": 18523, - "campaigning": 18524, - "lim": 18525, - "piles": 18526, - "ironically": 18527, - "jong": 18528, - "mohan": 18529, - "successors": 18530, - "usaf": 18531, - "##tem": 18532, - "##ught": 18533, - "autobiographical": 18534, - "haute": 18535, - "preserves": 18536, - "##ending": 18537, - "acquitted": 18538, - "comparisons": 18539, - "203": 18540, - "hydroelectric": 18541, - "gangs": 18542, - "cypriot": 18543, - "torpedoes": 18544, - "rushes": 18545, - "chrome": 18546, - "derive": 18547, - "bumps": 18548, - "instability": 18549, - "fiat": 18550, - "pets": 18551, - "##mbe": 18552, - "silas": 18553, - "dye": 18554, - "reckless": 18555, - "settler": 18556, - "##itation": 18557, - "info": 18558, - "heats": 18559, - "##writing": 18560, - "176": 18561, - "canonical": 18562, - "maltese": 18563, - "fins": 18564, - "mushroom": 18565, - "stacy": 18566, - "aspen": 18567, - "avid": 18568, - "##kur": 18569, - "##loading": 18570, - "vickers": 18571, - "gaston": 18572, - "hillside": 18573, - "statutes": 18574, - "wilde": 18575, - "gail": 18576, - "kung": 18577, - "sabine": 18578, - "comfortably": 18579, - "motorcycles": 18580, - "##rgo": 18581, - "169": 18582, - "pneumonia": 18583, - "fetch": 18584, - "##sonic": 18585, - "axel": 18586, - "faintly": 18587, - "parallels": 18588, - "##oop": 18589, - "mclaren": 18590, - "spouse": 18591, - "compton": 18592, - "interdisciplinary": 18593, - "miner": 18594, - "##eni": 18595, - "181": 18596, - "clamped": 18597, - "##chal": 18598, - "##llah": 18599, - "separates": 18600, - "versa": 18601, - "##mler": 18602, - "scarborough": 18603, - "labrador": 18604, - "##lity": 18605, - "##osing": 18606, - "rutgers": 18607, - "hurdles": 18608, - "como": 18609, - "166": 18610, - "burt": 18611, - "divers": 18612, - "##100": 18613, - "wichita": 18614, - "cade": 18615, - "coincided": 18616, - "##erson": 18617, - "bruised": 18618, - "mla": 18619, - "##pper": 18620, - "vineyard": 18621, - "##ili": 18622, - "##brush": 18623, - "notch": 18624, - "mentioning": 18625, - "jase": 18626, - "hearted": 18627, - "kits": 18628, - "doe": 18629, - "##acle": 18630, - "pomerania": 18631, - "##ady": 18632, - "ronan": 18633, - "seizure": 18634, - "pavel": 18635, - "problematic": 18636, - "##zaki": 18637, - "domenico": 18638, - "##ulin": 18639, - "catering": 18640, - "penelope": 18641, - "dependence": 18642, - "parental": 18643, - "emilio": 18644, - "ministerial": 18645, - "atkinson": 18646, - "##bolic": 18647, - "clarkson": 18648, - "chargers": 18649, - "colby": 18650, - "grill": 18651, - "peeked": 18652, - "arises": 18653, - "summon": 18654, - "##aged": 18655, - "fools": 18656, - "##grapher": 18657, - "faculties": 18658, - "qaeda": 18659, - "##vial": 18660, - "garner": 18661, - "refurbished": 18662, - "##hwa": 18663, - "geelong": 18664, - "disasters": 18665, - "nudged": 18666, - "bs": 18667, - "shareholder": 18668, - "lori": 18669, - "algae": 18670, - "reinstated": 18671, - "rot": 18672, - "##ades": 18673, - "##nous": 18674, - "invites": 18675, - "stainless": 18676, - "183": 18677, - "inclusive": 18678, - "##itude": 18679, - "diocesan": 18680, - "til": 18681, - "##icz": 18682, - "denomination": 18683, - "##xa": 18684, - "benton": 18685, - "floral": 18686, - "registers": 18687, - "##ider": 18688, - "##erman": 18689, - "##kell": 18690, - "absurd": 18691, - "brunei": 18692, - "guangzhou": 18693, - "hitter": 18694, - "retaliation": 18695, - "##uled": 18696, - "##eve": 18697, - "blanc": 18698, - "nh": 18699, - "consistency": 18700, - "contamination": 18701, - "##eres": 18702, - "##rner": 18703, - "dire": 18704, - "palermo": 18705, - "broadcasters": 18706, - "diaries": 18707, - "inspire": 18708, - "vols": 18709, - "brewer": 18710, - "tightening": 18711, - "ky": 18712, - "mixtape": 18713, - "hormone": 18714, - "##tok": 18715, - "stokes": 18716, - "##color": 18717, - "##dly": 18718, - "##ssi": 18719, - "pg": 18720, - "##ometer": 18721, - "##lington": 18722, - "sanitation": 18723, - "##tility": 18724, - "intercontinental": 18725, - "apps": 18726, - "##adt": 18727, - "¹⁄₂": 18728, - "cylinders": 18729, - "economies": 18730, - "favourable": 18731, - "unison": 18732, - "croix": 18733, - "gertrude": 18734, - "odyssey": 18735, - "vanity": 18736, - "dangling": 18737, - "##logists": 18738, - "upgrades": 18739, - "dice": 18740, - "middleweight": 18741, - "practitioner": 18742, - "##ight": 18743, - "206": 18744, - "henrik": 18745, - "parlor": 18746, - "orion": 18747, - "angered": 18748, - "lac": 18749, - "python": 18750, - "blurted": 18751, - "##rri": 18752, - "sensual": 18753, - "intends": 18754, - "swings": 18755, - "angled": 18756, - "##phs": 18757, - "husky": 18758, - "attain": 18759, - "peerage": 18760, - "precinct": 18761, - "textiles": 18762, - "cheltenham": 18763, - "shuffled": 18764, - "dai": 18765, - "confess": 18766, - "tasting": 18767, - "bhutan": 18768, - "##riation": 18769, - "tyrone": 18770, - "segregation": 18771, - "abrupt": 18772, - "ruiz": 18773, - "##rish": 18774, - "smirked": 18775, - "blackwell": 18776, - "confidential": 18777, - "browning": 18778, - "amounted": 18779, - "##put": 18780, - "vase": 18781, - "scarce": 18782, - "fabulous": 18783, - "raided": 18784, - "staple": 18785, - "guyana": 18786, - "unemployed": 18787, - "glider": 18788, - "shay": 18789, - "##tow": 18790, - "carmine": 18791, - "troll": 18792, - "intervene": 18793, - "squash": 18794, - "superstar": 18795, - "##uce": 18796, - "cylindrical": 18797, - "len": 18798, - "roadway": 18799, - "researched": 18800, - "handy": 18801, - "##rium": 18802, - "##jana": 18803, - "meta": 18804, - "lao": 18805, - "declares": 18806, - "##rring": 18807, - "##tadt": 18808, - "##elin": 18809, - "##kova": 18810, - "willem": 18811, - "shrubs": 18812, - "napoleonic": 18813, - "realms": 18814, - "skater": 18815, - "qi": 18816, - "volkswagen": 18817, - "##ł": 18818, - "tad": 18819, - "hara": 18820, - "archaeologist": 18821, - "awkwardly": 18822, - "eerie": 18823, - "##kind": 18824, - "wiley": 18825, - "##heimer": 18826, - "##24": 18827, - "titus": 18828, - "organizers": 18829, - "cfl": 18830, - "crusaders": 18831, - "lama": 18832, - "usb": 18833, - "vent": 18834, - "enraged": 18835, - "thankful": 18836, - "occupants": 18837, - "maximilian": 18838, - "##gaard": 18839, - "possessing": 18840, - "textbooks": 18841, - "##oran": 18842, - "collaborator": 18843, - "quaker": 18844, - "##ulo": 18845, - "avalanche": 18846, - "mono": 18847, - "silky": 18848, - "straits": 18849, - "isaiah": 18850, - "mustang": 18851, - "surged": 18852, - "resolutions": 18853, - "potomac": 18854, - "descend": 18855, - "cl": 18856, - "kilograms": 18857, - "plato": 18858, - "strains": 18859, - "saturdays": 18860, - "##olin": 18861, - "bernstein": 18862, - "##ype": 18863, - "holstein": 18864, - "ponytail": 18865, - "##watch": 18866, - "belize": 18867, - "conversely": 18868, - "heroine": 18869, - "perpetual": 18870, - "##ylus": 18871, - "charcoal": 18872, - "piedmont": 18873, - "glee": 18874, - "negotiating": 18875, - "backdrop": 18876, - "prologue": 18877, - "##jah": 18878, - "##mmy": 18879, - "pasadena": 18880, - "climbs": 18881, - "ramos": 18882, - "sunni": 18883, - "##holm": 18884, - "##tner": 18885, - "##tri": 18886, - "anand": 18887, - "deficiency": 18888, - "hertfordshire": 18889, - "stout": 18890, - "##avi": 18891, - "aperture": 18892, - "orioles": 18893, - "##irs": 18894, - "doncaster": 18895, - "intrigued": 18896, - "bombed": 18897, - "coating": 18898, - "otis": 18899, - "##mat": 18900, - "cocktail": 18901, - "##jit": 18902, - "##eto": 18903, - "amir": 18904, - "arousal": 18905, - "sar": 18906, - "##proof": 18907, - "##act": 18908, - "##ories": 18909, - "dixie": 18910, - "pots": 18911, - "##bow": 18912, - "whereabouts": 18913, - "159": 18914, - "##fted": 18915, - "drains": 18916, - "bullying": 18917, - "cottages": 18918, - "scripture": 18919, - "coherent": 18920, - "fore": 18921, - "poe": 18922, - "appetite": 18923, - "##uration": 18924, - "sampled": 18925, - "##ators": 18926, - "##dp": 18927, - "derrick": 18928, - "rotor": 18929, - "jays": 18930, - "peacock": 18931, - "installment": 18932, - "##rro": 18933, - "advisors": 18934, - "##coming": 18935, - "rodeo": 18936, - "scotch": 18937, - "##mot": 18938, - "##db": 18939, - "##fen": 18940, - "##vant": 18941, - "ensued": 18942, - "rodrigo": 18943, - "dictatorship": 18944, - "martyrs": 18945, - "twenties": 18946, - "##н": 18947, - "towed": 18948, - "incidence": 18949, - "marta": 18950, - "rainforest": 18951, - "sai": 18952, - "scaled": 18953, - "##cles": 18954, - "oceanic": 18955, - "qualifiers": 18956, - "symphonic": 18957, - "mcbride": 18958, - "dislike": 18959, - "generalized": 18960, - "aubrey": 18961, - "colonization": 18962, - "##iation": 18963, - "##lion": 18964, - "##ssing": 18965, - "disliked": 18966, - "lublin": 18967, - "salesman": 18968, - "##ulates": 18969, - "spherical": 18970, - "whatsoever": 18971, - "sweating": 18972, - "avalon": 18973, - "contention": 18974, - "punt": 18975, - "severity": 18976, - "alderman": 18977, - "atari": 18978, - "##dina": 18979, - "##grant": 18980, - "##rop": 18981, - "scarf": 18982, - "seville": 18983, - "vertices": 18984, - "annexation": 18985, - "fairfield": 18986, - "fascination": 18987, - "inspiring": 18988, - "launches": 18989, - "palatinate": 18990, - "regretted": 18991, - "##rca": 18992, - "feral": 18993, - "##iom": 18994, - "elk": 18995, - "nap": 18996, - "olsen": 18997, - "reddy": 18998, - "yong": 18999, - "##leader": 19000, - "##iae": 19001, - "garment": 19002, - "transports": 19003, - "feng": 19004, - "gracie": 19005, - "outrage": 19006, - "viceroy": 19007, - "insides": 19008, - "##esis": 19009, - "breakup": 19010, - "grady": 19011, - "organizer": 19012, - "softer": 19013, - "grimaced": 19014, - "222": 19015, - "murals": 19016, - "galicia": 19017, - "arranging": 19018, - "vectors": 19019, - "##rsten": 19020, - "bas": 19021, - "##sb": 19022, - "##cens": 19023, - "sloan": 19024, - "##eka": 19025, - "bitten": 19026, - "ara": 19027, - "fender": 19028, - "nausea": 19029, - "bumped": 19030, - "kris": 19031, - "banquet": 19032, - "comrades": 19033, - "detector": 19034, - "persisted": 19035, - "##llan": 19036, - "adjustment": 19037, - "endowed": 19038, - "cinemas": 19039, - "##shot": 19040, - "sellers": 19041, - "##uman": 19042, - "peek": 19043, - "epa": 19044, - "kindly": 19045, - "neglect": 19046, - "simpsons": 19047, - "talon": 19048, - "mausoleum": 19049, - "runaway": 19050, - "hangul": 19051, - "lookout": 19052, - "##cic": 19053, - "rewards": 19054, - "coughed": 19055, - "acquainted": 19056, - "chloride": 19057, - "##ald": 19058, - "quicker": 19059, - "accordion": 19060, - "neolithic": 19061, - "##qa": 19062, - "artemis": 19063, - "coefficient": 19064, - "lenny": 19065, - "pandora": 19066, - "tx": 19067, - "##xed": 19068, - "ecstasy": 19069, - "litter": 19070, - "segunda": 19071, - "chairperson": 19072, - "gemma": 19073, - "hiss": 19074, - "rumor": 19075, - "vow": 19076, - "nasal": 19077, - "antioch": 19078, - "compensate": 19079, - "patiently": 19080, - "transformers": 19081, - "##eded": 19082, - "judo": 19083, - "morrow": 19084, - "penis": 19085, - "posthumous": 19086, - "philips": 19087, - "bandits": 19088, - "husbands": 19089, - "denote": 19090, - "flaming": 19091, - "##any": 19092, - "##phones": 19093, - "langley": 19094, - "yorker": 19095, - "1760": 19096, - "walters": 19097, - "##uo": 19098, - "##kle": 19099, - "gubernatorial": 19100, - "fatty": 19101, - "samsung": 19102, - "leroy": 19103, - "outlaw": 19104, - "##nine": 19105, - "unpublished": 19106, - "poole": 19107, - "jakob": 19108, - "##ᵢ": 19109, - "##ₙ": 19110, - "crete": 19111, - "distorted": 19112, - "superiority": 19113, - "##dhi": 19114, - "intercept": 19115, - "crust": 19116, - "mig": 19117, - "claus": 19118, - "crashes": 19119, - "positioning": 19120, - "188": 19121, - "stallion": 19122, - "301": 19123, - "frontal": 19124, - "armistice": 19125, - "##estinal": 19126, - "elton": 19127, - "aj": 19128, - "encompassing": 19129, - "camel": 19130, - "commemorated": 19131, - "malaria": 19132, - "woodward": 19133, - "calf": 19134, - "cigar": 19135, - "penetrate": 19136, - "##oso": 19137, - "willard": 19138, - "##rno": 19139, - "##uche": 19140, - "illustrate": 19141, - "amusing": 19142, - "convergence": 19143, - "noteworthy": 19144, - "##lma": 19145, - "##rva": 19146, - "journeys": 19147, - "realise": 19148, - "manfred": 19149, - "##sable": 19150, - "410": 19151, - "##vocation": 19152, - "hearings": 19153, - "fiance": 19154, - "##posed": 19155, - "educators": 19156, - "provoked": 19157, - "adjusting": 19158, - "##cturing": 19159, - "modular": 19160, - "stockton": 19161, - "paterson": 19162, - "vlad": 19163, - "rejects": 19164, - "electors": 19165, - "selena": 19166, - "maureen": 19167, - "##tres": 19168, - "uber": 19169, - "##rce": 19170, - "swirled": 19171, - "##num": 19172, - "proportions": 19173, - "nanny": 19174, - "pawn": 19175, - "naturalist": 19176, - "parma": 19177, - "apostles": 19178, - "awoke": 19179, - "ethel": 19180, - "wen": 19181, - "##bey": 19182, - "monsoon": 19183, - "overview": 19184, - "##inating": 19185, - "mccain": 19186, - "rendition": 19187, - "risky": 19188, - "adorned": 19189, - "##ih": 19190, - "equestrian": 19191, - "germain": 19192, - "nj": 19193, - "conspicuous": 19194, - "confirming": 19195, - "##yoshi": 19196, - "shivering": 19197, - "##imeter": 19198, - "milestone": 19199, - "rumours": 19200, - "flinched": 19201, - "bounds": 19202, - "smacked": 19203, - "token": 19204, - "##bei": 19205, - "lectured": 19206, - "automobiles": 19207, - "##shore": 19208, - "impacted": 19209, - "##iable": 19210, - "nouns": 19211, - "nero": 19212, - "##leaf": 19213, - "ismail": 19214, - "prostitute": 19215, - "trams": 19216, - "##lace": 19217, - "bridget": 19218, - "sud": 19219, - "stimulus": 19220, - "impressions": 19221, - "reins": 19222, - "revolves": 19223, - "##oud": 19224, - "##gned": 19225, - "giro": 19226, - "honeymoon": 19227, - "##swell": 19228, - "criterion": 19229, - "##sms": 19230, - "##uil": 19231, - "libyan": 19232, - "prefers": 19233, - "##osition": 19234, - "211": 19235, - "preview": 19236, - "sucks": 19237, - "accusation": 19238, - "bursts": 19239, - "metaphor": 19240, - "diffusion": 19241, - "tolerate": 19242, - "faye": 19243, - "betting": 19244, - "cinematographer": 19245, - "liturgical": 19246, - "specials": 19247, - "bitterly": 19248, - "humboldt": 19249, - "##ckle": 19250, - "flux": 19251, - "rattled": 19252, - "##itzer": 19253, - "archaeologists": 19254, - "odor": 19255, - "authorised": 19256, - "marshes": 19257, - "discretion": 19258, - "##ов": 19259, - "alarmed": 19260, - "archaic": 19261, - "inverse": 19262, - "##leton": 19263, - "explorers": 19264, - "##pine": 19265, - "drummond": 19266, - "tsunami": 19267, - "woodlands": 19268, - "##minate": 19269, - "##tland": 19270, - "booklet": 19271, - "insanity": 19272, - "owning": 19273, - "insert": 19274, - "crafted": 19275, - "calculus": 19276, - "##tore": 19277, - "receivers": 19278, - "##bt": 19279, - "stung": 19280, - "##eca": 19281, - "##nched": 19282, - "prevailing": 19283, - "travellers": 19284, - "eyeing": 19285, - "lila": 19286, - "graphs": 19287, - "##borne": 19288, - "178": 19289, - "julien": 19290, - "##won": 19291, - "morale": 19292, - "adaptive": 19293, - "therapist": 19294, - "erica": 19295, - "cw": 19296, - "libertarian": 19297, - "bowman": 19298, - "pitches": 19299, - "vita": 19300, - "##ional": 19301, - "crook": 19302, - "##ads": 19303, - "##entation": 19304, - "caledonia": 19305, - "mutiny": 19306, - "##sible": 19307, - "1840s": 19308, - "automation": 19309, - "##ß": 19310, - "flock": 19311, - "##pia": 19312, - "ironic": 19313, - "pathology": 19314, - "##imus": 19315, - "remarried": 19316, - "##22": 19317, - "joker": 19318, - "withstand": 19319, - "energies": 19320, - "##att": 19321, - "shropshire": 19322, - "hostages": 19323, - "madeleine": 19324, - "tentatively": 19325, - "conflicting": 19326, - "mateo": 19327, - "recipes": 19328, - "euros": 19329, - "ol": 19330, - "mercenaries": 19331, - "nico": 19332, - "##ndon": 19333, - "albuquerque": 19334, - "augmented": 19335, - "mythical": 19336, - "bel": 19337, - "freud": 19338, - "##child": 19339, - "cough": 19340, - "##lica": 19341, - "365": 19342, - "freddy": 19343, - "lillian": 19344, - "genetically": 19345, - "nuremberg": 19346, - "calder": 19347, - "209": 19348, - "bonn": 19349, - "outdoors": 19350, - "paste": 19351, - "suns": 19352, - "urgency": 19353, - "vin": 19354, - "restraint": 19355, - "tyson": 19356, - "##cera": 19357, - "##selle": 19358, - "barrage": 19359, - "bethlehem": 19360, - "kahn": 19361, - "##par": 19362, - "mounts": 19363, - "nippon": 19364, - "barony": 19365, - "happier": 19366, - "ryu": 19367, - "makeshift": 19368, - "sheldon": 19369, - "blushed": 19370, - "castillo": 19371, - "barking": 19372, - "listener": 19373, - "taped": 19374, - "bethel": 19375, - "fluent": 19376, - "headlines": 19377, - "pornography": 19378, - "rum": 19379, - "disclosure": 19380, - "sighing": 19381, - "mace": 19382, - "doubling": 19383, - "gunther": 19384, - "manly": 19385, - "##plex": 19386, - "rt": 19387, - "interventions": 19388, - "physiological": 19389, - "forwards": 19390, - "emerges": 19391, - "##tooth": 19392, - "##gny": 19393, - "compliment": 19394, - "rib": 19395, - "recession": 19396, - "visibly": 19397, - "barge": 19398, - "faults": 19399, - "connector": 19400, - "exquisite": 19401, - "prefect": 19402, - "##rlin": 19403, - "patio": 19404, - "##cured": 19405, - "elevators": 19406, - "brandt": 19407, - "italics": 19408, - "pena": 19409, - "173": 19410, - "wasp": 19411, - "satin": 19412, - "ea": 19413, - "botswana": 19414, - "graceful": 19415, - "respectable": 19416, - "##jima": 19417, - "##rter": 19418, - "##oic": 19419, - "franciscan": 19420, - "generates": 19421, - "##dl": 19422, - "alfredo": 19423, - "disgusting": 19424, - "##olate": 19425, - "##iously": 19426, - "sherwood": 19427, - "warns": 19428, - "cod": 19429, - "promo": 19430, - "cheryl": 19431, - "sino": 19432, - "##ة": 19433, - "##escu": 19434, - "twitch": 19435, - "##zhi": 19436, - "brownish": 19437, - "thom": 19438, - "ortiz": 19439, - "##dron": 19440, - "densely": 19441, - "##beat": 19442, - "carmel": 19443, - "reinforce": 19444, - "##bana": 19445, - "187": 19446, - "anastasia": 19447, - "downhill": 19448, - "vertex": 19449, - "contaminated": 19450, - "remembrance": 19451, - "harmonic": 19452, - "homework": 19453, - "##sol": 19454, - "fiancee": 19455, - "gears": 19456, - "olds": 19457, - "angelica": 19458, - "loft": 19459, - "ramsay": 19460, - "quiz": 19461, - "colliery": 19462, - "sevens": 19463, - "##cape": 19464, - "autism": 19465, - "##hil": 19466, - "walkway": 19467, - "##boats": 19468, - "ruben": 19469, - "abnormal": 19470, - "ounce": 19471, - "khmer": 19472, - "##bbe": 19473, - "zachary": 19474, - "bedside": 19475, - "morphology": 19476, - "punching": 19477, - "##olar": 19478, - "sparrow": 19479, - "convinces": 19480, - "##35": 19481, - "hewitt": 19482, - "queer": 19483, - "remastered": 19484, - "rods": 19485, - "mabel": 19486, - "solemn": 19487, - "notified": 19488, - "lyricist": 19489, - "symmetric": 19490, - "##xide": 19491, - "174": 19492, - "encore": 19493, - "passports": 19494, - "wildcats": 19495, - "##uni": 19496, - "baja": 19497, - "##pac": 19498, - "mildly": 19499, - "##ease": 19500, - "bleed": 19501, - "commodity": 19502, - "mounds": 19503, - "glossy": 19504, - "orchestras": 19505, - "##omo": 19506, - "damian": 19507, - "prelude": 19508, - "ambitions": 19509, - "##vet": 19510, - "awhile": 19511, - "remotely": 19512, - "##aud": 19513, - "asserts": 19514, - "imply": 19515, - "##iques": 19516, - "distinctly": 19517, - "modelling": 19518, - "remedy": 19519, - "##dded": 19520, - "windshield": 19521, - "dani": 19522, - "xiao": 19523, - "##endra": 19524, - "audible": 19525, - "powerplant": 19526, - "1300": 19527, - "invalid": 19528, - "elemental": 19529, - "acquisitions": 19530, - "##hala": 19531, - "immaculate": 19532, - "libby": 19533, - "plata": 19534, - "smuggling": 19535, - "ventilation": 19536, - "denoted": 19537, - "minh": 19538, - "##morphism": 19539, - "430": 19540, - "differed": 19541, - "dion": 19542, - "kelley": 19543, - "lore": 19544, - "mocking": 19545, - "sabbath": 19546, - "spikes": 19547, - "hygiene": 19548, - "drown": 19549, - "runoff": 19550, - "stylized": 19551, - "tally": 19552, - "liberated": 19553, - "aux": 19554, - "interpreter": 19555, - "righteous": 19556, - "aba": 19557, - "siren": 19558, - "reaper": 19559, - "pearce": 19560, - "millie": 19561, - "##cier": 19562, - "##yra": 19563, - "gaius": 19564, - "##iso": 19565, - "captures": 19566, - "##ttering": 19567, - "dorm": 19568, - "claudio": 19569, - "##sic": 19570, - "benches": 19571, - "knighted": 19572, - "blackness": 19573, - "##ored": 19574, - "discount": 19575, - "fumble": 19576, - "oxidation": 19577, - "routed": 19578, - "##ς": 19579, - "novak": 19580, - "perpendicular": 19581, - "spoiled": 19582, - "fracture": 19583, - "splits": 19584, - "##urt": 19585, - "pads": 19586, - "topology": 19587, - "##cats": 19588, - "axes": 19589, - "fortunate": 19590, - "offenders": 19591, - "protestants": 19592, - "esteem": 19593, - "221": 19594, - "broadband": 19595, - "convened": 19596, - "frankly": 19597, - "hound": 19598, - "prototypes": 19599, - "isil": 19600, - "facilitated": 19601, - "keel": 19602, - "##sher": 19603, - "sahara": 19604, - "awaited": 19605, - "bubba": 19606, - "orb": 19607, - "prosecutors": 19608, - "186": 19609, - "hem": 19610, - "520": 19611, - "##xing": 19612, - "relaxing": 19613, - "remnant": 19614, - "romney": 19615, - "sorted": 19616, - "slalom": 19617, - "stefano": 19618, - "ulrich": 19619, - "##active": 19620, - "exemption": 19621, - "folder": 19622, - "pauses": 19623, - "foliage": 19624, - "hitchcock": 19625, - "epithet": 19626, - "204": 19627, - "criticisms": 19628, - "##aca": 19629, - "ballistic": 19630, - "brody": 19631, - "hinduism": 19632, - "chaotic": 19633, - "youths": 19634, - "equals": 19635, - "##pala": 19636, - "pts": 19637, - "thicker": 19638, - "analogous": 19639, - "capitalist": 19640, - "improvised": 19641, - "overseeing": 19642, - "sinatra": 19643, - "ascended": 19644, - "beverage": 19645, - "##tl": 19646, - "straightforward": 19647, - "##kon": 19648, - "curran": 19649, - "##west": 19650, - "bois": 19651, - "325": 19652, - "induce": 19653, - "surveying": 19654, - "emperors": 19655, - "sax": 19656, - "unpopular": 19657, - "##kk": 19658, - "cartoonist": 19659, - "fused": 19660, - "##mble": 19661, - "unto": 19662, - "##yuki": 19663, - "localities": 19664, - "##cko": 19665, - "##ln": 19666, - "darlington": 19667, - "slain": 19668, - "academie": 19669, - "lobbying": 19670, - "sediment": 19671, - "puzzles": 19672, - "##grass": 19673, - "defiance": 19674, - "dickens": 19675, - "manifest": 19676, - "tongues": 19677, - "alumnus": 19678, - "arbor": 19679, - "coincide": 19680, - "184": 19681, - "appalachian": 19682, - "mustafa": 19683, - "examiner": 19684, - "cabaret": 19685, - "traumatic": 19686, - "yves": 19687, - "bracelet": 19688, - "draining": 19689, - "heroin": 19690, - "magnum": 19691, - "baths": 19692, - "odessa": 19693, - "consonants": 19694, - "mitsubishi": 19695, - "##gua": 19696, - "kellan": 19697, - "vaudeville": 19698, - "##fr": 19699, - "joked": 19700, - "null": 19701, - "straps": 19702, - "probation": 19703, - "##ław": 19704, - "ceded": 19705, - "interfaces": 19706, - "##pas": 19707, - "##zawa": 19708, - "blinding": 19709, - "viet": 19710, - "224": 19711, - "rothschild": 19712, - "museo": 19713, - "640": 19714, - "huddersfield": 19715, - "##vr": 19716, - "tactic": 19717, - "##storm": 19718, - "brackets": 19719, - "dazed": 19720, - "incorrectly": 19721, - "##vu": 19722, - "reg": 19723, - "glazed": 19724, - "fearful": 19725, - "manifold": 19726, - "benefited": 19727, - "irony": 19728, - "##sun": 19729, - "stumbling": 19730, - "##rte": 19731, - "willingness": 19732, - "balkans": 19733, - "mei": 19734, - "wraps": 19735, - "##aba": 19736, - "injected": 19737, - "##lea": 19738, - "gu": 19739, - "syed": 19740, - "harmless": 19741, - "##hammer": 19742, - "bray": 19743, - "takeoff": 19744, - "poppy": 19745, - "timor": 19746, - "cardboard": 19747, - "astronaut": 19748, - "purdue": 19749, - "weeping": 19750, - "southbound": 19751, - "cursing": 19752, - "stalls": 19753, - "diagonal": 19754, - "##neer": 19755, - "lamar": 19756, - "bryce": 19757, - "comte": 19758, - "weekdays": 19759, - "harrington": 19760, - "##uba": 19761, - "negatively": 19762, - "##see": 19763, - "lays": 19764, - "grouping": 19765, - "##cken": 19766, - "##henko": 19767, - "affirmed": 19768, - "halle": 19769, - "modernist": 19770, - "##lai": 19771, - "hodges": 19772, - "smelling": 19773, - "aristocratic": 19774, - "baptized": 19775, - "dismiss": 19776, - "justification": 19777, - "oilers": 19778, - "##now": 19779, - "coupling": 19780, - "qin": 19781, - "snack": 19782, - "healer": 19783, - "##qing": 19784, - "gardener": 19785, - "layla": 19786, - "battled": 19787, - "formulated": 19788, - "stephenson": 19789, - "gravitational": 19790, - "##gill": 19791, - "##jun": 19792, - "1768": 19793, - "granny": 19794, - "coordinating": 19795, - "suites": 19796, - "##cd": 19797, - "##ioned": 19798, - "monarchs": 19799, - "##cote": 19800, - "##hips": 19801, - "sep": 19802, - "blended": 19803, - "apr": 19804, - "barrister": 19805, - "deposition": 19806, - "fia": 19807, - "mina": 19808, - "policemen": 19809, - "paranoid": 19810, - "##pressed": 19811, - "churchyard": 19812, - "covert": 19813, - "crumpled": 19814, - "creep": 19815, - "abandoning": 19816, - "tr": 19817, - "transmit": 19818, - "conceal": 19819, - "barr": 19820, - "understands": 19821, - "readiness": 19822, - "spire": 19823, - "##cology": 19824, - "##enia": 19825, - "##erry": 19826, - "610": 19827, - "startling": 19828, - "unlock": 19829, - "vida": 19830, - "bowled": 19831, - "slots": 19832, - "##nat": 19833, - "##islav": 19834, - "spaced": 19835, - "trusting": 19836, - "admire": 19837, - "rig": 19838, - "##ink": 19839, - "slack": 19840, - "##70": 19841, - "mv": 19842, - "207": 19843, - "casualty": 19844, - "##wei": 19845, - "classmates": 19846, - "##odes": 19847, - "##rar": 19848, - "##rked": 19849, - "amherst": 19850, - "furnished": 19851, - "evolve": 19852, - "foundry": 19853, - "menace": 19854, - "mead": 19855, - "##lein": 19856, - "flu": 19857, - "wesleyan": 19858, - "##kled": 19859, - "monterey": 19860, - "webber": 19861, - "##vos": 19862, - "wil": 19863, - "##mith": 19864, - "##на": 19865, - "bartholomew": 19866, - "justices": 19867, - "restrained": 19868, - "##cke": 19869, - "amenities": 19870, - "191": 19871, - "mediated": 19872, - "sewage": 19873, - "trenches": 19874, - "ml": 19875, - "mainz": 19876, - "##thus": 19877, - "1800s": 19878, - "##cula": 19879, - "##inski": 19880, - "caine": 19881, - "bonding": 19882, - "213": 19883, - "converts": 19884, - "spheres": 19885, - "superseded": 19886, - "marianne": 19887, - "crypt": 19888, - "sweaty": 19889, - "ensign": 19890, - "historia": 19891, - "##br": 19892, - "spruce": 19893, - "##post": 19894, - "##ask": 19895, - "forks": 19896, - "thoughtfully": 19897, - "yukon": 19898, - "pamphlet": 19899, - "ames": 19900, - "##uter": 19901, - "karma": 19902, - "##yya": 19903, - "bryn": 19904, - "negotiation": 19905, - "sighs": 19906, - "incapable": 19907, - "##mbre": 19908, - "##ntial": 19909, - "actresses": 19910, - "taft": 19911, - "##mill": 19912, - "luce": 19913, - "prevailed": 19914, - "##amine": 19915, - "1773": 19916, - "motionless": 19917, - "envoy": 19918, - "testify": 19919, - "investing": 19920, - "sculpted": 19921, - "instructors": 19922, - "provence": 19923, - "kali": 19924, - "cullen": 19925, - "horseback": 19926, - "##while": 19927, - "goodwin": 19928, - "##jos": 19929, - "gaa": 19930, - "norte": 19931, - "##ldon": 19932, - "modify": 19933, - "wavelength": 19934, - "abd": 19935, - "214": 19936, - "skinned": 19937, - "sprinter": 19938, - "forecast": 19939, - "scheduling": 19940, - "marries": 19941, - "squared": 19942, - "tentative": 19943, - "##chman": 19944, - "boer": 19945, - "##isch": 19946, - "bolts": 19947, - "swap": 19948, - "fisherman": 19949, - "assyrian": 19950, - "impatiently": 19951, - "guthrie": 19952, - "martins": 19953, - "murdoch": 19954, - "194": 19955, - "tanya": 19956, - "nicely": 19957, - "dolly": 19958, - "lacy": 19959, - "med": 19960, - "##45": 19961, - "syn": 19962, - "decks": 19963, - "fashionable": 19964, - "millionaire": 19965, - "##ust": 19966, - "surfing": 19967, - "##ml": 19968, - "##ision": 19969, - "heaved": 19970, - "tammy": 19971, - "consulate": 19972, - "attendees": 19973, - "routinely": 19974, - "197": 19975, - "fuse": 19976, - "saxophonist": 19977, - "backseat": 19978, - "malaya": 19979, - "##lord": 19980, - "scowl": 19981, - "tau": 19982, - "##ishly": 19983, - "193": 19984, - "sighted": 19985, - "steaming": 19986, - "##rks": 19987, - "303": 19988, - "911": 19989, - "##holes": 19990, - "##hong": 19991, - "ching": 19992, - "##wife": 19993, - "bless": 19994, - "conserved": 19995, - "jurassic": 19996, - "stacey": 19997, - "unix": 19998, - "zion": 19999, - "chunk": 20000, - "rigorous": 20001, - "blaine": 20002, - "198": 20003, - "peabody": 20004, - "slayer": 20005, - "dismay": 20006, - "brewers": 20007, - "nz": 20008, - "##jer": 20009, - "det": 20010, - "##glia": 20011, - "glover": 20012, - "postwar": 20013, - "int": 20014, - "penetration": 20015, - "sylvester": 20016, - "imitation": 20017, - "vertically": 20018, - "airlift": 20019, - "heiress": 20020, - "knoxville": 20021, - "viva": 20022, - "##uin": 20023, - "390": 20024, - "macon": 20025, - "##rim": 20026, - "##fighter": 20027, - "##gonal": 20028, - "janice": 20029, - "##orescence": 20030, - "##wari": 20031, - "marius": 20032, - "belongings": 20033, - "leicestershire": 20034, - "196": 20035, - "blanco": 20036, - "inverted": 20037, - "preseason": 20038, - "sanity": 20039, - "sobbing": 20040, - "##due": 20041, - "##elt": 20042, - "##dled": 20043, - "collingwood": 20044, - "regeneration": 20045, - "flickering": 20046, - "shortest": 20047, - "##mount": 20048, - "##osi": 20049, - "feminism": 20050, - "##lat": 20051, - "sherlock": 20052, - "cabinets": 20053, - "fumbled": 20054, - "northbound": 20055, - "precedent": 20056, - "snaps": 20057, - "##mme": 20058, - "researching": 20059, - "##akes": 20060, - "guillaume": 20061, - "insights": 20062, - "manipulated": 20063, - "vapor": 20064, - "neighbour": 20065, - "sap": 20066, - "gangster": 20067, - "frey": 20068, - "f1": 20069, - "stalking": 20070, - "scarcely": 20071, - "callie": 20072, - "barnett": 20073, - "tendencies": 20074, - "audi": 20075, - "doomed": 20076, - "assessing": 20077, - "slung": 20078, - "panchayat": 20079, - "ambiguous": 20080, - "bartlett": 20081, - "##etto": 20082, - "distributing": 20083, - "violating": 20084, - "wolverhampton": 20085, - "##hetic": 20086, - "swami": 20087, - "histoire": 20088, - "##urus": 20089, - "liable": 20090, - "pounder": 20091, - "groin": 20092, - "hussain": 20093, - "larsen": 20094, - "popping": 20095, - "surprises": 20096, - "##atter": 20097, - "vie": 20098, - "curt": 20099, - "##station": 20100, - "mute": 20101, - "relocate": 20102, - "musicals": 20103, - "authorization": 20104, - "richter": 20105, - "##sef": 20106, - "immortality": 20107, - "tna": 20108, - "bombings": 20109, - "##press": 20110, - "deteriorated": 20111, - "yiddish": 20112, - "##acious": 20113, - "robbed": 20114, - "colchester": 20115, - "cs": 20116, - "pmid": 20117, - "ao": 20118, - "verified": 20119, - "balancing": 20120, - "apostle": 20121, - "swayed": 20122, - "recognizable": 20123, - "oxfordshire": 20124, - "retention": 20125, - "nottinghamshire": 20126, - "contender": 20127, - "judd": 20128, - "invitational": 20129, - "shrimp": 20130, - "uhf": 20131, - "##icient": 20132, - "cleaner": 20133, - "longitudinal": 20134, - "tanker": 20135, - "##mur": 20136, - "acronym": 20137, - "broker": 20138, - "koppen": 20139, - "sundance": 20140, - "suppliers": 20141, - "##gil": 20142, - "4000": 20143, - "clipped": 20144, - "fuels": 20145, - "petite": 20146, - "##anne": 20147, - "landslide": 20148, - "helene": 20149, - "diversion": 20150, - "populous": 20151, - "landowners": 20152, - "auspices": 20153, - "melville": 20154, - "quantitative": 20155, - "##xes": 20156, - "ferries": 20157, - "nicky": 20158, - "##llus": 20159, - "doo": 20160, - "haunting": 20161, - "roche": 20162, - "carver": 20163, - "downed": 20164, - "unavailable": 20165, - "##pathy": 20166, - "approximation": 20167, - "hiroshima": 20168, - "##hue": 20169, - "garfield": 20170, - "valle": 20171, - "comparatively": 20172, - "keyboardist": 20173, - "traveler": 20174, - "##eit": 20175, - "congestion": 20176, - "calculating": 20177, - "subsidiaries": 20178, - "##bate": 20179, - "serb": 20180, - "modernization": 20181, - "fairies": 20182, - "deepened": 20183, - "ville": 20184, - "averages": 20185, - "##lore": 20186, - "inflammatory": 20187, - "tonga": 20188, - "##itch": 20189, - "co₂": 20190, - "squads": 20191, - "##hea": 20192, - "gigantic": 20193, - "serum": 20194, - "enjoyment": 20195, - "retailer": 20196, - "verona": 20197, - "35th": 20198, - "cis": 20199, - "##phobic": 20200, - "magna": 20201, - "technicians": 20202, - "##vati": 20203, - "arithmetic": 20204, - "##sport": 20205, - "levin": 20206, - "##dation": 20207, - "amtrak": 20208, - "chow": 20209, - "sienna": 20210, - "##eyer": 20211, - "backstage": 20212, - "entrepreneurship": 20213, - "##otic": 20214, - "learnt": 20215, - "tao": 20216, - "##udy": 20217, - "worcestershire": 20218, - "formulation": 20219, - "baggage": 20220, - "hesitant": 20221, - "bali": 20222, - "sabotage": 20223, - "##kari": 20224, - "barren": 20225, - "enhancing": 20226, - "murmur": 20227, - "pl": 20228, - "freshly": 20229, - "putnam": 20230, - "syntax": 20231, - "aces": 20232, - "medicines": 20233, - "resentment": 20234, - "bandwidth": 20235, - "##sier": 20236, - "grins": 20237, - "chili": 20238, - "guido": 20239, - "##sei": 20240, - "framing": 20241, - "implying": 20242, - "gareth": 20243, - "lissa": 20244, - "genevieve": 20245, - "pertaining": 20246, - "admissions": 20247, - "geo": 20248, - "thorpe": 20249, - "proliferation": 20250, - "sato": 20251, - "bela": 20252, - "analyzing": 20253, - "parting": 20254, - "##gor": 20255, - "awakened": 20256, - "##isman": 20257, - "huddled": 20258, - "secrecy": 20259, - "##kling": 20260, - "hush": 20261, - "gentry": 20262, - "540": 20263, - "dungeons": 20264, - "##ego": 20265, - "coasts": 20266, - "##utz": 20267, - "sacrificed": 20268, - "##chule": 20269, - "landowner": 20270, - "mutually": 20271, - "prevalence": 20272, - "programmer": 20273, - "adolescent": 20274, - "disrupted": 20275, - "seaside": 20276, - "gee": 20277, - "trusts": 20278, - "vamp": 20279, - "georgie": 20280, - "##nesian": 20281, - "##iol": 20282, - "schedules": 20283, - "sindh": 20284, - "##market": 20285, - "etched": 20286, - "hm": 20287, - "sparse": 20288, - "bey": 20289, - "beaux": 20290, - "scratching": 20291, - "gliding": 20292, - "unidentified": 20293, - "216": 20294, - "collaborating": 20295, - "gems": 20296, - "jesuits": 20297, - "oro": 20298, - "accumulation": 20299, - "shaping": 20300, - "mbe": 20301, - "anal": 20302, - "##xin": 20303, - "231": 20304, - "enthusiasts": 20305, - "newscast": 20306, - "##egan": 20307, - "janata": 20308, - "dewey": 20309, - "parkinson": 20310, - "179": 20311, - "ankara": 20312, - "biennial": 20313, - "towering": 20314, - "dd": 20315, - "inconsistent": 20316, - "950": 20317, - "##chet": 20318, - "thriving": 20319, - "terminate": 20320, - "cabins": 20321, - "furiously": 20322, - "eats": 20323, - "advocating": 20324, - "donkey": 20325, - "marley": 20326, - "muster": 20327, - "phyllis": 20328, - "leiden": 20329, - "##user": 20330, - "grassland": 20331, - "glittering": 20332, - "iucn": 20333, - "loneliness": 20334, - "217": 20335, - "memorandum": 20336, - "armenians": 20337, - "##ddle": 20338, - "popularized": 20339, - "rhodesia": 20340, - "60s": 20341, - "lame": 20342, - "##illon": 20343, - "sans": 20344, - "bikini": 20345, - "header": 20346, - "orbits": 20347, - "##xx": 20348, - "##finger": 20349, - "##ulator": 20350, - "sharif": 20351, - "spines": 20352, - "biotechnology": 20353, - "strolled": 20354, - "naughty": 20355, - "yates": 20356, - "##wire": 20357, - "fremantle": 20358, - "milo": 20359, - "##mour": 20360, - "abducted": 20361, - "removes": 20362, - "##atin": 20363, - "humming": 20364, - "wonderland": 20365, - "##chrome": 20366, - "##ester": 20367, - "hume": 20368, - "pivotal": 20369, - "##rates": 20370, - "armand": 20371, - "grams": 20372, - "believers": 20373, - "elector": 20374, - "rte": 20375, - "apron": 20376, - "bis": 20377, - "scraped": 20378, - "##yria": 20379, - "endorsement": 20380, - "initials": 20381, - "##llation": 20382, - "eps": 20383, - "dotted": 20384, - "hints": 20385, - "buzzing": 20386, - "emigration": 20387, - "nearer": 20388, - "##tom": 20389, - "indicators": 20390, - "##ulu": 20391, - "coarse": 20392, - "neutron": 20393, - "protectorate": 20394, - "##uze": 20395, - "directional": 20396, - "exploits": 20397, - "pains": 20398, - "loire": 20399, - "1830s": 20400, - "proponents": 20401, - "guggenheim": 20402, - "rabbits": 20403, - "ritchie": 20404, - "305": 20405, - "hectare": 20406, - "inputs": 20407, - "hutton": 20408, - "##raz": 20409, - "verify": 20410, - "##ako": 20411, - "boilers": 20412, - "longitude": 20413, - "##lev": 20414, - "skeletal": 20415, - "yer": 20416, - "emilia": 20417, - "citrus": 20418, - "compromised": 20419, - "##gau": 20420, - "pokemon": 20421, - "prescription": 20422, - "paragraph": 20423, - "eduard": 20424, - "cadillac": 20425, - "attire": 20426, - "categorized": 20427, - "kenyan": 20428, - "weddings": 20429, - "charley": 20430, - "##bourg": 20431, - "entertain": 20432, - "monmouth": 20433, - "##lles": 20434, - "nutrients": 20435, - "davey": 20436, - "mesh": 20437, - "incentive": 20438, - "practised": 20439, - "ecosystems": 20440, - "kemp": 20441, - "subdued": 20442, - "overheard": 20443, - "##rya": 20444, - "bodily": 20445, - "maxim": 20446, - "##nius": 20447, - "apprenticeship": 20448, - "ursula": 20449, - "##fight": 20450, - "lodged": 20451, - "rug": 20452, - "silesian": 20453, - "unconstitutional": 20454, - "patel": 20455, - "inspected": 20456, - "coyote": 20457, - "unbeaten": 20458, - "##hak": 20459, - "34th": 20460, - "disruption": 20461, - "convict": 20462, - "parcel": 20463, - "##cl": 20464, - "##nham": 20465, - "collier": 20466, - "implicated": 20467, - "mallory": 20468, - "##iac": 20469, - "##lab": 20470, - "susannah": 20471, - "winkler": 20472, - "##rber": 20473, - "shia": 20474, - "phelps": 20475, - "sediments": 20476, - "graphical": 20477, - "robotic": 20478, - "##sner": 20479, - "adulthood": 20480, - "mart": 20481, - "smoked": 20482, - "##isto": 20483, - "kathryn": 20484, - "clarified": 20485, - "##aran": 20486, - "divides": 20487, - "convictions": 20488, - "oppression": 20489, - "pausing": 20490, - "burying": 20491, - "##mt": 20492, - "federico": 20493, - "mathias": 20494, - "eileen": 20495, - "##tana": 20496, - "kite": 20497, - "hunched": 20498, - "##acies": 20499, - "189": 20500, - "##atz": 20501, - "disadvantage": 20502, - "liza": 20503, - "kinetic": 20504, - "greedy": 20505, - "paradox": 20506, - "yokohama": 20507, - "dowager": 20508, - "trunks": 20509, - "ventured": 20510, - "##gement": 20511, - "gupta": 20512, - "vilnius": 20513, - "olaf": 20514, - "##thest": 20515, - "crimean": 20516, - "hopper": 20517, - "##ej": 20518, - "progressively": 20519, - "arturo": 20520, - "mouthed": 20521, - "arrondissement": 20522, - "##fusion": 20523, - "rubin": 20524, - "simulcast": 20525, - "oceania": 20526, - "##orum": 20527, - "##stra": 20528, - "##rred": 20529, - "busiest": 20530, - "intensely": 20531, - "navigator": 20532, - "cary": 20533, - "##vine": 20534, - "##hini": 20535, - "##bies": 20536, - "fife": 20537, - "rowe": 20538, - "rowland": 20539, - "posing": 20540, - "insurgents": 20541, - "shafts": 20542, - "lawsuits": 20543, - "activate": 20544, - "conor": 20545, - "inward": 20546, - "culturally": 20547, - "garlic": 20548, - "265": 20549, - "##eering": 20550, - "eclectic": 20551, - "##hui": 20552, - "##kee": 20553, - "##nl": 20554, - "furrowed": 20555, - "vargas": 20556, - "meteorological": 20557, - "rendezvous": 20558, - "##aus": 20559, - "culinary": 20560, - "commencement": 20561, - "##dition": 20562, - "quota": 20563, - "##notes": 20564, - "mommy": 20565, - "salaries": 20566, - "overlapping": 20567, - "mule": 20568, - "##iology": 20569, - "##mology": 20570, - "sums": 20571, - "wentworth": 20572, - "##isk": 20573, - "##zione": 20574, - "mainline": 20575, - "subgroup": 20576, - "##illy": 20577, - "hack": 20578, - "plaintiff": 20579, - "verdi": 20580, - "bulb": 20581, - "differentiation": 20582, - "engagements": 20583, - "multinational": 20584, - "supplemented": 20585, - "bertrand": 20586, - "caller": 20587, - "regis": 20588, - "##naire": 20589, - "##sler": 20590, - "##arts": 20591, - "##imated": 20592, - "blossom": 20593, - "propagation": 20594, - "kilometer": 20595, - "viaduct": 20596, - "vineyards": 20597, - "##uate": 20598, - "beckett": 20599, - "optimization": 20600, - "golfer": 20601, - "songwriters": 20602, - "seminal": 20603, - "semitic": 20604, - "thud": 20605, - "volatile": 20606, - "evolving": 20607, - "ridley": 20608, - "##wley": 20609, - "trivial": 20610, - "distributions": 20611, - "scandinavia": 20612, - "jiang": 20613, - "##ject": 20614, - "wrestled": 20615, - "insistence": 20616, - "##dio": 20617, - "emphasizes": 20618, - "napkin": 20619, - "##ods": 20620, - "adjunct": 20621, - "rhyme": 20622, - "##ricted": 20623, - "##eti": 20624, - "hopeless": 20625, - "surrounds": 20626, - "tremble": 20627, - "32nd": 20628, - "smoky": 20629, - "##ntly": 20630, - "oils": 20631, - "medicinal": 20632, - "padded": 20633, - "steer": 20634, - "wilkes": 20635, - "219": 20636, - "255": 20637, - "concessions": 20638, - "hue": 20639, - "uniquely": 20640, - "blinded": 20641, - "landon": 20642, - "yahoo": 20643, - "##lane": 20644, - "hendrix": 20645, - "commemorating": 20646, - "dex": 20647, - "specify": 20648, - "chicks": 20649, - "##ggio": 20650, - "intercity": 20651, - "1400": 20652, - "morley": 20653, - "##torm": 20654, - "highlighting": 20655, - "##oting": 20656, - "pang": 20657, - "oblique": 20658, - "stalled": 20659, - "##liner": 20660, - "flirting": 20661, - "newborn": 20662, - "1769": 20663, - "bishopric": 20664, - "shaved": 20665, - "232": 20666, - "currie": 20667, - "##ush": 20668, - "dharma": 20669, - "spartan": 20670, - "##ooped": 20671, - "favorites": 20672, - "smug": 20673, - "novella": 20674, - "sirens": 20675, - "abusive": 20676, - "creations": 20677, - "espana": 20678, - "##lage": 20679, - "paradigm": 20680, - "semiconductor": 20681, - "sheen": 20682, - "##rdo": 20683, - "##yen": 20684, - "##zak": 20685, - "nrl": 20686, - "renew": 20687, - "##pose": 20688, - "##tur": 20689, - "adjutant": 20690, - "marches": 20691, - "norma": 20692, - "##enity": 20693, - "ineffective": 20694, - "weimar": 20695, - "grunt": 20696, - "##gat": 20697, - "lordship": 20698, - "plotting": 20699, - "expenditure": 20700, - "infringement": 20701, - "lbs": 20702, - "refrain": 20703, - "av": 20704, - "mimi": 20705, - "mistakenly": 20706, - "postmaster": 20707, - "1771": 20708, - "##bara": 20709, - "ras": 20710, - "motorsports": 20711, - "tito": 20712, - "199": 20713, - "subjective": 20714, - "##zza": 20715, - "bully": 20716, - "stew": 20717, - "##kaya": 20718, - "prescott": 20719, - "1a": 20720, - "##raphic": 20721, - "##zam": 20722, - "bids": 20723, - "styling": 20724, - "paranormal": 20725, - "reeve": 20726, - "sneaking": 20727, - "exploding": 20728, - "katz": 20729, - "akbar": 20730, - "migrant": 20731, - "syllables": 20732, - "indefinitely": 20733, - "##ogical": 20734, - "destroys": 20735, - "replaces": 20736, - "applause": 20737, - "##phine": 20738, - "pest": 20739, - "##fide": 20740, - "218": 20741, - "articulated": 20742, - "bertie": 20743, - "##thing": 20744, - "##cars": 20745, - "##ptic": 20746, - "courtroom": 20747, - "crowley": 20748, - "aesthetics": 20749, - "cummings": 20750, - "tehsil": 20751, - "hormones": 20752, - "titanic": 20753, - "dangerously": 20754, - "##ibe": 20755, - "stadion": 20756, - "jaenelle": 20757, - "auguste": 20758, - "ciudad": 20759, - "##chu": 20760, - "mysore": 20761, - "partisans": 20762, - "##sio": 20763, - "lucan": 20764, - "philipp": 20765, - "##aly": 20766, - "debating": 20767, - "henley": 20768, - "interiors": 20769, - "##rano": 20770, - "##tious": 20771, - "homecoming": 20772, - "beyonce": 20773, - "usher": 20774, - "henrietta": 20775, - "prepares": 20776, - "weeds": 20777, - "##oman": 20778, - "ely": 20779, - "plucked": 20780, - "##pire": 20781, - "##dable": 20782, - "luxurious": 20783, - "##aq": 20784, - "artifact": 20785, - "password": 20786, - "pasture": 20787, - "juno": 20788, - "maddy": 20789, - "minsk": 20790, - "##dder": 20791, - "##ologies": 20792, - "##rone": 20793, - "assessments": 20794, - "martian": 20795, - "royalist": 20796, - "1765": 20797, - "examines": 20798, - "##mani": 20799, - "##rge": 20800, - "nino": 20801, - "223": 20802, - "parry": 20803, - "scooped": 20804, - "relativity": 20805, - "##eli": 20806, - "##uting": 20807, - "##cao": 20808, - "congregational": 20809, - "noisy": 20810, - "traverse": 20811, - "##agawa": 20812, - "strikeouts": 20813, - "nickelodeon": 20814, - "obituary": 20815, - "transylvania": 20816, - "binds": 20817, - "depictions": 20818, - "polk": 20819, - "trolley": 20820, - "##yed": 20821, - "##lard": 20822, - "breeders": 20823, - "##under": 20824, - "dryly": 20825, - "hokkaido": 20826, - "1762": 20827, - "strengths": 20828, - "stacks": 20829, - "bonaparte": 20830, - "connectivity": 20831, - "neared": 20832, - "prostitutes": 20833, - "stamped": 20834, - "anaheim": 20835, - "gutierrez": 20836, - "sinai": 20837, - "##zzling": 20838, - "bram": 20839, - "fresno": 20840, - "madhya": 20841, - "##86": 20842, - "proton": 20843, - "##lena": 20844, - "##llum": 20845, - "##phon": 20846, - "reelected": 20847, - "wanda": 20848, - "##anus": 20849, - "##lb": 20850, - "ample": 20851, - "distinguishing": 20852, - "##yler": 20853, - "grasping": 20854, - "sermons": 20855, - "tomato": 20856, - "bland": 20857, - "stimulation": 20858, - "avenues": 20859, - "##eux": 20860, - "spreads": 20861, - "scarlett": 20862, - "fern": 20863, - "pentagon": 20864, - "assert": 20865, - "baird": 20866, - "chesapeake": 20867, - "ir": 20868, - "calmed": 20869, - "distortion": 20870, - "fatalities": 20871, - "##olis": 20872, - "correctional": 20873, - "pricing": 20874, - "##astic": 20875, - "##gina": 20876, - "prom": 20877, - "dammit": 20878, - "ying": 20879, - "collaborate": 20880, - "##chia": 20881, - "welterweight": 20882, - "33rd": 20883, - "pointer": 20884, - "substitution": 20885, - "bonded": 20886, - "umpire": 20887, - "communicating": 20888, - "multitude": 20889, - "paddle": 20890, - "##obe": 20891, - "federally": 20892, - "intimacy": 20893, - "##insky": 20894, - "betray": 20895, - "ssr": 20896, - "##lett": 20897, - "##lean": 20898, - "##lves": 20899, - "##therapy": 20900, - "airbus": 20901, - "##tery": 20902, - "functioned": 20903, - "ud": 20904, - "bearer": 20905, - "biomedical": 20906, - "netflix": 20907, - "##hire": 20908, - "##nca": 20909, - "condom": 20910, - "brink": 20911, - "ik": 20912, - "##nical": 20913, - "macy": 20914, - "##bet": 20915, - "flap": 20916, - "gma": 20917, - "experimented": 20918, - "jelly": 20919, - "lavender": 20920, - "##icles": 20921, - "##ulia": 20922, - "munro": 20923, - "##mian": 20924, - "##tial": 20925, - "rye": 20926, - "##rle": 20927, - "60th": 20928, - "gigs": 20929, - "hottest": 20930, - "rotated": 20931, - "predictions": 20932, - "fuji": 20933, - "bu": 20934, - "##erence": 20935, - "##omi": 20936, - "barangay": 20937, - "##fulness": 20938, - "##sas": 20939, - "clocks": 20940, - "##rwood": 20941, - "##liness": 20942, - "cereal": 20943, - "roe": 20944, - "wight": 20945, - "decker": 20946, - "uttered": 20947, - "babu": 20948, - "onion": 20949, - "xml": 20950, - "forcibly": 20951, - "##df": 20952, - "petra": 20953, - "sarcasm": 20954, - "hartley": 20955, - "peeled": 20956, - "storytelling": 20957, - "##42": 20958, - "##xley": 20959, - "##ysis": 20960, - "##ffa": 20961, - "fibre": 20962, - "kiel": 20963, - "auditor": 20964, - "fig": 20965, - "harald": 20966, - "greenville": 20967, - "##berries": 20968, - "geographically": 20969, - "nell": 20970, - "quartz": 20971, - "##athic": 20972, - "cemeteries": 20973, - "##lr": 20974, - "crossings": 20975, - "nah": 20976, - "holloway": 20977, - "reptiles": 20978, - "chun": 20979, - "sichuan": 20980, - "snowy": 20981, - "660": 20982, - "corrections": 20983, - "##ivo": 20984, - "zheng": 20985, - "ambassadors": 20986, - "blacksmith": 20987, - "fielded": 20988, - "fluids": 20989, - "hardcover": 20990, - "turnover": 20991, - "medications": 20992, - "melvin": 20993, - "academies": 20994, - "##erton": 20995, - "ro": 20996, - "roach": 20997, - "absorbing": 20998, - "spaniards": 20999, - "colton": 21000, - "##founded": 21001, - "outsider": 21002, - "espionage": 21003, - "kelsey": 21004, - "245": 21005, - "edible": 21006, - "##ulf": 21007, - "dora": 21008, - "establishes": 21009, - "##sham": 21010, - "##tries": 21011, - "contracting": 21012, - "##tania": 21013, - "cinematic": 21014, - "costello": 21015, - "nesting": 21016, - "##uron": 21017, - "connolly": 21018, - "duff": 21019, - "##nology": 21020, - "mma": 21021, - "##mata": 21022, - "fergus": 21023, - "sexes": 21024, - "gi": 21025, - "optics": 21026, - "spectator": 21027, - "woodstock": 21028, - "banning": 21029, - "##hee": 21030, - "##fle": 21031, - "differentiate": 21032, - "outfielder": 21033, - "refinery": 21034, - "226": 21035, - "312": 21036, - "gerhard": 21037, - "horde": 21038, - "lair": 21039, - "drastically": 21040, - "##udi": 21041, - "landfall": 21042, - "##cheng": 21043, - "motorsport": 21044, - "odi": 21045, - "##achi": 21046, - "predominant": 21047, - "quay": 21048, - "skins": 21049, - "##ental": 21050, - "edna": 21051, - "harshly": 21052, - "complementary": 21053, - "murdering": 21054, - "##aves": 21055, - "wreckage": 21056, - "##90": 21057, - "ono": 21058, - "outstretched": 21059, - "lennox": 21060, - "munitions": 21061, - "galen": 21062, - "reconcile": 21063, - "470": 21064, - "scalp": 21065, - "bicycles": 21066, - "gillespie": 21067, - "questionable": 21068, - "rosenberg": 21069, - "guillermo": 21070, - "hostel": 21071, - "jarvis": 21072, - "kabul": 21073, - "volvo": 21074, - "opium": 21075, - "yd": 21076, - "##twined": 21077, - "abuses": 21078, - "decca": 21079, - "outpost": 21080, - "##cino": 21081, - "sensible": 21082, - "neutrality": 21083, - "##64": 21084, - "ponce": 21085, - "anchorage": 21086, - "atkins": 21087, - "turrets": 21088, - "inadvertently": 21089, - "disagree": 21090, - "libre": 21091, - "vodka": 21092, - "reassuring": 21093, - "weighs": 21094, - "##yal": 21095, - "glide": 21096, - "jumper": 21097, - "ceilings": 21098, - "repertory": 21099, - "outs": 21100, - "stain": 21101, - "##bial": 21102, - "envy": 21103, - "##ucible": 21104, - "smashing": 21105, - "heightened": 21106, - "policing": 21107, - "hyun": 21108, - "mixes": 21109, - "lai": 21110, - "prima": 21111, - "##ples": 21112, - "celeste": 21113, - "##bina": 21114, - "lucrative": 21115, - "intervened": 21116, - "kc": 21117, - "manually": 21118, - "##rned": 21119, - "stature": 21120, - "staffed": 21121, - "bun": 21122, - "bastards": 21123, - "nairobi": 21124, - "priced": 21125, - "##auer": 21126, - "thatcher": 21127, - "##kia": 21128, - "tripped": 21129, - "comune": 21130, - "##ogan": 21131, - "##pled": 21132, - "brasil": 21133, - "incentives": 21134, - "emanuel": 21135, - "hereford": 21136, - "musica": 21137, - "##kim": 21138, - "benedictine": 21139, - "biennale": 21140, - "##lani": 21141, - "eureka": 21142, - "gardiner": 21143, - "rb": 21144, - "knocks": 21145, - "sha": 21146, - "##ael": 21147, - "##elled": 21148, - "##onate": 21149, - "efficacy": 21150, - "ventura": 21151, - "masonic": 21152, - "sanford": 21153, - "maize": 21154, - "leverage": 21155, - "##feit": 21156, - "capacities": 21157, - "santana": 21158, - "##aur": 21159, - "novelty": 21160, - "vanilla": 21161, - "##cter": 21162, - "##tour": 21163, - "benin": 21164, - "##oir": 21165, - "##rain": 21166, - "neptune": 21167, - "drafting": 21168, - "tallinn": 21169, - "##cable": 21170, - "humiliation": 21171, - "##boarding": 21172, - "schleswig": 21173, - "fabian": 21174, - "bernardo": 21175, - "liturgy": 21176, - "spectacle": 21177, - "sweeney": 21178, - "pont": 21179, - "routledge": 21180, - "##tment": 21181, - "cosmos": 21182, - "ut": 21183, - "hilt": 21184, - "sleek": 21185, - "universally": 21186, - "##eville": 21187, - "##gawa": 21188, - "typed": 21189, - "##dry": 21190, - "favors": 21191, - "allegheny": 21192, - "glaciers": 21193, - "##rly": 21194, - "recalling": 21195, - "aziz": 21196, - "##log": 21197, - "parasite": 21198, - "requiem": 21199, - "auf": 21200, - "##berto": 21201, - "##llin": 21202, - "illumination": 21203, - "##breaker": 21204, - "##issa": 21205, - "festivities": 21206, - "bows": 21207, - "govern": 21208, - "vibe": 21209, - "vp": 21210, - "333": 21211, - "sprawled": 21212, - "larson": 21213, - "pilgrim": 21214, - "bwf": 21215, - "leaping": 21216, - "##rts": 21217, - "##ssel": 21218, - "alexei": 21219, - "greyhound": 21220, - "hoarse": 21221, - "##dler": 21222, - "##oration": 21223, - "seneca": 21224, - "##cule": 21225, - "gaping": 21226, - "##ulously": 21227, - "##pura": 21228, - "cinnamon": 21229, - "##gens": 21230, - "##rricular": 21231, - "craven": 21232, - "fantasies": 21233, - "houghton": 21234, - "engined": 21235, - "reigned": 21236, - "dictator": 21237, - "supervising": 21238, - "##oris": 21239, - "bogota": 21240, - "commentaries": 21241, - "unnatural": 21242, - "fingernails": 21243, - "spirituality": 21244, - "tighten": 21245, - "##tm": 21246, - "canadiens": 21247, - "protesting": 21248, - "intentional": 21249, - "cheers": 21250, - "sparta": 21251, - "##ytic": 21252, - "##iere": 21253, - "##zine": 21254, - "widen": 21255, - "belgarath": 21256, - "controllers": 21257, - "dodd": 21258, - "iaaf": 21259, - "navarre": 21260, - "##ication": 21261, - "defect": 21262, - "squire": 21263, - "steiner": 21264, - "whisky": 21265, - "##mins": 21266, - "560": 21267, - "inevitably": 21268, - "tome": 21269, - "##gold": 21270, - "chew": 21271, - "##uid": 21272, - "##lid": 21273, - "elastic": 21274, - "##aby": 21275, - "streaked": 21276, - "alliances": 21277, - "jailed": 21278, - "regal": 21279, - "##ined": 21280, - "##phy": 21281, - "czechoslovak": 21282, - "narration": 21283, - "absently": 21284, - "##uld": 21285, - "bluegrass": 21286, - "guangdong": 21287, - "quran": 21288, - "criticizing": 21289, - "hose": 21290, - "hari": 21291, - "##liest": 21292, - "##owa": 21293, - "skier": 21294, - "streaks": 21295, - "deploy": 21296, - "##lom": 21297, - "raft": 21298, - "bose": 21299, - "dialed": 21300, - "huff": 21301, - "##eira": 21302, - "haifa": 21303, - "simplest": 21304, - "bursting": 21305, - "endings": 21306, - "ib": 21307, - "sultanate": 21308, - "##titled": 21309, - "franks": 21310, - "whitman": 21311, - "ensures": 21312, - "sven": 21313, - "##ggs": 21314, - "collaborators": 21315, - "forster": 21316, - "organising": 21317, - "ui": 21318, - "banished": 21319, - "napier": 21320, - "injustice": 21321, - "teller": 21322, - "layered": 21323, - "thump": 21324, - "##otti": 21325, - "roc": 21326, - "battleships": 21327, - "evidenced": 21328, - "fugitive": 21329, - "sadie": 21330, - "robotics": 21331, - "##roud": 21332, - "equatorial": 21333, - "geologist": 21334, - "##iza": 21335, - "yielding": 21336, - "##bron": 21337, - "##sr": 21338, - "internationale": 21339, - "mecca": 21340, - "##diment": 21341, - "sbs": 21342, - "skyline": 21343, - "toad": 21344, - "uploaded": 21345, - "reflective": 21346, - "undrafted": 21347, - "lal": 21348, - "leafs": 21349, - "bayern": 21350, - "##dai": 21351, - "lakshmi": 21352, - "shortlisted": 21353, - "##stick": 21354, - "##wicz": 21355, - "camouflage": 21356, - "donate": 21357, - "af": 21358, - "christi": 21359, - "lau": 21360, - "##acio": 21361, - "disclosed": 21362, - "nemesis": 21363, - "1761": 21364, - "assemble": 21365, - "straining": 21366, - "northamptonshire": 21367, - "tal": 21368, - "##asi": 21369, - "bernardino": 21370, - "premature": 21371, - "heidi": 21372, - "42nd": 21373, - "coefficients": 21374, - "galactic": 21375, - "reproduce": 21376, - "buzzed": 21377, - "sensations": 21378, - "zionist": 21379, - "monsieur": 21380, - "myrtle": 21381, - "##eme": 21382, - "archery": 21383, - "strangled": 21384, - "musically": 21385, - "viewpoint": 21386, - "antiquities": 21387, - "bei": 21388, - "trailers": 21389, - "seahawks": 21390, - "cured": 21391, - "pee": 21392, - "preferring": 21393, - "tasmanian": 21394, - "lange": 21395, - "sul": 21396, - "##mail": 21397, - "##working": 21398, - "colder": 21399, - "overland": 21400, - "lucivar": 21401, - "massey": 21402, - "gatherings": 21403, - "haitian": 21404, - "##smith": 21405, - "disapproval": 21406, - "flaws": 21407, - "##cco": 21408, - "##enbach": 21409, - "1766": 21410, - "npr": 21411, - "##icular": 21412, - "boroughs": 21413, - "creole": 21414, - "forums": 21415, - "techno": 21416, - "1755": 21417, - "dent": 21418, - "abdominal": 21419, - "streetcar": 21420, - "##eson": 21421, - "##stream": 21422, - "procurement": 21423, - "gemini": 21424, - "predictable": 21425, - "##tya": 21426, - "acheron": 21427, - "christoph": 21428, - "feeder": 21429, - "fronts": 21430, - "vendor": 21431, - "bernhard": 21432, - "jammu": 21433, - "tumors": 21434, - "slang": 21435, - "##uber": 21436, - "goaltender": 21437, - "twists": 21438, - "curving": 21439, - "manson": 21440, - "vuelta": 21441, - "mer": 21442, - "peanut": 21443, - "confessions": 21444, - "pouch": 21445, - "unpredictable": 21446, - "allowance": 21447, - "theodor": 21448, - "vascular": 21449, - "##factory": 21450, - "bala": 21451, - "authenticity": 21452, - "metabolic": 21453, - "coughing": 21454, - "nanjing": 21455, - "##cea": 21456, - "pembroke": 21457, - "##bard": 21458, - "splendid": 21459, - "36th": 21460, - "ff": 21461, - "hourly": 21462, - "##ahu": 21463, - "elmer": 21464, - "handel": 21465, - "##ivate": 21466, - "awarding": 21467, - "thrusting": 21468, - "dl": 21469, - "experimentation": 21470, - "##hesion": 21471, - "##46": 21472, - "caressed": 21473, - "entertained": 21474, - "steak": 21475, - "##rangle": 21476, - "biologist": 21477, - "orphans": 21478, - "baroness": 21479, - "oyster": 21480, - "stepfather": 21481, - "##dridge": 21482, - "mirage": 21483, - "reefs": 21484, - "speeding": 21485, - "##31": 21486, - "barons": 21487, - "1764": 21488, - "227": 21489, - "inhabit": 21490, - "preached": 21491, - "repealed": 21492, - "##tral": 21493, - "honoring": 21494, - "boogie": 21495, - "captives": 21496, - "administer": 21497, - "johanna": 21498, - "##imate": 21499, - "gel": 21500, - "suspiciously": 21501, - "1767": 21502, - "sobs": 21503, - "##dington": 21504, - "backbone": 21505, - "hayward": 21506, - "garry": 21507, - "##folding": 21508, - "##nesia": 21509, - "maxi": 21510, - "##oof": 21511, - "##ppe": 21512, - "ellison": 21513, - "galileo": 21514, - "##stand": 21515, - "crimea": 21516, - "frenzy": 21517, - "amour": 21518, - "bumper": 21519, - "matrices": 21520, - "natalia": 21521, - "baking": 21522, - "garth": 21523, - "palestinians": 21524, - "##grove": 21525, - "smack": 21526, - "conveyed": 21527, - "ensembles": 21528, - "gardening": 21529, - "##manship": 21530, - "##rup": 21531, - "##stituting": 21532, - "1640": 21533, - "harvesting": 21534, - "topography": 21535, - "jing": 21536, - "shifters": 21537, - "dormitory": 21538, - "##carriage": 21539, - "##lston": 21540, - "ist": 21541, - "skulls": 21542, - "##stadt": 21543, - "dolores": 21544, - "jewellery": 21545, - "sarawak": 21546, - "##wai": 21547, - "##zier": 21548, - "fences": 21549, - "christy": 21550, - "confinement": 21551, - "tumbling": 21552, - "credibility": 21553, - "fir": 21554, - "stench": 21555, - "##bria": 21556, - "##plication": 21557, - "##nged": 21558, - "##sam": 21559, - "virtues": 21560, - "##belt": 21561, - "marjorie": 21562, - "pba": 21563, - "##eem": 21564, - "##made": 21565, - "celebrates": 21566, - "schooner": 21567, - "agitated": 21568, - "barley": 21569, - "fulfilling": 21570, - "anthropologist": 21571, - "##pro": 21572, - "restrict": 21573, - "novi": 21574, - "regulating": 21575, - "##nent": 21576, - "padres": 21577, - "##rani": 21578, - "##hesive": 21579, - "loyola": 21580, - "tabitha": 21581, - "milky": 21582, - "olson": 21583, - "proprietor": 21584, - "crambidae": 21585, - "guarantees": 21586, - "intercollegiate": 21587, - "ljubljana": 21588, - "hilda": 21589, - "##sko": 21590, - "ignorant": 21591, - "hooded": 21592, - "##lts": 21593, - "sardinia": 21594, - "##lidae": 21595, - "##vation": 21596, - "frontman": 21597, - "privileged": 21598, - "witchcraft": 21599, - "##gp": 21600, - "jammed": 21601, - "laude": 21602, - "poking": 21603, - "##than": 21604, - "bracket": 21605, - "amazement": 21606, - "yunnan": 21607, - "##erus": 21608, - "maharaja": 21609, - "linnaeus": 21610, - "264": 21611, - "commissioning": 21612, - "milano": 21613, - "peacefully": 21614, - "##logies": 21615, - "akira": 21616, - "rani": 21617, - "regulator": 21618, - "##36": 21619, - "grasses": 21620, - "##rance": 21621, - "luzon": 21622, - "crows": 21623, - "compiler": 21624, - "gretchen": 21625, - "seaman": 21626, - "edouard": 21627, - "tab": 21628, - "buccaneers": 21629, - "ellington": 21630, - "hamlets": 21631, - "whig": 21632, - "socialists": 21633, - "##anto": 21634, - "directorial": 21635, - "easton": 21636, - "mythological": 21637, - "##kr": 21638, - "##vary": 21639, - "rhineland": 21640, - "semantic": 21641, - "taut": 21642, - "dune": 21643, - "inventions": 21644, - "succeeds": 21645, - "##iter": 21646, - "replication": 21647, - "branched": 21648, - "##pired": 21649, - "jul": 21650, - "prosecuted": 21651, - "kangaroo": 21652, - "penetrated": 21653, - "##avian": 21654, - "middlesbrough": 21655, - "doses": 21656, - "bleak": 21657, - "madam": 21658, - "predatory": 21659, - "relentless": 21660, - "##vili": 21661, - "reluctance": 21662, - "##vir": 21663, - "hailey": 21664, - "crore": 21665, - "silvery": 21666, - "1759": 21667, - "monstrous": 21668, - "swimmers": 21669, - "transmissions": 21670, - "hawthorn": 21671, - "informing": 21672, - "##eral": 21673, - "toilets": 21674, - "caracas": 21675, - "crouch": 21676, - "kb": 21677, - "##sett": 21678, - "295": 21679, - "cartel": 21680, - "hadley": 21681, - "##aling": 21682, - "alexia": 21683, - "yvonne": 21684, - "##biology": 21685, - "cinderella": 21686, - "eton": 21687, - "superb": 21688, - "blizzard": 21689, - "stabbing": 21690, - "industrialist": 21691, - "maximus": 21692, - "##gm": 21693, - "##orus": 21694, - "groves": 21695, - "maud": 21696, - "clade": 21697, - "oversized": 21698, - "comedic": 21699, - "##bella": 21700, - "rosen": 21701, - "nomadic": 21702, - "fulham": 21703, - "montane": 21704, - "beverages": 21705, - "galaxies": 21706, - "redundant": 21707, - "swarm": 21708, - "##rot": 21709, - "##folia": 21710, - "##llis": 21711, - "buckinghamshire": 21712, - "fen": 21713, - "bearings": 21714, - "bahadur": 21715, - "##rom": 21716, - "gilles": 21717, - "phased": 21718, - "dynamite": 21719, - "faber": 21720, - "benoit": 21721, - "vip": 21722, - "##ount": 21723, - "##wd": 21724, - "booking": 21725, - "fractured": 21726, - "tailored": 21727, - "anya": 21728, - "spices": 21729, - "westwood": 21730, - "cairns": 21731, - "auditions": 21732, - "inflammation": 21733, - "steamed": 21734, - "##rocity": 21735, - "##acion": 21736, - "##urne": 21737, - "skyla": 21738, - "thereof": 21739, - "watford": 21740, - "torment": 21741, - "archdeacon": 21742, - "transforms": 21743, - "lulu": 21744, - "demeanor": 21745, - "fucked": 21746, - "serge": 21747, - "##sor": 21748, - "mckenna": 21749, - "minas": 21750, - "entertainer": 21751, - "##icide": 21752, - "caress": 21753, - "originate": 21754, - "residue": 21755, - "##sty": 21756, - "1740": 21757, - "##ilised": 21758, - "##org": 21759, - "beech": 21760, - "##wana": 21761, - "subsidies": 21762, - "##ghton": 21763, - "emptied": 21764, - "gladstone": 21765, - "ru": 21766, - "firefighters": 21767, - "voodoo": 21768, - "##rcle": 21769, - "het": 21770, - "nightingale": 21771, - "tamara": 21772, - "edmond": 21773, - "ingredient": 21774, - "weaknesses": 21775, - "silhouette": 21776, - "285": 21777, - "compatibility": 21778, - "withdrawing": 21779, - "hampson": 21780, - "##mona": 21781, - "anguish": 21782, - "giggling": 21783, - "##mber": 21784, - "bookstore": 21785, - "##jiang": 21786, - "southernmost": 21787, - "tilting": 21788, - "##vance": 21789, - "bai": 21790, - "economical": 21791, - "rf": 21792, - "briefcase": 21793, - "dreadful": 21794, - "hinted": 21795, - "projections": 21796, - "shattering": 21797, - "totaling": 21798, - "##rogate": 21799, - "analogue": 21800, - "indicted": 21801, - "periodical": 21802, - "fullback": 21803, - "##dman": 21804, - "haynes": 21805, - "##tenberg": 21806, - "##ffs": 21807, - "##ishment": 21808, - "1745": 21809, - "thirst": 21810, - "stumble": 21811, - "penang": 21812, - "vigorous": 21813, - "##ddling": 21814, - "##kor": 21815, - "##lium": 21816, - "octave": 21817, - "##ove": 21818, - "##enstein": 21819, - "##inen": 21820, - "##ones": 21821, - "siberian": 21822, - "##uti": 21823, - "cbn": 21824, - "repeal": 21825, - "swaying": 21826, - "##vington": 21827, - "khalid": 21828, - "tanaka": 21829, - "unicorn": 21830, - "otago": 21831, - "plastered": 21832, - "lobe": 21833, - "riddle": 21834, - "##rella": 21835, - "perch": 21836, - "##ishing": 21837, - "croydon": 21838, - "filtered": 21839, - "graeme": 21840, - "tripoli": 21841, - "##ossa": 21842, - "crocodile": 21843, - "##chers": 21844, - "sufi": 21845, - "mined": 21846, - "##tung": 21847, - "inferno": 21848, - "lsu": 21849, - "##phi": 21850, - "swelled": 21851, - "utilizes": 21852, - "£2": 21853, - "cale": 21854, - "periodicals": 21855, - "styx": 21856, - "hike": 21857, - "informally": 21858, - "coop": 21859, - "lund": 21860, - "##tidae": 21861, - "ala": 21862, - "hen": 21863, - "qui": 21864, - "transformations": 21865, - "disposed": 21866, - "sheath": 21867, - "chickens": 21868, - "##cade": 21869, - "fitzroy": 21870, - "sas": 21871, - "silesia": 21872, - "unacceptable": 21873, - "odisha": 21874, - "1650": 21875, - "sabrina": 21876, - "pe": 21877, - "spokane": 21878, - "ratios": 21879, - "athena": 21880, - "massage": 21881, - "shen": 21882, - "dilemma": 21883, - "##drum": 21884, - "##riz": 21885, - "##hul": 21886, - "corona": 21887, - "doubtful": 21888, - "niall": 21889, - "##pha": 21890, - "##bino": 21891, - "fines": 21892, - "cite": 21893, - "acknowledging": 21894, - "bangor": 21895, - "ballard": 21896, - "bathurst": 21897, - "##resh": 21898, - "huron": 21899, - "mustered": 21900, - "alzheimer": 21901, - "garments": 21902, - "kinase": 21903, - "tyre": 21904, - "warship": 21905, - "##cp": 21906, - "flashback": 21907, - "pulmonary": 21908, - "braun": 21909, - "cheat": 21910, - "kamal": 21911, - "cyclists": 21912, - "constructions": 21913, - "grenades": 21914, - "ndp": 21915, - "traveller": 21916, - "excuses": 21917, - "stomped": 21918, - "signalling": 21919, - "trimmed": 21920, - "futsal": 21921, - "mosques": 21922, - "relevance": 21923, - "##wine": 21924, - "wta": 21925, - "##23": 21926, - "##vah": 21927, - "##lter": 21928, - "hoc": 21929, - "##riding": 21930, - "optimistic": 21931, - "##´s": 21932, - "deco": 21933, - "sim": 21934, - "interacting": 21935, - "rejecting": 21936, - "moniker": 21937, - "waterways": 21938, - "##ieri": 21939, - "##oku": 21940, - "mayors": 21941, - "gdansk": 21942, - "outnumbered": 21943, - "pearls": 21944, - "##ended": 21945, - "##hampton": 21946, - "fairs": 21947, - "totals": 21948, - "dominating": 21949, - "262": 21950, - "notions": 21951, - "stairway": 21952, - "compiling": 21953, - "pursed": 21954, - "commodities": 21955, - "grease": 21956, - "yeast": 21957, - "##jong": 21958, - "carthage": 21959, - "griffiths": 21960, - "residual": 21961, - "amc": 21962, - "contraction": 21963, - "laird": 21964, - "sapphire": 21965, - "##marine": 21966, - "##ivated": 21967, - "amalgamation": 21968, - "dissolve": 21969, - "inclination": 21970, - "lyle": 21971, - "packaged": 21972, - "altitudes": 21973, - "suez": 21974, - "canons": 21975, - "graded": 21976, - "lurched": 21977, - "narrowing": 21978, - "boasts": 21979, - "guise": 21980, - "wed": 21981, - "enrico": 21982, - "##ovsky": 21983, - "rower": 21984, - "scarred": 21985, - "bree": 21986, - "cub": 21987, - "iberian": 21988, - "protagonists": 21989, - "bargaining": 21990, - "proposing": 21991, - "trainers": 21992, - "voyages": 21993, - "vans": 21994, - "fishes": 21995, - "##aea": 21996, - "##ivist": 21997, - "##verance": 21998, - "encryption": 21999, - "artworks": 22000, - "kazan": 22001, - "sabre": 22002, - "cleopatra": 22003, - "hepburn": 22004, - "rotting": 22005, - "supremacy": 22006, - "mecklenburg": 22007, - "##brate": 22008, - "burrows": 22009, - "hazards": 22010, - "outgoing": 22011, - "flair": 22012, - "organizes": 22013, - "##ctions": 22014, - "scorpion": 22015, - "##usions": 22016, - "boo": 22017, - "234": 22018, - "chevalier": 22019, - "dunedin": 22020, - "slapping": 22021, - "##34": 22022, - "ineligible": 22023, - "pensions": 22024, - "##38": 22025, - "##omic": 22026, - "manufactures": 22027, - "emails": 22028, - "bismarck": 22029, - "238": 22030, - "weakening": 22031, - "blackish": 22032, - "ding": 22033, - "mcgee": 22034, - "quo": 22035, - "##rling": 22036, - "northernmost": 22037, - "xx": 22038, - "manpower": 22039, - "greed": 22040, - "sampson": 22041, - "clicking": 22042, - "##ange": 22043, - "##horpe": 22044, - "##inations": 22045, - "##roving": 22046, - "torre": 22047, - "##eptive": 22048, - "##moral": 22049, - "symbolism": 22050, - "38th": 22051, - "asshole": 22052, - "meritorious": 22053, - "outfits": 22054, - "splashed": 22055, - "biographies": 22056, - "sprung": 22057, - "astros": 22058, - "##tale": 22059, - "302": 22060, - "737": 22061, - "filly": 22062, - "raoul": 22063, - "nw": 22064, - "tokugawa": 22065, - "linden": 22066, - "clubhouse": 22067, - "##apa": 22068, - "tracts": 22069, - "romano": 22070, - "##pio": 22071, - "putin": 22072, - "tags": 22073, - "##note": 22074, - "chained": 22075, - "dickson": 22076, - "gunshot": 22077, - "moe": 22078, - "gunn": 22079, - "rashid": 22080, - "##tails": 22081, - "zipper": 22082, - "##bas": 22083, - "##nea": 22084, - "contrasted": 22085, - "##ply": 22086, - "##udes": 22087, - "plum": 22088, - "pharaoh": 22089, - "##pile": 22090, - "aw": 22091, - "comedies": 22092, - "ingrid": 22093, - "sandwiches": 22094, - "subdivisions": 22095, - "1100": 22096, - "mariana": 22097, - "nokia": 22098, - "kamen": 22099, - "hz": 22100, - "delaney": 22101, - "veto": 22102, - "herring": 22103, - "##words": 22104, - "possessive": 22105, - "outlines": 22106, - "##roup": 22107, - "siemens": 22108, - "stairwell": 22109, - "rc": 22110, - "gallantry": 22111, - "messiah": 22112, - "palais": 22113, - "yells": 22114, - "233": 22115, - "zeppelin": 22116, - "##dm": 22117, - "bolivar": 22118, - "##cede": 22119, - "smackdown": 22120, - "mckinley": 22121, - "##mora": 22122, - "##yt": 22123, - "muted": 22124, - "geologic": 22125, - "finely": 22126, - "unitary": 22127, - "avatar": 22128, - "hamas": 22129, - "maynard": 22130, - "rees": 22131, - "bog": 22132, - "contrasting": 22133, - "##rut": 22134, - "liv": 22135, - "chico": 22136, - "disposition": 22137, - "pixel": 22138, - "##erate": 22139, - "becca": 22140, - "dmitry": 22141, - "yeshiva": 22142, - "narratives": 22143, - "##lva": 22144, - "##ulton": 22145, - "mercenary": 22146, - "sharpe": 22147, - "tempered": 22148, - "navigate": 22149, - "stealth": 22150, - "amassed": 22151, - "keynes": 22152, - "##lini": 22153, - "untouched": 22154, - "##rrie": 22155, - "havoc": 22156, - "lithium": 22157, - "##fighting": 22158, - "abyss": 22159, - "graf": 22160, - "southward": 22161, - "wolverine": 22162, - "balloons": 22163, - "implements": 22164, - "ngos": 22165, - "transitions": 22166, - "##icum": 22167, - "ambushed": 22168, - "concacaf": 22169, - "dormant": 22170, - "economists": 22171, - "##dim": 22172, - "costing": 22173, - "csi": 22174, - "rana": 22175, - "universite": 22176, - "boulders": 22177, - "verity": 22178, - "##llon": 22179, - "collin": 22180, - "mellon": 22181, - "misses": 22182, - "cypress": 22183, - "fluorescent": 22184, - "lifeless": 22185, - "spence": 22186, - "##ulla": 22187, - "crewe": 22188, - "shepard": 22189, - "pak": 22190, - "revelations": 22191, - "##م": 22192, - "jolly": 22193, - "gibbons": 22194, - "paw": 22195, - "##dro": 22196, - "##quel": 22197, - "freeing": 22198, - "##test": 22199, - "shack": 22200, - "fries": 22201, - "palatine": 22202, - "##51": 22203, - "##hiko": 22204, - "accompaniment": 22205, - "cruising": 22206, - "recycled": 22207, - "##aver": 22208, - "erwin": 22209, - "sorting": 22210, - "synthesizers": 22211, - "dyke": 22212, - "realities": 22213, - "sg": 22214, - "strides": 22215, - "enslaved": 22216, - "wetland": 22217, - "##ghan": 22218, - "competence": 22219, - "gunpowder": 22220, - "grassy": 22221, - "maroon": 22222, - "reactors": 22223, - "objection": 22224, - "##oms": 22225, - "carlson": 22226, - "gearbox": 22227, - "macintosh": 22228, - "radios": 22229, - "shelton": 22230, - "##sho": 22231, - "clergyman": 22232, - "prakash": 22233, - "254": 22234, - "mongols": 22235, - "trophies": 22236, - "oricon": 22237, - "228": 22238, - "stimuli": 22239, - "twenty20": 22240, - "cantonese": 22241, - "cortes": 22242, - "mirrored": 22243, - "##saurus": 22244, - "bhp": 22245, - "cristina": 22246, - "melancholy": 22247, - "##lating": 22248, - "enjoyable": 22249, - "nuevo": 22250, - "##wny": 22251, - "downfall": 22252, - "schumacher": 22253, - "##ind": 22254, - "banging": 22255, - "lausanne": 22256, - "rumbled": 22257, - "paramilitary": 22258, - "reflex": 22259, - "ax": 22260, - "amplitude": 22261, - "migratory": 22262, - "##gall": 22263, - "##ups": 22264, - "midi": 22265, - "barnard": 22266, - "lastly": 22267, - "sherry": 22268, - "##hp": 22269, - "##nall": 22270, - "keystone": 22271, - "##kra": 22272, - "carleton": 22273, - "slippery": 22274, - "##53": 22275, - "coloring": 22276, - "foe": 22277, - "socket": 22278, - "otter": 22279, - "##rgos": 22280, - "mats": 22281, - "##tose": 22282, - "consultants": 22283, - "bafta": 22284, - "bison": 22285, - "topping": 22286, - "##km": 22287, - "490": 22288, - "primal": 22289, - "abandonment": 22290, - "transplant": 22291, - "atoll": 22292, - "hideous": 22293, - "mort": 22294, - "pained": 22295, - "reproduced": 22296, - "tae": 22297, - "howling": 22298, - "##turn": 22299, - "unlawful": 22300, - "billionaire": 22301, - "hotter": 22302, - "poised": 22303, - "lansing": 22304, - "##chang": 22305, - "dinamo": 22306, - "retro": 22307, - "messing": 22308, - "nfc": 22309, - "domesday": 22310, - "##mina": 22311, - "blitz": 22312, - "timed": 22313, - "##athing": 22314, - "##kley": 22315, - "ascending": 22316, - "gesturing": 22317, - "##izations": 22318, - "signaled": 22319, - "tis": 22320, - "chinatown": 22321, - "mermaid": 22322, - "savanna": 22323, - "jameson": 22324, - "##aint": 22325, - "catalina": 22326, - "##pet": 22327, - "##hers": 22328, - "cochrane": 22329, - "cy": 22330, - "chatting": 22331, - "##kus": 22332, - "alerted": 22333, - "computation": 22334, - "mused": 22335, - "noelle": 22336, - "majestic": 22337, - "mohawk": 22338, - "campo": 22339, - "octagonal": 22340, - "##sant": 22341, - "##hend": 22342, - "241": 22343, - "aspiring": 22344, - "##mart": 22345, - "comprehend": 22346, - "iona": 22347, - "paralyzed": 22348, - "shimmering": 22349, - "swindon": 22350, - "rhone": 22351, - "##eley": 22352, - "reputed": 22353, - "configurations": 22354, - "pitchfork": 22355, - "agitation": 22356, - "francais": 22357, - "gillian": 22358, - "lipstick": 22359, - "##ilo": 22360, - "outsiders": 22361, - "pontifical": 22362, - "resisting": 22363, - "bitterness": 22364, - "sewer": 22365, - "rockies": 22366, - "##edd": 22367, - "##ucher": 22368, - "misleading": 22369, - "1756": 22370, - "exiting": 22371, - "galloway": 22372, - "##nging": 22373, - "risked": 22374, - "##heart": 22375, - "246": 22376, - "commemoration": 22377, - "schultz": 22378, - "##rka": 22379, - "integrating": 22380, - "##rsa": 22381, - "poses": 22382, - "shrieked": 22383, - "##weiler": 22384, - "guineas": 22385, - "gladys": 22386, - "jerking": 22387, - "owls": 22388, - "goldsmith": 22389, - "nightly": 22390, - "penetrating": 22391, - "##unced": 22392, - "lia": 22393, - "##33": 22394, - "ignited": 22395, - "betsy": 22396, - "##aring": 22397, - "##thorpe": 22398, - "follower": 22399, - "vigorously": 22400, - "##rave": 22401, - "coded": 22402, - "kiran": 22403, - "knit": 22404, - "zoology": 22405, - "tbilisi": 22406, - "##28": 22407, - "##bered": 22408, - "repository": 22409, - "govt": 22410, - "deciduous": 22411, - "dino": 22412, - "growling": 22413, - "##bba": 22414, - "enhancement": 22415, - "unleashed": 22416, - "chanting": 22417, - "pussy": 22418, - "biochemistry": 22419, - "##eric": 22420, - "kettle": 22421, - "repression": 22422, - "toxicity": 22423, - "nrhp": 22424, - "##arth": 22425, - "##kko": 22426, - "##bush": 22427, - "ernesto": 22428, - "commended": 22429, - "outspoken": 22430, - "242": 22431, - "mca": 22432, - "parchment": 22433, - "sms": 22434, - "kristen": 22435, - "##aton": 22436, - "bisexual": 22437, - "raked": 22438, - "glamour": 22439, - "navajo": 22440, - "a2": 22441, - "conditioned": 22442, - "showcased": 22443, - "##hma": 22444, - "spacious": 22445, - "youthful": 22446, - "##esa": 22447, - "usl": 22448, - "appliances": 22449, - "junta": 22450, - "brest": 22451, - "layne": 22452, - "conglomerate": 22453, - "enchanted": 22454, - "chao": 22455, - "loosened": 22456, - "picasso": 22457, - "circulating": 22458, - "inspect": 22459, - "montevideo": 22460, - "##centric": 22461, - "##kti": 22462, - "piazza": 22463, - "spurred": 22464, - "##aith": 22465, - "bari": 22466, - "freedoms": 22467, - "poultry": 22468, - "stamford": 22469, - "lieu": 22470, - "##ect": 22471, - "indigo": 22472, - "sarcastic": 22473, - "bahia": 22474, - "stump": 22475, - "attach": 22476, - "dvds": 22477, - "frankenstein": 22478, - "lille": 22479, - "approx": 22480, - "scriptures": 22481, - "pollen": 22482, - "##script": 22483, - "nmi": 22484, - "overseen": 22485, - "##ivism": 22486, - "tides": 22487, - "proponent": 22488, - "newmarket": 22489, - "inherit": 22490, - "milling": 22491, - "##erland": 22492, - "centralized": 22493, - "##rou": 22494, - "distributors": 22495, - "credentials": 22496, - "drawers": 22497, - "abbreviation": 22498, - "##lco": 22499, - "##xon": 22500, - "downing": 22501, - "uncomfortably": 22502, - "ripe": 22503, - "##oes": 22504, - "erase": 22505, - "franchises": 22506, - "##ever": 22507, - "populace": 22508, - "##bery": 22509, - "##khar": 22510, - "decomposition": 22511, - "pleas": 22512, - "##tet": 22513, - "daryl": 22514, - "sabah": 22515, - "##stle": 22516, - "##wide": 22517, - "fearless": 22518, - "genie": 22519, - "lesions": 22520, - "annette": 22521, - "##ogist": 22522, - "oboe": 22523, - "appendix": 22524, - "nair": 22525, - "dripped": 22526, - "petitioned": 22527, - "maclean": 22528, - "mosquito": 22529, - "parrot": 22530, - "rpg": 22531, - "hampered": 22532, - "1648": 22533, - "operatic": 22534, - "reservoirs": 22535, - "##tham": 22536, - "irrelevant": 22537, - "jolt": 22538, - "summarized": 22539, - "##fp": 22540, - "medallion": 22541, - "##taff": 22542, - "##−": 22543, - "clawed": 22544, - "harlow": 22545, - "narrower": 22546, - "goddard": 22547, - "marcia": 22548, - "bodied": 22549, - "fremont": 22550, - "suarez": 22551, - "altering": 22552, - "tempest": 22553, - "mussolini": 22554, - "porn": 22555, - "##isms": 22556, - "sweetly": 22557, - "oversees": 22558, - "walkers": 22559, - "solitude": 22560, - "grimly": 22561, - "shrines": 22562, - "hk": 22563, - "ich": 22564, - "supervisors": 22565, - "hostess": 22566, - "dietrich": 22567, - "legitimacy": 22568, - "brushes": 22569, - "expressive": 22570, - "##yp": 22571, - "dissipated": 22572, - "##rse": 22573, - "localized": 22574, - "systemic": 22575, - "##nikov": 22576, - "gettysburg": 22577, - "##js": 22578, - "##uaries": 22579, - "dialogues": 22580, - "muttering": 22581, - "251": 22582, - "housekeeper": 22583, - "sicilian": 22584, - "discouraged": 22585, - "##frey": 22586, - "beamed": 22587, - "kaladin": 22588, - "halftime": 22589, - "kidnap": 22590, - "##amo": 22591, - "##llet": 22592, - "1754": 22593, - "synonymous": 22594, - "depleted": 22595, - "instituto": 22596, - "insulin": 22597, - "reprised": 22598, - "##opsis": 22599, - "clashed": 22600, - "##ctric": 22601, - "interrupting": 22602, - "radcliffe": 22603, - "insisting": 22604, - "medici": 22605, - "1715": 22606, - "ejected": 22607, - "playfully": 22608, - "turbulent": 22609, - "##47": 22610, - "starvation": 22611, - "##rini": 22612, - "shipment": 22613, - "rebellious": 22614, - "petersen": 22615, - "verification": 22616, - "merits": 22617, - "##rified": 22618, - "cakes": 22619, - "##charged": 22620, - "1757": 22621, - "milford": 22622, - "shortages": 22623, - "spying": 22624, - "fidelity": 22625, - "##aker": 22626, - "emitted": 22627, - "storylines": 22628, - "harvested": 22629, - "seismic": 22630, - "##iform": 22631, - "cheung": 22632, - "kilda": 22633, - "theoretically": 22634, - "barbie": 22635, - "lynx": 22636, - "##rgy": 22637, - "##tius": 22638, - "goblin": 22639, - "mata": 22640, - "poisonous": 22641, - "##nburg": 22642, - "reactive": 22643, - "residues": 22644, - "obedience": 22645, - "##евич": 22646, - "conjecture": 22647, - "##rac": 22648, - "401": 22649, - "hating": 22650, - "sixties": 22651, - "kicker": 22652, - "moaning": 22653, - "motown": 22654, - "##bha": 22655, - "emancipation": 22656, - "neoclassical": 22657, - "##hering": 22658, - "consoles": 22659, - "ebert": 22660, - "professorship": 22661, - "##tures": 22662, - "sustaining": 22663, - "assaults": 22664, - "obeyed": 22665, - "affluent": 22666, - "incurred": 22667, - "tornadoes": 22668, - "##eber": 22669, - "##zow": 22670, - "emphasizing": 22671, - "highlanders": 22672, - "cheated": 22673, - "helmets": 22674, - "##ctus": 22675, - "internship": 22676, - "terence": 22677, - "bony": 22678, - "executions": 22679, - "legislators": 22680, - "berries": 22681, - "peninsular": 22682, - "tinged": 22683, - "##aco": 22684, - "1689": 22685, - "amplifier": 22686, - "corvette": 22687, - "ribbons": 22688, - "lavish": 22689, - "pennant": 22690, - "##lander": 22691, - "worthless": 22692, - "##chfield": 22693, - "##forms": 22694, - "mariano": 22695, - "pyrenees": 22696, - "expenditures": 22697, - "##icides": 22698, - "chesterfield": 22699, - "mandir": 22700, - "tailor": 22701, - "39th": 22702, - "sergey": 22703, - "nestled": 22704, - "willed": 22705, - "aristocracy": 22706, - "devotees": 22707, - "goodnight": 22708, - "raaf": 22709, - "rumored": 22710, - "weaponry": 22711, - "remy": 22712, - "appropriations": 22713, - "harcourt": 22714, - "burr": 22715, - "riaa": 22716, - "##lence": 22717, - "limitation": 22718, - "unnoticed": 22719, - "guo": 22720, - "soaking": 22721, - "swamps": 22722, - "##tica": 22723, - "collapsing": 22724, - "tatiana": 22725, - "descriptive": 22726, - "brigham": 22727, - "psalm": 22728, - "##chment": 22729, - "maddox": 22730, - "##lization": 22731, - "patti": 22732, - "caliph": 22733, - "##aja": 22734, - "akron": 22735, - "injuring": 22736, - "serra": 22737, - "##ganj": 22738, - "basins": 22739, - "##sari": 22740, - "astonished": 22741, - "launcher": 22742, - "##church": 22743, - "hilary": 22744, - "wilkins": 22745, - "sewing": 22746, - "##sf": 22747, - "stinging": 22748, - "##fia": 22749, - "##ncia": 22750, - "underwood": 22751, - "startup": 22752, - "##ition": 22753, - "compilations": 22754, - "vibrations": 22755, - "embankment": 22756, - "jurist": 22757, - "##nity": 22758, - "bard": 22759, - "juventus": 22760, - "groundwater": 22761, - "kern": 22762, - "palaces": 22763, - "helium": 22764, - "boca": 22765, - "cramped": 22766, - "marissa": 22767, - "soto": 22768, - "##worm": 22769, - "jae": 22770, - "princely": 22771, - "##ggy": 22772, - "faso": 22773, - "bazaar": 22774, - "warmly": 22775, - "##voking": 22776, - "229": 22777, - "pairing": 22778, - "##lite": 22779, - "##grate": 22780, - "##nets": 22781, - "wien": 22782, - "freaked": 22783, - "ulysses": 22784, - "rebirth": 22785, - "##alia": 22786, - "##rent": 22787, - "mummy": 22788, - "guzman": 22789, - "jimenez": 22790, - "stilled": 22791, - "##nitz": 22792, - "trajectory": 22793, - "tha": 22794, - "woken": 22795, - "archival": 22796, - "professions": 22797, - "##pts": 22798, - "##pta": 22799, - "hilly": 22800, - "shadowy": 22801, - "shrink": 22802, - "##bolt": 22803, - "norwood": 22804, - "glued": 22805, - "migrate": 22806, - "stereotypes": 22807, - "devoid": 22808, - "##pheus": 22809, - "625": 22810, - "evacuate": 22811, - "horrors": 22812, - "infancy": 22813, - "gotham": 22814, - "knowles": 22815, - "optic": 22816, - "downloaded": 22817, - "sachs": 22818, - "kingsley": 22819, - "parramatta": 22820, - "darryl": 22821, - "mor": 22822, - "##onale": 22823, - "shady": 22824, - "commence": 22825, - "confesses": 22826, - "kan": 22827, - "##meter": 22828, - "##placed": 22829, - "marlborough": 22830, - "roundabout": 22831, - "regents": 22832, - "frigates": 22833, - "io": 22834, - "##imating": 22835, - "gothenburg": 22836, - "revoked": 22837, - "carvings": 22838, - "clockwise": 22839, - "convertible": 22840, - "intruder": 22841, - "##sche": 22842, - "banged": 22843, - "##ogo": 22844, - "vicky": 22845, - "bourgeois": 22846, - "##mony": 22847, - "dupont": 22848, - "footing": 22849, - "##gum": 22850, - "pd": 22851, - "##real": 22852, - "buckle": 22853, - "yun": 22854, - "penthouse": 22855, - "sane": 22856, - "720": 22857, - "serviced": 22858, - "stakeholders": 22859, - "neumann": 22860, - "bb": 22861, - "##eers": 22862, - "comb": 22863, - "##gam": 22864, - "catchment": 22865, - "pinning": 22866, - "rallies": 22867, - "typing": 22868, - "##elles": 22869, - "forefront": 22870, - "freiburg": 22871, - "sweetie": 22872, - "giacomo": 22873, - "widowed": 22874, - "goodwill": 22875, - "worshipped": 22876, - "aspirations": 22877, - "midday": 22878, - "##vat": 22879, - "fishery": 22880, - "##trick": 22881, - "bournemouth": 22882, - "turk": 22883, - "243": 22884, - "hearth": 22885, - "ethanol": 22886, - "guadalajara": 22887, - "murmurs": 22888, - "sl": 22889, - "##uge": 22890, - "afforded": 22891, - "scripted": 22892, - "##hta": 22893, - "wah": 22894, - "##jn": 22895, - "coroner": 22896, - "translucent": 22897, - "252": 22898, - "memorials": 22899, - "puck": 22900, - "progresses": 22901, - "clumsy": 22902, - "##race": 22903, - "315": 22904, - "candace": 22905, - "recounted": 22906, - "##27": 22907, - "##slin": 22908, - "##uve": 22909, - "filtering": 22910, - "##mac": 22911, - "howl": 22912, - "strata": 22913, - "heron": 22914, - "leveled": 22915, - "##ays": 22916, - "dubious": 22917, - "##oja": 22918, - "##т": 22919, - "##wheel": 22920, - "citations": 22921, - "exhibiting": 22922, - "##laya": 22923, - "##mics": 22924, - "##pods": 22925, - "turkic": 22926, - "##lberg": 22927, - "injunction": 22928, - "##ennial": 22929, - "##mit": 22930, - "antibodies": 22931, - "##44": 22932, - "organise": 22933, - "##rigues": 22934, - "cardiovascular": 22935, - "cushion": 22936, - "inverness": 22937, - "##zquez": 22938, - "dia": 22939, - "cocoa": 22940, - "sibling": 22941, - "##tman": 22942, - "##roid": 22943, - "expanse": 22944, - "feasible": 22945, - "tunisian": 22946, - "algiers": 22947, - "##relli": 22948, - "rus": 22949, - "bloomberg": 22950, - "dso": 22951, - "westphalia": 22952, - "bro": 22953, - "tacoma": 22954, - "281": 22955, - "downloads": 22956, - "##ours": 22957, - "konrad": 22958, - "duran": 22959, - "##hdi": 22960, - "continuum": 22961, - "jett": 22962, - "compares": 22963, - "legislator": 22964, - "secession": 22965, - "##nable": 22966, - "##gues": 22967, - "##zuka": 22968, - "translating": 22969, - "reacher": 22970, - "##gley": 22971, - "##ła": 22972, - "aleppo": 22973, - "##agi": 22974, - "tc": 22975, - "orchards": 22976, - "trapping": 22977, - "linguist": 22978, - "versatile": 22979, - "drumming": 22980, - "postage": 22981, - "calhoun": 22982, - "superiors": 22983, - "##mx": 22984, - "barefoot": 22985, - "leary": 22986, - "##cis": 22987, - "ignacio": 22988, - "alfa": 22989, - "kaplan": 22990, - "##rogen": 22991, - "bratislava": 22992, - "mori": 22993, - "##vot": 22994, - "disturb": 22995, - "haas": 22996, - "313": 22997, - "cartridges": 22998, - "gilmore": 22999, - "radiated": 23000, - "salford": 23001, - "tunic": 23002, - "hades": 23003, - "##ulsive": 23004, - "archeological": 23005, - "delilah": 23006, - "magistrates": 23007, - "auditioned": 23008, - "brewster": 23009, - "charters": 23010, - "empowerment": 23011, - "blogs": 23012, - "cappella": 23013, - "dynasties": 23014, - "iroquois": 23015, - "whipping": 23016, - "##krishna": 23017, - "raceway": 23018, - "truths": 23019, - "myra": 23020, - "weaken": 23021, - "judah": 23022, - "mcgregor": 23023, - "##horse": 23024, - "mic": 23025, - "refueling": 23026, - "37th": 23027, - "burnley": 23028, - "bosses": 23029, - "markus": 23030, - "premio": 23031, - "query": 23032, - "##gga": 23033, - "dunbar": 23034, - "##economic": 23035, - "darkest": 23036, - "lyndon": 23037, - "sealing": 23038, - "commendation": 23039, - "reappeared": 23040, - "##mun": 23041, - "addicted": 23042, - "ezio": 23043, - "slaughtered": 23044, - "satisfactory": 23045, - "shuffle": 23046, - "##eves": 23047, - "##thic": 23048, - "##uj": 23049, - "fortification": 23050, - "warrington": 23051, - "##otto": 23052, - "resurrected": 23053, - "fargo": 23054, - "mane": 23055, - "##utable": 23056, - "##lei": 23057, - "##space": 23058, - "foreword": 23059, - "ox": 23060, - "##aris": 23061, - "##vern": 23062, - "abrams": 23063, - "hua": 23064, - "##mento": 23065, - "sakura": 23066, - "##alo": 23067, - "uv": 23068, - "sentimental": 23069, - "##skaya": 23070, - "midfield": 23071, - "##eses": 23072, - "sturdy": 23073, - "scrolls": 23074, - "macleod": 23075, - "##kyu": 23076, - "entropy": 23077, - "##lance": 23078, - "mitochondrial": 23079, - "cicero": 23080, - "excelled": 23081, - "thinner": 23082, - "convoys": 23083, - "perceive": 23084, - "##oslav": 23085, - "##urable": 23086, - "systematically": 23087, - "grind": 23088, - "burkina": 23089, - "287": 23090, - "##tagram": 23091, - "ops": 23092, - "##aman": 23093, - "guantanamo": 23094, - "##cloth": 23095, - "##tite": 23096, - "forcefully": 23097, - "wavy": 23098, - "##jou": 23099, - "pointless": 23100, - "##linger": 23101, - "##tze": 23102, - "layton": 23103, - "portico": 23104, - "superficial": 23105, - "clerical": 23106, - "outlaws": 23107, - "##hism": 23108, - "burials": 23109, - "muir": 23110, - "##inn": 23111, - "creditors": 23112, - "hauling": 23113, - "rattle": 23114, - "##leg": 23115, - "calais": 23116, - "monde": 23117, - "archers": 23118, - "reclaimed": 23119, - "dwell": 23120, - "wexford": 23121, - "hellenic": 23122, - "falsely": 23123, - "remorse": 23124, - "##tek": 23125, - "dough": 23126, - "furnishings": 23127, - "##uttered": 23128, - "gabon": 23129, - "neurological": 23130, - "novice": 23131, - "##igraphy": 23132, - "contemplated": 23133, - "pulpit": 23134, - "nightstand": 23135, - "saratoga": 23136, - "##istan": 23137, - "documenting": 23138, - "pulsing": 23139, - "taluk": 23140, - "##firmed": 23141, - "busted": 23142, - "marital": 23143, - "##rien": 23144, - "disagreements": 23145, - "wasps": 23146, - "##yes": 23147, - "hodge": 23148, - "mcdonnell": 23149, - "mimic": 23150, - "fran": 23151, - "pendant": 23152, - "dhabi": 23153, - "musa": 23154, - "##nington": 23155, - "congratulations": 23156, - "argent": 23157, - "darrell": 23158, - "concussion": 23159, - "losers": 23160, - "regrets": 23161, - "thessaloniki": 23162, - "reversal": 23163, - "donaldson": 23164, - "hardwood": 23165, - "thence": 23166, - "achilles": 23167, - "ritter": 23168, - "##eran": 23169, - "demonic": 23170, - "jurgen": 23171, - "prophets": 23172, - "goethe": 23173, - "eki": 23174, - "classmate": 23175, - "buff": 23176, - "##cking": 23177, - "yank": 23178, - "irrational": 23179, - "##inging": 23180, - "perished": 23181, - "seductive": 23182, - "qur": 23183, - "sourced": 23184, - "##crat": 23185, - "##typic": 23186, - "mustard": 23187, - "ravine": 23188, - "barre": 23189, - "horizontally": 23190, - "characterization": 23191, - "phylogenetic": 23192, - "boise": 23193, - "##dit": 23194, - "##runner": 23195, - "##tower": 23196, - "brutally": 23197, - "intercourse": 23198, - "seduce": 23199, - "##bbing": 23200, - "fay": 23201, - "ferris": 23202, - "ogden": 23203, - "amar": 23204, - "nik": 23205, - "unarmed": 23206, - "##inator": 23207, - "evaluating": 23208, - "kyrgyzstan": 23209, - "sweetness": 23210, - "##lford": 23211, - "##oki": 23212, - "mccormick": 23213, - "meiji": 23214, - "notoriety": 23215, - "stimulate": 23216, - "disrupt": 23217, - "figuring": 23218, - "instructional": 23219, - "mcgrath": 23220, - "##zoo": 23221, - "groundbreaking": 23222, - "##lto": 23223, - "flinch": 23224, - "khorasan": 23225, - "agrarian": 23226, - "bengals": 23227, - "mixer": 23228, - "radiating": 23229, - "##sov": 23230, - "ingram": 23231, - "pitchers": 23232, - "nad": 23233, - "tariff": 23234, - "##cript": 23235, - "tata": 23236, - "##codes": 23237, - "##emi": 23238, - "##ungen": 23239, - "appellate": 23240, - "lehigh": 23241, - "##bled": 23242, - "##giri": 23243, - "brawl": 23244, - "duct": 23245, - "texans": 23246, - "##ciation": 23247, - "##ropolis": 23248, - "skipper": 23249, - "speculative": 23250, - "vomit": 23251, - "doctrines": 23252, - "stresses": 23253, - "253": 23254, - "davy": 23255, - "graders": 23256, - "whitehead": 23257, - "jozef": 23258, - "timely": 23259, - "cumulative": 23260, - "haryana": 23261, - "paints": 23262, - "appropriately": 23263, - "boon": 23264, - "cactus": 23265, - "##ales": 23266, - "##pid": 23267, - "dow": 23268, - "legions": 23269, - "##pit": 23270, - "perceptions": 23271, - "1730": 23272, - "picturesque": 23273, - "##yse": 23274, - "periphery": 23275, - "rune": 23276, - "wr": 23277, - "##aha": 23278, - "celtics": 23279, - "sentencing": 23280, - "whoa": 23281, - "##erin": 23282, - "confirms": 23283, - "variance": 23284, - "425": 23285, - "moines": 23286, - "mathews": 23287, - "spade": 23288, - "rave": 23289, - "m1": 23290, - "fronted": 23291, - "fx": 23292, - "blending": 23293, - "alleging": 23294, - "reared": 23295, - "##gl": 23296, - "237": 23297, - "##paper": 23298, - "grassroots": 23299, - "eroded": 23300, - "##free": 23301, - "##physical": 23302, - "directs": 23303, - "ordeal": 23304, - "##sław": 23305, - "accelerate": 23306, - "hacker": 23307, - "rooftop": 23308, - "##inia": 23309, - "lev": 23310, - "buys": 23311, - "cebu": 23312, - "devote": 23313, - "##lce": 23314, - "specialising": 23315, - "##ulsion": 23316, - "choreographed": 23317, - "repetition": 23318, - "warehouses": 23319, - "##ryl": 23320, - "paisley": 23321, - "tuscany": 23322, - "analogy": 23323, - "sorcerer": 23324, - "hash": 23325, - "huts": 23326, - "shards": 23327, - "descends": 23328, - "exclude": 23329, - "nix": 23330, - "chaplin": 23331, - "gaga": 23332, - "ito": 23333, - "vane": 23334, - "##drich": 23335, - "causeway": 23336, - "misconduct": 23337, - "limo": 23338, - "orchestrated": 23339, - "glands": 23340, - "jana": 23341, - "##kot": 23342, - "u2": 23343, - "##mple": 23344, - "##sons": 23345, - "branching": 23346, - "contrasts": 23347, - "scoop": 23348, - "longed": 23349, - "##virus": 23350, - "chattanooga": 23351, - "##75": 23352, - "syrup": 23353, - "cornerstone": 23354, - "##tized": 23355, - "##mind": 23356, - "##iaceae": 23357, - "careless": 23358, - "precedence": 23359, - "frescoes": 23360, - "##uet": 23361, - "chilled": 23362, - "consult": 23363, - "modelled": 23364, - "snatch": 23365, - "peat": 23366, - "##thermal": 23367, - "caucasian": 23368, - "humane": 23369, - "relaxation": 23370, - "spins": 23371, - "temperance": 23372, - "##lbert": 23373, - "occupations": 23374, - "lambda": 23375, - "hybrids": 23376, - "moons": 23377, - "mp3": 23378, - "##oese": 23379, - "247": 23380, - "rolf": 23381, - "societal": 23382, - "yerevan": 23383, - "ness": 23384, - "##ssler": 23385, - "befriended": 23386, - "mechanized": 23387, - "nominate": 23388, - "trough": 23389, - "boasted": 23390, - "cues": 23391, - "seater": 23392, - "##hom": 23393, - "bends": 23394, - "##tangle": 23395, - "conductors": 23396, - "emptiness": 23397, - "##lmer": 23398, - "eurasian": 23399, - "adriatic": 23400, - "tian": 23401, - "##cie": 23402, - "anxiously": 23403, - "lark": 23404, - "propellers": 23405, - "chichester": 23406, - "jock": 23407, - "ev": 23408, - "2a": 23409, - "##holding": 23410, - "credible": 23411, - "recounts": 23412, - "tori": 23413, - "loyalist": 23414, - "abduction": 23415, - "##hoot": 23416, - "##redo": 23417, - "nepali": 23418, - "##mite": 23419, - "ventral": 23420, - "tempting": 23421, - "##ango": 23422, - "##crats": 23423, - "steered": 23424, - "##wice": 23425, - "javelin": 23426, - "dipping": 23427, - "laborers": 23428, - "prentice": 23429, - "looming": 23430, - "titanium": 23431, - "##ː": 23432, - "badges": 23433, - "emir": 23434, - "tensor": 23435, - "##ntation": 23436, - "egyptians": 23437, - "rash": 23438, - "denies": 23439, - "hawthorne": 23440, - "lombard": 23441, - "showers": 23442, - "wehrmacht": 23443, - "dietary": 23444, - "trojan": 23445, - "##reus": 23446, - "welles": 23447, - "executing": 23448, - "horseshoe": 23449, - "lifeboat": 23450, - "##lak": 23451, - "elsa": 23452, - "infirmary": 23453, - "nearing": 23454, - "roberta": 23455, - "boyer": 23456, - "mutter": 23457, - "trillion": 23458, - "joanne": 23459, - "##fine": 23460, - "##oked": 23461, - "sinks": 23462, - "vortex": 23463, - "uruguayan": 23464, - "clasp": 23465, - "sirius": 23466, - "##block": 23467, - "accelerator": 23468, - "prohibit": 23469, - "sunken": 23470, - "byu": 23471, - "chronological": 23472, - "diplomats": 23473, - "ochreous": 23474, - "510": 23475, - "symmetrical": 23476, - "1644": 23477, - "maia": 23478, - "##tology": 23479, - "salts": 23480, - "reigns": 23481, - "atrocities": 23482, - "##ия": 23483, - "hess": 23484, - "bared": 23485, - "issn": 23486, - "##vyn": 23487, - "cater": 23488, - "saturated": 23489, - "##cycle": 23490, - "##isse": 23491, - "sable": 23492, - "voyager": 23493, - "dyer": 23494, - "yusuf": 23495, - "##inge": 23496, - "fountains": 23497, - "wolff": 23498, - "##39": 23499, - "##nni": 23500, - "engraving": 23501, - "rollins": 23502, - "atheist": 23503, - "ominous": 23504, - "##ault": 23505, - "herr": 23506, - "chariot": 23507, - "martina": 23508, - "strung": 23509, - "##fell": 23510, - "##farlane": 23511, - "horrific": 23512, - "sahib": 23513, - "gazes": 23514, - "saetan": 23515, - "erased": 23516, - "ptolemy": 23517, - "##olic": 23518, - "flushing": 23519, - "lauderdale": 23520, - "analytic": 23521, - "##ices": 23522, - "530": 23523, - "navarro": 23524, - "beak": 23525, - "gorilla": 23526, - "herrera": 23527, - "broom": 23528, - "guadalupe": 23529, - "raiding": 23530, - "sykes": 23531, - "311": 23532, - "bsc": 23533, - "deliveries": 23534, - "1720": 23535, - "invasions": 23536, - "carmichael": 23537, - "tajikistan": 23538, - "thematic": 23539, - "ecumenical": 23540, - "sentiments": 23541, - "onstage": 23542, - "##rians": 23543, - "##brand": 23544, - "##sume": 23545, - "catastrophic": 23546, - "flanks": 23547, - "molten": 23548, - "##arns": 23549, - "waller": 23550, - "aimee": 23551, - "terminating": 23552, - "##icing": 23553, - "alternately": 23554, - "##oche": 23555, - "nehru": 23556, - "printers": 23557, - "outraged": 23558, - "##eving": 23559, - "empires": 23560, - "template": 23561, - "banners": 23562, - "repetitive": 23563, - "za": 23564, - "##oise": 23565, - "vegetarian": 23566, - "##tell": 23567, - "guiana": 23568, - "opt": 23569, - "cavendish": 23570, - "lucknow": 23571, - "synthesized": 23572, - "##hani": 23573, - "##mada": 23574, - "finalized": 23575, - "##ctable": 23576, - "fictitious": 23577, - "mayoral": 23578, - "unreliable": 23579, - "##enham": 23580, - "embracing": 23581, - "peppers": 23582, - "rbis": 23583, - "##chio": 23584, - "##neo": 23585, - "inhibition": 23586, - "slashed": 23587, - "togo": 23588, - "orderly": 23589, - "embroidered": 23590, - "safari": 23591, - "salty": 23592, - "236": 23593, - "barron": 23594, - "benito": 23595, - "totaled": 23596, - "##dak": 23597, - "pubs": 23598, - "simulated": 23599, - "caden": 23600, - "devin": 23601, - "tolkien": 23602, - "momma": 23603, - "welding": 23604, - "sesame": 23605, - "##ept": 23606, - "gottingen": 23607, - "hardness": 23608, - "630": 23609, - "shaman": 23610, - "temeraire": 23611, - "620": 23612, - "adequately": 23613, - "pediatric": 23614, - "##kit": 23615, - "ck": 23616, - "assertion": 23617, - "radicals": 23618, - "composure": 23619, - "cadence": 23620, - "seafood": 23621, - "beaufort": 23622, - "lazarus": 23623, - "mani": 23624, - "warily": 23625, - "cunning": 23626, - "kurdistan": 23627, - "249": 23628, - "cantata": 23629, - "##kir": 23630, - "ares": 23631, - "##41": 23632, - "##clusive": 23633, - "nape": 23634, - "townland": 23635, - "geared": 23636, - "insulted": 23637, - "flutter": 23638, - "boating": 23639, - "violate": 23640, - "draper": 23641, - "dumping": 23642, - "malmo": 23643, - "##hh": 23644, - "##romatic": 23645, - "firearm": 23646, - "alta": 23647, - "bono": 23648, - "obscured": 23649, - "##clave": 23650, - "exceeds": 23651, - "panorama": 23652, - "unbelievable": 23653, - "##train": 23654, - "preschool": 23655, - "##essed": 23656, - "disconnected": 23657, - "installing": 23658, - "rescuing": 23659, - "secretaries": 23660, - "accessibility": 23661, - "##castle": 23662, - "##drive": 23663, - "##ifice": 23664, - "##film": 23665, - "bouts": 23666, - "slug": 23667, - "waterway": 23668, - "mindanao": 23669, - "##buro": 23670, - "##ratic": 23671, - "halves": 23672, - "##ل": 23673, - "calming": 23674, - "liter": 23675, - "maternity": 23676, - "adorable": 23677, - "bragg": 23678, - "electrification": 23679, - "mcc": 23680, - "##dote": 23681, - "roxy": 23682, - "schizophrenia": 23683, - "##body": 23684, - "munoz": 23685, - "kaye": 23686, - "whaling": 23687, - "239": 23688, - "mil": 23689, - "tingling": 23690, - "tolerant": 23691, - "##ago": 23692, - "unconventional": 23693, - "volcanoes": 23694, - "##finder": 23695, - "deportivo": 23696, - "##llie": 23697, - "robson": 23698, - "kaufman": 23699, - "neuroscience": 23700, - "wai": 23701, - "deportation": 23702, - "masovian": 23703, - "scraping": 23704, - "converse": 23705, - "##bh": 23706, - "hacking": 23707, - "bulge": 23708, - "##oun": 23709, - "administratively": 23710, - "yao": 23711, - "580": 23712, - "amp": 23713, - "mammoth": 23714, - "booster": 23715, - "claremont": 23716, - "hooper": 23717, - "nomenclature": 23718, - "pursuits": 23719, - "mclaughlin": 23720, - "melinda": 23721, - "##sul": 23722, - "catfish": 23723, - "barclay": 23724, - "substrates": 23725, - "taxa": 23726, - "zee": 23727, - "originals": 23728, - "kimberly": 23729, - "packets": 23730, - "padma": 23731, - "##ality": 23732, - "borrowing": 23733, - "ostensibly": 23734, - "solvent": 23735, - "##bri": 23736, - "##genesis": 23737, - "##mist": 23738, - "lukas": 23739, - "shreveport": 23740, - "veracruz": 23741, - "##ь": 23742, - "##lou": 23743, - "##wives": 23744, - "cheney": 23745, - "tt": 23746, - "anatolia": 23747, - "hobbs": 23748, - "##zyn": 23749, - "cyclic": 23750, - "radiant": 23751, - "alistair": 23752, - "greenish": 23753, - "siena": 23754, - "dat": 23755, - "independents": 23756, - "##bation": 23757, - "conform": 23758, - "pieter": 23759, - "hyper": 23760, - "applicant": 23761, - "bradshaw": 23762, - "spores": 23763, - "telangana": 23764, - "vinci": 23765, - "inexpensive": 23766, - "nuclei": 23767, - "322": 23768, - "jang": 23769, - "nme": 23770, - "soho": 23771, - "spd": 23772, - "##ign": 23773, - "cradled": 23774, - "receptionist": 23775, - "pow": 23776, - "##43": 23777, - "##rika": 23778, - "fascism": 23779, - "##ifer": 23780, - "experimenting": 23781, - "##ading": 23782, - "##iec": 23783, - "##region": 23784, - "345": 23785, - "jocelyn": 23786, - "maris": 23787, - "stair": 23788, - "nocturnal": 23789, - "toro": 23790, - "constabulary": 23791, - "elgin": 23792, - "##kker": 23793, - "msc": 23794, - "##giving": 23795, - "##schen": 23796, - "##rase": 23797, - "doherty": 23798, - "doping": 23799, - "sarcastically": 23800, - "batter": 23801, - "maneuvers": 23802, - "##cano": 23803, - "##apple": 23804, - "##gai": 23805, - "##git": 23806, - "intrinsic": 23807, - "##nst": 23808, - "##stor": 23809, - "1753": 23810, - "showtime": 23811, - "cafes": 23812, - "gasps": 23813, - "lviv": 23814, - "ushered": 23815, - "##thed": 23816, - "fours": 23817, - "restart": 23818, - "astonishment": 23819, - "transmitting": 23820, - "flyer": 23821, - "shrugs": 23822, - "##sau": 23823, - "intriguing": 23824, - "cones": 23825, - "dictated": 23826, - "mushrooms": 23827, - "medial": 23828, - "##kovsky": 23829, - "##elman": 23830, - "escorting": 23831, - "gaped": 23832, - "##26": 23833, - "godfather": 23834, - "##door": 23835, - "##sell": 23836, - "djs": 23837, - "recaptured": 23838, - "timetable": 23839, - "vila": 23840, - "1710": 23841, - "3a": 23842, - "aerodrome": 23843, - "mortals": 23844, - "scientology": 23845, - "##orne": 23846, - "angelina": 23847, - "mag": 23848, - "convection": 23849, - "unpaid": 23850, - "insertion": 23851, - "intermittent": 23852, - "lego": 23853, - "##nated": 23854, - "endeavor": 23855, - "kota": 23856, - "pereira": 23857, - "##lz": 23858, - "304": 23859, - "bwv": 23860, - "glamorgan": 23861, - "insults": 23862, - "agatha": 23863, - "fey": 23864, - "##cend": 23865, - "fleetwood": 23866, - "mahogany": 23867, - "protruding": 23868, - "steamship": 23869, - "zeta": 23870, - "##arty": 23871, - "mcguire": 23872, - "suspense": 23873, - "##sphere": 23874, - "advising": 23875, - "urges": 23876, - "##wala": 23877, - "hurriedly": 23878, - "meteor": 23879, - "gilded": 23880, - "inline": 23881, - "arroyo": 23882, - "stalker": 23883, - "##oge": 23884, - "excitedly": 23885, - "revered": 23886, - "##cure": 23887, - "earle": 23888, - "introductory": 23889, - "##break": 23890, - "##ilde": 23891, - "mutants": 23892, - "puff": 23893, - "pulses": 23894, - "reinforcement": 23895, - "##haling": 23896, - "curses": 23897, - "lizards": 23898, - "stalk": 23899, - "correlated": 23900, - "##fixed": 23901, - "fallout": 23902, - "macquarie": 23903, - "##unas": 23904, - "bearded": 23905, - "denton": 23906, - "heaving": 23907, - "802": 23908, - "##ocation": 23909, - "winery": 23910, - "assign": 23911, - "dortmund": 23912, - "##lkirk": 23913, - "everest": 23914, - "invariant": 23915, - "charismatic": 23916, - "susie": 23917, - "##elling": 23918, - "bled": 23919, - "lesley": 23920, - "telegram": 23921, - "sumner": 23922, - "bk": 23923, - "##ogen": 23924, - "##к": 23925, - "wilcox": 23926, - "needy": 23927, - "colbert": 23928, - "duval": 23929, - "##iferous": 23930, - "##mbled": 23931, - "allotted": 23932, - "attends": 23933, - "imperative": 23934, - "##hita": 23935, - "replacements": 23936, - "hawker": 23937, - "##inda": 23938, - "insurgency": 23939, - "##zee": 23940, - "##eke": 23941, - "casts": 23942, - "##yla": 23943, - "680": 23944, - "ives": 23945, - "transitioned": 23946, - "##pack": 23947, - "##powering": 23948, - "authoritative": 23949, - "baylor": 23950, - "flex": 23951, - "cringed": 23952, - "plaintiffs": 23953, - "woodrow": 23954, - "##skie": 23955, - "drastic": 23956, - "ape": 23957, - "aroma": 23958, - "unfolded": 23959, - "commotion": 23960, - "nt": 23961, - "preoccupied": 23962, - "theta": 23963, - "routines": 23964, - "lasers": 23965, - "privatization": 23966, - "wand": 23967, - "domino": 23968, - "ek": 23969, - "clenching": 23970, - "nsa": 23971, - "strategically": 23972, - "showered": 23973, - "bile": 23974, - "handkerchief": 23975, - "pere": 23976, - "storing": 23977, - "christophe": 23978, - "insulting": 23979, - "316": 23980, - "nakamura": 23981, - "romani": 23982, - "asiatic": 23983, - "magdalena": 23984, - "palma": 23985, - "cruises": 23986, - "stripping": 23987, - "405": 23988, - "konstantin": 23989, - "soaring": 23990, - "##berman": 23991, - "colloquially": 23992, - "forerunner": 23993, - "havilland": 23994, - "incarcerated": 23995, - "parasites": 23996, - "sincerity": 23997, - "##utus": 23998, - "disks": 23999, - "plank": 24000, - "saigon": 24001, - "##ining": 24002, - "corbin": 24003, - "homo": 24004, - "ornaments": 24005, - "powerhouse": 24006, - "##tlement": 24007, - "chong": 24008, - "fastened": 24009, - "feasibility": 24010, - "idf": 24011, - "morphological": 24012, - "usable": 24013, - "##nish": 24014, - "##zuki": 24015, - "aqueduct": 24016, - "jaguars": 24017, - "keepers": 24018, - "##flies": 24019, - "aleksandr": 24020, - "faust": 24021, - "assigns": 24022, - "ewing": 24023, - "bacterium": 24024, - "hurled": 24025, - "tricky": 24026, - "hungarians": 24027, - "integers": 24028, - "wallis": 24029, - "321": 24030, - "yamaha": 24031, - "##isha": 24032, - "hushed": 24033, - "oblivion": 24034, - "aviator": 24035, - "evangelist": 24036, - "friars": 24037, - "##eller": 24038, - "monograph": 24039, - "ode": 24040, - "##nary": 24041, - "airplanes": 24042, - "labourers": 24043, - "charms": 24044, - "##nee": 24045, - "1661": 24046, - "hagen": 24047, - "tnt": 24048, - "rudder": 24049, - "fiesta": 24050, - "transcript": 24051, - "dorothea": 24052, - "ska": 24053, - "inhibitor": 24054, - "maccabi": 24055, - "retorted": 24056, - "raining": 24057, - "encompassed": 24058, - "clauses": 24059, - "menacing": 24060, - "1642": 24061, - "lineman": 24062, - "##gist": 24063, - "vamps": 24064, - "##ape": 24065, - "##dick": 24066, - "gloom": 24067, - "##rera": 24068, - "dealings": 24069, - "easing": 24070, - "seekers": 24071, - "##nut": 24072, - "##pment": 24073, - "helens": 24074, - "unmanned": 24075, - "##anu": 24076, - "##isson": 24077, - "basics": 24078, - "##amy": 24079, - "##ckman": 24080, - "adjustments": 24081, - "1688": 24082, - "brutality": 24083, - "horne": 24084, - "##zell": 24085, - "sui": 24086, - "##55": 24087, - "##mable": 24088, - "aggregator": 24089, - "##thal": 24090, - "rhino": 24091, - "##drick": 24092, - "##vira": 24093, - "counters": 24094, - "zoom": 24095, - "##01": 24096, - "##rting": 24097, - "mn": 24098, - "montenegrin": 24099, - "packard": 24100, - "##unciation": 24101, - "##♭": 24102, - "##kki": 24103, - "reclaim": 24104, - "scholastic": 24105, - "thugs": 24106, - "pulsed": 24107, - "##icia": 24108, - "syriac": 24109, - "quan": 24110, - "saddam": 24111, - "banda": 24112, - "kobe": 24113, - "blaming": 24114, - "buddies": 24115, - "dissent": 24116, - "##lusion": 24117, - "##usia": 24118, - "corbett": 24119, - "jaya": 24120, - "delle": 24121, - "erratic": 24122, - "lexie": 24123, - "##hesis": 24124, - "435": 24125, - "amiga": 24126, - "hermes": 24127, - "##pressing": 24128, - "##leen": 24129, - "chapels": 24130, - "gospels": 24131, - "jamal": 24132, - "##uating": 24133, - "compute": 24134, - "revolving": 24135, - "warp": 24136, - "##sso": 24137, - "##thes": 24138, - "armory": 24139, - "##eras": 24140, - "##gol": 24141, - "antrim": 24142, - "loki": 24143, - "##kow": 24144, - "##asian": 24145, - "##good": 24146, - "##zano": 24147, - "braid": 24148, - "handwriting": 24149, - "subdistrict": 24150, - "funky": 24151, - "pantheon": 24152, - "##iculate": 24153, - "concurrency": 24154, - "estimation": 24155, - "improper": 24156, - "juliana": 24157, - "##his": 24158, - "newcomers": 24159, - "johnstone": 24160, - "staten": 24161, - "communicated": 24162, - "##oco": 24163, - "##alle": 24164, - "sausage": 24165, - "stormy": 24166, - "##stered": 24167, - "##tters": 24168, - "superfamily": 24169, - "##grade": 24170, - "acidic": 24171, - "collateral": 24172, - "tabloid": 24173, - "##oped": 24174, - "##rza": 24175, - "bladder": 24176, - "austen": 24177, - "##ellant": 24178, - "mcgraw": 24179, - "##hay": 24180, - "hannibal": 24181, - "mein": 24182, - "aquino": 24183, - "lucifer": 24184, - "wo": 24185, - "badger": 24186, - "boar": 24187, - "cher": 24188, - "christensen": 24189, - "greenberg": 24190, - "interruption": 24191, - "##kken": 24192, - "jem": 24193, - "244": 24194, - "mocked": 24195, - "bottoms": 24196, - "cambridgeshire": 24197, - "##lide": 24198, - "sprawling": 24199, - "##bbly": 24200, - "eastwood": 24201, - "ghent": 24202, - "synth": 24203, - "##buck": 24204, - "advisers": 24205, - "##bah": 24206, - "nominally": 24207, - "hapoel": 24208, - "qu": 24209, - "daggers": 24210, - "estranged": 24211, - "fabricated": 24212, - "towels": 24213, - "vinnie": 24214, - "wcw": 24215, - "misunderstanding": 24216, - "anglia": 24217, - "nothin": 24218, - "unmistakable": 24219, - "##dust": 24220, - "##lova": 24221, - "chilly": 24222, - "marquette": 24223, - "truss": 24224, - "##edge": 24225, - "##erine": 24226, - "reece": 24227, - "##lty": 24228, - "##chemist": 24229, - "##connected": 24230, - "272": 24231, - "308": 24232, - "41st": 24233, - "bash": 24234, - "raion": 24235, - "waterfalls": 24236, - "##ump": 24237, - "##main": 24238, - "labyrinth": 24239, - "queue": 24240, - "theorist": 24241, - "##istle": 24242, - "bharatiya": 24243, - "flexed": 24244, - "soundtracks": 24245, - "rooney": 24246, - "leftist": 24247, - "patrolling": 24248, - "wharton": 24249, - "plainly": 24250, - "alleviate": 24251, - "eastman": 24252, - "schuster": 24253, - "topographic": 24254, - "engages": 24255, - "immensely": 24256, - "unbearable": 24257, - "fairchild": 24258, - "1620": 24259, - "dona": 24260, - "lurking": 24261, - "parisian": 24262, - "oliveira": 24263, - "ia": 24264, - "indictment": 24265, - "hahn": 24266, - "bangladeshi": 24267, - "##aster": 24268, - "vivo": 24269, - "##uming": 24270, - "##ential": 24271, - "antonia": 24272, - "expects": 24273, - "indoors": 24274, - "kildare": 24275, - "harlan": 24276, - "##logue": 24277, - "##ogenic": 24278, - "##sities": 24279, - "forgiven": 24280, - "##wat": 24281, - "childish": 24282, - "tavi": 24283, - "##mide": 24284, - "##orra": 24285, - "plausible": 24286, - "grimm": 24287, - "successively": 24288, - "scooted": 24289, - "##bola": 24290, - "##dget": 24291, - "##rith": 24292, - "spartans": 24293, - "emery": 24294, - "flatly": 24295, - "azure": 24296, - "epilogue": 24297, - "##wark": 24298, - "flourish": 24299, - "##iny": 24300, - "##tracted": 24301, - "##overs": 24302, - "##oshi": 24303, - "bestseller": 24304, - "distressed": 24305, - "receipt": 24306, - "spitting": 24307, - "hermit": 24308, - "topological": 24309, - "##cot": 24310, - "drilled": 24311, - "subunit": 24312, - "francs": 24313, - "##layer": 24314, - "eel": 24315, - "##fk": 24316, - "##itas": 24317, - "octopus": 24318, - "footprint": 24319, - "petitions": 24320, - "ufo": 24321, - "##say": 24322, - "##foil": 24323, - "interfering": 24324, - "leaking": 24325, - "palo": 24326, - "##metry": 24327, - "thistle": 24328, - "valiant": 24329, - "##pic": 24330, - "narayan": 24331, - "mcpherson": 24332, - "##fast": 24333, - "gonzales": 24334, - "##ym": 24335, - "##enne": 24336, - "dustin": 24337, - "novgorod": 24338, - "solos": 24339, - "##zman": 24340, - "doin": 24341, - "##raph": 24342, - "##patient": 24343, - "##meyer": 24344, - "soluble": 24345, - "ashland": 24346, - "cuffs": 24347, - "carole": 24348, - "pendleton": 24349, - "whistling": 24350, - "vassal": 24351, - "##river": 24352, - "deviation": 24353, - "revisited": 24354, - "constituents": 24355, - "rallied": 24356, - "rotate": 24357, - "loomed": 24358, - "##eil": 24359, - "##nting": 24360, - "amateurs": 24361, - "augsburg": 24362, - "auschwitz": 24363, - "crowns": 24364, - "skeletons": 24365, - "##cona": 24366, - "bonnet": 24367, - "257": 24368, - "dummy": 24369, - "globalization": 24370, - "simeon": 24371, - "sleeper": 24372, - "mandal": 24373, - "differentiated": 24374, - "##crow": 24375, - "##mare": 24376, - "milne": 24377, - "bundled": 24378, - "exasperated": 24379, - "talmud": 24380, - "owes": 24381, - "segregated": 24382, - "##feng": 24383, - "##uary": 24384, - "dentist": 24385, - "piracy": 24386, - "props": 24387, - "##rang": 24388, - "devlin": 24389, - "##torium": 24390, - "malicious": 24391, - "paws": 24392, - "##laid": 24393, - "dependency": 24394, - "##ergy": 24395, - "##fers": 24396, - "##enna": 24397, - "258": 24398, - "pistons": 24399, - "rourke": 24400, - "jed": 24401, - "grammatical": 24402, - "tres": 24403, - "maha": 24404, - "wig": 24405, - "512": 24406, - "ghostly": 24407, - "jayne": 24408, - "##achal": 24409, - "##creen": 24410, - "##ilis": 24411, - "##lins": 24412, - "##rence": 24413, - "designate": 24414, - "##with": 24415, - "arrogance": 24416, - "cambodian": 24417, - "clones": 24418, - "showdown": 24419, - "throttle": 24420, - "twain": 24421, - "##ception": 24422, - "lobes": 24423, - "metz": 24424, - "nagoya": 24425, - "335": 24426, - "braking": 24427, - "##furt": 24428, - "385": 24429, - "roaming": 24430, - "##minster": 24431, - "amin": 24432, - "crippled": 24433, - "##37": 24434, - "##llary": 24435, - "indifferent": 24436, - "hoffmann": 24437, - "idols": 24438, - "intimidating": 24439, - "1751": 24440, - "261": 24441, - "influenza": 24442, - "memo": 24443, - "onions": 24444, - "1748": 24445, - "bandage": 24446, - "consciously": 24447, - "##landa": 24448, - "##rage": 24449, - "clandestine": 24450, - "observes": 24451, - "swiped": 24452, - "tangle": 24453, - "##ener": 24454, - "##jected": 24455, - "##trum": 24456, - "##bill": 24457, - "##lta": 24458, - "hugs": 24459, - "congresses": 24460, - "josiah": 24461, - "spirited": 24462, - "##dek": 24463, - "humanist": 24464, - "managerial": 24465, - "filmmaking": 24466, - "inmate": 24467, - "rhymes": 24468, - "debuting": 24469, - "grimsby": 24470, - "ur": 24471, - "##laze": 24472, - "duplicate": 24473, - "vigor": 24474, - "##tf": 24475, - "republished": 24476, - "bolshevik": 24477, - "refurbishment": 24478, - "antibiotics": 24479, - "martini": 24480, - "methane": 24481, - "newscasts": 24482, - "royale": 24483, - "horizons": 24484, - "levant": 24485, - "iain": 24486, - "visas": 24487, - "##ischen": 24488, - "paler": 24489, - "##around": 24490, - "manifestation": 24491, - "snuck": 24492, - "alf": 24493, - "chop": 24494, - "futile": 24495, - "pedestal": 24496, - "rehab": 24497, - "##kat": 24498, - "bmg": 24499, - "kerman": 24500, - "res": 24501, - "fairbanks": 24502, - "jarrett": 24503, - "abstraction": 24504, - "saharan": 24505, - "##zek": 24506, - "1746": 24507, - "procedural": 24508, - "clearer": 24509, - "kincaid": 24510, - "sash": 24511, - "luciano": 24512, - "##ffey": 24513, - "crunch": 24514, - "helmut": 24515, - "##vara": 24516, - "revolutionaries": 24517, - "##tute": 24518, - "creamy": 24519, - "leach": 24520, - "##mmon": 24521, - "1747": 24522, - "permitting": 24523, - "nes": 24524, - "plight": 24525, - "wendell": 24526, - "##lese": 24527, - "contra": 24528, - "ts": 24529, - "clancy": 24530, - "ipa": 24531, - "mach": 24532, - "staples": 24533, - "autopsy": 24534, - "disturbances": 24535, - "nueva": 24536, - "karin": 24537, - "pontiac": 24538, - "##uding": 24539, - "proxy": 24540, - "venerable": 24541, - "haunt": 24542, - "leto": 24543, - "bergman": 24544, - "expands": 24545, - "##helm": 24546, - "wal": 24547, - "##pipe": 24548, - "canning": 24549, - "celine": 24550, - "cords": 24551, - "obesity": 24552, - "##enary": 24553, - "intrusion": 24554, - "planner": 24555, - "##phate": 24556, - "reasoned": 24557, - "sequencing": 24558, - "307": 24559, - "harrow": 24560, - "##chon": 24561, - "##dora": 24562, - "marred": 24563, - "mcintyre": 24564, - "repay": 24565, - "tarzan": 24566, - "darting": 24567, - "248": 24568, - "harrisburg": 24569, - "margarita": 24570, - "repulsed": 24571, - "##hur": 24572, - "##lding": 24573, - "belinda": 24574, - "hamburger": 24575, - "novo": 24576, - "compliant": 24577, - "runways": 24578, - "bingham": 24579, - "registrar": 24580, - "skyscraper": 24581, - "ic": 24582, - "cuthbert": 24583, - "improvisation": 24584, - "livelihood": 24585, - "##corp": 24586, - "##elial": 24587, - "admiring": 24588, - "##dened": 24589, - "sporadic": 24590, - "believer": 24591, - "casablanca": 24592, - "popcorn": 24593, - "##29": 24594, - "asha": 24595, - "shovel": 24596, - "##bek": 24597, - "##dice": 24598, - "coiled": 24599, - "tangible": 24600, - "##dez": 24601, - "casper": 24602, - "elsie": 24603, - "resin": 24604, - "tenderness": 24605, - "rectory": 24606, - "##ivision": 24607, - "avail": 24608, - "sonar": 24609, - "##mori": 24610, - "boutique": 24611, - "##dier": 24612, - "guerre": 24613, - "bathed": 24614, - "upbringing": 24615, - "vaulted": 24616, - "sandals": 24617, - "blessings": 24618, - "##naut": 24619, - "##utnant": 24620, - "1680": 24621, - "306": 24622, - "foxes": 24623, - "pia": 24624, - "corrosion": 24625, - "hesitantly": 24626, - "confederates": 24627, - "crystalline": 24628, - "footprints": 24629, - "shapiro": 24630, - "tirana": 24631, - "valentin": 24632, - "drones": 24633, - "45th": 24634, - "microscope": 24635, - "shipments": 24636, - "texted": 24637, - "inquisition": 24638, - "wry": 24639, - "guernsey": 24640, - "unauthorized": 24641, - "resigning": 24642, - "760": 24643, - "ripple": 24644, - "schubert": 24645, - "stu": 24646, - "reassure": 24647, - "felony": 24648, - "##ardo": 24649, - "brittle": 24650, - "koreans": 24651, - "##havan": 24652, - "##ives": 24653, - "dun": 24654, - "implicit": 24655, - "tyres": 24656, - "##aldi": 24657, - "##lth": 24658, - "magnolia": 24659, - "##ehan": 24660, - "##puri": 24661, - "##poulos": 24662, - "aggressively": 24663, - "fei": 24664, - "gr": 24665, - "familiarity": 24666, - "##poo": 24667, - "indicative": 24668, - "##trust": 24669, - "fundamentally": 24670, - "jimmie": 24671, - "overrun": 24672, - "395": 24673, - "anchors": 24674, - "moans": 24675, - "##opus": 24676, - "britannia": 24677, - "armagh": 24678, - "##ggle": 24679, - "purposely": 24680, - "seizing": 24681, - "##vao": 24682, - "bewildered": 24683, - "mundane": 24684, - "avoidance": 24685, - "cosmopolitan": 24686, - "geometridae": 24687, - "quartermaster": 24688, - "caf": 24689, - "415": 24690, - "chatter": 24691, - "engulfed": 24692, - "gleam": 24693, - "purge": 24694, - "##icate": 24695, - "juliette": 24696, - "jurisprudence": 24697, - "guerra": 24698, - "revisions": 24699, - "##bn": 24700, - "casimir": 24701, - "brew": 24702, - "##jm": 24703, - "1749": 24704, - "clapton": 24705, - "cloudy": 24706, - "conde": 24707, - "hermitage": 24708, - "278": 24709, - "simulations": 24710, - "torches": 24711, - "vincenzo": 24712, - "matteo": 24713, - "##rill": 24714, - "hidalgo": 24715, - "booming": 24716, - "westbound": 24717, - "accomplishment": 24718, - "tentacles": 24719, - "unaffected": 24720, - "##sius": 24721, - "annabelle": 24722, - "flopped": 24723, - "sloping": 24724, - "##litz": 24725, - "dreamer": 24726, - "interceptor": 24727, - "vu": 24728, - "##loh": 24729, - "consecration": 24730, - "copying": 24731, - "messaging": 24732, - "breaker": 24733, - "climates": 24734, - "hospitalized": 24735, - "1752": 24736, - "torino": 24737, - "afternoons": 24738, - "winfield": 24739, - "witnessing": 24740, - "##teacher": 24741, - "breakers": 24742, - "choirs": 24743, - "sawmill": 24744, - "coldly": 24745, - "##ege": 24746, - "sipping": 24747, - "haste": 24748, - "uninhabited": 24749, - "conical": 24750, - "bibliography": 24751, - "pamphlets": 24752, - "severn": 24753, - "edict": 24754, - "##oca": 24755, - "deux": 24756, - "illnesses": 24757, - "grips": 24758, - "##pl": 24759, - "rehearsals": 24760, - "sis": 24761, - "thinkers": 24762, - "tame": 24763, - "##keepers": 24764, - "1690": 24765, - "acacia": 24766, - "reformer": 24767, - "##osed": 24768, - "##rys": 24769, - "shuffling": 24770, - "##iring": 24771, - "##shima": 24772, - "eastbound": 24773, - "ionic": 24774, - "rhea": 24775, - "flees": 24776, - "littered": 24777, - "##oum": 24778, - "rocker": 24779, - "vomiting": 24780, - "groaning": 24781, - "champ": 24782, - "overwhelmingly": 24783, - "civilizations": 24784, - "paces": 24785, - "sloop": 24786, - "adoptive": 24787, - "##tish": 24788, - "skaters": 24789, - "##vres": 24790, - "aiding": 24791, - "mango": 24792, - "##joy": 24793, - "nikola": 24794, - "shriek": 24795, - "##ignon": 24796, - "pharmaceuticals": 24797, - "##mg": 24798, - "tuna": 24799, - "calvert": 24800, - "gustavo": 24801, - "stocked": 24802, - "yearbook": 24803, - "##urai": 24804, - "##mana": 24805, - "computed": 24806, - "subsp": 24807, - "riff": 24808, - "hanoi": 24809, - "kelvin": 24810, - "hamid": 24811, - "moors": 24812, - "pastures": 24813, - "summons": 24814, - "jihad": 24815, - "nectar": 24816, - "##ctors": 24817, - "bayou": 24818, - "untitled": 24819, - "pleasing": 24820, - "vastly": 24821, - "republics": 24822, - "intellect": 24823, - "##η": 24824, - "##ulio": 24825, - "##tou": 24826, - "crumbling": 24827, - "stylistic": 24828, - "sb": 24829, - "##ی": 24830, - "consolation": 24831, - "frequented": 24832, - "h₂o": 24833, - "walden": 24834, - "widows": 24835, - "##iens": 24836, - "404": 24837, - "##ignment": 24838, - "chunks": 24839, - "improves": 24840, - "288": 24841, - "grit": 24842, - "recited": 24843, - "##dev": 24844, - "snarl": 24845, - "sociological": 24846, - "##arte": 24847, - "##gul": 24848, - "inquired": 24849, - "##held": 24850, - "bruise": 24851, - "clube": 24852, - "consultancy": 24853, - "homogeneous": 24854, - "hornets": 24855, - "multiplication": 24856, - "pasta": 24857, - "prick": 24858, - "savior": 24859, - "##grin": 24860, - "##kou": 24861, - "##phile": 24862, - "yoon": 24863, - "##gara": 24864, - "grimes": 24865, - "vanishing": 24866, - "cheering": 24867, - "reacting": 24868, - "bn": 24869, - "distillery": 24870, - "##quisite": 24871, - "##vity": 24872, - "coe": 24873, - "dockyard": 24874, - "massif": 24875, - "##jord": 24876, - "escorts": 24877, - "voss": 24878, - "##valent": 24879, - "byte": 24880, - "chopped": 24881, - "hawke": 24882, - "illusions": 24883, - "workings": 24884, - "floats": 24885, - "##koto": 24886, - "##vac": 24887, - "kv": 24888, - "annapolis": 24889, - "madden": 24890, - "##onus": 24891, - "alvaro": 24892, - "noctuidae": 24893, - "##cum": 24894, - "##scopic": 24895, - "avenge": 24896, - "steamboat": 24897, - "forte": 24898, - "illustrates": 24899, - "erika": 24900, - "##trip": 24901, - "570": 24902, - "dew": 24903, - "nationalities": 24904, - "bran": 24905, - "manifested": 24906, - "thirsty": 24907, - "diversified": 24908, - "muscled": 24909, - "reborn": 24910, - "##standing": 24911, - "arson": 24912, - "##lessness": 24913, - "##dran": 24914, - "##logram": 24915, - "##boys": 24916, - "##kushima": 24917, - "##vious": 24918, - "willoughby": 24919, - "##phobia": 24920, - "286": 24921, - "alsace": 24922, - "dashboard": 24923, - "yuki": 24924, - "##chai": 24925, - "granville": 24926, - "myspace": 24927, - "publicized": 24928, - "tricked": 24929, - "##gang": 24930, - "adjective": 24931, - "##ater": 24932, - "relic": 24933, - "reorganisation": 24934, - "enthusiastically": 24935, - "indications": 24936, - "saxe": 24937, - "##lassified": 24938, - "consolidate": 24939, - "iec": 24940, - "padua": 24941, - "helplessly": 24942, - "ramps": 24943, - "renaming": 24944, - "regulars": 24945, - "pedestrians": 24946, - "accents": 24947, - "convicts": 24948, - "inaccurate": 24949, - "lowers": 24950, - "mana": 24951, - "##pati": 24952, - "barrie": 24953, - "bjp": 24954, - "outta": 24955, - "someplace": 24956, - "berwick": 24957, - "flanking": 24958, - "invoked": 24959, - "marrow": 24960, - "sparsely": 24961, - "excerpts": 24962, - "clothed": 24963, - "rei": 24964, - "##ginal": 24965, - "wept": 24966, - "##straße": 24967, - "##vish": 24968, - "alexa": 24969, - "excel": 24970, - "##ptive": 24971, - "membranes": 24972, - "aquitaine": 24973, - "creeks": 24974, - "cutler": 24975, - "sheppard": 24976, - "implementations": 24977, - "ns": 24978, - "##dur": 24979, - "fragrance": 24980, - "budge": 24981, - "concordia": 24982, - "magnesium": 24983, - "marcelo": 24984, - "##antes": 24985, - "gladly": 24986, - "vibrating": 24987, - "##rral": 24988, - "##ggles": 24989, - "montrose": 24990, - "##omba": 24991, - "lew": 24992, - "seamus": 24993, - "1630": 24994, - "cocky": 24995, - "##ament": 24996, - "##uen": 24997, - "bjorn": 24998, - "##rrick": 24999, - "fielder": 25000, - "fluttering": 25001, - "##lase": 25002, - "methyl": 25003, - "kimberley": 25004, - "mcdowell": 25005, - "reductions": 25006, - "barbed": 25007, - "##jic": 25008, - "##tonic": 25009, - "aeronautical": 25010, - "condensed": 25011, - "distracting": 25012, - "##promising": 25013, - "huffed": 25014, - "##cala": 25015, - "##sle": 25016, - "claudius": 25017, - "invincible": 25018, - "missy": 25019, - "pious": 25020, - "balthazar": 25021, - "ci": 25022, - "##lang": 25023, - "butte": 25024, - "combo": 25025, - "orson": 25026, - "##dication": 25027, - "myriad": 25028, - "1707": 25029, - "silenced": 25030, - "##fed": 25031, - "##rh": 25032, - "coco": 25033, - "netball": 25034, - "yourselves": 25035, - "##oza": 25036, - "clarify": 25037, - "heller": 25038, - "peg": 25039, - "durban": 25040, - "etudes": 25041, - "offender": 25042, - "roast": 25043, - "blackmail": 25044, - "curvature": 25045, - "##woods": 25046, - "vile": 25047, - "309": 25048, - "illicit": 25049, - "suriname": 25050, - "##linson": 25051, - "overture": 25052, - "1685": 25053, - "bubbling": 25054, - "gymnast": 25055, - "tucking": 25056, - "##mming": 25057, - "##ouin": 25058, - "maldives": 25059, - "##bala": 25060, - "gurney": 25061, - "##dda": 25062, - "##eased": 25063, - "##oides": 25064, - "backside": 25065, - "pinto": 25066, - "jars": 25067, - "racehorse": 25068, - "tending": 25069, - "##rdial": 25070, - "baronetcy": 25071, - "wiener": 25072, - "duly": 25073, - "##rke": 25074, - "barbarian": 25075, - "cupping": 25076, - "flawed": 25077, - "##thesis": 25078, - "bertha": 25079, - "pleistocene": 25080, - "puddle": 25081, - "swearing": 25082, - "##nob": 25083, - "##tically": 25084, - "fleeting": 25085, - "prostate": 25086, - "amulet": 25087, - "educating": 25088, - "##mined": 25089, - "##iti": 25090, - "##tler": 25091, - "75th": 25092, - "jens": 25093, - "respondents": 25094, - "analytics": 25095, - "cavaliers": 25096, - "papacy": 25097, - "raju": 25098, - "##iente": 25099, - "##ulum": 25100, - "##tip": 25101, - "funnel": 25102, - "271": 25103, - "disneyland": 25104, - "##lley": 25105, - "sociologist": 25106, - "##iam": 25107, - "2500": 25108, - "faulkner": 25109, - "louvre": 25110, - "menon": 25111, - "##dson": 25112, - "276": 25113, - "##ower": 25114, - "afterlife": 25115, - "mannheim": 25116, - "peptide": 25117, - "referees": 25118, - "comedians": 25119, - "meaningless": 25120, - "##anger": 25121, - "##laise": 25122, - "fabrics": 25123, - "hurley": 25124, - "renal": 25125, - "sleeps": 25126, - "##bour": 25127, - "##icle": 25128, - "breakout": 25129, - "kristin": 25130, - "roadside": 25131, - "animator": 25132, - "clover": 25133, - "disdain": 25134, - "unsafe": 25135, - "redesign": 25136, - "##urity": 25137, - "firth": 25138, - "barnsley": 25139, - "portage": 25140, - "reset": 25141, - "narrows": 25142, - "268": 25143, - "commandos": 25144, - "expansive": 25145, - "speechless": 25146, - "tubular": 25147, - "##lux": 25148, - "essendon": 25149, - "eyelashes": 25150, - "smashwords": 25151, - "##yad": 25152, - "##bang": 25153, - "##claim": 25154, - "craved": 25155, - "sprinted": 25156, - "chet": 25157, - "somme": 25158, - "astor": 25159, - "wrocław": 25160, - "orton": 25161, - "266": 25162, - "bane": 25163, - "##erving": 25164, - "##uing": 25165, - "mischief": 25166, - "##amps": 25167, - "##sund": 25168, - "scaling": 25169, - "terre": 25170, - "##xious": 25171, - "impairment": 25172, - "offenses": 25173, - "undermine": 25174, - "moi": 25175, - "soy": 25176, - "contiguous": 25177, - "arcadia": 25178, - "inuit": 25179, - "seam": 25180, - "##tops": 25181, - "macbeth": 25182, - "rebelled": 25183, - "##icative": 25184, - "##iot": 25185, - "590": 25186, - "elaborated": 25187, - "frs": 25188, - "uniformed": 25189, - "##dberg": 25190, - "259": 25191, - "powerless": 25192, - "priscilla": 25193, - "stimulated": 25194, - "980": 25195, - "qc": 25196, - "arboretum": 25197, - "frustrating": 25198, - "trieste": 25199, - "bullock": 25200, - "##nified": 25201, - "enriched": 25202, - "glistening": 25203, - "intern": 25204, - "##adia": 25205, - "locus": 25206, - "nouvelle": 25207, - "ollie": 25208, - "ike": 25209, - "lash": 25210, - "starboard": 25211, - "ee": 25212, - "tapestry": 25213, - "headlined": 25214, - "hove": 25215, - "rigged": 25216, - "##vite": 25217, - "pollock": 25218, - "##yme": 25219, - "thrive": 25220, - "clustered": 25221, - "cas": 25222, - "roi": 25223, - "gleamed": 25224, - "olympiad": 25225, - "##lino": 25226, - "pressured": 25227, - "regimes": 25228, - "##hosis": 25229, - "##lick": 25230, - "ripley": 25231, - "##ophone": 25232, - "kickoff": 25233, - "gallon": 25234, - "rockwell": 25235, - "##arable": 25236, - "crusader": 25237, - "glue": 25238, - "revolutions": 25239, - "scrambling": 25240, - "1714": 25241, - "grover": 25242, - "##jure": 25243, - "englishman": 25244, - "aztec": 25245, - "263": 25246, - "contemplating": 25247, - "coven": 25248, - "ipad": 25249, - "preach": 25250, - "triumphant": 25251, - "tufts": 25252, - "##esian": 25253, - "rotational": 25254, - "##phus": 25255, - "328": 25256, - "falkland": 25257, - "##brates": 25258, - "strewn": 25259, - "clarissa": 25260, - "rejoin": 25261, - "environmentally": 25262, - "glint": 25263, - "banded": 25264, - "drenched": 25265, - "moat": 25266, - "albanians": 25267, - "johor": 25268, - "rr": 25269, - "maestro": 25270, - "malley": 25271, - "nouveau": 25272, - "shaded": 25273, - "taxonomy": 25274, - "v6": 25275, - "adhere": 25276, - "bunk": 25277, - "airfields": 25278, - "##ritan": 25279, - "1741": 25280, - "encompass": 25281, - "remington": 25282, - "tran": 25283, - "##erative": 25284, - "amelie": 25285, - "mazda": 25286, - "friar": 25287, - "morals": 25288, - "passions": 25289, - "##zai": 25290, - "breadth": 25291, - "vis": 25292, - "##hae": 25293, - "argus": 25294, - "burnham": 25295, - "caressing": 25296, - "insider": 25297, - "rudd": 25298, - "##imov": 25299, - "##mini": 25300, - "##rso": 25301, - "italianate": 25302, - "murderous": 25303, - "textual": 25304, - "wainwright": 25305, - "armada": 25306, - "bam": 25307, - "weave": 25308, - "timer": 25309, - "##taken": 25310, - "##nh": 25311, - "fra": 25312, - "##crest": 25313, - "ardent": 25314, - "salazar": 25315, - "taps": 25316, - "tunis": 25317, - "##ntino": 25318, - "allegro": 25319, - "gland": 25320, - "philanthropic": 25321, - "##chester": 25322, - "implication": 25323, - "##optera": 25324, - "esq": 25325, - "judas": 25326, - "noticeably": 25327, - "wynn": 25328, - "##dara": 25329, - "inched": 25330, - "indexed": 25331, - "crises": 25332, - "villiers": 25333, - "bandit": 25334, - "royalties": 25335, - "patterned": 25336, - "cupboard": 25337, - "interspersed": 25338, - "accessory": 25339, - "isla": 25340, - "kendrick": 25341, - "entourage": 25342, - "stitches": 25343, - "##esthesia": 25344, - "headwaters": 25345, - "##ior": 25346, - "interlude": 25347, - "distraught": 25348, - "draught": 25349, - "1727": 25350, - "##basket": 25351, - "biased": 25352, - "sy": 25353, - "transient": 25354, - "triad": 25355, - "subgenus": 25356, - "adapting": 25357, - "kidd": 25358, - "shortstop": 25359, - "##umatic": 25360, - "dimly": 25361, - "spiked": 25362, - "mcleod": 25363, - "reprint": 25364, - "nellie": 25365, - "pretoria": 25366, - "windmill": 25367, - "##cek": 25368, - "singled": 25369, - "##mps": 25370, - "273": 25371, - "reunite": 25372, - "##orous": 25373, - "747": 25374, - "bankers": 25375, - "outlying": 25376, - "##omp": 25377, - "##ports": 25378, - "##tream": 25379, - "apologies": 25380, - "cosmetics": 25381, - "patsy": 25382, - "##deh": 25383, - "##ocks": 25384, - "##yson": 25385, - "bender": 25386, - "nantes": 25387, - "serene": 25388, - "##nad": 25389, - "lucha": 25390, - "mmm": 25391, - "323": 25392, - "##cius": 25393, - "##gli": 25394, - "cmll": 25395, - "coinage": 25396, - "nestor": 25397, - "juarez": 25398, - "##rook": 25399, - "smeared": 25400, - "sprayed": 25401, - "twitching": 25402, - "sterile": 25403, - "irina": 25404, - "embodied": 25405, - "juveniles": 25406, - "enveloped": 25407, - "miscellaneous": 25408, - "cancers": 25409, - "dq": 25410, - "gulped": 25411, - "luisa": 25412, - "crested": 25413, - "swat": 25414, - "donegal": 25415, - "ref": 25416, - "##anov": 25417, - "##acker": 25418, - "hearst": 25419, - "mercantile": 25420, - "##lika": 25421, - "doorbell": 25422, - "ua": 25423, - "vicki": 25424, - "##alla": 25425, - "##som": 25426, - "bilbao": 25427, - "psychologists": 25428, - "stryker": 25429, - "sw": 25430, - "horsemen": 25431, - "turkmenistan": 25432, - "wits": 25433, - "##national": 25434, - "anson": 25435, - "mathew": 25436, - "screenings": 25437, - "##umb": 25438, - "rihanna": 25439, - "##agne": 25440, - "##nessy": 25441, - "aisles": 25442, - "##iani": 25443, - "##osphere": 25444, - "hines": 25445, - "kenton": 25446, - "saskatoon": 25447, - "tasha": 25448, - "truncated": 25449, - "##champ": 25450, - "##itan": 25451, - "mildred": 25452, - "advises": 25453, - "fredrik": 25454, - "interpreting": 25455, - "inhibitors": 25456, - "##athi": 25457, - "spectroscopy": 25458, - "##hab": 25459, - "##kong": 25460, - "karim": 25461, - "panda": 25462, - "##oia": 25463, - "##nail": 25464, - "##vc": 25465, - "conqueror": 25466, - "kgb": 25467, - "leukemia": 25468, - "##dity": 25469, - "arrivals": 25470, - "cheered": 25471, - "pisa": 25472, - "phosphorus": 25473, - "shielded": 25474, - "##riated": 25475, - "mammal": 25476, - "unitarian": 25477, - "urgently": 25478, - "chopin": 25479, - "sanitary": 25480, - "##mission": 25481, - "spicy": 25482, - "drugged": 25483, - "hinges": 25484, - "##tort": 25485, - "tipping": 25486, - "trier": 25487, - "impoverished": 25488, - "westchester": 25489, - "##caster": 25490, - "267": 25491, - "epoch": 25492, - "nonstop": 25493, - "##gman": 25494, - "##khov": 25495, - "aromatic": 25496, - "centrally": 25497, - "cerro": 25498, - "##tively": 25499, - "##vio": 25500, - "billions": 25501, - "modulation": 25502, - "sedimentary": 25503, - "283": 25504, - "facilitating": 25505, - "outrageous": 25506, - "goldstein": 25507, - "##eak": 25508, - "##kt": 25509, - "ld": 25510, - "maitland": 25511, - "penultimate": 25512, - "pollard": 25513, - "##dance": 25514, - "fleets": 25515, - "spaceship": 25516, - "vertebrae": 25517, - "##nig": 25518, - "alcoholism": 25519, - "als": 25520, - "recital": 25521, - "##bham": 25522, - "##ference": 25523, - "##omics": 25524, - "m2": 25525, - "##bm": 25526, - "trois": 25527, - "##tropical": 25528, - "##в": 25529, - "commemorates": 25530, - "##meric": 25531, - "marge": 25532, - "##raction": 25533, - "1643": 25534, - "670": 25535, - "cosmetic": 25536, - "ravaged": 25537, - "##ige": 25538, - "catastrophe": 25539, - "eng": 25540, - "##shida": 25541, - "albrecht": 25542, - "arterial": 25543, - "bellamy": 25544, - "decor": 25545, - "harmon": 25546, - "##rde": 25547, - "bulbs": 25548, - "synchronized": 25549, - "vito": 25550, - "easiest": 25551, - "shetland": 25552, - "shielding": 25553, - "wnba": 25554, - "##glers": 25555, - "##ssar": 25556, - "##riam": 25557, - "brianna": 25558, - "cumbria": 25559, - "##aceous": 25560, - "##rard": 25561, - "cores": 25562, - "thayer": 25563, - "##nsk": 25564, - "brood": 25565, - "hilltop": 25566, - "luminous": 25567, - "carts": 25568, - "keynote": 25569, - "larkin": 25570, - "logos": 25571, - "##cta": 25572, - "##ا": 25573, - "##mund": 25574, - "##quay": 25575, - "lilith": 25576, - "tinted": 25577, - "277": 25578, - "wrestle": 25579, - "mobilization": 25580, - "##uses": 25581, - "sequential": 25582, - "siam": 25583, - "bloomfield": 25584, - "takahashi": 25585, - "274": 25586, - "##ieving": 25587, - "presenters": 25588, - "ringo": 25589, - "blazed": 25590, - "witty": 25591, - "##oven": 25592, - "##ignant": 25593, - "devastation": 25594, - "haydn": 25595, - "harmed": 25596, - "newt": 25597, - "therese": 25598, - "##peed": 25599, - "gershwin": 25600, - "molina": 25601, - "rabbis": 25602, - "sudanese": 25603, - "001": 25604, - "innate": 25605, - "restarted": 25606, - "##sack": 25607, - "##fus": 25608, - "slices": 25609, - "wb": 25610, - "##shah": 25611, - "enroll": 25612, - "hypothetical": 25613, - "hysterical": 25614, - "1743": 25615, - "fabio": 25616, - "indefinite": 25617, - "warped": 25618, - "##hg": 25619, - "exchanging": 25620, - "525": 25621, - "unsuitable": 25622, - "##sboro": 25623, - "gallo": 25624, - "1603": 25625, - "bret": 25626, - "cobalt": 25627, - "homemade": 25628, - "##hunter": 25629, - "mx": 25630, - "operatives": 25631, - "##dhar": 25632, - "terraces": 25633, - "durable": 25634, - "latch": 25635, - "pens": 25636, - "whorls": 25637, - "##ctuated": 25638, - "##eaux": 25639, - "billing": 25640, - "ligament": 25641, - "succumbed": 25642, - "##gly": 25643, - "regulators": 25644, - "spawn": 25645, - "##brick": 25646, - "##stead": 25647, - "filmfare": 25648, - "rochelle": 25649, - "##nzo": 25650, - "1725": 25651, - "circumstance": 25652, - "saber": 25653, - "supplements": 25654, - "##nsky": 25655, - "##tson": 25656, - "crowe": 25657, - "wellesley": 25658, - "carrot": 25659, - "##9th": 25660, - "##movable": 25661, - "primate": 25662, - "drury": 25663, - "sincerely": 25664, - "topical": 25665, - "##mad": 25666, - "##rao": 25667, - "callahan": 25668, - "kyiv": 25669, - "smarter": 25670, - "tits": 25671, - "undo": 25672, - "##yeh": 25673, - "announcements": 25674, - "anthologies": 25675, - "barrio": 25676, - "nebula": 25677, - "##islaus": 25678, - "##shaft": 25679, - "##tyn": 25680, - "bodyguards": 25681, - "2021": 25682, - "assassinate": 25683, - "barns": 25684, - "emmett": 25685, - "scully": 25686, - "##mah": 25687, - "##yd": 25688, - "##eland": 25689, - "##tino": 25690, - "##itarian": 25691, - "demoted": 25692, - "gorman": 25693, - "lashed": 25694, - "prized": 25695, - "adventist": 25696, - "writ": 25697, - "##gui": 25698, - "alla": 25699, - "invertebrates": 25700, - "##ausen": 25701, - "1641": 25702, - "amman": 25703, - "1742": 25704, - "align": 25705, - "healy": 25706, - "redistribution": 25707, - "##gf": 25708, - "##rize": 25709, - "insulation": 25710, - "##drop": 25711, - "adherents": 25712, - "hezbollah": 25713, - "vitro": 25714, - "ferns": 25715, - "yanking": 25716, - "269": 25717, - "php": 25718, - "registering": 25719, - "uppsala": 25720, - "cheerleading": 25721, - "confines": 25722, - "mischievous": 25723, - "tully": 25724, - "##ross": 25725, - "49th": 25726, - "docked": 25727, - "roam": 25728, - "stipulated": 25729, - "pumpkin": 25730, - "##bry": 25731, - "prompt": 25732, - "##ezer": 25733, - "blindly": 25734, - "shuddering": 25735, - "craftsmen": 25736, - "frail": 25737, - "scented": 25738, - "katharine": 25739, - "scramble": 25740, - "shaggy": 25741, - "sponge": 25742, - "helix": 25743, - "zaragoza": 25744, - "279": 25745, - "##52": 25746, - "43rd": 25747, - "backlash": 25748, - "fontaine": 25749, - "seizures": 25750, - "posse": 25751, - "cowan": 25752, - "nonfiction": 25753, - "telenovela": 25754, - "wwii": 25755, - "hammered": 25756, - "undone": 25757, - "##gpur": 25758, - "encircled": 25759, - "irs": 25760, - "##ivation": 25761, - "artefacts": 25762, - "oneself": 25763, - "searing": 25764, - "smallpox": 25765, - "##belle": 25766, - "##osaurus": 25767, - "shandong": 25768, - "breached": 25769, - "upland": 25770, - "blushing": 25771, - "rankin": 25772, - "infinitely": 25773, - "psyche": 25774, - "tolerated": 25775, - "docking": 25776, - "evicted": 25777, - "##col": 25778, - "unmarked": 25779, - "##lving": 25780, - "gnome": 25781, - "lettering": 25782, - "litres": 25783, - "musique": 25784, - "##oint": 25785, - "benevolent": 25786, - "##jal": 25787, - "blackened": 25788, - "##anna": 25789, - "mccall": 25790, - "racers": 25791, - "tingle": 25792, - "##ocene": 25793, - "##orestation": 25794, - "introductions": 25795, - "radically": 25796, - "292": 25797, - "##hiff": 25798, - "##باد": 25799, - "1610": 25800, - "1739": 25801, - "munchen": 25802, - "plead": 25803, - "##nka": 25804, - "condo": 25805, - "scissors": 25806, - "##sight": 25807, - "##tens": 25808, - "apprehension": 25809, - "##cey": 25810, - "##yin": 25811, - "hallmark": 25812, - "watering": 25813, - "formulas": 25814, - "sequels": 25815, - "##llas": 25816, - "aggravated": 25817, - "bae": 25818, - "commencing": 25819, - "##building": 25820, - "enfield": 25821, - "prohibits": 25822, - "marne": 25823, - "vedic": 25824, - "civilized": 25825, - "euclidean": 25826, - "jagger": 25827, - "beforehand": 25828, - "blasts": 25829, - "dumont": 25830, - "##arney": 25831, - "##nem": 25832, - "740": 25833, - "conversions": 25834, - "hierarchical": 25835, - "rios": 25836, - "simulator": 25837, - "##dya": 25838, - "##lellan": 25839, - "hedges": 25840, - "oleg": 25841, - "thrusts": 25842, - "shadowed": 25843, - "darby": 25844, - "maximize": 25845, - "1744": 25846, - "gregorian": 25847, - "##nded": 25848, - "##routed": 25849, - "sham": 25850, - "unspecified": 25851, - "##hog": 25852, - "emory": 25853, - "factual": 25854, - "##smo": 25855, - "##tp": 25856, - "fooled": 25857, - "##rger": 25858, - "ortega": 25859, - "wellness": 25860, - "marlon": 25861, - "##oton": 25862, - "##urance": 25863, - "casket": 25864, - "keating": 25865, - "ley": 25866, - "enclave": 25867, - "##ayan": 25868, - "char": 25869, - "influencing": 25870, - "jia": 25871, - "##chenko": 25872, - "412": 25873, - "ammonia": 25874, - "erebidae": 25875, - "incompatible": 25876, - "violins": 25877, - "cornered": 25878, - "##arat": 25879, - "grooves": 25880, - "astronauts": 25881, - "columbian": 25882, - "rampant": 25883, - "fabrication": 25884, - "kyushu": 25885, - "mahmud": 25886, - "vanish": 25887, - "##dern": 25888, - "mesopotamia": 25889, - "##lete": 25890, - "ict": 25891, - "##rgen": 25892, - "caspian": 25893, - "kenji": 25894, - "pitted": 25895, - "##vered": 25896, - "999": 25897, - "grimace": 25898, - "roanoke": 25899, - "tchaikovsky": 25900, - "twinned": 25901, - "##analysis": 25902, - "##awan": 25903, - "xinjiang": 25904, - "arias": 25905, - "clemson": 25906, - "kazakh": 25907, - "sizable": 25908, - "1662": 25909, - "##khand": 25910, - "##vard": 25911, - "plunge": 25912, - "tatum": 25913, - "vittorio": 25914, - "##nden": 25915, - "cholera": 25916, - "##dana": 25917, - "##oper": 25918, - "bracing": 25919, - "indifference": 25920, - "projectile": 25921, - "superliga": 25922, - "##chee": 25923, - "realises": 25924, - "upgrading": 25925, - "299": 25926, - "porte": 25927, - "retribution": 25928, - "##vies": 25929, - "nk": 25930, - "stil": 25931, - "##resses": 25932, - "ama": 25933, - "bureaucracy": 25934, - "blackberry": 25935, - "bosch": 25936, - "testosterone": 25937, - "collapses": 25938, - "greer": 25939, - "##pathic": 25940, - "ioc": 25941, - "fifties": 25942, - "malls": 25943, - "##erved": 25944, - "bao": 25945, - "baskets": 25946, - "adolescents": 25947, - "siegfried": 25948, - "##osity": 25949, - "##tosis": 25950, - "mantra": 25951, - "detecting": 25952, - "existent": 25953, - "fledgling": 25954, - "##cchi": 25955, - "dissatisfied": 25956, - "gan": 25957, - "telecommunication": 25958, - "mingled": 25959, - "sobbed": 25960, - "6000": 25961, - "controversies": 25962, - "outdated": 25963, - "taxis": 25964, - "##raus": 25965, - "fright": 25966, - "slams": 25967, - "##lham": 25968, - "##fect": 25969, - "##tten": 25970, - "detectors": 25971, - "fetal": 25972, - "tanned": 25973, - "##uw": 25974, - "fray": 25975, - "goth": 25976, - "olympian": 25977, - "skipping": 25978, - "mandates": 25979, - "scratches": 25980, - "sheng": 25981, - "unspoken": 25982, - "hyundai": 25983, - "tracey": 25984, - "hotspur": 25985, - "restrictive": 25986, - "##buch": 25987, - "americana": 25988, - "mundo": 25989, - "##bari": 25990, - "burroughs": 25991, - "diva": 25992, - "vulcan": 25993, - "##6th": 25994, - "distinctions": 25995, - "thumping": 25996, - "##ngen": 25997, - "mikey": 25998, - "sheds": 25999, - "fide": 26000, - "rescues": 26001, - "springsteen": 26002, - "vested": 26003, - "valuation": 26004, - "##ece": 26005, - "##ely": 26006, - "pinnacle": 26007, - "rake": 26008, - "sylvie": 26009, - "##edo": 26010, - "almond": 26011, - "quivering": 26012, - "##irus": 26013, - "alteration": 26014, - "faltered": 26015, - "##wad": 26016, - "51st": 26017, - "hydra": 26018, - "ticked": 26019, - "##kato": 26020, - "recommends": 26021, - "##dicated": 26022, - "antigua": 26023, - "arjun": 26024, - "stagecoach": 26025, - "wilfred": 26026, - "trickle": 26027, - "pronouns": 26028, - "##pon": 26029, - "aryan": 26030, - "nighttime": 26031, - "##anian": 26032, - "gall": 26033, - "pea": 26034, - "stitch": 26035, - "##hei": 26036, - "leung": 26037, - "milos": 26038, - "##dini": 26039, - "eritrea": 26040, - "nexus": 26041, - "starved": 26042, - "snowfall": 26043, - "kant": 26044, - "parasitic": 26045, - "cot": 26046, - "discus": 26047, - "hana": 26048, - "strikers": 26049, - "appleton": 26050, - "kitchens": 26051, - "##erina": 26052, - "##partisan": 26053, - "##itha": 26054, - "##vius": 26055, - "disclose": 26056, - "metis": 26057, - "##channel": 26058, - "1701": 26059, - "tesla": 26060, - "##vera": 26061, - "fitch": 26062, - "1735": 26063, - "blooded": 26064, - "##tila": 26065, - "decimal": 26066, - "##tang": 26067, - "##bai": 26068, - "cyclones": 26069, - "eun": 26070, - "bottled": 26071, - "peas": 26072, - "pensacola": 26073, - "basha": 26074, - "bolivian": 26075, - "crabs": 26076, - "boil": 26077, - "lanterns": 26078, - "partridge": 26079, - "roofed": 26080, - "1645": 26081, - "necks": 26082, - "##phila": 26083, - "opined": 26084, - "patting": 26085, - "##kla": 26086, - "##lland": 26087, - "chuckles": 26088, - "volta": 26089, - "whereupon": 26090, - "##nche": 26091, - "devout": 26092, - "euroleague": 26093, - "suicidal": 26094, - "##dee": 26095, - "inherently": 26096, - "involuntary": 26097, - "knitting": 26098, - "nasser": 26099, - "##hide": 26100, - "puppets": 26101, - "colourful": 26102, - "courageous": 26103, - "southend": 26104, - "stills": 26105, - "miraculous": 26106, - "hodgson": 26107, - "richer": 26108, - "rochdale": 26109, - "ethernet": 26110, - "greta": 26111, - "uniting": 26112, - "prism": 26113, - "umm": 26114, - "##haya": 26115, - "##itical": 26116, - "##utation": 26117, - "deterioration": 26118, - "pointe": 26119, - "prowess": 26120, - "##ropriation": 26121, - "lids": 26122, - "scranton": 26123, - "billings": 26124, - "subcontinent": 26125, - "##koff": 26126, - "##scope": 26127, - "brute": 26128, - "kellogg": 26129, - "psalms": 26130, - "degraded": 26131, - "##vez": 26132, - "stanisław": 26133, - "##ructured": 26134, - "ferreira": 26135, - "pun": 26136, - "astonishing": 26137, - "gunnar": 26138, - "##yat": 26139, - "arya": 26140, - "prc": 26141, - "gottfried": 26142, - "##tight": 26143, - "excursion": 26144, - "##ographer": 26145, - "dina": 26146, - "##quil": 26147, - "##nare": 26148, - "huffington": 26149, - "illustrious": 26150, - "wilbur": 26151, - "gundam": 26152, - "verandah": 26153, - "##zard": 26154, - "naacp": 26155, - "##odle": 26156, - "constructive": 26157, - "fjord": 26158, - "kade": 26159, - "##naud": 26160, - "generosity": 26161, - "thrilling": 26162, - "baseline": 26163, - "cayman": 26164, - "frankish": 26165, - "plastics": 26166, - "accommodations": 26167, - "zoological": 26168, - "##fting": 26169, - "cedric": 26170, - "qb": 26171, - "motorized": 26172, - "##dome": 26173, - "##otted": 26174, - "squealed": 26175, - "tackled": 26176, - "canucks": 26177, - "budgets": 26178, - "situ": 26179, - "asthma": 26180, - "dail": 26181, - "gabled": 26182, - "grasslands": 26183, - "whimpered": 26184, - "writhing": 26185, - "judgments": 26186, - "##65": 26187, - "minnie": 26188, - "pv": 26189, - "##carbon": 26190, - "bananas": 26191, - "grille": 26192, - "domes": 26193, - "monique": 26194, - "odin": 26195, - "maguire": 26196, - "markham": 26197, - "tierney": 26198, - "##estra": 26199, - "##chua": 26200, - "libel": 26201, - "poke": 26202, - "speedy": 26203, - "atrium": 26204, - "laval": 26205, - "notwithstanding": 26206, - "##edly": 26207, - "fai": 26208, - "kala": 26209, - "##sur": 26210, - "robb": 26211, - "##sma": 26212, - "listings": 26213, - "luz": 26214, - "supplementary": 26215, - "tianjin": 26216, - "##acing": 26217, - "enzo": 26218, - "jd": 26219, - "ric": 26220, - "scanner": 26221, - "croats": 26222, - "transcribed": 26223, - "##49": 26224, - "arden": 26225, - "cv": 26226, - "##hair": 26227, - "##raphy": 26228, - "##lver": 26229, - "##uy": 26230, - "357": 26231, - "seventies": 26232, - "staggering": 26233, - "alam": 26234, - "horticultural": 26235, - "hs": 26236, - "regression": 26237, - "timbers": 26238, - "blasting": 26239, - "##ounded": 26240, - "montagu": 26241, - "manipulating": 26242, - "##cit": 26243, - "catalytic": 26244, - "1550": 26245, - "troopers": 26246, - "##meo": 26247, - "condemnation": 26248, - "fitzpatrick": 26249, - "##oire": 26250, - "##roved": 26251, - "inexperienced": 26252, - "1670": 26253, - "castes": 26254, - "##lative": 26255, - "outing": 26256, - "314": 26257, - "dubois": 26258, - "flicking": 26259, - "quarrel": 26260, - "ste": 26261, - "learners": 26262, - "1625": 26263, - "iq": 26264, - "whistled": 26265, - "##class": 26266, - "282": 26267, - "classify": 26268, - "tariffs": 26269, - "temperament": 26270, - "355": 26271, - "folly": 26272, - "liszt": 26273, - "##yles": 26274, - "immersed": 26275, - "jordanian": 26276, - "ceasefire": 26277, - "apparel": 26278, - "extras": 26279, - "maru": 26280, - "fished": 26281, - "##bio": 26282, - "harta": 26283, - "stockport": 26284, - "assortment": 26285, - "craftsman": 26286, - "paralysis": 26287, - "transmitters": 26288, - "##cola": 26289, - "blindness": 26290, - "##wk": 26291, - "fatally": 26292, - "proficiency": 26293, - "solemnly": 26294, - "##orno": 26295, - "repairing": 26296, - "amore": 26297, - "groceries": 26298, - "ultraviolet": 26299, - "##chase": 26300, - "schoolhouse": 26301, - "##tua": 26302, - "resurgence": 26303, - "nailed": 26304, - "##otype": 26305, - "##×": 26306, - "ruse": 26307, - "saliva": 26308, - "diagrams": 26309, - "##tructing": 26310, - "albans": 26311, - "rann": 26312, - "thirties": 26313, - "1b": 26314, - "antennas": 26315, - "hilarious": 26316, - "cougars": 26317, - "paddington": 26318, - "stats": 26319, - "##eger": 26320, - "breakaway": 26321, - "ipod": 26322, - "reza": 26323, - "authorship": 26324, - "prohibiting": 26325, - "scoffed": 26326, - "##etz": 26327, - "##ttle": 26328, - "conscription": 26329, - "defected": 26330, - "trondheim": 26331, - "##fires": 26332, - "ivanov": 26333, - "keenan": 26334, - "##adan": 26335, - "##ciful": 26336, - "##fb": 26337, - "##slow": 26338, - "locating": 26339, - "##ials": 26340, - "##tford": 26341, - "cadiz": 26342, - "basalt": 26343, - "blankly": 26344, - "interned": 26345, - "rags": 26346, - "rattling": 26347, - "##tick": 26348, - "carpathian": 26349, - "reassured": 26350, - "sync": 26351, - "bum": 26352, - "guildford": 26353, - "iss": 26354, - "staunch": 26355, - "##onga": 26356, - "astronomers": 26357, - "sera": 26358, - "sofie": 26359, - "emergencies": 26360, - "susquehanna": 26361, - "##heard": 26362, - "duc": 26363, - "mastery": 26364, - "vh1": 26365, - "williamsburg": 26366, - "bayer": 26367, - "buckled": 26368, - "craving": 26369, - "##khan": 26370, - "##rdes": 26371, - "bloomington": 26372, - "##write": 26373, - "alton": 26374, - "barbecue": 26375, - "##bians": 26376, - "justine": 26377, - "##hri": 26378, - "##ndt": 26379, - "delightful": 26380, - "smartphone": 26381, - "newtown": 26382, - "photon": 26383, - "retrieval": 26384, - "peugeot": 26385, - "hissing": 26386, - "##monium": 26387, - "##orough": 26388, - "flavors": 26389, - "lighted": 26390, - "relaunched": 26391, - "tainted": 26392, - "##games": 26393, - "##lysis": 26394, - "anarchy": 26395, - "microscopic": 26396, - "hopping": 26397, - "adept": 26398, - "evade": 26399, - "evie": 26400, - "##beau": 26401, - "inhibit": 26402, - "sinn": 26403, - "adjustable": 26404, - "hurst": 26405, - "intuition": 26406, - "wilton": 26407, - "cisco": 26408, - "44th": 26409, - "lawful": 26410, - "lowlands": 26411, - "stockings": 26412, - "thierry": 26413, - "##dalen": 26414, - "##hila": 26415, - "##nai": 26416, - "fates": 26417, - "prank": 26418, - "tb": 26419, - "maison": 26420, - "lobbied": 26421, - "provocative": 26422, - "1724": 26423, - "4a": 26424, - "utopia": 26425, - "##qual": 26426, - "carbonate": 26427, - "gujarati": 26428, - "purcell": 26429, - "##rford": 26430, - "curtiss": 26431, - "##mei": 26432, - "overgrown": 26433, - "arenas": 26434, - "mediation": 26435, - "swallows": 26436, - "##rnik": 26437, - "respectful": 26438, - "turnbull": 26439, - "##hedron": 26440, - "##hope": 26441, - "alyssa": 26442, - "ozone": 26443, - "##ʻi": 26444, - "ami": 26445, - "gestapo": 26446, - "johansson": 26447, - "snooker": 26448, - "canteen": 26449, - "cuff": 26450, - "declines": 26451, - "empathy": 26452, - "stigma": 26453, - "##ags": 26454, - "##iner": 26455, - "##raine": 26456, - "taxpayers": 26457, - "gui": 26458, - "volga": 26459, - "##wright": 26460, - "##copic": 26461, - "lifespan": 26462, - "overcame": 26463, - "tattooed": 26464, - "enactment": 26465, - "giggles": 26466, - "##ador": 26467, - "##camp": 26468, - "barrington": 26469, - "bribe": 26470, - "obligatory": 26471, - "orbiting": 26472, - "peng": 26473, - "##enas": 26474, - "elusive": 26475, - "sucker": 26476, - "##vating": 26477, - "cong": 26478, - "hardship": 26479, - "empowered": 26480, - "anticipating": 26481, - "estrada": 26482, - "cryptic": 26483, - "greasy": 26484, - "detainees": 26485, - "planck": 26486, - "sudbury": 26487, - "plaid": 26488, - "dod": 26489, - "marriott": 26490, - "kayla": 26491, - "##ears": 26492, - "##vb": 26493, - "##zd": 26494, - "mortally": 26495, - "##hein": 26496, - "cognition": 26497, - "radha": 26498, - "319": 26499, - "liechtenstein": 26500, - "meade": 26501, - "richly": 26502, - "argyle": 26503, - "harpsichord": 26504, - "liberalism": 26505, - "trumpets": 26506, - "lauded": 26507, - "tyrant": 26508, - "salsa": 26509, - "tiled": 26510, - "lear": 26511, - "promoters": 26512, - "reused": 26513, - "slicing": 26514, - "trident": 26515, - "##chuk": 26516, - "##gami": 26517, - "##lka": 26518, - "cantor": 26519, - "checkpoint": 26520, - "##points": 26521, - "gaul": 26522, - "leger": 26523, - "mammalian": 26524, - "##tov": 26525, - "##aar": 26526, - "##schaft": 26527, - "doha": 26528, - "frenchman": 26529, - "nirvana": 26530, - "##vino": 26531, - "delgado": 26532, - "headlining": 26533, - "##eron": 26534, - "##iography": 26535, - "jug": 26536, - "tko": 26537, - "1649": 26538, - "naga": 26539, - "intersections": 26540, - "##jia": 26541, - "benfica": 26542, - "nawab": 26543, - "##suka": 26544, - "ashford": 26545, - "gulp": 26546, - "##deck": 26547, - "##vill": 26548, - "##rug": 26549, - "brentford": 26550, - "frazier": 26551, - "pleasures": 26552, - "dunne": 26553, - "potsdam": 26554, - "shenzhen": 26555, - "dentistry": 26556, - "##tec": 26557, - "flanagan": 26558, - "##dorff": 26559, - "##hear": 26560, - "chorale": 26561, - "dinah": 26562, - "prem": 26563, - "quezon": 26564, - "##rogated": 26565, - "relinquished": 26566, - "sutra": 26567, - "terri": 26568, - "##pani": 26569, - "flaps": 26570, - "##rissa": 26571, - "poly": 26572, - "##rnet": 26573, - "homme": 26574, - "aback": 26575, - "##eki": 26576, - "linger": 26577, - "womb": 26578, - "##kson": 26579, - "##lewood": 26580, - "doorstep": 26581, - "orthodoxy": 26582, - "threaded": 26583, - "westfield": 26584, - "##rval": 26585, - "dioceses": 26586, - "fridays": 26587, - "subsided": 26588, - "##gata": 26589, - "loyalists": 26590, - "##biotic": 26591, - "##ettes": 26592, - "letterman": 26593, - "lunatic": 26594, - "prelate": 26595, - "tenderly": 26596, - "invariably": 26597, - "souza": 26598, - "thug": 26599, - "winslow": 26600, - "##otide": 26601, - "furlongs": 26602, - "gogh": 26603, - "jeopardy": 26604, - "##runa": 26605, - "pegasus": 26606, - "##umble": 26607, - "humiliated": 26608, - "standalone": 26609, - "tagged": 26610, - "##roller": 26611, - "freshmen": 26612, - "klan": 26613, - "##bright": 26614, - "attaining": 26615, - "initiating": 26616, - "transatlantic": 26617, - "logged": 26618, - "viz": 26619, - "##uance": 26620, - "1723": 26621, - "combatants": 26622, - "intervening": 26623, - "stephane": 26624, - "chieftain": 26625, - "despised": 26626, - "grazed": 26627, - "317": 26628, - "cdc": 26629, - "galveston": 26630, - "godzilla": 26631, - "macro": 26632, - "simulate": 26633, - "##planes": 26634, - "parades": 26635, - "##esses": 26636, - "960": 26637, - "##ductive": 26638, - "##unes": 26639, - "equator": 26640, - "overdose": 26641, - "##cans": 26642, - "##hosh": 26643, - "##lifting": 26644, - "joshi": 26645, - "epstein": 26646, - "sonora": 26647, - "treacherous": 26648, - "aquatics": 26649, - "manchu": 26650, - "responsive": 26651, - "##sation": 26652, - "supervisory": 26653, - "##christ": 26654, - "##llins": 26655, - "##ibar": 26656, - "##balance": 26657, - "##uso": 26658, - "kimball": 26659, - "karlsruhe": 26660, - "mab": 26661, - "##emy": 26662, - "ignores": 26663, - "phonetic": 26664, - "reuters": 26665, - "spaghetti": 26666, - "820": 26667, - "almighty": 26668, - "danzig": 26669, - "rumbling": 26670, - "tombstone": 26671, - "designations": 26672, - "lured": 26673, - "outset": 26674, - "##felt": 26675, - "supermarkets": 26676, - "##wt": 26677, - "grupo": 26678, - "kei": 26679, - "kraft": 26680, - "susanna": 26681, - "##blood": 26682, - "comprehension": 26683, - "genealogy": 26684, - "##aghan": 26685, - "##verted": 26686, - "redding": 26687, - "##ythe": 26688, - "1722": 26689, - "bowing": 26690, - "##pore": 26691, - "##roi": 26692, - "lest": 26693, - "sharpened": 26694, - "fulbright": 26695, - "valkyrie": 26696, - "sikhs": 26697, - "##unds": 26698, - "swans": 26699, - "bouquet": 26700, - "merritt": 26701, - "##tage": 26702, - "##venting": 26703, - "commuted": 26704, - "redhead": 26705, - "clerks": 26706, - "leasing": 26707, - "cesare": 26708, - "dea": 26709, - "hazy": 26710, - "##vances": 26711, - "fledged": 26712, - "greenfield": 26713, - "servicemen": 26714, - "##gical": 26715, - "armando": 26716, - "blackout": 26717, - "dt": 26718, - "sagged": 26719, - "downloadable": 26720, - "intra": 26721, - "potion": 26722, - "pods": 26723, - "##4th": 26724, - "##mism": 26725, - "xp": 26726, - "attendants": 26727, - "gambia": 26728, - "stale": 26729, - "##ntine": 26730, - "plump": 26731, - "asteroids": 26732, - "rediscovered": 26733, - "buds": 26734, - "flea": 26735, - "hive": 26736, - "##neas": 26737, - "1737": 26738, - "classifications": 26739, - "debuts": 26740, - "##eles": 26741, - "olympus": 26742, - "scala": 26743, - "##eurs": 26744, - "##gno": 26745, - "##mute": 26746, - "hummed": 26747, - "sigismund": 26748, - "visuals": 26749, - "wiggled": 26750, - "await": 26751, - "pilasters": 26752, - "clench": 26753, - "sulfate": 26754, - "##ances": 26755, - "bellevue": 26756, - "enigma": 26757, - "trainee": 26758, - "snort": 26759, - "##sw": 26760, - "clouded": 26761, - "denim": 26762, - "##rank": 26763, - "##rder": 26764, - "churning": 26765, - "hartman": 26766, - "lodges": 26767, - "riches": 26768, - "sima": 26769, - "##missible": 26770, - "accountable": 26771, - "socrates": 26772, - "regulates": 26773, - "mueller": 26774, - "##cr": 26775, - "1702": 26776, - "avoids": 26777, - "solids": 26778, - "himalayas": 26779, - "nutrient": 26780, - "pup": 26781, - "##jevic": 26782, - "squat": 26783, - "fades": 26784, - "nec": 26785, - "##lates": 26786, - "##pina": 26787, - "##rona": 26788, - "##ου": 26789, - "privateer": 26790, - "tequila": 26791, - "##gative": 26792, - "##mpton": 26793, - "apt": 26794, - "hornet": 26795, - "immortals": 26796, - "##dou": 26797, - "asturias": 26798, - "cleansing": 26799, - "dario": 26800, - "##rries": 26801, - "##anta": 26802, - "etymology": 26803, - "servicing": 26804, - "zhejiang": 26805, - "##venor": 26806, - "##nx": 26807, - "horned": 26808, - "erasmus": 26809, - "rayon": 26810, - "relocating": 26811, - "£10": 26812, - "##bags": 26813, - "escalated": 26814, - "promenade": 26815, - "stubble": 26816, - "2010s": 26817, - "artisans": 26818, - "axial": 26819, - "liquids": 26820, - "mora": 26821, - "sho": 26822, - "yoo": 26823, - "##tsky": 26824, - "bundles": 26825, - "oldies": 26826, - "##nally": 26827, - "notification": 26828, - "bastion": 26829, - "##ths": 26830, - "sparkle": 26831, - "##lved": 26832, - "1728": 26833, - "leash": 26834, - "pathogen": 26835, - "highs": 26836, - "##hmi": 26837, - "immature": 26838, - "880": 26839, - "gonzaga": 26840, - "ignatius": 26841, - "mansions": 26842, - "monterrey": 26843, - "sweets": 26844, - "bryson": 26845, - "##loe": 26846, - "polled": 26847, - "regatta": 26848, - "brightest": 26849, - "pei": 26850, - "rosy": 26851, - "squid": 26852, - "hatfield": 26853, - "payroll": 26854, - "addict": 26855, - "meath": 26856, - "cornerback": 26857, - "heaviest": 26858, - "lodging": 26859, - "##mage": 26860, - "capcom": 26861, - "rippled": 26862, - "##sily": 26863, - "barnet": 26864, - "mayhem": 26865, - "ymca": 26866, - "snuggled": 26867, - "rousseau": 26868, - "##cute": 26869, - "blanchard": 26870, - "284": 26871, - "fragmented": 26872, - "leighton": 26873, - "chromosomes": 26874, - "risking": 26875, - "##md": 26876, - "##strel": 26877, - "##utter": 26878, - "corinne": 26879, - "coyotes": 26880, - "cynical": 26881, - "hiroshi": 26882, - "yeomanry": 26883, - "##ractive": 26884, - "ebook": 26885, - "grading": 26886, - "mandela": 26887, - "plume": 26888, - "agustin": 26889, - "magdalene": 26890, - "##rkin": 26891, - "bea": 26892, - "femme": 26893, - "trafford": 26894, - "##coll": 26895, - "##lun": 26896, - "##tance": 26897, - "52nd": 26898, - "fourier": 26899, - "upton": 26900, - "##mental": 26901, - "camilla": 26902, - "gust": 26903, - "iihf": 26904, - "islamabad": 26905, - "longevity": 26906, - "##kala": 26907, - "feldman": 26908, - "netting": 26909, - "##rization": 26910, - "endeavour": 26911, - "foraging": 26912, - "mfa": 26913, - "orr": 26914, - "##open": 26915, - "greyish": 26916, - "contradiction": 26917, - "graz": 26918, - "##ruff": 26919, - "handicapped": 26920, - "marlene": 26921, - "tweed": 26922, - "oaxaca": 26923, - "spp": 26924, - "campos": 26925, - "miocene": 26926, - "pri": 26927, - "configured": 26928, - "cooks": 26929, - "pluto": 26930, - "cozy": 26931, - "pornographic": 26932, - "##entes": 26933, - "70th": 26934, - "fairness": 26935, - "glided": 26936, - "jonny": 26937, - "lynne": 26938, - "rounding": 26939, - "sired": 26940, - "##emon": 26941, - "##nist": 26942, - "remade": 26943, - "uncover": 26944, - "##mack": 26945, - "complied": 26946, - "lei": 26947, - "newsweek": 26948, - "##jured": 26949, - "##parts": 26950, - "##enting": 26951, - "##pg": 26952, - "293": 26953, - "finer": 26954, - "guerrillas": 26955, - "athenian": 26956, - "deng": 26957, - "disused": 26958, - "stepmother": 26959, - "accuse": 26960, - "gingerly": 26961, - "seduction": 26962, - "521": 26963, - "confronting": 26964, - "##walker": 26965, - "##going": 26966, - "gora": 26967, - "nostalgia": 26968, - "sabres": 26969, - "virginity": 26970, - "wrenched": 26971, - "##minated": 26972, - "syndication": 26973, - "wielding": 26974, - "eyre": 26975, - "##56": 26976, - "##gnon": 26977, - "##igny": 26978, - "behaved": 26979, - "taxpayer": 26980, - "sweeps": 26981, - "##growth": 26982, - "childless": 26983, - "gallant": 26984, - "##ywood": 26985, - "amplified": 26986, - "geraldine": 26987, - "scrape": 26988, - "##ffi": 26989, - "babylonian": 26990, - "fresco": 26991, - "##rdan": 26992, - "##kney": 26993, - "##position": 26994, - "1718": 26995, - "restricting": 26996, - "tack": 26997, - "fukuoka": 26998, - "osborn": 26999, - "selector": 27000, - "partnering": 27001, - "##dlow": 27002, - "318": 27003, - "gnu": 27004, - "kia": 27005, - "tak": 27006, - "whitley": 27007, - "gables": 27008, - "##54": 27009, - "##mania": 27010, - "mri": 27011, - "softness": 27012, - "immersion": 27013, - "##bots": 27014, - "##evsky": 27015, - "1713": 27016, - "chilling": 27017, - "insignificant": 27018, - "pcs": 27019, - "##uis": 27020, - "elites": 27021, - "lina": 27022, - "purported": 27023, - "supplemental": 27024, - "teaming": 27025, - "##americana": 27026, - "##dding": 27027, - "##inton": 27028, - "proficient": 27029, - "rouen": 27030, - "##nage": 27031, - "##rret": 27032, - "niccolo": 27033, - "selects": 27034, - "##bread": 27035, - "fluffy": 27036, - "1621": 27037, - "gruff": 27038, - "knotted": 27039, - "mukherjee": 27040, - "polgara": 27041, - "thrash": 27042, - "nicholls": 27043, - "secluded": 27044, - "smoothing": 27045, - "thru": 27046, - "corsica": 27047, - "loaf": 27048, - "whitaker": 27049, - "inquiries": 27050, - "##rrier": 27051, - "##kam": 27052, - "indochina": 27053, - "289": 27054, - "marlins": 27055, - "myles": 27056, - "peking": 27057, - "##tea": 27058, - "extracts": 27059, - "pastry": 27060, - "superhuman": 27061, - "connacht": 27062, - "vogel": 27063, - "##ditional": 27064, - "##het": 27065, - "##udged": 27066, - "##lash": 27067, - "gloss": 27068, - "quarries": 27069, - "refit": 27070, - "teaser": 27071, - "##alic": 27072, - "##gaon": 27073, - "20s": 27074, - "materialized": 27075, - "sling": 27076, - "camped": 27077, - "pickering": 27078, - "tung": 27079, - "tracker": 27080, - "pursuant": 27081, - "##cide": 27082, - "cranes": 27083, - "soc": 27084, - "##cini": 27085, - "##typical": 27086, - "##viere": 27087, - "anhalt": 27088, - "overboard": 27089, - "workout": 27090, - "chores": 27091, - "fares": 27092, - "orphaned": 27093, - "stains": 27094, - "##logie": 27095, - "fenton": 27096, - "surpassing": 27097, - "joyah": 27098, - "triggers": 27099, - "##itte": 27100, - "grandmaster": 27101, - "##lass": 27102, - "##lists": 27103, - "clapping": 27104, - "fraudulent": 27105, - "ledger": 27106, - "nagasaki": 27107, - "##cor": 27108, - "##nosis": 27109, - "##tsa": 27110, - "eucalyptus": 27111, - "tun": 27112, - "##icio": 27113, - "##rney": 27114, - "##tara": 27115, - "dax": 27116, - "heroism": 27117, - "ina": 27118, - "wrexham": 27119, - "onboard": 27120, - "unsigned": 27121, - "##dates": 27122, - "moshe": 27123, - "galley": 27124, - "winnie": 27125, - "droplets": 27126, - "exiles": 27127, - "praises": 27128, - "watered": 27129, - "noodles": 27130, - "##aia": 27131, - "fein": 27132, - "adi": 27133, - "leland": 27134, - "multicultural": 27135, - "stink": 27136, - "bingo": 27137, - "comets": 27138, - "erskine": 27139, - "modernized": 27140, - "canned": 27141, - "constraint": 27142, - "domestically": 27143, - "chemotherapy": 27144, - "featherweight": 27145, - "stifled": 27146, - "##mum": 27147, - "darkly": 27148, - "irresistible": 27149, - "refreshing": 27150, - "hasty": 27151, - "isolate": 27152, - "##oys": 27153, - "kitchener": 27154, - "planners": 27155, - "##wehr": 27156, - "cages": 27157, - "yarn": 27158, - "implant": 27159, - "toulon": 27160, - "elects": 27161, - "childbirth": 27162, - "yue": 27163, - "##lind": 27164, - "##lone": 27165, - "cn": 27166, - "rightful": 27167, - "sportsman": 27168, - "junctions": 27169, - "remodeled": 27170, - "specifies": 27171, - "##rgh": 27172, - "291": 27173, - "##oons": 27174, - "complimented": 27175, - "##urgent": 27176, - "lister": 27177, - "ot": 27178, - "##logic": 27179, - "bequeathed": 27180, - "cheekbones": 27181, - "fontana": 27182, - "gabby": 27183, - "##dial": 27184, - "amadeus": 27185, - "corrugated": 27186, - "maverick": 27187, - "resented": 27188, - "triangles": 27189, - "##hered": 27190, - "##usly": 27191, - "nazareth": 27192, - "tyrol": 27193, - "1675": 27194, - "assent": 27195, - "poorer": 27196, - "sectional": 27197, - "aegean": 27198, - "##cous": 27199, - "296": 27200, - "nylon": 27201, - "ghanaian": 27202, - "##egorical": 27203, - "##weig": 27204, - "cushions": 27205, - "forbid": 27206, - "fusiliers": 27207, - "obstruction": 27208, - "somerville": 27209, - "##scia": 27210, - "dime": 27211, - "earrings": 27212, - "elliptical": 27213, - "leyte": 27214, - "oder": 27215, - "polymers": 27216, - "timmy": 27217, - "atm": 27218, - "midtown": 27219, - "piloted": 27220, - "settles": 27221, - "continual": 27222, - "externally": 27223, - "mayfield": 27224, - "##uh": 27225, - "enrichment": 27226, - "henson": 27227, - "keane": 27228, - "persians": 27229, - "1733": 27230, - "benji": 27231, - "braden": 27232, - "pep": 27233, - "324": 27234, - "##efe": 27235, - "contenders": 27236, - "pepsi": 27237, - "valet": 27238, - "##isches": 27239, - "298": 27240, - "##asse": 27241, - "##earing": 27242, - "goofy": 27243, - "stroll": 27244, - "##amen": 27245, - "authoritarian": 27246, - "occurrences": 27247, - "adversary": 27248, - "ahmedabad": 27249, - "tangent": 27250, - "toppled": 27251, - "dorchester": 27252, - "1672": 27253, - "modernism": 27254, - "marxism": 27255, - "islamist": 27256, - "charlemagne": 27257, - "exponential": 27258, - "racks": 27259, - "unicode": 27260, - "brunette": 27261, - "mbc": 27262, - "pic": 27263, - "skirmish": 27264, - "##bund": 27265, - "##lad": 27266, - "##powered": 27267, - "##yst": 27268, - "hoisted": 27269, - "messina": 27270, - "shatter": 27271, - "##ctum": 27272, - "jedi": 27273, - "vantage": 27274, - "##music": 27275, - "##neil": 27276, - "clemens": 27277, - "mahmoud": 27278, - "corrupted": 27279, - "authentication": 27280, - "lowry": 27281, - "nils": 27282, - "##washed": 27283, - "omnibus": 27284, - "wounding": 27285, - "jillian": 27286, - "##itors": 27287, - "##opped": 27288, - "serialized": 27289, - "narcotics": 27290, - "handheld": 27291, - "##arm": 27292, - "##plicity": 27293, - "intersecting": 27294, - "stimulating": 27295, - "##onis": 27296, - "crate": 27297, - "fellowships": 27298, - "hemingway": 27299, - "casinos": 27300, - "climatic": 27301, - "fordham": 27302, - "copeland": 27303, - "drip": 27304, - "beatty": 27305, - "leaflets": 27306, - "robber": 27307, - "brothel": 27308, - "madeira": 27309, - "##hedral": 27310, - "sphinx": 27311, - "ultrasound": 27312, - "##vana": 27313, - "valor": 27314, - "forbade": 27315, - "leonid": 27316, - "villas": 27317, - "##aldo": 27318, - "duane": 27319, - "marquez": 27320, - "##cytes": 27321, - "disadvantaged": 27322, - "forearms": 27323, - "kawasaki": 27324, - "reacts": 27325, - "consular": 27326, - "lax": 27327, - "uncles": 27328, - "uphold": 27329, - "##hopper": 27330, - "concepcion": 27331, - "dorsey": 27332, - "lass": 27333, - "##izan": 27334, - "arching": 27335, - "passageway": 27336, - "1708": 27337, - "researches": 27338, - "tia": 27339, - "internationals": 27340, - "##graphs": 27341, - "##opers": 27342, - "distinguishes": 27343, - "javanese": 27344, - "divert": 27345, - "##uven": 27346, - "plotted": 27347, - "##listic": 27348, - "##rwin": 27349, - "##erik": 27350, - "##tify": 27351, - "affirmative": 27352, - "signifies": 27353, - "validation": 27354, - "##bson": 27355, - "kari": 27356, - "felicity": 27357, - "georgina": 27358, - "zulu": 27359, - "##eros": 27360, - "##rained": 27361, - "##rath": 27362, - "overcoming": 27363, - "##dot": 27364, - "argyll": 27365, - "##rbin": 27366, - "1734": 27367, - "chiba": 27368, - "ratification": 27369, - "windy": 27370, - "earls": 27371, - "parapet": 27372, - "##marks": 27373, - "hunan": 27374, - "pristine": 27375, - "astrid": 27376, - "punta": 27377, - "##gart": 27378, - "brodie": 27379, - "##kota": 27380, - "##oder": 27381, - "malaga": 27382, - "minerva": 27383, - "rouse": 27384, - "##phonic": 27385, - "bellowed": 27386, - "pagoda": 27387, - "portals": 27388, - "reclamation": 27389, - "##gur": 27390, - "##odies": 27391, - "##⁄₄": 27392, - "parentheses": 27393, - "quoting": 27394, - "allergic": 27395, - "palette": 27396, - "showcases": 27397, - "benefactor": 27398, - "heartland": 27399, - "nonlinear": 27400, - "##tness": 27401, - "bladed": 27402, - "cheerfully": 27403, - "scans": 27404, - "##ety": 27405, - "##hone": 27406, - "1666": 27407, - "girlfriends": 27408, - "pedersen": 27409, - "hiram": 27410, - "sous": 27411, - "##liche": 27412, - "##nator": 27413, - "1683": 27414, - "##nery": 27415, - "##orio": 27416, - "##umen": 27417, - "bobo": 27418, - "primaries": 27419, - "smiley": 27420, - "##cb": 27421, - "unearthed": 27422, - "uniformly": 27423, - "fis": 27424, - "metadata": 27425, - "1635": 27426, - "ind": 27427, - "##oted": 27428, - "recoil": 27429, - "##titles": 27430, - "##tura": 27431, - "##ια": 27432, - "406": 27433, - "hilbert": 27434, - "jamestown": 27435, - "mcmillan": 27436, - "tulane": 27437, - "seychelles": 27438, - "##frid": 27439, - "antics": 27440, - "coli": 27441, - "fated": 27442, - "stucco": 27443, - "##grants": 27444, - "1654": 27445, - "bulky": 27446, - "accolades": 27447, - "arrays": 27448, - "caledonian": 27449, - "carnage": 27450, - "optimism": 27451, - "puebla": 27452, - "##tative": 27453, - "##cave": 27454, - "enforcing": 27455, - "rotherham": 27456, - "seo": 27457, - "dunlop": 27458, - "aeronautics": 27459, - "chimed": 27460, - "incline": 27461, - "zoning": 27462, - "archduke": 27463, - "hellenistic": 27464, - "##oses": 27465, - "##sions": 27466, - "candi": 27467, - "thong": 27468, - "##ople": 27469, - "magnate": 27470, - "rustic": 27471, - "##rsk": 27472, - "projective": 27473, - "slant": 27474, - "##offs": 27475, - "danes": 27476, - "hollis": 27477, - "vocalists": 27478, - "##ammed": 27479, - "congenital": 27480, - "contend": 27481, - "gesellschaft": 27482, - "##ocating": 27483, - "##pressive": 27484, - "douglass": 27485, - "quieter": 27486, - "##cm": 27487, - "##kshi": 27488, - "howled": 27489, - "salim": 27490, - "spontaneously": 27491, - "townsville": 27492, - "buena": 27493, - "southport": 27494, - "##bold": 27495, - "kato": 27496, - "1638": 27497, - "faerie": 27498, - "stiffly": 27499, - "##vus": 27500, - "##rled": 27501, - "297": 27502, - "flawless": 27503, - "realising": 27504, - "taboo": 27505, - "##7th": 27506, - "bytes": 27507, - "straightening": 27508, - "356": 27509, - "jena": 27510, - "##hid": 27511, - "##rmin": 27512, - "cartwright": 27513, - "berber": 27514, - "bertram": 27515, - "soloists": 27516, - "411": 27517, - "noses": 27518, - "417": 27519, - "coping": 27520, - "fission": 27521, - "hardin": 27522, - "inca": 27523, - "##cen": 27524, - "1717": 27525, - "mobilized": 27526, - "vhf": 27527, - "##raf": 27528, - "biscuits": 27529, - "curate": 27530, - "##85": 27531, - "##anial": 27532, - "331": 27533, - "gaunt": 27534, - "neighbourhoods": 27535, - "1540": 27536, - "##abas": 27537, - "blanca": 27538, - "bypassed": 27539, - "sockets": 27540, - "behold": 27541, - "coincidentally": 27542, - "##bane": 27543, - "nara": 27544, - "shave": 27545, - "splinter": 27546, - "terrific": 27547, - "##arion": 27548, - "##erian": 27549, - "commonplace": 27550, - "juris": 27551, - "redwood": 27552, - "waistband": 27553, - "boxed": 27554, - "caitlin": 27555, - "fingerprints": 27556, - "jennie": 27557, - "naturalized": 27558, - "##ired": 27559, - "balfour": 27560, - "craters": 27561, - "jody": 27562, - "bungalow": 27563, - "hugely": 27564, - "quilt": 27565, - "glitter": 27566, - "pigeons": 27567, - "undertaker": 27568, - "bulging": 27569, - "constrained": 27570, - "goo": 27571, - "##sil": 27572, - "##akh": 27573, - "assimilation": 27574, - "reworked": 27575, - "##person": 27576, - "persuasion": 27577, - "##pants": 27578, - "felicia": 27579, - "##cliff": 27580, - "##ulent": 27581, - "1732": 27582, - "explodes": 27583, - "##dun": 27584, - "##inium": 27585, - "##zic": 27586, - "lyman": 27587, - "vulture": 27588, - "hog": 27589, - "overlook": 27590, - "begs": 27591, - "northwards": 27592, - "ow": 27593, - "spoil": 27594, - "##urer": 27595, - "fatima": 27596, - "favorably": 27597, - "accumulate": 27598, - "sargent": 27599, - "sorority": 27600, - "corresponded": 27601, - "dispersal": 27602, - "kochi": 27603, - "toned": 27604, - "##imi": 27605, - "##lita": 27606, - "internacional": 27607, - "newfound": 27608, - "##agger": 27609, - "##lynn": 27610, - "##rigue": 27611, - "booths": 27612, - "peanuts": 27613, - "##eborg": 27614, - "medicare": 27615, - "muriel": 27616, - "nur": 27617, - "##uram": 27618, - "crates": 27619, - "millennia": 27620, - "pajamas": 27621, - "worsened": 27622, - "##breakers": 27623, - "jimi": 27624, - "vanuatu": 27625, - "yawned": 27626, - "##udeau": 27627, - "carousel": 27628, - "##hony": 27629, - "hurdle": 27630, - "##ccus": 27631, - "##mounted": 27632, - "##pod": 27633, - "rv": 27634, - "##eche": 27635, - "airship": 27636, - "ambiguity": 27637, - "compulsion": 27638, - "recapture": 27639, - "##claiming": 27640, - "arthritis": 27641, - "##osomal": 27642, - "1667": 27643, - "asserting": 27644, - "ngc": 27645, - "sniffing": 27646, - "dade": 27647, - "discontent": 27648, - "glendale": 27649, - "ported": 27650, - "##amina": 27651, - "defamation": 27652, - "rammed": 27653, - "##scent": 27654, - "fling": 27655, - "livingstone": 27656, - "##fleet": 27657, - "875": 27658, - "##ppy": 27659, - "apocalyptic": 27660, - "comrade": 27661, - "lcd": 27662, - "##lowe": 27663, - "cessna": 27664, - "eine": 27665, - "persecuted": 27666, - "subsistence": 27667, - "demi": 27668, - "hoop": 27669, - "reliefs": 27670, - "710": 27671, - "coptic": 27672, - "progressing": 27673, - "stemmed": 27674, - "perpetrators": 27675, - "1665": 27676, - "priestess": 27677, - "##nio": 27678, - "dobson": 27679, - "ebony": 27680, - "rooster": 27681, - "itf": 27682, - "tortricidae": 27683, - "##bbon": 27684, - "##jian": 27685, - "cleanup": 27686, - "##jean": 27687, - "##øy": 27688, - "1721": 27689, - "eighties": 27690, - "taxonomic": 27691, - "holiness": 27692, - "##hearted": 27693, - "##spar": 27694, - "antilles": 27695, - "showcasing": 27696, - "stabilized": 27697, - "##nb": 27698, - "gia": 27699, - "mascara": 27700, - "michelangelo": 27701, - "dawned": 27702, - "##uria": 27703, - "##vinsky": 27704, - "extinguished": 27705, - "fitz": 27706, - "grotesque": 27707, - "£100": 27708, - "##fera": 27709, - "##loid": 27710, - "##mous": 27711, - "barges": 27712, - "neue": 27713, - "throbbed": 27714, - "cipher": 27715, - "johnnie": 27716, - "##a1": 27717, - "##mpt": 27718, - "outburst": 27719, - "##swick": 27720, - "spearheaded": 27721, - "administrations": 27722, - "c1": 27723, - "heartbreak": 27724, - "pixels": 27725, - "pleasantly": 27726, - "##enay": 27727, - "lombardy": 27728, - "plush": 27729, - "##nsed": 27730, - "bobbie": 27731, - "##hly": 27732, - "reapers": 27733, - "tremor": 27734, - "xiang": 27735, - "minogue": 27736, - "substantive": 27737, - "hitch": 27738, - "barak": 27739, - "##wyl": 27740, - "kwan": 27741, - "##encia": 27742, - "910": 27743, - "obscene": 27744, - "elegance": 27745, - "indus": 27746, - "surfer": 27747, - "bribery": 27748, - "conserve": 27749, - "##hyllum": 27750, - "##masters": 27751, - "horatio": 27752, - "##fat": 27753, - "apes": 27754, - "rebound": 27755, - "psychotic": 27756, - "##pour": 27757, - "iteration": 27758, - "##mium": 27759, - "##vani": 27760, - "botanic": 27761, - "horribly": 27762, - "antiques": 27763, - "dispose": 27764, - "paxton": 27765, - "##hli": 27766, - "##wg": 27767, - "timeless": 27768, - "1704": 27769, - "disregard": 27770, - "engraver": 27771, - "hounds": 27772, - "##bau": 27773, - "##version": 27774, - "looted": 27775, - "uno": 27776, - "facilitates": 27777, - "groans": 27778, - "masjid": 27779, - "rutland": 27780, - "antibody": 27781, - "disqualification": 27782, - "decatur": 27783, - "footballers": 27784, - "quake": 27785, - "slacks": 27786, - "48th": 27787, - "rein": 27788, - "scribe": 27789, - "stabilize": 27790, - "commits": 27791, - "exemplary": 27792, - "tho": 27793, - "##hort": 27794, - "##chison": 27795, - "pantry": 27796, - "traversed": 27797, - "##hiti": 27798, - "disrepair": 27799, - "identifiable": 27800, - "vibrated": 27801, - "baccalaureate": 27802, - "##nnis": 27803, - "csa": 27804, - "interviewing": 27805, - "##iensis": 27806, - "##raße": 27807, - "greaves": 27808, - "wealthiest": 27809, - "343": 27810, - "classed": 27811, - "jogged": 27812, - "£5": 27813, - "##58": 27814, - "##atal": 27815, - "illuminating": 27816, - "knicks": 27817, - "respecting": 27818, - "##uno": 27819, - "scrubbed": 27820, - "##iji": 27821, - "##dles": 27822, - "kruger": 27823, - "moods": 27824, - "growls": 27825, - "raider": 27826, - "silvia": 27827, - "chefs": 27828, - "kam": 27829, - "vr": 27830, - "cree": 27831, - "percival": 27832, - "##terol": 27833, - "gunter": 27834, - "counterattack": 27835, - "defiant": 27836, - "henan": 27837, - "ze": 27838, - "##rasia": 27839, - "##riety": 27840, - "equivalence": 27841, - "submissions": 27842, - "##fra": 27843, - "##thor": 27844, - "bautista": 27845, - "mechanically": 27846, - "##heater": 27847, - "cornice": 27848, - "herbal": 27849, - "templar": 27850, - "##mering": 27851, - "outputs": 27852, - "ruining": 27853, - "ligand": 27854, - "renumbered": 27855, - "extravagant": 27856, - "mika": 27857, - "blockbuster": 27858, - "eta": 27859, - "insurrection": 27860, - "##ilia": 27861, - "darkening": 27862, - "ferocious": 27863, - "pianos": 27864, - "strife": 27865, - "kinship": 27866, - "##aer": 27867, - "melee": 27868, - "##anor": 27869, - "##iste": 27870, - "##may": 27871, - "##oue": 27872, - "decidedly": 27873, - "weep": 27874, - "##jad": 27875, - "##missive": 27876, - "##ppel": 27877, - "354": 27878, - "puget": 27879, - "unease": 27880, - "##gnant": 27881, - "1629": 27882, - "hammering": 27883, - "kassel": 27884, - "ob": 27885, - "wessex": 27886, - "##lga": 27887, - "bromwich": 27888, - "egan": 27889, - "paranoia": 27890, - "utilization": 27891, - "##atable": 27892, - "##idad": 27893, - "contradictory": 27894, - "provoke": 27895, - "##ols": 27896, - "##ouring": 27897, - "##tangled": 27898, - "knesset": 27899, - "##very": 27900, - "##lette": 27901, - "plumbing": 27902, - "##sden": 27903, - "##¹": 27904, - "greensboro": 27905, - "occult": 27906, - "sniff": 27907, - "338": 27908, - "zev": 27909, - "beaming": 27910, - "gamer": 27911, - "haggard": 27912, - "mahal": 27913, - "##olt": 27914, - "##pins": 27915, - "mendes": 27916, - "utmost": 27917, - "briefing": 27918, - "gunnery": 27919, - "##gut": 27920, - "##pher": 27921, - "##zh": 27922, - "##rok": 27923, - "1679": 27924, - "khalifa": 27925, - "sonya": 27926, - "##boot": 27927, - "principals": 27928, - "urbana": 27929, - "wiring": 27930, - "##liffe": 27931, - "##minating": 27932, - "##rrado": 27933, - "dahl": 27934, - "nyu": 27935, - "skepticism": 27936, - "np": 27937, - "townspeople": 27938, - "ithaca": 27939, - "lobster": 27940, - "somethin": 27941, - "##fur": 27942, - "##arina": 27943, - "##−1": 27944, - "freighter": 27945, - "zimmerman": 27946, - "biceps": 27947, - "contractual": 27948, - "##herton": 27949, - "amend": 27950, - "hurrying": 27951, - "subconscious": 27952, - "##anal": 27953, - "336": 27954, - "meng": 27955, - "clermont": 27956, - "spawning": 27957, - "##eia": 27958, - "##lub": 27959, - "dignitaries": 27960, - "impetus": 27961, - "snacks": 27962, - "spotting": 27963, - "twigs": 27964, - "##bilis": 27965, - "##cz": 27966, - "##ouk": 27967, - "libertadores": 27968, - "nic": 27969, - "skylar": 27970, - "##aina": 27971, - "##firm": 27972, - "gustave": 27973, - "asean": 27974, - "##anum": 27975, - "dieter": 27976, - "legislatures": 27977, - "flirt": 27978, - "bromley": 27979, - "trolls": 27980, - "umar": 27981, - "##bbies": 27982, - "##tyle": 27983, - "blah": 27984, - "parc": 27985, - "bridgeport": 27986, - "crank": 27987, - "negligence": 27988, - "##nction": 27989, - "46th": 27990, - "constantin": 27991, - "molded": 27992, - "bandages": 27993, - "seriousness": 27994, - "00pm": 27995, - "siegel": 27996, - "carpets": 27997, - "compartments": 27998, - "upbeat": 27999, - "statehood": 28000, - "##dner": 28001, - "##edging": 28002, - "marko": 28003, - "730": 28004, - "platt": 28005, - "##hane": 28006, - "paving": 28007, - "##iy": 28008, - "1738": 28009, - "abbess": 28010, - "impatience": 28011, - "limousine": 28012, - "nbl": 28013, - "##talk": 28014, - "441": 28015, - "lucille": 28016, - "mojo": 28017, - "nightfall": 28018, - "robbers": 28019, - "##nais": 28020, - "karel": 28021, - "brisk": 28022, - "calves": 28023, - "replicate": 28024, - "ascribed": 28025, - "telescopes": 28026, - "##olf": 28027, - "intimidated": 28028, - "##reen": 28029, - "ballast": 28030, - "specialization": 28031, - "##sit": 28032, - "aerodynamic": 28033, - "caliphate": 28034, - "rainer": 28035, - "visionary": 28036, - "##arded": 28037, - "epsilon": 28038, - "##aday": 28039, - "##onte": 28040, - "aggregation": 28041, - "auditory": 28042, - "boosted": 28043, - "reunification": 28044, - "kathmandu": 28045, - "loco": 28046, - "robyn": 28047, - "402": 28048, - "acknowledges": 28049, - "appointing": 28050, - "humanoid": 28051, - "newell": 28052, - "redeveloped": 28053, - "restraints": 28054, - "##tained": 28055, - "barbarians": 28056, - "chopper": 28057, - "1609": 28058, - "italiana": 28059, - "##lez": 28060, - "##lho": 28061, - "investigates": 28062, - "wrestlemania": 28063, - "##anies": 28064, - "##bib": 28065, - "690": 28066, - "##falls": 28067, - "creaked": 28068, - "dragoons": 28069, - "gravely": 28070, - "minions": 28071, - "stupidity": 28072, - "volley": 28073, - "##harat": 28074, - "##week": 28075, - "musik": 28076, - "##eries": 28077, - "##uously": 28078, - "fungal": 28079, - "massimo": 28080, - "semantics": 28081, - "malvern": 28082, - "##ahl": 28083, - "##pee": 28084, - "discourage": 28085, - "embryo": 28086, - "imperialism": 28087, - "1910s": 28088, - "profoundly": 28089, - "##ddled": 28090, - "jiangsu": 28091, - "sparkled": 28092, - "stat": 28093, - "##holz": 28094, - "sweatshirt": 28095, - "tobin": 28096, - "##iction": 28097, - "sneered": 28098, - "##cheon": 28099, - "##oit": 28100, - "brit": 28101, - "causal": 28102, - "smyth": 28103, - "##neuve": 28104, - "diffuse": 28105, - "perrin": 28106, - "silvio": 28107, - "##ipes": 28108, - "##recht": 28109, - "detonated": 28110, - "iqbal": 28111, - "selma": 28112, - "##nism": 28113, - "##zumi": 28114, - "roasted": 28115, - "##riders": 28116, - "tay": 28117, - "##ados": 28118, - "##mament": 28119, - "##mut": 28120, - "##rud": 28121, - "840": 28122, - "completes": 28123, - "nipples": 28124, - "cfa": 28125, - "flavour": 28126, - "hirsch": 28127, - "##laus": 28128, - "calderon": 28129, - "sneakers": 28130, - "moravian": 28131, - "##ksha": 28132, - "1622": 28133, - "rq": 28134, - "294": 28135, - "##imeters": 28136, - "bodo": 28137, - "##isance": 28138, - "##pre": 28139, - "##ronia": 28140, - "anatomical": 28141, - "excerpt": 28142, - "##lke": 28143, - "dh": 28144, - "kunst": 28145, - "##tablished": 28146, - "##scoe": 28147, - "biomass": 28148, - "panted": 28149, - "unharmed": 28150, - "gael": 28151, - "housemates": 28152, - "montpellier": 28153, - "##59": 28154, - "coa": 28155, - "rodents": 28156, - "tonic": 28157, - "hickory": 28158, - "singleton": 28159, - "##taro": 28160, - "451": 28161, - "1719": 28162, - "aldo": 28163, - "breaststroke": 28164, - "dempsey": 28165, - "och": 28166, - "rocco": 28167, - "##cuit": 28168, - "merton": 28169, - "dissemination": 28170, - "midsummer": 28171, - "serials": 28172, - "##idi": 28173, - "haji": 28174, - "polynomials": 28175, - "##rdon": 28176, - "gs": 28177, - "enoch": 28178, - "prematurely": 28179, - "shutter": 28180, - "taunton": 28181, - "£3": 28182, - "##grating": 28183, - "##inates": 28184, - "archangel": 28185, - "harassed": 28186, - "##asco": 28187, - "326": 28188, - "archway": 28189, - "dazzling": 28190, - "##ecin": 28191, - "1736": 28192, - "sumo": 28193, - "wat": 28194, - "##kovich": 28195, - "1086": 28196, - "honneur": 28197, - "##ently": 28198, - "##nostic": 28199, - "##ttal": 28200, - "##idon": 28201, - "1605": 28202, - "403": 28203, - "1716": 28204, - "blogger": 28205, - "rents": 28206, - "##gnan": 28207, - "hires": 28208, - "##ikh": 28209, - "##dant": 28210, - "howie": 28211, - "##rons": 28212, - "handler": 28213, - "retracted": 28214, - "shocks": 28215, - "1632": 28216, - "arun": 28217, - "duluth": 28218, - "kepler": 28219, - "trumpeter": 28220, - "##lary": 28221, - "peeking": 28222, - "seasoned": 28223, - "trooper": 28224, - "##mara": 28225, - "laszlo": 28226, - "##iciencies": 28227, - "##rti": 28228, - "heterosexual": 28229, - "##inatory": 28230, - "##ssion": 28231, - "indira": 28232, - "jogging": 28233, - "##inga": 28234, - "##lism": 28235, - "beit": 28236, - "dissatisfaction": 28237, - "malice": 28238, - "##ately": 28239, - "nedra": 28240, - "peeling": 28241, - "##rgeon": 28242, - "47th": 28243, - "stadiums": 28244, - "475": 28245, - "vertigo": 28246, - "##ains": 28247, - "iced": 28248, - "restroom": 28249, - "##plify": 28250, - "##tub": 28251, - "illustrating": 28252, - "pear": 28253, - "##chner": 28254, - "##sibility": 28255, - "inorganic": 28256, - "rappers": 28257, - "receipts": 28258, - "watery": 28259, - "##kura": 28260, - "lucinda": 28261, - "##oulos": 28262, - "reintroduced": 28263, - "##8th": 28264, - "##tched": 28265, - "gracefully": 28266, - "saxons": 28267, - "nutritional": 28268, - "wastewater": 28269, - "rained": 28270, - "favourites": 28271, - "bedrock": 28272, - "fisted": 28273, - "hallways": 28274, - "likeness": 28275, - "upscale": 28276, - "##lateral": 28277, - "1580": 28278, - "blinds": 28279, - "prequel": 28280, - "##pps": 28281, - "##tama": 28282, - "deter": 28283, - "humiliating": 28284, - "restraining": 28285, - "tn": 28286, - "vents": 28287, - "1659": 28288, - "laundering": 28289, - "recess": 28290, - "rosary": 28291, - "tractors": 28292, - "coulter": 28293, - "federer": 28294, - "##ifiers": 28295, - "##plin": 28296, - "persistence": 28297, - "##quitable": 28298, - "geschichte": 28299, - "pendulum": 28300, - "quakers": 28301, - "##beam": 28302, - "bassett": 28303, - "pictorial": 28304, - "buffet": 28305, - "koln": 28306, - "##sitor": 28307, - "drills": 28308, - "reciprocal": 28309, - "shooters": 28310, - "##57": 28311, - "##cton": 28312, - "##tees": 28313, - "converge": 28314, - "pip": 28315, - "dmitri": 28316, - "donnelly": 28317, - "yamamoto": 28318, - "aqua": 28319, - "azores": 28320, - "demographics": 28321, - "hypnotic": 28322, - "spitfire": 28323, - "suspend": 28324, - "wryly": 28325, - "roderick": 28326, - "##rran": 28327, - "sebastien": 28328, - "##asurable": 28329, - "mavericks": 28330, - "##fles": 28331, - "##200": 28332, - "himalayan": 28333, - "prodigy": 28334, - "##iance": 28335, - "transvaal": 28336, - "demonstrators": 28337, - "handcuffs": 28338, - "dodged": 28339, - "mcnamara": 28340, - "sublime": 28341, - "1726": 28342, - "crazed": 28343, - "##efined": 28344, - "##till": 28345, - "ivo": 28346, - "pondered": 28347, - "reconciled": 28348, - "shrill": 28349, - "sava": 28350, - "##duk": 28351, - "bal": 28352, - "cad": 28353, - "heresy": 28354, - "jaipur": 28355, - "goran": 28356, - "##nished": 28357, - "341": 28358, - "lux": 28359, - "shelly": 28360, - "whitehall": 28361, - "##hre": 28362, - "israelis": 28363, - "peacekeeping": 28364, - "##wled": 28365, - "1703": 28366, - "demetrius": 28367, - "ousted": 28368, - "##arians": 28369, - "##zos": 28370, - "beale": 28371, - "anwar": 28372, - "backstroke": 28373, - "raged": 28374, - "shrinking": 28375, - "cremated": 28376, - "##yck": 28377, - "benign": 28378, - "towing": 28379, - "wadi": 28380, - "darmstadt": 28381, - "landfill": 28382, - "parana": 28383, - "soothe": 28384, - "colleen": 28385, - "sidewalks": 28386, - "mayfair": 28387, - "tumble": 28388, - "hepatitis": 28389, - "ferrer": 28390, - "superstructure": 28391, - "##gingly": 28392, - "##urse": 28393, - "##wee": 28394, - "anthropological": 28395, - "translators": 28396, - "##mies": 28397, - "closeness": 28398, - "hooves": 28399, - "##pw": 28400, - "mondays": 28401, - "##roll": 28402, - "##vita": 28403, - "landscaping": 28404, - "##urized": 28405, - "purification": 28406, - "sock": 28407, - "thorns": 28408, - "thwarted": 28409, - "jalan": 28410, - "tiberius": 28411, - "##taka": 28412, - "saline": 28413, - "##rito": 28414, - "confidently": 28415, - "khyber": 28416, - "sculptors": 28417, - "##ij": 28418, - "brahms": 28419, - "hammersmith": 28420, - "inspectors": 28421, - "battista": 28422, - "fivb": 28423, - "fragmentation": 28424, - "hackney": 28425, - "##uls": 28426, - "arresting": 28427, - "exercising": 28428, - "antoinette": 28429, - "bedfordshire": 28430, - "##zily": 28431, - "dyed": 28432, - "##hema": 28433, - "1656": 28434, - "racetrack": 28435, - "variability": 28436, - "##tique": 28437, - "1655": 28438, - "austrians": 28439, - "deteriorating": 28440, - "madman": 28441, - "theorists": 28442, - "aix": 28443, - "lehman": 28444, - "weathered": 28445, - "1731": 28446, - "decreed": 28447, - "eruptions": 28448, - "1729": 28449, - "flaw": 28450, - "quinlan": 28451, - "sorbonne": 28452, - "flutes": 28453, - "nunez": 28454, - "1711": 28455, - "adored": 28456, - "downwards": 28457, - "fable": 28458, - "rasped": 28459, - "1712": 28460, - "moritz": 28461, - "mouthful": 28462, - "renegade": 28463, - "shivers": 28464, - "stunts": 28465, - "dysfunction": 28466, - "restrain": 28467, - "translit": 28468, - "327": 28469, - "pancakes": 28470, - "##avio": 28471, - "##cision": 28472, - "##tray": 28473, - "351": 28474, - "vial": 28475, - "##lden": 28476, - "bain": 28477, - "##maid": 28478, - "##oxide": 28479, - "chihuahua": 28480, - "malacca": 28481, - "vimes": 28482, - "##rba": 28483, - "##rnier": 28484, - "1664": 28485, - "donnie": 28486, - "plaques": 28487, - "##ually": 28488, - "337": 28489, - "bangs": 28490, - "floppy": 28491, - "huntsville": 28492, - "loretta": 28493, - "nikolay": 28494, - "##otte": 28495, - "eater": 28496, - "handgun": 28497, - "ubiquitous": 28498, - "##hett": 28499, - "eras": 28500, - "zodiac": 28501, - "1634": 28502, - "##omorphic": 28503, - "1820s": 28504, - "##zog": 28505, - "cochran": 28506, - "##bula": 28507, - "##lithic": 28508, - "warring": 28509, - "##rada": 28510, - "dalai": 28511, - "excused": 28512, - "blazers": 28513, - "mcconnell": 28514, - "reeling": 28515, - "bot": 28516, - "este": 28517, - "##abi": 28518, - "geese": 28519, - "hoax": 28520, - "taxon": 28521, - "##bla": 28522, - "guitarists": 28523, - "##icon": 28524, - "condemning": 28525, - "hunts": 28526, - "inversion": 28527, - "moffat": 28528, - "taekwondo": 28529, - "##lvis": 28530, - "1624": 28531, - "stammered": 28532, - "##rest": 28533, - "##rzy": 28534, - "sousa": 28535, - "fundraiser": 28536, - "marylebone": 28537, - "navigable": 28538, - "uptown": 28539, - "cabbage": 28540, - "daniela": 28541, - "salman": 28542, - "shitty": 28543, - "whimper": 28544, - "##kian": 28545, - "##utive": 28546, - "programmers": 28547, - "protections": 28548, - "rm": 28549, - "##rmi": 28550, - "##rued": 28551, - "forceful": 28552, - "##enes": 28553, - "fuss": 28554, - "##tao": 28555, - "##wash": 28556, - "brat": 28557, - "oppressive": 28558, - "reykjavik": 28559, - "spartak": 28560, - "ticking": 28561, - "##inkles": 28562, - "##kiewicz": 28563, - "adolph": 28564, - "horst": 28565, - "maui": 28566, - "protege": 28567, - "straighten": 28568, - "cpc": 28569, - "landau": 28570, - "concourse": 28571, - "clements": 28572, - "resultant": 28573, - "##ando": 28574, - "imaginative": 28575, - "joo": 28576, - "reactivated": 28577, - "##rem": 28578, - "##ffled": 28579, - "##uising": 28580, - "consultative": 28581, - "##guide": 28582, - "flop": 28583, - "kaitlyn": 28584, - "mergers": 28585, - "parenting": 28586, - "somber": 28587, - "##vron": 28588, - "supervise": 28589, - "vidhan": 28590, - "##imum": 28591, - "courtship": 28592, - "exemplified": 28593, - "harmonies": 28594, - "medallist": 28595, - "refining": 28596, - "##rrow": 28597, - "##ка": 28598, - "amara": 28599, - "##hum": 28600, - "780": 28601, - "goalscorer": 28602, - "sited": 28603, - "overshadowed": 28604, - "rohan": 28605, - "displeasure": 28606, - "secretive": 28607, - "multiplied": 28608, - "osman": 28609, - "##orth": 28610, - "engravings": 28611, - "padre": 28612, - "##kali": 28613, - "##veda": 28614, - "miniatures": 28615, - "mis": 28616, - "##yala": 28617, - "clap": 28618, - "pali": 28619, - "rook": 28620, - "##cana": 28621, - "1692": 28622, - "57th": 28623, - "antennae": 28624, - "astro": 28625, - "oskar": 28626, - "1628": 28627, - "bulldog": 28628, - "crotch": 28629, - "hackett": 28630, - "yucatan": 28631, - "##sure": 28632, - "amplifiers": 28633, - "brno": 28634, - "ferrara": 28635, - "migrating": 28636, - "##gree": 28637, - "thanking": 28638, - "turing": 28639, - "##eza": 28640, - "mccann": 28641, - "ting": 28642, - "andersson": 28643, - "onslaught": 28644, - "gaines": 28645, - "ganga": 28646, - "incense": 28647, - "standardization": 28648, - "##mation": 28649, - "sentai": 28650, - "scuba": 28651, - "stuffing": 28652, - "turquoise": 28653, - "waivers": 28654, - "alloys": 28655, - "##vitt": 28656, - "regaining": 28657, - "vaults": 28658, - "##clops": 28659, - "##gizing": 28660, - "digger": 28661, - "furry": 28662, - "memorabilia": 28663, - "probing": 28664, - "##iad": 28665, - "payton": 28666, - "rec": 28667, - "deutschland": 28668, - "filippo": 28669, - "opaque": 28670, - "seamen": 28671, - "zenith": 28672, - "afrikaans": 28673, - "##filtration": 28674, - "disciplined": 28675, - "inspirational": 28676, - "##merie": 28677, - "banco": 28678, - "confuse": 28679, - "grafton": 28680, - "tod": 28681, - "##dgets": 28682, - "championed": 28683, - "simi": 28684, - "anomaly": 28685, - "biplane": 28686, - "##ceptive": 28687, - "electrode": 28688, - "##para": 28689, - "1697": 28690, - "cleavage": 28691, - "crossbow": 28692, - "swirl": 28693, - "informant": 28694, - "##lars": 28695, - "##osta": 28696, - "afi": 28697, - "bonfire": 28698, - "spec": 28699, - "##oux": 28700, - "lakeside": 28701, - "slump": 28702, - "##culus": 28703, - "##lais": 28704, - "##qvist": 28705, - "##rrigan": 28706, - "1016": 28707, - "facades": 28708, - "borg": 28709, - "inwardly": 28710, - "cervical": 28711, - "xl": 28712, - "pointedly": 28713, - "050": 28714, - "stabilization": 28715, - "##odon": 28716, - "chests": 28717, - "1699": 28718, - "hacked": 28719, - "ctv": 28720, - "orthogonal": 28721, - "suzy": 28722, - "##lastic": 28723, - "gaulle": 28724, - "jacobite": 28725, - "rearview": 28726, - "##cam": 28727, - "##erted": 28728, - "ashby": 28729, - "##drik": 28730, - "##igate": 28731, - "##mise": 28732, - "##zbek": 28733, - "affectionately": 28734, - "canine": 28735, - "disperse": 28736, - "latham": 28737, - "##istles": 28738, - "##ivar": 28739, - "spielberg": 28740, - "##orin": 28741, - "##idium": 28742, - "ezekiel": 28743, - "cid": 28744, - "##sg": 28745, - "durga": 28746, - "middletown": 28747, - "##cina": 28748, - "customized": 28749, - "frontiers": 28750, - "harden": 28751, - "##etano": 28752, - "##zzy": 28753, - "1604": 28754, - "bolsheviks": 28755, - "##66": 28756, - "coloration": 28757, - "yoko": 28758, - "##bedo": 28759, - "briefs": 28760, - "slabs": 28761, - "debra": 28762, - "liquidation": 28763, - "plumage": 28764, - "##oin": 28765, - "blossoms": 28766, - "dementia": 28767, - "subsidy": 28768, - "1611": 28769, - "proctor": 28770, - "relational": 28771, - "jerseys": 28772, - "parochial": 28773, - "ter": 28774, - "##ici": 28775, - "esa": 28776, - "peshawar": 28777, - "cavalier": 28778, - "loren": 28779, - "cpi": 28780, - "idiots": 28781, - "shamrock": 28782, - "1646": 28783, - "dutton": 28784, - "malabar": 28785, - "mustache": 28786, - "##endez": 28787, - "##ocytes": 28788, - "referencing": 28789, - "terminates": 28790, - "marche": 28791, - "yarmouth": 28792, - "##sop": 28793, - "acton": 28794, - "mated": 28795, - "seton": 28796, - "subtly": 28797, - "baptised": 28798, - "beige": 28799, - "extremes": 28800, - "jolted": 28801, - "kristina": 28802, - "telecast": 28803, - "##actic": 28804, - "safeguard": 28805, - "waldo": 28806, - "##baldi": 28807, - "##bular": 28808, - "endeavors": 28809, - "sloppy": 28810, - "subterranean": 28811, - "##ensburg": 28812, - "##itung": 28813, - "delicately": 28814, - "pigment": 28815, - "tq": 28816, - "##scu": 28817, - "1626": 28818, - "##ound": 28819, - "collisions": 28820, - "coveted": 28821, - "herds": 28822, - "##personal": 28823, - "##meister": 28824, - "##nberger": 28825, - "chopra": 28826, - "##ricting": 28827, - "abnormalities": 28828, - "defective": 28829, - "galician": 28830, - "lucie": 28831, - "##dilly": 28832, - "alligator": 28833, - "likened": 28834, - "##genase": 28835, - "burundi": 28836, - "clears": 28837, - "complexion": 28838, - "derelict": 28839, - "deafening": 28840, - "diablo": 28841, - "fingered": 28842, - "champaign": 28843, - "dogg": 28844, - "enlist": 28845, - "isotope": 28846, - "labeling": 28847, - "mrna": 28848, - "##erre": 28849, - "brilliance": 28850, - "marvelous": 28851, - "##ayo": 28852, - "1652": 28853, - "crawley": 28854, - "ether": 28855, - "footed": 28856, - "dwellers": 28857, - "deserts": 28858, - "hamish": 28859, - "rubs": 28860, - "warlock": 28861, - "skimmed": 28862, - "##lizer": 28863, - "870": 28864, - "buick": 28865, - "embark": 28866, - "heraldic": 28867, - "irregularities": 28868, - "##ajan": 28869, - "kiara": 28870, - "##kulam": 28871, - "##ieg": 28872, - "antigen": 28873, - "kowalski": 28874, - "##lge": 28875, - "oakley": 28876, - "visitation": 28877, - "##mbit": 28878, - "vt": 28879, - "##suit": 28880, - "1570": 28881, - "murderers": 28882, - "##miento": 28883, - "##rites": 28884, - "chimneys": 28885, - "##sling": 28886, - "condemn": 28887, - "custer": 28888, - "exchequer": 28889, - "havre": 28890, - "##ghi": 28891, - "fluctuations": 28892, - "##rations": 28893, - "dfb": 28894, - "hendricks": 28895, - "vaccines": 28896, - "##tarian": 28897, - "nietzsche": 28898, - "biking": 28899, - "juicy": 28900, - "##duced": 28901, - "brooding": 28902, - "scrolling": 28903, - "selangor": 28904, - "##ragan": 28905, - "352": 28906, - "annum": 28907, - "boomed": 28908, - "seminole": 28909, - "sugarcane": 28910, - "##dna": 28911, - "departmental": 28912, - "dismissing": 28913, - "innsbruck": 28914, - "arteries": 28915, - "ashok": 28916, - "batavia": 28917, - "daze": 28918, - "kun": 28919, - "overtook": 28920, - "##rga": 28921, - "##tlan": 28922, - "beheaded": 28923, - "gaddafi": 28924, - "holm": 28925, - "electronically": 28926, - "faulty": 28927, - "galilee": 28928, - "fractures": 28929, - "kobayashi": 28930, - "##lized": 28931, - "gunmen": 28932, - "magma": 28933, - "aramaic": 28934, - "mala": 28935, - "eastenders": 28936, - "inference": 28937, - "messengers": 28938, - "bf": 28939, - "##qu": 28940, - "407": 28941, - "bathrooms": 28942, - "##vere": 28943, - "1658": 28944, - "flashbacks": 28945, - "ideally": 28946, - "misunderstood": 28947, - "##jali": 28948, - "##weather": 28949, - "mendez": 28950, - "##grounds": 28951, - "505": 28952, - "uncanny": 28953, - "##iii": 28954, - "1709": 28955, - "friendships": 28956, - "##nbc": 28957, - "sacrament": 28958, - "accommodated": 28959, - "reiterated": 28960, - "logistical": 28961, - "pebbles": 28962, - "thumped": 28963, - "##escence": 28964, - "administering": 28965, - "decrees": 28966, - "drafts": 28967, - "##flight": 28968, - "##cased": 28969, - "##tula": 28970, - "futuristic": 28971, - "picket": 28972, - "intimidation": 28973, - "winthrop": 28974, - "##fahan": 28975, - "interfered": 28976, - "339": 28977, - "afar": 28978, - "francoise": 28979, - "morally": 28980, - "uta": 28981, - "cochin": 28982, - "croft": 28983, - "dwarfs": 28984, - "##bruck": 28985, - "##dents": 28986, - "##nami": 28987, - "biker": 28988, - "##hner": 28989, - "##meral": 28990, - "nano": 28991, - "##isen": 28992, - "##ometric": 28993, - "##pres": 28994, - "##ан": 28995, - "brightened": 28996, - "meek": 28997, - "parcels": 28998, - "securely": 28999, - "gunners": 29000, - "##jhl": 29001, - "##zko": 29002, - "agile": 29003, - "hysteria": 29004, - "##lten": 29005, - "##rcus": 29006, - "bukit": 29007, - "champs": 29008, - "chevy": 29009, - "cuckoo": 29010, - "leith": 29011, - "sadler": 29012, - "theologians": 29013, - "welded": 29014, - "##section": 29015, - "1663": 29016, - "jj": 29017, - "plurality": 29018, - "xander": 29019, - "##rooms": 29020, - "##formed": 29021, - "shredded": 29022, - "temps": 29023, - "intimately": 29024, - "pau": 29025, - "tormented": 29026, - "##lok": 29027, - "##stellar": 29028, - "1618": 29029, - "charred": 29030, - "ems": 29031, - "essen": 29032, - "##mmel": 29033, - "alarms": 29034, - "spraying": 29035, - "ascot": 29036, - "blooms": 29037, - "twinkle": 29038, - "##abia": 29039, - "##apes": 29040, - "internment": 29041, - "obsidian": 29042, - "##chaft": 29043, - "snoop": 29044, - "##dav": 29045, - "##ooping": 29046, - "malibu": 29047, - "##tension": 29048, - "quiver": 29049, - "##itia": 29050, - "hays": 29051, - "mcintosh": 29052, - "travers": 29053, - "walsall": 29054, - "##ffie": 29055, - "1623": 29056, - "beverley": 29057, - "schwarz": 29058, - "plunging": 29059, - "structurally": 29060, - "m3": 29061, - "rosenthal": 29062, - "vikram": 29063, - "##tsk": 29064, - "770": 29065, - "ghz": 29066, - "##onda": 29067, - "##tiv": 29068, - "chalmers": 29069, - "groningen": 29070, - "pew": 29071, - "reckon": 29072, - "unicef": 29073, - "##rvis": 29074, - "55th": 29075, - "##gni": 29076, - "1651": 29077, - "sulawesi": 29078, - "avila": 29079, - "cai": 29080, - "metaphysical": 29081, - "screwing": 29082, - "turbulence": 29083, - "##mberg": 29084, - "augusto": 29085, - "samba": 29086, - "56th": 29087, - "baffled": 29088, - "momentary": 29089, - "toxin": 29090, - "##urian": 29091, - "##wani": 29092, - "aachen": 29093, - "condoms": 29094, - "dali": 29095, - "steppe": 29096, - "##3d": 29097, - "##app": 29098, - "##oed": 29099, - "##year": 29100, - "adolescence": 29101, - "dauphin": 29102, - "electrically": 29103, - "inaccessible": 29104, - "microscopy": 29105, - "nikita": 29106, - "##ega": 29107, - "atv": 29108, - "##cel": 29109, - "##enter": 29110, - "##oles": 29111, - "##oteric": 29112, - "##ы": 29113, - "accountants": 29114, - "punishments": 29115, - "wrongly": 29116, - "bribes": 29117, - "adventurous": 29118, - "clinch": 29119, - "flinders": 29120, - "southland": 29121, - "##hem": 29122, - "##kata": 29123, - "gough": 29124, - "##ciency": 29125, - "lads": 29126, - "soared": 29127, - "##ה": 29128, - "undergoes": 29129, - "deformation": 29130, - "outlawed": 29131, - "rubbish": 29132, - "##arus": 29133, - "##mussen": 29134, - "##nidae": 29135, - "##rzburg": 29136, - "arcs": 29137, - "##ingdon": 29138, - "##tituted": 29139, - "1695": 29140, - "wheelbase": 29141, - "wheeling": 29142, - "bombardier": 29143, - "campground": 29144, - "zebra": 29145, - "##lices": 29146, - "##oj": 29147, - "##bain": 29148, - "lullaby": 29149, - "##ecure": 29150, - "donetsk": 29151, - "wylie": 29152, - "grenada": 29153, - "##arding": 29154, - "##ης": 29155, - "squinting": 29156, - "eireann": 29157, - "opposes": 29158, - "##andra": 29159, - "maximal": 29160, - "runes": 29161, - "##broken": 29162, - "##cuting": 29163, - "##iface": 29164, - "##ror": 29165, - "##rosis": 29166, - "additive": 29167, - "britney": 29168, - "adultery": 29169, - "triggering": 29170, - "##drome": 29171, - "detrimental": 29172, - "aarhus": 29173, - "containment": 29174, - "jc": 29175, - "swapped": 29176, - "vichy": 29177, - "##ioms": 29178, - "madly": 29179, - "##oric": 29180, - "##rag": 29181, - "brant": 29182, - "##ckey": 29183, - "##trix": 29184, - "1560": 29185, - "1612": 29186, - "broughton": 29187, - "rustling": 29188, - "##stems": 29189, - "##uder": 29190, - "asbestos": 29191, - "mentoring": 29192, - "##nivorous": 29193, - "finley": 29194, - "leaps": 29195, - "##isan": 29196, - "apical": 29197, - "pry": 29198, - "slits": 29199, - "substitutes": 29200, - "##dict": 29201, - "intuitive": 29202, - "fantasia": 29203, - "insistent": 29204, - "unreasonable": 29205, - "##igen": 29206, - "##vna": 29207, - "domed": 29208, - "hannover": 29209, - "margot": 29210, - "ponder": 29211, - "##zziness": 29212, - "impromptu": 29213, - "jian": 29214, - "lc": 29215, - "rampage": 29216, - "stemming": 29217, - "##eft": 29218, - "andrey": 29219, - "gerais": 29220, - "whichever": 29221, - "amnesia": 29222, - "appropriated": 29223, - "anzac": 29224, - "clicks": 29225, - "modifying": 29226, - "ultimatum": 29227, - "cambrian": 29228, - "maids": 29229, - "verve": 29230, - "yellowstone": 29231, - "##mbs": 29232, - "conservatoire": 29233, - "##scribe": 29234, - "adherence": 29235, - "dinners": 29236, - "spectra": 29237, - "imperfect": 29238, - "mysteriously": 29239, - "sidekick": 29240, - "tatar": 29241, - "tuba": 29242, - "##aks": 29243, - "##ifolia": 29244, - "distrust": 29245, - "##athan": 29246, - "##zle": 29247, - "c2": 29248, - "ronin": 29249, - "zac": 29250, - "##pse": 29251, - "celaena": 29252, - "instrumentalist": 29253, - "scents": 29254, - "skopje": 29255, - "##mbling": 29256, - "comical": 29257, - "compensated": 29258, - "vidal": 29259, - "condor": 29260, - "intersect": 29261, - "jingle": 29262, - "wavelengths": 29263, - "##urrent": 29264, - "mcqueen": 29265, - "##izzly": 29266, - "carp": 29267, - "weasel": 29268, - "422": 29269, - "kanye": 29270, - "militias": 29271, - "postdoctoral": 29272, - "eugen": 29273, - "gunslinger": 29274, - "##ɛ": 29275, - "faux": 29276, - "hospice": 29277, - "##for": 29278, - "appalled": 29279, - "derivation": 29280, - "dwarves": 29281, - "##elis": 29282, - "dilapidated": 29283, - "##folk": 29284, - "astoria": 29285, - "philology": 29286, - "##lwyn": 29287, - "##otho": 29288, - "##saka": 29289, - "inducing": 29290, - "philanthropy": 29291, - "##bf": 29292, - "##itative": 29293, - "geek": 29294, - "markedly": 29295, - "sql": 29296, - "##yce": 29297, - "bessie": 29298, - "indices": 29299, - "rn": 29300, - "##flict": 29301, - "495": 29302, - "frowns": 29303, - "resolving": 29304, - "weightlifting": 29305, - "tugs": 29306, - "cleric": 29307, - "contentious": 29308, - "1653": 29309, - "mania": 29310, - "rms": 29311, - "##miya": 29312, - "##reate": 29313, - "##ruck": 29314, - "##tucket": 29315, - "bien": 29316, - "eels": 29317, - "marek": 29318, - "##ayton": 29319, - "##cence": 29320, - "discreet": 29321, - "unofficially": 29322, - "##ife": 29323, - "leaks": 29324, - "##bber": 29325, - "1705": 29326, - "332": 29327, - "dung": 29328, - "compressor": 29329, - "hillsborough": 29330, - "pandit": 29331, - "shillings": 29332, - "distal": 29333, - "##skin": 29334, - "381": 29335, - "##tat": 29336, - "##you": 29337, - "nosed": 29338, - "##nir": 29339, - "mangrove": 29340, - "undeveloped": 29341, - "##idia": 29342, - "textures": 29343, - "##inho": 29344, - "##500": 29345, - "##rise": 29346, - "ae": 29347, - "irritating": 29348, - "nay": 29349, - "amazingly": 29350, - "bancroft": 29351, - "apologetic": 29352, - "compassionate": 29353, - "kata": 29354, - "symphonies": 29355, - "##lovic": 29356, - "airspace": 29357, - "##lch": 29358, - "930": 29359, - "gifford": 29360, - "precautions": 29361, - "fulfillment": 29362, - "sevilla": 29363, - "vulgar": 29364, - "martinique": 29365, - "##urities": 29366, - "looting": 29367, - "piccolo": 29368, - "tidy": 29369, - "##dermott": 29370, - "quadrant": 29371, - "armchair": 29372, - "incomes": 29373, - "mathematicians": 29374, - "stampede": 29375, - "nilsson": 29376, - "##inking": 29377, - "##scan": 29378, - "foo": 29379, - "quarterfinal": 29380, - "##ostal": 29381, - "shang": 29382, - "shouldered": 29383, - "squirrels": 29384, - "##owe": 29385, - "344": 29386, - "vinegar": 29387, - "##bner": 29388, - "##rchy": 29389, - "##systems": 29390, - "delaying": 29391, - "##trics": 29392, - "ars": 29393, - "dwyer": 29394, - "rhapsody": 29395, - "sponsoring": 29396, - "##gration": 29397, - "bipolar": 29398, - "cinder": 29399, - "starters": 29400, - "##olio": 29401, - "##urst": 29402, - "421": 29403, - "signage": 29404, - "##nty": 29405, - "aground": 29406, - "figurative": 29407, - "mons": 29408, - "acquaintances": 29409, - "duets": 29410, - "erroneously": 29411, - "soyuz": 29412, - "elliptic": 29413, - "recreated": 29414, - "##cultural": 29415, - "##quette": 29416, - "##ssed": 29417, - "##tma": 29418, - "##zcz": 29419, - "moderator": 29420, - "scares": 29421, - "##itaire": 29422, - "##stones": 29423, - "##udence": 29424, - "juniper": 29425, - "sighting": 29426, - "##just": 29427, - "##nsen": 29428, - "britten": 29429, - "calabria": 29430, - "ry": 29431, - "bop": 29432, - "cramer": 29433, - "forsyth": 29434, - "stillness": 29435, - "##л": 29436, - "airmen": 29437, - "gathers": 29438, - "unfit": 29439, - "##umber": 29440, - "##upt": 29441, - "taunting": 29442, - "##rip": 29443, - "seeker": 29444, - "streamlined": 29445, - "##bution": 29446, - "holster": 29447, - "schumann": 29448, - "tread": 29449, - "vox": 29450, - "##gano": 29451, - "##onzo": 29452, - "strive": 29453, - "dil": 29454, - "reforming": 29455, - "covent": 29456, - "newbury": 29457, - "predicting": 29458, - "##orro": 29459, - "decorate": 29460, - "tre": 29461, - "##puted": 29462, - "andover": 29463, - "ie": 29464, - "asahi": 29465, - "dept": 29466, - "dunkirk": 29467, - "gills": 29468, - "##tori": 29469, - "buren": 29470, - "huskies": 29471, - "##stis": 29472, - "##stov": 29473, - "abstracts": 29474, - "bets": 29475, - "loosen": 29476, - "##opa": 29477, - "1682": 29478, - "yearning": 29479, - "##glio": 29480, - "##sir": 29481, - "berman": 29482, - "effortlessly": 29483, - "enamel": 29484, - "napoli": 29485, - "persist": 29486, - "##peration": 29487, - "##uez": 29488, - "attache": 29489, - "elisa": 29490, - "b1": 29491, - "invitations": 29492, - "##kic": 29493, - "accelerating": 29494, - "reindeer": 29495, - "boardwalk": 29496, - "clutches": 29497, - "nelly": 29498, - "polka": 29499, - "starbucks": 29500, - "##kei": 29501, - "adamant": 29502, - "huey": 29503, - "lough": 29504, - "unbroken": 29505, - "adventurer": 29506, - "embroidery": 29507, - "inspecting": 29508, - "stanza": 29509, - "##ducted": 29510, - "naia": 29511, - "taluka": 29512, - "##pone": 29513, - "##roids": 29514, - "chases": 29515, - "deprivation": 29516, - "florian": 29517, - "##jing": 29518, - "##ppet": 29519, - "earthly": 29520, - "##lib": 29521, - "##ssee": 29522, - "colossal": 29523, - "foreigner": 29524, - "vet": 29525, - "freaks": 29526, - "patrice": 29527, - "rosewood": 29528, - "triassic": 29529, - "upstate": 29530, - "##pkins": 29531, - "dominates": 29532, - "ata": 29533, - "chants": 29534, - "ks": 29535, - "vo": 29536, - "##400": 29537, - "##bley": 29538, - "##raya": 29539, - "##rmed": 29540, - "555": 29541, - "agra": 29542, - "infiltrate": 29543, - "##ailing": 29544, - "##ilation": 29545, - "##tzer": 29546, - "##uppe": 29547, - "##werk": 29548, - "binoculars": 29549, - "enthusiast": 29550, - "fujian": 29551, - "squeak": 29552, - "##avs": 29553, - "abolitionist": 29554, - "almeida": 29555, - "boredom": 29556, - "hampstead": 29557, - "marsden": 29558, - "rations": 29559, - "##ands": 29560, - "inflated": 29561, - "334": 29562, - "bonuses": 29563, - "rosalie": 29564, - "patna": 29565, - "##rco": 29566, - "329": 29567, - "detachments": 29568, - "penitentiary": 29569, - "54th": 29570, - "flourishing": 29571, - "woolf": 29572, - "##dion": 29573, - "##etched": 29574, - "papyrus": 29575, - "##lster": 29576, - "##nsor": 29577, - "##toy": 29578, - "bobbed": 29579, - "dismounted": 29580, - "endelle": 29581, - "inhuman": 29582, - "motorola": 29583, - "tbs": 29584, - "wince": 29585, - "wreath": 29586, - "##ticus": 29587, - "hideout": 29588, - "inspections": 29589, - "sanjay": 29590, - "disgrace": 29591, - "infused": 29592, - "pudding": 29593, - "stalks": 29594, - "##urbed": 29595, - "arsenic": 29596, - "leases": 29597, - "##hyl": 29598, - "##rrard": 29599, - "collarbone": 29600, - "##waite": 29601, - "##wil": 29602, - "dowry": 29603, - "##bant": 29604, - "##edance": 29605, - "genealogical": 29606, - "nitrate": 29607, - "salamanca": 29608, - "scandals": 29609, - "thyroid": 29610, - "necessitated": 29611, - "##!": 29612, - "##\"": 29613, - "###": 29614, - "##$": 29615, - "##%": 29616, - "##&": 29617, - "##'": 29618, - "##(": 29619, - "##)": 29620, - "##*": 29621, - "##+": 29622, - "##,": 29623, - "##-": 29624, - "##.": 29625, - "##/": 29626, - "##:": 29627, - "##;": 29628, - "##<": 29629, - "##=": 29630, - "##>": 29631, - "##?": 29632, - "##@": 29633, - "##[": 29634, - "##\\": 29635, - "##]": 29636, - "##^": 29637, - "##_": 29638, - "##`": 29639, - "##{": 29640, - "##|": 29641, - "##}": 29642, - "##~": 29643, - "##¡": 29644, - "##¢": 29645, - "##£": 29646, - "##¤": 29647, - "##¥": 29648, - "##¦": 29649, - "##§": 29650, - "##¨": 29651, - "##©": 29652, - "##ª": 29653, - "##«": 29654, - "##¬": 29655, - "##®": 29656, - "##±": 29657, - "##´": 29658, - "##µ": 29659, - "##¶": 29660, - "##·": 29661, - "##º": 29662, - "##»": 29663, - "##¼": 29664, - "##¾": 29665, - "##¿": 29666, - "##æ": 29667, - "##ð": 29668, - "##÷": 29669, - "##þ": 29670, - "##đ": 29671, - "##ħ": 29672, - "##ŋ": 29673, - "##œ": 29674, - "##ƒ": 29675, - "##ɐ": 29676, - "##ɑ": 29677, - "##ɒ": 29678, - "##ɔ": 29679, - "##ɕ": 29680, - "##ə": 29681, - "##ɡ": 29682, - "##ɣ": 29683, - "##ɨ": 29684, - "##ɪ": 29685, - "##ɫ": 29686, - "##ɬ": 29687, - "##ɯ": 29688, - "##ɲ": 29689, - "##ɴ": 29690, - "##ɹ": 29691, - "##ɾ": 29692, - "##ʀ": 29693, - "##ʁ": 29694, - "##ʂ": 29695, - "##ʃ": 29696, - "##ʉ": 29697, - "##ʊ": 29698, - "##ʋ": 29699, - "##ʌ": 29700, - "##ʎ": 29701, - "##ʐ": 29702, - "##ʑ": 29703, - "##ʒ": 29704, - "##ʔ": 29705, - "##ʰ": 29706, - "##ʲ": 29707, - "##ʳ": 29708, - "##ʷ": 29709, - "##ʸ": 29710, - "##ʻ": 29711, - "##ʼ": 29712, - "##ʾ": 29713, - "##ʿ": 29714, - "##ˈ": 29715, - "##ˡ": 29716, - "##ˢ": 29717, - "##ˣ": 29718, - "##ˤ": 29719, - "##β": 29720, - "##γ": 29721, - "##δ": 29722, - "##ε": 29723, - "##ζ": 29724, - "##θ": 29725, - "##κ": 29726, - "##λ": 29727, - "##μ": 29728, - "##ξ": 29729, - "##ο": 29730, - "##π": 29731, - "##ρ": 29732, - "##σ": 29733, - "##τ": 29734, - "##υ": 29735, - "##φ": 29736, - "##χ": 29737, - "##ψ": 29738, - "##ω": 29739, - "##б": 29740, - "##г": 29741, - "##д": 29742, - "##ж": 29743, - "##з": 29744, - "##м": 29745, - "##п": 29746, - "##с": 29747, - "##у": 29748, - "##ф": 29749, - "##х": 29750, - "##ц": 29751, - "##ч": 29752, - "##ш": 29753, - "##щ": 29754, - "##ъ": 29755, - "##э": 29756, - "##ю": 29757, - "##ђ": 29758, - "##є": 29759, - "##і": 29760, - "##ј": 29761, - "##љ": 29762, - "##њ": 29763, - "##ћ": 29764, - "##ӏ": 29765, - "##ա": 29766, - "##բ": 29767, - "##գ": 29768, - "##դ": 29769, - "##ե": 29770, - "##թ": 29771, - "##ի": 29772, - "##լ": 29773, - "##կ": 29774, - "##հ": 29775, - "##մ": 29776, - "##յ": 29777, - "##ն": 29778, - "##ո": 29779, - "##պ": 29780, - "##ս": 29781, - "##վ": 29782, - "##տ": 29783, - "##ր": 29784, - "##ւ": 29785, - "##ք": 29786, - "##־": 29787, - "##א": 29788, - "##ב": 29789, - "##ג": 29790, - "##ד": 29791, - "##ו": 29792, - "##ז": 29793, - "##ח": 29794, - "##ט": 29795, - "##י": 29796, - "##ך": 29797, - "##כ": 29798, - "##ל": 29799, - "##ם": 29800, - "##מ": 29801, - "##ן": 29802, - "##נ": 29803, - "##ס": 29804, - "##ע": 29805, - "##ף": 29806, - "##פ": 29807, - "##ץ": 29808, - "##צ": 29809, - "##ק": 29810, - "##ר": 29811, - "##ש": 29812, - "##ת": 29813, - "##،": 29814, - "##ء": 29815, - "##ب": 29816, - "##ت": 29817, - "##ث": 29818, - "##ج": 29819, - "##ح": 29820, - "##خ": 29821, - "##ذ": 29822, - "##ز": 29823, - "##س": 29824, - "##ش": 29825, - "##ص": 29826, - "##ض": 29827, - "##ط": 29828, - "##ظ": 29829, - "##ع": 29830, - "##غ": 29831, - "##ـ": 29832, - "##ف": 29833, - "##ق": 29834, - "##ك": 29835, - "##و": 29836, - "##ى": 29837, - "##ٹ": 29838, - "##پ": 29839, - "##چ": 29840, - "##ک": 29841, - "##گ": 29842, - "##ں": 29843, - "##ھ": 29844, - "##ہ": 29845, - "##ے": 29846, - "##अ": 29847, - "##आ": 29848, - "##उ": 29849, - "##ए": 29850, - "##क": 29851, - "##ख": 29852, - "##ग": 29853, - "##च": 29854, - "##ज": 29855, - "##ट": 29856, - "##ड": 29857, - "##ण": 29858, - "##त": 29859, - "##थ": 29860, - "##द": 29861, - "##ध": 29862, - "##न": 29863, - "##प": 29864, - "##ब": 29865, - "##भ": 29866, - "##म": 29867, - "##य": 29868, - "##र": 29869, - "##ल": 29870, - "##व": 29871, - "##श": 29872, - "##ष": 29873, - "##स": 29874, - "##ह": 29875, - "##ा": 29876, - "##ि": 29877, - "##ी": 29878, - "##ो": 29879, - "##।": 29880, - "##॥": 29881, - "##ং": 29882, - "##অ": 29883, - "##আ": 29884, - "##ই": 29885, - "##উ": 29886, - "##এ": 29887, - "##ও": 29888, - "##ক": 29889, - "##খ": 29890, - "##গ": 29891, - "##চ": 29892, - "##ছ": 29893, - "##জ": 29894, - "##ট": 29895, - "##ড": 29896, - "##ণ": 29897, - "##ত": 29898, - "##থ": 29899, - "##দ": 29900, - "##ধ": 29901, - "##ন": 29902, - "##প": 29903, - "##ব": 29904, - "##ভ": 29905, - "##ম": 29906, - "##য": 29907, - "##র": 29908, - "##ল": 29909, - "##শ": 29910, - "##ষ": 29911, - "##স": 29912, - "##হ": 29913, - "##া": 29914, - "##ি": 29915, - "##ী": 29916, - "##ে": 29917, - "##க": 29918, - "##ச": 29919, - "##ட": 29920, - "##த": 29921, - "##ந": 29922, - "##ன": 29923, - "##ப": 29924, - "##ம": 29925, - "##ய": 29926, - "##ர": 29927, - "##ல": 29928, - "##ள": 29929, - "##வ": 29930, - "##ா": 29931, - "##ி": 29932, - "##ு": 29933, - "##ே": 29934, - "##ை": 29935, - "##ನ": 29936, - "##ರ": 29937, - "##ಾ": 29938, - "##ක": 29939, - "##ය": 29940, - "##ර": 29941, - "##ල": 29942, - "##ව": 29943, - "##ා": 29944, - "##ก": 29945, - "##ง": 29946, - "##ต": 29947, - "##ท": 29948, - "##น": 29949, - "##พ": 29950, - "##ม": 29951, - "##ย": 29952, - "##ร": 29953, - "##ล": 29954, - "##ว": 29955, - "##ส": 29956, - "##อ": 29957, - "##า": 29958, - "##เ": 29959, - "##་": 29960, - "##།": 29961, - "##ག": 29962, - "##ང": 29963, - "##ད": 29964, - "##ན": 29965, - "##པ": 29966, - "##བ": 29967, - "##མ": 29968, - "##འ": 29969, - "##ར": 29970, - "##ལ": 29971, - "##ས": 29972, - "##မ": 29973, - "##ა": 29974, - "##ბ": 29975, - "##გ": 29976, - "##დ": 29977, - "##ე": 29978, - "##ვ": 29979, - "##თ": 29980, - "##ი": 29981, - "##კ": 29982, - "##ლ": 29983, - "##მ": 29984, - "##ნ": 29985, - "##ო": 29986, - "##რ": 29987, - "##ს": 29988, - "##ტ": 29989, - "##უ": 29990, - "##ᄀ": 29991, - "##ᄂ": 29992, - "##ᄃ": 29993, - "##ᄅ": 29994, - "##ᄆ": 29995, - "##ᄇ": 29996, - "##ᄉ": 29997, - "##ᄊ": 29998, - "##ᄋ": 29999, - "##ᄌ": 30000, - "##ᄎ": 30001, - "##ᄏ": 30002, - "##ᄐ": 30003, - "##ᄑ": 30004, - "##ᄒ": 30005, - "##ᅡ": 30006, - "##ᅢ": 30007, - "##ᅥ": 30008, - "##ᅦ": 30009, - "##ᅧ": 30010, - "##ᅩ": 30011, - "##ᅪ": 30012, - "##ᅭ": 30013, - "##ᅮ": 30014, - "##ᅯ": 30015, - "##ᅲ": 30016, - "##ᅳ": 30017, - "##ᅴ": 30018, - "##ᅵ": 30019, - "##ᆨ": 30020, - "##ᆫ": 30021, - "##ᆯ": 30022, - "##ᆷ": 30023, - "##ᆸ": 30024, - "##ᆼ": 30025, - "##ᴬ": 30026, - "##ᴮ": 30027, - "##ᴰ": 30028, - "##ᴵ": 30029, - "##ᴺ": 30030, - "##ᵀ": 30031, - "##ᵃ": 30032, - "##ᵇ": 30033, - "##ᵈ": 30034, - "##ᵉ": 30035, - "##ᵍ": 30036, - "##ᵏ": 30037, - "##ᵐ": 30038, - "##ᵒ": 30039, - "##ᵖ": 30040, - "##ᵗ": 30041, - "##ᵘ": 30042, - "##ᵣ": 30043, - "##ᵤ": 30044, - "##ᵥ": 30045, - "##ᶜ": 30046, - "##ᶠ": 30047, - "##‐": 30048, - "##‑": 30049, - "##‒": 30050, - "##–": 30051, - "##—": 30052, - "##―": 30053, - "##‖": 30054, - "##‘": 30055, - "##’": 30056, - "##‚": 30057, - "##“": 30058, - "##”": 30059, - "##„": 30060, - "##†": 30061, - "##‡": 30062, - "##•": 30063, - "##…": 30064, - "##‰": 30065, - "##′": 30066, - "##″": 30067, - "##›": 30068, - "##‿": 30069, - "##⁄": 30070, - "##⁰": 30071, - "##ⁱ": 30072, - "##⁴": 30073, - "##⁵": 30074, - "##⁶": 30075, - "##⁷": 30076, - "##⁸": 30077, - "##⁹": 30078, - "##⁻": 30079, - "##ⁿ": 30080, - "##₅": 30081, - "##₆": 30082, - "##₇": 30083, - "##₈": 30084, - "##₉": 30085, - "##₊": 30086, - "##₍": 30087, - "##₎": 30088, - "##ₐ": 30089, - "##ₑ": 30090, - "##ₒ": 30091, - "##ₓ": 30092, - "##ₕ": 30093, - "##ₖ": 30094, - "##ₗ": 30095, - "##ₘ": 30096, - "##ₚ": 30097, - "##ₛ": 30098, - "##ₜ": 30099, - "##₤": 30100, - "##₩": 30101, - "##€": 30102, - "##₱": 30103, - "##₹": 30104, - "##ℓ": 30105, - "##№": 30106, - "##ℝ": 30107, - "##™": 30108, - "##⅓": 30109, - "##⅔": 30110, - "##←": 30111, - "##↑": 30112, - "##→": 30113, - "##↓": 30114, - "##↔": 30115, - "##↦": 30116, - "##⇄": 30117, - "##⇌": 30118, - "##⇒": 30119, - "##∂": 30120, - "##∅": 30121, - "##∆": 30122, - "##∇": 30123, - "##∈": 30124, - "##∗": 30125, - "##∘": 30126, - "##√": 30127, - "##∞": 30128, - "##∧": 30129, - "##∨": 30130, - "##∩": 30131, - "##∪": 30132, - "##≈": 30133, - "##≡": 30134, - "##≤": 30135, - "##≥": 30136, - "##⊂": 30137, - "##⊆": 30138, - "##⊕": 30139, - "##⊗": 30140, - "##⋅": 30141, - "##─": 30142, - "##│": 30143, - "##■": 30144, - "##▪": 30145, - "##●": 30146, - "##★": 30147, - "##☆": 30148, - "##☉": 30149, - "##♠": 30150, - "##♣": 30151, - "##♥": 30152, - "##♦": 30153, - "##♯": 30154, - "##⟨": 30155, - "##⟩": 30156, - "##ⱼ": 30157, - "##⺩": 30158, - "##⺼": 30159, - "##⽥": 30160, - "##、": 30161, - "##。": 30162, - "##〈": 30163, - "##〉": 30164, - "##《": 30165, - "##》": 30166, - "##「": 30167, - "##」": 30168, - "##『": 30169, - "##』": 30170, - "##〜": 30171, - "##あ": 30172, - "##い": 30173, - "##う": 30174, - "##え": 30175, - "##お": 30176, - "##か": 30177, - "##き": 30178, - "##く": 30179, - "##け": 30180, - "##こ": 30181, - "##さ": 30182, - "##し": 30183, - "##す": 30184, - "##せ": 30185, - "##そ": 30186, - "##た": 30187, - "##ち": 30188, - "##っ": 30189, - "##つ": 30190, - "##て": 30191, - "##と": 30192, - "##な": 30193, - "##に": 30194, - "##ぬ": 30195, - "##ね": 30196, - "##の": 30197, - "##は": 30198, - "##ひ": 30199, - "##ふ": 30200, - "##へ": 30201, - "##ほ": 30202, - "##ま": 30203, - "##み": 30204, - "##む": 30205, - "##め": 30206, - "##も": 30207, - "##や": 30208, - "##ゆ": 30209, - "##よ": 30210, - "##ら": 30211, - "##り": 30212, - "##る": 30213, - "##れ": 30214, - "##ろ": 30215, - "##を": 30216, - "##ん": 30217, - "##ァ": 30218, - "##ア": 30219, - "##ィ": 30220, - "##イ": 30221, - "##ウ": 30222, - "##ェ": 30223, - "##エ": 30224, - "##オ": 30225, - "##カ": 30226, - "##キ": 30227, - "##ク": 30228, - "##ケ": 30229, - "##コ": 30230, - "##サ": 30231, - "##シ": 30232, - "##ス": 30233, - "##セ": 30234, - "##タ": 30235, - "##チ": 30236, - "##ッ": 30237, - "##ツ": 30238, - "##テ": 30239, - "##ト": 30240, - "##ナ": 30241, - "##ニ": 30242, - "##ノ": 30243, - "##ハ": 30244, - "##ヒ": 30245, - "##フ": 30246, - "##ヘ": 30247, - "##ホ": 30248, - "##マ": 30249, - "##ミ": 30250, - "##ム": 30251, - "##メ": 30252, - "##モ": 30253, - "##ャ": 30254, - "##ュ": 30255, - "##ョ": 30256, - "##ラ": 30257, - "##リ": 30258, - "##ル": 30259, - "##レ": 30260, - "##ロ": 30261, - "##ワ": 30262, - "##ン": 30263, - "##・": 30264, - "##ー": 30265, - "##一": 30266, - "##三": 30267, - "##上": 30268, - "##下": 30269, - "##不": 30270, - "##世": 30271, - "##中": 30272, - "##主": 30273, - "##久": 30274, - "##之": 30275, - "##也": 30276, - "##事": 30277, - "##二": 30278, - "##五": 30279, - "##井": 30280, - "##京": 30281, - "##人": 30282, - "##亻": 30283, - "##仁": 30284, - "##介": 30285, - "##代": 30286, - "##仮": 30287, - "##伊": 30288, - "##会": 30289, - "##佐": 30290, - "##侍": 30291, - "##保": 30292, - "##信": 30293, - "##健": 30294, - "##元": 30295, - "##光": 30296, - "##八": 30297, - "##公": 30298, - "##内": 30299, - "##出": 30300, - "##分": 30301, - "##前": 30302, - "##劉": 30303, - "##力": 30304, - "##加": 30305, - "##勝": 30306, - "##北": 30307, - "##区": 30308, - "##十": 30309, - "##千": 30310, - "##南": 30311, - "##博": 30312, - "##原": 30313, - "##口": 30314, - "##古": 30315, - "##史": 30316, - "##司": 30317, - "##合": 30318, - "##吉": 30319, - "##同": 30320, - "##名": 30321, - "##和": 30322, - "##囗": 30323, - "##四": 30324, - "##国": 30325, - "##國": 30326, - "##土": 30327, - "##地": 30328, - "##坂": 30329, - "##城": 30330, - "##堂": 30331, - "##場": 30332, - "##士": 30333, - "##夏": 30334, - "##外": 30335, - "##大": 30336, - "##天": 30337, - "##太": 30338, - "##夫": 30339, - "##奈": 30340, - "##女": 30341, - "##子": 30342, - "##学": 30343, - "##宀": 30344, - "##宇": 30345, - "##安": 30346, - "##宗": 30347, - "##定": 30348, - "##宣": 30349, - "##宮": 30350, - "##家": 30351, - "##宿": 30352, - "##寺": 30353, - "##將": 30354, - "##小": 30355, - "##尚": 30356, - "##山": 30357, - "##岡": 30358, - "##島": 30359, - "##崎": 30360, - "##川": 30361, - "##州": 30362, - "##巿": 30363, - "##帝": 30364, - "##平": 30365, - "##年": 30366, - "##幸": 30367, - "##广": 30368, - "##弘": 30369, - "##張": 30370, - "##彳": 30371, - "##後": 30372, - "##御": 30373, - "##德": 30374, - "##心": 30375, - "##忄": 30376, - "##志": 30377, - "##忠": 30378, - "##愛": 30379, - "##成": 30380, - "##我": 30381, - "##戦": 30382, - "##戸": 30383, - "##手": 30384, - "##扌": 30385, - "##政": 30386, - "##文": 30387, - "##新": 30388, - "##方": 30389, - "##日": 30390, - "##明": 30391, - "##星": 30392, - "##春": 30393, - "##昭": 30394, - "##智": 30395, - "##曲": 30396, - "##書": 30397, - "##月": 30398, - "##有": 30399, - "##朝": 30400, - "##木": 30401, - "##本": 30402, - "##李": 30403, - "##村": 30404, - "##東": 30405, - "##松": 30406, - "##林": 30407, - "##森": 30408, - "##楊": 30409, - "##樹": 30410, - "##橋": 30411, - "##歌": 30412, - "##止": 30413, - "##正": 30414, - "##武": 30415, - "##比": 30416, - "##氏": 30417, - "##民": 30418, - "##水": 30419, - "##氵": 30420, - "##氷": 30421, - "##永": 30422, - "##江": 30423, - "##沢": 30424, - "##河": 30425, - "##治": 30426, - "##法": 30427, - "##海": 30428, - "##清": 30429, - "##漢": 30430, - "##瀬": 30431, - "##火": 30432, - "##版": 30433, - "##犬": 30434, - "##王": 30435, - "##生": 30436, - "##田": 30437, - "##男": 30438, - "##疒": 30439, - "##発": 30440, - "##白": 30441, - "##的": 30442, - "##皇": 30443, - "##目": 30444, - "##相": 30445, - "##省": 30446, - "##真": 30447, - "##石": 30448, - "##示": 30449, - "##社": 30450, - "##神": 30451, - "##福": 30452, - "##禾": 30453, - "##秀": 30454, - "##秋": 30455, - "##空": 30456, - "##立": 30457, - "##章": 30458, - "##竹": 30459, - "##糹": 30460, - "##美": 30461, - "##義": 30462, - "##耳": 30463, - "##良": 30464, - "##艹": 30465, - "##花": 30466, - "##英": 30467, - "##華": 30468, - "##葉": 30469, - "##藤": 30470, - "##行": 30471, - "##街": 30472, - "##西": 30473, - "##見": 30474, - "##訁": 30475, - "##語": 30476, - "##谷": 30477, - "##貝": 30478, - "##貴": 30479, - "##車": 30480, - "##軍": 30481, - "##辶": 30482, - "##道": 30483, - "##郎": 30484, - "##郡": 30485, - "##部": 30486, - "##都": 30487, - "##里": 30488, - "##野": 30489, - "##金": 30490, - "##鈴": 30491, - "##镇": 30492, - "##長": 30493, - "##門": 30494, - "##間": 30495, - "##阝": 30496, - "##阿": 30497, - "##陳": 30498, - "##陽": 30499, - "##雄": 30500, - "##青": 30501, - "##面": 30502, - "##風": 30503, - "##食": 30504, - "##香": 30505, - "##馬": 30506, - "##高": 30507, - "##龍": 30508, - "##龸": 30509, - "##fi": 30510, - "##fl": 30511, - "##!": 30512, - "##(": 30513, - "##)": 30514, - "##,": 30515, - "##-": 30516, - "##.": 30517, - "##/": 30518, - "##:": 30519, - "##?": 30520, - "##~": 30521 - } - } -} diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/tokenizer_config.json b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/tokenizer_config.json deleted file mode 100644 index 37fca7477..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/tokenizer_config.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "clean_up_tokenization_spaces": true, - "cls_token": "[CLS]", - "do_basic_tokenize": true, - "do_lower_case": true, - "mask_token": "[MASK]", - "model_max_length": 512, - "never_split": null, - "pad_token": "[PAD]", - "sep_token": "[SEP]", - "strip_accents": null, - "tokenize_chinese_chars": true, - "tokenizer_class": "BertTokenizer", - "unk_token": "[UNK]" -} diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/vocab.txt b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/vocab.txt deleted file mode 100644 index fb140275c..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/models/all-MiniLM-L6-v2/vocab.txt +++ /dev/null @@ -1,30522 +0,0 @@ -[PAD] -[unused0] -[unused1] -[unused2] -[unused3] -[unused4] -[unused5] -[unused6] -[unused7] -[unused8] -[unused9] -[unused10] -[unused11] -[unused12] -[unused13] -[unused14] -[unused15] -[unused16] -[unused17] -[unused18] -[unused19] -[unused20] -[unused21] -[unused22] -[unused23] -[unused24] -[unused25] -[unused26] -[unused27] -[unused28] -[unused29] -[unused30] -[unused31] -[unused32] -[unused33] -[unused34] -[unused35] -[unused36] -[unused37] -[unused38] -[unused39] -[unused40] -[unused41] -[unused42] -[unused43] -[unused44] -[unused45] -[unused46] -[unused47] -[unused48] -[unused49] -[unused50] -[unused51] -[unused52] -[unused53] -[unused54] -[unused55] -[unused56] -[unused57] -[unused58] -[unused59] -[unused60] -[unused61] -[unused62] -[unused63] -[unused64] -[unused65] -[unused66] -[unused67] -[unused68] -[unused69] -[unused70] -[unused71] -[unused72] -[unused73] -[unused74] -[unused75] -[unused76] -[unused77] -[unused78] -[unused79] -[unused80] -[unused81] -[unused82] -[unused83] -[unused84] -[unused85] -[unused86] -[unused87] -[unused88] -[unused89] -[unused90] -[unused91] -[unused92] -[unused93] -[unused94] -[unused95] -[unused96] -[unused97] -[unused98] -[UNK] -[CLS] -[SEP] -[MASK] -[unused99] -[unused100] -[unused101] -[unused102] -[unused103] -[unused104] -[unused105] -[unused106] -[unused107] -[unused108] -[unused109] -[unused110] -[unused111] -[unused112] -[unused113] -[unused114] -[unused115] -[unused116] -[unused117] -[unused118] -[unused119] -[unused120] -[unused121] -[unused122] -[unused123] -[unused124] -[unused125] -[unused126] -[unused127] -[unused128] -[unused129] -[unused130] -[unused131] -[unused132] -[unused133] -[unused134] -[unused135] -[unused136] -[unused137] -[unused138] -[unused139] -[unused140] -[unused141] -[unused142] -[unused143] -[unused144] -[unused145] -[unused146] -[unused147] -[unused148] -[unused149] -[unused150] -[unused151] -[unused152] -[unused153] -[unused154] -[unused155] -[unused156] -[unused157] -[unused158] -[unused159] -[unused160] -[unused161] -[unused162] -[unused163] -[unused164] -[unused165] -[unused166] -[unused167] -[unused168] -[unused169] -[unused170] -[unused171] -[unused172] -[unused173] -[unused174] -[unused175] -[unused176] -[unused177] -[unused178] -[unused179] -[unused180] -[unused181] -[unused182] -[unused183] -[unused184] -[unused185] -[unused186] -[unused187] -[unused188] -[unused189] -[unused190] -[unused191] -[unused192] -[unused193] -[unused194] -[unused195] -[unused196] -[unused197] -[unused198] -[unused199] -[unused200] -[unused201] -[unused202] -[unused203] -[unused204] -[unused205] -[unused206] -[unused207] -[unused208] -[unused209] -[unused210] -[unused211] -[unused212] -[unused213] -[unused214] -[unused215] -[unused216] -[unused217] -[unused218] -[unused219] -[unused220] -[unused221] -[unused222] -[unused223] -[unused224] -[unused225] -[unused226] -[unused227] -[unused228] -[unused229] -[unused230] -[unused231] -[unused232] -[unused233] -[unused234] -[unused235] -[unused236] -[unused237] -[unused238] -[unused239] -[unused240] -[unused241] -[unused242] -[unused243] -[unused244] -[unused245] -[unused246] -[unused247] -[unused248] -[unused249] -[unused250] -[unused251] -[unused252] -[unused253] -[unused254] -[unused255] -[unused256] -[unused257] -[unused258] -[unused259] -[unused260] -[unused261] -[unused262] -[unused263] -[unused264] -[unused265] -[unused266] -[unused267] -[unused268] -[unused269] -[unused270] -[unused271] -[unused272] -[unused273] -[unused274] -[unused275] -[unused276] -[unused277] -[unused278] -[unused279] -[unused280] -[unused281] -[unused282] -[unused283] -[unused284] -[unused285] -[unused286] -[unused287] -[unused288] -[unused289] -[unused290] -[unused291] -[unused292] -[unused293] -[unused294] -[unused295] -[unused296] -[unused297] -[unused298] -[unused299] -[unused300] -[unused301] -[unused302] -[unused303] -[unused304] -[unused305] -[unused306] -[unused307] -[unused308] -[unused309] -[unused310] -[unused311] -[unused312] -[unused313] -[unused314] -[unused315] -[unused316] -[unused317] -[unused318] -[unused319] -[unused320] -[unused321] -[unused322] -[unused323] -[unused324] -[unused325] -[unused326] -[unused327] -[unused328] -[unused329] -[unused330] -[unused331] -[unused332] -[unused333] -[unused334] -[unused335] -[unused336] -[unused337] -[unused338] -[unused339] -[unused340] -[unused341] -[unused342] -[unused343] -[unused344] -[unused345] -[unused346] -[unused347] -[unused348] -[unused349] -[unused350] -[unused351] -[unused352] -[unused353] -[unused354] -[unused355] -[unused356] -[unused357] -[unused358] -[unused359] -[unused360] -[unused361] -[unused362] -[unused363] -[unused364] -[unused365] -[unused366] -[unused367] -[unused368] -[unused369] -[unused370] -[unused371] -[unused372] -[unused373] -[unused374] -[unused375] -[unused376] -[unused377] -[unused378] -[unused379] -[unused380] -[unused381] -[unused382] -[unused383] -[unused384] -[unused385] -[unused386] -[unused387] -[unused388] -[unused389] -[unused390] -[unused391] -[unused392] -[unused393] -[unused394] -[unused395] -[unused396] -[unused397] -[unused398] -[unused399] -[unused400] -[unused401] -[unused402] -[unused403] -[unused404] -[unused405] -[unused406] -[unused407] -[unused408] -[unused409] -[unused410] -[unused411] -[unused412] -[unused413] -[unused414] -[unused415] -[unused416] -[unused417] -[unused418] -[unused419] -[unused420] -[unused421] -[unused422] -[unused423] -[unused424] -[unused425] -[unused426] -[unused427] -[unused428] -[unused429] -[unused430] -[unused431] -[unused432] -[unused433] -[unused434] -[unused435] -[unused436] -[unused437] -[unused438] -[unused439] -[unused440] -[unused441] -[unused442] -[unused443] -[unused444] -[unused445] -[unused446] -[unused447] -[unused448] -[unused449] -[unused450] -[unused451] -[unused452] -[unused453] -[unused454] -[unused455] -[unused456] -[unused457] -[unused458] -[unused459] -[unused460] -[unused461] -[unused462] -[unused463] -[unused464] -[unused465] -[unused466] -[unused467] -[unused468] -[unused469] -[unused470] -[unused471] -[unused472] -[unused473] -[unused474] -[unused475] -[unused476] -[unused477] -[unused478] -[unused479] -[unused480] -[unused481] -[unused482] -[unused483] -[unused484] -[unused485] -[unused486] -[unused487] -[unused488] -[unused489] -[unused490] -[unused491] -[unused492] -[unused493] -[unused494] -[unused495] -[unused496] -[unused497] -[unused498] -[unused499] -[unused500] -[unused501] -[unused502] -[unused503] -[unused504] -[unused505] -[unused506] -[unused507] -[unused508] -[unused509] -[unused510] -[unused511] -[unused512] -[unused513] -[unused514] -[unused515] -[unused516] -[unused517] -[unused518] -[unused519] -[unused520] -[unused521] -[unused522] -[unused523] -[unused524] -[unused525] -[unused526] -[unused527] -[unused528] -[unused529] -[unused530] -[unused531] -[unused532] -[unused533] -[unused534] -[unused535] -[unused536] -[unused537] -[unused538] -[unused539] -[unused540] -[unused541] -[unused542] -[unused543] -[unused544] -[unused545] -[unused546] -[unused547] -[unused548] -[unused549] -[unused550] -[unused551] -[unused552] -[unused553] -[unused554] -[unused555] -[unused556] -[unused557] -[unused558] -[unused559] -[unused560] -[unused561] -[unused562] -[unused563] -[unused564] -[unused565] -[unused566] -[unused567] -[unused568] -[unused569] -[unused570] -[unused571] -[unused572] -[unused573] -[unused574] -[unused575] -[unused576] -[unused577] -[unused578] -[unused579] -[unused580] -[unused581] -[unused582] -[unused583] -[unused584] -[unused585] -[unused586] -[unused587] -[unused588] -[unused589] -[unused590] -[unused591] -[unused592] -[unused593] -[unused594] -[unused595] -[unused596] -[unused597] -[unused598] -[unused599] -[unused600] -[unused601] -[unused602] -[unused603] -[unused604] -[unused605] -[unused606] -[unused607] -[unused608] -[unused609] -[unused610] -[unused611] -[unused612] -[unused613] -[unused614] -[unused615] -[unused616] -[unused617] -[unused618] -[unused619] -[unused620] -[unused621] -[unused622] -[unused623] -[unused624] -[unused625] -[unused626] -[unused627] -[unused628] -[unused629] -[unused630] -[unused631] -[unused632] -[unused633] -[unused634] -[unused635] -[unused636] -[unused637] -[unused638] -[unused639] -[unused640] -[unused641] -[unused642] -[unused643] -[unused644] -[unused645] -[unused646] -[unused647] -[unused648] -[unused649] -[unused650] -[unused651] -[unused652] -[unused653] -[unused654] -[unused655] -[unused656] -[unused657] -[unused658] -[unused659] -[unused660] -[unused661] -[unused662] -[unused663] -[unused664] -[unused665] -[unused666] -[unused667] -[unused668] -[unused669] -[unused670] -[unused671] -[unused672] -[unused673] -[unused674] -[unused675] -[unused676] -[unused677] -[unused678] -[unused679] -[unused680] -[unused681] -[unused682] -[unused683] -[unused684] -[unused685] -[unused686] -[unused687] -[unused688] -[unused689] -[unused690] -[unused691] -[unused692] -[unused693] -[unused694] -[unused695] -[unused696] -[unused697] -[unused698] -[unused699] -[unused700] -[unused701] -[unused702] -[unused703] -[unused704] -[unused705] -[unused706] -[unused707] -[unused708] -[unused709] -[unused710] -[unused711] -[unused712] -[unused713] -[unused714] -[unused715] -[unused716] -[unused717] -[unused718] -[unused719] -[unused720] -[unused721] -[unused722] -[unused723] -[unused724] -[unused725] -[unused726] -[unused727] -[unused728] -[unused729] -[unused730] -[unused731] -[unused732] -[unused733] -[unused734] -[unused735] -[unused736] -[unused737] -[unused738] -[unused739] -[unused740] -[unused741] -[unused742] -[unused743] -[unused744] -[unused745] -[unused746] -[unused747] -[unused748] -[unused749] -[unused750] -[unused751] -[unused752] -[unused753] -[unused754] -[unused755] -[unused756] -[unused757] -[unused758] -[unused759] -[unused760] -[unused761] -[unused762] -[unused763] -[unused764] -[unused765] -[unused766] -[unused767] -[unused768] -[unused769] -[unused770] -[unused771] -[unused772] -[unused773] -[unused774] -[unused775] -[unused776] -[unused777] -[unused778] -[unused779] -[unused780] -[unused781] -[unused782] -[unused783] -[unused784] -[unused785] -[unused786] -[unused787] -[unused788] -[unused789] -[unused790] -[unused791] -[unused792] -[unused793] -[unused794] -[unused795] -[unused796] -[unused797] -[unused798] -[unused799] -[unused800] -[unused801] -[unused802] -[unused803] -[unused804] -[unused805] -[unused806] -[unused807] -[unused808] -[unused809] -[unused810] -[unused811] -[unused812] -[unused813] -[unused814] -[unused815] -[unused816] -[unused817] -[unused818] -[unused819] -[unused820] -[unused821] -[unused822] -[unused823] -[unused824] -[unused825] -[unused826] -[unused827] -[unused828] -[unused829] -[unused830] -[unused831] -[unused832] -[unused833] -[unused834] -[unused835] -[unused836] -[unused837] -[unused838] -[unused839] -[unused840] -[unused841] -[unused842] -[unused843] -[unused844] -[unused845] -[unused846] -[unused847] -[unused848] -[unused849] -[unused850] -[unused851] -[unused852] -[unused853] -[unused854] -[unused855] -[unused856] -[unused857] -[unused858] -[unused859] -[unused860] -[unused861] -[unused862] -[unused863] -[unused864] -[unused865] -[unused866] -[unused867] -[unused868] -[unused869] -[unused870] -[unused871] -[unused872] -[unused873] -[unused874] -[unused875] -[unused876] -[unused877] -[unused878] -[unused879] -[unused880] -[unused881] -[unused882] -[unused883] -[unused884] -[unused885] -[unused886] -[unused887] -[unused888] -[unused889] -[unused890] -[unused891] -[unused892] -[unused893] -[unused894] -[unused895] -[unused896] -[unused897] -[unused898] -[unused899] -[unused900] -[unused901] -[unused902] -[unused903] -[unused904] -[unused905] -[unused906] -[unused907] -[unused908] -[unused909] -[unused910] -[unused911] -[unused912] -[unused913] -[unused914] -[unused915] -[unused916] -[unused917] -[unused918] -[unused919] -[unused920] -[unused921] -[unused922] -[unused923] -[unused924] -[unused925] -[unused926] -[unused927] -[unused928] -[unused929] -[unused930] -[unused931] -[unused932] -[unused933] -[unused934] -[unused935] -[unused936] -[unused937] -[unused938] -[unused939] -[unused940] -[unused941] -[unused942] -[unused943] -[unused944] -[unused945] -[unused946] -[unused947] -[unused948] -[unused949] -[unused950] -[unused951] -[unused952] -[unused953] -[unused954] -[unused955] -[unused956] -[unused957] -[unused958] -[unused959] -[unused960] -[unused961] -[unused962] -[unused963] -[unused964] -[unused965] -[unused966] -[unused967] -[unused968] -[unused969] -[unused970] -[unused971] -[unused972] -[unused973] -[unused974] -[unused975] -[unused976] -[unused977] -[unused978] -[unused979] -[unused980] -[unused981] -[unused982] -[unused983] -[unused984] -[unused985] -[unused986] -[unused987] -[unused988] -[unused989] -[unused990] -[unused991] -[unused992] -[unused993] -! -" -# -$ -% -& -' -( -) -* -+ -, -- -. -/ -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -: -; -< -= -> -? -@ -[ -\ -] -^ -_ -` -a -b -c -d -e -f -g -h -i -j -k -l -m -n -o -p -q -r -s -t -u -v -w -x -y -z -{ -| -} -~ -¡ -¢ -£ -¤ -¥ -¦ -§ -¨ -© -ª -« -¬ -® -° -± -² -³ -´ -µ -¶ -· -¹ -º -» -¼ -½ -¾ -¿ -× -ß -æ -ð -÷ -ø -þ -đ -ħ -ı -ł -ŋ -œ -ƒ -ɐ -ɑ -ɒ -ɔ -ɕ -ə -ɛ -ɡ -ɣ -ɨ -ɪ -ɫ -ɬ -ɯ -ɲ -ɴ -ɹ -ɾ -ʀ -ʁ -ʂ -ʃ -ʉ -ʊ -ʋ -ʌ -ʎ -ʐ -ʑ -ʒ -ʔ -ʰ -ʲ -ʳ -ʷ -ʸ -ʻ -ʼ -ʾ -ʿ -ˈ -ː -ˡ -ˢ -ˣ -ˤ -α -β -γ -δ -ε -ζ -η -θ -ι -κ -λ -μ -ν -ξ -ο -π -ρ -ς -σ -τ -υ -φ -χ -ψ -ω -а -б -в -г -д -е -ж -з -и -к -л -м -н -о -п -р -с -т -у -ф -х -ц -ч -ш -щ -ъ -ы -ь -э -ю -я -ђ -є -і -ј -љ -њ -ћ -ӏ -ա -բ -գ -դ -ե -թ -ի -լ -կ -հ -մ -յ -ն -ո -պ -ս -վ -տ -ր -ւ -ք -־ -א -ב -ג -ד -ה -ו -ז -ח -ט -י -ך -כ -ל -ם -מ -ן -נ -ס -ע -ף -פ -ץ -צ -ק -ר -ש -ת -، -ء -ا -ب -ة -ت -ث -ج -ح -خ -د -ذ -ر -ز -س -ش -ص -ض -ط -ظ -ع -غ -ـ -ف -ق -ك -ل -م -ن -ه -و -ى -ي -ٹ -پ -چ -ک -گ -ں -ھ -ہ -ی -ے -अ -आ -उ -ए -क -ख -ग -च -ज -ट -ड -ण -त -थ -द -ध -न -प -ब -भ -म -य -र -ल -व -श -ष -स -ह -ा -ि -ी -ो -। -॥ -ং -অ -আ -ই -উ -এ -ও -ক -খ -গ -চ -ছ -জ -ট -ড -ণ -ত -থ -দ -ধ -ন -প -ব -ভ -ম -য -র -ল -শ -ষ -স -হ -া -ি -ী -ে -க -ச -ட -த -ந -ன -ப -ம -ய -ர -ல -ள -வ -ா -ி -ு -ே -ை -ನ -ರ -ಾ -ක -ය -ර -ල -ව -ා -ก -ง -ต -ท -น -พ -ม -ย -ร -ล -ว -ส -อ -า -เ -་ -། -ག -ང -ད -ན -པ -བ -མ -འ -ར -ལ -ས -မ -ა -ბ -გ -დ -ე -ვ -თ -ი -კ -ლ -მ -ნ -ო -რ -ს -ტ -უ -ᄀ -ᄂ -ᄃ -ᄅ -ᄆ -ᄇ -ᄉ -ᄊ -ᄋ -ᄌ -ᄎ -ᄏ -ᄐ -ᄑ -ᄒ -ᅡ -ᅢ -ᅥ -ᅦ -ᅧ -ᅩ -ᅪ -ᅭ -ᅮ -ᅯ -ᅲ -ᅳ -ᅴ -ᅵ -ᆨ -ᆫ -ᆯ -ᆷ -ᆸ -ᆼ -ᴬ -ᴮ -ᴰ -ᴵ -ᴺ -ᵀ -ᵃ -ᵇ -ᵈ -ᵉ -ᵍ -ᵏ -ᵐ -ᵒ -ᵖ -ᵗ -ᵘ -ᵢ -ᵣ -ᵤ -ᵥ -ᶜ -ᶠ -‐ -‑ -‒ -– -— -― -‖ -‘ -’ -‚ -“ -” -„ -† -‡ -• -… -‰ -′ -″ -› -‿ -⁄ -⁰ -ⁱ -⁴ -⁵ -⁶ -⁷ -⁸ -⁹ -⁺ -⁻ -ⁿ -₀ -₁ -₂ -₃ -₄ -₅ -₆ -₇ -₈ -₉ -₊ -₍ -₎ -ₐ -ₑ -ₒ -ₓ -ₕ -ₖ -ₗ -ₘ -ₙ -ₚ -ₛ -ₜ -₤ -₩ -€ -₱ -₹ -ℓ -№ -ℝ -™ -⅓ -⅔ -← -↑ -→ -↓ -↔ -↦ -⇄ -⇌ -⇒ -∂ -∅ -∆ -∇ -∈ -− -∗ -∘ -√ -∞ -∧ -∨ -∩ -∪ -≈ -≡ -≤ -≥ -⊂ -⊆ -⊕ -⊗ -⋅ -─ -│ -■ -▪ -● -★ -☆ -☉ -♠ -♣ -♥ -♦ -♭ -♯ -⟨ -⟩ -ⱼ -⺩ -⺼ -⽥ -、 -。 -〈 -〉 -《 -》 -「 -」 -『 -』 -〜 -あ -い -う -え -お -か -き -く -け -こ -さ -し -す -せ -そ -た -ち -っ -つ -て -と -な -に -ぬ -ね -の -は -ひ -ふ -へ -ほ -ま -み -む -め -も -や -ゆ -よ -ら -り -る -れ -ろ -を -ん -ァ -ア -ィ -イ -ウ -ェ -エ -オ -カ -キ -ク -ケ -コ -サ -シ -ス -セ -タ -チ -ッ -ツ -テ -ト -ナ -ニ -ノ -ハ -ヒ -フ -ヘ -ホ -マ -ミ -ム -メ -モ -ャ -ュ -ョ -ラ -リ -ル -レ -ロ -ワ -ン -・ -ー -一 -三 -上 -下 -不 -世 -中 -主 -久 -之 -也 -事 -二 -五 -井 -京 -人 -亻 -仁 -介 -代 -仮 -伊 -会 -佐 -侍 -保 -信 -健 -元 -光 -八 -公 -内 -出 -分 -前 -劉 -力 -加 -勝 -北 -区 -十 -千 -南 -博 -原 -口 -古 -史 -司 -合 -吉 -同 -名 -和 -囗 -四 -国 -國 -土 -地 -坂 -城 -堂 -場 -士 -夏 -外 -大 -天 -太 -夫 -奈 -女 -子 -学 -宀 -宇 -安 -宗 -定 -宣 -宮 -家 -宿 -寺 -將 -小 -尚 -山 -岡 -島 -崎 -川 -州 -巿 -帝 -平 -年 -幸 -广 -弘 -張 -彳 -後 -御 -德 -心 -忄 -志 -忠 -愛 -成 -我 -戦 -戸 -手 -扌 -政 -文 -新 -方 -日 -明 -星 -春 -昭 -智 -曲 -書 -月 -有 -朝 -木 -本 -李 -村 -東 -松 -林 -森 -楊 -樹 -橋 -歌 -止 -正 -武 -比 -氏 -民 -水 -氵 -氷 -永 -江 -沢 -河 -治 -法 -海 -清 -漢 -瀬 -火 -版 -犬 -王 -生 -田 -男 -疒 -発 -白 -的 -皇 -目 -相 -省 -真 -石 -示 -社 -神 -福 -禾 -秀 -秋 -空 -立 -章 -竹 -糹 -美 -義 -耳 -良 -艹 -花 -英 -華 -葉 -藤 -行 -街 -西 -見 -訁 -語 -谷 -貝 -貴 -車 -軍 -辶 -道 -郎 -郡 -部 -都 -里 -野 -金 -鈴 -镇 -長 -門 -間 -阝 -阿 -陳 -陽 -雄 -青 -面 -風 -食 -香 -馬 -高 -龍 -龸 -fi -fl -! -( -) -, -- -. -/ -: -? -~ -the -of -and -in -to -was -he -is -as -for -on -with -that -it -his -by -at -from -her -##s -she -you -had -an -were -but -be -this -are -not -my -they -one -which -or -have -him -me -first -all -also -their -has -up -who -out -been -when -after -there -into -new -two -its -##a -time -would -no -what -about -said -we -over -then -other -so -more -##e -can -if -like -back -them -only -some -could -##i -where -just -##ing -during -before -##n -do -##o -made -school -through -than -now -years -most -world -may -between -down -well -three -##d -year -while -will -##ed -##r -##y -later -##t -city -under -around -did -such -being -used -state -people -part -know -against -your -many -second -university -both -national -##er -these -don -known -off -way -until -re -how -even -get -head -... -didn -##ly -team -american -because -de -##l -born -united -film -since -still -long -work -south -us -became -any -high -again -day -family -see -right -man -eyes -house -season -war -states -including -took -life -north -same -each -called -name -much -place -however -go -four -group -another -found -won -area -here -going -10 -away -series -left -home -music -best -make -hand -number -company -several -never -last -john -000 -very -album -take -end -good -too -following -released -game -played -little -began -district -##m -old -want -those -side -held -own -early -county -ll -league -use -west -##u -face -think -##es -2010 -government -##h -march -came -small -general -town -june -##on -line -based -something -##k -september -thought -looked -along -international -2011 -air -july -club -went -january -october -our -august -april -york -12 -few -2012 -2008 -east -show -member -college -2009 -father -public -##us -come -men -five -set -station -church -##c -next -former -november -room -party -located -december -2013 -age -got -2007 -##g -system -let -love -2006 -though -every -2014 -look -song -water -century -without -body -black -night -within -great -women -single -ve -building -large -population -river -named -band -white -started -##an -once -15 -20 -should -18 -2015 -service -top -built -british -open -death -king -moved -local -times -children -february -book -why -11 -door -need -president -order -final -road -wasn -although -due -major -died -village -third -knew -2016 -asked -turned -st -wanted -say -##p -together -received -main -son -served -different -##en -behind -himself -felt -members -power -football -law -voice -play -##in -near -park -history -30 -having -2005 -16 -##man -saw -mother -##al -army -point -front -help -english -street -art -late -hands -games -award -##ia -young -14 -put -published -country -division -across -told -13 -often -ever -french -london -center -six -red -2017 -led -days -include -light -25 -find -tell -among -species -really -according -central -half -2004 -form -original -gave -office -making -enough -lost -full -opened -must -included -live -given -german -player -run -business -woman -community -cup -might -million -land -2000 -court -development -17 -short -round -ii -km -seen -class -story -always -become -sure -research -almost -director -council -la -##2 -career -things -using -island -##z -couldn -car -##is -24 -close -force -##1 -better -free -support -control -field -students -2003 -education -married -##b -nothing -worked -others -record -big -inside -level -anything -continued -give -james -##3 -military -established -non -returned -feel -does -title -written -thing -feet -william -far -co -association -hard -already -2002 -##ra -championship -human -western -100 -##na -department -hall -role -various -production -21 -19 -heart -2001 -living -fire -version -##ers -##f -television -royal -##4 -produced -working -act -case -society -region -present -radio -period -looking -least -total -keep -england -wife -program -per -brother -mind -special -22 -##le -am -works -soon -##6 -political -george -services -taken -created -##7 -further -able -reached -david -union -joined -upon -done -important -social -information -either -##ic -##x -appeared -position -ground -lead -rock -dark -election -23 -board -france -hair -course -arms -site -police -girl -instead -real -sound -##v -words -moment -##te -someone -##8 -summer -project -announced -san -less -wrote -past -followed -##5 -blue -founded -al -finally -india -taking -records -america -##ne -1999 -design -considered -northern -god -stop -battle -toward -european -outside -described -track -today -playing -language -28 -call -26 -heard -professional -low -australia -miles -california -win -yet -green -##ie -trying -blood -##ton -southern -science -maybe -everything -match -square -27 -mouth -video -race -recorded -leave -above -##9 -daughter -points -space -1998 -museum -change -middle -common -##0 -move -tv -post -##ta -lake -seven -tried -elected -closed -ten -paul -minister -##th -months -start -chief -return -canada -person -sea -release -similar -modern -brought -rest -hit -formed -mr -##la -1997 -floor -event -doing -thomas -1996 -robert -care -killed -training -star -week -needed -turn -finished -railway -rather -news -health -sent -example -ran -term -michael -coming -currently -yes -forces -despite -gold -areas -50 -stage -fact -29 -dead -says -popular -2018 -originally -germany -probably -developed -result -pulled -friend -stood -money -running -mi -signed -word -songs -child -eventually -met -tour -average -teams -minutes -festival -current -deep -kind -1995 -decided -usually -eastern -seemed -##ness -episode -bed -added -table -indian -private -charles -route -available -idea -throughout -centre -addition -appointed -style -1994 -books -eight -construction -press -mean -wall -friends -remained -schools -study -##ch -##um -institute -oh -chinese -sometimes -events -possible -1992 -australian -type -brown -forward -talk -process -food -debut -seat -performance -committee -features -character -arts -herself -else -lot -strong -russian -range -hours -peter -arm -##da -morning -dr -sold -##ry -quickly -directed -1993 -guitar -china -##w -31 -list -##ma -performed -media -uk -players -smile -##rs -myself -40 -placed -coach -province -towards -wouldn -leading -whole -boy -official -designed -grand -census -##el -europe -attack -japanese -henry -1991 -##re -##os -cross -getting -alone -action -lower -network -wide -washington -japan -1990 -hospital -believe -changed -sister -##ar -hold -gone -sir -hadn -ship -##ka -studies -academy -shot -rights -below -base -bad -involved -kept -largest -##ist -bank -future -especially -beginning -mark -movement -section -female -magazine -plan -professor -lord -longer -##ian -sat -walked -hill -actually -civil -energy -model -families -size -thus -aircraft -completed -includes -data -captain -##or -fight -vocals -featured -richard -bridge -fourth -1989 -officer -stone -hear -##ism -means -medical -groups -management -self -lips -competition -entire -lived -technology -leaving -federal -tournament -bit -passed -hot -independent -awards -kingdom -mary -spent -fine -doesn -reported -##ling -jack -fall -raised -itself -stay -true -studio -1988 -sports -replaced -paris -systems -saint -leader -theatre -whose -market -capital -parents -spanish -canadian -earth -##ity -cut -degree -writing -bay -christian -awarded -natural -higher -bill -##as -coast -provided -previous -senior -ft -valley -organization -stopped -onto -countries -parts -conference -queen -security -interest -saying -allowed -master -earlier -phone -matter -smith -winning -try -happened -moving -campaign -los -##ley -breath -nearly -mid -1987 -certain -girls -date -italian -african -standing -fell -artist -##ted -shows -deal -mine -industry -1986 -##ng -everyone -republic -provide -collection -library -student -##ville -primary -owned -older -via -heavy -1st -makes -##able -attention -anyone -africa -##ri -stated -length -ended -fingers -command -staff -skin -foreign -opening -governor -okay -medal -kill -sun -cover -job -1985 -introduced -chest -hell -feeling -##ies -success -meet -reason -standard -meeting -novel -1984 -trade -source -buildings -##land -rose -guy -goal -##ur -chapter -native -husband -previously -unit -limited -entered -weeks -producer -operations -mountain -takes -covered -forced -related -roman -complete -successful -key -texas -cold -##ya -channel -1980 -traditional -films -dance -clear -approximately -500 -nine -van -prince -question -active -tracks -ireland -regional -silver -author -personal -sense -operation -##ine -economic -1983 -holding -twenty -isbn -additional -speed -hour -edition -regular -historic -places -whom -shook -movie -km² -secretary -prior -report -chicago -read -foundation -view -engine -scored -1982 -units -ask -airport -property -ready -immediately -lady -month -listed -contract -##de -manager -themselves -lines -##ki -navy -writer -meant -##ts -runs -##ro -practice -championships -singer -glass -commission -required -forest -starting -culture -generally -giving -access -attended -test -couple -stand -catholic -martin -caught -executive -##less -eye -##ey -thinking -chair -quite -shoulder -1979 -hope -decision -plays -defeated -municipality -whether -structure -offered -slowly -pain -ice -direction -##ion -paper -mission -1981 -mostly -200 -noted -individual -managed -nature -lives -plant -##ha -helped -except -studied -computer -figure -relationship -issue -significant -loss -die -smiled -gun -ago -highest -1972 -##am -male -bring -goals -mexico -problem -distance -commercial -completely -location -annual -famous -drive -1976 -neck -1978 -surface -caused -italy -understand -greek -highway -wrong -hotel -comes -appearance -joseph -double -issues -musical -companies -castle -income -review -assembly -bass -initially -parliament -artists -experience -1974 -particular -walk -foot -engineering -talking -window -dropped -##ter -miss -baby -boys -break -1975 -stars -edge -remember -policy -carried -train -stadium -bar -sex -angeles -evidence -##ge -becoming -assistant -soviet -1977 -upper -step -wing -1970 -youth -financial -reach -##ll -actor -numerous -##se -##st -nodded -arrived -##ation -minute -##nt -believed -sorry -complex -beautiful -victory -associated -temple -1968 -1973 -chance -perhaps -metal -##son -1945 -bishop -##et -lee -launched -particularly -tree -le -retired -subject -prize -contains -yeah -theory -empire -##ce -suddenly -waiting -trust -recording -##to -happy -terms -camp -champion -1971 -religious -pass -zealand -names -2nd -port -ancient -tom -corner -represented -watch -legal -anti -justice -cause -watched -brothers -45 -material -changes -simply -response -louis -fast -##ting -answer -60 -historical -1969 -stories -straight -create -feature -increased -rate -administration -virginia -el -activities -cultural -overall -winner -programs -basketball -legs -guard -beyond -cast -doctor -mm -flight -results -remains -cost -effect -winter -##ble -larger -islands -problems -chairman -grew -commander -isn -1967 -pay -failed -selected -hurt -fort -box -regiment -majority -journal -35 -edward -plans -##ke -##ni -shown -pretty -irish -characters -directly -scene -likely -operated -allow -spring -##j -junior -matches -looks -mike -houses -fellow -##tion -beach -marriage -##ham -##ive -rules -oil -65 -florida -expected -nearby -congress -sam -peace -recent -iii -wait -subsequently -cell -##do -variety -serving -agreed -please -poor -joe -pacific -attempt -wood -democratic -piece -prime -##ca -rural -mile -touch -appears -township -1964 -1966 -soldiers -##men -##ized -1965 -pennsylvania -closer -fighting -claimed -score -jones -physical -editor -##ous -filled -genus -specific -sitting -super -mom -##va -therefore -supported -status -fear -cases -store -meaning -wales -minor -spain -tower -focus -vice -frank -follow -parish -separate -golden -horse -fifth -remaining -branch -32 -presented -stared -##id -uses -secret -forms -##co -baseball -exactly -##ck -choice -note -discovered -travel -composed -truth -russia -ball -color -kiss -dad -wind -continue -ring -referred -numbers -digital -greater -##ns -metres -slightly -direct -increase -1960 -responsible -crew -rule -trees -troops -##no -broke -goes -individuals -hundred -weight -creek -sleep -memory -defense -provides -ordered -code -value -jewish -windows -1944 -safe -judge -whatever -corps -realized -growing -pre -##ga -cities -alexander -gaze -lies -spread -scott -letter -showed -situation -mayor -transport -watching -workers -extended -##li -expression -normal -##ment -chart -multiple -border -##ba -host -##ner -daily -mrs -walls -piano -##ko -heat -cannot -##ate -earned -products -drama -era -authority -seasons -join -grade -##io -sign -difficult -machine -1963 -territory -mainly -##wood -stations -squadron -1962 -stepped -iron -19th -##led -serve -appear -sky -speak -broken -charge -knowledge -kilometres -removed -ships -article -campus -simple -##ty -pushed -britain -##ve -leaves -recently -cd -soft -boston -latter -easy -acquired -poland -##sa -quality -officers -presence -planned -nations -mass -broadcast -jean -share -image -influence -wild -offer -emperor -electric -reading -headed -ability -promoted -yellow -ministry -1942 -throat -smaller -politician -##by -latin -spoke -cars -williams -males -lack -pop -80 -##ier -acting -seeing -consists -##ti -estate -1961 -pressure -johnson -newspaper -jr -chris -olympics -online -conditions -beat -elements -walking -vote -##field -needs -carolina -text -featuring -global -block -shirt -levels -francisco -purpose -females -et -dutch -duke -ahead -gas -twice -safety -serious -turning -highly -lieutenant -firm -maria -amount -mixed -daniel -proposed -perfect -agreement -affairs -3rd -seconds -contemporary -paid -1943 -prison -save -kitchen -label -administrative -intended -constructed -academic -nice -teacher -races -1956 -formerly -corporation -ben -nation -issued -shut -1958 -drums -housing -victoria -seems -opera -1959 -graduated -function -von -mentioned -picked -build -recognized -shortly -protection -picture -notable -exchange -elections -1980s -loved -percent -racing -fish -elizabeth -garden -volume -hockey -1941 -beside -settled -##ford -1940 -competed -replied -drew -1948 -actress -marine -scotland -steel -glanced -farm -steve -1957 -risk -tonight -positive -magic -singles -effects -gray -screen -dog -##ja -residents -bus -sides -none -secondary -literature -polish -destroyed -flying -founder -households -1939 -lay -reserve -usa -gallery -##ler -1946 -industrial -younger -approach -appearances -urban -ones -1950 -finish -avenue -powerful -fully -growth -page -honor -jersey -projects -advanced -revealed -basic -90 -infantry -pair -equipment -visit -33 -evening -search -grant -effort -solo -treatment -buried -republican -primarily -bottom -owner -1970s -israel -gives -jim -dream -bob -remain -spot -70 -notes -produce -champions -contact -ed -soul -accepted -ways -del -##ally -losing -split -price -capacity -basis -trial -questions -##ina -1955 -20th -guess -officially -memorial -naval -initial -##ization -whispered -median -engineer -##ful -sydney -##go -columbia -strength -300 -1952 -tears -senate -00 -card -asian -agent -1947 -software -44 -draw -warm -supposed -com -pro -##il -transferred -leaned -##at -candidate -escape -mountains -asia -potential -activity -entertainment -seem -traffic -jackson -murder -36 -slow -product -orchestra -haven -agency -bbc -taught -website -comedy -unable -storm -planning -albums -rugby -environment -scientific -grabbed -protect -##hi -boat -typically -1954 -1953 -damage -principal -divided -dedicated -mount -ohio -##berg -pick -fought -driver -##der -empty -shoulders -sort -thank -berlin -prominent -account -freedom -necessary -efforts -alex -headquarters -follows -alongside -des -simon -andrew -suggested -operating -learning -steps -1949 -sweet -technical -begin -easily -34 -teeth -speaking -settlement -scale -##sh -renamed -ray -max -enemy -semi -joint -compared -##rd -scottish -leadership -analysis -offers -georgia -pieces -captured -animal -deputy -guest -organized -##lin -tony -combined -method -challenge -1960s -huge -wants -battalion -sons -rise -crime -types -facilities -telling -path -1951 -platform -sit -1990s -##lo -tells -assigned -rich -pull -##ot -commonly -alive -##za -letters -concept -conducted -wearing -happen -bought -becomes -holy -gets -ocean -defeat -languages -purchased -coffee -occurred -titled -##q -declared -applied -sciences -concert -sounds -jazz -brain -##me -painting -fleet -tax -nick -##ius -michigan -count -animals -leaders -episodes -##line -content -##den -birth -##it -clubs -64 -palace -critical -refused -fair -leg -laughed -returning -surrounding -participated -formation -lifted -pointed -connected -rome -medicine -laid -taylor -santa -powers -adam -tall -shared -focused -knowing -yards -entrance -falls -##wa -calling -##ad -sources -chosen -beneath -resources -yard -##ite -nominated -silence -zone -defined -##que -gained -thirty -38 -bodies -moon -##ard -adopted -christmas -widely -register -apart -iran -premier -serves -du -unknown -parties -##les -generation -##ff -continues -quick -fields -brigade -quiet -teaching -clothes -impact -weapons -partner -flat -theater -supreme -1938 -37 -relations -##tor -plants -suffered -1936 -wilson -kids -begins -##age -1918 -seats -armed -internet -models -worth -laws -400 -communities -classes -background -knows -thanks -quarter -reaching -humans -carry -killing -format -kong -hong -setting -75 -architecture -disease -railroad -inc -possibly -wish -arthur -thoughts -harry -doors -density -##di -crowd -illinois -stomach -tone -unique -reports -anyway -##ir -liberal -der -vehicle -thick -dry -drug -faced -largely -facility -theme -holds -creation -strange -colonel -##mi -revolution -bell -politics -turns -silent -rail -relief -independence -combat -shape -write -determined -sales -learned -4th -finger -oxford -providing -1937 -heritage -fiction -situated -designated -allowing -distribution -hosted -##est -sight -interview -estimated -reduced -##ria -toronto -footballer -keeping -guys -damn -claim -motion -sport -sixth -stayed -##ze -en -rear -receive -handed -twelve -dress -audience -granted -brazil -##well -spirit -##ated -noticed -etc -olympic -representative -eric -tight -trouble -reviews -drink -vampire -missing -roles -ranked -newly -household -finals -wave -critics -##ee -phase -massachusetts -pilot -unlike -philadelphia -bright -guns -crown -organizations -roof -42 -respectively -clearly -tongue -marked -circle -fox -korea -bronze -brian -expanded -sexual -supply -yourself -inspired -labour -fc -##ah -reference -vision -draft -connection -brand -reasons -1935 -classic -driving -trip -jesus -cells -entry -1920 -neither -trail -claims -atlantic -orders -labor -nose -afraid -identified -intelligence -calls -cancer -attacked -passing -stephen -positions -imperial -grey -jason -39 -sunday -48 -swedish -avoid -extra -uncle -message -covers -allows -surprise -materials -fame -hunter -##ji -1930 -citizens -figures -davis -environmental -confirmed -shit -titles -di -performing -difference -acts -attacks -##ov -existing -votes -opportunity -nor -shop -entirely -trains -opposite -pakistan -##pa -develop -resulted -representatives -actions -reality -pressed -##ish -barely -wine -conversation -faculty -northwest -ends -documentary -nuclear -stock -grace -sets -eat -alternative -##ps -bag -resulting -creating -surprised -cemetery -1919 -drop -finding -sarah -cricket -streets -tradition -ride -1933 -exhibition -target -ear -explained -rain -composer -injury -apartment -municipal -educational -occupied -netherlands -clean -billion -constitution -learn -1914 -maximum -classical -francis -lose -opposition -jose -ontario -bear -core -hills -rolled -ending -drawn -permanent -fun -##tes -##lla -lewis -sites -chamber -ryan -##way -scoring -height -1934 -##house -lyrics -staring -55 -officials -1917 -snow -oldest -##tic -orange -##ger -qualified -interior -apparently -succeeded -thousand -dinner -lights -existence -fans -heavily -41 -greatest -conservative -send -bowl -plus -enter -catch -##un -economy -duty -1929 -speech -authorities -princess -performances -versions -shall -graduate -pictures -effective -remembered -poetry -desk -crossed -starring -starts -passenger -sharp -##ant -acres -ass -weather -falling -rank -fund -supporting -check -adult -publishing -heads -cm -southeast -lane -##burg -application -bc -##ura -les -condition -transfer -prevent -display -ex -regions -earl -federation -cool -relatively -answered -besides -1928 -obtained -portion -##town -mix -##ding -reaction -liked -dean -express -peak -1932 -##tte -counter -religion -chain -rare -miller -convention -aid -lie -vehicles -mobile -perform -squad -wonder -lying -crazy -sword -##ping -attempted -centuries -weren -philosophy -category -##ize -anna -interested -47 -sweden -wolf -frequently -abandoned -kg -literary -alliance -task -entitled -##ay -threw -promotion -factory -tiny -soccer -visited -matt -fm -achieved -52 -defence -internal -persian -43 -methods -##ging -arrested -otherwise -cambridge -programming -villages -elementary -districts -rooms -criminal -conflict -worry -trained -1931 -attempts -waited -signal -bird -truck -subsequent -programme -##ol -ad -49 -communist -details -faith -sector -patrick -carrying -laugh -##ss -controlled -korean -showing -origin -fuel -evil -1927 -##ent -brief -identity -darkness -address -pool -missed -publication -web -planet -ian -anne -wings -invited -##tt -briefly -standards -kissed -##be -ideas -climate -causing -walter -worse -albert -articles -winners -desire -aged -northeast -dangerous -gate -doubt -1922 -wooden -multi -##ky -poet -rising -funding -46 -communications -communication -violence -copies -prepared -ford -investigation -skills -1924 -pulling -electronic -##ak -##ial -##han -containing -ultimately -offices -singing -understanding -restaurant -tomorrow -fashion -christ -ward -da -pope -stands -5th -flow -studios -aired -commissioned -contained -exist -fresh -americans -##per -wrestling -approved -kid -employed -respect -suit -1925 -angel -asking -increasing -frame -angry -selling -1950s -thin -finds -##nd -temperature -statement -ali -explain -inhabitants -towns -extensive -narrow -51 -jane -flowers -images -promise -somewhere -object -fly -closely -##ls -1912 -bureau -cape -1926 -weekly -presidential -legislative -1921 -##ai -##au -launch -founding -##ny -978 -##ring -artillery -strike -un -institutions -roll -writers -landing -chose -kevin -anymore -pp -##ut -attorney -fit -dan -billboard -receiving -agricultural -breaking -sought -dave -admitted -lands -mexican -##bury -charlie -specifically -hole -iv -howard -credit -moscow -roads -accident -1923 -proved -wear -struck -hey -guards -stuff -slid -expansion -1915 -cat -anthony -##kin -melbourne -opposed -sub -southwest -architect -failure -plane -1916 -##ron -map -camera -tank -listen -regarding -wet -introduction -metropolitan -link -ep -fighter -inch -grown -gene -anger -fixed -buy -dvd -khan -domestic -worldwide -chapel -mill -functions -examples -##head -developing -1910 -turkey -hits -pocket -antonio -papers -grow -unless -circuit -18th -concerned -attached -journalist -selection -journey -converted -provincial -painted -hearing -aren -bands -negative -aside -wondered -knight -lap -survey -ma -##ow -noise -billy -##ium -shooting -guide -bedroom -priest -resistance -motor -homes -sounded -giant -##mer -150 -scenes -equal -comic -patients -hidden -solid -actual -bringing -afternoon -touched -funds -wedding -consisted -marie -canal -sr -kim -treaty -turkish -recognition -residence -cathedral -broad -knees -incident -shaped -fired -norwegian -handle -cheek -contest -represent -##pe -representing -beauty -##sen -birds -advantage -emergency -wrapped -drawing -notice -pink -broadcasting -##ong -somehow -bachelor -seventh -collected -registered -establishment -alan -assumed -chemical -personnel -roger -retirement -jeff -portuguese -wore -tied -device -threat -progress -advance -##ised -banks -hired -manchester -nfl -teachers -structures -forever -##bo -tennis -helping -saturday -sale -applications -junction -hip -incorporated -neighborhood -dressed -ceremony -##ds -influenced -hers -visual -stairs -decades -inner -kansas -hung -hoped -gain -scheduled -downtown -engaged -austria -clock -norway -certainly -pale -protected -1913 -victor -employees -plate -putting -surrounded -##ists -finishing -blues -tropical -##ries -minnesota -consider -philippines -accept -54 -retrieved -1900 -concern -anderson -properties -institution -gordon -successfully -vietnam -##dy -backing -outstanding -muslim -crossing -folk -producing -usual -demand -occurs -observed -lawyer -educated -##ana -kelly -string -pleasure -budget -items -quietly -colorado -philip -typical -##worth -derived -600 -survived -asks -mental -##ide -56 -jake -jews -distinguished -ltd -1911 -sri -extremely -53 -athletic -loud -thousands -worried -shadow -transportation -horses -weapon -arena -importance -users -tim -objects -contributed -dragon -douglas -aware -senator -johnny -jordan -sisters -engines -flag -investment -samuel -shock -capable -clark -row -wheel -refers -session -familiar -biggest -wins -hate -maintained -drove -hamilton -request -expressed -injured -underground -churches -walker -wars -tunnel -passes -stupid -agriculture -softly -cabinet -regarded -joining -indiana -##ea -##ms -push -dates -spend -behavior -woods -protein -gently -chase -morgan -mention -burning -wake -combination -occur -mirror -leads -jimmy -indeed -impossible -singapore -paintings -covering -##nes -soldier -locations -attendance -sell -historian -wisconsin -invasion -argued -painter -diego -changing -egypt -##don -experienced -inches -##ku -missouri -vol -grounds -spoken -switzerland -##gan -reform -rolling -ha -forget -massive -resigned -burned -allen -tennessee -locked -values -improved -##mo -wounded -universe -sick -dating -facing -pack -purchase -user -##pur -moments -##ul -merged -anniversary -1908 -coal -brick -understood -causes -dynasty -queensland -establish -stores -crisis -promote -hoping -views -cards -referee -extension -##si -raise -arizona -improve -colonial -formal -charged -##rt -palm -lucky -hide -rescue -faces -95 -feelings -candidates -juan -##ell -goods -6th -courses -weekend -59 -luke -cash -fallen -##om -delivered -affected -installed -carefully -tries -swiss -hollywood -costs -lincoln -responsibility -##he -shore -file -proper -normally -maryland -assistance -jump -constant -offering -friendly -waters -persons -realize -contain -trophy -800 -partnership -factor -58 -musicians -cry -bound -oregon -indicated -hero -houston -medium -##ure -consisting -somewhat -##ara -57 -cycle -##che -beer -moore -frederick -gotten -eleven -worst -weak -approached -arranged -chin -loan -universal -bond -fifteen -pattern -disappeared -##ney -translated -##zed -lip -arab -capture -interests -insurance -##chi -shifted -cave -prix -warning -sections -courts -coat -plot -smell -feed -golf -favorite -maintain -knife -vs -voted -degrees -finance -quebec -opinion -translation -manner -ruled -operate -productions -choose -musician -discovery -confused -tired -separated -stream -techniques -committed -attend -ranking -kings -throw -passengers -measure -horror -fan -mining -sand -danger -salt -calm -decade -dam -require -runner -##ik -rush -associate -greece -##ker -rivers -consecutive -matthew -##ski -sighed -sq -documents -steam -edited -closing -tie -accused -1905 -##ini -islamic -distributed -directors -organisation -bruce -7th -breathing -mad -lit -arrival -concrete -taste -08 -composition -shaking -faster -amateur -adjacent -stating -1906 -twin -flew -##ran -tokyo -publications -##tone -obviously -ridge -storage -1907 -carl -pages -concluded -desert -driven -universities -ages -terminal -sequence -borough -250 -constituency -creative -cousin -economics -dreams -margaret -notably -reduce -montreal -mode -17th -ears -saved -jan -vocal -##ica -1909 -andy -##jo -riding -roughly -threatened -##ise -meters -meanwhile -landed -compete -repeated -grass -czech -regularly -charges -tea -sudden -appeal -##ung -solution -describes -pierre -classification -glad -parking -##ning -belt -physics -99 -rachel -add -hungarian -participate -expedition -damaged -gift -childhood -85 -fifty -##red -mathematics -jumped -letting -defensive -mph -##ux -##gh -testing -##hip -hundreds -shoot -owners -matters -smoke -israeli -kentucky -dancing -mounted -grandfather -emma -designs -profit -argentina -##gs -truly -li -lawrence -cole -begun -detroit -willing -branches -smiling -decide -miami -enjoyed -recordings -##dale -poverty -ethnic -gay -##bi -gary -arabic -09 -accompanied -##one -##ons -fishing -determine -residential -acid -##ary -alice -returns -starred -mail -##ang -jonathan -strategy -##ue -net -forty -cook -businesses -equivalent -commonwealth -distinct -ill -##cy -seriously -##ors -##ped -shift -harris -replace -rio -imagine -formula -ensure -##ber -additionally -scheme -conservation -occasionally -purposes -feels -favor -##and -##ore -1930s -contrast -hanging -hunt -movies -1904 -instruments -victims -danish -christopher -busy -demon -sugar -earliest -colony -studying -balance -duties -##ks -belgium -slipped -carter -05 -visible -stages -iraq -fifa -##im -commune -forming -zero -07 -continuing -talked -counties -legend -bathroom -option -tail -clay -daughters -afterwards -severe -jaw -visitors -##ded -devices -aviation -russell -kate -##vi -entering -subjects -##ino -temporary -swimming -forth -smooth -ghost -audio -bush -operates -rocks -movements -signs -eddie -##tz -ann -voices -honorary -06 -memories -dallas -pure -measures -racial -promised -66 -harvard -ceo -16th -parliamentary -indicate -benefit -flesh -dublin -louisiana -1902 -1901 -patient -sleeping -1903 -membership -coastal -medieval -wanting -element -scholars -rice -62 -limit -survive -makeup -rating -definitely -collaboration -obvious -##tan -boss -ms -baron -birthday -linked -soil -diocese -##lan -ncaa -##mann -offensive -shell -shouldn -waist -##tus -plain -ross -organ -resolution -manufacturing -adding -relative -kennedy -98 -whilst -moth -marketing -gardens -crash -72 -heading -partners -credited -carlos -moves -cable -##zi -marshall -##out -depending -bottle -represents -rejected -responded -existed -04 -jobs -denmark -lock -##ating -treated -graham -routes -talent -commissioner -drugs -secure -tests -reign -restored -photography -##gi -contributions -oklahoma -designer -disc -grin -seattle -robin -paused -atlanta -unusual -##gate -praised -las -laughing -satellite -hungary -visiting -##sky -interesting -factors -deck -poems -norman -##water -stuck -speaker -rifle -domain -premiered -##her -dc -comics -actors -01 -reputation -eliminated -8th -ceiling -prisoners -script -##nce -leather -austin -mississippi -rapidly -admiral -parallel -charlotte -guilty -tools -gender -divisions -fruit -##bs -laboratory -nelson -fantasy -marry -rapid -aunt -tribe -requirements -aspects -suicide -amongst -adams -bone -ukraine -abc -kick -sees -edinburgh -clothing -column -rough -gods -hunting -broadway -gathered -concerns -##ek -spending -ty -12th -snapped -requires -solar -bones -cavalry -##tta -iowa -drinking -waste -index -franklin -charity -thompson -stewart -tip -flash -landscape -friday -enjoy -singh -poem -listening -##back -eighth -fred -differences -adapted -bomb -ukrainian -surgery -corporate -masters -anywhere -##more -waves -odd -sean -portugal -orleans -dick -debate -kent -eating -puerto -cleared -96 -expect -cinema -97 -guitarist -blocks -electrical -agree -involving -depth -dying -panel -struggle -##ged -peninsula -adults -novels -emerged -vienna -metro -debuted -shoes -tamil -songwriter -meets -prove -beating -instance -heaven -scared -sending -marks -artistic -passage -superior -03 -significantly -shopping -##tive -retained -##izing -malaysia -technique -cheeks -##ola -warren -maintenance -destroy -extreme -allied -120 -appearing -##yn -fill -advice -alabama -qualifying -policies -cleveland -hat -battery -smart -authors -10th -soundtrack -acted -dated -lb -glance -equipped -coalition -funny -outer -ambassador -roy -possibility -couples -campbell -dna -loose -ethan -supplies -1898 -gonna -88 -monster -##res -shake -agents -frequency -springs -dogs -practices -61 -gang -plastic -easier -suggests -gulf -blade -exposed -colors -industries -markets -pan -nervous -electoral -charts -legislation -ownership -##idae -mac -appointment -shield -copy -assault -socialist -abbey -monument -license -throne -employment -jay -93 -replacement -charter -cloud -powered -suffering -accounts -oak -connecticut -strongly -wright -colour -crystal -13th -context -welsh -networks -voiced -gabriel -jerry -##cing -forehead -mp -##ens -manage -schedule -totally -remix -##ii -forests -occupation -print -nicholas -brazilian -strategic -vampires -engineers -76 -roots -seek -correct -instrumental -und -alfred -backed -hop -##des -stanley -robinson -traveled -wayne -welcome -austrian -achieve -67 -exit -rates -1899 -strip -whereas -##cs -sing -deeply -adventure -bobby -rick -jamie -careful -components -cap -useful -personality -knee -##shi -pushing -hosts -02 -protest -ca -ottoman -symphony -##sis -63 -boundary -1890 -processes -considering -considerable -tons -##work -##ft -##nia -cooper -trading -dear -conduct -91 -illegal -apple -revolutionary -holiday -definition -harder -##van -jacob -circumstances -destruction -##lle -popularity -grip -classified -liverpool -donald -baltimore -flows -seeking -honour -approval -92 -mechanical -till -happening -statue -critic -increasingly -immediate -describe -commerce -stare -##ster -indonesia -meat -rounds -boats -baker -orthodox -depression -formally -worn -naked -claire -muttered -sentence -11th -emily -document -77 -criticism -wished -vessel -spiritual -bent -virgin -parker -minimum -murray -lunch -danny -printed -compilation -keyboards -false -blow -belonged -68 -raising -78 -cutting -##board -pittsburgh -##up -9th -shadows -81 -hated -indigenous -jon -15th -barry -scholar -ah -##zer -oliver -##gy -stick -susan -meetings -attracted -spell -romantic -##ver -ye -1895 -photo -demanded -customers -##ac -1896 -logan -revival -keys -modified -commanded -jeans -##ious -upset -raw -phil -detective -hiding -resident -vincent -##bly -experiences -diamond -defeating -coverage -lucas -external -parks -franchise -helen -bible -successor -percussion -celebrated -il -lift -profile -clan -romania -##ied -mills -##su -nobody -achievement -shrugged -fault -1897 -rhythm -initiative -breakfast -carbon -700 -69 -lasted -violent -74 -wound -ken -killer -gradually -filmed -°c -dollars -processing -94 -remove -criticized -guests -sang -chemistry -##vin -legislature -disney -##bridge -uniform -escaped -integrated -proposal -purple -denied -liquid -karl -influential -morris -nights -stones -intense -experimental -twisted -71 -84 -##ld -pace -nazi -mitchell -ny -blind -reporter -newspapers -14th -centers -burn -basin -forgotten -surviving -filed -collections -monastery -losses -manual -couch -description -appropriate -merely -tag -missions -sebastian -restoration -replacing -triple -73 -elder -julia -warriors -benjamin -julian -convinced -stronger -amazing -declined -versus -merchant -happens -output -finland -bare -barbara -absence -ignored -dawn -injuries -##port -producers -##ram -82 -luis -##ities -kw -admit -expensive -electricity -nba -exception -symbol -##ving -ladies -shower -sheriff -characteristics -##je -aimed -button -ratio -effectively -summit -angle -jury -bears -foster -vessels -pants -executed -evans -dozen -advertising -kicked -patrol -1889 -competitions -lifetime -principles -athletics -##logy -birmingham -sponsored -89 -rob -nomination -1893 -acoustic -##sm -creature -longest -##tra -credits -harbor -dust -josh -##so -territories -milk -infrastructure -completion -thailand -indians -leon -archbishop -##sy -assist -pitch -blake -arrangement -girlfriend -serbian -operational -hence -sad -scent -fur -dj -sessions -hp -refer -rarely -##ora -exists -1892 -##ten -scientists -dirty -penalty -burst -portrait -seed -79 -pole -limits -rival -1894 -stable -alpha -grave -constitutional -alcohol -arrest -flower -mystery -devil -architectural -relationships -greatly -habitat -##istic -larry -progressive -remote -cotton -##ics -##ok -preserved -reaches -##ming -cited -86 -vast -scholarship -decisions -cbs -joy -teach -1885 -editions -knocked -eve -searching -partly -participation -gap -animated -fate -excellent -##ett -na -87 -alternate -saints -youngest -##ily -climbed -##ita -##tors -suggest -##ct -discussion -staying -choir -lakes -jacket -revenue -nevertheless -peaked -instrument -wondering -annually -managing -neil -1891 -signing -terry -##ice -apply -clinical -brooklyn -aim -catherine -fuck -farmers -figured -ninth -pride -hugh -evolution -ordinary -involvement -comfortable -shouted -tech -encouraged -taiwan -representation -sharing -##lia -##em -panic -exact -cargo -competing -fat -cried -83 -1920s -occasions -pa -cabin -borders -utah -marcus -##isation -badly -muscles -##ance -victorian -transition -warner -bet -permission -##rin -slave -terrible -similarly -shares -seth -uefa -possession -medals -benefits -colleges -lowered -perfectly -mall -transit -##ye -##kar -publisher -##ened -harrison -deaths -elevation -##ae -asleep -machines -sigh -ash -hardly -argument -occasion -parent -leo -decline -1888 -contribution -##ua -concentration -1000 -opportunities -hispanic -guardian -extent -emotions -hips -mason -volumes -bloody -controversy -diameter -steady -mistake -phoenix -identify -violin -##sk -departure -richmond -spin -funeral -enemies -1864 -gear -literally -connor -random -sergeant -grab -confusion -1865 -transmission -informed -op -leaning -sacred -suspended -thinks -gates -portland -luck -agencies -yours -hull -expert -muscle -layer -practical -sculpture -jerusalem -latest -lloyd -statistics -deeper -recommended -warrior -arkansas -mess -supports -greg -eagle -1880 -recovered -rated -concerts -rushed -##ano -stops -eggs -files -premiere -keith -##vo -delhi -turner -pit -affair -belief -paint -##zing -mate -##ach -##ev -victim -##ology -withdrew -bonus -styles -fled -##ud -glasgow -technologies -funded -nbc -adaptation -##ata -portrayed -cooperation -supporters -judges -bernard -justin -hallway -ralph -##ick -graduating -controversial -distant -continental -spider -bite -##ho -recognize -intention -mixing -##ese -egyptian -bow -tourism -suppose -claiming -tiger -dominated -participants -vi -##ru -nurse -partially -tape -##rum -psychology -##rn -essential -touring -duo -voting -civilian -emotional -channels -##king -apparent -hebrew -1887 -tommy -carrier -intersection -beast -hudson -##gar -##zo -lab -nova -bench -discuss -costa -##ered -detailed -behalf -drivers -unfortunately -obtain -##lis -rocky -##dae -siege -friendship -honey -##rian -1861 -amy -hang -posted -governments -collins -respond -wildlife -preferred -operator -##po -laura -pregnant -videos -dennis -suspected -boots -instantly -weird -automatic -businessman -alleged -placing -throwing -ph -mood -1862 -perry -venue -jet -remainder -##lli -##ci -passion -biological -boyfriend -1863 -dirt -buffalo -ron -segment -fa -abuse -##era -genre -thrown -stroke -colored -stress -exercise -displayed -##gen -struggled -##tti -abroad -dramatic -wonderful -thereafter -madrid -component -widespread -##sed -tale -citizen -todd -monday -1886 -vancouver -overseas -forcing -crying -descent -##ris -discussed -substantial -ranks -regime -1870 -provinces -switch -drum -zane -ted -tribes -proof -lp -cream -researchers -volunteer -manor -silk -milan -donated -allies -venture -principle -delivery -enterprise -##ves -##ans -bars -traditionally -witch -reminded -copper -##uk -pete -inter -links -colin -grinned -elsewhere -competitive -frequent -##oy -scream -##hu -tension -texts -submarine -finnish -defending -defend -pat -detail -1884 -affiliated -stuart -themes -villa -periods -tool -belgian -ruling -crimes -answers -folded -licensed -resort -demolished -hans -lucy -1881 -lion -traded -photographs -writes -craig -##fa -trials -generated -beth -noble -debt -percentage -yorkshire -erected -ss -viewed -grades -confidence -ceased -islam -telephone -retail -##ible -chile -m² -roberts -sixteen -##ich -commented -hampshire -innocent -dual -pounds -checked -regulations -afghanistan -sung -rico -liberty -assets -bigger -options -angels -relegated -tribute -wells -attending -leaf -##yan -butler -romanian -forum -monthly -lisa -patterns -gmina -##tory -madison -hurricane -rev -##ians -bristol -##ula -elite -valuable -disaster -democracy -awareness -germans -freyja -##ins -loop -absolutely -paying -populations -maine -sole -prayer -spencer -releases -doorway -bull -##ani -lover -midnight -conclusion -##sson -thirteen -lily -mediterranean -##lt -nhl -proud -sample -##hill -drummer -guinea -##ova -murphy -climb -##ston -instant -attributed -horn -ain -railways -steven -##ao -autumn -ferry -opponent -root -traveling -secured -corridor -stretched -tales -sheet -trinity -cattle -helps -indicates -manhattan -murdered -fitted -1882 -gentle -grandmother -mines -shocked -vegas -produces -##light -caribbean -##ou -belong -continuous -desperate -drunk -historically -trio -waved -raf -dealing -nathan -bat -murmured -interrupted -residing -scientist -pioneer -harold -aaron -##net -delta -attempting -minority -mini -believes -chorus -tend -lots -eyed -indoor -load -shots -updated -jail -##llo -concerning -connecting -wealth -##ved -slaves -arrive -rangers -sufficient -rebuilt -##wick -cardinal -flood -muhammad -whenever -relation -runners -moral -repair -viewers -arriving -revenge -punk -assisted -bath -fairly -breathe -lists -innings -illustrated -whisper -nearest -voters -clinton -ties -ultimate -screamed -beijing -lions -andre -fictional -gathering -comfort -radar -suitable -dismissed -hms -ban -pine -wrist -atmosphere -voivodeship -bid -timber -##ned -##nan -giants -##ane -cameron -recovery -uss -identical -categories -switched -serbia -laughter -noah -ensemble -therapy -peoples -touching -##off -locally -pearl -platforms -everywhere -ballet -tables -lanka -herbert -outdoor -toured -derek -1883 -spaces -contested -swept -1878 -exclusive -slight -connections -##dra -winds -prisoner -collective -bangladesh -tube -publicly -wealthy -thai -##ys -isolated -select -##ric -insisted -pen -fortune -ticket -spotted -reportedly -animation -enforcement -tanks -110 -decides -wider -lowest -owen -##time -nod -hitting -##hn -gregory -furthermore -magazines -fighters -solutions -##ery -pointing -requested -peru -reed -chancellor -knights -mask -worker -eldest -flames -reduction -1860 -volunteers -##tis -reporting -##hl -wire -advisory -endemic -origins -settlers -pursue -knock -consumer -1876 -eu -compound -creatures -mansion -sentenced -ivan -deployed -guitars -frowned -involves -mechanism -kilometers -perspective -shops -maps -terminus -duncan -alien -fist -bridges -##pers -heroes -fed -derby -swallowed -##ros -patent -sara -illness -characterized -adventures -slide -hawaii -jurisdiction -##op -organised -##side -adelaide -walks -biology -se -##ties -rogers -swing -tightly -boundaries -##rie -prepare -implementation -stolen -##sha -certified -colombia -edwards -garage -##mm -recalled -##ball -rage -harm -nigeria -breast -##ren -furniture -pupils -settle -##lus -cuba -balls -client -alaska -21st -linear -thrust -celebration -latino -genetic -terror -##cia -##ening -lightning -fee -witness -lodge -establishing -skull -##ique -earning -hood -##ei -rebellion -wang -sporting -warned -missile -devoted -activist -porch -worship -fourteen -package -1871 -decorated -##shire -housed -##ock -chess -sailed -doctors -oscar -joan -treat -garcia -harbour -jeremy -##ire -traditions -dominant -jacques -##gon -##wan -relocated -1879 -amendment -sized -companion -simultaneously -volleyball -spun -acre -increases -stopping -loves -belongs -affect -drafted -tossed -scout -battles -1875 -filming -shoved -munich -tenure -vertical -romance -pc -##cher -argue -##ical -craft -ranging -www -opens -honest -tyler -yesterday -virtual -##let -muslims -reveal -snake -immigrants -radical -screaming -speakers -firing -saving -belonging -ease -lighting -prefecture -blame -farmer -hungry -grows -rubbed -beam -sur -subsidiary -##cha -armenian -sao -dropping -conventional -##fer -microsoft -reply -qualify -spots -1867 -sweat -festivals -##ken -immigration -physician -discover -exposure -sandy -explanation -isaac -implemented -##fish -hart -initiated -connect -stakes -presents -heights -householder -pleased -tourist -regardless -slip -closest -##ction -surely -sultan -brings -riley -preparation -aboard -slammed -baptist -experiment -ongoing -interstate -organic -playoffs -##ika -1877 -130 -##tar -hindu -error -tours -tier -plenty -arrangements -talks -trapped -excited -sank -ho -athens -1872 -denver -welfare -suburb -athletes -trick -diverse -belly -exclusively -yelled -1868 -##med -conversion -##ette -1874 -internationally -computers -conductor -abilities -sensitive -hello -dispute -measured -globe -rocket -prices -amsterdam -flights -tigers -inn -municipalities -emotion -references -3d -##mus -explains -airlines -manufactured -pm -archaeological -1873 -interpretation -devon -comment -##ites -settlements -kissing -absolute -improvement -suite -impressed -barcelona -sullivan -jefferson -towers -jesse -julie -##tin -##lu -grandson -hi -gauge -regard -rings -interviews -trace -raymond -thumb -departments -burns -serial -bulgarian -scores -demonstrated -##ix -1866 -kyle -alberta -underneath -romanized -##ward -relieved -acquisition -phrase -cliff -reveals -han -cuts -merger -custom -##dar -nee -gilbert -graduation -##nts -assessment -cafe -difficulty -demands -swung -democrat -jennifer -commons -1940s -grove -##yo -completing -focuses -sum -substitute -bearing -stretch -reception -##py -reflected -essentially -destination -pairs -##ched -survival -resource -##bach -promoting -doubles -messages -tear -##down -##fully -parade -florence -harvey -incumbent -partial -framework -900 -pedro -frozen -procedure -olivia -controls -##mic -shelter -personally -temperatures -##od -brisbane -tested -sits -marble -comprehensive -oxygen -leonard -##kov -inaugural -iranian -referring -quarters -attitude -##ivity -mainstream -lined -mars -dakota -norfolk -unsuccessful -##° -explosion -helicopter -congressional -##sing -inspector -bitch -seal -departed -divine -##ters -coaching -examination -punishment -manufacturer -sink -columns -unincorporated -signals -nevada -squeezed -dylan -dining -photos -martial -manuel -eighteen -elevator -brushed -plates -ministers -ivy -congregation -##len -slept -specialized -taxes -curve -restricted -negotiations -likes -statistical -arnold -inspiration -execution -bold -intermediate -significance -margin -ruler -wheels -gothic -intellectual -dependent -listened -eligible -buses -widow -syria -earn -cincinnati -collapsed -recipient -secrets -accessible -philippine -maritime -goddess -clerk -surrender -breaks -playoff -database -##ified -##lon -ideal -beetle -aspect -soap -regulation -strings -expand -anglo -shorter -crosses -retreat -tough -coins -wallace -directions -pressing -##oon -shipping -locomotives -comparison -topics -nephew -##mes -distinction -honors -travelled -sierra -ibn -##over -fortress -sa -recognised -carved -1869 -clients -##dan -intent -##mar -coaches -describing -bread -##ington -beaten -northwestern -##ona -merit -youtube -collapse -challenges -em -historians -objective -submitted -virus -attacking -drake -assume -##ere -diseases -marc -stem -leeds -##cus -##ab -farming -glasses -##lock -visits -nowhere -fellowship -relevant -carries -restaurants -experiments -101 -constantly -bases -targets -shah -tenth -opponents -verse -territorial -##ira -writings -corruption -##hs -instruction -inherited -reverse -emphasis -##vic -employee -arch -keeps -rabbi -watson -payment -uh -##ala -nancy -##tre -venice -fastest -sexy -banned -adrian -properly -ruth -touchdown -dollar -boards -metre -circles -edges -favour -comments -ok -travels -liberation -scattered -firmly -##ular -holland -permitted -diesel -kenya -den -originated -##ral -demons -resumed -dragged -rider -##rus -servant -blinked -extend -torn -##ias -##sey -input -meal -everybody -cylinder -kinds -camps -##fe -bullet -logic -##wn -croatian -evolved -healthy -fool -chocolate -wise -preserve -pradesh -##ess -respective -1850 -##ew -chicken -artificial -gross -corresponding -convicted -cage -caroline -dialogue -##dor -narrative -stranger -mario -br -christianity -failing -trent -commanding -buddhist -1848 -maurice -focusing -yale -bike -altitude -##ering -mouse -revised -##sley -veteran -##ig -pulls -theology -crashed -campaigns -legion -##ability -drag -excellence -customer -cancelled -intensity -excuse -##lar -liga -participating -contributing -printing -##burn -variable -##rk -curious -bin -legacy -renaissance -##my -symptoms -binding -vocalist -dancer -##nie -grammar -gospel -democrats -ya -enters -sc -diplomatic -hitler -##ser -clouds -mathematical -quit -defended -oriented -##heim -fundamental -hardware -impressive -equally -convince -confederate -guilt -chuck -sliding -##ware -magnetic -narrowed -petersburg -bulgaria -otto -phd -skill -##ama -reader -hopes -pitcher -reservoir -hearts -automatically -expecting -mysterious -bennett -extensively -imagined -seeds -monitor -fix -##ative -journalism -struggling -signature -ranch -encounter -photographer -observation -protests -##pin -influences -##hr -calendar -##all -cruz -croatia -locomotive -hughes -naturally -shakespeare -basement -hook -uncredited -faded -theories -approaches -dare -phillips -filling -fury -obama -##ain -efficient -arc -deliver -min -raid -breeding -inducted -leagues -efficiency -axis -montana -eagles -##ked -supplied -instructions -karen -picking -indicating -trap -anchor -practically -christians -tomb -vary -occasional -electronics -lords -readers -newcastle -faint -innovation -collect -situations -engagement -160 -claude -mixture -##feld -peer -tissue -logo -lean -##ration -°f -floors -##ven -architects -reducing -##our -##ments -rope -1859 -ottawa -##har -samples -banking -declaration -proteins -resignation -francois -saudi -advocate -exhibited -armor -twins -divorce -##ras -abraham -reviewed -jo -temporarily -matrix -physically -pulse -curled -##ena -difficulties -bengal -usage -##ban -annie -riders -certificate -##pi -holes -warsaw -distinctive -jessica -##mon -mutual -1857 -customs -circular -eugene -removal -loaded -mere -vulnerable -depicted -generations -dame -heir -enormous -lightly -climbing -pitched -lessons -pilots -nepal -ram -google -preparing -brad -louise -renowned -##₂ -liam -##ably -plaza -shaw -sophie -brilliant -bills -##bar -##nik -fucking -mainland -server -pleasant -seized -veterans -jerked -fail -beta -brush -radiation -stored -warmth -southeastern -nate -sin -raced -berkeley -joke -athlete -designation -trunk -##low -roland -qualification -archives -heels -artwork -receives -judicial -reserves -##bed -woke -installation -abu -floating -fake -lesser -excitement -interface -concentrated -addressed -characteristic -amanda -saxophone -monk -auto -##bus -releasing -egg -dies -interaction -defender -ce -outbreak -glory -loving -##bert -sequel -consciousness -http -awake -ski -enrolled -##ress -handling -rookie -brow -somebody -biography -warfare -amounts -contracts -presentation -fabric -dissolved -challenged -meter -psychological -lt -elevated -rally -accurate -##tha -hospitals -undergraduate -specialist -venezuela -exhibit -shed -nursing -protestant -fluid -structural -footage -jared -consistent -prey -##ska -succession -reflect -exile -lebanon -wiped -suspect -shanghai -resting -integration -preservation -marvel -variant -pirates -sheep -rounded -capita -sailing -colonies -manuscript -deemed -variations -clarke -functional -emerging -boxing -relaxed -curse -azerbaijan -heavyweight -nickname -editorial -rang -grid -tightened -earthquake -flashed -miguel -rushing -##ches -improvements -boxes -brooks -180 -consumption -molecular -felix -societies -repeatedly -variation -aids -civic -graphics -professionals -realm -autonomous -receiver -delayed -workshop -militia -chairs -trump -canyon -##point -harsh -extending -lovely -happiness -##jan -stake -eyebrows -embassy -wellington -hannah -##ella -sony -corners -bishops -swear -cloth -contents -xi -namely -commenced -1854 -stanford -nashville -courage -graphic -commitment -garrison -##bin -hamlet -clearing -rebels -attraction -literacy -cooking -ruins -temples -jenny -humanity -celebrate -hasn -freight -sixty -rebel -bastard -##art -newton -##ada -deer -##ges -##ching -smiles -delaware -singers -##ets -approaching -assists -flame -##ph -boulevard -barrel -planted -##ome -pursuit -##sia -consequences -posts -shallow -invitation -rode -depot -ernest -kane -rod -concepts -preston -topic -chambers -striking -blast -arrives -descendants -montgomery -ranges -worlds -##lay -##ari -span -chaos -praise -##ag -fewer -1855 -sanctuary -mud -fbi -##ions -programmes -maintaining -unity -harper -bore -handsome -closure -tournaments -thunder -nebraska -linda -facade -puts -satisfied -argentine -dale -cork -dome -panama -##yl -1858 -tasks -experts -##ates -feeding -equation -##las -##ida -##tu -engage -bryan -##ax -um -quartet -melody -disbanded -sheffield -blocked -gasped -delay -kisses -maggie -connects -##non -sts -poured -creator -publishers -##we -guided -ellis -extinct -hug -gaining -##ord -complicated -##bility -poll -clenched -investigate -##use -thereby -quantum -spine -cdp -humor -kills -administered -semifinals -##du -encountered -ignore -##bu -commentary -##maker -bother -roosevelt -140 -plains -halfway -flowing -cultures -crack -imprisoned -neighboring -airline -##ses -##view -##mate -##ec -gather -wolves -marathon -transformed -##ill -cruise -organisations -carol -punch -exhibitions -numbered -alarm -ratings -daddy -silently -##stein -queens -colours -impression -guidance -liu -tactical -##rat -marshal -della -arrow -##ings -rested -feared -tender -owns -bitter -advisor -escort -##ides -spare -farms -grants -##ene -dragons -encourage -colleagues -cameras -##und -sucked -pile -spirits -prague -statements -suspension -landmark -fence -torture -recreation -bags -permanently -survivors -pond -spy -predecessor -bombing -coup -##og -protecting -transformation -glow -##lands -##book -dug -priests -andrea -feat -barn -jumping -##chen -##ologist -##con -casualties -stern -auckland -pipe -serie -revealing -ba -##bel -trevor -mercy -spectrum -yang -consist -governing -collaborated -possessed -epic -comprises -blew -shane -##ack -lopez -honored -magical -sacrifice -judgment -perceived -hammer -mtv -baronet -tune -das -missionary -sheets -350 -neutral -oral -threatening -attractive -shade -aims -seminary -##master -estates -1856 -michel -wounds -refugees -manufacturers -##nic -mercury -syndrome -porter -##iya -##din -hamburg -identification -upstairs -purse -widened -pause -cared -breathed -affiliate -santiago -prevented -celtic -fisher -125 -recruited -byzantine -reconstruction -farther -##mp -diet -sake -au -spite -sensation -##ert -blank -separation -105 -##hon -vladimir -armies -anime -##lie -accommodate -orbit -cult -sofia -archive -##ify -##box -founders -sustained -disorder -honours -northeastern -mia -crops -violet -threats -blanket -fires -canton -followers -southwestern -prototype -voyage -assignment -altered -moderate -protocol -pistol -##eo -questioned -brass -lifting -1852 -math -authored -##ual -doug -dimensional -dynamic -##san -1851 -pronounced -grateful -quest -uncomfortable -boom -presidency -stevens -relating -politicians -chen -barrier -quinn -diana -mosque -tribal -cheese -palmer -portions -sometime -chester -treasure -wu -bend -download -millions -reforms -registration -##osa -consequently -monitoring -ate -preliminary -brandon -invented -ps -eaten -exterior -intervention -ports -documented -log -displays -lecture -sally -favourite -##itz -vermont -lo -invisible -isle -breed -##ator -journalists -relay -speaks -backward -explore -midfielder -actively -stefan -procedures -cannon -blond -kenneth -centered -servants -chains -libraries -malcolm -essex -henri -slavery -##hal -facts -fairy -coached -cassie -cats -washed -cop -##fi -announcement -item -2000s -vinyl -activated -marco -frontier -growled -curriculum -##das -loyal -accomplished -leslie -ritual -kenny -##00 -vii -napoleon -hollow -hybrid -jungle -stationed -friedrich -counted -##ulated -platinum -theatrical -seated -col -rubber -glen -1840 -diversity -healing -extends -id -provisions -administrator -columbus -##oe -tributary -te -assured -org -##uous -prestigious -examined -lectures -grammy -ronald -associations -bailey -allan -essays -flute -believing -consultant -proceedings -travelling -1853 -kit -kerala -yugoslavia -buddy -methodist -##ith -burial -centres -batman -##nda -discontinued -bo -dock -stockholm -lungs -severely -##nk -citing -manga -##ugh -steal -mumbai -iraqi -robot -celebrity -bride -broadcasts -abolished -pot -joel -overhead -franz -packed -reconnaissance -johann -acknowledged -introduce -handled -doctorate -developments -drinks -alley -palestine -##nis -##aki -proceeded -recover -bradley -grain -patch -afford -infection -nationalist -legendary -##ath -interchange -virtually -gen -gravity -exploration -amber -vital -wishes -powell -doctrine -elbow -screenplay -##bird -contribute -indonesian -pet -creates -##com -enzyme -kylie -discipline -drops -manila -hunger -##ien -layers -suffer -fever -bits -monica -keyboard -manages -##hood -searched -appeals -##bad -testament -grande -reid -##war -beliefs -congo -##ification -##dia -si -requiring -##via -casey -1849 -regret -streak -rape -depends -syrian -sprint -pound -tourists -upcoming -pub -##xi -tense -##els -practiced -echo -nationwide -guild -motorcycle -liz -##zar -chiefs -desired -elena -bye -precious -absorbed -relatives -booth -pianist -##mal -citizenship -exhausted -wilhelm -##ceae -##hed -noting -quarterback -urge -hectares -##gue -ace -holly -##tal -blonde -davies -parked -sustainable -stepping -twentieth -airfield -galaxy -nest -chip -##nell -tan -shaft -paulo -requirement -##zy -paradise -tobacco -trans -renewed -vietnamese -##cker -##ju -suggesting -catching -holmes -enjoying -md -trips -colt -holder -butterfly -nerve -reformed -cherry -bowling -trailer -carriage -goodbye -appreciate -toy -joshua -interactive -enabled -involve -##kan -collar -determination -bunch -facebook -recall -shorts -superintendent -episcopal -frustration -giovanni -nineteenth -laser -privately -array -circulation -##ovic -armstrong -deals -painful -permit -discrimination -##wi -aires -retiring -cottage -ni -##sta -horizon -ellen -jamaica -ripped -fernando -chapters -playstation -patron -lecturer -navigation -behaviour -genes -georgian -export -solomon -rivals -swift -seventeen -rodriguez -princeton -independently -sox -1847 -arguing -entity -casting -hank -criteria -oakland -geographic -milwaukee -reflection -expanding -conquest -dubbed -##tv -halt -brave -brunswick -doi -arched -curtis -divorced -predominantly -somerset -streams -ugly -zoo -horrible -curved -buenos -fierce -dictionary -vector -theological -unions -handful -stability -chan -punjab -segments -##lly -altar -ignoring -gesture -monsters -pastor -##stone -thighs -unexpected -operators -abruptly -coin -compiled -associates -improving -migration -pin -##ose -compact -collegiate -reserved -##urs -quarterfinals -roster -restore -assembled -hurry -oval -##cies -1846 -flags -martha -##del -victories -sharply -##rated -argues -deadly -neo -drawings -symbols -performer -##iel -griffin -restrictions -editing -andrews -java -journals -arabia -compositions -dee -pierce -removing -hindi -casino -runway -civilians -minds -nasa -hotels -##zation -refuge -rent -retain -potentially -conferences -suburban -conducting -##tto -##tions -##tle -descended -massacre -##cal -ammunition -terrain -fork -souls -counts -chelsea -durham -drives -cab -##bank -perth -realizing -palestinian -finn -simpson -##dal -betty -##ule -moreover -particles -cardinals -tent -evaluation -extraordinary -##oid -inscription -##works -wednesday -chloe -maintains -panels -ashley -trucks -##nation -cluster -sunlight -strikes -zhang -##wing -dialect -canon -##ap -tucked -##ws -collecting -##mas -##can -##sville -maker -quoted -evan -franco -aria -buying -cleaning -eva -closet -provision -apollo -clinic -rat -##ez -necessarily -ac -##gle -##ising -venues -flipped -cent -spreading -trustees -checking -authorized -##sco -disappointed -##ado -notion -duration -trumpet -hesitated -topped -brussels -rolls -theoretical -hint -define -aggressive -repeat -wash -peaceful -optical -width -allegedly -mcdonald -strict -copyright -##illa -investors -mar -jam -witnesses -sounding -miranda -michelle -privacy -hugo -harmony -##pp -valid -lynn -glared -nina -102 -headquartered -diving -boarding -gibson -##ncy -albanian -marsh -routine -dealt -enhanced -er -intelligent -substance -targeted -enlisted -discovers -spinning -observations -pissed -smoking -rebecca -capitol -visa -varied -costume -seemingly -indies -compensation -surgeon -thursday -arsenal -westminster -suburbs -rid -anglican -##ridge -knots -foods -alumni -lighter -fraser -whoever -portal -scandal -##ray -gavin -advised -instructor -flooding -terrorist -##ale -teenage -interim -senses -duck -teen -thesis -abby -eager -overcome -##ile -newport -glenn -rises -shame -##cc -prompted -priority -forgot -bomber -nicolas -protective -360 -cartoon -katherine -breeze -lonely -trusted -henderson -richardson -relax -banner -candy -palms -remarkable -##rio -legends -cricketer -essay -ordained -edmund -rifles -trigger -##uri -##away -sail -alert -1830 -audiences -penn -sussex -siblings -pursued -indianapolis -resist -rosa -consequence -succeed -avoided -1845 -##ulation -inland -##tie -##nna -counsel -profession -chronicle -hurried -##una -eyebrow -eventual -bleeding -innovative -cure -##dom -committees -accounting -con -scope -hardy -heather -tenor -gut -herald -codes -tore -scales -wagon -##oo -luxury -tin -prefer -fountain -triangle -bonds -darling -convoy -dried -traced -beings -troy -accidentally -slam -findings -smelled -joey -lawyers -outcome -steep -bosnia -configuration -shifting -toll -brook -performers -lobby -philosophical -construct -shrine -aggregate -boot -cox -phenomenon -savage -insane -solely -reynolds -lifestyle -##ima -nationally -holdings -consideration -enable -edgar -mo -mama -##tein -fights -relegation -chances -atomic -hub -conjunction -awkward -reactions -currency -finale -kumar -underwent -steering -elaborate -gifts -comprising -melissa -veins -reasonable -sunshine -chi -solve -trails -inhabited -elimination -ethics -huh -ana -molly -consent -apartments -layout -marines -##ces -hunters -bulk -##oma -hometown -##wall -##mont -cracked -reads -neighbouring -withdrawn -admission -wingspan -damned -anthology -lancashire -brands -batting -forgive -cuban -awful -##lyn -104 -dimensions -imagination -##ade -dante -##ship -tracking -desperately -goalkeeper -##yne -groaned -workshops -confident -burton -gerald -milton -circus -uncertain -slope -copenhagen -sophia -fog -philosopher -portraits -accent -cycling -varying -gripped -larvae -garrett -specified -scotia -mature -luther -kurt -rap -##kes -aerial -750 -ferdinand -heated -es -transported -##shan -safely -nonetheless -##orn -##gal -motors -demanding -##sburg -startled -##brook -ally -generate -caps -ghana -stained -demo -mentions -beds -ap -afterward -diary -##bling -utility -##iro -richards -1837 -conspiracy -conscious -shining -footsteps -observer -cyprus -urged -loyalty -developer -probability -olive -upgraded -gym -miracle -insects -graves -1844 -ourselves -hydrogen -amazon -katie -tickets -poets -##pm -planes -##pan -prevention -witnessed -dense -jin -randy -tang -warehouse -monroe -bang -archived -elderly -investigations -alec -granite -mineral -conflicts -controlling -aboriginal -carlo -##zu -mechanics -stan -stark -rhode -skirt -est -##berry -bombs -respected -##horn -imposed -limestone -deny -nominee -memphis -grabbing -disabled -##als -amusement -aa -frankfurt -corn -referendum -varies -slowed -disk -firms -unconscious -incredible -clue -sue -##zhou -twist -##cio -joins -idaho -chad -developers -computing -destroyer -103 -mortal -tucker -kingston -choices -yu -carson -1800 -os -whitney -geneva -pretend -dimension -staged -plateau -maya -##une -freestyle -##bc -rovers -hiv -##ids -tristan -classroom -prospect -##hus -honestly -diploma -lied -thermal -auxiliary -feast -unlikely -iata -##tel -morocco -pounding -treasury -lithuania -considerably -1841 -dish -1812 -geological -matching -stumbled -destroying -marched -brien -advances -cake -nicole -belle -settling -measuring -directing -##mie -tuesday -bassist -capabilities -stunned -fraud -torpedo -##list -##phone -anton -wisdom -surveillance -ruined -##ulate -lawsuit -healthcare -theorem -halls -trend -aka -horizontal -dozens -acquire -lasting -swim -hawk -gorgeous -fees -vicinity -decrease -adoption -tactics -##ography -pakistani -##ole -draws -##hall -willie -burke -heath -algorithm -integral -powder -elliott -brigadier -jackie -tate -varieties -darker -##cho -lately -cigarette -specimens -adds -##ree -##ensis -##inger -exploded -finalist -cia -murders -wilderness -arguments -nicknamed -acceptance -onwards -manufacture -robertson -jets -tampa -enterprises -blog -loudly -composers -nominations -1838 -ai -malta -inquiry -automobile -hosting -viii -rays -tilted -grief -museums -strategies -furious -euro -equality -cohen -poison -surrey -wireless -governed -ridiculous -moses -##esh -##room -vanished -##ito -barnes -attract -morrison -istanbul -##iness -absent -rotation -petition -janet -##logical -satisfaction -custody -deliberately -observatory -comedian -surfaces -pinyin -novelist -strictly -canterbury -oslo -monks -embrace -ibm -jealous -photograph -continent -dorothy -marina -doc -excess -holden -allegations -explaining -stack -avoiding -lance -storyline -majesty -poorly -spike -dos -bradford -raven -travis -classics -proven -voltage -pillow -fists -butt -1842 -interpreted -##car -1839 -gage -telegraph -lens -promising -expelled -casual -collector -zones -##min -silly -nintendo -##kh -##bra -downstairs -chef -suspicious -afl -flies -vacant -uganda -pregnancy -condemned -lutheran -estimates -cheap -decree -saxon -proximity -stripped -idiot -deposits -contrary -presenter -magnus -glacier -im -offense -edwin -##ori -upright -##long -bolt -##ois -toss -geographical -##izes -environments -delicate -marking -abstract -xavier -nails -windsor -plantation -occurring -equity -saskatchewan -fears -drifted -sequences -vegetation -revolt -##stic -1843 -sooner -fusion -opposing -nato -skating -1836 -secretly -ruin -lease -##oc -edit -##nne -flora -anxiety -ruby -##ological -##mia -tel -bout -taxi -emmy -frost -rainbow -compounds -foundations -rainfall -assassination -nightmare -dominican -##win -achievements -deserve -orlando -intact -armenia -##nte -calgary -valentine -106 -marion -proclaimed -theodore -bells -courtyard -thigh -gonzalez -console -troop -minimal -monte -everyday -##ence -##if -supporter -terrorism -buck -openly -presbyterian -activists -carpet -##iers -rubbing -uprising -##yi -cute -conceived -legally -##cht -millennium -cello -velocity -ji -rescued -cardiff -1835 -rex -concentrate -senators -beard -rendered -glowing -battalions -scouts -competitors -sculptor -catalogue -arctic -ion -raja -bicycle -wow -glancing -lawn -##woman -gentleman -lighthouse -publish -predicted -calculated -##val -variants -##gne -strain -##ui -winston -deceased -##nus -touchdowns -brady -caleb -sinking -echoed -crush -hon -blessed -protagonist -hayes -endangered -magnitude -editors -##tine -estimate -responsibilities -##mel -backup -laying -consumed -sealed -zurich -lovers -frustrated -##eau -ahmed -kicking -mit -treasurer -1832 -biblical -refuse -terrified -pump -agrees -genuine -imprisonment -refuses -plymouth -##hen -lou -##nen -tara -trembling -antarctic -ton -learns -##tas -crap -crucial -faction -atop -##borough -wrap -lancaster -odds -hopkins -erik -lyon -##eon -bros -##ode -snap -locality -tips -empress -crowned -cal -acclaimed -chuckled -##ory -clara -sends -mild -towel -##fl -##day -##а -wishing -assuming -interviewed -##bal -##die -interactions -eden -cups -helena -##lf -indie -beck -##fire -batteries -filipino -wizard -parted -##lam -traces -##born -rows -idol -albany -delegates -##ees -##sar -discussions -##ex -notre -instructed -belgrade -highways -suggestion -lauren -possess -orientation -alexandria -abdul -beats -salary -reunion -ludwig -alright -wagner -intimate -pockets -slovenia -hugged -brighton -merchants -cruel -stole -trek -slopes -repairs -enrollment -politically -underlying -promotional -counting -boeing -##bb -isabella -naming -##и -keen -bacteria -listing -separately -belfast -ussr -450 -lithuanian -anybody -ribs -sphere -martinez -cock -embarrassed -proposals -fragments -nationals -##fs -##wski -premises -fin -1500 -alpine -matched -freely -bounded -jace -sleeve -##af -gaming -pier -populated -evident -##like -frances -flooded -##dle -frightened -pour -trainer -framed -visitor -challenging -pig -wickets -##fold -infected -email -##pes -arose -##aw -reward -ecuador -oblast -vale -ch -shuttle -##usa -bach -rankings -forbidden -cornwall -accordance -salem -consumers -bruno -fantastic -toes -machinery -resolved -julius -remembering -propaganda -iceland -bombardment -tide -contacts -wives -##rah -concerto -macdonald -albania -implement -daisy -tapped -sudan -helmet -angela -mistress -##lic -crop -sunk -finest -##craft -hostile -##ute -##tsu -boxer -fr -paths -adjusted -habit -ballot -supervision -soprano -##zen -bullets -wicked -sunset -regiments -disappear -lamp -performs -app -##gia -##oa -rabbit -digging -incidents -entries -##cion -dishes -##oi -introducing -##ati -##fied -freshman -slot -jill -tackles -baroque -backs -##iest -lone -sponsor -destiny -altogether -convert -##aro -consensus -shapes -demonstration -basically -feminist -auction -artifacts -##bing -strongest -twitter -halifax -2019 -allmusic -mighty -smallest -precise -alexandra -viola -##los -##ille -manuscripts -##illo -dancers -ari -managers -monuments -blades -barracks -springfield -maiden -consolidated -electron -##end -berry -airing -wheat -nobel -inclusion -blair -payments -geography -bee -cc -eleanor -react -##hurst -afc -manitoba -##yu -su -lineup -fitness -recreational -investments -airborne -disappointment -##dis -edmonton -viewing -##row -renovation -##cast -infant -bankruptcy -roses -aftermath -pavilion -##yer -carpenter -withdrawal -ladder -##hy -discussing -popped -reliable -agreements -rochester -##abad -curves -bombers -220 -rao -reverend -decreased -choosing -107 -stiff -consulting -naples -crawford -tracy -ka -ribbon -cops -##lee -crushed -deciding -unified -teenager -accepting -flagship -explorer -poles -sanchez -inspection -revived -skilled -induced -exchanged -flee -locals -tragedy -swallow -loading -hanna -demonstrate -##ela -salvador -flown -contestants -civilization -##ines -wanna -rhodes -fletcher -hector -knocking -considers -##ough -nash -mechanisms -sensed -mentally -walt -unclear -##eus -renovated -madame -##cks -crews -governmental -##hin -undertaken -monkey -##ben -##ato -fatal -armored -copa -caves -governance -grasp -perception -certification -froze -damp -tugged -wyoming -##rg -##ero -newman -##lor -nerves -curiosity -graph -115 -##ami -withdraw -tunnels -dull -meredith -moss -exhibits -neighbors -communicate -accuracy -explored -raiders -republicans -secular -kat -superman -penny -criticised -##tch -freed -update -conviction -wade -ham -likewise -delegation -gotta -doll -promises -technological -myth -nationality -resolve -convent -##mark -sharon -dig -sip -coordinator -entrepreneur -fold -##dine -capability -councillor -synonym -blown -swan -cursed -1815 -jonas -haired -sofa -canvas -keeper -rivalry -##hart -rapper -speedway -swords -postal -maxwell -estonia -potter -recurring -##nn -##ave -errors -##oni -cognitive -1834 -##² -claws -nadu -roberto -bce -wrestler -ellie -##ations -infinite -ink -##tia -presumably -finite -staircase -108 -noel -patricia -nacional -##cation -chill -eternal -tu -preventing -prussia -fossil -limbs -##logist -ernst -frog -perez -rene -##ace -pizza -prussian -##ios -##vy -molecules -regulatory -answering -opinions -sworn -lengths -supposedly -hypothesis -upward -habitats -seating -ancestors -drank -yield -hd -synthesis -researcher -modest -##var -mothers -peered -voluntary -homeland -##the -acclaim -##igan -static -valve -luxembourg -alto -carroll -fe -receptor -norton -ambulance -##tian -johnston -catholics -depicting -jointly -elephant -gloria -mentor -badge -ahmad -distinguish -remarked -councils -precisely -allison -advancing -detection -crowded -##10 -cooperative -ankle -mercedes -dagger -surrendered -pollution -commit -subway -jeffrey -lesson -sculptures -provider -##fication -membrane -timothy -rectangular -fiscal -heating -teammate -basket -particle -anonymous -deployment -##ple -missiles -courthouse -proportion -shoe -sec -##ller -complaints -forbes -blacks -abandon -remind -sizes -overwhelming -autobiography -natalie -##awa -risks -contestant -countryside -babies -scorer -invaded -enclosed -proceed -hurling -disorders -##cu -reflecting -continuously -cruiser -graduates -freeway -investigated -ore -deserved -maid -blocking -phillip -jorge -shakes -dove -mann -variables -lacked -burden -accompanying -que -consistently -organizing -provisional -complained -endless -##rm -tubes -juice -georges -krishna -mick -labels -thriller -##uch -laps -arcade -sage -snail -##table -shannon -fi -laurence -seoul -vacation -presenting -hire -churchill -surprisingly -prohibited -savannah -technically -##oli -170 -##lessly -testimony -suited -speeds -toys -romans -mlb -flowering -measurement -talented -kay -settings -charleston -expectations -shattered -achieving -triumph -ceremonies -portsmouth -lanes -mandatory -loser -stretching -cologne -realizes -seventy -cornell -careers -webb -##ulating -americas -budapest -ava -suspicion -##ison -yo -conrad -##hai -sterling -jessie -rector -##az -1831 -transform -organize -loans -christine -volcanic -warrant -slender -summers -subfamily -newer -danced -dynamics -rhine -proceeds -heinrich -gastropod -commands -sings -facilitate -easter -ra -positioned -responses -expense -fruits -yanked -imported -25th -velvet -vic -primitive -tribune -baldwin -neighbourhood -donna -rip -hay -pr -##uro -1814 -espn -welcomed -##aria -qualifier -glare -highland -timing -##cted -shells -eased -geometry -louder -exciting -slovakia -##sion -##iz -##lot -savings -prairie -##ques -marching -rafael -tonnes -##lled -curtain -preceding -shy -heal -greene -worthy -##pot -detachment -bury -sherman -##eck -reinforced -seeks -bottles -contracted -duchess -outfit -walsh -##sc -mickey -##ase -geoffrey -archer -squeeze -dawson -eliminate -invention -##enberg -neal -##eth -stance -dealer -coral -maple -retire -polo -simplified -##ht -1833 -hid -watts -backwards -jules -##oke -genesis -mt -frames -rebounds -burma -woodland -moist -santos -whispers -drained -subspecies -##aa -streaming -ulster -burnt -correspondence -maternal -gerard -denis -stealing -##load -genius -duchy -##oria -inaugurated -momentum -suits -placement -sovereign -clause -thames -##hara -confederation -reservation -sketch -yankees -lets -rotten -charm -hal -verses -ultra -commercially -dot -salon -citation -adopt -winnipeg -mist -allocated -cairo -##boy -jenkins -interference -objectives -##wind -1820 -portfolio -armoured -sectors -##eh -initiatives -##world -integrity -exercises -robe -tap -ab -gazed -##tones -distracted -rulers -111 -favorable -jerome -tended -cart -factories -##eri -diplomat -valued -gravel -charitable -##try -calvin -exploring -chang -shepherd -terrace -pdf -pupil -##ural -reflects -ups -##rch -governors -shelf -depths -##nberg -trailed -crest -tackle -##nian -##ats -hatred -##kai -clare -makers -ethiopia -longtime -detected -embedded -lacking -slapped -rely -thomson -anticipation -iso -morton -successive -agnes -screenwriter -straightened -philippe -playwright -haunted -licence -iris -intentions -sutton -112 -logical -correctly -##weight -branded -licked -tipped -silva -ricky -narrator -requests -##ents -greeted -supernatural -cow -##wald -lung -refusing -employer -strait -gaelic -liner -##piece -zoe -sabha -##mba -driveway -harvest -prints -bates -reluctantly -threshold -algebra -ira -wherever -coupled -240 -assumption -picks -##air -designers -raids -gentlemen -##ean -roller -blowing -leipzig -locks -screw -dressing -strand -##lings -scar -dwarf -depicts -##nu -nods -##mine -differ -boris -##eur -yuan -flip -##gie -mob -invested -questioning -applying -##ture -shout -##sel -gameplay -blamed -illustrations -bothered -weakness -rehabilitation -##of -##zes -envelope -rumors -miners -leicester -subtle -kerry -##ico -ferguson -##fu -premiership -ne -##cat -bengali -prof -catches -remnants -dana -##rily -shouting -presidents -baltic -ought -ghosts -dances -sailors -shirley -fancy -dominic -##bie -madonna -##rick -bark -buttons -gymnasium -ashes -liver -toby -oath -providence -doyle -evangelical -nixon -cement -carnegie -embarked -hatch -surroundings -guarantee -needing -pirate -essence -##bee -filter -crane -hammond -projected -immune -percy -twelfth -##ult -regent -doctoral -damon -mikhail -##ichi -lu -critically -elect -realised -abortion -acute -screening -mythology -steadily -##fc -frown -nottingham -kirk -wa -minneapolis -##rra -module -algeria -mc -nautical -encounters -surprising -statues -availability -shirts -pie -alma -brows -munster -mack -soup -crater -tornado -sanskrit -cedar -explosive -bordered -dixon -planets -stamp -exam -happily -##bble -carriers -kidnapped -##vis -accommodation -emigrated -##met -knockout -correspondent -violation -profits -peaks -lang -specimen -agenda -ancestry -pottery -spelling -equations -obtaining -ki -linking -1825 -debris -asylum -##20 -buddhism -teddy -##ants -gazette -##nger -##sse -dental -eligibility -utc -fathers -averaged -zimbabwe -francesco -coloured -hissed -translator -lynch -mandate -humanities -mackenzie -uniforms -lin -##iana -##gio -asset -mhz -fitting -samantha -genera -wei -rim -beloved -shark -riot -entities -expressions -indo -carmen -slipping -owing -abbot -neighbor -sidney -##av -rats -recommendations -encouraging -squadrons -anticipated -commanders -conquered -##oto -donations -diagnosed -##mond -divide -##iva -guessed -decoration -vernon -auditorium -revelation -conversations -##kers -##power -herzegovina -dash -alike -protested -lateral -herman -accredited -mg -##gent -freeman -mel -fiji -crow -crimson -##rine -livestock -##pped -humanitarian -bored -oz -whip -##lene -##ali -legitimate -alter -grinning -spelled -anxious -oriental -wesley -##nin -##hole -carnival -controller -detect -##ssa -bowed -educator -kosovo -macedonia -##sin -occupy -mastering -stephanie -janeiro -para -unaware -nurses -noon -135 -cam -hopefully -ranger -combine -sociology -polar -rica -##eer -neill -##sman -holocaust -##ip -doubled -lust -1828 -109 -decent -cooling -unveiled -##card -1829 -nsw -homer -chapman -meyer -##gin -dive -mae -reagan -expertise -##gled -darwin -brooke -sided -prosecution -investigating -comprised -petroleum -genres -reluctant -differently -trilogy -johns -vegetables -corpse -highlighted -lounge -pension -unsuccessfully -elegant -aided -ivory -beatles -amelia -cain -dubai -sunny -immigrant -babe -click -##nder -underwater -pepper -combining -mumbled -atlas -horns -accessed -ballad -physicians -homeless -gestured -rpm -freak -louisville -corporations -patriots -prizes -rational -warn -modes -decorative -overnight -din -troubled -phantom -##ort -monarch -sheer -##dorf -generals -guidelines -organs -addresses -##zon -enhance -curling -parishes -cord -##kie -linux -caesar -deutsche -bavaria -##bia -coleman -cyclone -##eria -bacon -petty -##yama -##old -hampton -diagnosis -1824 -throws -complexity -rita -disputed -##₃ -pablo -##sch -marketed -trafficking -##ulus -examine -plague -formats -##oh -vault -faithful -##bourne -webster -##ox -highlights -##ient -##ann -phones -vacuum -sandwich -modeling -##gated -bolivia -clergy -qualities -isabel -##nas -##ars -wears -screams -reunited -annoyed -bra -##ancy -##rate -differential -transmitter -tattoo -container -poker -##och -excessive -resides -cowboys -##tum -augustus -trash -providers -statute -retreated -balcony -reversed -void -storey -preceded -masses -leap -laughs -neighborhoods -wards -schemes -falcon -santo -battlefield -pad -ronnie -thread -lesbian -venus -##dian -beg -sandstone -daylight -punched -gwen -analog -stroked -wwe -acceptable -measurements -dec -toxic -##kel -adequate -surgical -economist -parameters -varsity -##sberg -quantity -ella -##chy -##rton -countess -generating -precision -diamonds -expressway -ga -##ı -1821 -uruguay -talents -galleries -expenses -scanned -colleague -outlets -ryder -lucien -##ila -paramount -##bon -syracuse -dim -fangs -gown -sweep -##sie -toyota -missionaries -websites -##nsis -sentences -adviser -val -trademark -spells -##plane -patience -starter -slim -##borg -toe -incredibly -shoots -elliot -nobility -##wyn -cowboy -endorsed -gardner -tendency -persuaded -organisms -emissions -kazakhstan -amused -boring -chips -themed -##hand -llc -constantinople -chasing -systematic -guatemala -borrowed -erin -carey -##hard -highlands -struggles -1810 -##ifying -##ced -wong -exceptions -develops -enlarged -kindergarten -castro -##ern -##rina -leigh -zombie -juvenile -##most -consul -##nar -sailor -hyde -clarence -intensive -pinned -nasty -useless -jung -clayton -stuffed -exceptional -ix -apostolic -230 -transactions -##dge -exempt -swinging -cove -religions -##ash -shields -dairy -bypass -190 -pursuing -bug -joyce -bombay -chassis -southampton -chat -interact -redesignated -##pen -nascar -pray -salmon -rigid -regained -malaysian -grim -publicity -constituted -capturing -toilet -delegate -purely -tray -drift -loosely -striker -weakened -trinidad -mitch -itv -defines -transmitted -ming -scarlet -nodding -fitzgerald -fu -narrowly -sp -tooth -standings -virtue -##₁ -##wara -##cting -chateau -gloves -lid -##nel -hurting -conservatory -##pel -sinclair -reopened -sympathy -nigerian -strode -advocated -optional -chronic -discharge -##rc -suck -compatible -laurel -stella -shi -fails -wage -dodge -128 -informal -sorts -levi -buddha -villagers -##aka -chronicles -heavier -summoned -gateway -3000 -eleventh -jewelry -translations -accordingly -seas -##ency -fiber -pyramid -cubic -dragging -##ista -caring -##ops -android -contacted -lunar -##dt -kai -lisbon -patted -1826 -sacramento -theft -madagascar -subtropical -disputes -ta -holidays -piper -willow -mare -cane -itunes -newfoundland -benny -companions -dong -raj -observe -roar -charming -plaque -tibetan -fossils -enacted -manning -bubble -tina -tanzania -##eda -##hir -funk -swamp -deputies -cloak -ufc -scenario -par -scratch -metals -anthem -guru -engaging -specially -##boat -dialects -nineteen -cecil -duet -disability -messenger -unofficial -##lies -defunct -eds -moonlight -drainage -surname -puzzle -honda -switching -conservatives -mammals -knox -broadcaster -sidewalk -cope -##ried -benson -princes -peterson -##sal -bedford -sharks -eli -wreck -alberto -gasp -archaeology -lgbt -teaches -securities -madness -compromise -waving -coordination -davidson -visions -leased -possibilities -eighty -jun -fernandez -enthusiasm -assassin -sponsorship -reviewer -kingdoms -estonian -laboratories -##fy -##nal -applies -verb -celebrations -##zzo -rowing -lightweight -sadness -submit -mvp -balanced -dude -##vas -explicitly -metric -magnificent -mound -brett -mohammad -mistakes -irregular -##hing -##ass -sanders -betrayed -shipped -surge -##enburg -reporters -termed -georg -pity -verbal -bulls -abbreviated -enabling -appealed -##are -##atic -sicily -sting -heel -sweetheart -bart -spacecraft -brutal -monarchy -##tter -aberdeen -cameo -diane -##ub -survivor -clyde -##aries -complaint -##makers -clarinet -delicious -chilean -karnataka -coordinates -1818 -panties -##rst -pretending -ar -dramatically -kiev -bella -tends -distances -113 -catalog -launching -instances -telecommunications -portable -lindsay -vatican -##eim -angles -aliens -marker -stint -screens -bolton -##rne -judy -wool -benedict -plasma -europa -spark -imaging -filmmaker -swiftly -##een -contributor -##nor -opted -stamps -apologize -financing -butter -gideon -sophisticated -alignment -avery -chemicals -yearly -speculation -prominence -professionally -##ils -immortal -institutional -inception -wrists -identifying -tribunal -derives -gains -##wo -papal -preference -linguistic -vince -operative -brewery -##ont -unemployment -boyd -##ured -##outs -albeit -prophet -1813 -bi -##rr -##face -##rad -quarterly -asteroid -cleaned -radius -temper -##llen -telugu -jerk -viscount -menu -##ote -glimpse -##aya -yacht -hawaiian -baden -##rl -laptop -readily -##gu -monetary -offshore -scots -watches -##yang -##arian -upgrade -needle -xbox -lea -encyclopedia -flank -fingertips -##pus -delight -teachings -confirm -roth -beaches -midway -winters -##iah -teasing -daytime -beverly -gambling -bonnie -##backs -regulated -clement -hermann -tricks -knot -##shing -##uring -##vre -detached -ecological -owed -specialty -byron -inventor -bats -stays -screened -unesco -midland -trim -affection -##ander -##rry -jess -thoroughly -feedback -##uma -chennai -strained -heartbeat -wrapping -overtime -pleaded -##sworth -mon -leisure -oclc -##tate -##ele -feathers -angelo -thirds -nuts -surveys -clever -gill -commentator -##dos -darren -rides -gibraltar -##nc -##mu -dissolution -dedication -shin -meals -saddle -elvis -reds -chaired -taller -appreciation -functioning -niece -favored -advocacy -robbie -criminals -suffolk -yugoslav -passport -constable -congressman -hastings -vera -##rov -consecrated -sparks -ecclesiastical -confined -##ovich -muller -floyd -nora -1822 -paved -1827 -cumberland -ned -saga -spiral -##flow -appreciated -yi -collaborative -treating -similarities -feminine -finishes -##ib -jade -import -##nse -##hot -champagne -mice -securing -celebrities -helsinki -attributes -##gos -cousins -phases -ache -lucia -gandhi -submission -vicar -spear -shine -tasmania -biting -detention -constitute -tighter -seasonal -##gus -terrestrial -matthews -##oka -effectiveness -parody -philharmonic -##onic -1816 -strangers -encoded -consortium -guaranteed -regards -shifts -tortured -collision -supervisor -inform -broader -insight -theaters -armour -emeritus -blink -incorporates -mapping -##50 -##ein -handball -flexible -##nta -substantially -generous -thief -##own -carr -loses -1793 -prose -ucla -romeo -generic -metallic -realization -damages -mk -commissioners -zach -default -##ther -helicopters -lengthy -stems -spa -partnered -spectators -rogue -indication -penalties -teresa -1801 -sen -##tric -dalton -##wich -irving -photographic -##vey -dell -deaf -peters -excluded -unsure -##vable -patterson -crawled -##zio -resided -whipped -latvia -slower -ecole -pipes -employers -maharashtra -comparable -va -textile -pageant -##gel -alphabet -binary -irrigation -chartered -choked -antoine -offs -waking -supplement -##wen -quantities -demolition -regain -locate -urdu -folks -alt -114 -##mc -scary -andreas -whites -##ava -classrooms -mw -aesthetic -publishes -valleys -guides -cubs -johannes -bryant -conventions -affecting -##itt -drain -awesome -isolation -prosecutor -ambitious -apology -captive -downs -atmospheric -lorenzo -aisle -beef -foul -##onia -kidding -composite -disturbed -illusion -natives -##ffer -emi -rockets -riverside -wartime -painters -adolf -melted -##ail -uncertainty -simulation -hawks -progressed -meantime -builder -spray -breach -unhappy -regina -russians -##urg -determining -##tation -tram -1806 -##quin -aging -##12 -1823 -garion -rented -mister -diaz -terminated -clip -1817 -depend -nervously -disco -owe -defenders -shiva -notorious -disbelief -shiny -worcester -##gation -##yr -trailing -undertook -islander -belarus -limitations -watershed -fuller -overlooking -utilized -raphael -1819 -synthetic -breakdown -klein -##nate -moaned -memoir -lamb -practicing -##erly -cellular -arrows -exotic -##graphy -witches -117 -charted -rey -hut -hierarchy -subdivision -freshwater -giuseppe -aloud -reyes -qatar -marty -sideways -utterly -sexually -jude -prayers -mccarthy -softball -blend -damien -##gging -##metric -wholly -erupted -lebanese -negro -revenues -tasted -comparative -teamed -transaction -labeled -maori -sovereignty -parkway -trauma -gran -malay -121 -advancement -descendant -2020 -buzz -salvation -inventory -symbolic -##making -antarctica -mps -##gas -##bro -mohammed -myanmar -holt -submarines -tones -##lman -locker -patriarch -bangkok -emerson -remarks -predators -kin -afghan -confession -norwich -rental -emerge -advantages -##zel -rca -##hold -shortened -storms -aidan -##matic -autonomy -compliance -##quet -dudley -atp -##osis -1803 -motto -documentation -summary -professors -spectacular -christina -archdiocese -flashing -innocence -remake -##dell -psychic -reef -scare -employ -rs -sticks -meg -gus -leans -##ude -accompany -bergen -tomas -##iko -doom -wages -pools -##nch -##bes -breasts -scholarly -alison -outline -brittany -breakthrough -willis -realistic -##cut -##boro -competitor -##stan -pike -picnic -icon -designing -commercials -washing -villain -skiing -micro -costumes -auburn -halted -executives -##hat -logistics -cycles -vowel -applicable -barrett -exclaimed -eurovision -eternity -ramon -##umi -##lls -modifications -sweeping -disgust -##uck -torch -aviv -ensuring -rude -dusty -sonic -donovan -outskirts -cu -pathway -##band -##gun -##lines -disciplines -acids -cadet -paired -##40 -sketches -##sive -marriages -##⁺ -folding -peers -slovak -implies -admired -##beck -1880s -leopold -instinct -attained -weston -megan -horace -##ination -dorsal -ingredients -evolutionary -##its -complications -deity -lethal -brushing -levy -deserted -institutes -posthumously -delivering -telescope -coronation -motivated -rapids -luc -flicked -pays -volcano -tanner -weighed -##nica -crowds -frankie -gifted -addressing -granddaughter -winding -##rna -constantine -gomez -##front -landscapes -rudolf -anthropology -slate -werewolf -##lio -astronomy -circa -rouge -dreaming -sack -knelt -drowned -naomi -prolific -tracked -freezing -herb -##dium -agony -randall -twisting -wendy -deposit -touches -vein -wheeler -##bbled -##bor -batted -retaining -tire -presently -compare -specification -daemon -nigel -##grave -merry -recommendation -czechoslovakia -sandra -ng -roma -##sts -lambert -inheritance -sheikh -winchester -cries -examining -##yle -comeback -cuisine -nave -##iv -ko -retrieve -tomatoes -barker -polished -defining -irene -lantern -personalities -begging -tract -swore -1809 -175 -##gic -omaha -brotherhood -##rley -haiti -##ots -exeter -##ete -##zia -steele -dumb -pearson -210 -surveyed -elisabeth -trends -##ef -fritz -##rf -premium -bugs -fraction -calmly -viking -##birds -tug -inserted -unusually -##ield -confronted -distress -crashing -brent -turks -resign -##olo -cambodia -gabe -sauce -##kal -evelyn -116 -extant -clusters -quarry -teenagers -luna -##lers -##ister -affiliation -drill -##ashi -panthers -scenic -libya -anita -strengthen -inscriptions -##cated -lace -sued -judith -riots -##uted -mint -##eta -preparations -midst -dub -challenger -##vich -mock -cf -displaced -wicket -breaths -enables -schmidt -analyst -##lum -ag -highlight -automotive -axe -josef -newark -sufficiently -resembles -50th -##pal -flushed -mum -traits -##ante -commodore -incomplete -warming -titular -ceremonial -ethical -118 -celebrating -eighteenth -cao -lima -medalist -mobility -strips -snakes -##city -miniature -zagreb -barton -escapes -umbrella -automated -doubted -differs -cooled -georgetown -dresden -cooked -fade -wyatt -rna -jacobs -carlton -abundant -stereo -boost -madras -inning -##hia -spur -ip -malayalam -begged -osaka -groan -escaping -charging -dose -vista -##aj -bud -papa -communists -advocates -edged -tri -##cent -resemble -peaking -necklace -fried -montenegro -saxony -goose -glances -stuttgart -curator -recruit -grocery -sympathetic -##tting -##fort -127 -lotus -randolph -ancestor -##rand -succeeding -jupiter -1798 -macedonian -##heads -hiking -1808 -handing -fischer -##itive -garbage -node -##pies -prone -singular -papua -inclined -attractions -italia -pouring -motioned -grandma -garnered -jacksonville -corp -ego -ringing -aluminum -##hausen -ordering -##foot -drawer -traders -synagogue -##play -##kawa -resistant -wandering -fragile -fiona -teased -var -hardcore -soaked -jubilee -decisive -exposition -mercer -poster -valencia -hale -kuwait -1811 -##ises -##wr -##eed -tavern -gamma -122 -johan -##uer -airways -amino -gil -##ury -vocational -domains -torres -##sp -generator -folklore -outcomes -##keeper -canberra -shooter -fl -beams -confrontation -##lling -##gram -feb -aligned -forestry -pipeline -jax -motorway -conception -decay -##tos -coffin -##cott -stalin -1805 -escorted -minded -##nam -sitcom -purchasing -twilight -veronica -additions -passive -tensions -straw -123 -frequencies -1804 -refugee -cultivation -##iate -christie -clary -bulletin -crept -disposal -##rich -##zong -processor -crescent -##rol -bmw -emphasized -whale -nazis -aurora -##eng -dwelling -hauled -sponsors -toledo -mega -ideology -theatres -tessa -cerambycidae -saves -turtle -cone -suspects -kara -rusty -yelling -greeks -mozart -shades -cocked -participant -##tro -shire -spit -freeze -necessity -##cos -inmates -nielsen -councillors -loaned -uncommon -omar -peasants -botanical -offspring -daniels -formations -jokes -1794 -pioneers -sigma -licensing -##sus -wheelchair -polite -1807 -liquor -pratt -trustee -##uta -forewings -balloon -##zz -kilometre -camping -explicit -casually -shawn -foolish -teammates -nm -hassan -carrie -judged -satisfy -vanessa -knives -selective -cnn -flowed -##lice -eclipse -stressed -eliza -mathematician -cease -cultivated -##roy -commissions -browns -##ania -destroyers -sheridan -meadow -##rius -minerals -##cial -downstream -clash -gram -memoirs -ventures -baha -seymour -archie -midlands -edith -fare -flynn -invite -canceled -tiles -stabbed -boulder -incorporate -amended -camden -facial -mollusk -unreleased -descriptions -yoga -grabs -550 -raises -ramp -shiver -##rose -coined -pioneering -tunes -qing -warwick -tops -119 -melanie -giles -##rous -wandered -##inal -annexed -nov -30th -unnamed -##ished -organizational -airplane -normandy -stoke -whistle -blessing -violations -chased -holders -shotgun -##ctic -outlet -reactor -##vik -tires -tearing -shores -fortified -mascot -constituencies -nc -columnist -productive -tibet -##rta -lineage -hooked -oct -tapes -judging -cody -##gger -hansen -kashmir -triggered -##eva -solved -cliffs -##tree -resisted -anatomy -protesters -transparent -implied -##iga -injection -mattress -excluding -##mbo -defenses -helpless -devotion -##elli -growl -liberals -weber -phenomena -atoms -plug -##iff -mortality -apprentice -howe -convincing -aaa -swimmer -barber -leone -promptly -sodium -def -nowadays -arise -##oning -gloucester -corrected -dignity -norm -erie -##ders -elders -evacuated -sylvia -compression -##yar -hartford -pose -backpack -reasoning -accepts -24th -wipe -millimetres -marcel -##oda -dodgers -albion -1790 -overwhelmed -aerospace -oaks -1795 -showcase -acknowledge -recovering -nolan -ashe -hurts -geology -fashioned -disappearance -farewell -swollen -shrug -marquis -wimbledon -124 -rue -1792 -commemorate -reduces -experiencing -inevitable -calcutta -intel -##court -murderer -sticking -fisheries -imagery -bloom -280 -brake -##inus -gustav -hesitation -memorable -po -viral -beans -accidents -tunisia -antenna -spilled -consort -treatments -aye -perimeter -##gard -donation -hostage -migrated -banker -addiction -apex -lil -trout -##ously -conscience -##nova -rams -sands -genome -passionate -troubles -##lets -##set -amid -##ibility -##ret -higgins -exceed -vikings -##vie -payne -##zan -muscular -##ste -defendant -sucking -##wal -ibrahim -fuselage -claudia -vfl -europeans -snails -interval -##garh -preparatory -statewide -tasked -lacrosse -viktor -##lation -angola -##hra -flint -implications -employs -teens -patrons -stall -weekends -barriers -scrambled -nucleus -tehran -jenna -parsons -lifelong -robots -displacement -5000 -##bles -precipitation -##gt -knuckles -clutched -1802 -marrying -ecology -marx -accusations -declare -scars -kolkata -mat -meadows -bermuda -skeleton -finalists -vintage -crawl -coordinate -affects -subjected -orchestral -mistaken -##tc -mirrors -dipped -relied -260 -arches -candle -##nick -incorporating -wildly -fond -basilica -owl -fringe -rituals -whispering -stirred -feud -tertiary -slick -goat -honorable -whereby -skip -ricardo -stripes -parachute -adjoining -submerged -synthesizer -##gren -intend -positively -ninety -phi -beaver -partition -fellows -alexis -prohibition -carlisle -bizarre -fraternity -##bre -doubts -icy -cbc -aquatic -sneak -sonny -combines -airports -crude -supervised -spatial -merge -alfonso -##bic -corrupt -scan -undergo -##ams -disabilities -colombian -comparing -dolphins -perkins -##lish -reprinted -unanimous -bounced -hairs -underworld -midwest -semester -bucket -paperback -miniseries -coventry -demise -##leigh -demonstrations -sensor -rotating -yan -##hler -arrange -soils -##idge -hyderabad -labs -##dr -brakes -grandchildren -##nde -negotiated -rover -ferrari -continuation -directorate -augusta -stevenson -counterpart -gore -##rda -nursery -rican -ave -collectively -broadly -pastoral -repertoire -asserted -discovering -nordic -styled -fiba -cunningham -harley -middlesex -survives -tumor -tempo -zack -aiming -lok -urgent -##rade -##nto -devils -##ement -contractor -turin -##wl -##ool -bliss -repaired -simmons -moan -astronomical -cr -negotiate -lyric -1890s -lara -bred -clad -angus -pbs -##ience -engineered -posed -##lk -hernandez -possessions -elbows -psychiatric -strokes -confluence -electorate -lifts -campuses -lava -alps -##ep -##ution -##date -physicist -woody -##page -##ographic -##itis -juliet -reformation -sparhawk -320 -complement -suppressed -jewel -##½ -floated -##kas -continuity -sadly -##ische -inability -melting -scanning -paula -flour -judaism -safer -vague -##lm -solving -curb -##stown -financially -gable -bees -expired -miserable -cassidy -dominion -1789 -cupped -145 -robbery -facto -amos -warden -resume -tallest -marvin -ing -pounded -usd -declaring -gasoline -##aux -darkened -270 -650 -sophomore -##mere -erection -gossip -televised -risen -dial -##eu -pillars -##link -passages -profound -##tina -arabian -ashton -silicon -nail -##ead -##lated -##wer -##hardt -fleming -firearms -ducked -circuits -blows -waterloo -titans -##lina -atom -fireplace -cheshire -financed -activation -algorithms -##zzi -constituent -catcher -cherokee -partnerships -sexuality -platoon -tragic -vivian -guarded -whiskey -meditation -poetic -##late -##nga -##ake -porto -listeners -dominance -kendra -mona -chandler -factions -22nd -salisbury -attitudes -derivative -##ido -##haus -intake -paced -javier -illustrator -barrels -bias -cockpit -burnett -dreamed -ensuing -##anda -receptors -someday -hawkins -mattered -##lal -slavic -1799 -jesuit -cameroon -wasted -tai -wax -lowering -victorious -freaking -outright -hancock -librarian -sensing -bald -calcium -myers -tablet -announcing -barack -shipyard -pharmaceutical -##uan -greenwich -flush -medley -patches -wolfgang -pt -speeches -acquiring -exams -nikolai -##gg -hayden -kannada -##type -reilly -##pt -waitress -abdomen -devastated -capped -pseudonym -pharmacy -fulfill -paraguay -1796 -clicked -##trom -archipelago -syndicated -##hman -lumber -orgasm -rejection -clifford -lorraine -advent -mafia -rodney -brock -##ght -##used -##elia -cassette -chamberlain -despair -mongolia -sensors -developmental -upstream -##eg -##alis -spanning -165 -trombone -basque -seeded -interred -renewable -rhys -leapt -revision -molecule -##ages -chord -vicious -nord -shivered -23rd -arlington -debts -corpus -sunrise -bays -blackburn -centimetres -##uded -shuddered -gm -strangely -gripping -cartoons -isabelle -orbital -##ppa -seals -proving -##lton -refusal -strengthened -bust -assisting -baghdad -batsman -portrayal -mara -pushes -spears -og -##cock -reside -nathaniel -brennan -1776 -confirmation -caucus -##worthy -markings -yemen -nobles -ku -lazy -viewer -catalan -encompasses -sawyer -##fall -sparked -substances -patents -braves -arranger -evacuation -sergio -persuade -dover -tolerance -penguin -cum -jockey -insufficient -townships -occupying -declining -plural -processed -projection -puppet -flanders -introduces -liability -##yon -gymnastics -antwerp -taipei -hobart -candles -jeep -wes -observers -126 -chaplain -bundle -glorious -##hine -hazel -flung -sol -excavations -dumped -stares -sh -bangalore -triangular -icelandic -intervals -expressing -turbine -##vers -songwriting -crafts -##igo -jasmine -ditch -rite -##ways -entertaining -comply -sorrow -wrestlers -basel -emirates -marian -rivera -helpful -##some -caution -downward -networking -##atory -##tered -darted -genocide -emergence -replies -specializing -spokesman -convenient -unlocked -fading -augustine -concentrations -resemblance -elijah -investigator -andhra -##uda -promotes -bean -##rrell -fleeing -wan -simone -announcer -##ame -##bby -lydia -weaver -132 -residency -modification -##fest -stretches -##ast -alternatively -nat -lowe -lacks -##ented -pam -tile -concealed -inferior -abdullah -residences -tissues -vengeance -##ided -moisture -peculiar -groove -zip -bologna -jennings -ninja -oversaw -zombies -pumping -batch -livingston -emerald -installations -1797 -peel -nitrogen -rama -##fying -##star -schooling -strands -responding -werner -##ost -lime -casa -accurately -targeting -##rod -underway -##uru -hemisphere -lester -##yard -occupies -2d -griffith -angrily -reorganized -##owing -courtney -deposited -##dd -##30 -estadio -##ifies -dunn -exiled -##ying -checks -##combe -##о -##fly -successes -unexpectedly -blu -assessed -##flower -##ه -observing -sacked -spiders -kn -##tail -mu -nodes -prosperity -audrey -divisional -155 -broncos -tangled -adjust -feeds -erosion -paolo -surf -directory -snatched -humid -admiralty -screwed -gt -reddish -##nese -modules -trench -lamps -bind -leah -bucks -competes -##nz -##form -transcription -##uc -isles -violently -clutching -pga -cyclist -inflation -flats -ragged -unnecessary -##hian -stubborn -coordinated -harriet -baba -disqualified -330 -insect -wolfe -##fies -reinforcements -rocked -duel -winked -embraced -bricks -##raj -hiatus -defeats -pending -brightly -jealousy -##xton -##hm -##uki -lena -gdp -colorful -##dley -stein -kidney -##shu -underwear -wanderers -##haw -##icus -guardians -m³ -roared -habits -##wise -permits -gp -uranium -punished -disguise -bundesliga -elise -dundee -erotic -partisan -pi -collectors -float -individually -rendering -behavioral -bucharest -ser -hare -valerie -corporal -nutrition -proportional -##isa -immense -##kis -pavement -##zie -##eld -sutherland -crouched -1775 -##lp -suzuki -trades -endurance -operas -crosby -prayed -priory -rory -socially -##urn -gujarat -##pu -walton -cube -pasha -privilege -lennon -floods -thorne -waterfall -nipple -scouting -approve -##lov -minorities -voter -dwight -extensions -assure -ballroom -slap -dripping -privileges -rejoined -confessed -demonstrating -patriotic -yell -investor -##uth -pagan -slumped -squares -##cle -##kins -confront -bert -embarrassment -##aid -aston -urging -sweater -starr -yuri -brains -williamson -commuter -mortar -structured -selfish -exports -##jon -cds -##him -unfinished -##rre -mortgage -destinations -##nagar -canoe -solitary -buchanan -delays -magistrate -fk -##pling -motivation -##lier -##vier -recruiting -assess -##mouth -malik -antique -1791 -pius -rahman -reich -tub -zhou -smashed -airs -galway -xii -conditioning -honduras -discharged -dexter -##pf -lionel -129 -debates -lemon -tiffany -volunteered -dom -dioxide -procession -devi -sic -tremendous -advertisements -colts -transferring -verdict -hanover -decommissioned -utter -relate -pac -racism -##top -beacon -limp -similarity -terra -occurrence -ant -##how -becky -capt -updates -armament -richie -pal -##graph -halloween -mayo -##ssen -##bone -cara -serena -fcc -dolls -obligations -##dling -violated -lafayette -jakarta -exploitation -##ime -infamous -iconic -##lah -##park -kitty -moody -reginald -dread -spill -crystals -olivier -modeled -bluff -equilibrium -separating -notices -ordnance -extinction -onset -cosmic -attachment -sammy -expose -privy -anchored -##bil -abbott -admits -bending -baritone -emmanuel -policeman -vaughan -winged -climax -dresses -denny -polytechnic -mohamed -burmese -authentic -nikki -genetics -grandparents -homestead -gaza -postponed -metacritic -una -##sby -##bat -unstable -dissertation -##rial -##cian -curls -obscure -uncovered -bronx -praying -disappearing -##hoe -prehistoric -coke -turret -mutations -nonprofit -pits -monaco -##ي -##usion -prominently -dispatched -podium -##mir -uci -##uation -133 -fortifications -birthplace -kendall -##lby -##oll -preacher -rack -goodman -##rman -persistent -##ott -countless -jaime -recorder -lexington -persecution -jumps -renewal -wagons -##11 -crushing -##holder -decorations -##lake -abundance -wrath -laundry -£1 -garde -##rp -jeanne -beetles -peasant -##sl -splitting -caste -sergei -##rer -##ema -scripts -##ively -rub -satellites -##vor -inscribed -verlag -scrapped -gale -packages -chick -potato -slogan -kathleen -arabs -##culture -counterparts -reminiscent -choral -##tead -rand -retains -bushes -dane -accomplish -courtesy -closes -##oth -slaughter -hague -krakow -lawson -tailed -elias -ginger -##ttes -canopy -betrayal -rebuilding -turf -##hof -frowning -allegiance -brigades -kicks -rebuild -polls -alias -nationalism -td -rowan -audition -bowie -fortunately -recognizes -harp -dillon -horrified -##oro -renault -##tics -ropes -##α -presumed -rewarded -infrared -wiping -accelerated -illustration -##rid -presses -practitioners -badminton -##iard -detained -##tera -recognizing -relates -misery -##sies -##tly -reproduction -piercing -potatoes -thornton -esther -manners -hbo -##aan -ours -bullshit -ernie -perennial -sensitivity -illuminated -rupert -##jin -##iss -##ear -rfc -nassau -##dock -staggered -socialism -##haven -appointments -nonsense -prestige -sharma -haul -##tical -solidarity -gps -##ook -##rata -igor -pedestrian -##uit -baxter -tenants -wires -medication -unlimited -guiding -impacts -diabetes -##rama -sasha -pas -clive -extraction -131 -continually -constraints -##bilities -sonata -hunted -sixteenth -chu -planting -quote -mayer -pretended -abs -spat -##hua -ceramic -##cci -curtains -pigs -pitching -##dad -latvian -sore -dayton -##sted -##qi -patrols -slice -playground -##nted -shone -stool -apparatus -inadequate -mates -treason -##ija -desires -##liga -##croft -somalia -laurent -mir -leonardo -oracle -grape -obliged -chevrolet -thirteenth -stunning -enthusiastic -##ede -accounted -concludes -currents -basil -##kovic -drought -##rica -mai -##aire -shove -posting -##shed -pilgrimage -humorous -packing -fry -pencil -wines -smells -144 -marilyn -aching -newest -clung -bon -neighbours -sanctioned -##pie -mug -##stock -drowning -##mma -hydraulic -##vil -hiring -reminder -lilly -investigators -##ncies -sour -##eous -compulsory -packet -##rion -##graphic -##elle -cannes -##inate -depressed -##rit -heroic -importantly -theresa -##tled -conway -saturn -marginal -rae -##xia -corresponds -royce -pact -jasper -explosives -packaging -aluminium -##ttered -denotes -rhythmic -spans -assignments -hereditary -outlined -originating -sundays -lad -reissued -greeting -beatrice -##dic -pillar -marcos -plots -handbook -alcoholic -judiciary -avant -slides -extract -masculine -blur -##eum -##force -homage -trembled -owens -hymn -trey -omega -signaling -socks -accumulated -reacted -attic -theo -lining -angie -distraction -primera -talbot -##key -1200 -ti -creativity -billed -##hey -deacon -eduardo -identifies -proposition -dizzy -gunner -hogan -##yam -##pping -##hol -ja -##chan -jensen -reconstructed -##berger -clearance -darius -##nier -abe -harlem -plea -dei -circled -emotionally -notation -fascist -neville -exceeded -upwards -viable -ducks -##fo -workforce -racer -limiting -shri -##lson -possesses -1600 -kerr -moths -devastating -laden -disturbing -locking -##cture -gal -fearing -accreditation -flavor -aide -1870s -mountainous -##baum -melt -##ures -motel -texture -servers -soda -##mb -herd -##nium -erect -puzzled -hum -peggy -examinations -gould -testified -geoff -ren -devised -sacks -##law -denial -posters -grunted -cesar -tutor -ec -gerry -offerings -byrne -falcons -combinations -ct -incoming -pardon -rocking -26th -avengers -flared -mankind -seller -uttar -loch -nadia -stroking -exposing -##hd -fertile -ancestral -instituted -##has -noises -prophecy -taxation -eminent -vivid -pol -##bol -dart -indirect -multimedia -notebook -upside -displaying -adrenaline -referenced -geometric -##iving -progression -##ddy -blunt -announce -##far -implementing -##lav -aggression -liaison -cooler -cares -headache -plantations -gorge -dots -impulse -thickness -ashamed -averaging -kathy -obligation -precursor -137 -fowler -symmetry -thee -225 -hears -##rai -undergoing -ads -butcher -bowler -##lip -cigarettes -subscription -goodness -##ically -browne -##hos -##tech -kyoto -donor -##erty -damaging -friction -drifting -expeditions -hardened -prostitution -152 -fauna -blankets -claw -tossing -snarled -butterflies -recruits -investigative -coated -healed -138 -communal -hai -xiii -academics -boone -psychologist -restless -lahore -stephens -mba -brendan -foreigners -printer -##pc -ached -explode -27th -deed -scratched -dared -##pole -cardiac -1780 -okinawa -proto -commando -compelled -oddly -electrons -##base -replica -thanksgiving -##rist -sheila -deliberate -stafford -tidal -representations -hercules -ou -##path -##iated -kidnapping -lenses -##tling -deficit -samoa -mouths -consuming -computational -maze -granting -smirk -razor -fixture -ideals -inviting -aiden -nominal -##vs -issuing -julio -pitt -ramsey -docks -##oss -exhaust -##owed -bavarian -draped -anterior -mating -ethiopian -explores -noticing -##nton -discarded -convenience -hoffman -endowment -beasts -cartridge -mormon -paternal -probe -sleeves -interfere -lump -deadline -##rail -jenks -bulldogs -scrap -alternating -justified -reproductive -nam -seize -descending -secretariat -kirby -coupe -grouped -smash -panther -sedan -tapping -##18 -lola -cheer -germanic -unfortunate -##eter -unrelated -##fan -subordinate -##sdale -suzanne -advertisement -##ility -horsepower -##lda -cautiously -discourse -luigi -##mans -##fields -noun -prevalent -mao -schneider -everett -surround -governorate -kira -##avia -westward -##take -misty -rails -sustainability -134 -unused -##rating -packs -toast -unwilling -regulate -thy -suffrage -nile -awe -assam -definitions -travelers -affordable -##rb -conferred -sells -undefeated -beneficial -torso -basal -repeating -remixes -##pass -bahrain -cables -fang -##itated -excavated -numbering -statutory -##rey -deluxe -##lian -forested -ramirez -derbyshire -zeus -slamming -transfers -astronomer -banana -lottery -berg -histories -bamboo -##uchi -resurrection -posterior -bowls -vaguely -##thi -thou -preserving -tensed -offence -##inas -meyrick -callum -ridden -watt -langdon -tying -lowland -snorted -daring -truman -##hale -##girl -aura -overly -filing -weighing -goa -infections -philanthropist -saunders -eponymous -##owski -latitude -perspectives -reviewing -mets -commandant -radial -##kha -flashlight -reliability -koch -vowels -amazed -ada -elaine -supper -##rth -##encies -predator -debated -soviets -cola -##boards -##nah -compartment -crooked -arbitrary -fourteenth -##ctive -havana -majors -steelers -clips -profitable -ambush -exited -packers -##tile -nude -cracks -fungi -##е -limb -trousers -josie -shelby -tens -frederic -##ος -definite -smoothly -constellation -insult -baton -discs -lingering -##nco -conclusions -lent -staging -becker -grandpa -shaky -##tron -einstein -obstacles -sk -adverse -elle -economically -##moto -mccartney -thor -dismissal -motions -readings -nostrils -treatise -##pace -squeezing -evidently -prolonged -1783 -venezuelan -je -marguerite -beirut -takeover -shareholders -##vent -denise -digit -airplay -norse -##bbling -imaginary -pills -hubert -blaze -vacated -eliminating -##ello -vine -mansfield -##tty -retrospective -barrow -borne -clutch -bail -forensic -weaving -##nett -##witz -desktop -citadel -promotions -worrying -dorset -ieee -subdivided -##iating -manned -expeditionary -pickup -synod -chuckle -185 -barney -##rz -##ffin -functionality -karachi -litigation -meanings -uc -lick -turbo -anders -##ffed -execute -curl -oppose -ankles -typhoon -##د -##ache -##asia -linguistics -compassion -pressures -grazing -perfection -##iting -immunity -monopoly -muddy -backgrounds -136 -namibia -francesca -monitors -attracting -stunt -tuition -##ии -vegetable -##mates -##quent -mgm -jen -complexes -forts -##ond -cellar -bites -seventeenth -royals -flemish -failures -mast -charities -##cular -peruvian -capitals -macmillan -ipswich -outward -frigate -postgraduate -folds -employing -##ouse -concurrently -fiery -##tai -contingent -nightmares -monumental -nicaragua -##kowski -lizard -mal -fielding -gig -reject -##pad -harding -##ipe -coastline -##cin -##nos -beethoven -humphrey -innovations -##tam -##nge -norris -doris -solicitor -huang -obey -141 -##lc -niagara -##tton -shelves -aug -bourbon -curry -nightclub -specifications -hilton -##ndo -centennial -dispersed -worm -neglected -briggs -sm -font -kuala -uneasy -plc -##nstein -##bound -##aking -##burgh -awaiting -pronunciation -##bbed -##quest -eh -optimal -zhu -raped -greens -presided -brenda -worries -##life -venetian -marxist -turnout -##lius -refined -braced -sins -grasped -sunderland -nickel -speculated -lowell -cyrillic -communism -fundraising -resembling -colonists -mutant -freddie -usc -##mos -gratitude -##run -mural -##lous -chemist -wi -reminds -28th -steals -tess -pietro -##ingen -promoter -ri -microphone -honoured -rai -sant -##qui -feather -##nson -burlington -kurdish -terrorists -deborah -sickness -##wed -##eet -hazard -irritated -desperation -veil -clarity -##rik -jewels -xv -##gged -##ows -##cup -berkshire -unfair -mysteries -orchid -winced -exhaustion -renovations -stranded -obe -infinity -##nies -adapt -redevelopment -thanked -registry -olga -domingo -noir -tudor -ole -##atus -commenting -behaviors -##ais -crisp -pauline -probable -stirling -wigan -##bian -paralympics -panting -surpassed -##rew -luca -barred -pony -famed -##sters -cassandra -waiter -carolyn -exported -##orted -andres -destructive -deeds -jonah -castles -vacancy -suv -##glass -1788 -orchard -yep -famine -belarusian -sprang -##forth -skinny -##mis -administrators -rotterdam -zambia -zhao -boiler -discoveries -##ride -##physics -lucius -disappointing -outreach -spoon -##frame -qualifications -unanimously -enjoys -regency -##iidae -stade -realism -veterinary -rodgers -dump -alain -chestnut -castile -censorship -rumble -gibbs -##itor -communion -reggae -inactivated -logs -loads -##houses -homosexual -##iano -ale -informs -##cas -phrases -plaster -linebacker -ambrose -kaiser -fascinated -850 -limerick -recruitment -forge -mastered -##nding -leinster -rooted -threaten -##strom -borneo -##hes -suggestions -scholarships -propeller -documentaries -patronage -coats -constructing -invest -neurons -comet -entirety -shouts -identities -annoying -unchanged -wary -##antly -##ogy -neat -oversight -##kos -phillies -replay -constance -##kka -incarnation -humble -skies -minus -##acy -smithsonian -##chel -guerrilla -jar -cadets -##plate -surplus -audit -##aru -cracking -joanna -louisa -pacing -##lights -intentionally -##iri -diner -nwa -imprint -australians -tong -unprecedented -bunker -naive -specialists -ark -nichols -railing -leaked -pedal -##uka -shrub -longing -roofs -v8 -captains -neural -tuned -##ntal -##jet -emission -medina -frantic -codex -definitive -sid -abolition -intensified -stocks -enrique -sustain -genoa -oxide -##written -clues -cha -##gers -tributaries -fragment -venom -##rity -##ente -##sca -muffled -vain -sire -laos -##ingly -##hana -hastily -snapping -surfaced -sentiment -motive -##oft -contests -approximate -mesa -luckily -dinosaur -exchanges -propelled -accord -bourne -relieve -tow -masks -offended -##ues -cynthia -##mmer -rains -bartender -zinc -reviewers -lois -##sai -legged -arrogant -rafe -rosie -comprise -handicap -blockade -inlet -lagoon -copied -drilling -shelley -petals -##inian -mandarin -obsolete -##inated -onward -arguably -productivity -cindy -praising -seldom -busch -discusses -raleigh -shortage -ranged -stanton -encouragement -firstly -conceded -overs -temporal -##uke -cbe -##bos -woo -certainty -pumps -##pton -stalked -##uli -lizzie -periodic -thieves -weaker -##night -gases -shoving -chooses -wc -##chemical -prompting -weights -##kill -robust -flanked -sticky -hu -tuberculosis -##eb -##eal -christchurch -resembled -wallet -reese -inappropriate -pictured -distract -fixing -fiddle -giggled -burger -heirs -hairy -mechanic -torque -apache -obsessed -chiefly -cheng -logging -##tag -extracted -meaningful -numb -##vsky -gloucestershire -reminding -##bay -unite -##lit -breeds -diminished -clown -glove -1860s -##ن -##ug -archibald -focal -freelance -sliced -depiction -##yk -organism -switches -sights -stray -crawling -##ril -lever -leningrad -interpretations -loops -anytime -reel -alicia -delighted -##ech -inhaled -xiv -suitcase -bernie -vega -licenses -northampton -exclusion -induction -monasteries -racecourse -homosexuality -##right -##sfield -##rky -dimitri -michele -alternatives -ions -commentators -genuinely -objected -pork -hospitality -fencing -stephan -warships -peripheral -wit -drunken -wrinkled -quentin -spends -departing -chung -numerical -spokesperson -##zone -johannesburg -caliber -killers -##udge -assumes -neatly -demographic -abigail -bloc -##vel -mounting -##lain -bentley -slightest -xu -recipients -##jk -merlin -##writer -seniors -prisons -blinking -hindwings -flickered -kappa -##hel -80s -strengthening -appealing -brewing -gypsy -mali -lashes -hulk -unpleasant -harassment -bio -treaties -predict -instrumentation -pulp -troupe -boiling -mantle -##ffe -ins -##vn -dividing -handles -verbs -##onal -coconut -senegal -340 -thorough -gum -momentarily -##sto -cocaine -panicked -destined -##turing -teatro -denying -weary -captained -mans -##hawks -##code -wakefield -bollywood -thankfully -##16 -cyril -##wu -amendments -##bahn -consultation -stud -reflections -kindness -1787 -internally -##ovo -tex -mosaic -distribute -paddy -seeming -143 -##hic -piers -##15 -##mura -##verse -popularly -winger -kang -sentinel -mccoy -##anza -covenant -##bag -verge -fireworks -suppress -thrilled -dominate -##jar -swansea -##60 -142 -reconciliation -##ndi -stiffened -cue -dorian -##uf -damascus -amor -ida -foremost -##aga -porsche -unseen -dir -##had -##azi -stony -lexi -melodies -##nko -angular -integer -podcast -ants -inherent -jaws -justify -persona -##olved -josephine -##nr -##ressed -customary -flashes -gala -cyrus -glaring -backyard -ariel -physiology -greenland -html -stir -avon -atletico -finch -methodology -ked -##lent -mas -catholicism -townsend -branding -quincy -fits -containers -1777 -ashore -aragon -##19 -forearm -poisoning -##sd -adopting -conquer -grinding -amnesty -keller -finances -evaluate -forged -lankan -instincts -##uto -guam -bosnian -photographed -workplace -desirable -protector -##dog -allocation -intently -encourages -willy -##sten -bodyguard -electro -brighter -##ν -bihar -##chev -lasts -opener -amphibious -sal -verde -arte -##cope -captivity -vocabulary -yields -##tted -agreeing -desmond -pioneered -##chus -strap -campaigned -railroads -##ович -emblem -##dre -stormed -501 -##ulous -marijuana -northumberland -##gn -##nath -bowen -landmarks -beaumont -##qua -danube -##bler -attorneys -th -ge -flyers -critique -villains -cass -mutation -acc -##0s -colombo -mckay -motif -sampling -concluding -syndicate -##rell -neon -stables -ds -warnings -clint -mourning -wilkinson -##tated -merrill -leopard -evenings -exhaled -emil -sonia -ezra -discrete -stove -farrell -fifteenth -prescribed -superhero -##rier -worms -helm -wren -##duction -##hc -expo -##rator -hq -unfamiliar -antony -prevents -acceleration -fiercely -mari -painfully -calculations -cheaper -ign -clifton -irvine -davenport -mozambique -##np -pierced -##evich -wonders -##wig -##cate -##iling -crusade -ware -##uel -enzymes -reasonably -mls -##coe -mater -ambition -bunny -eliot -kernel -##fin -asphalt -headmaster -torah -aden -lush -pins -waived -##care -##yas -joao -substrate -enforce -##grad -##ules -alvarez -selections -epidemic -tempted -##bit -bremen -translates -ensured -waterfront -29th -forrest -manny -malone -kramer -reigning -cookies -simpler -absorption -205 -engraved -##ffy -evaluated -1778 -haze -146 -comforting -crossover -##abe -thorn -##rift -##imo -##pop -suppression -fatigue -cutter -##tr -201 -wurttemberg -##orf -enforced -hovering -proprietary -gb -samurai -syllable -ascent -lacey -tick -lars -tractor -merchandise -rep -bouncing -defendants -##yre -huntington -##ground -##oko -standardized -##hor -##hima -assassinated -nu -predecessors -rainy -liar -assurance -lyrical -##uga -secondly -flattened -ios -parameter -undercover -##mity -bordeaux -punish -ridges -markers -exodus -inactive -hesitate -debbie -nyc -pledge -savoy -nagar -offset -organist -##tium -hesse -marin -converting -##iver -diagram -propulsion -pu -validity -reverted -supportive -##dc -ministries -clans -responds -proclamation -##inae -##ø -##rea -ein -pleading -patriot -sf -birch -islanders -strauss -hates -##dh -brandenburg -concession -rd -##ob -1900s -killings -textbook -antiquity -cinematography -wharf -embarrassing -setup -creed -farmland -inequality -centred -signatures -fallon -370 -##ingham -##uts -ceylon -gazing -directive -laurie -##tern -globally -##uated -##dent -allah -excavation -threads -##cross -148 -frantically -icc -utilize -determines -respiratory -thoughtful -receptions -##dicate -merging -chandra -seine -147 -builders -builds -diagnostic -dev -visibility -goddamn -analyses -dhaka -cho -proves -chancel -concurrent -curiously -canadians -pumped -restoring -1850s -turtles -jaguar -sinister -spinal -traction -declan -vows -1784 -glowed -capitalism -swirling -install -universidad -##lder -##oat -soloist -##genic -##oor -coincidence -beginnings -nissan -dip -resorts -caucasus -combustion -infectious -##eno -pigeon -serpent -##itating -conclude -masked -salad -jew -##gr -surreal -toni -##wc -harmonica -151 -##gins -##etic -##coat -fishermen -intending -bravery -##wave -klaus -titan -wembley -taiwanese -ransom -40th -incorrect -hussein -eyelids -jp -cooke -dramas -utilities -##etta -##print -eisenhower -principally -granada -lana -##rak -openings -concord -##bl -bethany -connie -morality -sega -##mons -##nard -earnings -##kara -##cine -wii -communes -##rel -coma -composing -softened -severed -grapes -##17 -nguyen -analyzed -warlord -hubbard -heavenly -behave -slovenian -##hit -##ony -hailed -filmmakers -trance -caldwell -skye -unrest -coward -likelihood -##aging -bern -sci -taliban -honolulu -propose -##wang -1700 -browser -imagining -cobra -contributes -dukes -instinctively -conan -violinist -##ores -accessories -gradual -##amp -quotes -sioux -##dating -undertake -intercepted -sparkling -compressed -139 -fungus -tombs -haley -imposing -rests -degradation -lincolnshire -retailers -wetlands -tulsa -distributor -dungeon -nun -greenhouse -convey -atlantis -aft -exits -oman -dresser -lyons -##sti -joking -eddy -judgement -omitted -digits -##cts -##game -juniors -##rae -cents -stricken -une -##ngo -wizards -weir -breton -nan -technician -fibers -liking -royalty -##cca -154 -persia -terribly -magician -##rable -##unt -vance -cafeteria -booker -camille -warmer -##static -consume -cavern -gaps -compass -contemporaries -foyer -soothing -graveyard -maj -plunged -blush -##wear -cascade -demonstrates -ordinance -##nov -boyle -##lana -rockefeller -shaken -banjo -izzy -##ense -breathless -vines -##32 -##eman -alterations -chromosome -dwellings -feudal -mole -153 -catalonia -relics -tenant -mandated -##fm -fridge -hats -honesty -patented -raul -heap -cruisers -accusing -enlightenment -infants -wherein -chatham -contractors -zen -affinity -hc -osborne -piston -156 -traps -maturity -##rana -lagos -##zal -peering -##nay -attendant -dealers -protocols -subset -prospects -biographical -##cre -artery -##zers -insignia -nuns -endured -##eration -recommend -schwartz -serbs -berger -cromwell -crossroads -##ctor -enduring -clasped -grounded -##bine -marseille -twitched -abel -choke -https -catalyst -moldova -italians -##tist -disastrous -wee -##oured -##nti -wwf -nope -##piration -##asa -expresses -thumbs -167 -##nza -coca -1781 -cheating -##ption -skipped -sensory -heidelberg -spies -satan -dangers -semifinal -202 -bohemia -whitish -confusing -shipbuilding -relies -surgeons -landings -ravi -baku -moor -suffix -alejandro -##yana -litre -upheld -##unk -rajasthan -##rek -coaster -insists -posture -scenarios -etienne -favoured -appoint -transgender -elephants -poked -greenwood -defences -fulfilled -militant -somali -1758 -chalk -potent -##ucci -migrants -wink -assistants -nos -restriction -activism -niger -##ario -colon -shaun -##sat -daphne -##erated -swam -congregations -reprise -considerations -magnet -playable -xvi -##р -overthrow -tobias -knob -chavez -coding -##mers -propped -katrina -orient -newcomer -##suke -temperate -##pool -farmhouse -interrogation -##vd -committing -##vert -forthcoming -strawberry -joaquin -macau -ponds -shocking -siberia -##cellular -chant -contributors -##nant -##ologists -sped -absorb -hail -1782 -spared -##hore -barbados -karate -opus -originates -saul -##xie -evergreen -leaped -##rock -correlation -exaggerated -weekday -unification -bump -tracing -brig -afb -pathways -utilizing -##ners -mod -mb -disturbance -kneeling -##stad -##guchi -100th -pune -##thy -decreasing -168 -manipulation -miriam -academia -ecosystem -occupational -rbi -##lem -rift -##14 -rotary -stacked -incorporation -awakening -generators -guerrero -racist -##omy -cyber -derivatives -culminated -allie -annals -panzer -sainte -wikipedia -pops -zu -austro -##vate -algerian -politely -nicholson -mornings -educate -tastes -thrill -dartmouth -##gating -db -##jee -regan -differing -concentrating -choreography -divinity -##media -pledged -alexandre -routing -gregor -madeline -##idal -apocalypse -##hora -gunfire -culminating -elves -fined -liang -lam -programmed -tar -guessing -transparency -gabrielle -##gna -cancellation -flexibility -##lining -accession -shea -stronghold -nets -specializes -##rgan -abused -hasan -sgt -ling -exceeding -##₄ -admiration -supermarket -##ark -photographers -specialised -tilt -resonance -hmm -perfume -380 -sami -threatens -garland -botany -guarding -boiled -greet -puppy -russo -supplier -wilmington -vibrant -vijay -##bius -paralympic -grumbled -paige -faa -licking -margins -hurricanes -##gong -fest -grenade -ripping -##uz -counseling -weigh -##sian -needles -wiltshire -edison -costly -##not -fulton -tramway -redesigned -staffordshire -cache -gasping -watkins -sleepy -candidacy -##group -monkeys -timeline -throbbing -##bid -##sos -berth -uzbekistan -vanderbilt -bothering -overturned -ballots -gem -##iger -sunglasses -subscribers -hooker -compelling -ang -exceptionally -saloon -stab -##rdi -carla -terrifying -rom -##vision -coil -##oids -satisfying -vendors -31st -mackay -deities -overlooked -ambient -bahamas -felipe -olympia -whirled -botanist -advertised -tugging -##dden -disciples -morales -unionist -rites -foley -morse -motives -creepy -##₀ -soo -##sz -bargain -highness -frightening -turnpike -tory -reorganization -##cer -depict -biographer -##walk -unopposed -manifesto -##gles -institut -emile -accidental -kapoor -##dam -kilkenny -cortex -lively -##13 -romanesque -jain -shan -cannons -##ood -##ske -petrol -echoing -amalgamated -disappears -cautious -proposes -sanctions -trenton -##ر -flotilla -aus -contempt -tor -canary -cote -theirs -##hun -conceptual -deleted -fascinating -paso -blazing -elf -honourable -hutchinson -##eiro -##outh -##zin -surveyor -tee -amidst -wooded -reissue -intro -##ono -cobb -shelters -newsletter -hanson -brace -encoding -confiscated -dem -caravan -marino -scroll -melodic -cows -imam -##adi -##aneous -northward -searches -biodiversity -cora -310 -roaring -##bers -connell -theologian -halo -compose -pathetic -unmarried -dynamo -##oot -az -calculation -toulouse -deserves -humour -nr -forgiveness -tam -undergone -martyr -pamela -myths -whore -counselor -hicks -290 -heavens -battleship -electromagnetic -##bbs -stellar -establishments -presley -hopped -##chin -temptation -90s -wills -nas -##yuan -nhs -##nya -seminars -##yev -adaptations -gong -asher -lex -indicator -sikh -tobago -cites -goin -##yte -satirical -##gies -characterised -correspond -bubbles -lure -participates -##vid -eruption -skate -therapeutic -1785 -canals -wholesale -defaulted -sac -460 -petit -##zzled -virgil -leak -ravens -256 -portraying -##yx -ghetto -creators -dams -portray -vicente -##rington -fae -namesake -bounty -##arium -joachim -##ota -##iser -aforementioned -axle -snout -depended -dismantled -reuben -480 -##ibly -gallagher -##lau -##pd -earnest -##ieu -##iary -inflicted -objections -##llar -asa -gritted -##athy -jericho -##sea -##was -flick -underside -ceramics -undead -substituted -195 -eastward -undoubtedly -wheeled -chimney -##iche -guinness -cb -##ager -siding -##bell -traitor -baptiste -disguised -inauguration -149 -tipperary -choreographer -perched -warmed -stationary -eco -##ike -##ntes -bacterial -##aurus -flores -phosphate -##core -attacker -invaders -alvin -intersects -a1 -indirectly -immigrated -businessmen -cornelius -valves -narrated -pill -sober -ul -nationale -monastic -applicants -scenery -##jack -161 -motifs -constitutes -cpu -##osh -jurisdictions -sd -tuning -irritation -woven -##uddin -fertility -gao -##erie -antagonist -impatient -glacial -hides -boarded -denominations -interception -##jas -cookie -nicola -##tee -algebraic -marquess -bahn -parole -buyers -bait -turbines -paperwork -bestowed -natasha -renee -oceans -purchases -157 -vaccine -215 -##tock -fixtures -playhouse -integrate -jai -oswald -intellectuals -##cky -booked -nests -mortimer -##isi -obsession -sept -##gler -##sum -440 -scrutiny -simultaneous -squinted -##shin -collects -oven -shankar -penned -remarkably -##я -slips -luggage -spectral -1786 -collaborations -louie -consolidation -##ailed -##ivating -420 -hoover -blackpool -harness -ignition -vest -tails -belmont -mongol -skinner -##nae -visually -mage -derry -##tism -##unce -stevie -transitional -##rdy -redskins -drying -prep -prospective -##21 -annoyance -oversee -##loaded -fills -##books -##iki -announces -fda -scowled -respects -prasad -mystic -tucson -##vale -revue -springer -bankrupt -1772 -aristotle -salvatore -habsburg -##geny -dal -natal -nut -pod -chewing -darts -moroccan -walkover -rosario -lenin -punjabi -##ße -grossed -scattering -wired -invasive -hui -polynomial -corridors -wakes -gina -portrays -##cratic -arid -retreating -erich -irwin -sniper -##dha -linen -lindsey -maneuver -butch -shutting -socio -bounce -commemorative -postseason -jeremiah -pines -275 -mystical -beads -bp -abbas -furnace -bidding -consulted -assaulted -empirical -rubble -enclosure -sob -weakly -cancel -polly -yielded -##emann -curly -prediction -battered -70s -vhs -jacqueline -render -sails -barked -detailing -grayson -riga -sloane -raging -##yah -herbs -bravo -##athlon -alloy -giggle -imminent -suffers -assumptions -waltz -##itate -accomplishments -##ited -bathing -remixed -deception -prefix -##emia -deepest -##tier -##eis -balkan -frogs -##rong -slab -##pate -philosophers -peterborough -grains -imports -dickinson -rwanda -##atics -1774 -dirk -lan -tablets -##rove -clone -##rice -caretaker -hostilities -mclean -##gre -regimental -treasures -norms -impose -tsar -tango -diplomacy -variously -complain -192 -recognise -arrests -1779 -celestial -pulitzer -##dus -bing -libretto -##moor -adele -splash -##rite -expectation -lds -confronts -##izer -spontaneous -harmful -wedge -entrepreneurs -buyer -##ope -bilingual -translate -rugged -conner -circulated -uae -eaton -##gra -##zzle -lingered -lockheed -vishnu -reelection -alonso -##oom -joints -yankee -headline -cooperate -heinz -laureate -invading -##sford -echoes -scandinavian -##dham -hugging -vitamin -salute -micah -hind -trader -##sper -radioactive -##ndra -militants -poisoned -ratified -remark -campeonato -deprived -wander -prop -##dong -outlook -##tani -##rix -##eye -chiang -darcy -##oping -mandolin -spice -statesman -babylon -182 -walled -forgetting -afro -##cap -158 -giorgio -buffer -##polis -planetary -##gis -overlap -terminals -kinda -centenary -##bir -arising -manipulate -elm -ke -1770 -ak -##tad -chrysler -mapped -moose -pomeranian -quad -macarthur -assemblies -shoreline -recalls -stratford -##rted -noticeable -##evic -imp -##rita -##sque -accustomed -supplying -tents -disgusted -vogue -sipped -filters -khz -reno -selecting -luftwaffe -mcmahon -tyne -masterpiece -carriages -collided -dunes -exercised -flare -remembers -muzzle -##mobile -heck -##rson -burgess -lunged -middleton -boycott -bilateral -##sity -hazardous -lumpur -multiplayer -spotlight -jackets -goldman -liege -porcelain -rag -waterford -benz -attracts -hopeful -battling -ottomans -kensington -baked -hymns -cheyenne -lattice -levine -borrow -polymer -clashes -michaels -monitored -commitments -denounced -##25 -##von -cavity -##oney -hobby -akin -##holders -futures -intricate -cornish -patty -##oned -illegally -dolphin -##lag -barlow -yellowish -maddie -apologized -luton -plagued -##puram -nana -##rds -sway -fanny -łodz -##rino -psi -suspicions -hanged -##eding -initiate -charlton -##por -nak -competent -235 -analytical -annex -wardrobe -reservations -##rma -sect -162 -fairfax -hedge -piled -buckingham -uneven -bauer -simplicity -snyder -interpret -accountability -donors -moderately -byrd -continents -##cite -##max -disciple -hr -jamaican -ping -nominees -##uss -mongolian -diver -attackers -eagerly -ideological -pillows -miracles -apartheid -revolver -sulfur -clinics -moran -163 -##enko -ile -katy -rhetoric -##icated -chronology -recycling -##hrer -elongated -mughal -pascal -profiles -vibration -databases -domination -##fare -##rant -matthias -digest -rehearsal -polling -weiss -initiation -reeves -clinging -flourished -impress -ngo -##hoff -##ume -buckley -symposium -rhythms -weed -emphasize -transforming -##taking -##gence -##yman -accountant -analyze -flicker -foil -priesthood -voluntarily -decreases -##80 -##hya -slater -sv -charting -mcgill -##lde -moreno -##iu -besieged -zur -robes -##phic -admitting -api -deported -turmoil -peyton -earthquakes -##ares -nationalists -beau -clair -brethren -interrupt -welch -curated -galerie -requesting -164 -##ested -impending -steward -viper -##vina -complaining -beautifully -brandy -foam -nl -1660 -##cake -alessandro -punches -laced -explanations -##lim -attribute -clit -reggie -discomfort -##cards -smoothed -whales -##cene -adler -countered -duffy -disciplinary -widening -recipe -reliance -conducts -goats -gradient -preaching -##shaw -matilda -quasi -striped -meridian -cannabis -cordoba -certificates -##agh -##tering -graffiti -hangs -pilgrims -repeats -##ych -revive -urine -etat -##hawk -fueled -belts -fuzzy -susceptible -##hang -mauritius -salle -sincere -beers -hooks -##cki -arbitration -entrusted -advise -sniffed -seminar -junk -donnell -processors -principality -strapped -celia -mendoza -everton -fortunes -prejudice -starving -reassigned -steamer -##lund -tuck -evenly -foreman -##ffen -dans -375 -envisioned -slit -##xy -baseman -liberia -rosemary -##weed -electrified -periodically -potassium -stride -contexts -sperm -slade -mariners -influx -bianca -subcommittee -##rane -spilling -icao -estuary -##nock -delivers -iphone -##ulata -isa -mira -bohemian -dessert -##sbury -welcoming -proudly -slowing -##chs -musee -ascension -russ -##vian -waits -##psy -africans -exploit -##morphic -gov -eccentric -crab -peck -##ull -entrances -formidable -marketplace -groom -bolted -metabolism -patton -robbins -courier -payload -endure -##ifier -andes -refrigerator -##pr -ornate -##uca -ruthless -illegitimate -masonry -strasbourg -bikes -adobe -##³ -apples -quintet -willingly -niche -bakery -corpses -energetic -##cliffe -##sser -##ards -177 -centimeters -centro -fuscous -cretaceous -rancho -##yde -andrei -telecom -tottenham -oasis -ordination -vulnerability -presiding -corey -cp -penguins -sims -##pis -malawi -piss -##48 -correction -##cked -##ffle -##ryn -countdown -detectives -psychiatrist -psychedelic -dinosaurs -blouse -##get -choi -vowed -##oz -randomly -##pol -49ers -scrub -blanche -bruins -dusseldorf -##using -unwanted -##ums -212 -dominique -elevations -headlights -om -laguna -##oga -1750 -famously -ignorance -shrewsbury -##aine -ajax -breuning -che -confederacy -greco -overhaul -##screen -paz -skirts -disagreement -cruelty -jagged -phoebe -shifter -hovered -viruses -##wes -mandy -##lined -##gc -landlord -squirrel -dashed -##ι -ornamental -gag -wally -grange -literal -spurs -undisclosed -proceeding -yin -##text -billie -orphan -spanned -humidity -indy -weighted -presentations -explosions -lucian -##tary -vaughn -hindus -##anga -##hell -psycho -171 -daytona -protects -efficiently -rematch -sly -tandem -##oya -rebranded -impaired -hee -metropolis -peach -godfrey -diaspora -ethnicity -prosperous -gleaming -dar -grossing -playback -##rden -stripe -pistols -##tain -births -labelled -##cating -172 -rudy -alba -##onne -aquarium -hostility -##gb -##tase -shudder -sumatra -hardest -lakers -consonant -creeping -demos -homicide -capsule -zeke -liberties -expulsion -pueblo -##comb -trait -transporting -##ddin -##neck -##yna -depart -gregg -mold -ledge -hangar -oldham -playboy -termination -analysts -gmbh -romero -##itic -insist -cradle -filthy -brightness -slash -shootout -deposed -bordering -##truct -isis -microwave -tumbled -sheltered -cathy -werewolves -messy -andersen -convex -clapped -clinched -satire -wasting -edo -vc -rufus -##jak -mont -##etti -poznan -##keeping -restructuring -transverse -##rland -azerbaijani -slovene -gestures -roommate -choking -shear -##quist -vanguard -oblivious -##hiro -disagreed -baptism -##lich -coliseum -##aceae -salvage -societe -cory -locke -relocation -relying -versailles -ahl -swelling -##elo -cheerful -##word -##edes -gin -sarajevo -obstacle -diverted -##nac -messed -thoroughbred -fluttered -utrecht -chewed -acquaintance -assassins -dispatch -mirza -##wart -nike -salzburg -swell -yen -##gee -idle -ligue -samson -##nds -##igh -playful -spawned -##cise -tease -##case -burgundy -##bot -stirring -skeptical -interceptions -marathi -##dies -bedrooms -aroused -pinch -##lik -preferences -tattoos -buster -digitally -projecting -rust -##ital -kitten -priorities -addison -pseudo -##guard -dusk -icons -sermon -##psis -##iba -bt -##lift -##xt -ju -truce -rink -##dah -##wy -defects -psychiatry -offences -calculate -glucose -##iful -##rized -##unda -francaise -##hari -richest -warwickshire -carly -1763 -purity -redemption -lending -##cious -muse -bruises -cerebral -aero -carving -##name -preface -terminology -invade -monty -##int -anarchist -blurred -##iled -rossi -treats -guts -shu -foothills -ballads -undertaking -premise -cecilia -affiliates -blasted -conditional -wilder -minors -drone -rudolph -buffy -swallowing -horton -attested -##hop -rutherford -howell -primetime -livery -penal -##bis -minimize -hydro -wrecked -wrought -palazzo -##gling -cans -vernacular -friedman -nobleman -shale -walnut -danielle -##ection -##tley -sears -##kumar -chords -lend -flipping -streamed -por -dracula -gallons -sacrifices -gamble -orphanage -##iman -mckenzie -##gible -boxers -daly -##balls -##ان -208 -##ific -##rative -##iq -exploited -slated -##uity -circling -hillary -pinched -goldberg -provost -campaigning -lim -piles -ironically -jong -mohan -successors -usaf -##tem -##ught -autobiographical -haute -preserves -##ending -acquitted -comparisons -203 -hydroelectric -gangs -cypriot -torpedoes -rushes -chrome -derive -bumps -instability -fiat -pets -##mbe -silas -dye -reckless -settler -##itation -info -heats -##writing -176 -canonical -maltese -fins -mushroom -stacy -aspen -avid -##kur -##loading -vickers -gaston -hillside -statutes -wilde -gail -kung -sabine -comfortably -motorcycles -##rgo -169 -pneumonia -fetch -##sonic -axel -faintly -parallels -##oop -mclaren -spouse -compton -interdisciplinary -miner -##eni -181 -clamped -##chal -##llah -separates -versa -##mler -scarborough -labrador -##lity -##osing -rutgers -hurdles -como -166 -burt -divers -##100 -wichita -cade -coincided -##erson -bruised -mla -##pper -vineyard -##ili -##brush -notch -mentioning -jase -hearted -kits -doe -##acle -pomerania -##ady -ronan -seizure -pavel -problematic -##zaki -domenico -##ulin -catering -penelope -dependence -parental -emilio -ministerial -atkinson -##bolic -clarkson -chargers -colby -grill -peeked -arises -summon -##aged -fools -##grapher -faculties -qaeda -##vial -garner -refurbished -##hwa -geelong -disasters -nudged -bs -shareholder -lori -algae -reinstated -rot -##ades -##nous -invites -stainless -183 -inclusive -##itude -diocesan -til -##icz -denomination -##xa -benton -floral -registers -##ider -##erman -##kell -absurd -brunei -guangzhou -hitter -retaliation -##uled -##eve -blanc -nh -consistency -contamination -##eres -##rner -dire -palermo -broadcasters -diaries -inspire -vols -brewer -tightening -ky -mixtape -hormone -##tok -stokes -##color -##dly -##ssi -pg -##ometer -##lington -sanitation -##tility -intercontinental -apps -##adt -¹⁄₂ -cylinders -economies -favourable -unison -croix -gertrude -odyssey -vanity -dangling -##logists -upgrades -dice -middleweight -practitioner -##ight -206 -henrik -parlor -orion -angered -lac -python -blurted -##rri -sensual -intends -swings -angled -##phs -husky -attain -peerage -precinct -textiles -cheltenham -shuffled -dai -confess -tasting -bhutan -##riation -tyrone -segregation -abrupt -ruiz -##rish -smirked -blackwell -confidential -browning -amounted -##put -vase -scarce -fabulous -raided -staple -guyana -unemployed -glider -shay -##tow -carmine -troll -intervene -squash -superstar -##uce -cylindrical -len -roadway -researched -handy -##rium -##jana -meta -lao -declares -##rring -##tadt -##elin -##kova -willem -shrubs -napoleonic -realms -skater -qi -volkswagen -##ł -tad -hara -archaeologist -awkwardly -eerie -##kind -wiley -##heimer -##24 -titus -organizers -cfl -crusaders -lama -usb -vent -enraged -thankful -occupants -maximilian -##gaard -possessing -textbooks -##oran -collaborator -quaker -##ulo -avalanche -mono -silky -straits -isaiah -mustang -surged -resolutions -potomac -descend -cl -kilograms -plato -strains -saturdays -##olin -bernstein -##ype -holstein -ponytail -##watch -belize -conversely -heroine -perpetual -##ylus -charcoal -piedmont -glee -negotiating -backdrop -prologue -##jah -##mmy -pasadena -climbs -ramos -sunni -##holm -##tner -##tri -anand -deficiency -hertfordshire -stout -##avi -aperture -orioles -##irs -doncaster -intrigued -bombed -coating -otis -##mat -cocktail -##jit -##eto -amir -arousal -sar -##proof -##act -##ories -dixie -pots -##bow -whereabouts -159 -##fted -drains -bullying -cottages -scripture -coherent -fore -poe -appetite -##uration -sampled -##ators -##dp -derrick -rotor -jays -peacock -installment -##rro -advisors -##coming -rodeo -scotch -##mot -##db -##fen -##vant -ensued -rodrigo -dictatorship -martyrs -twenties -##н -towed -incidence -marta -rainforest -sai -scaled -##cles -oceanic -qualifiers -symphonic -mcbride -dislike -generalized -aubrey -colonization -##iation -##lion -##ssing -disliked -lublin -salesman -##ulates -spherical -whatsoever -sweating -avalon -contention -punt -severity -alderman -atari -##dina -##grant -##rop -scarf -seville -vertices -annexation -fairfield -fascination -inspiring -launches -palatinate -regretted -##rca -feral -##iom -elk -nap -olsen -reddy -yong -##leader -##iae -garment -transports -feng -gracie -outrage -viceroy -insides -##esis -breakup -grady -organizer -softer -grimaced -222 -murals -galicia -arranging -vectors -##rsten -bas -##sb -##cens -sloan -##eka -bitten -ara -fender -nausea -bumped -kris -banquet -comrades -detector -persisted -##llan -adjustment -endowed -cinemas -##shot -sellers -##uman -peek -epa -kindly -neglect -simpsons -talon -mausoleum -runaway -hangul -lookout -##cic -rewards -coughed -acquainted -chloride -##ald -quicker -accordion -neolithic -##qa -artemis -coefficient -lenny -pandora -tx -##xed -ecstasy -litter -segunda -chairperson -gemma -hiss -rumor -vow -nasal -antioch -compensate -patiently -transformers -##eded -judo -morrow -penis -posthumous -philips -bandits -husbands -denote -flaming -##any -##phones -langley -yorker -1760 -walters -##uo -##kle -gubernatorial -fatty -samsung -leroy -outlaw -##nine -unpublished -poole -jakob -##ᵢ -##ₙ -crete -distorted -superiority -##dhi -intercept -crust -mig -claus -crashes -positioning -188 -stallion -301 -frontal -armistice -##estinal -elton -aj -encompassing -camel -commemorated -malaria -woodward -calf -cigar -penetrate -##oso -willard -##rno -##uche -illustrate -amusing -convergence -noteworthy -##lma -##rva -journeys -realise -manfred -##sable -410 -##vocation -hearings -fiance -##posed -educators -provoked -adjusting -##cturing -modular -stockton -paterson -vlad -rejects -electors -selena -maureen -##tres -uber -##rce -swirled -##num -proportions -nanny -pawn -naturalist -parma -apostles -awoke -ethel -wen -##bey -monsoon -overview -##inating -mccain -rendition -risky -adorned -##ih -equestrian -germain -nj -conspicuous -confirming -##yoshi -shivering -##imeter -milestone -rumours -flinched -bounds -smacked -token -##bei -lectured -automobiles -##shore -impacted -##iable -nouns -nero -##leaf -ismail -prostitute -trams -##lace -bridget -sud -stimulus -impressions -reins -revolves -##oud -##gned -giro -honeymoon -##swell -criterion -##sms -##uil -libyan -prefers -##osition -211 -preview -sucks -accusation -bursts -metaphor -diffusion -tolerate -faye -betting -cinematographer -liturgical -specials -bitterly -humboldt -##ckle -flux -rattled -##itzer -archaeologists -odor -authorised -marshes -discretion -##ов -alarmed -archaic -inverse -##leton -explorers -##pine -drummond -tsunami -woodlands -##minate -##tland -booklet -insanity -owning -insert -crafted -calculus -##tore -receivers -##bt -stung -##eca -##nched -prevailing -travellers -eyeing -lila -graphs -##borne -178 -julien -##won -morale -adaptive -therapist -erica -cw -libertarian -bowman -pitches -vita -##ional -crook -##ads -##entation -caledonia -mutiny -##sible -1840s -automation -##ß -flock -##pia -ironic -pathology -##imus -remarried -##22 -joker -withstand -energies -##att -shropshire -hostages -madeleine -tentatively -conflicting -mateo -recipes -euros -ol -mercenaries -nico -##ndon -albuquerque -augmented -mythical -bel -freud -##child -cough -##lica -365 -freddy -lillian -genetically -nuremberg -calder -209 -bonn -outdoors -paste -suns -urgency -vin -restraint -tyson -##cera -##selle -barrage -bethlehem -kahn -##par -mounts -nippon -barony -happier -ryu -makeshift -sheldon -blushed -castillo -barking -listener -taped -bethel -fluent -headlines -pornography -rum -disclosure -sighing -mace -doubling -gunther -manly -##plex -rt -interventions -physiological -forwards -emerges -##tooth -##gny -compliment -rib -recession -visibly -barge -faults -connector -exquisite -prefect -##rlin -patio -##cured -elevators -brandt -italics -pena -173 -wasp -satin -ea -botswana -graceful -respectable -##jima -##rter -##oic -franciscan -generates -##dl -alfredo -disgusting -##olate -##iously -sherwood -warns -cod -promo -cheryl -sino -##ة -##escu -twitch -##zhi -brownish -thom -ortiz -##dron -densely -##beat -carmel -reinforce -##bana -187 -anastasia -downhill -vertex -contaminated -remembrance -harmonic -homework -##sol -fiancee -gears -olds -angelica -loft -ramsay -quiz -colliery -sevens -##cape -autism -##hil -walkway -##boats -ruben -abnormal -ounce -khmer -##bbe -zachary -bedside -morphology -punching -##olar -sparrow -convinces -##35 -hewitt -queer -remastered -rods -mabel -solemn -notified -lyricist -symmetric -##xide -174 -encore -passports -wildcats -##uni -baja -##pac -mildly -##ease -bleed -commodity -mounds -glossy -orchestras -##omo -damian -prelude -ambitions -##vet -awhile -remotely -##aud -asserts -imply -##iques -distinctly -modelling -remedy -##dded -windshield -dani -xiao -##endra -audible -powerplant -1300 -invalid -elemental -acquisitions -##hala -immaculate -libby -plata -smuggling -ventilation -denoted -minh -##morphism -430 -differed -dion -kelley -lore -mocking -sabbath -spikes -hygiene -drown -runoff -stylized -tally -liberated -aux -interpreter -righteous -aba -siren -reaper -pearce -millie -##cier -##yra -gaius -##iso -captures -##ttering -dorm -claudio -##sic -benches -knighted -blackness -##ored -discount -fumble -oxidation -routed -##ς -novak -perpendicular -spoiled -fracture -splits -##urt -pads -topology -##cats -axes -fortunate -offenders -protestants -esteem -221 -broadband -convened -frankly -hound -prototypes -isil -facilitated -keel -##sher -sahara -awaited -bubba -orb -prosecutors -186 -hem -520 -##xing -relaxing -remnant -romney -sorted -slalom -stefano -ulrich -##active -exemption -folder -pauses -foliage -hitchcock -epithet -204 -criticisms -##aca -ballistic -brody -hinduism -chaotic -youths -equals -##pala -pts -thicker -analogous -capitalist -improvised -overseeing -sinatra -ascended -beverage -##tl -straightforward -##kon -curran -##west -bois -325 -induce -surveying -emperors -sax -unpopular -##kk -cartoonist -fused -##mble -unto -##yuki -localities -##cko -##ln -darlington -slain -academie -lobbying -sediment -puzzles -##grass -defiance -dickens -manifest -tongues -alumnus -arbor -coincide -184 -appalachian -mustafa -examiner -cabaret -traumatic -yves -bracelet -draining -heroin -magnum -baths -odessa -consonants -mitsubishi -##gua -kellan -vaudeville -##fr -joked -null -straps -probation -##ław -ceded -interfaces -##pas -##zawa -blinding -viet -224 -rothschild -museo -640 -huddersfield -##vr -tactic -##storm -brackets -dazed -incorrectly -##vu -reg -glazed -fearful -manifold -benefited -irony -##sun -stumbling -##rte -willingness -balkans -mei -wraps -##aba -injected -##lea -gu -syed -harmless -##hammer -bray -takeoff -poppy -timor -cardboard -astronaut -purdue -weeping -southbound -cursing -stalls -diagonal -##neer -lamar -bryce -comte -weekdays -harrington -##uba -negatively -##see -lays -grouping -##cken -##henko -affirmed -halle -modernist -##lai -hodges -smelling -aristocratic -baptized -dismiss -justification -oilers -##now -coupling -qin -snack -healer -##qing -gardener -layla -battled -formulated -stephenson -gravitational -##gill -##jun -1768 -granny -coordinating -suites -##cd -##ioned -monarchs -##cote -##hips -sep -blended -apr -barrister -deposition -fia -mina -policemen -paranoid -##pressed -churchyard -covert -crumpled -creep -abandoning -tr -transmit -conceal -barr -understands -readiness -spire -##cology -##enia -##erry -610 -startling -unlock -vida -bowled -slots -##nat -##islav -spaced -trusting -admire -rig -##ink -slack -##70 -mv -207 -casualty -##wei -classmates -##odes -##rar -##rked -amherst -furnished -evolve -foundry -menace -mead -##lein -flu -wesleyan -##kled -monterey -webber -##vos -wil -##mith -##на -bartholomew -justices -restrained -##cke -amenities -191 -mediated -sewage -trenches -ml -mainz -##thus -1800s -##cula -##inski -caine -bonding -213 -converts -spheres -superseded -marianne -crypt -sweaty -ensign -historia -##br -spruce -##post -##ask -forks -thoughtfully -yukon -pamphlet -ames -##uter -karma -##yya -bryn -negotiation -sighs -incapable -##mbre -##ntial -actresses -taft -##mill -luce -prevailed -##amine -1773 -motionless -envoy -testify -investing -sculpted -instructors -provence -kali -cullen -horseback -##while -goodwin -##jos -gaa -norte -##ldon -modify -wavelength -abd -214 -skinned -sprinter -forecast -scheduling -marries -squared -tentative -##chman -boer -##isch -bolts -swap -fisherman -assyrian -impatiently -guthrie -martins -murdoch -194 -tanya -nicely -dolly -lacy -med -##45 -syn -decks -fashionable -millionaire -##ust -surfing -##ml -##ision -heaved -tammy -consulate -attendees -routinely -197 -fuse -saxophonist -backseat -malaya -##lord -scowl -tau -##ishly -193 -sighted -steaming -##rks -303 -911 -##holes -##hong -ching -##wife -bless -conserved -jurassic -stacey -unix -zion -chunk -rigorous -blaine -198 -peabody -slayer -dismay -brewers -nz -##jer -det -##glia -glover -postwar -int -penetration -sylvester -imitation -vertically -airlift -heiress -knoxville -viva -##uin -390 -macon -##rim -##fighter -##gonal -janice -##orescence -##wari -marius -belongings -leicestershire -196 -blanco -inverted -preseason -sanity -sobbing -##due -##elt -##dled -collingwood -regeneration -flickering -shortest -##mount -##osi -feminism -##lat -sherlock -cabinets -fumbled -northbound -precedent -snaps -##mme -researching -##akes -guillaume -insights -manipulated -vapor -neighbour -sap -gangster -frey -f1 -stalking -scarcely -callie -barnett -tendencies -audi -doomed -assessing -slung -panchayat -ambiguous -bartlett -##etto -distributing -violating -wolverhampton -##hetic -swami -histoire -##urus -liable -pounder -groin -hussain -larsen -popping -surprises -##atter -vie -curt -##station -mute -relocate -musicals -authorization -richter -##sef -immortality -tna -bombings -##press -deteriorated -yiddish -##acious -robbed -colchester -cs -pmid -ao -verified -balancing -apostle -swayed -recognizable -oxfordshire -retention -nottinghamshire -contender -judd -invitational -shrimp -uhf -##icient -cleaner -longitudinal -tanker -##mur -acronym -broker -koppen -sundance -suppliers -##gil -4000 -clipped -fuels -petite -##anne -landslide -helene -diversion -populous -landowners -auspices -melville -quantitative -##xes -ferries -nicky -##llus -doo -haunting -roche -carver -downed -unavailable -##pathy -approximation -hiroshima -##hue -garfield -valle -comparatively -keyboardist -traveler -##eit -congestion -calculating -subsidiaries -##bate -serb -modernization -fairies -deepened -ville -averages -##lore -inflammatory -tonga -##itch -co₂ -squads -##hea -gigantic -serum -enjoyment -retailer -verona -35th -cis -##phobic -magna -technicians -##vati -arithmetic -##sport -levin -##dation -amtrak -chow -sienna -##eyer -backstage -entrepreneurship -##otic -learnt -tao -##udy -worcestershire -formulation -baggage -hesitant -bali -sabotage -##kari -barren -enhancing -murmur -pl -freshly -putnam -syntax -aces -medicines -resentment -bandwidth -##sier -grins -chili -guido -##sei -framing -implying -gareth -lissa -genevieve -pertaining -admissions -geo -thorpe -proliferation -sato -bela -analyzing -parting -##gor -awakened -##isman -huddled -secrecy -##kling -hush -gentry -540 -dungeons -##ego -coasts -##utz -sacrificed -##chule -landowner -mutually -prevalence -programmer -adolescent -disrupted -seaside -gee -trusts -vamp -georgie -##nesian -##iol -schedules -sindh -##market -etched -hm -sparse -bey -beaux -scratching -gliding -unidentified -216 -collaborating -gems -jesuits -oro -accumulation -shaping -mbe -anal -##xin -231 -enthusiasts -newscast -##egan -janata -dewey -parkinson -179 -ankara -biennial -towering -dd -inconsistent -950 -##chet -thriving -terminate -cabins -furiously -eats -advocating -donkey -marley -muster -phyllis -leiden -##user -grassland -glittering -iucn -loneliness -217 -memorandum -armenians -##ddle -popularized -rhodesia -60s -lame -##illon -sans -bikini -header -orbits -##xx -##finger -##ulator -sharif -spines -biotechnology -strolled -naughty -yates -##wire -fremantle -milo -##mour -abducted -removes -##atin -humming -wonderland -##chrome -##ester -hume -pivotal -##rates -armand -grams -believers -elector -rte -apron -bis -scraped -##yria -endorsement -initials -##llation -eps -dotted -hints -buzzing -emigration -nearer -##tom -indicators -##ulu -coarse -neutron -protectorate -##uze -directional -exploits -pains -loire -1830s -proponents -guggenheim -rabbits -ritchie -305 -hectare -inputs -hutton -##raz -verify -##ako -boilers -longitude -##lev -skeletal -yer -emilia -citrus -compromised -##gau -pokemon -prescription -paragraph -eduard -cadillac -attire -categorized -kenyan -weddings -charley -##bourg -entertain -monmouth -##lles -nutrients -davey -mesh -incentive -practised -ecosystems -kemp -subdued -overheard -##rya -bodily -maxim -##nius -apprenticeship -ursula -##fight -lodged -rug -silesian -unconstitutional -patel -inspected -coyote -unbeaten -##hak -34th -disruption -convict -parcel -##cl -##nham -collier -implicated -mallory -##iac -##lab -susannah -winkler -##rber -shia -phelps -sediments -graphical -robotic -##sner -adulthood -mart -smoked -##isto -kathryn -clarified -##aran -divides -convictions -oppression -pausing -burying -##mt -federico -mathias -eileen -##tana -kite -hunched -##acies -189 -##atz -disadvantage -liza -kinetic -greedy -paradox -yokohama -dowager -trunks -ventured -##gement -gupta -vilnius -olaf -##thest -crimean -hopper -##ej -progressively -arturo -mouthed -arrondissement -##fusion -rubin -simulcast -oceania -##orum -##stra -##rred -busiest -intensely -navigator -cary -##vine -##hini -##bies -fife -rowe -rowland -posing -insurgents -shafts -lawsuits -activate -conor -inward -culturally -garlic -265 -##eering -eclectic -##hui -##kee -##nl -furrowed -vargas -meteorological -rendezvous -##aus -culinary -commencement -##dition -quota -##notes -mommy -salaries -overlapping -mule -##iology -##mology -sums -wentworth -##isk -##zione -mainline -subgroup -##illy -hack -plaintiff -verdi -bulb -differentiation -engagements -multinational -supplemented -bertrand -caller -regis -##naire -##sler -##arts -##imated -blossom -propagation -kilometer -viaduct -vineyards -##uate -beckett -optimization -golfer -songwriters -seminal -semitic -thud -volatile -evolving -ridley -##wley -trivial -distributions -scandinavia -jiang -##ject -wrestled -insistence -##dio -emphasizes -napkin -##ods -adjunct -rhyme -##ricted -##eti -hopeless -surrounds -tremble -32nd -smoky -##ntly -oils -medicinal -padded -steer -wilkes -219 -255 -concessions -hue -uniquely -blinded -landon -yahoo -##lane -hendrix -commemorating -dex -specify -chicks -##ggio -intercity -1400 -morley -##torm -highlighting -##oting -pang -oblique -stalled -##liner -flirting -newborn -1769 -bishopric -shaved -232 -currie -##ush -dharma -spartan -##ooped -favorites -smug -novella -sirens -abusive -creations -espana -##lage -paradigm -semiconductor -sheen -##rdo -##yen -##zak -nrl -renew -##pose -##tur -adjutant -marches -norma -##enity -ineffective -weimar -grunt -##gat -lordship -plotting -expenditure -infringement -lbs -refrain -av -mimi -mistakenly -postmaster -1771 -##bara -ras -motorsports -tito -199 -subjective -##zza -bully -stew -##kaya -prescott -1a -##raphic -##zam -bids -styling -paranormal -reeve -sneaking -exploding -katz -akbar -migrant -syllables -indefinitely -##ogical -destroys -replaces -applause -##phine -pest -##fide -218 -articulated -bertie -##thing -##cars -##ptic -courtroom -crowley -aesthetics -cummings -tehsil -hormones -titanic -dangerously -##ibe -stadion -jaenelle -auguste -ciudad -##chu -mysore -partisans -##sio -lucan -philipp -##aly -debating -henley -interiors -##rano -##tious -homecoming -beyonce -usher -henrietta -prepares -weeds -##oman -ely -plucked -##pire -##dable -luxurious -##aq -artifact -password -pasture -juno -maddy -minsk -##dder -##ologies -##rone -assessments -martian -royalist -1765 -examines -##mani -##rge -nino -223 -parry -scooped -relativity -##eli -##uting -##cao -congregational -noisy -traverse -##agawa -strikeouts -nickelodeon -obituary -transylvania -binds -depictions -polk -trolley -##yed -##lard -breeders -##under -dryly -hokkaido -1762 -strengths -stacks -bonaparte -connectivity -neared -prostitutes -stamped -anaheim -gutierrez -sinai -##zzling -bram -fresno -madhya -##86 -proton -##lena -##llum -##phon -reelected -wanda -##anus -##lb -ample -distinguishing -##yler -grasping -sermons -tomato -bland -stimulation -avenues -##eux -spreads -scarlett -fern -pentagon -assert -baird -chesapeake -ir -calmed -distortion -fatalities -##olis -correctional -pricing -##astic -##gina -prom -dammit -ying -collaborate -##chia -welterweight -33rd -pointer -substitution -bonded -umpire -communicating -multitude -paddle -##obe -federally -intimacy -##insky -betray -ssr -##lett -##lean -##lves -##therapy -airbus -##tery -functioned -ud -bearer -biomedical -netflix -##hire -##nca -condom -brink -ik -##nical -macy -##bet -flap -gma -experimented -jelly -lavender -##icles -##ulia -munro -##mian -##tial -rye -##rle -60th -gigs -hottest -rotated -predictions -fuji -bu -##erence -##omi -barangay -##fulness -##sas -clocks -##rwood -##liness -cereal -roe -wight -decker -uttered -babu -onion -xml -forcibly -##df -petra -sarcasm -hartley -peeled -storytelling -##42 -##xley -##ysis -##ffa -fibre -kiel -auditor -fig -harald -greenville -##berries -geographically -nell -quartz -##athic -cemeteries -##lr -crossings -nah -holloway -reptiles -chun -sichuan -snowy -660 -corrections -##ivo -zheng -ambassadors -blacksmith -fielded -fluids -hardcover -turnover -medications -melvin -academies -##erton -ro -roach -absorbing -spaniards -colton -##founded -outsider -espionage -kelsey -245 -edible -##ulf -dora -establishes -##sham -##tries -contracting -##tania -cinematic -costello -nesting -##uron -connolly -duff -##nology -mma -##mata -fergus -sexes -gi -optics -spectator -woodstock -banning -##hee -##fle -differentiate -outfielder -refinery -226 -312 -gerhard -horde -lair -drastically -##udi -landfall -##cheng -motorsport -odi -##achi -predominant -quay -skins -##ental -edna -harshly -complementary -murdering -##aves -wreckage -##90 -ono -outstretched -lennox -munitions -galen -reconcile -470 -scalp -bicycles -gillespie -questionable -rosenberg -guillermo -hostel -jarvis -kabul -volvo -opium -yd -##twined -abuses -decca -outpost -##cino -sensible -neutrality -##64 -ponce -anchorage -atkins -turrets -inadvertently -disagree -libre -vodka -reassuring -weighs -##yal -glide -jumper -ceilings -repertory -outs -stain -##bial -envy -##ucible -smashing -heightened -policing -hyun -mixes -lai -prima -##ples -celeste -##bina -lucrative -intervened -kc -manually -##rned -stature -staffed -bun -bastards -nairobi -priced -##auer -thatcher -##kia -tripped -comune -##ogan -##pled -brasil -incentives -emanuel -hereford -musica -##kim -benedictine -biennale -##lani -eureka -gardiner -rb -knocks -sha -##ael -##elled -##onate -efficacy -ventura -masonic -sanford -maize -leverage -##feit -capacities -santana -##aur -novelty -vanilla -##cter -##tour -benin -##oir -##rain -neptune -drafting -tallinn -##cable -humiliation -##boarding -schleswig -fabian -bernardo -liturgy -spectacle -sweeney -pont -routledge -##tment -cosmos -ut -hilt -sleek -universally -##eville -##gawa -typed -##dry -favors -allegheny -glaciers -##rly -recalling -aziz -##log -parasite -requiem -auf -##berto -##llin -illumination -##breaker -##issa -festivities -bows -govern -vibe -vp -333 -sprawled -larson -pilgrim -bwf -leaping -##rts -##ssel -alexei -greyhound -hoarse -##dler -##oration -seneca -##cule -gaping -##ulously -##pura -cinnamon -##gens -##rricular -craven -fantasies -houghton -engined -reigned -dictator -supervising -##oris -bogota -commentaries -unnatural -fingernails -spirituality -tighten -##tm -canadiens -protesting -intentional -cheers -sparta -##ytic -##iere -##zine -widen -belgarath -controllers -dodd -iaaf -navarre -##ication -defect -squire -steiner -whisky -##mins -560 -inevitably -tome -##gold -chew -##uid -##lid -elastic -##aby -streaked -alliances -jailed -regal -##ined -##phy -czechoslovak -narration -absently -##uld -bluegrass -guangdong -quran -criticizing -hose -hari -##liest -##owa -skier -streaks -deploy -##lom -raft -bose -dialed -huff -##eira -haifa -simplest -bursting -endings -ib -sultanate -##titled -franks -whitman -ensures -sven -##ggs -collaborators -forster -organising -ui -banished -napier -injustice -teller -layered -thump -##otti -roc -battleships -evidenced -fugitive -sadie -robotics -##roud -equatorial -geologist -##iza -yielding -##bron -##sr -internationale -mecca -##diment -sbs -skyline -toad -uploaded -reflective -undrafted -lal -leafs -bayern -##dai -lakshmi -shortlisted -##stick -##wicz -camouflage -donate -af -christi -lau -##acio -disclosed -nemesis -1761 -assemble -straining -northamptonshire -tal -##asi -bernardino -premature -heidi -42nd -coefficients -galactic -reproduce -buzzed -sensations -zionist -monsieur -myrtle -##eme -archery -strangled -musically -viewpoint -antiquities -bei -trailers -seahawks -cured -pee -preferring -tasmanian -lange -sul -##mail -##working -colder -overland -lucivar -massey -gatherings -haitian -##smith -disapproval -flaws -##cco -##enbach -1766 -npr -##icular -boroughs -creole -forums -techno -1755 -dent -abdominal -streetcar -##eson -##stream -procurement -gemini -predictable -##tya -acheron -christoph -feeder -fronts -vendor -bernhard -jammu -tumors -slang -##uber -goaltender -twists -curving -manson -vuelta -mer -peanut -confessions -pouch -unpredictable -allowance -theodor -vascular -##factory -bala -authenticity -metabolic -coughing -nanjing -##cea -pembroke -##bard -splendid -36th -ff -hourly -##ahu -elmer -handel -##ivate -awarding -thrusting -dl -experimentation -##hesion -##46 -caressed -entertained -steak -##rangle -biologist -orphans -baroness -oyster -stepfather -##dridge -mirage -reefs -speeding -##31 -barons -1764 -227 -inhabit -preached -repealed -##tral -honoring -boogie -captives -administer -johanna -##imate -gel -suspiciously -1767 -sobs -##dington -backbone -hayward -garry -##folding -##nesia -maxi -##oof -##ppe -ellison -galileo -##stand -crimea -frenzy -amour -bumper -matrices -natalia -baking -garth -palestinians -##grove -smack -conveyed -ensembles -gardening -##manship -##rup -##stituting -1640 -harvesting -topography -jing -shifters -dormitory -##carriage -##lston -ist -skulls -##stadt -dolores -jewellery -sarawak -##wai -##zier -fences -christy -confinement -tumbling -credibility -fir -stench -##bria -##plication -##nged -##sam -virtues -##belt -marjorie -pba -##eem -##made -celebrates -schooner -agitated -barley -fulfilling -anthropologist -##pro -restrict -novi -regulating -##nent -padres -##rani -##hesive -loyola -tabitha -milky -olson -proprietor -crambidae -guarantees -intercollegiate -ljubljana -hilda -##sko -ignorant -hooded -##lts -sardinia -##lidae -##vation -frontman -privileged -witchcraft -##gp -jammed -laude -poking -##than -bracket -amazement -yunnan -##erus -maharaja -linnaeus -264 -commissioning -milano -peacefully -##logies -akira -rani -regulator -##36 -grasses -##rance -luzon -crows -compiler -gretchen -seaman -edouard -tab -buccaneers -ellington -hamlets -whig -socialists -##anto -directorial -easton -mythological -##kr -##vary -rhineland -semantic -taut -dune -inventions -succeeds -##iter -replication -branched -##pired -jul -prosecuted -kangaroo -penetrated -##avian -middlesbrough -doses -bleak -madam -predatory -relentless -##vili -reluctance -##vir -hailey -crore -silvery -1759 -monstrous -swimmers -transmissions -hawthorn -informing -##eral -toilets -caracas -crouch -kb -##sett -295 -cartel -hadley -##aling -alexia -yvonne -##biology -cinderella -eton -superb -blizzard -stabbing -industrialist -maximus -##gm -##orus -groves -maud -clade -oversized -comedic -##bella -rosen -nomadic -fulham -montane -beverages -galaxies -redundant -swarm -##rot -##folia -##llis -buckinghamshire -fen -bearings -bahadur -##rom -gilles -phased -dynamite -faber -benoit -vip -##ount -##wd -booking -fractured -tailored -anya -spices -westwood -cairns -auditions -inflammation -steamed -##rocity -##acion -##urne -skyla -thereof -watford -torment -archdeacon -transforms -lulu -demeanor -fucked -serge -##sor -mckenna -minas -entertainer -##icide -caress -originate -residue -##sty -1740 -##ilised -##org -beech -##wana -subsidies -##ghton -emptied -gladstone -ru -firefighters -voodoo -##rcle -het -nightingale -tamara -edmond -ingredient -weaknesses -silhouette -285 -compatibility -withdrawing -hampson -##mona -anguish -giggling -##mber -bookstore -##jiang -southernmost -tilting -##vance -bai -economical -rf -briefcase -dreadful -hinted -projections -shattering -totaling -##rogate -analogue -indicted -periodical -fullback -##dman -haynes -##tenberg -##ffs -##ishment -1745 -thirst -stumble -penang -vigorous -##ddling -##kor -##lium -octave -##ove -##enstein -##inen -##ones -siberian -##uti -cbn -repeal -swaying -##vington -khalid -tanaka -unicorn -otago -plastered -lobe -riddle -##rella -perch -##ishing -croydon -filtered -graeme -tripoli -##ossa -crocodile -##chers -sufi -mined -##tung -inferno -lsu -##phi -swelled -utilizes -£2 -cale -periodicals -styx -hike -informally -coop -lund -##tidae -ala -hen -qui -transformations -disposed -sheath -chickens -##cade -fitzroy -sas -silesia -unacceptable -odisha -1650 -sabrina -pe -spokane -ratios -athena -massage -shen -dilemma -##drum -##riz -##hul -corona -doubtful -niall -##pha -##bino -fines -cite -acknowledging -bangor -ballard -bathurst -##resh -huron -mustered -alzheimer -garments -kinase -tyre -warship -##cp -flashback -pulmonary -braun -cheat -kamal -cyclists -constructions -grenades -ndp -traveller -excuses -stomped -signalling -trimmed -futsal -mosques -relevance -##wine -wta -##23 -##vah -##lter -hoc -##riding -optimistic -##´s -deco -sim -interacting -rejecting -moniker -waterways -##ieri -##oku -mayors -gdansk -outnumbered -pearls -##ended -##hampton -fairs -totals -dominating -262 -notions -stairway -compiling -pursed -commodities -grease -yeast -##jong -carthage -griffiths -residual -amc -contraction -laird -sapphire -##marine -##ivated -amalgamation -dissolve -inclination -lyle -packaged -altitudes -suez -canons -graded -lurched -narrowing -boasts -guise -wed -enrico -##ovsky -rower -scarred -bree -cub -iberian -protagonists -bargaining -proposing -trainers -voyages -vans -fishes -##aea -##ivist -##verance -encryption -artworks -kazan -sabre -cleopatra -hepburn -rotting -supremacy -mecklenburg -##brate -burrows -hazards -outgoing -flair -organizes -##ctions -scorpion -##usions -boo -234 -chevalier -dunedin -slapping -##34 -ineligible -pensions -##38 -##omic -manufactures -emails -bismarck -238 -weakening -blackish -ding -mcgee -quo -##rling -northernmost -xx -manpower -greed -sampson -clicking -##ange -##horpe -##inations -##roving -torre -##eptive -##moral -symbolism -38th -asshole -meritorious -outfits -splashed -biographies -sprung -astros -##tale -302 -737 -filly -raoul -nw -tokugawa -linden -clubhouse -##apa -tracts -romano -##pio -putin -tags -##note -chained -dickson -gunshot -moe -gunn -rashid -##tails -zipper -##bas -##nea -contrasted -##ply -##udes -plum -pharaoh -##pile -aw -comedies -ingrid -sandwiches -subdivisions -1100 -mariana -nokia -kamen -hz -delaney -veto -herring -##words -possessive -outlines -##roup -siemens -stairwell -rc -gallantry -messiah -palais -yells -233 -zeppelin -##dm -bolivar -##cede -smackdown -mckinley -##mora -##yt -muted -geologic -finely -unitary -avatar -hamas -maynard -rees -bog -contrasting -##rut -liv -chico -disposition -pixel -##erate -becca -dmitry -yeshiva -narratives -##lva -##ulton -mercenary -sharpe -tempered -navigate -stealth -amassed -keynes -##lini -untouched -##rrie -havoc -lithium -##fighting -abyss -graf -southward -wolverine -balloons -implements -ngos -transitions -##icum -ambushed -concacaf -dormant -economists -##dim -costing -csi -rana -universite -boulders -verity -##llon -collin -mellon -misses -cypress -fluorescent -lifeless -spence -##ulla -crewe -shepard -pak -revelations -##م -jolly -gibbons -paw -##dro -##quel -freeing -##test -shack -fries -palatine -##51 -##hiko -accompaniment -cruising -recycled -##aver -erwin -sorting -synthesizers -dyke -realities -sg -strides -enslaved -wetland -##ghan -competence -gunpowder -grassy -maroon -reactors -objection -##oms -carlson -gearbox -macintosh -radios -shelton -##sho -clergyman -prakash -254 -mongols -trophies -oricon -228 -stimuli -twenty20 -cantonese -cortes -mirrored -##saurus -bhp -cristina -melancholy -##lating -enjoyable -nuevo -##wny -downfall -schumacher -##ind -banging -lausanne -rumbled -paramilitary -reflex -ax -amplitude -migratory -##gall -##ups -midi -barnard -lastly -sherry -##hp -##nall -keystone -##kra -carleton -slippery -##53 -coloring -foe -socket -otter -##rgos -mats -##tose -consultants -bafta -bison -topping -##km -490 -primal -abandonment -transplant -atoll -hideous -mort -pained -reproduced -tae -howling -##turn -unlawful -billionaire -hotter -poised -lansing -##chang -dinamo -retro -messing -nfc -domesday -##mina -blitz -timed -##athing -##kley -ascending -gesturing -##izations -signaled -tis -chinatown -mermaid -savanna -jameson -##aint -catalina -##pet -##hers -cochrane -cy -chatting -##kus -alerted -computation -mused -noelle -majestic -mohawk -campo -octagonal -##sant -##hend -241 -aspiring -##mart -comprehend -iona -paralyzed -shimmering -swindon -rhone -##eley -reputed -configurations -pitchfork -agitation -francais -gillian -lipstick -##ilo -outsiders -pontifical -resisting -bitterness -sewer -rockies -##edd -##ucher -misleading -1756 -exiting -galloway -##nging -risked -##heart -246 -commemoration -schultz -##rka -integrating -##rsa -poses -shrieked -##weiler -guineas -gladys -jerking -owls -goldsmith -nightly -penetrating -##unced -lia -##33 -ignited -betsy -##aring -##thorpe -follower -vigorously -##rave -coded -kiran -knit -zoology -tbilisi -##28 -##bered -repository -govt -deciduous -dino -growling -##bba -enhancement -unleashed -chanting -pussy -biochemistry -##eric -kettle -repression -toxicity -nrhp -##arth -##kko -##bush -ernesto -commended -outspoken -242 -mca -parchment -sms -kristen -##aton -bisexual -raked -glamour -navajo -a2 -conditioned -showcased -##hma -spacious -youthful -##esa -usl -appliances -junta -brest -layne -conglomerate -enchanted -chao -loosened -picasso -circulating -inspect -montevideo -##centric -##kti -piazza -spurred -##aith -bari -freedoms -poultry -stamford -lieu -##ect -indigo -sarcastic -bahia -stump -attach -dvds -frankenstein -lille -approx -scriptures -pollen -##script -nmi -overseen -##ivism -tides -proponent -newmarket -inherit -milling -##erland -centralized -##rou -distributors -credentials -drawers -abbreviation -##lco -##xon -downing -uncomfortably -ripe -##oes -erase -franchises -##ever -populace -##bery -##khar -decomposition -pleas -##tet -daryl -sabah -##stle -##wide -fearless -genie -lesions -annette -##ogist -oboe -appendix -nair -dripped -petitioned -maclean -mosquito -parrot -rpg -hampered -1648 -operatic -reservoirs -##tham -irrelevant -jolt -summarized -##fp -medallion -##taff -##− -clawed -harlow -narrower -goddard -marcia -bodied -fremont -suarez -altering -tempest -mussolini -porn -##isms -sweetly -oversees -walkers -solitude -grimly -shrines -hk -ich -supervisors -hostess -dietrich -legitimacy -brushes -expressive -##yp -dissipated -##rse -localized -systemic -##nikov -gettysburg -##js -##uaries -dialogues -muttering -251 -housekeeper -sicilian -discouraged -##frey -beamed -kaladin -halftime -kidnap -##amo -##llet -1754 -synonymous -depleted -instituto -insulin -reprised -##opsis -clashed -##ctric -interrupting -radcliffe -insisting -medici -1715 -ejected -playfully -turbulent -##47 -starvation -##rini -shipment -rebellious -petersen -verification -merits -##rified -cakes -##charged -1757 -milford -shortages -spying -fidelity -##aker -emitted -storylines -harvested -seismic -##iform -cheung -kilda -theoretically -barbie -lynx -##rgy -##tius -goblin -mata -poisonous -##nburg -reactive -residues -obedience -##евич -conjecture -##rac -401 -hating -sixties -kicker -moaning -motown -##bha -emancipation -neoclassical -##hering -consoles -ebert -professorship -##tures -sustaining -assaults -obeyed -affluent -incurred -tornadoes -##eber -##zow -emphasizing -highlanders -cheated -helmets -##ctus -internship -terence -bony -executions -legislators -berries -peninsular -tinged -##aco -1689 -amplifier -corvette -ribbons -lavish -pennant -##lander -worthless -##chfield -##forms -mariano -pyrenees -expenditures -##icides -chesterfield -mandir -tailor -39th -sergey -nestled -willed -aristocracy -devotees -goodnight -raaf -rumored -weaponry -remy -appropriations -harcourt -burr -riaa -##lence -limitation -unnoticed -guo -soaking -swamps -##tica -collapsing -tatiana -descriptive -brigham -psalm -##chment -maddox -##lization -patti -caliph -##aja -akron -injuring -serra -##ganj -basins -##sari -astonished -launcher -##church -hilary -wilkins -sewing -##sf -stinging -##fia -##ncia -underwood -startup -##ition -compilations -vibrations -embankment -jurist -##nity -bard -juventus -groundwater -kern -palaces -helium -boca -cramped -marissa -soto -##worm -jae -princely -##ggy -faso -bazaar -warmly -##voking -229 -pairing -##lite -##grate -##nets -wien -freaked -ulysses -rebirth -##alia -##rent -mummy -guzman -jimenez -stilled -##nitz -trajectory -tha -woken -archival -professions -##pts -##pta -hilly -shadowy -shrink -##bolt -norwood -glued -migrate -stereotypes -devoid -##pheus -625 -evacuate -horrors -infancy -gotham -knowles -optic -downloaded -sachs -kingsley -parramatta -darryl -mor -##onale -shady -commence -confesses -kan -##meter -##placed -marlborough -roundabout -regents -frigates -io -##imating -gothenburg -revoked -carvings -clockwise -convertible -intruder -##sche -banged -##ogo -vicky -bourgeois -##mony -dupont -footing -##gum -pd -##real -buckle -yun -penthouse -sane -720 -serviced -stakeholders -neumann -bb -##eers -comb -##gam -catchment -pinning -rallies -typing -##elles -forefront -freiburg -sweetie -giacomo -widowed -goodwill -worshipped -aspirations -midday -##vat -fishery -##trick -bournemouth -turk -243 -hearth -ethanol -guadalajara -murmurs -sl -##uge -afforded -scripted -##hta -wah -##jn -coroner -translucent -252 -memorials -puck -progresses -clumsy -##race -315 -candace -recounted -##27 -##slin -##uve -filtering -##mac -howl -strata -heron -leveled -##ays -dubious -##oja -##т -##wheel -citations -exhibiting -##laya -##mics -##pods -turkic -##lberg -injunction -##ennial -##mit -antibodies -##44 -organise -##rigues -cardiovascular -cushion -inverness -##zquez -dia -cocoa -sibling -##tman -##roid -expanse -feasible -tunisian -algiers -##relli -rus -bloomberg -dso -westphalia -bro -tacoma -281 -downloads -##ours -konrad -duran -##hdi -continuum -jett -compares -legislator -secession -##nable -##gues -##zuka -translating -reacher -##gley -##ła -aleppo -##agi -tc -orchards -trapping -linguist -versatile -drumming -postage -calhoun -superiors -##mx -barefoot -leary -##cis -ignacio -alfa -kaplan -##rogen -bratislava -mori -##vot -disturb -haas -313 -cartridges -gilmore -radiated -salford -tunic -hades -##ulsive -archeological -delilah -magistrates -auditioned -brewster -charters -empowerment -blogs -cappella -dynasties -iroquois -whipping -##krishna -raceway -truths -myra -weaken -judah -mcgregor -##horse -mic -refueling -37th -burnley -bosses -markus -premio -query -##gga -dunbar -##economic -darkest -lyndon -sealing -commendation -reappeared -##mun -addicted -ezio -slaughtered -satisfactory -shuffle -##eves -##thic -##uj -fortification -warrington -##otto -resurrected -fargo -mane -##utable -##lei -##space -foreword -ox -##aris -##vern -abrams -hua -##mento -sakura -##alo -uv -sentimental -##skaya -midfield -##eses -sturdy -scrolls -macleod -##kyu -entropy -##lance -mitochondrial -cicero -excelled -thinner -convoys -perceive -##oslav -##urable -systematically -grind -burkina -287 -##tagram -ops -##aman -guantanamo -##cloth -##tite -forcefully -wavy -##jou -pointless -##linger -##tze -layton -portico -superficial -clerical -outlaws -##hism -burials -muir -##inn -creditors -hauling -rattle -##leg -calais -monde -archers -reclaimed -dwell -wexford -hellenic -falsely -remorse -##tek -dough -furnishings -##uttered -gabon -neurological -novice -##igraphy -contemplated -pulpit -nightstand -saratoga -##istan -documenting -pulsing -taluk -##firmed -busted -marital -##rien -disagreements -wasps -##yes -hodge -mcdonnell -mimic -fran -pendant -dhabi -musa -##nington -congratulations -argent -darrell -concussion -losers -regrets -thessaloniki -reversal -donaldson -hardwood -thence -achilles -ritter -##eran -demonic -jurgen -prophets -goethe -eki -classmate -buff -##cking -yank -irrational -##inging -perished -seductive -qur -sourced -##crat -##typic -mustard -ravine -barre -horizontally -characterization -phylogenetic -boise -##dit -##runner -##tower -brutally -intercourse -seduce -##bbing -fay -ferris -ogden -amar -nik -unarmed -##inator -evaluating -kyrgyzstan -sweetness -##lford -##oki -mccormick -meiji -notoriety -stimulate -disrupt -figuring -instructional -mcgrath -##zoo -groundbreaking -##lto -flinch -khorasan -agrarian -bengals -mixer -radiating -##sov -ingram -pitchers -nad -tariff -##cript -tata -##codes -##emi -##ungen -appellate -lehigh -##bled -##giri -brawl -duct -texans -##ciation -##ropolis -skipper -speculative -vomit -doctrines -stresses -253 -davy -graders -whitehead -jozef -timely -cumulative -haryana -paints -appropriately -boon -cactus -##ales -##pid -dow -legions -##pit -perceptions -1730 -picturesque -##yse -periphery -rune -wr -##aha -celtics -sentencing -whoa -##erin -confirms -variance -425 -moines -mathews -spade -rave -m1 -fronted -fx -blending -alleging -reared -##gl -237 -##paper -grassroots -eroded -##free -##physical -directs -ordeal -##sław -accelerate -hacker -rooftop -##inia -lev -buys -cebu -devote -##lce -specialising -##ulsion -choreographed -repetition -warehouses -##ryl -paisley -tuscany -analogy -sorcerer -hash -huts -shards -descends -exclude -nix -chaplin -gaga -ito -vane -##drich -causeway -misconduct -limo -orchestrated -glands -jana -##kot -u2 -##mple -##sons -branching -contrasts -scoop -longed -##virus -chattanooga -##75 -syrup -cornerstone -##tized -##mind -##iaceae -careless -precedence -frescoes -##uet -chilled -consult -modelled -snatch -peat -##thermal -caucasian -humane -relaxation -spins -temperance -##lbert -occupations -lambda -hybrids -moons -mp3 -##oese -247 -rolf -societal -yerevan -ness -##ssler -befriended -mechanized -nominate -trough -boasted -cues -seater -##hom -bends -##tangle -conductors -emptiness -##lmer -eurasian -adriatic -tian -##cie -anxiously -lark -propellers -chichester -jock -ev -2a -##holding -credible -recounts -tori -loyalist -abduction -##hoot -##redo -nepali -##mite -ventral -tempting -##ango -##crats -steered -##wice -javelin -dipping -laborers -prentice -looming -titanium -##ː -badges -emir -tensor -##ntation -egyptians -rash -denies -hawthorne -lombard -showers -wehrmacht -dietary -trojan -##reus -welles -executing -horseshoe -lifeboat -##lak -elsa -infirmary -nearing -roberta -boyer -mutter -trillion -joanne -##fine -##oked -sinks -vortex -uruguayan -clasp -sirius -##block -accelerator -prohibit -sunken -byu -chronological -diplomats -ochreous -510 -symmetrical -1644 -maia -##tology -salts -reigns -atrocities -##ия -hess -bared -issn -##vyn -cater -saturated -##cycle -##isse -sable -voyager -dyer -yusuf -##inge -fountains -wolff -##39 -##nni -engraving -rollins -atheist -ominous -##ault -herr -chariot -martina -strung -##fell -##farlane -horrific -sahib -gazes -saetan -erased -ptolemy -##olic -flushing -lauderdale -analytic -##ices -530 -navarro -beak -gorilla -herrera -broom -guadalupe -raiding -sykes -311 -bsc -deliveries -1720 -invasions -carmichael -tajikistan -thematic -ecumenical -sentiments -onstage -##rians -##brand -##sume -catastrophic -flanks -molten -##arns -waller -aimee -terminating -##icing -alternately -##oche -nehru -printers -outraged -##eving -empires -template -banners -repetitive -za -##oise -vegetarian -##tell -guiana -opt -cavendish -lucknow -synthesized -##hani -##mada -finalized -##ctable -fictitious -mayoral -unreliable -##enham -embracing -peppers -rbis -##chio -##neo -inhibition -slashed -togo -orderly -embroidered -safari -salty -236 -barron -benito -totaled -##dak -pubs -simulated -caden -devin -tolkien -momma -welding -sesame -##ept -gottingen -hardness -630 -shaman -temeraire -620 -adequately -pediatric -##kit -ck -assertion -radicals -composure -cadence -seafood -beaufort -lazarus -mani -warily -cunning -kurdistan -249 -cantata -##kir -ares -##41 -##clusive -nape -townland -geared -insulted -flutter -boating -violate -draper -dumping -malmo -##hh -##romatic -firearm -alta -bono -obscured -##clave -exceeds -panorama -unbelievable -##train -preschool -##essed -disconnected -installing -rescuing -secretaries -accessibility -##castle -##drive -##ifice -##film -bouts -slug -waterway -mindanao -##buro -##ratic -halves -##ل -calming -liter -maternity -adorable -bragg -electrification -mcc -##dote -roxy -schizophrenia -##body -munoz -kaye -whaling -239 -mil -tingling -tolerant -##ago -unconventional -volcanoes -##finder -deportivo -##llie -robson -kaufman -neuroscience -wai -deportation -masovian -scraping -converse -##bh -hacking -bulge -##oun -administratively -yao -580 -amp -mammoth -booster -claremont -hooper -nomenclature -pursuits -mclaughlin -melinda -##sul -catfish -barclay -substrates -taxa -zee -originals -kimberly -packets -padma -##ality -borrowing -ostensibly -solvent -##bri -##genesis -##mist -lukas -shreveport -veracruz -##ь -##lou -##wives -cheney -tt -anatolia -hobbs -##zyn -cyclic -radiant -alistair -greenish -siena -dat -independents -##bation -conform -pieter -hyper -applicant -bradshaw -spores -telangana -vinci -inexpensive -nuclei -322 -jang -nme -soho -spd -##ign -cradled -receptionist -pow -##43 -##rika -fascism -##ifer -experimenting -##ading -##iec -##region -345 -jocelyn -maris -stair -nocturnal -toro -constabulary -elgin -##kker -msc -##giving -##schen -##rase -doherty -doping -sarcastically -batter -maneuvers -##cano -##apple -##gai -##git -intrinsic -##nst -##stor -1753 -showtime -cafes -gasps -lviv -ushered -##thed -fours -restart -astonishment -transmitting -flyer -shrugs -##sau -intriguing -cones -dictated -mushrooms -medial -##kovsky -##elman -escorting -gaped -##26 -godfather -##door -##sell -djs -recaptured -timetable -vila -1710 -3a -aerodrome -mortals -scientology -##orne -angelina -mag -convection -unpaid -insertion -intermittent -lego -##nated -endeavor -kota -pereira -##lz -304 -bwv -glamorgan -insults -agatha -fey -##cend -fleetwood -mahogany -protruding -steamship -zeta -##arty -mcguire -suspense -##sphere -advising -urges -##wala -hurriedly -meteor -gilded -inline -arroyo -stalker -##oge -excitedly -revered -##cure -earle -introductory -##break -##ilde -mutants -puff -pulses -reinforcement -##haling -curses -lizards -stalk -correlated -##fixed -fallout -macquarie -##unas -bearded -denton -heaving -802 -##ocation -winery -assign -dortmund -##lkirk -everest -invariant -charismatic -susie -##elling -bled -lesley -telegram -sumner -bk -##ogen -##к -wilcox -needy -colbert -duval -##iferous -##mbled -allotted -attends -imperative -##hita -replacements -hawker -##inda -insurgency -##zee -##eke -casts -##yla -680 -ives -transitioned -##pack -##powering -authoritative -baylor -flex -cringed -plaintiffs -woodrow -##skie -drastic -ape -aroma -unfolded -commotion -nt -preoccupied -theta -routines -lasers -privatization -wand -domino -ek -clenching -nsa -strategically -showered -bile -handkerchief -pere -storing -christophe -insulting -316 -nakamura -romani -asiatic -magdalena -palma -cruises -stripping -405 -konstantin -soaring -##berman -colloquially -forerunner -havilland -incarcerated -parasites -sincerity -##utus -disks -plank -saigon -##ining -corbin -homo -ornaments -powerhouse -##tlement -chong -fastened -feasibility -idf -morphological -usable -##nish -##zuki -aqueduct -jaguars -keepers -##flies -aleksandr -faust -assigns -ewing -bacterium -hurled -tricky -hungarians -integers -wallis -321 -yamaha -##isha -hushed -oblivion -aviator -evangelist -friars -##eller -monograph -ode -##nary -airplanes -labourers -charms -##nee -1661 -hagen -tnt -rudder -fiesta -transcript -dorothea -ska -inhibitor -maccabi -retorted -raining -encompassed -clauses -menacing -1642 -lineman -##gist -vamps -##ape -##dick -gloom -##rera -dealings -easing -seekers -##nut -##pment -helens -unmanned -##anu -##isson -basics -##amy -##ckman -adjustments -1688 -brutality -horne -##zell -sui -##55 -##mable -aggregator -##thal -rhino -##drick -##vira -counters -zoom -##01 -##rting -mn -montenegrin -packard -##unciation -##♭ -##kki -reclaim -scholastic -thugs -pulsed -##icia -syriac -quan -saddam -banda -kobe -blaming -buddies -dissent -##lusion -##usia -corbett -jaya -delle -erratic -lexie -##hesis -435 -amiga -hermes -##pressing -##leen -chapels -gospels -jamal -##uating -compute -revolving -warp -##sso -##thes -armory -##eras -##gol -antrim -loki -##kow -##asian -##good -##zano -braid -handwriting -subdistrict -funky -pantheon -##iculate -concurrency -estimation -improper -juliana -##his -newcomers -johnstone -staten -communicated -##oco -##alle -sausage -stormy -##stered -##tters -superfamily -##grade -acidic -collateral -tabloid -##oped -##rza -bladder -austen -##ellant -mcgraw -##hay -hannibal -mein -aquino -lucifer -wo -badger -boar -cher -christensen -greenberg -interruption -##kken -jem -244 -mocked -bottoms -cambridgeshire -##lide -sprawling -##bbly -eastwood -ghent -synth -##buck -advisers -##bah -nominally -hapoel -qu -daggers -estranged -fabricated -towels -vinnie -wcw -misunderstanding -anglia -nothin -unmistakable -##dust -##lova -chilly -marquette -truss -##edge -##erine -reece -##lty -##chemist -##connected -272 -308 -41st -bash -raion -waterfalls -##ump -##main -labyrinth -queue -theorist -##istle -bharatiya -flexed -soundtracks -rooney -leftist -patrolling -wharton -plainly -alleviate -eastman -schuster -topographic -engages -immensely -unbearable -fairchild -1620 -dona -lurking -parisian -oliveira -ia -indictment -hahn -bangladeshi -##aster -vivo -##uming -##ential -antonia -expects -indoors -kildare -harlan -##logue -##ogenic -##sities -forgiven -##wat -childish -tavi -##mide -##orra -plausible -grimm -successively -scooted -##bola -##dget -##rith -spartans -emery -flatly -azure -epilogue -##wark -flourish -##iny -##tracted -##overs -##oshi -bestseller -distressed -receipt -spitting -hermit -topological -##cot -drilled -subunit -francs -##layer -eel -##fk -##itas -octopus -footprint -petitions -ufo -##say -##foil -interfering -leaking -palo -##metry -thistle -valiant -##pic -narayan -mcpherson -##fast -gonzales -##ym -##enne -dustin -novgorod -solos -##zman -doin -##raph -##patient -##meyer -soluble -ashland -cuffs -carole -pendleton -whistling -vassal -##river -deviation -revisited -constituents -rallied -rotate -loomed -##eil -##nting -amateurs -augsburg -auschwitz -crowns -skeletons -##cona -bonnet -257 -dummy -globalization -simeon -sleeper -mandal -differentiated -##crow -##mare -milne -bundled -exasperated -talmud -owes -segregated -##feng -##uary -dentist -piracy -props -##rang -devlin -##torium -malicious -paws -##laid -dependency -##ergy -##fers -##enna -258 -pistons -rourke -jed -grammatical -tres -maha -wig -512 -ghostly -jayne -##achal -##creen -##ilis -##lins -##rence -designate -##with -arrogance -cambodian -clones -showdown -throttle -twain -##ception -lobes -metz -nagoya -335 -braking -##furt -385 -roaming -##minster -amin -crippled -##37 -##llary -indifferent -hoffmann -idols -intimidating -1751 -261 -influenza -memo -onions -1748 -bandage -consciously -##landa -##rage -clandestine -observes -swiped -tangle -##ener -##jected -##trum -##bill -##lta -hugs -congresses -josiah -spirited -##dek -humanist -managerial -filmmaking -inmate -rhymes -debuting -grimsby -ur -##laze -duplicate -vigor -##tf -republished -bolshevik -refurbishment -antibiotics -martini -methane -newscasts -royale -horizons -levant -iain -visas -##ischen -paler -##around -manifestation -snuck -alf -chop -futile -pedestal -rehab -##kat -bmg -kerman -res -fairbanks -jarrett -abstraction -saharan -##zek -1746 -procedural -clearer -kincaid -sash -luciano -##ffey -crunch -helmut -##vara -revolutionaries -##tute -creamy -leach -##mmon -1747 -permitting -nes -plight -wendell -##lese -contra -ts -clancy -ipa -mach -staples -autopsy -disturbances -nueva -karin -pontiac -##uding -proxy -venerable -haunt -leto -bergman -expands -##helm -wal -##pipe -canning -celine -cords -obesity -##enary -intrusion -planner -##phate -reasoned -sequencing -307 -harrow -##chon -##dora -marred -mcintyre -repay -tarzan -darting -248 -harrisburg -margarita -repulsed -##hur -##lding -belinda -hamburger -novo -compliant -runways -bingham -registrar -skyscraper -ic -cuthbert -improvisation -livelihood -##corp -##elial -admiring -##dened -sporadic -believer -casablanca -popcorn -##29 -asha -shovel -##bek -##dice -coiled -tangible -##dez -casper -elsie -resin -tenderness -rectory -##ivision -avail -sonar -##mori -boutique -##dier -guerre -bathed -upbringing -vaulted -sandals -blessings -##naut -##utnant -1680 -306 -foxes -pia -corrosion -hesitantly -confederates -crystalline -footprints -shapiro -tirana -valentin -drones -45th -microscope -shipments -texted -inquisition -wry -guernsey -unauthorized -resigning -760 -ripple -schubert -stu -reassure -felony -##ardo -brittle -koreans -##havan -##ives -dun -implicit -tyres -##aldi -##lth -magnolia -##ehan -##puri -##poulos -aggressively -fei -gr -familiarity -##poo -indicative -##trust -fundamentally -jimmie -overrun -395 -anchors -moans -##opus -britannia -armagh -##ggle -purposely -seizing -##vao -bewildered -mundane -avoidance -cosmopolitan -geometridae -quartermaster -caf -415 -chatter -engulfed -gleam -purge -##icate -juliette -jurisprudence -guerra -revisions -##bn -casimir -brew -##jm -1749 -clapton -cloudy -conde -hermitage -278 -simulations -torches -vincenzo -matteo -##rill -hidalgo -booming -westbound -accomplishment -tentacles -unaffected -##sius -annabelle -flopped -sloping -##litz -dreamer -interceptor -vu -##loh -consecration -copying -messaging -breaker -climates -hospitalized -1752 -torino -afternoons -winfield -witnessing -##teacher -breakers -choirs -sawmill -coldly -##ege -sipping -haste -uninhabited -conical -bibliography -pamphlets -severn -edict -##oca -deux -illnesses -grips -##pl -rehearsals -sis -thinkers -tame -##keepers -1690 -acacia -reformer -##osed -##rys -shuffling -##iring -##shima -eastbound -ionic -rhea -flees -littered -##oum -rocker -vomiting -groaning -champ -overwhelmingly -civilizations -paces -sloop -adoptive -##tish -skaters -##vres -aiding -mango -##joy -nikola -shriek -##ignon -pharmaceuticals -##mg -tuna -calvert -gustavo -stocked -yearbook -##urai -##mana -computed -subsp -riff -hanoi -kelvin -hamid -moors -pastures -summons -jihad -nectar -##ctors -bayou -untitled -pleasing -vastly -republics -intellect -##η -##ulio -##tou -crumbling -stylistic -sb -##ی -consolation -frequented -h₂o -walden -widows -##iens -404 -##ignment -chunks -improves -288 -grit -recited -##dev -snarl -sociological -##arte -##gul -inquired -##held -bruise -clube -consultancy -homogeneous -hornets -multiplication -pasta -prick -savior -##grin -##kou -##phile -yoon -##gara -grimes -vanishing -cheering -reacting -bn -distillery -##quisite -##vity -coe -dockyard -massif -##jord -escorts -voss -##valent -byte -chopped -hawke -illusions -workings -floats -##koto -##vac -kv -annapolis -madden -##onus -alvaro -noctuidae -##cum -##scopic -avenge -steamboat -forte -illustrates -erika -##trip -570 -dew -nationalities -bran -manifested -thirsty -diversified -muscled -reborn -##standing -arson -##lessness -##dran -##logram -##boys -##kushima -##vious -willoughby -##phobia -286 -alsace -dashboard -yuki -##chai -granville -myspace -publicized -tricked -##gang -adjective -##ater -relic -reorganisation -enthusiastically -indications -saxe -##lassified -consolidate -iec -padua -helplessly -ramps -renaming -regulars -pedestrians -accents -convicts -inaccurate -lowers -mana -##pati -barrie -bjp -outta -someplace -berwick -flanking -invoked -marrow -sparsely -excerpts -clothed -rei -##ginal -wept -##straße -##vish -alexa -excel -##ptive -membranes -aquitaine -creeks -cutler -sheppard -implementations -ns -##dur -fragrance -budge -concordia -magnesium -marcelo -##antes -gladly -vibrating -##rral -##ggles -montrose -##omba -lew -seamus -1630 -cocky -##ament -##uen -bjorn -##rrick -fielder -fluttering -##lase -methyl -kimberley -mcdowell -reductions -barbed -##jic -##tonic -aeronautical -condensed -distracting -##promising -huffed -##cala -##sle -claudius -invincible -missy -pious -balthazar -ci -##lang -butte -combo -orson -##dication -myriad -1707 -silenced -##fed -##rh -coco -netball -yourselves -##oza -clarify -heller -peg -durban -etudes -offender -roast -blackmail -curvature -##woods -vile -309 -illicit -suriname -##linson -overture -1685 -bubbling -gymnast -tucking -##mming -##ouin -maldives -##bala -gurney -##dda -##eased -##oides -backside -pinto -jars -racehorse -tending -##rdial -baronetcy -wiener -duly -##rke -barbarian -cupping -flawed -##thesis -bertha -pleistocene -puddle -swearing -##nob -##tically -fleeting -prostate -amulet -educating -##mined -##iti -##tler -75th -jens -respondents -analytics -cavaliers -papacy -raju -##iente -##ulum -##tip -funnel -271 -disneyland -##lley -sociologist -##iam -2500 -faulkner -louvre -menon -##dson -276 -##ower -afterlife -mannheim -peptide -referees -comedians -meaningless -##anger -##laise -fabrics -hurley -renal -sleeps -##bour -##icle -breakout -kristin -roadside -animator -clover -disdain -unsafe -redesign -##urity -firth -barnsley -portage -reset -narrows -268 -commandos -expansive -speechless -tubular -##lux -essendon -eyelashes -smashwords -##yad -##bang -##claim -craved -sprinted -chet -somme -astor -wrocław -orton -266 -bane -##erving -##uing -mischief -##amps -##sund -scaling -terre -##xious -impairment -offenses -undermine -moi -soy -contiguous -arcadia -inuit -seam -##tops -macbeth -rebelled -##icative -##iot -590 -elaborated -frs -uniformed -##dberg -259 -powerless -priscilla -stimulated -980 -qc -arboretum -frustrating -trieste -bullock -##nified -enriched -glistening -intern -##adia -locus -nouvelle -ollie -ike -lash -starboard -ee -tapestry -headlined -hove -rigged -##vite -pollock -##yme -thrive -clustered -cas -roi -gleamed -olympiad -##lino -pressured -regimes -##hosis -##lick -ripley -##ophone -kickoff -gallon -rockwell -##arable -crusader -glue -revolutions -scrambling -1714 -grover -##jure -englishman -aztec -263 -contemplating -coven -ipad -preach -triumphant -tufts -##esian -rotational -##phus -328 -falkland -##brates -strewn -clarissa -rejoin -environmentally -glint -banded -drenched -moat -albanians -johor -rr -maestro -malley -nouveau -shaded -taxonomy -v6 -adhere -bunk -airfields -##ritan -1741 -encompass -remington -tran -##erative -amelie -mazda -friar -morals -passions -##zai -breadth -vis -##hae -argus -burnham -caressing -insider -rudd -##imov -##mini -##rso -italianate -murderous -textual -wainwright -armada -bam -weave -timer -##taken -##nh -fra -##crest -ardent -salazar -taps -tunis -##ntino -allegro -gland -philanthropic -##chester -implication -##optera -esq -judas -noticeably -wynn -##dara -inched -indexed -crises -villiers -bandit -royalties -patterned -cupboard -interspersed -accessory -isla -kendrick -entourage -stitches -##esthesia -headwaters -##ior -interlude -distraught -draught -1727 -##basket -biased -sy -transient -triad -subgenus -adapting -kidd -shortstop -##umatic -dimly -spiked -mcleod -reprint -nellie -pretoria -windmill -##cek -singled -##mps -273 -reunite -##orous -747 -bankers -outlying -##omp -##ports -##tream -apologies -cosmetics -patsy -##deh -##ocks -##yson -bender -nantes -serene -##nad -lucha -mmm -323 -##cius -##gli -cmll -coinage -nestor -juarez -##rook -smeared -sprayed -twitching -sterile -irina -embodied -juveniles -enveloped -miscellaneous -cancers -dq -gulped -luisa -crested -swat -donegal -ref -##anov -##acker -hearst -mercantile -##lika -doorbell -ua -vicki -##alla -##som -bilbao -psychologists -stryker -sw -horsemen -turkmenistan -wits -##national -anson -mathew -screenings -##umb -rihanna -##agne -##nessy -aisles -##iani -##osphere -hines -kenton -saskatoon -tasha -truncated -##champ -##itan -mildred -advises -fredrik -interpreting -inhibitors -##athi -spectroscopy -##hab -##kong -karim -panda -##oia -##nail -##vc -conqueror -kgb -leukemia -##dity -arrivals -cheered -pisa -phosphorus -shielded -##riated -mammal -unitarian -urgently -chopin -sanitary -##mission -spicy -drugged -hinges -##tort -tipping -trier -impoverished -westchester -##caster -267 -epoch -nonstop -##gman -##khov -aromatic -centrally -cerro -##tively -##vio -billions -modulation -sedimentary -283 -facilitating -outrageous -goldstein -##eak -##kt -ld -maitland -penultimate -pollard -##dance -fleets -spaceship -vertebrae -##nig -alcoholism -als -recital -##bham -##ference -##omics -m2 -##bm -trois -##tropical -##в -commemorates -##meric -marge -##raction -1643 -670 -cosmetic -ravaged -##ige -catastrophe -eng -##shida -albrecht -arterial -bellamy -decor -harmon -##rde -bulbs -synchronized -vito -easiest -shetland -shielding -wnba -##glers -##ssar -##riam -brianna -cumbria -##aceous -##rard -cores -thayer -##nsk -brood -hilltop -luminous -carts -keynote -larkin -logos -##cta -##ا -##mund -##quay -lilith -tinted -277 -wrestle -mobilization -##uses -sequential -siam -bloomfield -takahashi -274 -##ieving -presenters -ringo -blazed -witty -##oven -##ignant -devastation -haydn -harmed -newt -therese -##peed -gershwin -molina -rabbis -sudanese -001 -innate -restarted -##sack -##fus -slices -wb -##shah -enroll -hypothetical -hysterical -1743 -fabio -indefinite -warped -##hg -exchanging -525 -unsuitable -##sboro -gallo -1603 -bret -cobalt -homemade -##hunter -mx -operatives -##dhar -terraces -durable -latch -pens -whorls -##ctuated -##eaux -billing -ligament -succumbed -##gly -regulators -spawn -##brick -##stead -filmfare -rochelle -##nzo -1725 -circumstance -saber -supplements -##nsky -##tson -crowe -wellesley -carrot -##9th -##movable -primate -drury -sincerely -topical -##mad -##rao -callahan -kyiv -smarter -tits -undo -##yeh -announcements -anthologies -barrio -nebula -##islaus -##shaft -##tyn -bodyguards -2021 -assassinate -barns -emmett -scully -##mah -##yd -##eland -##tino -##itarian -demoted -gorman -lashed -prized -adventist -writ -##gui -alla -invertebrates -##ausen -1641 -amman -1742 -align -healy -redistribution -##gf -##rize -insulation -##drop -adherents -hezbollah -vitro -ferns -yanking -269 -php -registering -uppsala -cheerleading -confines -mischievous -tully -##ross -49th -docked -roam -stipulated -pumpkin -##bry -prompt -##ezer -blindly -shuddering -craftsmen -frail -scented -katharine -scramble -shaggy -sponge -helix -zaragoza -279 -##52 -43rd -backlash -fontaine -seizures -posse -cowan -nonfiction -telenovela -wwii -hammered -undone -##gpur -encircled -irs -##ivation -artefacts -oneself -searing -smallpox -##belle -##osaurus -shandong -breached -upland -blushing -rankin -infinitely -psyche -tolerated -docking -evicted -##col -unmarked -##lving -gnome -lettering -litres -musique -##oint -benevolent -##jal -blackened -##anna -mccall -racers -tingle -##ocene -##orestation -introductions -radically -292 -##hiff -##باد -1610 -1739 -munchen -plead -##nka -condo -scissors -##sight -##tens -apprehension -##cey -##yin -hallmark -watering -formulas -sequels -##llas -aggravated -bae -commencing -##building -enfield -prohibits -marne -vedic -civilized -euclidean -jagger -beforehand -blasts -dumont -##arney -##nem -740 -conversions -hierarchical -rios -simulator -##dya -##lellan -hedges -oleg -thrusts -shadowed -darby -maximize -1744 -gregorian -##nded -##routed -sham -unspecified -##hog -emory -factual -##smo -##tp -fooled -##rger -ortega -wellness -marlon -##oton -##urance -casket -keating -ley -enclave -##ayan -char -influencing -jia -##chenko -412 -ammonia -erebidae -incompatible -violins -cornered -##arat -grooves -astronauts -columbian -rampant -fabrication -kyushu -mahmud -vanish -##dern -mesopotamia -##lete -ict -##rgen -caspian -kenji -pitted -##vered -999 -grimace -roanoke -tchaikovsky -twinned -##analysis -##awan -xinjiang -arias -clemson -kazakh -sizable -1662 -##khand -##vard -plunge -tatum -vittorio -##nden -cholera -##dana -##oper -bracing -indifference -projectile -superliga -##chee -realises -upgrading -299 -porte -retribution -##vies -nk -stil -##resses -ama -bureaucracy -blackberry -bosch -testosterone -collapses -greer -##pathic -ioc -fifties -malls -##erved -bao -baskets -adolescents -siegfried -##osity -##tosis -mantra -detecting -existent -fledgling -##cchi -dissatisfied -gan -telecommunication -mingled -sobbed -6000 -controversies -outdated -taxis -##raus -fright -slams -##lham -##fect -##tten -detectors -fetal -tanned -##uw -fray -goth -olympian -skipping -mandates -scratches -sheng -unspoken -hyundai -tracey -hotspur -restrictive -##buch -americana -mundo -##bari -burroughs -diva -vulcan -##6th -distinctions -thumping -##ngen -mikey -sheds -fide -rescues -springsteen -vested -valuation -##ece -##ely -pinnacle -rake -sylvie -##edo -almond -quivering -##irus -alteration -faltered -##wad -51st -hydra -ticked -##kato -recommends -##dicated -antigua -arjun -stagecoach -wilfred -trickle -pronouns -##pon -aryan -nighttime -##anian -gall -pea -stitch -##hei -leung -milos -##dini -eritrea -nexus -starved -snowfall -kant -parasitic -cot -discus -hana -strikers -appleton -kitchens -##erina -##partisan -##itha -##vius -disclose -metis -##channel -1701 -tesla -##vera -fitch -1735 -blooded -##tila -decimal -##tang -##bai -cyclones -eun -bottled -peas -pensacola -basha -bolivian -crabs -boil -lanterns -partridge -roofed -1645 -necks -##phila -opined -patting -##kla -##lland -chuckles -volta -whereupon -##nche -devout -euroleague -suicidal -##dee -inherently -involuntary -knitting -nasser -##hide -puppets -colourful -courageous -southend -stills -miraculous -hodgson -richer -rochdale -ethernet -greta -uniting -prism -umm -##haya -##itical -##utation -deterioration -pointe -prowess -##ropriation -lids -scranton -billings -subcontinent -##koff -##scope -brute -kellogg -psalms -degraded -##vez -stanisław -##ructured -ferreira -pun -astonishing -gunnar -##yat -arya -prc -gottfried -##tight -excursion -##ographer -dina -##quil -##nare -huffington -illustrious -wilbur -gundam -verandah -##zard -naacp -##odle -constructive -fjord -kade -##naud -generosity -thrilling -baseline -cayman -frankish -plastics -accommodations -zoological -##fting -cedric -qb -motorized -##dome -##otted -squealed -tackled -canucks -budgets -situ -asthma -dail -gabled -grasslands -whimpered -writhing -judgments -##65 -minnie -pv -##carbon -bananas -grille -domes -monique -odin -maguire -markham -tierney -##estra -##chua -libel -poke -speedy -atrium -laval -notwithstanding -##edly -fai -kala -##sur -robb -##sma -listings -luz -supplementary -tianjin -##acing -enzo -jd -ric -scanner -croats -transcribed -##49 -arden -cv -##hair -##raphy -##lver -##uy -357 -seventies -staggering -alam -horticultural -hs -regression -timbers -blasting -##ounded -montagu -manipulating -##cit -catalytic -1550 -troopers -##meo -condemnation -fitzpatrick -##oire -##roved -inexperienced -1670 -castes -##lative -outing -314 -dubois -flicking -quarrel -ste -learners -1625 -iq -whistled -##class -282 -classify -tariffs -temperament -355 -folly -liszt -##yles -immersed -jordanian -ceasefire -apparel -extras -maru -fished -##bio -harta -stockport -assortment -craftsman -paralysis -transmitters -##cola -blindness -##wk -fatally -proficiency -solemnly -##orno -repairing -amore -groceries -ultraviolet -##chase -schoolhouse -##tua -resurgence -nailed -##otype -##× -ruse -saliva -diagrams -##tructing -albans -rann -thirties -1b -antennas -hilarious -cougars -paddington -stats -##eger -breakaway -ipod -reza -authorship -prohibiting -scoffed -##etz -##ttle -conscription -defected -trondheim -##fires -ivanov -keenan -##adan -##ciful -##fb -##slow -locating -##ials -##tford -cadiz -basalt -blankly -interned -rags -rattling -##tick -carpathian -reassured -sync -bum -guildford -iss -staunch -##onga -astronomers -sera -sofie -emergencies -susquehanna -##heard -duc -mastery -vh1 -williamsburg -bayer -buckled -craving -##khan -##rdes -bloomington -##write -alton -barbecue -##bians -justine -##hri -##ndt -delightful -smartphone -newtown -photon -retrieval -peugeot -hissing -##monium -##orough -flavors -lighted -relaunched -tainted -##games -##lysis -anarchy -microscopic -hopping -adept -evade -evie -##beau -inhibit -sinn -adjustable -hurst -intuition -wilton -cisco -44th -lawful -lowlands -stockings -thierry -##dalen -##hila -##nai -fates -prank -tb -maison -lobbied -provocative -1724 -4a -utopia -##qual -carbonate -gujarati -purcell -##rford -curtiss -##mei -overgrown -arenas -mediation -swallows -##rnik -respectful -turnbull -##hedron -##hope -alyssa -ozone -##ʻi -ami -gestapo -johansson -snooker -canteen -cuff -declines -empathy -stigma -##ags -##iner -##raine -taxpayers -gui -volga -##wright -##copic -lifespan -overcame -tattooed -enactment -giggles -##ador -##camp -barrington -bribe -obligatory -orbiting -peng -##enas -elusive -sucker -##vating -cong -hardship -empowered -anticipating -estrada -cryptic -greasy -detainees -planck -sudbury -plaid -dod -marriott -kayla -##ears -##vb -##zd -mortally -##hein -cognition -radha -319 -liechtenstein -meade -richly -argyle -harpsichord -liberalism -trumpets -lauded -tyrant -salsa -tiled -lear -promoters -reused -slicing -trident -##chuk -##gami -##lka -cantor -checkpoint -##points -gaul -leger -mammalian -##tov -##aar -##schaft -doha -frenchman -nirvana -##vino -delgado -headlining -##eron -##iography -jug -tko -1649 -naga -intersections -##jia -benfica -nawab -##suka -ashford -gulp -##deck -##vill -##rug -brentford -frazier -pleasures -dunne -potsdam -shenzhen -dentistry -##tec -flanagan -##dorff -##hear -chorale -dinah -prem -quezon -##rogated -relinquished -sutra -terri -##pani -flaps -##rissa -poly -##rnet -homme -aback -##eki -linger -womb -##kson -##lewood -doorstep -orthodoxy -threaded -westfield -##rval -dioceses -fridays -subsided -##gata -loyalists -##biotic -##ettes -letterman -lunatic -prelate -tenderly -invariably -souza -thug -winslow -##otide -furlongs -gogh -jeopardy -##runa -pegasus -##umble -humiliated -standalone -tagged -##roller -freshmen -klan -##bright -attaining -initiating -transatlantic -logged -viz -##uance -1723 -combatants -intervening -stephane -chieftain -despised -grazed -317 -cdc -galveston -godzilla -macro -simulate -##planes -parades -##esses -960 -##ductive -##unes -equator -overdose -##cans -##hosh -##lifting -joshi -epstein -sonora -treacherous -aquatics -manchu -responsive -##sation -supervisory -##christ -##llins -##ibar -##balance -##uso -kimball -karlsruhe -mab -##emy -ignores -phonetic -reuters -spaghetti -820 -almighty -danzig -rumbling -tombstone -designations -lured -outset -##felt -supermarkets -##wt -grupo -kei -kraft -susanna -##blood -comprehension -genealogy -##aghan -##verted -redding -##ythe -1722 -bowing -##pore -##roi -lest -sharpened -fulbright -valkyrie -sikhs -##unds -swans -bouquet -merritt -##tage -##venting -commuted -redhead -clerks -leasing -cesare -dea -hazy -##vances -fledged -greenfield -servicemen -##gical -armando -blackout -dt -sagged -downloadable -intra -potion -pods -##4th -##mism -xp -attendants -gambia -stale -##ntine -plump -asteroids -rediscovered -buds -flea -hive -##neas -1737 -classifications -debuts -##eles -olympus -scala -##eurs -##gno -##mute -hummed -sigismund -visuals -wiggled -await -pilasters -clench -sulfate -##ances -bellevue -enigma -trainee -snort -##sw -clouded -denim -##rank -##rder -churning -hartman -lodges -riches -sima -##missible -accountable -socrates -regulates -mueller -##cr -1702 -avoids -solids -himalayas -nutrient -pup -##jevic -squat -fades -nec -##lates -##pina -##rona -##ου -privateer -tequila -##gative -##mpton -apt -hornet -immortals -##dou -asturias -cleansing -dario -##rries -##anta -etymology -servicing -zhejiang -##venor -##nx -horned -erasmus -rayon -relocating -£10 -##bags -escalated -promenade -stubble -2010s -artisans -axial -liquids -mora -sho -yoo -##tsky -bundles -oldies -##nally -notification -bastion -##ths -sparkle -##lved -1728 -leash -pathogen -highs -##hmi -immature -880 -gonzaga -ignatius -mansions -monterrey -sweets -bryson -##loe -polled -regatta -brightest -pei -rosy -squid -hatfield -payroll -addict -meath -cornerback -heaviest -lodging -##mage -capcom -rippled -##sily -barnet -mayhem -ymca -snuggled -rousseau -##cute -blanchard -284 -fragmented -leighton -chromosomes -risking -##md -##strel -##utter -corinne -coyotes -cynical -hiroshi -yeomanry -##ractive -ebook -grading -mandela -plume -agustin -magdalene -##rkin -bea -femme -trafford -##coll -##lun -##tance -52nd -fourier -upton -##mental -camilla -gust -iihf -islamabad -longevity -##kala -feldman -netting -##rization -endeavour -foraging -mfa -orr -##open -greyish -contradiction -graz -##ruff -handicapped -marlene -tweed -oaxaca -spp -campos -miocene -pri -configured -cooks -pluto -cozy -pornographic -##entes -70th -fairness -glided -jonny -lynne -rounding -sired -##emon -##nist -remade -uncover -##mack -complied -lei -newsweek -##jured -##parts -##enting -##pg -293 -finer -guerrillas -athenian -deng -disused -stepmother -accuse -gingerly -seduction -521 -confronting -##walker -##going -gora -nostalgia -sabres -virginity -wrenched -##minated -syndication -wielding -eyre -##56 -##gnon -##igny -behaved -taxpayer -sweeps -##growth -childless -gallant -##ywood -amplified -geraldine -scrape -##ffi -babylonian -fresco -##rdan -##kney -##position -1718 -restricting -tack -fukuoka -osborn -selector -partnering -##dlow -318 -gnu -kia -tak -whitley -gables -##54 -##mania -mri -softness -immersion -##bots -##evsky -1713 -chilling -insignificant -pcs -##uis -elites -lina -purported -supplemental -teaming -##americana -##dding -##inton -proficient -rouen -##nage -##rret -niccolo -selects -##bread -fluffy -1621 -gruff -knotted -mukherjee -polgara -thrash -nicholls -secluded -smoothing -thru -corsica -loaf -whitaker -inquiries -##rrier -##kam -indochina -289 -marlins -myles -peking -##tea -extracts -pastry -superhuman -connacht -vogel -##ditional -##het -##udged -##lash -gloss -quarries -refit -teaser -##alic -##gaon -20s -materialized -sling -camped -pickering -tung -tracker -pursuant -##cide -cranes -soc -##cini -##typical -##viere -anhalt -overboard -workout -chores -fares -orphaned -stains -##logie -fenton -surpassing -joyah -triggers -##itte -grandmaster -##lass -##lists -clapping -fraudulent -ledger -nagasaki -##cor -##nosis -##tsa -eucalyptus -tun -##icio -##rney -##tara -dax -heroism -ina -wrexham -onboard -unsigned -##dates -moshe -galley -winnie -droplets -exiles -praises -watered -noodles -##aia -fein -adi -leland -multicultural -stink -bingo -comets -erskine -modernized -canned -constraint -domestically -chemotherapy -featherweight -stifled -##mum -darkly -irresistible -refreshing -hasty -isolate -##oys -kitchener -planners -##wehr -cages -yarn -implant -toulon -elects -childbirth -yue -##lind -##lone -cn -rightful -sportsman -junctions -remodeled -specifies -##rgh -291 -##oons -complimented -##urgent -lister -ot -##logic -bequeathed -cheekbones -fontana -gabby -##dial -amadeus -corrugated -maverick -resented -triangles -##hered -##usly -nazareth -tyrol -1675 -assent -poorer -sectional -aegean -##cous -296 -nylon -ghanaian -##egorical -##weig -cushions -forbid -fusiliers -obstruction -somerville -##scia -dime -earrings -elliptical -leyte -oder -polymers -timmy -atm -midtown -piloted -settles -continual -externally -mayfield -##uh -enrichment -henson -keane -persians -1733 -benji -braden -pep -324 -##efe -contenders -pepsi -valet -##isches -298 -##asse -##earing -goofy -stroll -##amen -authoritarian -occurrences -adversary -ahmedabad -tangent -toppled -dorchester -1672 -modernism -marxism -islamist -charlemagne -exponential -racks -unicode -brunette -mbc -pic -skirmish -##bund -##lad -##powered -##yst -hoisted -messina -shatter -##ctum -jedi -vantage -##music -##neil -clemens -mahmoud -corrupted -authentication -lowry -nils -##washed -omnibus -wounding -jillian -##itors -##opped -serialized -narcotics -handheld -##arm -##plicity -intersecting -stimulating -##onis -crate -fellowships -hemingway -casinos -climatic -fordham -copeland -drip -beatty -leaflets -robber -brothel -madeira -##hedral -sphinx -ultrasound -##vana -valor -forbade -leonid -villas -##aldo -duane -marquez -##cytes -disadvantaged -forearms -kawasaki -reacts -consular -lax -uncles -uphold -##hopper -concepcion -dorsey -lass -##izan -arching -passageway -1708 -researches -tia -internationals -##graphs -##opers -distinguishes -javanese -divert -##uven -plotted -##listic -##rwin -##erik -##tify -affirmative -signifies -validation -##bson -kari -felicity -georgina -zulu -##eros -##rained -##rath -overcoming -##dot -argyll -##rbin -1734 -chiba -ratification -windy -earls -parapet -##marks -hunan -pristine -astrid -punta -##gart -brodie -##kota -##oder -malaga -minerva -rouse -##phonic -bellowed -pagoda -portals -reclamation -##gur -##odies -##⁄₄ -parentheses -quoting -allergic -palette -showcases -benefactor -heartland -nonlinear -##tness -bladed -cheerfully -scans -##ety -##hone -1666 -girlfriends -pedersen -hiram -sous -##liche -##nator -1683 -##nery -##orio -##umen -bobo -primaries -smiley -##cb -unearthed -uniformly -fis -metadata -1635 -ind -##oted -recoil -##titles -##tura -##ια -406 -hilbert -jamestown -mcmillan -tulane -seychelles -##frid -antics -coli -fated -stucco -##grants -1654 -bulky -accolades -arrays -caledonian -carnage -optimism -puebla -##tative -##cave -enforcing -rotherham -seo -dunlop -aeronautics -chimed -incline -zoning -archduke -hellenistic -##oses -##sions -candi -thong -##ople -magnate -rustic -##rsk -projective -slant -##offs -danes -hollis -vocalists -##ammed -congenital -contend -gesellschaft -##ocating -##pressive -douglass -quieter -##cm -##kshi -howled -salim -spontaneously -townsville -buena -southport -##bold -kato -1638 -faerie -stiffly -##vus -##rled -297 -flawless -realising -taboo -##7th -bytes -straightening -356 -jena -##hid -##rmin -cartwright -berber -bertram -soloists -411 -noses -417 -coping -fission -hardin -inca -##cen -1717 -mobilized -vhf -##raf -biscuits -curate -##85 -##anial -331 -gaunt -neighbourhoods -1540 -##abas -blanca -bypassed -sockets -behold -coincidentally -##bane -nara -shave -splinter -terrific -##arion -##erian -commonplace -juris -redwood -waistband -boxed -caitlin -fingerprints -jennie -naturalized -##ired -balfour -craters -jody -bungalow -hugely -quilt -glitter -pigeons -undertaker -bulging -constrained -goo -##sil -##akh -assimilation -reworked -##person -persuasion -##pants -felicia -##cliff -##ulent -1732 -explodes -##dun -##inium -##zic -lyman -vulture -hog -overlook -begs -northwards -ow -spoil -##urer -fatima -favorably -accumulate -sargent -sorority -corresponded -dispersal -kochi -toned -##imi -##lita -internacional -newfound -##agger -##lynn -##rigue -booths -peanuts -##eborg -medicare -muriel -nur -##uram -crates -millennia -pajamas -worsened -##breakers -jimi -vanuatu -yawned -##udeau -carousel -##hony -hurdle -##ccus -##mounted -##pod -rv -##eche -airship -ambiguity -compulsion -recapture -##claiming -arthritis -##osomal -1667 -asserting -ngc -sniffing -dade -discontent -glendale -ported -##amina -defamation -rammed -##scent -fling -livingstone -##fleet -875 -##ppy -apocalyptic -comrade -lcd -##lowe -cessna -eine -persecuted -subsistence -demi -hoop -reliefs -710 -coptic -progressing -stemmed -perpetrators -1665 -priestess -##nio -dobson -ebony -rooster -itf -tortricidae -##bbon -##jian -cleanup -##jean -##øy -1721 -eighties -taxonomic -holiness -##hearted -##spar -antilles -showcasing -stabilized -##nb -gia -mascara -michelangelo -dawned -##uria -##vinsky -extinguished -fitz -grotesque -£100 -##fera -##loid -##mous -barges -neue -throbbed -cipher -johnnie -##a1 -##mpt -outburst -##swick -spearheaded -administrations -c1 -heartbreak -pixels -pleasantly -##enay -lombardy -plush -##nsed -bobbie -##hly -reapers -tremor -xiang -minogue -substantive -hitch -barak -##wyl -kwan -##encia -910 -obscene -elegance -indus -surfer -bribery -conserve -##hyllum -##masters -horatio -##fat -apes -rebound -psychotic -##pour -iteration -##mium -##vani -botanic -horribly -antiques -dispose -paxton -##hli -##wg -timeless -1704 -disregard -engraver -hounds -##bau -##version -looted -uno -facilitates -groans -masjid -rutland -antibody -disqualification -decatur -footballers -quake -slacks -48th -rein -scribe -stabilize -commits -exemplary -tho -##hort -##chison -pantry -traversed -##hiti -disrepair -identifiable -vibrated -baccalaureate -##nnis -csa -interviewing -##iensis -##raße -greaves -wealthiest -343 -classed -jogged -£5 -##58 -##atal -illuminating -knicks -respecting -##uno -scrubbed -##iji -##dles -kruger -moods -growls -raider -silvia -chefs -kam -vr -cree -percival -##terol -gunter -counterattack -defiant -henan -ze -##rasia -##riety -equivalence -submissions -##fra -##thor -bautista -mechanically -##heater -cornice -herbal -templar -##mering -outputs -ruining -ligand -renumbered -extravagant -mika -blockbuster -eta -insurrection -##ilia -darkening -ferocious -pianos -strife -kinship -##aer -melee -##anor -##iste -##may -##oue -decidedly -weep -##jad -##missive -##ppel -354 -puget -unease -##gnant -1629 -hammering -kassel -ob -wessex -##lga -bromwich -egan -paranoia -utilization -##atable -##idad -contradictory -provoke -##ols -##ouring -##tangled -knesset -##very -##lette -plumbing -##sden -##¹ -greensboro -occult -sniff -338 -zev -beaming -gamer -haggard -mahal -##olt -##pins -mendes -utmost -briefing -gunnery -##gut -##pher -##zh -##rok -1679 -khalifa -sonya -##boot -principals -urbana -wiring -##liffe -##minating -##rrado -dahl -nyu -skepticism -np -townspeople -ithaca -lobster -somethin -##fur -##arina -##−1 -freighter -zimmerman -biceps -contractual -##herton -amend -hurrying -subconscious -##anal -336 -meng -clermont -spawning -##eia -##lub -dignitaries -impetus -snacks -spotting -twigs -##bilis -##cz -##ouk -libertadores -nic -skylar -##aina -##firm -gustave -asean -##anum -dieter -legislatures -flirt -bromley -trolls -umar -##bbies -##tyle -blah -parc -bridgeport -crank -negligence -##nction -46th -constantin -molded -bandages -seriousness -00pm -siegel -carpets -compartments -upbeat -statehood -##dner -##edging -marko -730 -platt -##hane -paving -##iy -1738 -abbess -impatience -limousine -nbl -##talk -441 -lucille -mojo -nightfall -robbers -##nais -karel -brisk -calves -replicate -ascribed -telescopes -##olf -intimidated -##reen -ballast -specialization -##sit -aerodynamic -caliphate -rainer -visionary -##arded -epsilon -##aday -##onte -aggregation -auditory -boosted -reunification -kathmandu -loco -robyn -402 -acknowledges -appointing -humanoid -newell -redeveloped -restraints -##tained -barbarians -chopper -1609 -italiana -##lez -##lho -investigates -wrestlemania -##anies -##bib -690 -##falls -creaked -dragoons -gravely -minions -stupidity -volley -##harat -##week -musik -##eries -##uously -fungal -massimo -semantics -malvern -##ahl -##pee -discourage -embryo -imperialism -1910s -profoundly -##ddled -jiangsu -sparkled -stat -##holz -sweatshirt -tobin -##iction -sneered -##cheon -##oit -brit -causal -smyth -##neuve -diffuse -perrin -silvio -##ipes -##recht -detonated -iqbal -selma -##nism -##zumi -roasted -##riders -tay -##ados -##mament -##mut -##rud -840 -completes -nipples -cfa -flavour -hirsch -##laus -calderon -sneakers -moravian -##ksha -1622 -rq -294 -##imeters -bodo -##isance -##pre -##ronia -anatomical -excerpt -##lke -dh -kunst -##tablished -##scoe -biomass -panted -unharmed -gael -housemates -montpellier -##59 -coa -rodents -tonic -hickory -singleton -##taro -451 -1719 -aldo -breaststroke -dempsey -och -rocco -##cuit -merton -dissemination -midsummer -serials -##idi -haji -polynomials -##rdon -gs -enoch -prematurely -shutter -taunton -£3 -##grating -##inates -archangel -harassed -##asco -326 -archway -dazzling -##ecin -1736 -sumo -wat -##kovich -1086 -honneur -##ently -##nostic -##ttal -##idon -1605 -403 -1716 -blogger -rents -##gnan -hires -##ikh -##dant -howie -##rons -handler -retracted -shocks -1632 -arun -duluth -kepler -trumpeter -##lary -peeking -seasoned -trooper -##mara -laszlo -##iciencies -##rti -heterosexual -##inatory -##ssion -indira -jogging -##inga -##lism -beit -dissatisfaction -malice -##ately -nedra -peeling -##rgeon -47th -stadiums -475 -vertigo -##ains -iced -restroom -##plify -##tub -illustrating -pear -##chner -##sibility -inorganic -rappers -receipts -watery -##kura -lucinda -##oulos -reintroduced -##8th -##tched -gracefully -saxons -nutritional -wastewater -rained -favourites -bedrock -fisted -hallways -likeness -upscale -##lateral -1580 -blinds -prequel -##pps -##tama -deter -humiliating -restraining -tn -vents -1659 -laundering -recess -rosary -tractors -coulter -federer -##ifiers -##plin -persistence -##quitable -geschichte -pendulum -quakers -##beam -bassett -pictorial -buffet -koln -##sitor -drills -reciprocal -shooters -##57 -##cton -##tees -converge -pip -dmitri -donnelly -yamamoto -aqua -azores -demographics -hypnotic -spitfire -suspend -wryly -roderick -##rran -sebastien -##asurable -mavericks -##fles -##200 -himalayan -prodigy -##iance -transvaal -demonstrators -handcuffs -dodged -mcnamara -sublime -1726 -crazed -##efined -##till -ivo -pondered -reconciled -shrill -sava -##duk -bal -cad -heresy -jaipur -goran -##nished -341 -lux -shelly -whitehall -##hre -israelis -peacekeeping -##wled -1703 -demetrius -ousted -##arians -##zos -beale -anwar -backstroke -raged -shrinking -cremated -##yck -benign -towing -wadi -darmstadt -landfill -parana -soothe -colleen -sidewalks -mayfair -tumble -hepatitis -ferrer -superstructure -##gingly -##urse -##wee -anthropological -translators -##mies -closeness -hooves -##pw -mondays -##roll -##vita -landscaping -##urized -purification -sock -thorns -thwarted -jalan -tiberius -##taka -saline -##rito -confidently -khyber -sculptors -##ij -brahms -hammersmith -inspectors -battista -fivb -fragmentation -hackney -##uls -arresting -exercising -antoinette -bedfordshire -##zily -dyed -##hema -1656 -racetrack -variability -##tique -1655 -austrians -deteriorating -madman -theorists -aix -lehman -weathered -1731 -decreed -eruptions -1729 -flaw -quinlan -sorbonne -flutes -nunez -1711 -adored -downwards -fable -rasped -1712 -moritz -mouthful -renegade -shivers -stunts -dysfunction -restrain -translit -327 -pancakes -##avio -##cision -##tray -351 -vial -##lden -bain -##maid -##oxide -chihuahua -malacca -vimes -##rba -##rnier -1664 -donnie -plaques -##ually -337 -bangs -floppy -huntsville -loretta -nikolay -##otte -eater -handgun -ubiquitous -##hett -eras -zodiac -1634 -##omorphic -1820s -##zog -cochran -##bula -##lithic -warring -##rada -dalai -excused -blazers -mcconnell -reeling -bot -este -##abi -geese -hoax -taxon -##bla -guitarists -##icon -condemning -hunts -inversion -moffat -taekwondo -##lvis -1624 -stammered -##rest -##rzy -sousa -fundraiser -marylebone -navigable -uptown -cabbage -daniela -salman -shitty -whimper -##kian -##utive -programmers -protections -rm -##rmi -##rued -forceful -##enes -fuss -##tao -##wash -brat -oppressive -reykjavik -spartak -ticking -##inkles -##kiewicz -adolph -horst -maui -protege -straighten -cpc -landau -concourse -clements -resultant -##ando -imaginative -joo -reactivated -##rem -##ffled -##uising -consultative -##guide -flop -kaitlyn -mergers -parenting -somber -##vron -supervise -vidhan -##imum -courtship -exemplified -harmonies -medallist -refining -##rrow -##ка -amara -##hum -780 -goalscorer -sited -overshadowed -rohan -displeasure -secretive -multiplied -osman -##orth -engravings -padre -##kali -##veda -miniatures -mis -##yala -clap -pali -rook -##cana -1692 -57th -antennae -astro -oskar -1628 -bulldog -crotch -hackett -yucatan -##sure -amplifiers -brno -ferrara -migrating -##gree -thanking -turing -##eza -mccann -ting -andersson -onslaught -gaines -ganga -incense -standardization -##mation -sentai -scuba -stuffing -turquoise -waivers -alloys -##vitt -regaining -vaults -##clops -##gizing -digger -furry -memorabilia -probing -##iad -payton -rec -deutschland -filippo -opaque -seamen -zenith -afrikaans -##filtration -disciplined -inspirational -##merie -banco -confuse -grafton -tod -##dgets -championed -simi -anomaly -biplane -##ceptive -electrode -##para -1697 -cleavage -crossbow -swirl -informant -##lars -##osta -afi -bonfire -spec -##oux -lakeside -slump -##culus -##lais -##qvist -##rrigan -1016 -facades -borg -inwardly -cervical -xl -pointedly -050 -stabilization -##odon -chests -1699 -hacked -ctv -orthogonal -suzy -##lastic -gaulle -jacobite -rearview -##cam -##erted -ashby -##drik -##igate -##mise -##zbek -affectionately -canine -disperse -latham -##istles -##ivar -spielberg -##orin -##idium -ezekiel -cid -##sg -durga -middletown -##cina -customized -frontiers -harden -##etano -##zzy -1604 -bolsheviks -##66 -coloration -yoko -##bedo -briefs -slabs -debra -liquidation -plumage -##oin -blossoms -dementia -subsidy -1611 -proctor -relational -jerseys -parochial -ter -##ici -esa -peshawar -cavalier -loren -cpi -idiots -shamrock -1646 -dutton -malabar -mustache -##endez -##ocytes -referencing -terminates -marche -yarmouth -##sop -acton -mated -seton -subtly -baptised -beige -extremes -jolted -kristina -telecast -##actic -safeguard -waldo -##baldi -##bular -endeavors -sloppy -subterranean -##ensburg -##itung -delicately -pigment -tq -##scu -1626 -##ound -collisions -coveted -herds -##personal -##meister -##nberger -chopra -##ricting -abnormalities -defective -galician -lucie -##dilly -alligator -likened -##genase -burundi -clears -complexion -derelict -deafening -diablo -fingered -champaign -dogg -enlist -isotope -labeling -mrna -##erre -brilliance -marvelous -##ayo -1652 -crawley -ether -footed -dwellers -deserts -hamish -rubs -warlock -skimmed -##lizer -870 -buick -embark -heraldic -irregularities -##ajan -kiara -##kulam -##ieg -antigen -kowalski -##lge -oakley -visitation -##mbit -vt -##suit -1570 -murderers -##miento -##rites -chimneys -##sling -condemn -custer -exchequer -havre -##ghi -fluctuations -##rations -dfb -hendricks -vaccines -##tarian -nietzsche -biking -juicy -##duced -brooding -scrolling -selangor -##ragan -352 -annum -boomed -seminole -sugarcane -##dna -departmental -dismissing -innsbruck -arteries -ashok -batavia -daze -kun -overtook -##rga -##tlan -beheaded -gaddafi -holm -electronically -faulty -galilee -fractures -kobayashi -##lized -gunmen -magma -aramaic -mala -eastenders -inference -messengers -bf -##qu -407 -bathrooms -##vere -1658 -flashbacks -ideally -misunderstood -##jali -##weather -mendez -##grounds -505 -uncanny -##iii -1709 -friendships -##nbc -sacrament -accommodated -reiterated -logistical -pebbles -thumped -##escence -administering -decrees -drafts -##flight -##cased -##tula -futuristic -picket -intimidation -winthrop -##fahan -interfered -339 -afar -francoise -morally -uta -cochin -croft -dwarfs -##bruck -##dents -##nami -biker -##hner -##meral -nano -##isen -##ometric -##pres -##ан -brightened -meek -parcels -securely -gunners -##jhl -##zko -agile -hysteria -##lten -##rcus -bukit -champs -chevy -cuckoo -leith -sadler -theologians -welded -##section -1663 -jj -plurality -xander -##rooms -##formed -shredded -temps -intimately -pau -tormented -##lok -##stellar -1618 -charred -ems -essen -##mmel -alarms -spraying -ascot -blooms -twinkle -##abia -##apes -internment -obsidian -##chaft -snoop -##dav -##ooping -malibu -##tension -quiver -##itia -hays -mcintosh -travers -walsall -##ffie -1623 -beverley -schwarz -plunging -structurally -m3 -rosenthal -vikram -##tsk -770 -ghz -##onda -##tiv -chalmers -groningen -pew -reckon -unicef -##rvis -55th -##gni -1651 -sulawesi -avila -cai -metaphysical -screwing -turbulence -##mberg -augusto -samba -56th -baffled -momentary -toxin -##urian -##wani -aachen -condoms -dali -steppe -##3d -##app -##oed -##year -adolescence -dauphin -electrically -inaccessible -microscopy -nikita -##ega -atv -##cel -##enter -##oles -##oteric -##ы -accountants -punishments -wrongly -bribes -adventurous -clinch -flinders -southland -##hem -##kata -gough -##ciency -lads -soared -##ה -undergoes -deformation -outlawed -rubbish -##arus -##mussen -##nidae -##rzburg -arcs -##ingdon -##tituted -1695 -wheelbase -wheeling -bombardier -campground -zebra -##lices -##oj -##bain -lullaby -##ecure -donetsk -wylie -grenada -##arding -##ης -squinting -eireann -opposes -##andra -maximal -runes -##broken -##cuting -##iface -##ror -##rosis -additive -britney -adultery -triggering -##drome -detrimental -aarhus -containment -jc -swapped -vichy -##ioms -madly -##oric -##rag -brant -##ckey -##trix -1560 -1612 -broughton -rustling -##stems -##uder -asbestos -mentoring -##nivorous -finley -leaps -##isan -apical -pry -slits -substitutes -##dict -intuitive -fantasia -insistent -unreasonable -##igen -##vna -domed -hannover -margot -ponder -##zziness -impromptu -jian -lc -rampage -stemming -##eft -andrey -gerais -whichever -amnesia -appropriated -anzac -clicks -modifying -ultimatum -cambrian -maids -verve -yellowstone -##mbs -conservatoire -##scribe -adherence -dinners -spectra -imperfect -mysteriously -sidekick -tatar -tuba -##aks -##ifolia -distrust -##athan -##zle -c2 -ronin -zac -##pse -celaena -instrumentalist -scents -skopje -##mbling -comical -compensated -vidal -condor -intersect -jingle -wavelengths -##urrent -mcqueen -##izzly -carp -weasel -422 -kanye -militias -postdoctoral -eugen -gunslinger -##ɛ -faux -hospice -##for -appalled -derivation -dwarves -##elis -dilapidated -##folk -astoria -philology -##lwyn -##otho -##saka -inducing -philanthropy -##bf -##itative -geek -markedly -sql -##yce -bessie -indices -rn -##flict -495 -frowns -resolving -weightlifting -tugs -cleric -contentious -1653 -mania -rms -##miya -##reate -##ruck -##tucket -bien -eels -marek -##ayton -##cence -discreet -unofficially -##ife -leaks -##bber -1705 -332 -dung -compressor -hillsborough -pandit -shillings -distal -##skin -381 -##tat -##you -nosed -##nir -mangrove -undeveloped -##idia -textures -##inho -##500 -##rise -ae -irritating -nay -amazingly -bancroft -apologetic -compassionate -kata -symphonies -##lovic -airspace -##lch -930 -gifford -precautions -fulfillment -sevilla -vulgar -martinique -##urities -looting -piccolo -tidy -##dermott -quadrant -armchair -incomes -mathematicians -stampede -nilsson -##inking -##scan -foo -quarterfinal -##ostal -shang -shouldered -squirrels -##owe -344 -vinegar -##bner -##rchy -##systems -delaying -##trics -ars -dwyer -rhapsody -sponsoring -##gration -bipolar -cinder -starters -##olio -##urst -421 -signage -##nty -aground -figurative -mons -acquaintances -duets -erroneously -soyuz -elliptic -recreated -##cultural -##quette -##ssed -##tma -##zcz -moderator -scares -##itaire -##stones -##udence -juniper -sighting -##just -##nsen -britten -calabria -ry -bop -cramer -forsyth -stillness -##л -airmen -gathers -unfit -##umber -##upt -taunting -##rip -seeker -streamlined -##bution -holster -schumann -tread -vox -##gano -##onzo -strive -dil -reforming -covent -newbury -predicting -##orro -decorate -tre -##puted -andover -ie -asahi -dept -dunkirk -gills -##tori -buren -huskies -##stis -##stov -abstracts -bets -loosen -##opa -1682 -yearning -##glio -##sir -berman -effortlessly -enamel -napoli -persist -##peration -##uez -attache -elisa -b1 -invitations -##kic -accelerating -reindeer -boardwalk -clutches -nelly -polka -starbucks -##kei -adamant -huey -lough -unbroken -adventurer -embroidery -inspecting -stanza -##ducted -naia -taluka -##pone -##roids -chases -deprivation -florian -##jing -##ppet -earthly -##lib -##ssee -colossal -foreigner -vet -freaks -patrice -rosewood -triassic -upstate -##pkins -dominates -ata -chants -ks -vo -##400 -##bley -##raya -##rmed -555 -agra -infiltrate -##ailing -##ilation -##tzer -##uppe -##werk -binoculars -enthusiast -fujian -squeak -##avs -abolitionist -almeida -boredom -hampstead -marsden -rations -##ands -inflated -334 -bonuses -rosalie -patna -##rco -329 -detachments -penitentiary -54th -flourishing -woolf -##dion -##etched -papyrus -##lster -##nsor -##toy -bobbed -dismounted -endelle -inhuman -motorola -tbs -wince -wreath -##ticus -hideout -inspections -sanjay -disgrace -infused -pudding -stalks -##urbed -arsenic -leases -##hyl -##rrard -collarbone -##waite -##wil -dowry -##bant -##edance -genealogical -nitrate -salamanca -scandals -thyroid -necessitated -##! -##" -### -##$ -##% -##& -##' -##( -##) -##* -##+ -##, -##- -##. -##/ -##: -##; -##< -##= -##> -##? -##@ -##[ -##\ -##] -##^ -##_ -##` -##{ -##| -##} -##~ -##¡ -##¢ -##£ -##¤ -##¥ -##¦ -##§ -##¨ -##© -##ª -##« -##¬ -##® -##± -##´ -##µ -##¶ -##· -##º -##» -##¼ -##¾ -##¿ -##æ -##ð -##÷ -##þ -##đ -##ħ -##ŋ -##œ -##ƒ -##ɐ -##ɑ -##ɒ -##ɔ -##ɕ -##ə -##ɡ -##ɣ -##ɨ -##ɪ -##ɫ -##ɬ -##ɯ -##ɲ -##ɴ -##ɹ -##ɾ -##ʀ -##ʁ -##ʂ -##ʃ -##ʉ -##ʊ -##ʋ -##ʌ -##ʎ -##ʐ -##ʑ -##ʒ -##ʔ -##ʰ -##ʲ -##ʳ -##ʷ -##ʸ -##ʻ -##ʼ -##ʾ -##ʿ -##ˈ -##ˡ -##ˢ -##ˣ -##ˤ -##β -##γ -##δ -##ε -##ζ -##θ -##κ -##λ -##μ -##ξ -##ο -##π -##ρ -##σ -##τ -##υ -##φ -##χ -##ψ -##ω -##б -##г -##д -##ж -##з -##м -##п -##с -##у -##ф -##х -##ц -##ч -##ш -##щ -##ъ -##э -##ю -##ђ -##є -##і -##ј -##љ -##њ -##ћ -##ӏ -##ա -##բ -##գ -##դ -##ե -##թ -##ի -##լ -##կ -##հ -##մ -##յ -##ն -##ո -##պ -##ս -##վ -##տ -##ր -##ւ -##ք -##־ -##א -##ב -##ג -##ד -##ו -##ז -##ח -##ט -##י -##ך -##כ -##ל -##ם -##מ -##ן -##נ -##ס -##ע -##ף -##פ -##ץ -##צ -##ק -##ר -##ש -##ת -##، -##ء -##ب -##ت -##ث -##ج -##ح -##خ -##ذ -##ز -##س -##ش -##ص -##ض -##ط -##ظ -##ع -##غ -##ـ -##ف -##ق -##ك -##و -##ى -##ٹ -##پ -##چ -##ک -##گ -##ں -##ھ -##ہ -##ے -##अ -##आ -##उ -##ए -##क -##ख -##ग -##च -##ज -##ट -##ड -##ण -##त -##थ -##द -##ध -##न -##प -##ब -##भ -##म -##य -##र -##ल -##व -##श -##ष -##स -##ह -##ा -##ि -##ी -##ो -##। -##॥ -##ং -##অ -##আ -##ই -##উ -##এ -##ও -##ক -##খ -##গ -##চ -##ছ -##জ -##ট -##ড -##ণ -##ত -##থ -##দ -##ধ -##ন -##প -##ব -##ভ -##ম -##য -##র -##ল -##শ -##ষ -##স -##হ -##া -##ি -##ী -##ে -##க -##ச -##ட -##த -##ந -##ன -##ப -##ம -##ய -##ர -##ல -##ள -##வ -##ா -##ி -##ு -##ே -##ை -##ನ -##ರ -##ಾ -##ක -##ය -##ර -##ල -##ව -##ා -##ก -##ง -##ต -##ท -##น -##พ -##ม -##ย -##ร -##ล -##ว -##ส -##อ -##า -##เ -##་ -##། -##ག -##ང -##ད -##ན -##པ -##བ -##མ -##འ -##ར -##ལ -##ས -##မ -##ა -##ბ -##გ -##დ -##ე -##ვ -##თ -##ი -##კ -##ლ -##მ -##ნ -##ო -##რ -##ს -##ტ -##უ -##ᄀ -##ᄂ -##ᄃ -##ᄅ -##ᄆ -##ᄇ -##ᄉ -##ᄊ -##ᄋ -##ᄌ -##ᄎ -##ᄏ -##ᄐ -##ᄑ -##ᄒ -##ᅡ -##ᅢ -##ᅥ -##ᅦ -##ᅧ -##ᅩ -##ᅪ -##ᅭ -##ᅮ -##ᅯ -##ᅲ -##ᅳ -##ᅴ -##ᅵ -##ᆨ -##ᆫ -##ᆯ -##ᆷ -##ᆸ -##ᆼ -##ᴬ -##ᴮ -##ᴰ -##ᴵ -##ᴺ -##ᵀ -##ᵃ -##ᵇ -##ᵈ -##ᵉ -##ᵍ -##ᵏ -##ᵐ -##ᵒ -##ᵖ -##ᵗ -##ᵘ -##ᵣ -##ᵤ -##ᵥ -##ᶜ -##ᶠ -##‐ -##‑ -##‒ -##– -##— -##― -##‖ -##‘ -##’ -##‚ -##“ -##” -##„ -##† -##‡ -##• -##… -##‰ -##′ -##″ -##› -##‿ -##⁄ -##⁰ -##ⁱ -##⁴ -##⁵ -##⁶ -##⁷ -##⁸ -##⁹ -##⁻ -##ⁿ -##₅ -##₆ -##₇ -##₈ -##₉ -##₊ -##₍ -##₎ -##ₐ -##ₑ -##ₒ -##ₓ -##ₕ -##ₖ -##ₗ -##ₘ -##ₚ -##ₛ -##ₜ -##₤ -##₩ -##€ -##₱ -##₹ -##ℓ -##№ -##ℝ -##™ -##⅓ -##⅔ -##← -##↑ -##→ -##↓ -##↔ -##↦ -##⇄ -##⇌ -##⇒ -##∂ -##∅ -##∆ -##∇ -##∈ -##∗ -##∘ -##√ -##∞ -##∧ -##∨ -##∩ -##∪ -##≈ -##≡ -##≤ -##≥ -##⊂ -##⊆ -##⊕ -##⊗ -##⋅ -##─ -##│ -##■ -##▪ -##● -##★ -##☆ -##☉ -##♠ -##♣ -##♥ -##♦ -##♯ -##⟨ -##⟩ -##ⱼ -##⺩ -##⺼ -##⽥ -##、 -##。 -##〈 -##〉 -##《 -##》 -##「 -##」 -##『 -##』 -##〜 -##あ -##い -##う -##え -##お -##か -##き -##く -##け -##こ -##さ -##し -##す -##せ -##そ -##た -##ち -##っ -##つ -##て -##と -##な -##に -##ぬ -##ね -##の -##は -##ひ -##ふ -##へ -##ほ -##ま -##み -##む -##め -##も -##や -##ゆ -##よ -##ら -##り -##る -##れ -##ろ -##を -##ん -##ァ -##ア -##ィ -##イ -##ウ -##ェ -##エ -##オ -##カ -##キ -##ク -##ケ -##コ -##サ -##シ -##ス -##セ -##タ -##チ -##ッ -##ツ -##テ -##ト -##ナ -##ニ -##ノ -##ハ -##ヒ -##フ -##ヘ -##ホ -##マ -##ミ -##ム -##メ -##モ -##ャ -##ュ -##ョ -##ラ -##リ -##ル -##レ -##ロ -##ワ -##ン -##・ -##ー -##一 -##三 -##上 -##下 -##不 -##世 -##中 -##主 -##久 -##之 -##也 -##事 -##二 -##五 -##井 -##京 -##人 -##亻 -##仁 -##介 -##代 -##仮 -##伊 -##会 -##佐 -##侍 -##保 -##信 -##健 -##元 -##光 -##八 -##公 -##内 -##出 -##分 -##前 -##劉 -##力 -##加 -##勝 -##北 -##区 -##十 -##千 -##南 -##博 -##原 -##口 -##古 -##史 -##司 -##合 -##吉 -##同 -##名 -##和 -##囗 -##四 -##国 -##國 -##土 -##地 -##坂 -##城 -##堂 -##場 -##士 -##夏 -##外 -##大 -##天 -##太 -##夫 -##奈 -##女 -##子 -##学 -##宀 -##宇 -##安 -##宗 -##定 -##宣 -##宮 -##家 -##宿 -##寺 -##將 -##小 -##尚 -##山 -##岡 -##島 -##崎 -##川 -##州 -##巿 -##帝 -##平 -##年 -##幸 -##广 -##弘 -##張 -##彳 -##後 -##御 -##德 -##心 -##忄 -##志 -##忠 -##愛 -##成 -##我 -##戦 -##戸 -##手 -##扌 -##政 -##文 -##新 -##方 -##日 -##明 -##星 -##春 -##昭 -##智 -##曲 -##書 -##月 -##有 -##朝 -##木 -##本 -##李 -##村 -##東 -##松 -##林 -##森 -##楊 -##樹 -##橋 -##歌 -##止 -##正 -##武 -##比 -##氏 -##民 -##水 -##氵 -##氷 -##永 -##江 -##沢 -##河 -##治 -##法 -##海 -##清 -##漢 -##瀬 -##火 -##版 -##犬 -##王 -##生 -##田 -##男 -##疒 -##発 -##白 -##的 -##皇 -##目 -##相 -##省 -##真 -##石 -##示 -##社 -##神 -##福 -##禾 -##秀 -##秋 -##空 -##立 -##章 -##竹 -##糹 -##美 -##義 -##耳 -##良 -##艹 -##花 -##英 -##華 -##葉 -##藤 -##行 -##街 -##西 -##見 -##訁 -##語 -##谷 -##貝 -##貴 -##車 -##軍 -##辶 -##道 -##郎 -##郡 -##部 -##都 -##里 -##野 -##金 -##鈴 -##镇 -##長 -##門 -##間 -##阝 -##阿 -##陳 -##陽 -##雄 -##青 -##面 -##風 -##食 -##香 -##馬 -##高 -##龍 -##龸 -##fi -##fl -##! -##( -##) -##, -##- -##. -##/ -##: -##? -##~ diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.asyncify.mjs b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.asyncify.mjs deleted file mode 100644 index 59fd26b1f..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.asyncify.mjs +++ /dev/null @@ -1,3281 +0,0 @@ -async function ortWasmThreaded(moduleArg = {}) { - var moduleRtn; - var g = moduleArg, - aa = !!globalThis.window, - ba = !!globalThis.WorkerGlobalScope, - l = globalThis.process?.versions?.node && "renderer" != globalThis.process?.type, - n = ba && self.name?.startsWith("em-pthread"); - if (l) { - const { createRequire: a } = await import("module"); - var require = a(import.meta.url), - ca = require("worker_threads"); - global.Worker = ca.Worker; - n = (ba = !ca.ne) && "em-pthread" == ca.workerData; - } - g.mountExternalData = (a, b) => { - a.startsWith("./") && (a = a.substring(2)); - (g.Uc || (g.Uc = new Map())).set(a, b); - }; - g.unmountExternalData = () => { - delete g.Uc; - }; - var SharedArrayBuffer = - globalThis.SharedArrayBuffer ?? - new WebAssembly.Memory({ initial: 0, maximum: 0, Be: !0 }).buffer.constructor; - let ea = () => { - const a = - (b) => - (...c) => { - const d = r; - c = b(...c); - return r != d ? da() : c; - }; - ((b) => { - for (const c of b) g[c] = a(g[c]); - })([ - "_OrtAppendExecutionProvider", - "_OrtCreateSession", - "_OrtRun", - "_OrtRunWithBinding", - "_OrtBindInput", - ]); - "undefined" !== typeof jsepRunAsync && - ((g._OrtRun = jsepRunAsync(g._OrtRun)), - (g._OrtRunWithBinding = jsepRunAsync(g._OrtRunWithBinding))); - ea = void 0; - }; - g.asyncInit = () => { - ea?.(); - }; - var fa = "./this.program", - ha = (a, b) => { - throw b; - }, - ia = import.meta.url, - ja = "", - ka, - la; - if (l) { - var fs = require("fs"); - ia.startsWith("file:") && - (ja = require("path").dirname(require("url").fileURLToPath(ia)) + "/"); - la = (a) => { - a = ma(a) ? new URL(a) : a; - return fs.readFileSync(a); - }; - ka = async (a) => { - a = ma(a) ? new URL(a) : a; - return fs.readFileSync(a, void 0); - }; - 1 < process.argv.length && (fa = process.argv[1].replace(/\\/g, "/")); - process.argv.slice(2); - ha = (a, b) => { - process.exitCode = a; - throw b; - }; - } else if (aa || ba) { - try { - ja = new URL(".", ia).href; - } catch {} - l || - (ba && - (la = (a) => { - var b = new XMLHttpRequest(); - b.open("GET", a, !1); - b.responseType = "arraybuffer"; - b.send(null); - return new Uint8Array(b.response); - }), - (ka = async (a) => { - if (ma(a)) - return new Promise((c, d) => { - var e = new XMLHttpRequest(); - e.open("GET", a, !0); - e.responseType = "arraybuffer"; - e.onload = () => { - 200 == e.status || (0 == e.status && e.response) ? c(e.response) : d(e.status); - }; - e.onerror = d; - e.send(null); - }); - var b = await fetch(a, { credentials: "same-origin" }); - if (b.ok) return b.arrayBuffer(); - throw Error(b.status + " : " + b.url); - })); - } - var na = console.log.bind(console), - oa = console.error.bind(console); - if (l) { - var pa = require("util"), - qa = (a) => ("object" == typeof a ? pa.inspect(a) : a); - na = (...a) => fs.writeSync(1, a.map(qa).join(" ") + "\n"); - oa = (...a) => fs.writeSync(2, a.map(qa).join(" ") + "\n"); - } - var ra = na, - t = oa, - sa, - ta, - ua = !1, - va, - ma = (a) => a.startsWith("file://"); - function u() { - v.buffer != w.buffer && wa(); - } - var xa, ya; - if (l && n) { - var Aa = ca.parentPort; - Aa.on("message", (a) => global.onmessage?.({ data: a })); - Object.assign(globalThis, { self: global, postMessage: (a) => Aa.postMessage(a) }); - process.on("uncaughtException", (a) => { - postMessage({ Oc: "uncaughtException", error: a }); - process.exit(1); - }); - } - var Ba; - if (n) { - var Ca = !1; - self.onunhandledrejection = (b) => { - throw b.reason || b; - }; - function a(b) { - try { - var c = b.data, - d = c.Oc; - if ("load" === d) { - let e = []; - self.onmessage = (f) => e.push(f); - Ba = () => { - postMessage({ Oc: "loaded" }); - for (let f of e) a(f); - self.onmessage = a; - }; - for (const f of c.de) - if (!g[f] || g[f].proxy) - ((g[f] = (...h) => { - postMessage({ Oc: "callHandler", ce: f, args: h }); - }), - "print" == f && (ra = g[f]), - "printErr" == f && (t = g[f])); - v = c.je; - wa(); - ta = c.ke; - Da(); - Ea(); - } else if ("run" === d) { - Fa(c.Nc); - Ga(c.Nc, 0, 0, 1, 0, 0); - Ha(); - Ia(c.Nc); - Ca || (Ja(), (Ca = !0)); - try { - Ka(c.he, c.Wc); - } catch (e) { - if ("unwind" != e) throw e; - } - } else - "setimmediate" !== c.target && - ("checkMailbox" === d - ? Ca && La() - : d && (t(`worker: received unknown command ${d}`), t(c))); - } catch (e) { - throw (Ma(), e); - } - } - self.onmessage = a; - } - var w, - x, - Na, - Oa, - A, - B, - Pa, - E, - F, - Qa, - Ra = !1; - function wa() { - var a = v.buffer; - g.HEAP8 = w = new Int8Array(a); - Na = new Int16Array(a); - g.HEAPU8 = x = new Uint8Array(a); - Oa = new Uint16Array(a); - g.HEAP32 = A = new Int32Array(a); - g.HEAPU32 = B = new Uint32Array(a); - Pa = new Float32Array(a); - E = new Float64Array(a); - F = new BigInt64Array(a); - Qa = new BigUint64Array(a); - } - function Sa() { - Ra = !0; - n ? Ba() : G._b(); - } - function Ta(a) { - a = "Aborted(" + a + ")"; - t(a); - ua = !0; - a = new WebAssembly.RuntimeError(a + ". Build with -sASSERTIONS for more info."); - ya?.(a); - throw a; - } - var Ua; - async function Va(a) { - if (!sa) - try { - var b = await ka(a); - return new Uint8Array(b); - } catch {} - if (a == Ua && sa) a = new Uint8Array(sa); - else if (la) a = la(a); - else throw "both async and sync fetching of the wasm failed"; - return a; - } - async function Wa(a, b) { - try { - var c = await Va(a); - return await WebAssembly.instantiate(c, b); - } catch (d) { - (t(`failed to asynchronously prepare wasm: ${d}`), Ta(d)); - } - } - async function Xa(a) { - var b = Ua; - if (!sa && !ma(b) && !l) - try { - var c = fetch(b, { credentials: "same-origin" }); - return await WebAssembly.instantiateStreaming(c, a); - } catch (d) { - (t(`wasm streaming compile failed: ${d}`), t("falling back to ArrayBuffer instantiation")); - } - return Wa(b, a); - } - function Ya() { - Za = { - f: $a, - J: ab, - k: bb, - p: cb, - l: db, - ta: eb, - b: fb, - ca: gb, - Ka: hb, - q: ib, - da: jb, - _a: kb, - Ga: lb, - Ia: mb, - $a: nb, - Ya: ob, - Ra: pb, - Xa: qb, - pa: rb, - Ha: sb, - Yb: tb, - Za: ub, - Fa: vb, - eb: wb, - Da: xb, - Tb: zb, - Rb: Ab, - Ca: Cb, - M: Db, - I: Eb, - Sb: Fb, - ka: Gb, - Ub: Hb, - Ua: Ib, - Wb: Jb, - La: Kb, - Pb: Lb, - la: Mb, - Ta: Ia, - bb: Nb, - U: Ob, - n: Pb, - c: Qb, - sb: Rb, - w: Sb, - L: Tb, - z: Ub, - j: Vb, - o: Wb, - tb: Xb, - G: Yb, - T: Zb, - h: $b, - u: ac, - m: bc, - i: cc, - Oa: dc, - Pa: ec, - Qa: fc, - Ma: gc, - Na: hc, - Qb: ic, - fb: jc, - db: kc, - Y: lc, - rb: mc, - ma: nc, - cb: oc, - gb: pc, - ab: qc, - Xb: rc, - N: sc, - hb: tc, - X: uc, - Vb: vc, - ob: wc, - C: xc, - sa: yc, - ra: zc, - qb: Ac, - W: Bc, - v: Cc, - nb: Dc, - mb: Ec, - lb: Fc, - pb: Gc, - kb: Hc, - jb: Ic, - ib: Jc, - Va: Kc, - Wa: Lc, - Ja: Mc, - ea: Nc, - oa: Oc, - Sa: Pc, - na: Qc, - Db: Rc, - xa: Sc, - Eb: Tc, - ya: Uc, - F: Vc, - e: Wc, - s: Xc, - x: Yc, - D: Zc, - Ib: $c, - ba: ad, - B: bd, - za: cd, - $: dd, - ha: ed, - Fb: fd, - Gb: gd, - Ba: hd, - Aa: jd, - Jb: kd, - wa: ld, - aa: md, - d: nd, - A: od, - r: pd, - Cb: qd, - t: rd, - y: sd, - H: td, - E: ud, - K: vd, - S: wd, - ja: xd, - _: yd, - Kb: zd, - Lb: Ad, - P: Bd, - g: Cd, - a: v, - Ob: Dd, - Hb: Ed, - ia: Fd, - O: Gd, - qa: Hd, - Mb: Id, - Q: Jd, - zb: Kd, - Ab: Ld, - ua: Md, - fa: Nd, - R: Od, - Ea: Pd, - va: Qd, - Z: Rd, - xb: Sd, - Zb: Td, - V: Ud, - Bb: Vd, - ub: Wd, - vb: Xd, - wb: Yd, - ga: Zd, - yb: $d, - Nb: ae, - }; - return { a: Za }; - } - async function Da() { - function a(d, e) { - var f = (G = d.exports); - d = {}; - for (let [h, k] of Object.entries(f)) - "function" == typeof k ? ((f = be(k)), (d[h] = f)) : (d[h] = k); - G = d; - G = ce(); - de.push(G.id); - d = G; - ee = d.$b; - Ja = d.ac; - g._OrtInit = d.bc; - g._OrtGetLastError = d.cc; - g._OrtCreateSessionOptions = d.dc; - g._OrtAppendExecutionProvider = d.ec; - g._OrtAddFreeDimensionOverride = d.fc; - g._OrtAddSessionConfigEntry = d.gc; - g._OrtReleaseSessionOptions = d.hc; - g._OrtCreateSession = d.ic; - g._OrtReleaseSession = d.jc; - g._OrtGetInputOutputCount = d.kc; - g._OrtGetInputOutputMetadata = d.lc; - g._OrtFree = d.mc; - g._OrtCreateTensor = d.nc; - g._OrtGetTensorData = d.oc; - g._OrtReleaseTensor = d.pc; - g._OrtCreateRunOptions = d.qc; - g._OrtAddRunConfigEntry = d.rc; - g._OrtReleaseRunOptions = d.sc; - g._OrtCreateBinding = d.tc; - g._OrtBindInput = d.uc; - g._OrtBindOutput = d.vc; - g._OrtClearBoundOutputs = d.wc; - g._OrtReleaseBinding = d.xc; - g._OrtRunWithBinding = d.yc; - g._OrtRun = d.zc; - g._OrtEndProfiling = d.Ac; - fe = g._OrtGetWebGpuDevice = d.Bc; - ge = d.Cc; - H = g._free = d.Dc; - he = g._malloc = d.Ec; - ie = g._wgpuBufferRelease = d.Fc; - je = g._wgpuCreateInstance = d.Gc; - ke = d.Hc; - le = d.Ic; - me = d.Jc; - ne = d.Kc; - oe = d.Lc; - pe = d.Pc; - qe = d.Zc; - re = d._c; - se = d.$c; - te = d.bd; - ue = d.cd; - ve = d.dd; - we = d.ed; - xe = d.fd; - ye = d.gd; - ze = d.hd; - Ga = d.kd; - Ma = d.ld; - Ae = d.md; - Be = d.nd; - Ce = d.od; - De = d.pd; - Ee = d.qd; - Fe = d.rd; - I = d.sd; - Ge = d.td; - He = d.ud; - J = d.vd; - Ie = d.wd; - K = d.xd; - Je = d.yd; - Ke = d.zd; - Le = d.Ad; - Me = d.Bd; - dynCall_vii = d.Cd; - Ne = d.Dd; - dynCall_v = d.Ed; - Oe = d.Fd; - Pe = d.Gd; - Qe = d.Hd; - dynCall_iii = d.Id; - Re = d.Jd; - Se = d.Kd; - Te = d.Ld; - dynCall_vi = d.Md; - Ue = d.Nd; - Ve = d.Od; - We = d.Pd; - Xe = d.Qd; - Ye = d.Rd; - Ze = d.Td; - $e = d.Ud; - af = d.Vd; - bf = d.Wd; - cf = d.Yd; - df = d.Zd; - ef = d._d; - ff = d.$d; - gf = d.ae; - hf = d.be; - jf = d.pe; - kf = d.qe; - lf = d.re; - mf = d.se; - nf = d.te; - of = d.ue; - pf = d.ve; - qf = d.we; - rf = d.xe; - sf = d.ye; - tf = d.ze; - uf = d.Xe; - vf = d.Ye; - wf = d.Ze; - xf = d._e; - ta = e; - return G; - } - var b = Ya(); - if (g.instantiateWasm) - return new Promise((d) => { - g.instantiateWasm(b, (e, f) => { - d(a(e, f)); - }); - }); - if (n) { - var c = new WebAssembly.Instance(ta, Ya()); - return a(c, ta); - } - Ua ??= g.locateFile - ? g.locateFile - ? g.locateFile("ort-wasm-simd-threaded.asyncify.wasm", ja) - : ja + "ort-wasm-simd-threaded.asyncify.wasm" - : new URL("ort-wasm-simd-threaded.asyncify.wasm", import.meta.url).href; - return (function (d) { - return a(d.instance, d.module); - })(await Xa(b)); - } - class yf { - name = "ExitStatus"; - constructor(a) { - this.message = `Program terminated with exit(${a})`; - this.status = a; - } - } - var zf = (a) => { - a.terminate(); - a.onmessage = () => {}; - }, - Af = [], - Bf = 0, - Cf = null, - If = (a) => { - 0 == Df.length && (Ef(), Ff(Df[0])); - var b = Df.pop(); - if (!b) return 6; - Gf.push(b); - Hf[a.Nc] = b; - b.Nc = a.Nc; - var c = { Oc: "run", he: a.ge, Wc: a.Wc, Nc: a.Nc }; - l && b.unref(); - b.postMessage(c, a.Yc); - return 0; - }, - L = 0, - M = (a, b, ...c) => { - var d = 16 * c.length, - e = K(), - f = Ie(d), - h = f >>> 3, - k; - for (k of c) - "bigint" == typeof k - ? (((u(), F)[h++ >>> 0] = 1n), ((u(), F)[h++ >>> 0] = k)) - : (((u(), F)[h++ >>> 0] = 0n), ((u(), E)[h++ >>> 0] = k)); - a = Ae(a, 0, d, f, b); - J(e); - return a; - }; - function Dd(a) { - if (n) return M(0, 1, a); - va = a; - if (!(0 < L)) { - for (var b of Gf) zf(b); - for (b of Df) zf(b); - Df = []; - Gf = []; - Hf = {}; - ua = !0; - } - ha(a, new yf(a)); - } - function Jf(a) { - if (n) return M(1, 0, a); - Mc(a); - } - var Mc = (a) => { - va = a; - if (n) throw (Jf(a), "unwind"); - Dd(a); - }, - Df = [], - Gf = [], - de = [], - Hf = {}; - function Kf() { - for (var a = g.numThreads - 1; a--; ) Ef(); - Af.push(async () => { - var b = Lf(); - Bf++; - await b; - Bf--; - 0 == Bf && Cf && ((b = Cf), (Cf = null), b()); - }); - } - var Mf = (a) => { - var b = a.Nc; - delete Hf[b]; - Df.push(a); - Gf.splice(Gf.indexOf(a), 1); - a.Nc = 0; - Be(b); - }; - function Ha() { - de.forEach((a) => a()); - } - var Ff = (a) => - new Promise((b) => { - a.onmessage = (f) => { - var h = f.data; - f = h.Oc; - if (h.Vc && h.Vc != ge()) { - var k = Hf[h.Vc]; - k - ? k.postMessage(h, h.Yc) - : t( - `Internal error! Worker sent a message "${f}" to target pthread ${h.Vc}, but that thread no longer exists!`, - ); - } else if ("checkMailbox" === f) La(); - else if ("spawnThread" === f) If(h); - else if ("cleanupThread" === f) - N(() => { - Mf(Hf[h.ie]); - }); - else if ("loaded" === f) ((a.loaded = !0), l && !a.Nc && a.unref(), b(a)); - else if ("setimmediate" === h.target) a.postMessage(h); - else if ("uncaughtException" === f) a.onerror(h.error); - else if ("callHandler" === f) g[h.ce](...h.args); - else f && t(`worker sent an unknown command ${f}`); - }; - a.onerror = (f) => { - t(`${"worker sent an error!"} ${f.filename}:${f.lineno}: ${f.message}`); - throw f; - }; - l && (a.on("message", (f) => a.onmessage({ data: f })), a.on("error", (f) => a.onerror(f))); - var c = [], - d = [], - e; - for (e of d) g.propertyIsEnumerable(e) && c.push(e); - a.postMessage({ Oc: "load", de: c, je: v, ke: ta }); - }); - async function Lf() { - if (!n) return Promise.all(Df.map(Ff)); - } - function Ef() { - var a = new Worker(new URL(import.meta.url), { - type: "module", - workerData: "em-pthread", - name: "em-pthread", - }); - Df.push(a); - } - function Fa(a) { - var b = (u(), B)[((a + 52) >>> 2) >>> 0]; - a = (u(), B)[((a + 56) >>> 2) >>> 0]; - He(b, b - a); - J(b); - } - var Ka = (a, b) => { - L = 0; - a = Ne(a, b); - 0 < L ? (va = a) : Ce(a); - }, - v, - Nf = [], - Of = 0, - O = (a) => (-9007199254740992 > a || 9007199254740992 < a ? NaN : Number(a)); - function $a(a) { - a >>>= 0; - var b = new Pf(a); - 0 == (u(), w)[(b.Qc + 12) >>> 0] && (Qf(b, !0), Of--); - Rf(b, !1); - Nf.push(b); - return Me(a); - } - var Sf = 0, - ab = () => { - I(0, 0); - var a = Nf.pop(); - Je(a.Xc); - Sf = 0; - }; - function Qf(a, b) { - b = b ? 1 : 0; - (u(), w)[(a.Qc + 12) >>> 0] = b; - } - function Rf(a, b) { - b = b ? 1 : 0; - (u(), w)[(a.Qc + 13) >>> 0] = b; - } - class Pf { - constructor(a) { - this.Xc = a; - this.Qc = a - 24; - } - } - var Tf = (a) => { - var b = Sf; - if (!b) return (Ge(0), 0); - var c = new Pf(b); - (u(), B)[((c.Qc + 16) >>> 2) >>> 0] = b; - var d = (u(), B)[((c.Qc + 4) >>> 2) >>> 0]; - if (!d) return (Ge(0), b); - for (var e of a) { - if (0 === e || e === d) break; - if (Le(e, d, c.Qc + 16)) return (Ge(e), b); - } - Ge(d); - return b; - }; - function bb() { - return Tf([]); - } - function cb(a) { - return Tf([a >>> 0]); - } - function db(a, b, c, d) { - return Tf([a >>> 0, b >>> 0, c >>> 0, d >>> 0]); - } - var eb = () => { - var a = Nf.pop(); - a || Ta("no exception to throw"); - var b = a.Xc; - 0 == (u(), w)[(a.Qc + 13) >>> 0] && (Nf.push(a), Rf(a, !0), Qf(a, !1), Of++); - Ke(b); - Sf = b; - throw Sf; - }; - function fb(a, b, c) { - a >>>= 0; - var d = new Pf(a); - b >>>= 0; - c >>>= 0; - (u(), B)[((d.Qc + 16) >>> 2) >>> 0] = 0; - (u(), B)[((d.Qc + 4) >>> 2) >>> 0] = b; - (u(), B)[((d.Qc + 8) >>> 2) >>> 0] = c; - Ke(a); - Sf = a; - Of++; - throw Sf; - } - var gb = () => Of; - function Uf(a, b, c, d) { - return n ? M(2, 1, a, b, c, d) : hb(a, b, c, d); - } - function hb(a, b, c, d) { - a >>>= 0; - b >>>= 0; - c >>>= 0; - d >>>= 0; - if (!globalThis.SharedArrayBuffer) return 6; - var e = []; - if (n && 0 === e.length) return Uf(a, b, c, d); - a = { ge: c, Nc: a, Wc: d, Yc: e }; - return n ? ((a.Oc = "spawnThread"), postMessage(a, e), 0) : If(a); - } - function ib(a) { - Sf ||= a >>> 0; - throw Sf; - } - var Vf = globalThis.TextDecoder && new TextDecoder(), - Wf = (a, b, c, d) => { - c = b + c; - if (d) return c; - for (; a[b] && !(b >= c); ) ++b; - return b; - }, - Xf = (a, b = 0, c, d) => { - b >>>= 0; - c = Wf(a, b, c, d); - if (16 < c - b && a.buffer && Vf) - return Vf.decode(a.buffer instanceof ArrayBuffer ? a.subarray(b, c) : a.slice(b, c)); - for (d = ""; b < c; ) { - var e = a[b++]; - if (e & 128) { - var f = a[b++] & 63; - if (192 == (e & 224)) d += String.fromCharCode(((e & 31) << 6) | f); - else { - var h = a[b++] & 63; - e = - 224 == (e & 240) - ? ((e & 15) << 12) | (f << 6) | h - : ((e & 7) << 18) | (f << 12) | (h << 6) | (a[b++] & 63); - 65536 > e - ? (d += String.fromCharCode(e)) - : ((e -= 65536), (d += String.fromCharCode(55296 | (e >> 10), 56320 | (e & 1023)))); - } - } else d += String.fromCharCode(e); - } - return d; - }, - Yf = (a, b, c) => ((a >>>= 0) ? Xf((u(), x), a, b, c) : ""); - function jb(a, b, c) { - return n ? M(3, 1, a, b, c) : 0; - } - function kb(a, b) { - if (n) return M(4, 1, a, b); - } - function lb(a, b) { - if (n) return M(5, 1, a, b); - } - function mb(a, b, c) { - if (n) return M(6, 1, a, b, c); - } - function nb(a, b, c) { - return n ? M(7, 1, a, b, c) : 0; - } - function ob(a, b) { - if (n) return M(8, 1, a, b); - } - function pb(a, b, c) { - if (n) return M(9, 1, a, b, c); - } - function qb(a, b, c, d) { - if (n) return M(10, 1, a, b, c, d); - } - function rb(a, b, c, d) { - if (n) return M(11, 1, a, b, c, d); - } - function sb(a, b, c, d) { - if (n) return M(12, 1, a, b, c, d); - } - function tb(a) { - if (n) return M(13, 1, a); - } - function ub(a, b) { - if (n) return M(14, 1, a, b); - } - function vb(a, b, c) { - if (n) return M(15, 1, a, b, c); - } - var wb = () => Ta(""), - P = (a) => { - a >>>= 0; - for (var b = ""; ; ) { - var c = (u(), x)[a++ >>> 0]; - if (!c) return b; - b += String.fromCharCode(c); - } - }, - Zf = {}, - $f = {}, - ag = {}, - bg = class extends Error { - constructor(a) { - super(a); - this.name = "BindingError"; - } - }; - function cg(a, b, c = {}) { - var d = b.name; - if (!a) throw new bg(`type "${d}" must have a positive integer typeid pointer`); - if ($f.hasOwnProperty(a)) { - if (c.ee) return; - throw new bg(`Cannot register type '${d}' twice`); - } - $f[a] = b; - delete ag[a]; - Zf.hasOwnProperty(a) && ((b = Zf[a]), delete Zf[a], b.forEach((e) => e())); - } - function Q(a, b, c = {}) { - return cg(a, b, c); - } - var dg = (a, b, c) => { - switch (b) { - case 1: - return c ? (d) => (u(), w)[d >>> 0] : (d) => (u(), x)[d >>> 0]; - case 2: - return c ? (d) => (u(), Na)[(d >>> 1) >>> 0] : (d) => (u(), Oa)[(d >>> 1) >>> 0]; - case 4: - return c ? (d) => (u(), A)[(d >>> 2) >>> 0] : (d) => (u(), B)[(d >>> 2) >>> 0]; - case 8: - return c ? (d) => (u(), F)[(d >>> 3) >>> 0] : (d) => (u(), Qa)[(d >>> 3) >>> 0]; - default: - throw new TypeError(`invalid integer width (${b}): ${a}`); - } - }; - function xb(a, b, c, d, e) { - a >>>= 0; - c >>>= 0; - b = P(b >>> 0); - d = 0n === d; - let f = (h) => h; - if (d) { - const h = 8 * c; - f = (k) => BigInt.asUintN(h, k); - e = f(e); - } - Q(a, { - name: b, - Mc: f, - Sc: (h, k) => { - "number" == typeof k && (k = BigInt(k)); - return k; - }, - Rc: dg(b, c, !d), - Tc: null, - }); - } - function zb(a, b, c, d) { - a >>>= 0; - b = P(b >>> 0); - Q(a, { - name: b, - Mc: function (e) { - return !!e; - }, - Sc: function (e, f) { - return f ? c : d; - }, - Rc: function (e) { - return this.Mc((u(), x)[e >>> 0]); - }, - Tc: null, - }); - } - var eg = [], - fg = [0, 1, , 1, null, 1, !0, 1, !1, 1]; - function Qb(a) { - a >>>= 0; - 9 < a && 0 === --fg[a + 1] && ((fg[a] = void 0), eg.push(a)); - } - var R = (a) => { - if (!a) throw new bg(`Cannot use deleted val. handle = ${a}`); - return fg[a]; - }, - S = (a) => { - switch (a) { - case void 0: - return 2; - case null: - return 4; - case !0: - return 6; - case !1: - return 8; - default: - const b = eg.pop() || fg.length; - fg[b] = a; - fg[b + 1] = 1; - return b; - } - }; - function gg(a) { - return this.Mc((u(), B)[(a >>> 2) >>> 0]); - } - var hg = { - name: "emscripten::val", - Mc: (a) => { - var b = R(a); - Qb(a); - return b; - }, - Sc: (a, b) => S(b), - Rc: gg, - Tc: null, - }; - function Ab(a) { - return Q(a >>> 0, hg); - } - var ig = (a, b) => { - switch (b) { - case 4: - return function (c) { - return this.Mc((u(), Pa)[(c >>> 2) >>> 0]); - }; - case 8: - return function (c) { - return this.Mc((u(), E)[(c >>> 3) >>> 0]); - }; - default: - throw new TypeError(`invalid float width (${b}): ${a}`); - } - }; - function Cb(a, b, c) { - a >>>= 0; - c >>>= 0; - b = P(b >>> 0); - Q(a, { name: b, Mc: (d) => d, Sc: (d, e) => e, Rc: ig(b, c), Tc: null }); - } - function Db(a, b, c, d, e) { - a >>>= 0; - c >>>= 0; - b = P(b >>> 0); - let f = (k) => k; - if (0 === d) { - var h = 32 - 8 * c; - f = (k) => (k << h) >>> h; - e = f(e); - } - Q(a, { name: b, Mc: f, Sc: (k, m) => m, Rc: dg(b, c, 0 !== d), Tc: null }); - } - function Eb(a, b, c) { - function d(f) { - var h = (u(), B)[(f >>> 2) >>> 0]; - f = (u(), B)[((f + 4) >>> 2) >>> 0]; - return new e((u(), w).buffer, f, h); - } - a >>>= 0; - var e = [ - Int8Array, - Uint8Array, - Int16Array, - Uint16Array, - Int32Array, - Uint32Array, - Float32Array, - Float64Array, - BigInt64Array, - BigUint64Array, - ][b]; - c = P(c >>> 0); - Q(a, { name: c, Mc: d, Rc: d }, { ee: !0 }); - } - var T = (a, b, c) => { - var d = (u(), x); - b >>>= 0; - if (0 < c) { - var e = b; - c = b + c - 1; - for (var f = 0; f < a.length; ++f) { - var h = a.codePointAt(f); - if (127 >= h) { - if (b >= c) break; - d[b++ >>> 0] = h; - } else if (2047 >= h) { - if (b + 1 >= c) break; - d[b++ >>> 0] = 192 | (h >> 6); - d[b++ >>> 0] = 128 | (h & 63); - } else if (65535 >= h) { - if (b + 2 >= c) break; - d[b++ >>> 0] = 224 | (h >> 12); - d[b++ >>> 0] = 128 | ((h >> 6) & 63); - d[b++ >>> 0] = 128 | (h & 63); - } else { - if (b + 3 >= c) break; - d[b++ >>> 0] = 240 | (h >> 18); - d[b++ >>> 0] = 128 | ((h >> 12) & 63); - d[b++ >>> 0] = 128 | ((h >> 6) & 63); - d[b++ >>> 0] = 128 | (h & 63); - f++; - } - } - d[b >>> 0] = 0; - a = b - e; - } else a = 0; - return a; - }, - U = (a) => { - for (var b = 0, c = 0; c < a.length; ++c) { - var d = a.charCodeAt(c); - 127 >= d - ? b++ - : 2047 >= d - ? (b += 2) - : 55296 <= d && 57343 >= d - ? ((b += 4), ++c) - : (b += 3); - } - return b; - }; - function Fb(a, b) { - a >>>= 0; - b = P(b >>> 0); - Q(a, { - name: b, - Mc(c) { - var d = (u(), B)[(c >>> 2) >>> 0]; - d = Yf(c + 4, d, !0); - H(c); - return d; - }, - Sc(c, d) { - d instanceof ArrayBuffer && (d = new Uint8Array(d)); - var e = "string" == typeof d; - if (!(e || (ArrayBuffer.isView(d) && 1 == d.BYTES_PER_ELEMENT))) - throw new bg("Cannot pass non-string to std::string"); - var f = e ? U(d) : d.length; - var h = he(4 + f + 1), - k = h + 4; - (u(), B)[(h >>> 2) >>> 0] = f; - e ? T(d, k, f + 1) : (u(), x).set(d, k >>> 0); - null !== c && c.push(H, h); - return h; - }, - Rc: gg, - Tc(c) { - H(c); - }, - }); - } - var jg = globalThis.TextDecoder ? new TextDecoder("utf-16le") : void 0, - kg = (a, b, c) => { - a >>>= 1; - b = Wf((u(), Oa), a, b / 2, c); - if (16 < b - a && jg) return jg.decode((u(), Oa).slice(a, b)); - for (c = ""; a < b; ++a) { - var d = (u(), Oa)[a >>> 0]; - c += String.fromCharCode(d); - } - return c; - }, - lg = (a, b, c) => { - c ??= 2147483647; - if (2 > c) return 0; - c -= 2; - var d = b; - c = c < 2 * a.length ? c / 2 : a.length; - for (var e = 0; e < c; ++e) { - var f = a.charCodeAt(e); - (u(), Na)[(b >>> 1) >>> 0] = f; - b += 2; - } - (u(), Na)[(b >>> 1) >>> 0] = 0; - return b - d; - }, - mg = (a) => 2 * a.length, - ng = (a, b, c) => { - var d = ""; - a >>>= 2; - for (var e = 0; !(e >= b / 4); e++) { - var f = (u(), B)[(a + e) >>> 0]; - if (!f && !c) break; - d += String.fromCodePoint(f); - } - return d; - }, - og = (a, b, c) => { - b >>>= 0; - c ??= 2147483647; - if (4 > c) return 0; - var d = b; - c = d + c - 4; - for (var e = 0; e < a.length; ++e) { - var f = a.codePointAt(e); - 65535 < f && e++; - (u(), A)[(b >>> 2) >>> 0] = f; - b += 4; - if (b + 4 > c) break; - } - (u(), A)[(b >>> 2) >>> 0] = 0; - return b - d; - }, - pg = (a) => { - for (var b = 0, c = 0; c < a.length; ++c) (65535 < a.codePointAt(c) && c++, (b += 4)); - return b; - }; - function Gb(a, b, c) { - a >>>= 0; - b >>>= 0; - c >>>= 0; - c = P(c); - if (2 === b) { - var d = kg; - var e = lg; - var f = mg; - } else ((d = ng), (e = og), (f = pg)); - Q(a, { - name: c, - Mc: (h) => { - var k = (u(), B)[(h >>> 2) >>> 0]; - k = d(h + 4, k * b, !0); - H(h); - return k; - }, - Sc: (h, k) => { - if ("string" != typeof k) throw new bg(`Cannot pass non-string to C++ string type ${c}`); - var m = f(k), - p = he(4 + m + b); - (u(), B)[(p >>> 2) >>> 0] = m / b; - e(k, p + 4, m + b); - null !== h && h.push(H, p); - return p; - }, - Rc: gg, - Tc(h) { - H(h); - }, - }); - } - function Hb(a, b) { - a >>>= 0; - b = P(b >>> 0); - Q(a, { fe: !0, name: b, Mc: () => {}, Sc: () => {} }); - } - function Ib(a) { - Ga(a >>> 0, !ba, 1, !aa, 131072, !1); - Ha(); - } - var N = (a) => { - if (!ua) - try { - if ((a(), !(0 < L))) - try { - n ? ge() && Ce(va) : Mc(va); - } catch (b) { - b instanceof yf || "unwind" == b || ha(1, b); - } - } catch (b) { - b instanceof yf || "unwind" == b || ha(1, b); - } - }, - qg = - !Atomics.waitAsync || - (globalThis.navigator?.userAgent && - 91 > Number((navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) || [])[2])); - function Ia(a) { - a >>>= 0; - qg || - (Atomics.waitAsync((u(), A), a >>> 2, a).value.then(La), - (a += 128), - Atomics.store((u(), A), a >>> 2, 1)); - } - var La = () => - N(() => { - var a = ge(); - a && (Ia(a), Ee()); - }); - function Jb(a, b) { - a >>>= 0; - a == b >>> 0 - ? setTimeout(La) - : n - ? postMessage({ Vc: a, Oc: "checkMailbox" }) - : (a = Hf[a]) && a.postMessage({ Oc: "checkMailbox" }); - } - var rg = []; - function Kb(a, b, c, d, e) { - b >>>= 0; - e >>>= 0; - rg.length = 0; - c = e >>> 3; - for (d = (e + d) >>> 3; c < d; ) { - var f; - (u(), F)[c++ >>> 0] ? (f = (u(), F)[c++ >>> 0]) : (f = (u(), E)[c++ >>> 0]); - rg.push(f); - } - return (b ? sg[b] : tg[a])(...rg); - } - var Lb = () => { - L = 0; - }; - function Mb(a) { - a >>>= 0; - n ? postMessage({ Oc: "cleanupThread", ie: a }) : Mf(Hf[a]); - } - function Nb(a) { - l && Hf[a >>> 0].ref(); - } - var ug = (a) => { - try { - a(); - } catch (b) { - Ta(b); - } - }; - function be(a) { - var b = (...c) => { - vg.push(a); - try { - return a(...c); - } finally { - ua || - (vg.pop(), - r && - 1 === wg && - 0 === vg.length && - ((wg = 0), (L += 1), ug(vf), "undefined" != typeof Fibers && Fibers.De())); - } - }; - xg.set(a, b); - return b; - } - var wg = 0, - r = null, - yg = 0, - vg = [], - zg = new Map(), - Ag = new Map(), - xg = new Map(), - Bg = 0, - Cg = null, - Dg = []; - function da() { - return new Promise((a, b) => { - Cg = { resolve: a, reject: b }; - }); - } - function Eg() { - var a = he(65548), - b = a + 12; - (u(), B)[(a >>> 2) >>> 0] = b; - (u(), B)[((a + 4) >>> 2) >>> 0] = b + 65536; - b = vg[0]; - if (!zg.has(b)) { - var c = Bg++; - zg.set(b, c); - Ag.set(c, b); - } - b = zg.get(b); - (u(), A)[((a + 8) >>> 2) >>> 0] = b; - return a; - } - function Fg() { - var a = (u(), A)[((r + 8) >>> 2) >>> 0]; - a = Ag.get(a); - a = xg.get(a); - --L; - return a(); - } - function Gg(a) { - if (!ua) { - if (0 === wg) { - var b = !1, - c = !1; - a((d = 0) => { - if (!ua && ((yg = d), (b = !0), c)) { - wg = 2; - ug(() => wf(r)); - "undefined" != typeof MainLoop && MainLoop.Xd && MainLoop.resume(); - d = !1; - try { - var e = Fg(); - } catch (k) { - ((e = k), (d = !0)); - } - var f = !1; - if (!r) { - var h = Cg; - h && ((Cg = null), (d ? h.reject : h.resolve)(e), (f = !0)); - } - if (d && !f) throw e; - } - }); - c = !0; - b || - ((wg = 1), - (r = Eg()), - "undefined" != typeof MainLoop && MainLoop.Xd && MainLoop.pause(), - ug(() => uf(r))); - } else - 2 === wg ? ((wg = 0), ug(xf), H(r), (r = null), Dg.forEach(N)) : Ta(`invalid state: ${wg}`); - return yg; - } - } - var Hg = (a) => - Gg((b) => { - a().then(b); - }); - function Ob(a) { - a >>>= 0; - return Hg(async () => { - var b = await R(a); - return S(b); - }); - } - var Ig = [], - Jg = (a) => { - var b = Ig.length; - Ig.push(a); - return b; - }, - Kg = (a, b) => { - for (var c = Array(a), d = 0; d < a; ++d) { - var e = d, - f = (u(), B)[((b + 4 * d) >>> 2) >>> 0], - h = $f[f]; - if (void 0 === h) - throw ( - (a = `parameter ${d}`), - (f = ee(f)), - (b = P(f)), - H(f), - new bg(`${a} has unknown type ${b}`) - ); - c[e] = h; - } - return c; - }, - Lg = (a, b, c) => { - var d = []; - a = a(d, c); - d.length && ((u(), B)[(b >>> 2) >>> 0] = S(d)); - return a; - }, - Mg = {}, - Ng = (a) => { - var b = Mg[a]; - return void 0 === b ? P(a) : b; - }; - function Pb(a, b, c) { - var [d, ...e] = Kg(a, b >>> 0); - b = d.Sc.bind(d); - var f = e.map((m) => m.Rc.bind(m)); - a--; - var h = { toValue: R }; - a = f.map((m, p) => { - var C = `argFromPtr${p}`; - h[C] = m; - return `${C}(args${p ? "+" + 8 * p : ""})`; - }); - switch (c) { - case 0: - var k = "toValue(handle)"; - break; - case 2: - k = "new (toValue(handle))"; - break; - case 3: - k = ""; - break; - case 1: - ((h.getStringOrSymbol = Ng), (k = "toValue(handle)[getStringOrSymbol(methodName)]")); - } - k += `(${a})`; - d.fe || - ((h.toReturnWire = b), - (h.emval_returnValue = Lg), - (k = `return emval_returnValue(toReturnWire, destructorsRef, ${k})`)); - k = `return function (handle, methodName, destructorsRef, args) {\n ${k}\n }`; - c = new Function(Object.keys(h), k)(...Object.values(h)); - k = `methodCaller<(${e.map((m) => m.name)}) => ${d.name}>`; - return Jg(Object.defineProperty(c, "name", { value: k })); - } - function Rb(a, b) { - b >>>= 0; - a = R(a >>> 0); - b = R(b); - return a == b; - } - function Sb(a) { - a >>>= 0; - if (!a) return S(globalThis); - a = Ng(a); - return S(globalThis[a]); - } - function Tb(a) { - a = Ng(a >>> 0); - return S(g[a]); - } - function Ub(a, b) { - b >>>= 0; - a = R(a >>> 0); - b = R(b); - return S(a[b]); - } - function Vb(a) { - a >>>= 0; - 9 < a && (fg[a + 1] += 1); - } - function Wb(a, b, c, d, e) { - return Ig[a >>> 0](b >>> 0, c >>> 0, d >>> 0, e >>> 0); - } - function Xb(a, b, c, d, e) { - return Wb(a >>> 0, b >>> 0, c >>> 0, d >>> 0, e >>> 0); - } - function Yb() { - return S([]); - } - function Zb(a) { - a = R(a >>> 0); - for (var b = Array(a.length), c = 0; c < a.length; c++) b[c] = a[c]; - return S(b); - } - function $b(a) { - return S(Ng(a >>> 0)); - } - function ac() { - return S({}); - } - function bc(a) { - a >>>= 0; - for (var b = R(a); b.length; ) { - var c = b.pop(); - b.pop()(c); - } - Qb(a); - } - function cc(a, b, c) { - b >>>= 0; - c >>>= 0; - a = R(a >>> 0); - b = R(b); - c = R(c); - a[b] = c; - } - function dc(a, b) { - a = O(a); - b >>>= 0; - a = new Date(1e3 * a); - (u(), A)[(b >>> 2) >>> 0] = a.getUTCSeconds(); - (u(), A)[((b + 4) >>> 2) >>> 0] = a.getUTCMinutes(); - (u(), A)[((b + 8) >>> 2) >>> 0] = a.getUTCHours(); - (u(), A)[((b + 12) >>> 2) >>> 0] = a.getUTCDate(); - (u(), A)[((b + 16) >>> 2) >>> 0] = a.getUTCMonth(); - (u(), A)[((b + 20) >>> 2) >>> 0] = a.getUTCFullYear() - 1900; - (u(), A)[((b + 24) >>> 2) >>> 0] = a.getUTCDay(); - a = ((a.getTime() - Date.UTC(a.getUTCFullYear(), 0, 1, 0, 0, 0, 0)) / 864e5) | 0; - (u(), A)[((b + 28) >>> 2) >>> 0] = a; - } - var Og = (a) => 0 === a % 4 && (0 !== a % 100 || 0 === a % 400), - Pg = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335], - Qg = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; - function ec(a, b) { - a = O(a); - b >>>= 0; - a = new Date(1e3 * a); - (u(), A)[(b >>> 2) >>> 0] = a.getSeconds(); - (u(), A)[((b + 4) >>> 2) >>> 0] = a.getMinutes(); - (u(), A)[((b + 8) >>> 2) >>> 0] = a.getHours(); - (u(), A)[((b + 12) >>> 2) >>> 0] = a.getDate(); - (u(), A)[((b + 16) >>> 2) >>> 0] = a.getMonth(); - (u(), A)[((b + 20) >>> 2) >>> 0] = a.getFullYear() - 1900; - (u(), A)[((b + 24) >>> 2) >>> 0] = a.getDay(); - var c = ((Og(a.getFullYear()) ? Pg : Qg)[a.getMonth()] + a.getDate() - 1) | 0; - (u(), A)[((b + 28) >>> 2) >>> 0] = c; - (u(), A)[((b + 36) >>> 2) >>> 0] = -(60 * a.getTimezoneOffset()); - c = new Date(a.getFullYear(), 6, 1).getTimezoneOffset(); - var d = new Date(a.getFullYear(), 0, 1).getTimezoneOffset(); - a = (c != d && a.getTimezoneOffset() == Math.min(d, c)) | 0; - (u(), A)[((b + 32) >>> 2) >>> 0] = a; - } - function fc(a) { - a >>>= 0; - var b = new Date( - (u(), A)[((a + 20) >>> 2) >>> 0] + 1900, - (u(), A)[((a + 16) >>> 2) >>> 0], - (u(), A)[((a + 12) >>> 2) >>> 0], - (u(), A)[((a + 8) >>> 2) >>> 0], - (u(), A)[((a + 4) >>> 2) >>> 0], - (u(), A)[(a >>> 2) >>> 0], - 0, - ), - c = (u(), A)[((a + 32) >>> 2) >>> 0], - d = b.getTimezoneOffset(), - e = new Date(b.getFullYear(), 6, 1).getTimezoneOffset(), - f = new Date(b.getFullYear(), 0, 1).getTimezoneOffset(), - h = Math.min(f, e); - 0 > c - ? ((u(), A)[((a + 32) >>> 2) >>> 0] = Number(e != f && h == d)) - : 0 < c != (h == d) && - ((e = Math.max(f, e)), b.setTime(b.getTime() + 6e4 * ((0 < c ? h : e) - d))); - (u(), A)[((a + 24) >>> 2) >>> 0] = b.getDay(); - c = ((Og(b.getFullYear()) ? Pg : Qg)[b.getMonth()] + b.getDate() - 1) | 0; - (u(), A)[((a + 28) >>> 2) >>> 0] = c; - (u(), A)[(a >>> 2) >>> 0] = b.getSeconds(); - (u(), A)[((a + 4) >>> 2) >>> 0] = b.getMinutes(); - (u(), A)[((a + 8) >>> 2) >>> 0] = b.getHours(); - (u(), A)[((a + 12) >>> 2) >>> 0] = b.getDate(); - (u(), A)[((a + 16) >>> 2) >>> 0] = b.getMonth(); - (u(), A)[((a + 20) >>> 2) >>> 0] = b.getYear(); - a = b.getTime(); - return BigInt(isNaN(a) ? -1 : a / 1e3); - } - function gc(a, b, c, d, e, f, h) { - return n ? M(16, 1, a, b, c, d, e, f, h) : -52; - } - function hc(a, b, c, d, e, f) { - if (n) return M(17, 1, a, b, c, d, e, f); - } - var Rg = {}, - sc = () => performance.timeOrigin + performance.now(); - function ic(a, b) { - if (n) return M(18, 1, a, b); - Rg[a] && (clearTimeout(Rg[a].id), delete Rg[a]); - if (!b) return 0; - var c = setTimeout(() => { - delete Rg[a]; - N(() => De(a, performance.timeOrigin + performance.now())); - }, b); - Rg[a] = { id: c, Ce: b }; - return 0; - } - function jc(a, b, c, d) { - a >>>= 0; - b >>>= 0; - c >>>= 0; - d >>>= 0; - var e = new Date().getFullYear(), - f = new Date(e, 0, 1).getTimezoneOffset(); - e = new Date(e, 6, 1).getTimezoneOffset(); - var h = Math.max(f, e); - (u(), B)[(a >>> 2) >>> 0] = 60 * h; - (u(), A)[(b >>> 2) >>> 0] = Number(f != e); - b = (k) => { - var m = Math.abs(k); - return `UTC${0 <= k ? "-" : "+"}${String(Math.floor(m / 60)).padStart(2, "0")}${String(m % 60).padStart(2, "0")}`; - }; - a = b(f); - b = b(e); - e < f ? (T(a, c, 17), T(b, d, 17)) : (T(a, d, 17), T(b, c, 17)); - } - var oc = () => Date.now(), - Sg = 1; - function kc(a, b, c) { - c >>>= 0; - if (!(0 <= a && 3 >= a)) return 28; - if (0 === a) a = Date.now(); - else if (Sg) a = performance.timeOrigin + performance.now(); - else return 52; - a = Math.round(1e6 * a); - (u(), F)[(c >>> 3) >>> 0] = BigInt(a); - return 0; - } - var Tg = [], - Ug = (a, b) => { - Tg.length = 0; - for (var c; (c = (u(), x)[a++ >>> 0]); ) { - var d = 105 != c; - d &= 112 != c; - b += d && b % 8 ? 4 : 0; - Tg.push( - 112 == c - ? (u(), B)[(b >>> 2) >>> 0] - : 106 == c - ? (u(), F)[(b >>> 3) >>> 0] - : 105 == c - ? (u(), A)[(b >>> 2) >>> 0] - : (u(), E)[(b >>> 3) >>> 0], - ); - b += d ? 8 : 4; - } - return Tg; - }; - function lc(a, b, c) { - a >>>= 0; - b = Ug(b >>> 0, c >>> 0); - return sg[a](...b); - } - function mc(a, b, c) { - a >>>= 0; - b = Ug(b >>> 0, c >>> 0); - return sg[a](...b); - } - var nc = () => {}; - function pc(a, b) { - return t(Yf(a >>> 0, b >>> 0)); - } - var qc = () => { - L += 1; - throw "unwind"; - }; - function rc() { - return 4294901760; - } - var tc = () => 1, - uc = () => (l ? require("os").cpus().length : navigator.hardwareConcurrency); - function vc(a) { - a >>>= 0; - var b = (u(), x).length; - if (a <= b || 4294901760 < a) return !1; - for (var c = 1; 4 >= c; c *= 2) { - var d = b * (1 + 0.2 / c); - d = Math.min(d, a + 100663296); - a: { - d = - ((Math.min(4294901760, 65536 * Math.ceil(Math.max(a, d) / 65536)) - - v.buffer.byteLength + - 65535) / - 65536) | - 0; - try { - v.grow(d); - wa(); - var e = 1; - break a; - } catch (f) {} - e = void 0; - } - if (e) return !0; - } - return !1; - } - var V = (a) => { - var b = U(a) + 1, - c = Ie(b); - T(a, c, b); - return c; - }, - Vg = (a, b) => { - (u(), B)[(a >>> 2) >>> 0] = b; - var c = (u(), B)[(a >>> 2) >>> 0]; - (u(), B)[((a + 4) >>> 2) >>> 0] = (b - c) / 4294967296; - }, - Wg = (a) => (u(), B)[(a >>> 2) >>> 0] + 4294967296 * (u(), A)[((a + 4) >>> 2) >>> 0], - W = [], - Xg = (a, b) => { - W[a >>> 0] = b; - }, - X = [], - Yg = [], - Zg = (a, b) => { - Yg[a] = new Promise((c) => b.finally(() => c(a))); - }, - Y = (a) => { - if (a) return W[a >>> 0]; - }, - $g = (a, b = 0) => { - "unmapped" === a.mapState || Ta(); - b = qe(b); - W[b >>> 0] = a; - return b; - }, - ah = (a, b = 0) => { - var c = se(b); - b = re(b, c); - W[c >>> 0] = a.queue; - W[b >>> 0] = a; - return b; - }, - bh = (a, b) => { - for (a = (u(), B)[(a >>> 2) >>> 0]; a; a = (u(), B)[(a >>> 2) >>> 0]) { - var c = (u(), A)[((a + 4) >>> 2) >>> 0]; - b[c](a); - } - }, - ch = (a, b, c) => { - (u(), B)[(a >>> 2) >>> 0] = b; - (u(), B)[((a + 4) >>> 2) >>> 0] = c; - }, - dh = (a) => { - var b = (u(), B)[(a >>> 2) >>> 0]; - a = (u(), B)[((a + 4) >>> 2) >>> 0]; - return Yf(b, a); - }, - Z = (a) => { - var b = (u(), B)[(a >>> 2) >>> 0]; - a = (u(), B)[((a + 4) >>> 2) >>> 0]; - if (b) return Yf(b, a); - if (0 === a) return ""; - }, - eh = (a) => { - var b = Z(a + 4); - var c = (c = (u(), B)[((a + 12) >>> 2) >>> 0]) ? Y(c) : "auto"; - if ((a += 16)) { - var d = Y((u(), B)[((a + 4) >>> 2) >>> 0]); - var e = (u(), B)[((a + 16) >>> 2) >>> 0]; - var f = (u(), B)[((a + 20) >>> 2) >>> 0]; - if (e) { - for (var h = {}, k = 0; k < e; ++k) { - var m = f + 24 * k, - p = dh(m + 4); - h[p] = (u(), E)[((m + 16) >>> 3) >>> 0]; - } - e = h; - } else e = void 0; - a = { module: d, constants: e, entryPoint: Z(a + 8) }; - } else a = void 0; - return { label: b, layout: c, compute: a }; - }, - fh = (a, b) => { - function c(d, e) { - d = a[d]; - (u(), B)[((b + e) >>> 2) >>> 0] = d; - } - c("maxTextureDimension1D", 4); - c("maxTextureDimension2D", 8); - c("maxTextureDimension3D", 12); - c("maxTextureArrayLayers", 16); - c("maxBindGroups", 20); - c("maxBindGroupsPlusVertexBuffers", 24); - c("maxBindingsPerBindGroup", 28); - c("maxDynamicUniformBuffersPerPipelineLayout", 32); - c("maxDynamicStorageBuffersPerPipelineLayout", 36); - c("maxSampledTexturesPerShaderStage", 40); - c("maxSamplersPerShaderStage", 44); - c("maxStorageBuffersPerShaderStage", 48); - c("maxStorageTexturesPerShaderStage", 52); - c("maxUniformBuffersPerShaderStage", 56); - c("minUniformBufferOffsetAlignment", 80); - c("minStorageBufferOffsetAlignment", 84); - Vg(b + 64, a.maxUniformBufferBindingSize); - Vg(b + 72, a.maxStorageBufferBindingSize); - c("maxVertexBuffers", 88); - Vg(b + 96, a.maxBufferSize); - c("maxVertexAttributes", 104); - c("maxVertexBufferArrayStride", 108); - c("maxInterStageShaderVariables", 112); - c("maxColorAttachments", 116); - c("maxColorAttachmentBytesPerSample", 120); - c("maxComputeWorkgroupStorageSize", 124); - c("maxComputeInvocationsPerWorkgroup", 128); - c("maxComputeWorkgroupSizeX", 132); - c("maxComputeWorkgroupSizeY", 136); - c("maxComputeWorkgroupSizeZ", 140); - c("maxComputeWorkgroupsPerDimension", 144); - void 0 !== a.Ae && c("maxImmediateSize", 148); - }, - gh = [, "validation", "out-of-memory", "internal"], - hh = [, "compatibility", "core"], - ih = { - 1: "core-features-and-limits", - 2: "depth-clip-control", - 3: "depth32float-stencil8", - 4: "texture-compression-bc", - 5: "texture-compression-bc-sliced-3d", - 6: "texture-compression-etc2", - 7: "texture-compression-astc", - 8: "texture-compression-astc-sliced-3d", - 9: "timestamp-query", - 10: "indirect-first-instance", - 11: "shader-f16", - 12: "rg11b10ufloat-renderable", - 13: "bgra8unorm-storage", - 14: "float32-filterable", - 15: "float32-blendable", - 16: "clip-distances", - 17: "dual-source-blending", - 18: "subgroups", - 19: "texture-formats-tier1", - 20: "texture-formats-tier2", - 21: "primitive-index", - 22: "texture-component-swizzle", - 327692: "chromium-experimental-unorm16-texture-formats", - 327729: "chromium-experimental-multi-draw-indirect", - }, - jh = [, "low-power", "high-performance"], - kh = [, "occlusion", "timestamp"], - lh = { undefined: 1, unknown: 1, destroyed: 2 }; - function wc(a, b, c, d, e, f) { - b = O(b); - c = O(c); - d >>>= 0; - e >>>= 0; - f >>>= 0; - var h = Y(a >>> 0); - a = {}; - if (f) { - var k = (u(), B)[((f + 12) >>> 2) >>> 0]; - if (k) { - var m = (u(), B)[((f + 16) >>> 2) >>> 0]; - a.requiredFeatures = Array.from( - (u(), B).subarray((m >>> 2) >>> 0, ((m + 4 * k) >>> 2) >>> 0), - (q) => ih[q], - ); - } - var p = (u(), B)[((f + 20) >>> 2) >>> 0]; - if (p) { - var C = {}; - function q(z, D, za = !1) { - D = p + D; - D = (u(), B)[(D >>> 2) >>> 0]; - 4294967295 == D || (za && 0 == D) || (C[z] = D); - } - function y(z, D) { - D = p + D; - var za = (u(), B)[(D >>> 2) >>> 0], - yb = (u(), B)[((D + 4) >>> 2) >>> 0]; - if (4294967295 != za || 4294967295 != yb) C[z] = Wg(D); - } - q("maxTextureDimension1D", 4); - q("maxTextureDimension2D", 8); - q("maxTextureDimension3D", 12); - q("maxTextureArrayLayers", 16); - q("maxBindGroups", 20); - q("maxBindGroupsPlusVertexBuffers", 24); - q("maxDynamicUniformBuffersPerPipelineLayout", 32); - q("maxDynamicStorageBuffersPerPipelineLayout", 36); - q("maxSampledTexturesPerShaderStage", 40); - q("maxSamplersPerShaderStage", 44); - q("maxStorageBuffersPerShaderStage", 48); - q("maxStorageTexturesPerShaderStage", 52); - q("maxUniformBuffersPerShaderStage", 56); - q("minUniformBufferOffsetAlignment", 80); - q("minStorageBufferOffsetAlignment", 84); - y("maxUniformBufferBindingSize", 64); - y("maxStorageBufferBindingSize", 72); - q("maxVertexBuffers", 88); - y("maxBufferSize", 96); - q("maxVertexAttributes", 104); - q("maxVertexBufferArrayStride", 108); - q("maxInterStageShaderVariables", 112); - q("maxColorAttachments", 116); - q("maxColorAttachmentBytesPerSample", 120); - q("maxComputeWorkgroupStorageSize", 124); - q("maxComputeInvocationsPerWorkgroup", 128); - q("maxComputeWorkgroupSizeX", 132); - q("maxComputeWorkgroupSizeY", 136); - q("maxComputeWorkgroupSizeZ", 140); - q("maxComputeWorkgroupsPerDimension", 144); - q("maxImmediateSize", 148, !0); - a.requiredLimits = C; - } - if ((k = (u(), B)[((f + 24) >>> 2) >>> 0])) ((k = { label: Z(k + 4) }), (a.defaultQueue = k)); - a.label = Z(f + 4); - } - L += 1; - Zg( - b, - h.requestDevice(a).then( - (q) => { - --L; - N(() => { - W[e >>> 0] = q.queue; - W[d >>> 0] = q; - L += 1; - Zg( - c, - q.lost.then((y) => { - N(() => { - q.onuncapturederror = () => {}; - var z = K(), - D = V(y.message); - ue(c, lh[y.reason], D); - J(z); - }); - --L; - }), - ); - q.onuncapturederror = (y) => { - var z = 5; - y.error instanceof GPUValidationError - ? (z = 2) - : y.error instanceof GPUOutOfMemoryError - ? (z = 3) - : y.error instanceof GPUInternalError && (z = 4); - var D = K(); - y = V(y.error.message); - ze(d, z, y); - J(D); - }; - "adapterInfo" in q || (q.adapterInfo = h.info); - ye(b, 1, d, 0); - }); - }, - (q) => { - --L; - N(() => { - var y = K(), - z = V(q.message); - ye(b, 3, d, z); - c && ue(c, 4, z); - J(y); - }); - }, - ), - ); - } - function xc(a) { - a >>>= 0; - var b = Y(a), - c = X[a]; - if (c) { - for (var d = 0; d < c.length; ++d) c[d](); - delete X[a]; - } - b.destroy(); - } - function yc(a, b, c) { - a >>>= 0; - c >>>= 0; - var d = Y(a); - 4294967295 == c && (c = void 0); - try { - var e = d.getMappedRange(b >>> 0, c); - } catch (h) { - return 0; - } - var f = Fe(16, e.byteLength); - (u(), x).set(new Uint8Array(e), f >>> 0); - X[a].push(() => H(f)); - return f; - } - function zc(a, b, c) { - a >>>= 0; - c >>>= 0; - var d = Y(a); - 4294967295 == c && (c = void 0); - try { - var e = d.getMappedRange(b >>> 0, c); - } catch (h) { - return 0; - } - var f = Fe(16, e.byteLength); - (u(), x).fill(0, f, e.byteLength); - X[a].push(() => { - new Uint8Array(e).set((u(), x).subarray(f >>> 0, (f + e.byteLength) >>> 0)); - H(f); - }); - return f; - } - function Ac(a, b, c, d, e) { - a >>>= 0; - b = O(b); - c = O(c); - e >>>= 0; - var f = Y(a); - X[a] = []; - 4294967295 == e && (e = void 0); - L += 1; - Zg( - b, - f.mapAsync(c, d >>> 0, e).then( - () => { - --L; - N(() => { - ve(b, 1, 0); - }); - }, - (h) => { - --L; - N(() => { - K(); - var k = V(h.message); - ve(b, "AbortError" === h.name ? 4 : "OperationError" === h.name ? 3 : 0, k); - delete X[a]; - }); - }, - ), - ); - } - function Bc(a) { - a >>>= 0; - var b = Y(a), - c = X[a]; - if (c) { - for (var d = 0; d < c.length; ++d) c[d](); - delete X[a]; - b.unmap(); - } - } - function Cc(a) { - delete W[a >>> 0]; - } - function Dc(a, b, c) { - a >>>= 0; - b >>>= 0; - c >>>= 0; - var d = !!(u(), B)[((b + 32) >>> 2) >>> 0]; - b = { - label: Z(b + 4), - usage: (u(), B)[((b + 16) >>> 2) >>> 0], - size: Wg(b + 24), - mappedAtCreation: d, - }; - a = Y(a); - try { - var e = a.createBuffer(b); - } catch (f) { - return !1; - } - W[c >>> 0] = e; - d && (X[c] = []); - return !0; - } - function Ec(a, b, c, d) { - a >>>= 0; - b = O(b); - d >>>= 0; - c = eh(c >>> 0); - a = Y(a); - L += 1; - Zg( - b, - a.createComputePipelineAsync(c).then( - (e) => { - --L; - N(() => { - W[d >>> 0] = e; - te(b, 1, d, 0); - }); - }, - (e) => { - --L; - N(() => { - var f = K(), - h = V(e.message); - te(b, "validation" === e.reason ? 3 : "internal" === e.reason ? 4 : 0, d, h); - J(f); - }); - }, - ), - ); - } - function Fc(a, b, c) { - a >>>= 0; - b >>>= 0; - c >>>= 0; - var d = (u(), B)[(b >>> 2) >>> 0], - e = (u(), A)[((d + 4) >>> 2) >>> 0]; - b = { label: Z(b + 4), code: "" }; - switch (e) { - case 2: - b.code = dh(d + 8); - } - a = Y(a).createShaderModule(b); - W[c >>> 0] = a; - } - var Gc = (a) => { - a = Y(a); - a.onuncapturederror = null; - a.destroy(); - }; - function Hc(a, b) { - b = O(b); - a = Y(a >>> 0); - L += 1; - Zg( - b, - a.popErrorScope().then( - (c) => { - --L; - N(() => { - var d = 5; - c - ? c instanceof GPUValidationError - ? (d = 2) - : c instanceof GPUOutOfMemoryError - ? (d = 3) - : c instanceof GPUInternalError && (d = 4) - : (d = 1); - var e = K(), - f = c ? V(c.message) : 0; - we(b, 1, d, f); - J(e); - }); - }, - (c) => { - --L; - N(() => { - var d = K(), - e = V(c.message); - we(b, 1, 5, e); - J(d); - }); - }, - ), - ); - } - function Ic(a, b, c, d) { - b = O(b); - c >>>= 0; - d >>>= 0; - if (c) { - var e = { - featureLevel: hh[(u(), A)[((c + 4) >>> 2) >>> 0]], - powerPreference: jh[(u(), A)[((c + 8) >>> 2) >>> 0]], - forceFallbackAdapter: !!(u(), B)[((c + 12) >>> 2) >>> 0], - }; - a = (u(), B)[(c >>> 2) >>> 0]; - 0 !== a && (u(), (e.Fe = !!(u(), B)[((a + 8) >>> 2) >>> 0])); - } - "gpu" in navigator - ? ((L += 1), - Zg( - b, - navigator.gpu.requestAdapter(e).then( - (f) => { - --L; - N(() => { - if (f) ((W[d >>> 0] = f), xe(b, 1, d, 0)); - else { - var h = K(), - k = V("WebGPU not available on this browser (requestAdapter returned null)"); - xe(b, 3, d, k); - J(h); - } - }); - }, - (f) => { - --L; - N(() => { - var h = K(), - k = V(f.message); - xe(b, 4, d, k); - J(h); - }); - }, - ), - )) - : ((e = K()), - (a = V("WebGPU not available on this browser (navigator.gpu is not available)")), - xe(b, 3, d, a), - J(e)); - } - function Jc(a, b, c) { - a >>>= 0; - b >>>= 0; - c >>>= 0; - return Hg(async () => { - var d = []; - if (c) { - var e = (u(), A)[(c >>> 2) >>> 0]; - d.length = b + 1; - d[b] = new Promise((k) => setTimeout(k, e, 0)); - } else d.length = b; - for (var f = 0; f < b; ++f) { - var h = Wg(a + 8 * f); - if (!(h in Yg)) return h; - d[f] = Yg[h]; - } - d = await Promise.race(d); - delete Yg[d]; - return d; - }); - } - var mh = {}, - oh = () => { - if (!nh) { - var a = { - USER: "web_user", - LOGNAME: "web_user", - PATH: "/", - PWD: "/", - HOME: "/home/web_user", - LANG: (globalThis.navigator?.language ?? "C").replace("-", "_") + ".UTF-8", - _: fa || "./this.program", - }, - b; - for (b in mh) void 0 === mh[b] ? delete a[b] : (a[b] = mh[b]); - var c = []; - for (b in a) c.push(`${b}=${a[b]}`); - nh = c; - } - return nh; - }, - nh; - function Kc(a, b) { - if (n) return M(19, 1, a, b); - a >>>= 0; - b >>>= 0; - var c = 0, - d = 0, - e; - for (e of oh()) { - var f = b + c; - (u(), B)[((a + d) >>> 2) >>> 0] = f; - c += T(e, f, Infinity) + 1; - d += 4; - } - return 0; - } - function Lc(a, b) { - if (n) return M(20, 1, a, b); - a >>>= 0; - b >>>= 0; - var c = oh(); - (u(), B)[(a >>> 2) >>> 0] = c.length; - a = 0; - for (var d of c) a += U(d) + 1; - (u(), B)[(b >>> 2) >>> 0] = a; - return 0; - } - function Nc(a) { - return n ? M(21, 1, a) : 52; - } - function Oc(a, b, c, d) { - return n ? M(22, 1, a, b, c, d) : 52; - } - function Pc(a, b, c, d) { - return n ? M(23, 1, a, b, c, d) : 70; - } - var ph = [null, [], []]; - function Qc(a, b, c, d) { - if (n) return M(24, 1, a, b, c, d); - b >>>= 0; - c >>>= 0; - d >>>= 0; - for (var e = 0, f = 0; f < c; f++) { - var h = (u(), B)[(b >>> 2) >>> 0], - k = (u(), B)[((b + 4) >>> 2) >>> 0]; - b += 8; - for (var m = 0; m < k; m++) { - var p = a, - C = (u(), x)[(h + m) >>> 0], - q = ph[p]; - 0 === C || 10 === C ? ((1 === p ? ra : t)(Xf(q)), (q.length = 0)) : q.push(C); - } - e += k; - } - (u(), B)[(d >>> 2) >>> 0] = e; - return 0; - } - function Cd(a) { - return a >>> 0; - } - function Ed(a, b) { - fh(Y(a >>> 0).limits, b >>> 0); - return 1; - } - function Fd(a, b) { - return Y(a >>> 0).features.has(ih[b]); - } - function Gd(a) { - return BigInt(Y(a >>> 0).size); - } - function Hd(a) { - return BigInt(Y(a >>> 0).usage); - } - function Id(a, b) { - a >>>= 0; - b >>>= 0; - if (b) { - var c = Z(b + 4); - b = (u(), B)[((b + 12) >>> 2) >>> 0]; - b = - 0 !== b - ? { - querySet: Y((u(), B)[((b + 4) >>> 2) >>> 0]), - beginningOfPassWriteIndex: (u(), B)[((b + 8) >>> 2) >>> 0], - endOfPassWriteIndex: (u(), B)[((b + 12) >>> 2) >>> 0], - } - : void 0; - c = { label: c, timestampWrites: b }; - } - b = Y(a); - a = oe(0); - c = b.beginComputePass(c); - W[a >>> 0] = c; - return a; - } - function Jd(a, b, c, d, e, f) { - c = O(c); - e = O(e); - f = O(f); - Y(a >>> 0).copyBufferToBuffer(Y(b >>> 0), c, Y(d >>> 0), e, f); - } - function Kd(a) { - var b = Y(a >>> 0); - a = me(0); - b = b.finish(); - W[a >>> 0] = b; - return a; - } - function Ld(a, b, c, d, e, f) { - f = O(f); - Y(a >>> 0).resolveQuerySet(Y(b >>> 0), c, d, Y(e >>> 0), f); - } - function Md(a, b, c, d) { - Y(a >>> 0).dispatchWorkgroups(b, c, d); - } - function Nd(a, b, c) { - c = O(c); - Y(a >>> 0).dispatchWorkgroupsIndirect(Y(b >>> 0), c); - } - function Od(a) { - Y(a >>> 0).end(); - } - function Pd(a, b, c, d, e) { - d >>>= 0; - e >>>= 0; - a = Y(a >>> 0); - c = Y(c >>> 0); - 0 == d ? a.setBindGroup(b, c) : a.setBindGroup(b, c, (u(), B), e >>> 2, d); - } - function Qd(a, b) { - Y(a >>> 0).setPipeline(Y(b >>> 0)); - } - function Rd(a, b, c) { - Y(a >>> 0).Ee(Y(b >>> 0), c); - } - function Sd(a, b) { - var c = Y(a >>> 0); - a = le(0); - b = c.getBindGroupLayout(b); - W[a >>> 0] = b; - return a; - } - function Td(a, b) { - function c(e) { - var f = (u(), B)[((e + 8) >>> 2) >>> 0], - h = (u(), B)[((e + 32) >>> 2) >>> 0], - k = (u(), B)[((e + 36) >>> 2) >>> 0], - m = 0; - bh(e, { - 327681: (p) => { - m = (u(), B)[((p + 8) >>> 2) >>> 0]; - }, - }); - f - ? ((h = Wg(e + 24)), - -1 == h && (h = void 0), - (f = { buffer: Y(f), offset: Wg(e + 16), size: h })) - : (f = Y(h || k || m)); - return { binding: (u(), B)[((e + 4) >>> 2) >>> 0], resource: f }; - } - a >>>= 0; - b >>>= 0; - b = { - label: Z(b + 4), - layout: Y((u(), B)[((b + 12) >>> 2) >>> 0]), - entries: (function (e, f) { - for (var h = [], k = 0; k < e; ++k) h.push(c(f + 40 * k)); - return h; - })((u(), B)[((b + 16) >>> 2) >>> 0], (u(), B)[((b + 20) >>> 2) >>> 0]), - }; - a = Y(a); - var d = ke(0); - Xg(d, a.createBindGroup(b)); - return d; - } - function Ud(a, b) { - a >>>= 0; - b >>>= 0; - var c; - b && (c = { label: Z(b + 4) }); - b = Y(a); - a = ne(0); - c = b.createCommandEncoder(c); - W[a >>> 0] = c; - return a; - } - function Vd(a, b) { - a >>>= 0; - b >>>= 0; - b = { type: kh[(u(), A)[((b + 12) >>> 2) >>> 0]], count: (u(), B)[((b + 16) >>> 2) >>> 0] }; - var c = Y(a); - a = pe(0); - b = c.createQuerySet(b); - W[a >>> 0] = b; - return a; - } - function Wd(a, b) { - a = Y(a >>> 0).adapterInfo; - b >>>= 0; - (u(), B)[((b + 52) >>> 2) >>> 0] = a.subgroupMinSize; - (u(), B)[((b + 56) >>> 2) >>> 0] = a.subgroupMaxSize; - var c = a.vendor + a.architecture + a.device + a.description; - var d = U(c) + 1, - e = he(d); - e && T(c, e, d); - c = e; - d = U(a.vendor); - ch(b + 4, c, d); - c += d; - d = U(a.architecture); - ch(b + 12, c, d); - c += d; - d = U(a.device); - ch(b + 20, c, d); - ch(b + 28, c + d, U(a.description)); - (u(), A)[((b + 36) >>> 2) >>> 0] = 2; - a = a.isFallbackAdapter ? 3 : 4; - (u(), A)[((b + 40) >>> 2) >>> 0] = a; - (u(), B)[((b + 44) >>> 2) >>> 0] = 0; - (u(), B)[((b + 48) >>> 2) >>> 0] = 0; - return 1; - } - var qh = { - "core-features-and-limits": 1, - "depth-clip-control": 2, - "depth32float-stencil8": 3, - "texture-compression-bc": 4, - "texture-compression-bc-sliced-3d": 5, - "texture-compression-etc2": 6, - "texture-compression-astc": 7, - "texture-compression-astc-sliced-3d": 8, - "timestamp-query": 9, - "indirect-first-instance": 10, - "shader-f16": 11, - "rg11b10ufloat-renderable": 12, - "bgra8unorm-storage": 13, - "float32-filterable": 14, - "float32-blendable": 15, - "clip-distances": 16, - "dual-source-blending": 17, - subgroups: 18, - "texture-formats-tier1": 19, - "texture-formats-tier2": 20, - "primitive-index": 21, - "texture-component-swizzle": 22, - "chromium-experimental-unorm16-texture-formats": 327692, - "chromium-experimental-multi-draw-indirect": 327729, - }; - function Xd(a, b) { - b >>>= 0; - var c = Y(a >>> 0); - a = he(4 * c.features.size); - var d = 0, - e = 0; - for (const f of c.features) - ((c = qh[f]), 0 <= c && (((u(), A)[((a + d) >>> 2) >>> 0] = c), (d += 4), e++)); - (u(), B)[((b + 4) >>> 2) >>> 0] = a; - (u(), B)[(b >>> 2) >>> 0] = e; - } - function Yd(a, b) { - fh(Y(a >>> 0).limits, b >>> 0); - return 1; - } - function Zd(a, b) { - Y(a >>> 0).pushErrorScope(gh[b]); - } - function $d(a, b, c) { - b >>>= 0; - c >>>= 0; - a = Y(a >>> 0); - b = Array.from((u(), A).subarray((c >>> 2) >>> 0, ((c + 4 * b) >>> 2) >>> 0), (d) => Y(d)); - a.submit(b); - } - function ae(a, b, c, d, e) { - c = O(c); - d >>>= 0; - e >>>= 0; - a = Y(a >>> 0); - b = Y(b >>> 0); - d = (u(), x).subarray(d >>> 0, (d + e) >>> 0); - a.writeBuffer(b, c, d, 0, e); - } - n || Kf(); - n || ((v = new WebAssembly.Memory({ initial: 256, maximum: 65536, shared: !0 })), wa()); - g.wasmBinary && (sa = g.wasmBinary); - g.stackSave = () => K(); - g.stackRestore = (a) => J(a); - g.stackAlloc = (a) => Ie(a); - g.setValue = function (a, b, c = "i8") { - c.endsWith("*") && (c = "*"); - switch (c) { - case "i1": - (u(), w)[a >>> 0] = b; - break; - case "i8": - (u(), w)[a >>> 0] = b; - break; - case "i16": - (u(), Na)[(a >>> 1) >>> 0] = b; - break; - case "i32": - (u(), A)[(a >>> 2) >>> 0] = b; - break; - case "i64": - (u(), F)[(a >>> 3) >>> 0] = BigInt(b); - break; - case "float": - (u(), Pa)[(a >>> 2) >>> 0] = b; - break; - case "double": - (u(), E)[(a >>> 3) >>> 0] = b; - break; - case "*": - (u(), B)[(a >>> 2) >>> 0] = b; - break; - default: - Ta(`invalid type for setValue: ${c}`); - } - }; - g.getValue = function (a, b = "i8") { - b.endsWith("*") && (b = "*"); - switch (b) { - case "i1": - return (u(), w)[a >>> 0]; - case "i8": - return (u(), w)[a >>> 0]; - case "i16": - return (u(), Na)[(a >>> 1) >>> 0]; - case "i32": - return (u(), A)[(a >>> 2) >>> 0]; - case "i64": - return (u(), F)[(a >>> 3) >>> 0]; - case "float": - return (u(), Pa)[(a >>> 2) >>> 0]; - case "double": - return (u(), E)[(a >>> 3) >>> 0]; - case "*": - return (u(), B)[(a >>> 2) >>> 0]; - default: - Ta(`invalid type for getValue: ${b}`); - } - }; - g.UTF8ToString = Yf; - g.stringToUTF8 = T; - g.lengthBytesUTF8 = U; - var tg = [ - Dd, - Jf, - Uf, - jb, - kb, - lb, - mb, - nb, - ob, - pb, - qb, - rb, - sb, - tb, - ub, - vb, - gc, - hc, - ic, - Kc, - Lc, - Nc, - Oc, - Pc, - Qc, - ], - sg = { - 937076: (a, b, c, d, e) => { - if ("undefined" == typeof g || !g.Uc) return 1; - a = Yf(Number(a >>> 0)); - a.startsWith("./") && (a = a.substring(2)); - a = g.Uc.get(a); - if (!a) return 2; - b = Number(b >>> 0); - c = Number(c >>> 0); - d = Number(d >>> 0); - if (b + c > a.byteLength) return 3; - try { - const f = a.subarray(b, b + c); - switch (e) { - case 0: - (u(), x).set(f, d >>> 0); - break; - case 1: - g.ad ? g.ad(d, f) : g.oe(d, f); - break; - default: - return 4; - } - return 0; - } catch { - return 4; - } - }, - 937900: (a, b, c) => { - g.Sd(a, (u(), x).subarray(b >>> 0, (b + c) >>> 0)); - }, - 937964: () => g.me(), - 938006: (a) => { - g.jd(a); - }, - 938043: () => "undefined" !== typeof wasmOffsetConverter, - }, - ee, - Ja, - fe, - ge, - H, - he, - ie, - je, - ke, - le, - me, - ne, - oe, - pe, - qe, - re, - se, - te, - ue, - ve, - we, - xe, - ye, - ze, - Ga, - Ma, - Ae, - Be, - Ce, - De, - Ee, - Fe, - I, - Ge, - He, - J, - Ie, - K, - Je, - Ke, - Le, - Me, - dynCall_vii, - Ne, - dynCall_v, - Oe, - Pe, - Qe, - dynCall_iii, - Re, - Se, - Te, - dynCall_vi, - Ue, - Ve, - We, - Xe, - Ye, - Ze, - $e, - af, - bf, - cf, - df, - ef, - ff, - gf, - hf, - jf, - kf, - lf, - mf, - nf, - of, - pf, - qf, - rf, - sf, - tf, - uf, - vf, - wf, - xf, - Za; - function Yc(a, b, c, d) { - var e = K(); - try { - return Te(a, b, c, d); - } catch (f) { - J(e); - if (f !== f + 0) throw f; - I(1, 0); - } - } - function Xc(a, b, c) { - var d = K(); - try { - return dynCall_iii(a, b, c); - } catch (e) { - J(d); - if (e !== e + 0) throw e; - I(1, 0); - } - } - function nd(a) { - var b = K(); - try { - dynCall_v(a); - } catch (c) { - J(b); - if (c !== c + 0) throw c; - I(1, 0); - } - } - function Wc(a, b) { - var c = K(); - try { - return Ne(a, b); - } catch (d) { - J(c); - if (d !== d + 0) throw d; - I(1, 0); - } - } - function pd(a, b, c) { - var d = K(); - try { - dynCall_vii(a, b, c); - } catch (e) { - J(d); - if (e !== e + 0) throw e; - I(1, 0); - } - } - function od(a, b) { - var c = K(); - try { - dynCall_vi(a, b); - } catch (d) { - J(c); - if (d !== d + 0) throw d; - I(1, 0); - } - } - function bd(a, b, c, d, e, f, h) { - var k = K(); - try { - return Qe(a, b, c, d, e, f, h); - } catch (m) { - J(k); - if (m !== m + 0) throw m; - I(1, 0); - } - } - function td(a, b, c, d, e, f) { - var h = K(); - try { - Oe(a, b, c, d, e, f); - } catch (k) { - J(h); - if (k !== k + 0) throw k; - I(1, 0); - } - } - function rd(a, b, c, d) { - var e = K(); - try { - Se(a, b, c, d); - } catch (f) { - J(e); - if (f !== f + 0) throw f; - I(1, 0); - } - } - function ud(a, b, c, d, e, f, h) { - var k = K(); - try { - Ve(a, b, c, d, e, f, h); - } catch (m) { - J(k); - if (m !== m + 0) throw m; - I(1, 0); - } - } - function Ad(a, b, c, d, e, f, h) { - var k = K(); - try { - We(a, b, c, d, e, f, h); - } catch (m) { - J(k); - if (m !== m + 0) throw m; - I(1, 0); - } - } - function zd(a, b, c, d, e, f, h, k) { - var m = K(); - try { - ef(a, b, c, d, e, f, h, k); - } catch (p) { - J(m); - if (p !== p + 0) throw p; - I(1, 0); - } - } - function xd(a, b, c, d, e, f, h, k, m, p, C, q) { - var y = K(); - try { - Xe(a, b, c, d, e, f, h, k, m, p, C, q); - } catch (z) { - J(y); - if (z !== z + 0) throw z; - I(1, 0); - } - } - function Zc(a, b, c, d, e) { - var f = K(); - try { - return Ue(a, b, c, d, e); - } catch (h) { - J(f); - if (h !== h + 0) throw h; - I(1, 0); - } - } - function sd(a, b, c, d, e) { - var f = K(); - try { - Pe(a, b, c, d, e); - } catch (h) { - J(f); - if (h !== h + 0) throw h; - I(1, 0); - } - } - function vd(a, b, c, d, e, f, h, k) { - var m = K(); - try { - Re(a, b, c, d, e, f, h, k); - } catch (p) { - J(m); - if (p !== p + 0) throw p; - I(1, 0); - } - } - function Vc(a) { - var b = K(); - try { - return ff(a); - } catch (c) { - J(b); - if (c !== c + 0) throw c; - I(1, 0); - } - } - function hd(a, b, c) { - var d = K(); - try { - return gf(a, b, c); - } catch (e) { - J(d); - if (e !== e + 0) throw e; - I(1, 0); - } - } - function kd(a, b) { - var c = K(); - try { - return tf(a, b); - } catch (d) { - J(c); - if (d !== d + 0) throw d; - I(1, 0); - return 0n; - } - } - function Bd(a, b, c, d, e) { - var f = K(); - try { - hf(a, b, c, d, e); - } catch (h) { - J(f); - if (h !== h + 0) throw h; - I(1, 0); - } - } - function jd(a) { - var b = K(); - try { - return Ye(a); - } catch (c) { - J(b); - if (c !== c + 0) throw c; - I(1, 0); - return 0n; - } - } - function ad(a, b, c, d, e, f) { - var h = K(); - try { - return cf(a, b, c, d, e, f); - } catch (k) { - J(h); - if (k !== k + 0) throw k; - I(1, 0); - } - } - function ed(a, b, c, d, e, f) { - var h = K(); - try { - return jf(a, b, c, d, e, f); - } catch (k) { - J(h); - if (k !== k + 0) throw k; - I(1, 0); - } - } - function $c(a, b, c, d, e, f) { - var h = K(); - try { - return kf(a, b, c, d, e, f); - } catch (k) { - J(h); - if (k !== k + 0) throw k; - I(1, 0); - } - } - function cd(a, b, c, d, e, f, h, k) { - var m = K(); - try { - return df(a, b, c, d, e, f, h, k); - } catch (p) { - J(m); - if (p !== p + 0) throw p; - I(1, 0); - } - } - function md(a, b, c, d, e) { - var f = K(); - try { - return lf(a, b, c, d, e); - } catch (h) { - J(f); - if (h !== h + 0) throw h; - I(1, 0); - return 0n; - } - } - function Uc(a, b, c, d) { - var e = K(); - try { - return mf(a, b, c, d); - } catch (f) { - J(e); - if (f !== f + 0) throw f; - I(1, 0); - } - } - function Sc(a, b, c, d) { - var e = K(); - try { - return nf(a, b, c, d); - } catch (f) { - J(e); - if (f !== f + 0) throw f; - I(1, 0); - } - } - function dd(a, b, c, d, e, f, h, k, m, p, C, q) { - var y = K(); - try { - return of(a, b, c, d, e, f, h, k, m, p, C, q); - } catch (z) { - J(y); - if (z !== z + 0) throw z; - I(1, 0); - } - } - function wd(a, b, c, d, e, f, h, k, m, p, C) { - var q = K(); - try { - pf(a, b, c, d, e, f, h, k, m, p, C); - } catch (y) { - J(q); - if (y !== y + 0) throw y; - I(1, 0); - } - } - function yd(a, b, c, d, e, f, h, k, m, p, C, q, y, z, D, za) { - var yb = K(); - try { - qf(a, b, c, d, e, f, h, k, m, p, C, q, y, z, D, za); - } catch (Bb) { - J(yb); - if (Bb !== Bb + 0) throw Bb; - I(1, 0); - } - } - function gd(a, b, c, d) { - var e = K(); - try { - return rf(a, b, c, d); - } catch (f) { - J(e); - if (f !== f + 0) throw f; - I(1, 0); - } - } - function fd(a, b, c, d, e) { - var f = K(); - try { - return sf(a, b, c, d, e); - } catch (h) { - J(f); - if (h !== h + 0) throw h; - I(1, 0); - } - } - function ld(a, b, c) { - var d = K(); - try { - return $e(a, b, c); - } catch (e) { - J(d); - if (e !== e + 0) throw e; - I(1, 0); - return 0n; - } - } - function Tc(a, b, c) { - var d = K(); - try { - return Ze(a, b, c); - } catch (e) { - J(d); - if (e !== e + 0) throw e; - I(1, 0); - } - } - function Rc(a, b, c) { - var d = K(); - try { - return af(a, b, c); - } catch (e) { - J(d); - if (e !== e + 0) throw e; - I(1, 0); - } - } - function qd(a, b, c, d) { - var e = K(); - try { - bf(a, b, c, d); - } catch (f) { - J(e); - if (f !== f + 0) throw f; - I(1, 0); - } - } - function ce() { - var a = G; - a = Object.assign({}, a); - var b = (d) => (e) => d(e) >>> 0, - c = (d) => () => d() >>> 0; - a.$b = b(a.$b); - a.Cc = c(a.Cc); - a.Ec = b(a.Ec); - a.rd = ( - (d) => (e, f) => - d(e, f) >>> 0 - )(a.rd); - a.wd = b(a.wd); - a.xd = c(a.xd); - a.Bd = b(a.Bd); - return a; - } - function Ea() { - if (0 < Bf) Cf = Ea; - else if (n) (xa?.(g), Sa()); - else { - for (var a = Af; 0 < a.length; ) a.shift()(g); - 0 < Bf ? (Cf = Ea) : ((g.calledRun = !0), ua || (Sa(), xa?.(g))); - } - } - var G; - n || ((G = await Da()), Ea()); - g.PTR_SIZE = 4; - g.webgpuInit = (a) => { - const b = new WeakMap(); - let c = 1, - d = void 0, - e = void 0; - g.webgpuRegisterDevice = (k) => { - if (void 0 !== e) throw Error("another WebGPU EP inference session is being created."); - if (k) { - var m = b.get(k); - if (!m) { - m = je(0); - const p = ah(k, m); - m = [c++, m, p]; - b.set(k, m); - } - d = k; - e = m[0]; - return m; - } - d = void 0; - e = 0; - }; - const f = new Map(); - g.webgpuOnCreateSession = (k) => { - if (void 0 !== e) { - var m = e; - e = void 0; - if (k) { - const p = fe(m); - f.set(k, p); - 0 === m && a(d ?? Y(p)); - } - d = void 0; - } - }; - g.webgpuOnReleaseSession = (k) => { - f.delete(k); - }; - const h = Symbol("gpuBufferMetadata"); - g.webgpuRegisterBuffer = (k, m, p) => { - if (p) return ((k[h] = [p, NaN]), p); - if ((p = k[h])) return (p[1]++, p[0]); - m = f.get(m); - if (void 0 === m) throw Error("Invalid session handle passed to webgpuRegisterBuffer"); - m = $g(k, m); - k[h] = [m, 1]; - return m; - }; - g.webgpuUnregisterBuffer = (k) => { - const m = k[h]; - if (!m) throw Error("Buffer is not registered"); - m[1]--; - 0 === m[1] && (ie(m[0]), delete k[h]); - }; - g.webgpuGetBuffer = (k) => Y(k); - g.webgpuCreateDownloader = (k, m, p) => { - p = f.get(p); - if (void 0 === p) throw Error("Invalid session handle passed to webgpuRegisterBuffer"); - const C = Y(p), - q = 16 * Math.ceil(Number(m) / 16); - return async () => { - const y = C.createBuffer({ size: q, usage: 9 }); - try { - const z = C.createCommandEncoder(); - z.copyBufferToBuffer(k, 0, y, 0, q); - C.queue.submit([z.finish()]); - await y.mapAsync(GPUMapMode.READ); - return y.getMappedRange().slice(0, m); - } finally { - y.destroy(); - } - }; - }; - g.ad = (k, m) => { - var p = m.buffer; - const C = m.byteOffset, - q = m.byteLength; - m = 16 * Math.ceil(Number(q) / 16); - k = Y(k); - if (!d) { - var y = fe(e); - d = Y(y); - } - y = d.createBuffer({ mappedAtCreation: !0, size: m, usage: 6 }); - const z = y.getMappedRange(); - new Uint8Array(z).set(new Uint8Array(p, C, q)); - y.unmap(); - p = d.createCommandEncoder(); - p.copyBufferToBuffer(y, 0, k, 0, m); - d.queue.submit([p.finish()]); - y.destroy(); - }; - }; - g.webnnInit = (a) => { - const b = a[0]; - [g.me, g.jd, g.webnnEnsureTensor, g.Sd, g.webnnDownloadTensor, g.le, g.webnnEnableTraceEvent] = - a.slice(1); - g.webnnReleaseTensorId = g.jd; - g.webnnUploadTensor = g.Sd; - g.webnnRegisterMLContext = g.le; - g.webnnOnRunStart = (c) => b.onRunStart(c); - g.webnnOnRunEnd = b.onRunEnd.bind(b); - g.webnnOnReleaseSession = (c) => { - b.onReleaseSession(c); - }; - g.webnnCreateMLTensorDownloader = (c, d) => b.createMLTensorDownloader(c, d); - g.webnnRegisterMLTensor = (c, d, e, f) => b.registerMLTensor(c, d, e, f); - g.webnnCreateMLContext = (c) => b.createMLContext(c); - g.webnnRegisterMLConstant = (c, d, e, f, h, k) => b.registerMLConstant(c, d, e, f, h, g.Uc, k); - g.webnnRegisterGraphInput = b.registerGraphInput.bind(b); - g.webnnIsGraphInput = b.isGraphInput.bind(b); - g.webnnRegisterGraphOutput = b.registerGraphOutput.bind(b); - g.webnnIsGraphOutput = b.isGraphOutput.bind(b); - g.webnnCreateTemporaryTensor = b.createTemporaryTensor.bind(b); - g.webnnIsGraphInputOutputTypeSupported = b.isGraphInputOutputTypeSupported.bind(b); - }; - Ra - ? (moduleRtn = g) - : (moduleRtn = new Promise((a, b) => { - xa = a; - ya = b; - })); - return moduleRtn; -} -export default ortWasmThreaded; -var isPthread = globalThis.self?.name?.startsWith("em-pthread"); -var isNode = globalThis.process?.versions?.node && globalThis.process?.type != "renderer"; -if (isNode) isPthread = (await import("worker_threads")).workerData === "em-pthread"; -isPthread && ortWasmThreaded(); diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.asyncify.wasm b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.asyncify.wasm deleted file mode 100644 index 3b9f7382e..000000000 Binary files a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.asyncify.wasm and /dev/null differ diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.mjs b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.mjs deleted file mode 100644 index ee89ecb4b..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.mjs +++ /dev/null @@ -1,1681 +0,0 @@ -async function ortWasmThreaded(moduleArg = {}) { - var moduleRtn; - var h = moduleArg, - aa = !!globalThis.window, - k = !!globalThis.WorkerGlobalScope, - m = globalThis.process?.versions?.node && "renderer" != globalThis.process?.type, - n = k && self.name?.startsWith("em-pthread"); - if (m) { - const { createRequire: a } = await import("module"); - var require = a(import.meta.url), - ba = require("worker_threads"); - global.Worker = ba.Worker; - n = (k = !ba.ic) && "em-pthread" == ba.workerData; - } - h.mountExternalData = (a, b) => { - a.startsWith("./") && (a = a.substring(2)); - (h.Sb || (h.Sb = new Map())).set(a, b); - }; - h.unmountExternalData = () => { - delete h.Sb; - }; - var SharedArrayBuffer = - globalThis.SharedArrayBuffer ?? - new WebAssembly.Memory({ initial: 0, maximum: 0, kc: !0 }).buffer.constructor, - ca = "./this.program", - da = (a, b) => { - throw b; - }, - ea = import.meta.url, - fa = "", - ha, - ia; - if (m) { - var fs = require("fs"); - ea.startsWith("file:") && - (fa = require("path").dirname(require("url").fileURLToPath(ea)) + "/"); - ia = (a) => { - a = ja(a) ? new URL(a) : a; - return fs.readFileSync(a); - }; - ha = async (a) => { - a = ja(a) ? new URL(a) : a; - return fs.readFileSync(a, void 0); - }; - 1 < process.argv.length && (ca = process.argv[1].replace(/\\/g, "/")); - process.argv.slice(2); - da = (a, b) => { - process.exitCode = a; - throw b; - }; - } else if (aa || k) { - try { - fa = new URL(".", ea).href; - } catch {} - m || - (k && - (ia = (a) => { - var b = new XMLHttpRequest(); - b.open("GET", a, !1); - b.responseType = "arraybuffer"; - b.send(null); - return new Uint8Array(b.response); - }), - (ha = async (a) => { - if (ja(a)) - return new Promise((d, c) => { - var e = new XMLHttpRequest(); - e.open("GET", a, !0); - e.responseType = "arraybuffer"; - e.onload = () => { - 200 == e.status || (0 == e.status && e.response) ? d(e.response) : c(e.status); - }; - e.onerror = c; - e.send(null); - }); - var b = await fetch(a, { credentials: "same-origin" }); - if (b.ok) return b.arrayBuffer(); - throw Error(b.status + " : " + b.url); - })); - } - var ka = console.log.bind(console), - la = console.error.bind(console); - if (m) { - var ma = require("util"), - na = (a) => ("object" == typeof a ? ma.inspect(a) : a); - ka = (...a) => fs.writeSync(1, a.map(na).join(" ") + "\n"); - la = (...a) => fs.writeSync(2, a.map(na).join(" ") + "\n"); - } - var oa = ka, - p = la, - q, - r, - pa = !1, - t, - ja = (a) => a.startsWith("file://"); - function v() { - x.buffer != z.buffer && qa(); - } - var ra, sa; - if (m && n) { - var ta = ba.parentPort; - ta.on("message", (a) => global.onmessage?.({ data: a })); - Object.assign(globalThis, { self: global, postMessage: (a) => ta.postMessage(a) }); - process.on("uncaughtException", (a) => { - postMessage({ Qb: "uncaughtException", error: a }); - process.exit(1); - }); - } - var ua; - if (n) { - var va = !1; - self.onunhandledrejection = (b) => { - throw b.reason || b; - }; - function a(b) { - try { - var d = b.data, - c = d.Qb; - if ("load" === c) { - let e = []; - self.onmessage = (f) => e.push(f); - ua = () => { - postMessage({ Qb: "loaded" }); - for (let f of e) a(f); - self.onmessage = a; - }; - for (const f of d.$b) - if (!h[f] || h[f].proxy) - ((h[f] = (...g) => { - postMessage({ Qb: "callHandler", Zb: f, args: g }); - }), - "print" == f && (oa = h[f]), - "printErr" == f && (p = h[f])); - x = d.ec; - qa(); - r = d.fc; - wa(); - xa(); - } else if ("run" === c) { - ya(d.Pb); - za(d.Pb, 0, 0, 1, 0, 0); - Aa(); - Ba(d.Pb); - va ||= !0; - try { - Ca(d.cc, d.Ub); - } catch (e) { - if ("unwind" != e) throw e; - } - } else - "setimmediate" !== d.target && - ("checkMailbox" === c - ? va && Da() - : c && (p(`worker: received unknown command ${c}`), p(d))); - } catch (e) { - throw (Ea(), e); - } - } - self.onmessage = a; - } - var z, - A, - Fa, - C, - D, - Ga, - G, - H, - Ha = !1; - function qa() { - var a = x.buffer; - h.HEAP8 = z = new Int8Array(a); - Fa = new Int16Array(a); - h.HEAPU8 = A = new Uint8Array(a); - new Uint16Array(a); - h.HEAP32 = C = new Int32Array(a); - h.HEAPU32 = D = new Uint32Array(a); - Ga = new Float32Array(a); - G = new Float64Array(a); - H = new BigInt64Array(a); - new BigUint64Array(a); - } - function Ia() { - Ha = !0; - n ? ua() : I.Ua(); - } - function J(a) { - a = "Aborted(" + a + ")"; - p(a); - pa = !0; - a = new WebAssembly.RuntimeError(a + ". Build with -sASSERTIONS for more info."); - sa?.(a); - throw a; - } - var Ja; - async function Ka(a) { - if (!q) - try { - var b = await ha(a); - return new Uint8Array(b); - } catch {} - if (a == Ja && q) a = new Uint8Array(q); - else if (ia) a = ia(a); - else throw "both async and sync fetching of the wasm failed"; - return a; - } - async function La(a, b) { - try { - var d = await Ka(a); - return await WebAssembly.instantiate(d, b); - } catch (c) { - (p(`failed to asynchronously prepare wasm: ${c}`), J(c)); - } - } - async function Na(a) { - var b = Ja; - if (!q && !ja(b) && !m) - try { - var d = fetch(b, { credentials: "same-origin" }); - return await WebAssembly.instantiateStreaming(d, a); - } catch (c) { - (p(`wasm streaming compile failed: ${c}`), p("falling back to ArrayBuffer instantiation")); - } - return La(b, a); - } - function Oa() { - Pa = { - S: Qa, - f: Ra, - w: Sa, - e: Ta, - k: Ua, - g: Va, - T: Wa, - b: Xa, - G: Ya, - ua: Za, - j: $a, - K: ab, - Ka: bb, - qa: cb, - sa: db, - La: eb, - Ia: fb, - Ba: gb, - Ha: hb, - Z: ib, - ra: jb, - oa: kb, - Ja: lb, - pa: mb, - Qa: nb, - Ea: ob, - ma: pb, - va: qb, - ja: rb, - U: sb, - Da: Ba, - Na: tb, - ya: ub, - za: vb, - Aa: wb, - wa: xb, - xa: yb, - ka: zb, - Sa: Ab, - Pa: Bb, - W: Cb, - V: Db, - Oa: Eb, - F: Fb, - Ma: Gb, - na: Hb, - u: Ib, - H: Jb, - R: Kb, - la: Lb, - da: Mb, - Ta: Nb, - Fa: Ob, - Ga: Pb, - ta: Qb, - L: Rb, - Y: Sb, - Ca: Tb, - X: Ub, - $: Vb, - M: Wb, - aa: Xb, - N: Yb, - v: Zb, - c: $b, - m: ac, - n: bc, - r: cc, - ea: dc, - x: ec, - o: fc, - O: gc, - D: hc, - I: ic, - ba: jc, - ca: kc, - Q: lc, - P: mc, - fa: nc, - z: oc, - E: pc, - d: qc, - q: rc, - i: sc, - _: tc, - l: uc, - p: vc, - s: wc, - t: xc, - y: yc, - ga: zc, - B: Ac, - J: Bc, - C: Cc, - ha: Dc, - ia: Ec, - A: Fc, - h: Gc, - a: x, - Ra: Hc, - }; - return { a: Pa }; - } - async function wa() { - function a(c, e) { - I = c.exports; - I = Ic(); - Jc.push(I.wb); - c = I; - h._OrtInit = c.Va; - h._OrtGetLastError = c.Wa; - h._OrtCreateSessionOptions = c.Xa; - h._OrtAppendExecutionProvider = c.Ya; - h._OrtAddFreeDimensionOverride = c.Za; - h._OrtAddSessionConfigEntry = c._a; - h._OrtReleaseSessionOptions = c.$a; - h._OrtCreateSession = c.ab; - h._OrtReleaseSession = c.bb; - h._OrtGetInputOutputCount = c.cb; - h._OrtGetInputOutputMetadata = c.db; - h._OrtFree = c.eb; - h._OrtCreateTensor = c.fb; - h._OrtGetTensorData = c.gb; - h._OrtReleaseTensor = c.hb; - h._OrtCreateRunOptions = c.ib; - h._OrtAddRunConfigEntry = c.jb; - h._OrtReleaseRunOptions = c.kb; - h._OrtCreateBinding = c.lb; - h._OrtBindInput = c.mb; - h._OrtBindOutput = c.nb; - h._OrtClearBoundOutputs = c.ob; - h._OrtReleaseBinding = c.pb; - h._OrtRunWithBinding = c.qb; - h._OrtRun = c.rb; - h._OrtEndProfiling = c.sb; - Kc = c.tb; - Lc = h._free = c.ub; - Mc = h._malloc = c.vb; - za = c.yb; - Ea = c.zb; - Nc = c.Ab; - Oc = c.Bb; - Pc = c.Cb; - Qc = c.Db; - Rc = c.Eb; - K = c.Fb; - L = c.Gb; - Sc = c.Hb; - M = c.Ib; - Tc = c.Jb; - N = c.Kb; - Uc = c.Lb; - Vc = c.Mb; - Wc = c.Nb; - Xc = c.Ob; - Yc = c.xb; - r = e; - return I; - } - var b = Oa(); - if (h.instantiateWasm) - return new Promise((c) => { - h.instantiateWasm(b, (e, f) => { - c(a(e, f)); - }); - }); - if (n) { - var d = new WebAssembly.Instance(r, Oa()); - return a(d, r); - } - Ja ??= h.locateFile - ? h.locateFile - ? h.locateFile("ort-wasm-simd-threaded.wasm", fa) - : fa + "ort-wasm-simd-threaded.wasm" - : new URL("ort-wasm-simd-threaded.wasm", import.meta.url).href; - return (function (c) { - return a(c.instance, c.module); - })(await Na(b)); - } - class Zc { - name = "ExitStatus"; - constructor(a) { - this.message = `Program terminated with exit(${a})`; - this.status = a; - } - } - var $c = (a) => { - a.terminate(); - a.onmessage = () => {}; - }, - ad = [], - O = 0, - P = null, - dd = (a) => { - 0 == Q.length && (bd(), cd(Q[0])); - var b = Q.pop(); - if (!b) return 6; - R.push(b); - S[a.Pb] = b; - b.Pb = a.Pb; - var d = { Qb: "run", cc: a.bc, Ub: a.Ub, Pb: a.Pb }; - m && b.unref(); - b.postMessage(d, a.Yb); - return 0; - }, - T = 0, - U = (a, b, ...d) => { - var c = 16 * d.length, - e = N(), - f = Tc(c), - g = f >>> 3, - l; - for (l of d) - "bigint" == typeof l - ? (((v(), H)[g++ >>> 0] = 1n), ((v(), H)[g++ >>> 0] = l)) - : (((v(), H)[g++ >>> 0] = 0n), ((v(), G)[g++ >>> 0] = l)); - a = Nc(a, 0, c, f, b); - M(e); - return a; - }; - function Hc(a) { - if (n) return U(0, 1, a); - t = a; - if (!(0 < T)) { - for (var b of R) $c(b); - for (b of Q) $c(b); - Q = []; - R = []; - S = {}; - pa = !0; - } - da(a, new Zc(a)); - } - function ed(a) { - if (n) return U(1, 0, a); - Qb(a); - } - var Qb = (a) => { - t = a; - if (n) throw (ed(a), "unwind"); - Hc(a); - }, - Q = [], - R = [], - Jc = [], - S = {}; - function fd() { - for (var a = h.numThreads - 1; a--; ) bd(); - ad.push(async () => { - var b = gd(); - O++; - await b; - O--; - 0 == O && P && ((b = P), (P = null), b()); - }); - } - var hd = (a) => { - var b = a.Pb; - delete S[b]; - Q.push(a); - R.splice(R.indexOf(a), 1); - a.Pb = 0; - Oc(b); - }; - function Aa() { - Jc.forEach((a) => a()); - } - var cd = (a) => - new Promise((b) => { - a.onmessage = (f) => { - var g = f.data; - f = g.Qb; - if (g.Tb && g.Tb != Kc()) { - var l = S[g.Tb]; - l - ? l.postMessage(g, g.Yb) - : p( - `Internal error! Worker sent a message "${f}" to target pthread ${g.Tb}, but that thread no longer exists!`, - ); - } else if ("checkMailbox" === f) Da(); - else if ("spawnThread" === f) dd(g); - else if ("cleanupThread" === f) - jd(() => { - hd(S[g.dc]); - }); - else if ("loaded" === f) ((a.loaded = !0), m && !a.Pb && a.unref(), b(a)); - else if ("setimmediate" === g.target) a.postMessage(g); - else if ("uncaughtException" === f) a.onerror(g.error); - else if ("callHandler" === f) h[g.Zb](...g.args); - else f && p(`worker sent an unknown command ${f}`); - }; - a.onerror = (f) => { - p(`${"worker sent an error!"} ${f.filename}:${f.lineno}: ${f.message}`); - throw f; - }; - m && (a.on("message", (f) => a.onmessage({ data: f })), a.on("error", (f) => a.onerror(f))); - var d = [], - c = [], - e; - for (e of c) h.propertyIsEnumerable(e) && d.push(e); - a.postMessage({ Qb: "load", $b: d, ec: x, fc: r }); - }); - async function gd() { - if (!n) return Promise.all(Q.map(cd)); - } - function bd() { - var a = new Worker(new URL(import.meta.url), { - type: "module", - workerData: "em-pthread", - name: "em-pthread", - }); - Q.push(a); - } - function ya(a) { - var b = (v(), D)[((a + 52) >>> 2) >>> 0]; - a = (v(), D)[((a + 56) >>> 2) >>> 0]; - Sc(b, b - a); - M(b); - } - var kd = [], - V = (a) => { - var b = kd[a]; - b || (kd[a] = b = Yc.get(a)); - return b; - }, - Ca = (a, b) => { - T = 0; - a = V(a)(b); - 0 < T ? (t = a) : Pc(a); - }, - x, - ld = [], - md = 0; - function Ra(a) { - a >>>= 0; - var b = new nd(a); - 0 == (v(), z)[(b.Rb + 12) >>> 0] && (od(b, !0), md--); - pd(b, !1); - ld.push(b); - return Xc(a); - } - var W = 0, - Sa = () => { - K(0, 0); - var a = ld.pop(); - Uc(a.Vb); - W = 0; - }; - function od(a, b) { - b = b ? 1 : 0; - (v(), z)[(a.Rb + 12) >>> 0] = b; - } - function pd(a, b) { - b = b ? 1 : 0; - (v(), z)[(a.Rb + 13) >>> 0] = b; - } - class nd { - constructor(a) { - this.Vb = a; - this.Rb = a - 24; - } - } - var qd = (a) => { - var b = W; - if (!b) return (L(0), 0); - var d = new nd(b); - (v(), D)[((d.Rb + 16) >>> 2) >>> 0] = b; - var c = (v(), D)[((d.Rb + 4) >>> 2) >>> 0]; - if (!c) return (L(0), b); - for (var e of a) { - if (0 === e || e === c) break; - if (Wc(e, c, d.Rb + 16)) return (L(e), b); - } - L(c); - return b; - }; - function Ta() { - return qd([]); - } - function Ua(a) { - return qd([a >>> 0]); - } - function Va(a, b, d, c) { - return qd([a >>> 0, b >>> 0, d >>> 0, c >>> 0]); - } - var Wa = () => { - var a = ld.pop(); - a || J("no exception to throw"); - var b = a.Vb; - 0 == (v(), z)[(a.Rb + 13) >>> 0] && (ld.push(a), pd(a, !0), od(a, !1), md++); - Vc(b); - W = b; - throw W; - }; - function Xa(a, b, d) { - a >>>= 0; - var c = new nd(a); - b >>>= 0; - d >>>= 0; - (v(), D)[((c.Rb + 16) >>> 2) >>> 0] = 0; - (v(), D)[((c.Rb + 4) >>> 2) >>> 0] = b; - (v(), D)[((c.Rb + 8) >>> 2) >>> 0] = d; - Vc(a); - W = a; - md++; - throw W; - } - var Ya = () => md; - function rd(a, b, d, c) { - return n ? U(2, 1, a, b, d, c) : Za(a, b, d, c); - } - function Za(a, b, d, c) { - a >>>= 0; - b >>>= 0; - d >>>= 0; - c >>>= 0; - if (!globalThis.SharedArrayBuffer) return 6; - var e = []; - if (n && 0 === e.length) return rd(a, b, d, c); - a = { bc: d, Pb: a, Ub: c, Yb: e }; - return n ? ((a.Qb = "spawnThread"), postMessage(a, e), 0) : dd(a); - } - function $a(a) { - W ||= a >>> 0; - throw W; - } - var sd = globalThis.TextDecoder && new TextDecoder(), - td = (a, b = 0, d, c) => { - b >>>= 0; - var e = b; - d = e + d; - if (c) c = d; - else { - for (; a[e] && !(e >= d); ) ++e; - c = e; - } - if (16 < c - b && a.buffer && sd) - return sd.decode(a.buffer instanceof ArrayBuffer ? a.subarray(b, c) : a.slice(b, c)); - for (e = ""; b < c; ) - if (((d = a[b++]), d & 128)) { - var f = a[b++] & 63; - if (192 == (d & 224)) e += String.fromCharCode(((d & 31) << 6) | f); - else { - var g = a[b++] & 63; - d = - 224 == (d & 240) - ? ((d & 15) << 12) | (f << 6) | g - : ((d & 7) << 18) | (f << 12) | (g << 6) | (a[b++] & 63); - 65536 > d - ? (e += String.fromCharCode(d)) - : ((d -= 65536), (e += String.fromCharCode(55296 | (d >> 10), 56320 | (d & 1023)))); - } - } else e += String.fromCharCode(d); - return e; - }, - ud = (a, b, d) => ((a >>>= 0) ? td((v(), A), a, b, d) : ""); - function ab(a, b, d) { - return n ? U(3, 1, a, b, d) : 0; - } - function bb(a, b) { - if (n) return U(4, 1, a, b); - } - function cb(a, b) { - if (n) return U(5, 1, a, b); - } - function db(a, b, d) { - if (n) return U(6, 1, a, b, d); - } - function eb(a, b, d) { - return n ? U(7, 1, a, b, d) : 0; - } - function fb(a, b) { - if (n) return U(8, 1, a, b); - } - function gb(a, b, d) { - if (n) return U(9, 1, a, b, d); - } - function hb(a, b, d, c) { - if (n) return U(10, 1, a, b, d, c); - } - function ib(a, b, d, c) { - if (n) return U(11, 1, a, b, d, c); - } - function jb(a, b, d, c) { - if (n) return U(12, 1, a, b, d, c); - } - function kb(a) { - if (n) return U(13, 1, a); - } - function lb(a, b) { - if (n) return U(14, 1, a, b); - } - function mb(a, b, d) { - if (n) return U(15, 1, a, b, d); - } - var nb = () => J(""); - function ob(a) { - za(a >>> 0, !k, 1, !aa, 131072, !1); - Aa(); - } - var jd = (a) => { - if (!pa) - try { - if ((a(), !(0 < T))) - try { - n ? Kc() && Pc(t) : Qb(t); - } catch (b) { - b instanceof Zc || "unwind" == b || da(1, b); - } - } catch (b) { - b instanceof Zc || "unwind" == b || da(1, b); - } - }, - vd = - !Atomics.waitAsync || - (globalThis.navigator?.userAgent && - 91 > Number((navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) || [])[2])); - function Ba(a) { - a >>>= 0; - vd || - (Atomics.waitAsync((v(), C), a >>> 2, a).value.then(Da), - (a += 128), - Atomics.store((v(), C), a >>> 2, 1)); - } - var Da = () => - jd(() => { - var a = Kc(); - a && (Ba(a), Rc()); - }); - function pb(a, b) { - a >>>= 0; - a == b >>> 0 - ? setTimeout(Da) - : n - ? postMessage({ Tb: a, Qb: "checkMailbox" }) - : (a = S[a]) && a.postMessage({ Qb: "checkMailbox" }); - } - var wd = []; - function qb(a, b, d, c, e) { - b >>>= 0; - e >>>= 0; - wd.length = 0; - d = e >>> 3; - for (c = (e + c) >>> 3; d < c; ) { - var f; - (v(), H)[d++ >>> 0] ? (f = (v(), H)[d++ >>> 0]) : (f = (v(), G)[d++ >>> 0]); - wd.push(f); - } - return (b ? xd[b] : yd[a])(...wd); - } - var rb = () => { - T = 0; - }; - function sb(a) { - a >>>= 0; - n ? postMessage({ Qb: "cleanupThread", dc: a }) : hd(S[a]); - } - function tb(a) { - m && S[a >>> 0].ref(); - } - function ub(a, b) { - a = -9007199254740992 > a || 9007199254740992 < a ? NaN : Number(a); - b >>>= 0; - a = new Date(1e3 * a); - (v(), C)[(b >>> 2) >>> 0] = a.getUTCSeconds(); - (v(), C)[((b + 4) >>> 2) >>> 0] = a.getUTCMinutes(); - (v(), C)[((b + 8) >>> 2) >>> 0] = a.getUTCHours(); - (v(), C)[((b + 12) >>> 2) >>> 0] = a.getUTCDate(); - (v(), C)[((b + 16) >>> 2) >>> 0] = a.getUTCMonth(); - (v(), C)[((b + 20) >>> 2) >>> 0] = a.getUTCFullYear() - 1900; - (v(), C)[((b + 24) >>> 2) >>> 0] = a.getUTCDay(); - a = ((a.getTime() - Date.UTC(a.getUTCFullYear(), 0, 1, 0, 0, 0, 0)) / 864e5) | 0; - (v(), C)[((b + 28) >>> 2) >>> 0] = a; - } - var zd = (a) => 0 === a % 4 && (0 !== a % 100 || 0 === a % 400), - Ad = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335], - Bd = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; - function vb(a, b) { - a = -9007199254740992 > a || 9007199254740992 < a ? NaN : Number(a); - b >>>= 0; - a = new Date(1e3 * a); - (v(), C)[(b >>> 2) >>> 0] = a.getSeconds(); - (v(), C)[((b + 4) >>> 2) >>> 0] = a.getMinutes(); - (v(), C)[((b + 8) >>> 2) >>> 0] = a.getHours(); - (v(), C)[((b + 12) >>> 2) >>> 0] = a.getDate(); - (v(), C)[((b + 16) >>> 2) >>> 0] = a.getMonth(); - (v(), C)[((b + 20) >>> 2) >>> 0] = a.getFullYear() - 1900; - (v(), C)[((b + 24) >>> 2) >>> 0] = a.getDay(); - var d = ((zd(a.getFullYear()) ? Ad : Bd)[a.getMonth()] + a.getDate() - 1) | 0; - (v(), C)[((b + 28) >>> 2) >>> 0] = d; - (v(), C)[((b + 36) >>> 2) >>> 0] = -(60 * a.getTimezoneOffset()); - d = new Date(a.getFullYear(), 6, 1).getTimezoneOffset(); - var c = new Date(a.getFullYear(), 0, 1).getTimezoneOffset(); - a = (d != c && a.getTimezoneOffset() == Math.min(c, d)) | 0; - (v(), C)[((b + 32) >>> 2) >>> 0] = a; - } - function wb(a) { - a >>>= 0; - var b = new Date( - (v(), C)[((a + 20) >>> 2) >>> 0] + 1900, - (v(), C)[((a + 16) >>> 2) >>> 0], - (v(), C)[((a + 12) >>> 2) >>> 0], - (v(), C)[((a + 8) >>> 2) >>> 0], - (v(), C)[((a + 4) >>> 2) >>> 0], - (v(), C)[(a >>> 2) >>> 0], - 0, - ), - d = (v(), C)[((a + 32) >>> 2) >>> 0], - c = b.getTimezoneOffset(), - e = new Date(b.getFullYear(), 6, 1).getTimezoneOffset(), - f = new Date(b.getFullYear(), 0, 1).getTimezoneOffset(), - g = Math.min(f, e); - 0 > d - ? ((v(), C)[((a + 32) >>> 2) >>> 0] = Number(e != f && g == c)) - : 0 < d != (g == c) && - ((e = Math.max(f, e)), b.setTime(b.getTime() + 6e4 * ((0 < d ? g : e) - c))); - (v(), C)[((a + 24) >>> 2) >>> 0] = b.getDay(); - d = ((zd(b.getFullYear()) ? Ad : Bd)[b.getMonth()] + b.getDate() - 1) | 0; - (v(), C)[((a + 28) >>> 2) >>> 0] = d; - (v(), C)[(a >>> 2) >>> 0] = b.getSeconds(); - (v(), C)[((a + 4) >>> 2) >>> 0] = b.getMinutes(); - (v(), C)[((a + 8) >>> 2) >>> 0] = b.getHours(); - (v(), C)[((a + 12) >>> 2) >>> 0] = b.getDate(); - (v(), C)[((a + 16) >>> 2) >>> 0] = b.getMonth(); - (v(), C)[((a + 20) >>> 2) >>> 0] = b.getYear(); - a = b.getTime(); - return BigInt(isNaN(a) ? -1 : a / 1e3); - } - function xb(a, b, d, c, e, f, g) { - return n ? U(16, 1, a, b, d, c, e, f, g) : -52; - } - function yb(a, b, d, c, e, f) { - if (n) return U(17, 1, a, b, d, c, e, f); - } - var X = {}, - Ib = () => performance.timeOrigin + performance.now(); - function zb(a, b) { - if (n) return U(18, 1, a, b); - X[a] && (clearTimeout(X[a].id), delete X[a]); - if (!b) return 0; - var d = setTimeout(() => { - delete X[a]; - jd(() => Qc(a, performance.timeOrigin + performance.now())); - }, b); - X[a] = { id: d, lc: b }; - return 0; - } - var Y = (a, b, d) => { - var c = (v(), A); - b >>>= 0; - if (0 < d) { - var e = b; - d = b + d - 1; - for (var f = 0; f < a.length; ++f) { - var g = a.codePointAt(f); - if (127 >= g) { - if (b >= d) break; - c[b++ >>> 0] = g; - } else if (2047 >= g) { - if (b + 1 >= d) break; - c[b++ >>> 0] = 192 | (g >> 6); - c[b++ >>> 0] = 128 | (g & 63); - } else if (65535 >= g) { - if (b + 2 >= d) break; - c[b++ >>> 0] = 224 | (g >> 12); - c[b++ >>> 0] = 128 | ((g >> 6) & 63); - c[b++ >>> 0] = 128 | (g & 63); - } else { - if (b + 3 >= d) break; - c[b++ >>> 0] = 240 | (g >> 18); - c[b++ >>> 0] = 128 | ((g >> 12) & 63); - c[b++ >>> 0] = 128 | ((g >> 6) & 63); - c[b++ >>> 0] = 128 | (g & 63); - f++; - } - } - c[b >>> 0] = 0; - a = b - e; - } else a = 0; - return a; - }; - function Ab(a, b, d, c) { - a >>>= 0; - b >>>= 0; - d >>>= 0; - c >>>= 0; - var e = new Date().getFullYear(), - f = new Date(e, 0, 1).getTimezoneOffset(); - e = new Date(e, 6, 1).getTimezoneOffset(); - var g = Math.max(f, e); - (v(), D)[(a >>> 2) >>> 0] = 60 * g; - (v(), C)[(b >>> 2) >>> 0] = Number(f != e); - b = (l) => { - var u = Math.abs(l); - return `UTC${0 <= l ? "-" : "+"}${String(Math.floor(u / 60)).padStart(2, "0")}${String(u % 60).padStart(2, "0")}`; - }; - a = b(f); - b = b(e); - e < f ? (Y(a, d, 17), Y(b, c, 17)) : (Y(a, c, 17), Y(b, d, 17)); - } - var Eb = () => Date.now(), - Cd = 1; - function Bb(a, b, d) { - d >>>= 0; - if (!(0 <= a && 3 >= a)) return 28; - if (0 === a) a = Date.now(); - else if (Cd) a = performance.timeOrigin + performance.now(); - else return 52; - a = Math.round(1e6 * a); - (v(), H)[(d >>> 3) >>> 0] = BigInt(a); - return 0; - } - var Dd = []; - function Cb(a, b, d) { - a >>>= 0; - b >>>= 0; - d >>>= 0; - Dd.length = 0; - for (var c; (c = (v(), A)[b++ >>> 0]); ) { - var e = 105 != c; - e &= 112 != c; - d += e && d % 8 ? 4 : 0; - Dd.push( - 112 == c - ? (v(), D)[(d >>> 2) >>> 0] - : 106 == c - ? (v(), H)[(d >>> 3) >>> 0] - : 105 == c - ? (v(), C)[(d >>> 2) >>> 0] - : (v(), G)[(d >>> 3) >>> 0], - ); - d += e ? 8 : 4; - } - return xd[a](...Dd); - } - var Db = () => {}; - function Fb(a, b) { - return p(ud(a >>> 0, b >>> 0)); - } - var Gb = () => { - T += 1; - throw "unwind"; - }; - function Hb() { - return 4294901760; - } - var Jb = () => (m ? require("os").cpus().length : navigator.hardwareConcurrency), - Z = {}, - Ed = (a) => { - for (var b = 0, d = 0; d < a.length; ++d) { - var c = a.charCodeAt(d); - 127 >= c - ? b++ - : 2047 >= c - ? (b += 2) - : 55296 <= c && 57343 >= c - ? ((b += 4), ++d) - : (b += 3); - } - return b; - }, - Fd = (a) => { - var b; - return (b = /\bwasm-function\[\d+\]:(0x[0-9a-f]+)/.exec(a)) - ? +b[1] - : (b = /:(\d+):\d+(?:\)|$)/.exec(a)) - ? 2147483648 | +b[1] - : 0; - }, - Gd = (a) => { - for (var b of a) (a = Fd(b)) && (Z[a] = b); - }; - function Mb() { - var a = Error().stack.toString().split("\n"); - "Error" == a[0] && a.shift(); - Gd(a); - Z.Wb = Fd(a[3]); - Z.ac = a; - return Z.Wb; - } - function Kb(a) { - a = Z[a >>> 0]; - if (!a) return 0; - var b; - if ((b = /^\s+at .*\.wasm\.(.*) \(.*\)$/.exec(a))) a = b[1]; - else if ((b = /^\s+at (.*) \(.*\)$/.exec(a))) a = b[1]; - else if ((b = /^(.+?)@/.exec(a))) a = b[1]; - else return 0; - Lc(Kb.Xb ?? 0); - b = Ed(a) + 1; - var d = Mc(b); - d && Y(a, d, b); - Kb.Xb = d; - return Kb.Xb; - } - function Lb(a) { - a >>>= 0; - var b = (v(), A).length; - if (a <= b || 4294901760 < a) return !1; - for (var d = 1; 4 >= d; d *= 2) { - var c = b * (1 + 0.2 / d); - c = Math.min(c, a + 100663296); - a: { - c = - ((Math.min(4294901760, 65536 * Math.ceil(Math.max(a, c) / 65536)) - - x.buffer.byteLength + - 65535) / - 65536) | - 0; - try { - x.grow(c); - qa(); - var e = 1; - break a; - } catch (f) {} - e = void 0; - } - if (e) return !0; - } - return !1; - } - function Nb(a, b, d) { - a >>>= 0; - b >>>= 0; - if (Z.Wb == a) var c = Z.ac; - else ((c = Error().stack.toString().split("\n")), "Error" == c[0] && c.shift(), Gd(c)); - for (var e = 3; c[e] && Fd(c[e]) != a; ) ++e; - for (a = 0; a < d && c[a + e]; ++a) (v(), C)[((b + 4 * a) >>> 2) >>> 0] = Fd(c[a + e]); - return a; - } - var Hd = {}, - Jd = () => { - if (!Id) { - var a = { - USER: "web_user", - LOGNAME: "web_user", - PATH: "/", - PWD: "/", - HOME: "/home/web_user", - LANG: (globalThis.navigator?.language ?? "C").replace("-", "_") + ".UTF-8", - _: ca || "./this.program", - }, - b; - for (b in Hd) void 0 === Hd[b] ? delete a[b] : (a[b] = Hd[b]); - var d = []; - for (b in a) d.push(`${b}=${a[b]}`); - Id = d; - } - return Id; - }, - Id; - function Ob(a, b) { - if (n) return U(19, 1, a, b); - a >>>= 0; - b >>>= 0; - var d = 0, - c = 0, - e; - for (e of Jd()) { - var f = b + d; - (v(), D)[((a + c) >>> 2) >>> 0] = f; - d += Y(e, f, Infinity) + 1; - c += 4; - } - return 0; - } - function Pb(a, b) { - if (n) return U(20, 1, a, b); - a >>>= 0; - b >>>= 0; - var d = Jd(); - (v(), D)[(a >>> 2) >>> 0] = d.length; - a = 0; - for (var c of d) a += Ed(c) + 1; - (v(), D)[(b >>> 2) >>> 0] = a; - return 0; - } - function Rb(a) { - return n ? U(21, 1, a) : 52; - } - function Sb(a, b, d, c) { - return n ? U(22, 1, a, b, d, c) : 52; - } - function Tb(a, b, d, c) { - return n ? U(23, 1, a, b, d, c) : 70; - } - var Kd = [null, [], []]; - function Ub(a, b, d, c) { - if (n) return U(24, 1, a, b, d, c); - b >>>= 0; - d >>>= 0; - c >>>= 0; - for (var e = 0, f = 0; f < d; f++) { - var g = (v(), D)[(b >>> 2) >>> 0], - l = (v(), D)[((b + 4) >>> 2) >>> 0]; - b += 8; - for (var u = 0; u < l; u++) { - var w = a, - y = (v(), A)[(g + u) >>> 0], - B = Kd[w]; - 0 === y || 10 === y ? ((1 === w ? oa : p)(td(B)), (B.length = 0)) : B.push(y); - } - e += l; - } - (v(), D)[(c >>> 2) >>> 0] = e; - return 0; - } - function Gc(a) { - return a >>> 0; - } - n || fd(); - n || ((x = new WebAssembly.Memory({ initial: 256, maximum: 65536, shared: !0 })), qa()); - h.wasmBinary && (q = h.wasmBinary); - h.stackSave = () => N(); - h.stackRestore = (a) => M(a); - h.stackAlloc = (a) => Tc(a); - h.setValue = function (a, b, d = "i8") { - d.endsWith("*") && (d = "*"); - switch (d) { - case "i1": - (v(), z)[a >>> 0] = b; - break; - case "i8": - (v(), z)[a >>> 0] = b; - break; - case "i16": - (v(), Fa)[(a >>> 1) >>> 0] = b; - break; - case "i32": - (v(), C)[(a >>> 2) >>> 0] = b; - break; - case "i64": - (v(), H)[(a >>> 3) >>> 0] = BigInt(b); - break; - case "float": - (v(), Ga)[(a >>> 2) >>> 0] = b; - break; - case "double": - (v(), G)[(a >>> 3) >>> 0] = b; - break; - case "*": - (v(), D)[(a >>> 2) >>> 0] = b; - break; - default: - J(`invalid type for setValue: ${d}`); - } - }; - h.getValue = function (a, b = "i8") { - b.endsWith("*") && (b = "*"); - switch (b) { - case "i1": - return (v(), z)[a >>> 0]; - case "i8": - return (v(), z)[a >>> 0]; - case "i16": - return (v(), Fa)[(a >>> 1) >>> 0]; - case "i32": - return (v(), C)[(a >>> 2) >>> 0]; - case "i64": - return (v(), H)[(a >>> 3) >>> 0]; - case "float": - return (v(), Ga)[(a >>> 2) >>> 0]; - case "double": - return (v(), G)[(a >>> 3) >>> 0]; - case "*": - return (v(), D)[(a >>> 2) >>> 0]; - default: - J(`invalid type for getValue: ${b}`); - } - }; - h.UTF8ToString = ud; - h.stringToUTF8 = Y; - h.lengthBytesUTF8 = Ed; - var yd = [ - Hc, - ed, - rd, - ab, - bb, - cb, - db, - eb, - fb, - gb, - hb, - ib, - jb, - kb, - lb, - mb, - xb, - yb, - zb, - Ob, - Pb, - Rb, - Sb, - Tb, - Ub, - ], - xd = { - 904364: (a, b, d, c, e) => { - if ("undefined" == typeof h || !h.Sb) return 1; - a = ud(Number(a >>> 0)); - a.startsWith("./") && (a = a.substring(2)); - a = h.Sb.get(a); - if (!a) return 2; - b = Number(b >>> 0); - d = Number(d >>> 0); - c = Number(c >>> 0); - if (b + d > a.byteLength) return 3; - try { - const f = a.subarray(b, b + d); - switch (e) { - case 0: - (v(), A).set(f, c >>> 0); - break; - case 1: - h.hc ? h.hc(c, f) : h.jc(c, f); - break; - default: - return 4; - } - return 0; - } catch { - return 4; - } - }, - 905188: () => "undefined" !== typeof wasmOffsetConverter, - }; - function Qa() { - return "undefined" !== typeof wasmOffsetConverter; - } - var Kc, Lc, Mc, za, Ea, Nc, Oc, Pc, Qc, Rc, K, L, Sc, M, Tc, N, Uc, Vc, Wc, Xc, Yc, Pa; - function bc(a, b, d, c) { - var e = N(); - try { - return V(a)(b, d, c); - } catch (f) { - M(e); - if (f !== f + 0) throw f; - K(1, 0); - } - } - function ac(a, b, d) { - var c = N(); - try { - return V(a)(b, d); - } catch (e) { - M(c); - if (e !== e + 0) throw e; - K(1, 0); - } - } - function qc(a) { - var b = N(); - try { - V(a)(); - } catch (d) { - M(b); - if (d !== d + 0) throw d; - K(1, 0); - } - } - function $b(a, b) { - var d = N(); - try { - return V(a)(b); - } catch (c) { - M(d); - if (c !== c + 0) throw c; - K(1, 0); - } - } - function sc(a, b, d) { - var c = N(); - try { - V(a)(b, d); - } catch (e) { - M(c); - if (e !== e + 0) throw e; - K(1, 0); - } - } - function rc(a, b) { - var d = N(); - try { - V(a)(b); - } catch (c) { - M(d); - if (c !== c + 0) throw c; - K(1, 0); - } - } - function fc(a, b, d, c, e, f, g) { - var l = N(); - try { - return V(a)(b, d, c, e, f, g); - } catch (u) { - M(l); - if (u !== u + 0) throw u; - K(1, 0); - } - } - function wc(a, b, d, c, e, f) { - var g = N(); - try { - V(a)(b, d, c, e, f); - } catch (l) { - M(g); - if (l !== l + 0) throw l; - K(1, 0); - } - } - function uc(a, b, d, c) { - var e = N(); - try { - V(a)(b, d, c); - } catch (f) { - M(e); - if (f !== f + 0) throw f; - K(1, 0); - } - } - function vc(a, b, d, c, e) { - var f = N(); - try { - V(a)(b, d, c, e); - } catch (g) { - M(f); - if (g !== g + 0) throw g; - K(1, 0); - } - } - function xc(a, b, d, c, e, f, g) { - var l = N(); - try { - V(a)(b, d, c, e, f, g); - } catch (u) { - M(l); - if (u !== u + 0) throw u; - K(1, 0); - } - } - function Ec(a, b, d, c, e, f, g) { - var l = N(); - try { - V(a)(b, d, c, e, f, g); - } catch (u) { - M(l); - if (u !== u + 0) throw u; - K(1, 0); - } - } - function Dc(a, b, d, c, e, f, g, l) { - var u = N(); - try { - V(a)(b, d, c, e, f, g, l); - } catch (w) { - M(u); - if (w !== w + 0) throw w; - K(1, 0); - } - } - function cc(a, b, d, c, e) { - var f = N(); - try { - return V(a)(b, d, c, e); - } catch (g) { - M(f); - if (g !== g + 0) throw g; - K(1, 0); - } - } - function yc(a, b, d, c, e, f, g, l) { - var u = N(); - try { - V(a)(b, d, c, e, f, g, l); - } catch (w) { - M(u); - if (w !== w + 0) throw w; - K(1, 0); - } - } - function Bc(a, b, d, c, e, f, g, l, u, w, y, B) { - var E = N(); - try { - V(a)(b, d, c, e, f, g, l, u, w, y, B); - } catch (F) { - M(E); - if (F !== F + 0) throw F; - K(1, 0); - } - } - function ec(a, b, d, c, e, f) { - var g = N(); - try { - return V(a)(b, d, c, e, f); - } catch (l) { - M(g); - if (l !== l + 0) throw l; - K(1, 0); - } - } - function oc(a, b, d) { - var c = N(); - try { - return V(a)(b, d); - } catch (e) { - M(c); - if (e !== e + 0) throw e; - K(1, 0); - return 0n; - } - } - function zc(a, b, d, c, e, f, g, l, u) { - var w = N(); - try { - V(a)(b, d, c, e, f, g, l, u); - } catch (y) { - M(w); - if (y !== y + 0) throw y; - K(1, 0); - } - } - function Zb(a) { - var b = N(); - try { - return V(a)(); - } catch (d) { - M(b); - if (d !== d + 0) throw d; - K(1, 0); - } - } - function lc(a, b, d) { - var c = N(); - try { - return V(a)(b, d); - } catch (e) { - M(c); - if (e !== e + 0) throw e; - K(1, 0); - } - } - function nc(a, b) { - var d = N(); - try { - return V(a)(b); - } catch (c) { - M(d); - if (c !== c + 0) throw c; - K(1, 0); - return 0n; - } - } - function Fc(a, b, d, c, e) { - var f = N(); - try { - V(a)(b, d, c, e); - } catch (g) { - M(f); - if (g !== g + 0) throw g; - K(1, 0); - } - } - function mc(a) { - var b = N(); - try { - return V(a)(); - } catch (d) { - M(b); - if (d !== d + 0) throw d; - K(1, 0); - return 0n; - } - } - function ic(a, b, d, c, e, f) { - var g = N(); - try { - return V(a)(b, d, c, e, f); - } catch (l) { - M(g); - if (l !== l + 0) throw l; - K(1, 0); - } - } - function dc(a, b, d, c, e, f) { - var g = N(); - try { - return V(a)(b, d, c, e, f); - } catch (l) { - M(g); - if (l !== l + 0) throw l; - K(1, 0); - } - } - function gc(a, b, d, c, e, f, g, l) { - var u = N(); - try { - return V(a)(b, d, c, e, f, g, l); - } catch (w) { - M(u); - if (w !== w + 0) throw w; - K(1, 0); - } - } - function pc(a, b, d, c, e) { - var f = N(); - try { - return V(a)(b, d, c, e); - } catch (g) { - M(f); - if (g !== g + 0) throw g; - K(1, 0); - return 0n; - } - } - function Yb(a, b, d, c) { - var e = N(); - try { - return V(a)(b, d, c); - } catch (f) { - M(e); - if (f !== f + 0) throw f; - K(1, 0); - } - } - function Wb(a, b, d, c) { - var e = N(); - try { - return V(a)(b, d, c); - } catch (f) { - M(e); - if (f !== f + 0) throw f; - K(1, 0); - } - } - function hc(a, b, d, c, e, f, g, l, u, w, y, B) { - var E = N(); - try { - return V(a)(b, d, c, e, f, g, l, u, w, y, B); - } catch (F) { - M(E); - if (F !== F + 0) throw F; - K(1, 0); - } - } - function Ac(a, b, d, c, e, f, g, l, u, w, y) { - var B = N(); - try { - V(a)(b, d, c, e, f, g, l, u, w, y); - } catch (E) { - M(B); - if (E !== E + 0) throw E; - K(1, 0); - } - } - function Cc(a, b, d, c, e, f, g, l, u, w, y, B, E, F, Ld, Md) { - var Nd = N(); - try { - V(a)(b, d, c, e, f, g, l, u, w, y, B, E, F, Ld, Md); - } catch (Ma) { - M(Nd); - if (Ma !== Ma + 0) throw Ma; - K(1, 0); - } - } - function kc(a, b, d, c) { - var e = N(); - try { - return V(a)(b, d, c); - } catch (f) { - M(e); - if (f !== f + 0) throw f; - K(1, 0); - } - } - function jc(a, b, d, c, e) { - var f = N(); - try { - return V(a)(b, d, c, e); - } catch (g) { - M(f); - if (g !== g + 0) throw g; - K(1, 0); - } - } - function Xb(a, b, d) { - var c = N(); - try { - return V(a)(b, d); - } catch (e) { - M(c); - if (e !== e + 0) throw e; - K(1, 0); - } - } - function Vb(a, b, d) { - var c = N(); - try { - return V(a)(b, d); - } catch (e) { - M(c); - if (e !== e + 0) throw e; - K(1, 0); - } - } - function tc(a, b, d, c) { - var e = N(); - try { - V(a)(b, d, c); - } catch (f) { - M(e); - if (f !== f + 0) throw f; - K(1, 0); - } - } - function Ic() { - var a = I; - a = Object.assign({}, a); - var b = (c) => () => c() >>> 0, - d = (c) => (e) => c(e) >>> 0; - a.tb = b(a.tb); - a.vb = d(a.vb); - a.Jb = d(a.Jb); - a.Kb = b(a.Kb); - a.Ob = d(a.Ob); - return a; - } - function xa() { - if (0 < O) P = xa; - else if (n) (ra?.(h), Ia()); - else { - for (var a = ad; 0 < a.length; ) a.shift()(h); - 0 < O ? (P = xa) : ((h.calledRun = !0), pa || (Ia(), ra?.(h))); - } - } - var I; - n || ((I = await wa()), xa()); - h.PTR_SIZE = 4; - Ha - ? (moduleRtn = h) - : (moduleRtn = new Promise((a, b) => { - ra = a; - sa = b; - })); - return moduleRtn; -} -export default ortWasmThreaded; -var isPthread = globalThis.self?.name?.startsWith("em-pthread"); -var isNode = globalThis.process?.versions?.node && globalThis.process?.type != "renderer"; -if (isNode) isPthread = (await import("worker_threads")).workerData === "em-pthread"; -isPthread && ortWasmThreaded(); diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.wasm b/examples/forge-sql-orm-example-ai/static/forge-orm-example/public/wasm/ort-wasm-simd-threaded.wasm deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/forge-sql-orm-example-ai/static/forge-orm-example/src/App.tsx b/examples/forge-sql-orm-example-ai/static/forge-orm-example/src/App.tsx deleted file mode 100644 index 379e4ef6a..000000000 --- a/examples/forge-sql-orm-example-ai/static/forge-orm-example/src/App.tsx +++ /dev/null @@ -1,345 +0,0 @@ -// SPDX-FileCopyrightText: 2025-2026 Vasyl Zakharchenko -// SPDX-License-Identifier: MIT - -import React, { useCallback, useEffect, useState } from "react"; -import { invoke } from "@forge/bridge"; -import Button from "@atlaskit/button"; -import DynamicTable from "@atlaskit/dynamic-table"; -import TextArea from "@atlaskit/textarea"; -import Textfield from "@atlaskit/textfield"; -import Tabs, { Tab, TabList, TabPanel } from "@atlaskit/tabs"; -import SectionMessage from "@atlaskit/section-message"; -import { Box, Inline, Stack, xcss } from "@atlaskit/primitives"; -import { useVectorModel } from "./vectorModelContext"; - -type SearchResult = { - id: number; - title: string; - document: string; - distance: number; -}; - -type DocumentRow = { - id: number; - title: string; - document: string; - embedding: number[]; -}; - -const pageContainerStyles = xcss({ - width: "100%", -}); - -const formBlockStyles = xcss({ - width: "100%", - maxWidth: "100%", -}); - -const contentCellStyles = xcss({ - whiteSpace: "normal", - overflowWrap: "anywhere", -}); - -function App() { - const vectorModel = useVectorModel(); - const [activeTabIndex, setActiveTabIndex] = useState(1); - const [title, setTitle] = useState(""); - const [documentText, setDocumentText] = useState(""); - const [searchText, setSearchText] = useState(""); - const [results, setResults] = useState([]); - const [documents, setDocuments] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const [message, setMessage] = useState(""); - const [openDocumentId, setOpenDocumentId] = useState(null); - const [openVectorId, setOpenVectorId] = useState(null); - const [openSearchDocumentId, setOpenSearchDocumentId] = useState(null); - const documentLimit = 2048; - - const fetchDocumentsFromApi = useCallback(async (): Promise => { - const data = await invoke("fetch"); - setDocuments(data); - setResults([]); - return data; - }, []); - - const handleFetchAll = useCallback(async () => { - setIsLoading(true); - setMessage(""); - try { - const data = await fetchDocumentsFromApi(); - setMessage(`Loaded ${data.length} document(s)`); - } catch (error) { - setMessage(`Fetch failed: ${error instanceof Error ? error.message : String(error)}`); - } finally { - setIsLoading(false); - } - }, [fetchDocumentsFromApi]); - - useEffect(() => { - if (activeTabIndex !== 0) return; - void handleFetchAll(); - }, [activeTabIndex, handleFetchAll]); - - const handleCreate = async () => { - const trimmedTitle = title.trim(); - const trimmedDocument = documentText.trim(); - if (!trimmedTitle) { - setMessage("Title is required"); - return; - } - if (!trimmedDocument) { - setMessage("Document is required"); - return; - } - if (trimmedDocument.length > documentLimit) { - setMessage(`Document must be at most ${documentLimit} characters`); - return; - } - - setIsLoading(true); - setMessage(""); - try { - const vector = await vectorModel.getVector(trimmedDocument); - const insertId = await invoke("create", { - data: { - title: trimmedTitle, - document: trimmedDocument, - embedding: vector, - }, - }); - try { - const rows = await fetchDocumentsFromApi(); - setMessage(`Document created. insertId: ${insertId}. Showing ${rows.length} document(s).`); - } catch (fetchError) { - setMessage( - `Document created. insertId: ${insertId}. Could not refresh list: ${fetchError instanceof Error ? fetchError.message : String(fetchError)}`, - ); - } - } catch (error) { - setMessage(`Create failed: ${error instanceof Error ? error.message : String(error)}`); - } finally { - setIsLoading(false); - } - }; - - const handleSearch = async () => { - const trimmedSearchText = searchText.trim(); - if (!trimmedSearchText) { - setMessage("Search text is required"); - return; - } - if (trimmedSearchText.length > documentLimit) { - setMessage(`Search text must be at most ${documentLimit} characters`); - return; - } - - setIsLoading(true); - setMessage(""); - try { - const vector = await vectorModel.getVector(trimmedSearchText); - const data = await invoke("search", { vector }); - setResults(data); - setDocuments([]); - setMessage(`Found ${data.length} result(s)`); - } catch (error) { - setMessage(`Search failed: ${error instanceof Error ? error.message : String(error)}`); - } finally { - setIsLoading(false); - } - }; - - const searchHead = { - cells: [ - { key: "id", content: "ID", width: 10 }, - { key: "title", content: "Title", width: 25 }, - { key: "document", content: "Document", width: 45 }, - { key: "similarity", content: "Similarity (%)", width: 20 }, - ], - }; - - const searchRows = results.map((row) => ({ - key: `search-${row.id}`, - cells: [ - { key: `id-${row.id}`, content: row.id }, - { key: `title-${row.id}`, content: row.title }, - { - key: `document-${row.id}`, - content: ( - - - - - {openSearchDocumentId === row.id ? ( - - Document: {row.document} - - ) : null} - - ), - }, - { key: `similarity-${row.id}`, content: `${((1 - row.distance) * 100).toFixed(2)}%` }, - ], - })); - - const documentsHead = { - cells: [ - { key: "id", content: "ID", width: 10 }, - { key: "title", content: "Title", width: 25 }, - { key: "document", content: "Document", width: 30 }, - { key: "vector", content: "Vector", width: 35 }, - ], - }; - - const documentRows = documents.map((row) => ({ - key: `fetch-${row.id}`, - cells: [ - { key: `id-${row.id}`, content: row.id }, - { key: `title-${row.id}`, content: row.title }, - { - key: `document-${row.id}`, - content: ( - - - - - {openDocumentId === row.id ? ( - - Document: {row.document} - - ) : null} - - ), - }, - { - key: `vector-${row.id}`, - content: ( - - - - - {openVectorId === row.id ? ( - - Vector: [{row.embedding.join(", ")}] - - ) : null} - - ), - }, - ], - })); - - return ( - - -

TiDB Vector Example (3D)

- - setActiveTabIndex(index)} - > - - Add documents - AI(Vector) search - - - - -

Insert document

- setTitle((e.target as HTMLInputElement).value)} - /> -