commit a801849fb2c369b999dc93bbe8fda2753fba8ae6 Author: web Date: Wed Nov 26 19:56:16 2025 -0800 🎉 feat: initialization diff --git a/.github/ISSUE_TEMPLATE/1_bug_report.yml b/.github/ISSUE_TEMPLATE/1_bug_report.yml new file mode 100644 index 0000000..d181c38 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1_bug_report.yml @@ -0,0 +1,45 @@ +name: '🐛 反馈缺陷 Bug Report' +description: '反馈一个问题缺陷 | Report an bug' +title: '[Bug] ' +labels: '🐛 Bug' +body: + - type: dropdown + attributes: + label: '💻 系统环境 | Operating System' + options: + - Windows + - macOS + - Ubuntu + - Other Linux + - Other + validations: + required: true + - type: dropdown + attributes: + label: '🌐 浏览器 | Browser' + options: + - Chrome + - Edge + - Safari + - Firefox + - Other + validations: + required: true + - type: textarea + attributes: + label: '🐛 问题描述 | Bug Description' + description: A clear and concise description of the bug. + validations: + required: true + - type: textarea + attributes: + label: '🚦 期望结果 | Expected Behavior' + description: A clear and concise description of what you expected to happen. + - type: textarea + attributes: + label: '📷 复现步骤 | Recurrence Steps' + description: A clear and concise description of how to recurrence. + - type: textarea + attributes: + label: '📝 补充信息 | Additional Information' + description: If your problem needs further explanation, or if the issue you're seeing cannot be reproduced in a gist, please add more information here. diff --git a/.github/ISSUE_TEMPLATE/2_feature_request.yml b/.github/ISSUE_TEMPLATE/2_feature_request.yml new file mode 100644 index 0000000..edcf7d0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/2_feature_request.yml @@ -0,0 +1,21 @@ +name: '🌠 功能需求 Feature Request' +description: '需求或建议 | Suggest an idea' +title: '[Request] ' +labels: '🌠 Feature Request' +body: + - type: textarea + attributes: + label: '🥰 需求描述 | Feature Description' + description: Please add a clear and concise description of the problem you are seeking to solve with this feature request. + validations: + required: true + - type: textarea + attributes: + label: '🧐 解决方案 | Proposed Solution' + description: Describe the solution you'd like in a clear and concise manner. + validations: + required: true + - type: textarea + attributes: + label: '📝 补充信息 | Additional Information' + description: Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/3_question.yml b/.github/ISSUE_TEMPLATE/3_question.yml new file mode 100644 index 0000000..f989f7d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/3_question.yml @@ -0,0 +1,15 @@ +name: '😇 疑问或帮助 Help Wanted' +description: '疑问或需要帮助 | Need help' +title: '[Question] ' +labels: '😇 Help Wanted' +body: + - type: textarea + attributes: + label: '🧐 问题描述 | Proposed Solution' + description: A clear and concise description of the proplem. + validations: + required: true + - type: textarea + attributes: + label: '📝 补充信息 | Additional Information' + description: Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/4_other.md b/.github/ISSUE_TEMPLATE/4_other.md new file mode 100644 index 0000000..215dd1f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/4_other.md @@ -0,0 +1,7 @@ +--- +name: '📝 其他 Other' +about: '其他问题 | Other issues' +title: '' +labels: '' +assignees: '' +--- diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..a73b6cf --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,17 @@ +#### 💻 变更类型 | Change Type + + + +- \[ ] ✨ feat +- \[ ] 🐛 fix +- \[ ] 💄 style +- \[ ] 🔨 chore +- \[ ] 📝 docs + +#### 🔀 变更说明 | Description of Change + + + +#### 📝 补充信息 | Additional Information + + diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml new file mode 100644 index 0000000..eea0d46 --- /dev/null +++ b/.github/workflows/auto-merge.yml @@ -0,0 +1,30 @@ +name: Dependabot Auto Merge +on: + pull_request_target: + types: [labeled, edited] + +jobs: + merge: + if: contains(github.event.pull_request.labels.*.name, 'dependencies') + name: Dependabot Auto Merge + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js environment + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install deps + run: pnpm install + + - name: Merge + uses: ahmadnassri/action-dependabot-auto-merge@v2 + with: + command: merge + target: minor + github-token: ${{ secrets.GH_TOKEN }} diff --git a/.github/workflows/issue-check-inactive.yml b/.github/workflows/issue-check-inactive.yml new file mode 100644 index 0000000..d37c4c3 --- /dev/null +++ b/.github/workflows/issue-check-inactive.yml @@ -0,0 +1,22 @@ +name: Issue Check Inactive + +on: + schedule: + - cron: '0 0 */15 * *' + +permissions: + contents: read + +jobs: + issue-check-inactive: + permissions: + issues: write # for actions-cool/issues-helper to update issues + pull-requests: write # for actions-cool/issues-helper to update PRs + runs-on: ubuntu-latest + steps: + - name: check-inactive + uses: actions-cool/issues-helper@v3 + with: + actions: 'check-inactive' + inactive-label: 'Inactive' + inactive-day: 30 diff --git a/.github/workflows/issue-close-require.yml b/.github/workflows/issue-close-require.yml new file mode 100644 index 0000000..68d6b6c --- /dev/null +++ b/.github/workflows/issue-close-require.yml @@ -0,0 +1,46 @@ +name: Issue Close Require + +on: + schedule: + - cron: '0 0 * * *' + +permissions: + contents: read + +jobs: + issue-close-require: + permissions: + issues: write # for actions-cool/issues-helper to update issues + pull-requests: write # for actions-cool/issues-helper to update PRs + runs-on: ubuntu-latest + steps: + - name: need reproduce + uses: actions-cool/issues-helper@v3 + with: + actions: 'close-issues' + labels: '✅ Fixed' + inactive-day: 3 + body: | + Since the issue was labeled with `✅ Fixed`, but no response in 3 days. This issue will be closed. If you have any questions, you can comment and reply. + + 由于该 issue 被标记为已修复,同时 3 天未收到回应。现关闭 issue,若有任何问题,可评论回复。 + - name: need reproduce + uses: actions-cool/issues-helper@v3 + with: + actions: 'close-issues' + labels: '🤔 Need Reproduce' + inactive-day: 3 + body: | + Since the issue was labeled with `🤔 Need Reproduce`, but no response in 3 days. This issue will be closed. If you have any questions, you can comment and reply. + + 由于该 issue 被标记为需要更多信息,却 3 天未收到回应。现关闭 issue,若有任何问题,可评论回复。 + - name: need reproduce + uses: actions-cool/issues-helper@v3 + with: + actions: 'close-issues' + labels: "🙅🏻‍♀️ WON'T DO" + inactive-day: 3 + body: | + Since the issue was labeled with `🙅🏻‍♀️ WON'T DO`, and no response in 3 days. This issue will be closed. If you have any questions, you can comment and reply. + + 由于该 issue 被标记为暂不处理,同时 3 天未收到回应。现关闭 issue,若有任何问题,可评论回复。 diff --git a/.github/workflows/issue-remove-inactive.yml b/.github/workflows/issue-remove-inactive.yml new file mode 100644 index 0000000..dbe42dd --- /dev/null +++ b/.github/workflows/issue-remove-inactive.yml @@ -0,0 +1,25 @@ +name: Issue Remove Inactive + +on: + issues: + types: [edited] + issue_comment: + types: [created, edited] + +permissions: + contents: read + +jobs: + issue-remove-inactive: + permissions: + issues: write # for actions-cool/issues-helper to update issues + pull-requests: write # for actions-cool/issues-helper to update PRs + runs-on: ubuntu-latest + steps: + - name: remove inactive + if: github.event.issue.state == 'open' && github.actor == github.event.issue.user.login + uses: actions-cool/issues-helper@v3 + with: + actions: 'remove-labels' + issue-number: ${{ github.event.issue.number }} + labels: 'Inactive' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..2dab160 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,42 @@ +name: Build and Release + +on: + push: + branches: [main, next, beta] + +permissions: + contents: write + +jobs: + release: + name: Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: 'latest' + + - name: Cache Bun dependencies + uses: actions/cache@v3 + with: + path: | + ~/.bun + node_modules + key: ${{ runner.os }}-bun-cache-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun-cache- + + - name: Install deps + run: bun install + + - name: Build + run: bun run build + + - name: Release + id: release + run: bun run release + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4133bab --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# Dependencies +node_modules +.pnp +.pnp.js + +# Local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Testing +coverage + +# Turbo +.turbo + +# Vercel +.vercel + +# Build Outputs +.next/ +out/ +build +dist + + +# Debug +npm-debug.log* + +# Misc +.DS_Store +*.pem diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..c415ba8 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,70 @@ +npm test + +#!/bin/sh +# Exit on any error +set -e + +# Check if there are any staged files +if [ -z "$(git diff --cached --name-only)" ]; then + echo "No staged files to format" + exit 0 +fi + +# Store the hash of staged changes to detect modifications +STAGED_HASH=$(git diff --cached | sha256sum | cut -d' ' -f1) + +# Save list of staged files (handling all file states) +STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR) +PARTIALLY_STAGED=$(git diff --name-only) + +# Stash unstaged changes to preserve working directory +# --keep-index keeps staged changes in working tree +git stash push --quiet --keep-index --message "pre-commit-stash" || true +STASHED=$? + +# Run formatter on the staged files +bun x ultracite fix +FORMAT_EXIT_CODE=$? + +# Restore working directory state +if [ $STASHED -eq 0 ]; then + # Re-stage the formatted files + if [ -n "$STAGED_FILES" ]; then + echo "$STAGED_FILES" | while IFS= read -r file; do + if [ -f "$file" ]; then + git add "$file" + fi + done + fi + + # Restore unstaged changes + git stash pop --quiet || true + + # Restore partial staging if files were partially staged + if [ -n "$PARTIALLY_STAGED" ]; then + for file in $PARTIALLY_STAGED; do + if [ -f "$file" ] && echo "$STAGED_FILES" | grep -q "^$file$"; then + # File was partially staged - need to unstage the unstaged parts + git restore --staged "$file" 2>/dev/null || true + git add -p "$file" < /dev/null 2>/dev/null || git add "$file" + fi + done + fi +else + # No stash was created, just re-add the formatted files + if [ -n "$STAGED_FILES" ]; then + echo "$STAGED_FILES" | while IFS= read -r file; do + if [ -f "$file" ]; then + git add "$file" + fi + done + fi +fi + +# Check if staged files actually changed +NEW_STAGED_HASH=$(git diff --cached | sha256sum | cut -d' ' -f1) +if [ "$STAGED_HASH" != "$NEW_STAGED_HASH" ]; then + echo "✨ Files formatted by Ultracite" +fi + +exit $FORMAT_EXIT_CODE diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..d7a0177 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,157 @@ +{ + "repositoryUrl": "https://github.com/perfect-panel/frontend", + "branches": [ + "main", + { + "name": "beta", + "prerelease": true + }, + { + "name": "alpha", + "prerelease": true + }, + { + "name": "develop", + "prerelease": "dev" + }, + { + "name": "next", + "prerelease": true + } + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { "type": "feat", "release": "minor" }, + { "type": "fix", "release": "patch" }, + { "type": "perf", "release": "patch" }, + { "type": "revert", "release": "patch" }, + { "type": "docs", "release": false }, + { "type": "style", "release": false }, + { "type": "chore", "release": false }, + { "type": "refactor", "release": "patch" }, + { "type": "test", "release": false }, + { "type": "build", "release": false }, + { "type": "ci", "release": false }, + { "release": "major", "breaking": true }, + { "release": "patch", "subject": "*force patch*" }, + { "release": "minor", "subject": "*force minor*" }, + { "release": "major", "subject": "*force major*" }, + { "release": false, "subject": "*skip release*" }, + { "release": false, "subject": "*no release*" }, + { "release": "patch", "revert": true }, + { "release": "patch", "type": "security" }, + { "release": "minor", "type": "deprecate" } + ], + "parserOpts": { + "headerPattern": "^(?:(\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff])\\s*)?(\\w*)(?:\\((.*)\\))?!?:\\s*(.*)$", + "headerCorrespondence": ["emoji", "type", "scope", "subject"], + "noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES", "BREAKING"], + "revertPattern": "^(?:Revert|revert:)\\s\"?([\\s\\S]*)\"?\\s*This reverts commit (\\w*)\\.?", + "revertCorrespondence": ["header", "hash"] + } + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "✨ Features / 新功能" + }, + { + "type": "fix", + "section": "🐛 Bug Fixes / 问题修复" + }, + { + "type": "docs", + "section": "📚 Documentation / 文档更新" + }, + { + "type": "style", + "section": "🎨 Code Style / 代码格式" + }, + { + "type": "refactor", + "section": "♻️ Code Refactoring / 代码重构" + }, + { + "type": "perf", + "section": "⚡️ Performance Improvements / 性能优化" + }, + { + "type": "test", + "section": "🧪 Tests / 测试相关" + }, + { + "type": "build", + "section": "🔨 Build System / 构建系统" + }, + { + "type": "ci", + "section": "👷 Continuous Integration / CI/CD" + }, + { + "type": "chore", + "section": "🔧 Chores / 其他变更" + } + ] + }, + "parserOpts": { + "headerPattern": "^(?:(\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff])\\s*)?(\\w*)(?:\\((.*)\\))?!?:\\s*(.*)$", + "headerCorrespondence": ["emoji", "type", "scope", "subject"], + "noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES", "BREAKING"], + "revertPattern": "^(?:Revert|revert:)\\s\"?([\\s\\S]*)\"?\\s*This reverts commit (\\w*)\\.?", + "revertCorrespondence": ["header", "hash"] + } + } + ], + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md", + "changelogTitle": "# 📋 Changelog / 更新日志\n\nThis document records all notable changes to ShadCN Admin.\n本文档记录了 ShadCN Admin 的所有重要变更。\n\n## Version Guide / 版本说明\n- 🔥 **Breaking Changes / 重大变更**: Contains breaking updates / 包含破坏性更新\n- ✨ **Features / 新功能**: New features added / 添加的新特性\n- 🐛 **Bug Fixes / 问题修复**: Fixed bugs / 修复的bug\n- 📚 **Documentation / 文档**: Documentation updates / 文档相关更新\n- 🎨 **Style / 样式**: Code formatting and style changes / 代码格式化、样式调整\n- ♻️ **Refactoring / 重构**: Code refactoring / 代码重构\n- ⚡️ **Performance / 性能**: Performance improvements / 性能优化\n- 🧪 **Tests / 测试**: Test related changes / 测试相关\n- 🔨 **Build / 构建**: Build system changes / 构建系统相关\n- 👷 **CI/CD**: Continuous integration changes / CI/CD相关\n- 🔧 **Chores / 杂项**: Other changes / 其他变更\n\n---\n" + } + ], + [ + "@semantic-release/npm", + { + "npmPublish": false + } + ], + [ + "@semantic-release/git", + { + "assets": ["CHANGELOG.md", "package.json"], + "message": "🚀 chore(release): Release ${nextRelease.version} / 发布版本 ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ], + [ + "@semantic-release/exec", + { + "prepareCmd": "tar -czf admin.tar.gz -C apps/admin dist/ && tar -czf user.tar.gz -C apps/user dist/" + } + ], + [ + "@semantic-release/github", + { + "assets": [ + { + "path": "admin.tar.gz", + "name": "ppanel-admin-${nextRelease.version}.tar.gz" + }, + { + "path": "user.tar.gz", + "name": "ppanel-user-${nextRelease.version}.tar.gz" + } + ] + } + ] + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d06a5a1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,44 @@ +{ + "tailwindCSS.experimental.configFile": "packages/ui/src/styles/globals.css", + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[css]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[graphql]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "typescript.tsdk": "node_modules/typescript/lib", + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "emmet.showExpandedAbbreviation": "never", + "editor.codeActionsOnSave": { + "source.fixAll.biome": "explicit", + "source.organizeImports.biome": "explicit" + }, + "explorer.fileNesting.enabled": true, + "explorer.fileNesting.patterns": { + "*.ts": "${capture}.js", + "*.js": "${capture}.js.map, ${capture}.min.js, ${capture}.d.ts", + "*.jsx": "${capture}.js", + "*.tsx": "${capture}.ts", + "README.md": "*.md, LICENSE" + } +} diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..42729d4 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# 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 +. +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 +. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +For answers to common questions about this code of conduct, see the FAQ at +. Translations are available at +. + +[homepage]: https://www.contributor-covenant.org diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6795220 --- /dev/null +++ b/README.md @@ -0,0 +1,138 @@ + + +
+ + + +

PPanel web

+ +This is a PPanel web powered by PPanel + +English +· +[Chinese](./README.zh-CN.md) +· +[Changelog](../../CHANGELOG.md) +· +[Report Bug][issues-link] +· +[Request Feature][issues-link] + + + +[![][github-release-shield]][github-release-link] +[![][github-releasedate-shield]][github-releasedate-link] +[![][github-action-test-shield]][github-action-test-link] +[![][github-action-release-shield]][github-action-release-link]
+[![][github-contributors-shield]][github-contributors-link] +[![][github-forks-shield]][github-forks-link] +[![][github-stars-shield]][github-stars-link] +[![][github-issues-shield]][github-issues-link] +[![][github-license-shield]][github-license-link] + +![][split] + +
+ +> **Article 1.** +> All human beings are born free and equal in dignity and rights. +> They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood. +> +> **Article 12.** +> No one shall be subjected to arbitrary interference with his privacy, family, home or correspondence, nor to attacks upon his honour and reputation. +> Everyone has the right to the protection of the law against such interference or attacks. +> +> **Article 19.** +> Everyone has the right to freedom of opinion and expression; this right includes freedom to hold opinions without interference and to seek, receive and impart information and ideas through any media and regardless of frontiers. +> +> _Source: [United Nations – Universal Declaration of Human Rights (UN.org)](https://www.un.org/sites/un2.un.org/files/2021/03/udhr.pdf)_ + +## 📦 Application List + +| 📦 Application | 🖼️ Preview | +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------- | +| [**PPanel User Web**][ppanel-user-web-github]
Developed with modern frontend technologies (Next.js, TypeScript, TailwindCSS), providing basic user features with support for multiple languages and themes.
[![One-Click Deploy](https://img.shields.io/badge/Deploy%20with-Vercel-blue?style=for-the-badge)][ppanel-user-web-deploy] | [![Preview][ppanel-user-web-cover]][ppanel-user-web-github] | +| [**PPanel Admin Web**][ppanel-admin-web-github]
Developed with modern frontend technologies, this admin web provides basic data management features with support for multiple languages and themes.
[![One-Click Deploy](https://img.shields.io/badge/Deploy%20with-Vercel-blue?style=for-the-badge)][ppanel-admin-web-deploy] | [![Preview][ppanel-admin-web-cover]][ppanel-admin-web-preview] | + +## ⌨️ Local Development + +You can use Github Codespaces for online development: + +[![][codespaces-shield]][codespaces-link] + +You can use Gitpod for online development: + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][gitpod-link] + +or clone it for local development: + +```bash +git clone https://github.com/perfect-panel/ppanel-web.git +cd ppanel-web + +# Install dependencies +bun install +``` + +## 🤝 Contributing + +Contributions of all types are more than welcome, +if you're interested in contributing code, feel free to check out our GitHub +[Issues][github-issues-link] to get stuck in to show us what you’re made of. + +[![][pr-welcome-shield]][pr-welcome-link] + +[![][contributors-contrib]][contributors-url] + +
+ +[![][back-to-top]](#readme-top) + +
+ +--- + +## 📝 License + +Copyright © 2024 [PPanel][profile-link].
+This project is [GNU](../../LICENSE) licensed. + + + +[back-to-top]: https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square +[codespaces-link]: https://codespaces.new/perfect-panel/ppanel-web +[codespaces-shield]: https://github.com/codespaces/badge.svg +[contributors-contrib]: https://contrib.rocks/image?repo=perfect-panel/ppanel-web +[contributors-url]: https://github.com/perfect-panel/ppanel-web/graphs/contributors +[github-action-release-link]: https://github.com/perfect-panel/ppanel-web/actions/workflows/release.yml +[github-action-release-shield]: https://img.shields.io/github/actions/workflow/status/perfect-panel/ppanel-web/release.yml?label=release&labelColor=black&logo=githubactions&logoColor=white&style=flat-square +[github-action-test-link]: https://github.com/perfect-panel/ppanel-web/actions/workflows/test.yml +[github-action-test-shield]: https://img.shields.io/github/actions/workflow/status/perfect-panel/ppanel-web/test.yml?label=test&labelColor=black&logo=githubactions&logoColor=white&style=flat-square +[github-contributors-link]: https://github.com/perfect-panel/ppanel-web/graphs/contributors +[github-contributors-shield]: https://img.shields.io/github/contributors/perfect-panel/ppanel-web?color=c4f042&labelColor=black&style=flat-square +[github-forks-link]: https://github.com/perfect-panel/ppanel-web/network/members +[github-forks-shield]: https://img.shields.io/github/forks/perfect-panel/ppanel-web?color=8ae8ff&labelColor=black&style=flat-square +[github-issues-link]: https://github.com/perfect-panel/ppanel-web/issues +[github-issues-shield]: https://img.shields.io/github/issues/perfect-panel/ppanel-web?color=ff80eb&labelColor=black&style=flat-square +[github-license-link]: https://github.com/perfect-panel/ppanel-web/blob/master/LICENSE +[github-license-shield]: https://img.shields.io/github/license/perfect-panel/ppanel-web?color=white&labelColor=black&style=flat-square +[github-release-link]: https://github.com/perfect-panel/ppanel-web/releases +[github-release-shield]: https://img.shields.io/github/v/release/perfect-panel/ppanel-web?style=flat-square&sort=semver&logo=github +[github-releasedate-link]: https://github.com/perfect-panel/ppanel-web/releases +[github-releasedate-shield]: https://img.shields.io/github/release-date/perfect-panel/ppanel-web?labelColor=black&style=flat-square +[github-stars-link]: https://github.com/perfect-panel/ppanel-web/network/stargazers +[github-stars-shield]: https://img.shields.io/github/stars/perfect-panel/ppanel-web?color=ffcb47&labelColor=black&style=flat-square +[gitpod-link]: https://gitpod.io/#https://github.com/perfect-panel/ppanel-web +[issues-link]: https://github.com/perfect-panel/ppanel-web/issues/new/choose +[pr-welcome-link]: https://github.com/perfect-panel/ppanel-web/pulls +[pr-welcome-shield]: https://img.shields.io/badge/🤯_pr_welcome-%E2%86%92-ffcb47?labelColor=black&style=for-the-badge +[profile-link]: https://github.com/perfect-panel +[split]: https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png +[ppanel-user-web-github]: https://github.com/perfect-panel/ppanel-web/tree/main/apps/user +[ppanel-user-web-cover]: https://urlscan.io/liveshot/?width=1920&height=1080&url=https://user.ppanel.dev +[ppanel-user-web-preview]: https://user.ppanel.dev +[ppanel-user-web-deploy]: https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool%2C%20designed%20to%20be%20your%20ideal%20choice%20for%20learning%20and%20practical%20use&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fuser.ppanel.dev&demo-title=PPanel%20User%20Web&demo-url=https%3A%2F%2Fuser.ppanel.dev%2F&from=.&project-name=ppanel-user-web&repository-name=ppanel-web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Fppanel-web&root-directory=apps%2Fuser&skippable-integrations=1 +[ppanel-admin-web-github]: https://github.com/perfect-panel/ppanel-web/tree/main/apps/admin +[ppanel-admin-web-cover]: https://urlscan.io/liveshot/?width=1920&height=1080&url=https://admin.ppanel.dev +[ppanel-admin-web-preview]: https://admin.ppanel.dev +[ppanel-admin-web-deploy]: https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool%2C%20designed%20to%20be%20your%20ideal%20choice%20for%20learning%20and%20practical%20use&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fadmin.ppanel.dev&demo-title=PPanel%20Admin%20Web&demo-url=https%3A%2F%2Fadmin.ppanel.dev%2F&from=.&project-name=ppanel-admin-web&repository-name=ppanel-web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Fppanel-web&root-directory=apps%2Fadmin&skippable-integrations=1 diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..717991a --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,138 @@ + + +
+ + + +

PPanel 前端

+ +这是由 PPanel 提供支持的前端 + +[英文](./README.md) +· +中文 +· +[更新日志](./CHANGELOG.md) +· +[报告问题][issues-link] +· +[请求功能][issues-link] + + + +[![][github-release-shield]][github-release-link] +[![][github-releasedate-shield]][github-releasedate-link] +[![][github-action-test-shield]][github-action-test-link] +[![][github-action-release-shield]][github-action-release-link]
+[![][github-contributors-shield]][github-contributors-link] +[![][github-forks-shield]][github-forks-link] +[![][github-stars-shield]][github-stars-link] +[![][github-issues-shield]][github-issues-link] +[![][github-license-shield]][github-license-link] + +![][split] + +
+ +> **第一条** +> 人人生而自由,在尊严与权利上一律平等。 +> 他们赋有理性与良知,应当以兄弟般的精神彼此相待。 +> +> **第十二条** +> 任何人的隐私、家庭、住宅和通信不得任意干涉,其名誉与荣誉不得加以攻击。 +> 人人有权受到法律的保护,以免遭受这种干涉或攻击。 +> +> **第十九条** +> 人人有思想与表达的自由;此项自由包括持有主张而不受干预,以及通过任何媒介、无论国界,自由寻求、接受和传播信息与思想。 +> +> _来源: [United Nations – Universal Declaration of Human Rights (UN.org)](https://www.un.org/sites/un2.un.org/files/2021/03/udhr.pdf)_ + +## 📦 Application List + +| 📦 Application | 🖼️ Preview | +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------- | +| [**PPanel User Web**][ppanel-user-web-github]
Developed with modern frontend technologies (Next.js, TypeScript, TailwindCSS), providing basic user features with support for multiple languages and themes.
[![One-Click Deploy](https://img.shields.io/badge/Deploy%20with-Vercel-blue?style=for-the-badge)][ppanel-user-web-deploy] | [![Preview][ppanel-user-web-cover]][ppanel-user-web-github] | +| [**PPanel Admin Web**][ppanel-admin-web-github]
Developed with modern frontend technologies, this admin web provides basic data management features with support for multiple languages and themes.
[![One-Click Deploy](https://img.shields.io/badge/Deploy%20with-Vercel-blue?style=for-the-badge)][ppanel-admin-web-deploy] | [![Preview][ppanel-admin-web-cover]][ppanel-admin-web-preview] | + +## ⌨️ 本地开发 + +您可以使用 Github Codespaces 进行在线开发: + +[![][codespaces-shield]][codespaces-link] + +您可以使用 Gitpod 进行在线开发: + +[![在 Gitpod 中打开](https://gitpod.io/button/open-in-gitpod.svg)][gitpod-link] + +或者克隆项目进行本地开发: + +```bash +git clone https://github.com/perfect-panel/ppanel-web.git +cd ppanel-web + +# 安装依赖 +bun install +``` + +## 🤝 贡献 + +欢迎各种类型的贡献, +如果您有兴趣贡献代码,请随时查看我们的 GitHub +[问题][github-issues-link] 来展示您的能力。 + +[![][pr-welcome-shield]][pr-welcome-link] + +[![][contributors-contrib]][contributors-url] + +
+ +[![][back-to-top]](#readme-top) + +
+ +--- + +## 📝 许可证 + +版权所有 © 2024 [PPanel][profile-link]。
+本项目使用 [GNU](./LICENSE) 许可证。 + + + +[back-to-top]: https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square +[codespaces-link]: https://codespaces.new/perfect-panel/ppanel-web +[codespaces-shield]: https://github.com/codespaces/badge.svg +[contributors-contrib]: https://contrib.rocks/image?repo=perfect-panel/ppanel-web +[contributors-url]: https://github.com/perfect-panel/ppanel-web/graphs/contributors +[github-action-release-link]: https://github.com/perfect-panel/ppanel-web/actions/workflows/release.yml +[github-action-release-shield]: https://img.shields.io/github/actions/workflow/status/perfect-panel/ppanel-web/release.yml?label=release&labelColor=black&logo=githubactions&logoColor=white&style=flat-square +[github-action-test-link]: https://github.com/perfect-panel/ppanel-web/actions/workflows/test.yml +[github-action-test-shield]: https://img.shields.io/github/actions/workflow/status/perfect-panel/ppanel-web/test.yml?label=test&labelColor=black&logo=githubactions&logoColor=white&style=flat-square +[github-contributors-link]: https://github.com/perfect-panel/ppanel-web/graphs/contributors +[github-contributors-shield]: https://img.shields.io/github/contributors/perfect-panel/ppanel-web?color=c4f042&labelColor=black&style=flat-square +[github-forks-link]: https://github.com/perfect-panel/ppanel-web/network/members +[github-forks-shield]: https://img.shields.io/github/forks/perfect-panel/ppanel-web?color=8ae8ff&labelColor=black&style=flat-square +[github-issues-link]: https://github.com/perfect-panel/ppanel-web/issues +[github-issues-shield]: https://img.shields.io/github/issues/perfect-panel/ppanel-web?color=ff80eb&labelColor=black&style=flat-square +[github-license-link]: https://github.com/perfect-panel/ppanel-web/blob/master/LICENSE +[github-license-shield]: https://img.shields.io/github/license/perfect-panel/ppanel-web?color=white&labelColor=black&style=flat-square +[github-release-link]: https://github.com/perfect-panel/ppanel-web/releases +[github-release-shield]: https://img.shields.io/github/v/release/perfect-panel/ppanel-web?style=flat-square&sort=semver&logo=github +[github-releasedate-link]: https://github.com/perfect-panel/ppanel-web/releases +[github-releasedate-shield]: https://img.shields.io/github/release-date/perfect-panel/ppanel-web?labelColor=black&style=flat-square +[github-stars-link]: https://github.com/perfect-panel/ppanel-web/network/stargazers +[github-stars-shield]: https://img.shields.io/github/stars/perfect-panel/ppanel-web?color=ffcb47&labelColor=black&style=flat-square +[gitpod-link]: https://gitpod.io/#https://github.com/perfect-panel/ppanel-web +[issues-link]: https://github.com/perfect-panel/ppanel-web/issues/new/choose +[pr-welcome-link]: https://github.com/perfect-panel/ppanel-web/pulls +[pr-welcome-shield]: https://img.shields.io/badge/🤯_pr_welcome-%E2%86%92-ffcb47?labelColor=black&style=for-the-badge +[profile-link]: https://github.com/perfect-panel +[split]: https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png +[ppanel-user-web-github]: https://github.com/perfect-panel/ppanel-web/tree/main/apps/user +[ppanel-user-web-cover]: https://urlscan.io/liveshot/?width=1920&height=1080&url=https://user.ppanel.dev +[ppanel-user-web-preview]: https://user.ppanel.dev +[ppanel-user-web-deploy]: https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool%2C%20designed%20to%20be%20your%20ideal%20choice%20for%20learning%20and%20practical%20use&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fuser.ppanel.dev&demo-title=PPanel%20User%20Web&demo-url=https%3A%2F%2Fuser.ppanel.dev%2F&from=.&project-name=ppanel-user-web&repository-name=ppanel-web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Fppanel-web&root-directory=apps%2Fuser&skippable-integrations=1 +[ppanel-admin-web-github]: https://github.com/perfect-panel/ppanel-web/tree/main/apps/admin +[ppanel-admin-web-cover]: https://urlscan.io/liveshot/?width=1920&height=1080&url=https://admin.ppanel.dev +[ppanel-admin-web-preview]: https://admin.ppanel.dev +[ppanel-admin-web-deploy]: https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool%2C%20designed%20to%20be%20your%20ideal%20choice%20for%20learning%20and%20practical%20use&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fadmin.ppanel.dev&demo-title=PPanel%20Admin%20Web&demo-url=https%3A%2F%2Fadmin.ppanel.dev%2F&from=.&project-name=ppanel-admin-web&repository-name=ppanel-web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Fppanel-web&root-directory=apps%2Fadmin&skippable-integrations=1 diff --git a/apps/admin/.cta.json b/apps/admin/.cta.json new file mode 100644 index 0000000..d19e33b --- /dev/null +++ b/apps/admin/.cta.json @@ -0,0 +1,12 @@ +{ + "projectName": "apps/user", + "mode": "file-router", + "typescript": true, + "tailwind": true, + "packageManager": "bun", + "addOnOptions": {}, + "git": true, + "version": 1, + "framework": "react-cra", + "chosenAddOns": ["biome", "tanstack-query", "table", "form", "shadcn"] +} diff --git a/apps/admin/.gitignore b/apps/admin/.gitignore new file mode 100644 index 0000000..58b8598 --- /dev/null +++ b/apps/admin/.gitignore @@ -0,0 +1,10 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local +count.txt +.env +.nitro +.tanstack +.wrangler diff --git a/apps/admin/.vscode/settings.json b/apps/admin/.vscode/settings.json new file mode 100644 index 0000000..70dd163 --- /dev/null +++ b/apps/admin/.vscode/settings.json @@ -0,0 +1,35 @@ +{ + "files.watcherExclude": { + "**/routeTree.gen.ts": true + }, + "search.exclude": { + "**/routeTree.gen.ts": true + }, + "files.readonlyInclude": { + "**/routeTree.gen.ts": true + }, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[css]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "source.organizeImports.biome": "explicit" + } +} diff --git a/apps/admin/README.md b/apps/admin/README.md new file mode 100644 index 0000000..37dc8b5 --- /dev/null +++ b/apps/admin/README.md @@ -0,0 +1,141 @@ + + +
+ + + +

PPanel admin web

+ +This is a PPanel admin web powered by PPanel + +English +· +[Chinese](./README.zh-CN.md) +· +[Changelog](../../CHANGELOG.md) +· +[Report Bug][issues-link] +· +[Request Feature][issues-link] + + + +[![][github-release-shield]][github-release-link] +[![][github-releasedate-shield]][github-releasedate-link] +[![][github-action-test-shield]][github-action-test-link] +[![][github-action-release-shield]][github-action-release-link]
+[![][github-contributors-shield]][github-contributors-link] +[![][github-forks-shield]][github-forks-link] +[![][github-stars-shield]][github-stars-link] +[![][github-issues-shield]][github-issues-link] +[![][github-license-shield]][github-license-link] + +![](https://urlscan.io/liveshot/?width=1920&height=1080&url=https://admin.ppanel.dev) + +
+ +
+Table of contents + +#### TOC + +- [⌨️ Local Development](#️-local-development) +- [🚀 Deploy on Vercel](#-deploy-on-vercel) +- [🤝 Contributing](#-contributing) +- [📝 License](#-license) + +#### + +
+ +## ⌨️ Local Development + +You can use Github Codespaces for online development: + +[![][codespaces-shield]][codespaces-link] + +You can use Gitpod for online development: + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][gitpod-link] + +or clone it for local development: + +```bash +git clone https://github.com/perfect-panel/ppanel-web.git +cd ppanel-web + +# Install dependencies +bun install + +# Run the development server +cd apps/admin +bun dev +``` + +Open with your browser to see the result. + +## 🚀 Deploy on Vercel + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool%2C%20designed%20to%20be%20your%20ideal%20choice%20for%20learning%20and%20practical%20use&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fadmin.ppanel.dev&demo-title=PPanel%20Admin%20Web&demo-url=https%3A%2F%2Fadmin.ppanel.dev%2F&from=.&project-name=ppanel-admin-web&repository-name=ppanel-web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Fppanel-web&root-directory=apps%2Fadmin&skippable-integrations=1) + +The easiest way to deploy your Next.js app is to use the +[Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) +from the creators of Next.js. + +Check out our +[Next.js deployment documentation](https://nextjs.org/docs/deployment) +for more details. + +## 🤝 Contributing + +Contributions of all types are more than welcome, +if you're interested in contributing code, feel free to check out our GitHub +[Issues][github-issues-link] to get stuck in to show us what you’re made of. + +[![][pr-welcome-shield]][pr-welcome-link] + +[![][contributors-contrib]][contributors-url] + +
+ +[![][back-to-top]](#readme-top) + +
+ +--- + +## 📝 License + +Copyright © 2024 [PPanel][profile-link].
+This project is [GNU](../../LICENSE) licensed. + + + +[back-to-top]: https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square +[codespaces-link]: https://codespaces.new/perfect-panel/ppanel-web +[codespaces-shield]: https://github.com/codespaces/badge.svg +[contributors-contrib]: https://contrib.rocks/image?repo=perfect-panel/ppanel-web +[contributors-url]: https://github.com/perfect-panel/ppanel-web/graphs/contributors +[github-action-release-link]: https://github.com/perfect-panel/ppanel-web/actions/workflows/release.yml +[github-action-release-shield]: https://img.shields.io/github/actions/workflow/status/perfect-panel/ppanel-web/release.yml?label=release&labelColor=black&logo=githubactions&logoColor=white&style=flat-square +[github-action-test-link]: https://github.com/perfect-panel/ppanel-web/actions/workflows/test.yml +[github-action-test-shield]: https://img.shields.io/github/actions/workflow/status/perfect-panel/ppanel-web/test.yml?label=test&labelColor=black&logo=githubactions&logoColor=white&style=flat-square +[github-contributors-link]: https://github.com/perfect-panel/ppanel-web/graphs/contributors +[github-contributors-shield]: https://img.shields.io/github/contributors/perfect-panel/ppanel-web?color=c4f042&labelColor=black&style=flat-square +[github-forks-link]: https://github.com/perfect-panel/ppanel-web/network/members +[github-forks-shield]: https://img.shields.io/github/forks/perfect-panel/ppanel-web?color=8ae8ff&labelColor=black&style=flat-square +[github-issues-link]: https://github.com/perfect-panel/ppanel-web/issues +[github-issues-shield]: https://img.shields.io/github/issues/perfect-panel/ppanel-web?color=ff80eb&labelColor=black&style=flat-square +[github-license-link]: https://github.com/perfect-panel/ppanel-web/blob/master/LICENSE +[github-license-shield]: https://img.shields.io/github/license/perfect-panel/ppanel-web?color=white&labelColor=black&style=flat-square +[github-release-link]: https://github.com/perfect-panel/ppanel-web/releases +[github-release-shield]: https://img.shields.io/github/v/release/perfect-panel/ppanel-web?style=flat-square&sort=semver&logo=github +[github-releasedate-link]: https://github.com/perfect-panel/ppanel-web/releases +[github-releasedate-shield]: https://img.shields.io/github/release-date/perfect-panel/ppanel-web?labelColor=black&style=flat-square +[github-stars-link]: https://github.com/perfect-panel/ppanel-web/network/stargazers +[github-stars-shield]: https://img.shields.io/github/stars/perfect-panel/ppanel-web?color=ffcb47&labelColor=black&style=flat-square +[gitpod-link]: https://gitpod.io/#https://github.com/perfect-panel/ppanel-web +[issues-link]: https://github.com/perfect-panel/ppanel-web/issues/new/choose +[pr-welcome-link]: https://github.com/perfect-panel/ppanel-web/pulls +[pr-welcome-shield]: https://img.shields.io/badge/🤯_pr_welcome-%E2%86%92-ffcb47?labelColor=black&style=for-the-badge +[profile-link]: https://github.com/perfect-panel diff --git a/apps/admin/README.zh-CN.md b/apps/admin/README.zh-CN.md new file mode 100644 index 0000000..f7aab82 --- /dev/null +++ b/apps/admin/README.zh-CN.md @@ -0,0 +1,141 @@ + + +
+ + + +

PPanel 管理后台

+ +这是由 PPanel 提供支持的 PPanel 管理后台 + +[英文](./README.md) +· +中文 +· +[更新日志](../../CHANGELOG.md) +· +[报告问题][issues-link] +· +[请求功能][issues-link] + + + +[![][github-release-shield]][github-release-link] +[![][github-releasedate-shield]][github-releasedate-link] +[![][github-action-test-shield]][github-action-test-link] +[![][github-action-release-shield]][github-action-release-link]
+[![][github-contributors-shield]][github-contributors-link] +[![][github-forks-shield]][github-forks-link] +[![][github-stars-shield]][github-stars-link] +[![][github-issues-shield]][github-issues-link] +[![][github-license-shield]][github-license-link] + +![](https://urlscan.io/liveshot/?width=1920&height=1080&url=https://admin.ppanel.dev) + +
+ +
+目录 + +#### 目录 + +- [⌨️ 本地开发](#️-本地开发) +- [🚀 在 Vercel 上部署](#-在-vercel-上部署) +- [🤝 贡献](#-贡献) +- [📝 许可证](#-许可证) + +#### + +
+ +## ⌨️ 本地开发 + +您可以使用 Github Codespaces 进行在线开发: + +[![][codespaces-shield]][codespaces-link] + +您可以使用 Gitpod 进行在线开发: + +[![在 Gitpod 中打开](https://gitpod.io/button/open-in-gitpod.svg)][gitpod-link] + +或者克隆项目进行本地开发: + +```bash +git clone https://github.com/perfect-panel/ppanel-web.git +cd ppanel-web + +# 安装依赖 +bun install + +# 运行开发服务器 +cd apps/admin +bun dev +``` + +在浏览器中打开 查看结果。 + +## 🚀 在 Vercel 上部署 + +[![使用 Vercel 部署](https://vercel.com/button)](https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool%2C%20designed%20to%20be%20your%20ideal%20choice%20for%20learning%20and%20practical%20use&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fadmin.ppanel.dev&demo-title=PPanel%20Admin%20Web&demo-url=https%3A%2F%2Fadmin.ppanel.dev%2F&from=.&project-name=ppanel-admin-web&repository-name=ppanel-web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Fppanel-web&root-directory=apps%2Fadmin&skippable-integrations=1) + +部署 Next.js 应用的最简单方式是使用 +[ Vercel 平台](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) +由 Next.js 的创建者提供支持。 + +查看我们的 +[Next.js 部署文档](https://nextjs.org/docs/deployment) +获取更多详情。 + +## 🤝 贡献 + +欢迎各种类型的贡献, +如果您有兴趣贡献代码,请随时查看我们的 GitHub +[问题][github-issues-link] 来展示您的能力。 + +[![][pr-welcome-shield]][pr-welcome-link] + +[![][contributors-contrib]][contributors-url] + +
+ +[![][back-to-top]](#readme-top) + +
+ +--- + +## 📝 许可证 + +版权所有 © 2024 [PPanel][profile-link]。
+本项目使用 [GNU](./LICENSE) 许可证。 + + + +[back-to-top]: https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square +[codespaces-link]: https://codespaces.new/perfect-panel/ppanel-web +[codespaces-shield]: https://github.com/codespaces/badge.svg +[contributors-contrib]: https://contrib.rocks/image?repo=perfect-panel/ppanel-web +[contributors-url]: https://github.com/perfect-panel/ppanel-web/graphs/contributors +[github-action-release-link]: https://github.com/perfect-panel/ppanel-web/actions/workflows/release.yml +[github-action-release-shield]: https://img.shields.io/github/actions/workflow/status/perfect-panel/ppanel-web/release.yml?label=release&labelColor=black&logo=githubactions&logoColor=white&style=flat-square +[github-action-test-link]: https://github.com/perfect-panel/ppanel-web/actions/workflows/test.yml +[github-action-test-shield]: https://img.shields.io/github/actions/workflow/status/perfect-panel/ppanel-web/test.yml?label=test&labelColor=black&logo=githubactions&logoColor=white&style=flat-square +[github-contributors-link]: https://github.com/perfect-panel/ppanel-web/graphs/contributors +[github-contributors-shield]: https://img.shields.io/github/contributors/perfect-panel/ppanel-web?color=c4f042&labelColor=black&style=flat-square +[github-forks-link]: https://github.com/perfect-panel/ppanel-web/network/members +[github-forks-shield]: https://img.shields.io/github/forks/perfect-panel/ppanel-web?color=8ae8ff&labelColor=black&style=flat-square +[github-issues-link]: https://github.com/perfect-panel/ppanel-web/issues +[github-issues-shield]: https://img.shields.io/github/issues/perfect-panel/ppanel-web?color=ff80eb&labelColor=black&style=flat-square +[github-license-link]: https://github.com/perfect-panel/ppanel-web/blob/master/LICENSE +[github-license-shield]: https://img.shields.io/github/license/perfect-panel/ppanel-web?color=white&labelColor=black&style=flat-square +[github-release-link]: https://github.com/perfect-panel/ppanel-web/releases +[github-release-shield]: https://img.shields.io/github/v/release/perfect-panel/ppanel-web?style=flat-square&sort=semver&logo=github +[github-releasedate-link]: https://github.com/perfect-panel/ppanel-web/releases +[github-releasedate-shield]: https://img.shields.io/github/release-date/perfect-panel/ppanel-web?labelColor=black&style=flat-square +[github-stars-link]: https://github.com/perfect-panel/ppanel-web/network/stargazers +[github-stars-shield]: https://img.shields.io/github/stars/perfect-panel/ppanel-web?color=ffcb47&labelColor=black&style=flat-square +[gitpod-link]: https://gitpod.io/#https://github.com/perfect-panel/ppanel-web +[issues-link]: https://github.com/perfect-panel/ppanel-web/issues/new/choose +[pr-welcome-link]: https://github.com/perfect-panel/ppanel-web/pulls +[pr-welcome-shield]: https://img.shields.io/badge/🤯_pr_welcome-%E2%86%92-ffcb47?labelColor=black&style=for-the-badge +[profile-link]: https://github.com/perfect-panel diff --git a/apps/admin/components.json b/apps/admin/components.json new file mode 100644 index 0000000..5e90ef2 --- /dev/null +++ b/apps/admin/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "../../packages/ui/src/styles/globals.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@workspace/ui/components", + "utils": "@workspace/ui/lib/utils", + "hooks": "@workspace/ui/hooks", + "lib": "@workspace/ui/lib", + "ui": "@workspace/ui/components" + }, + "iconLibrary": "lucide" +} diff --git a/apps/admin/i18next.config.ts b/apps/admin/i18next.config.ts new file mode 100644 index 0000000..ac2b09a --- /dev/null +++ b/apps/admin/i18next.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from "i18next-cli"; + +/** + * i18next CLI configuration + * + * Used for extracting translation keys and managing translation files. + * Inherits language settings from the shared i18n configuration. + * + * @see https://github.com/i18next/i18next-cli + */ +export default defineConfig({ + // Use supported languages from shared config + locales: ["en-US", "zh-CN"], + + // Extraction configuration + extract: { + input: [ + "src/**/*.{js,jsx,ts,tsx}", + "../../packages/ui/src/**/*.{js,jsx,ts,tsx}", + ], // Source files to scan + output: "public/locales/{{language}}/{{namespace}}.json", // Output path template + }, +}); diff --git a/apps/admin/index.html b/apps/admin/index.html new file mode 100644 index 0000000..98d03e5 --- /dev/null +++ b/apps/admin/index.html @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + Loading... + + +
+ + + diff --git a/apps/admin/package.json b/apps/admin/package.json new file mode 100644 index 0000000..e49cbdd --- /dev/null +++ b/apps/admin/package.json @@ -0,0 +1,52 @@ +{ + "name": "ppanel-admin-web", + "private": true, + "type": "module", + "scripts": { + "dev": "vite --port 3001", + "build": "vite build && tsc", + "serve": "vite preview", + "lint": "biome lint", + "check": "biome check", + "i18n:extract": "i18next-cli extract", + "i18n:sync": "i18next-cli sync", + "i18n:status": "i18next-cli status" + }, + "dependencies": { + "@faker-js/faker": "^10.0.0", + "@lottiefiles/dotlottie-react": "^0.17.7", + "@noble/curves": "^2.0.1", + "@stripe/react-stripe-js": "^5.4.0", + "@stripe/stripe-js": "^8.5.2", + "@tailwindcss/vite": "^4.0.6", + "@tanstack/match-sorter-utils": "^8.19.4", + "@tanstack/react-devtools": "^0.7.0", + "@tanstack/react-form": "^1.0.0", + "@tanstack/react-router-devtools": "^1.132.0", + "@tanstack/react-table": "^8.21.2", + "@tanstack/router-plugin": "^1.132.0", + "@workspace/typescript-config": "workspace:*", + "@workspace/ui": "workspace:*", + "ahooks": "^3.9.6", + "date-fns": "^4.1.0", + "framer-motion": "^12.23.24", + "mlkem-wasm": "^0.0.7", + "motion": "^12.23.24", + "qrcode.react": "^4.2.0", + "radash": "^12.1.1", + "react-copy-to-clipboard": "^5.1.0", + "react-helmet-async": "^2.0.5", + "react-turnstile": "^1.1.4", + "zustand": "^5.0.8" + }, + "devDependencies": { + "@tanstack/devtools-vite": "^0.3.11", + "@testing-library/dom": "^10.4.0", + "@testing-library/react": "^16.2.0", + "@vitejs/plugin-react": "^5.0.4", + "jsdom": "^27.0.0", + "vite": "^7.1.7", + "vitest": "^3.0.5", + "web-vitals": "^5.1.0" + } +} diff --git a/apps/admin/public/apple-touch-icon.png b/apps/admin/public/apple-touch-icon.png new file mode 100644 index 0000000..3c0c9bf Binary files /dev/null and b/apps/admin/public/apple-touch-icon.png differ diff --git a/apps/admin/public/favicon.ico b/apps/admin/public/favicon.ico new file mode 100644 index 0000000..171c82e Binary files /dev/null and b/apps/admin/public/favicon.ico differ diff --git a/apps/admin/public/favicon.svg b/apps/admin/public/favicon.svg new file mode 100644 index 0000000..ec5b71a --- /dev/null +++ b/apps/admin/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/admin/public/locales/en-US/ads.json b/apps/admin/public/locales/en-US/ads.json new file mode 100644 index 0000000..710ac41 --- /dev/null +++ b/apps/admin/public/locales/en-US/ads.json @@ -0,0 +1,39 @@ +{ + "cancel": "Cancel", + "confirm": "Confirm", + "confirmDelete": "Confirm Delete", + "create": "Create", + "createAds": "Create Ad", + "createSuccess": "Created successfully", + "delete": "Delete", + "deleteSuccess": "Deleted successfully", + "deleteWarning": "Are you sure you want to delete this ad? This action cannot be undone.", + "disabled": "Disabled", + "edit": "Edit", + "editAds": "Edit Ad", + "enabled": "Enabled", + "form": { + "cancel": "Cancel", + "confirm": "Confirm", + "content": "Content", + "description": "Description", + "endTime": "End Time", + "enterDescription": "Enter description", + "enterEndTime": "Select end time", + "enterStartTime": "Select start time", + "enterTargetUrl": "Enter target URL", + "enterTitle": "Enter title", + "startTime": "Start Time", + "targetUrl": "Target URL", + "title": "Title", + "type": "Type", + "typeImage": "Image", + "typeVideo": "Video" + }, + "status": "Status", + "targetUrl": "Target URL", + "title": "Title", + "type": "Type", + "updateSuccess": "Updated successfully", + "validityPeriod": "Validity Period" +} diff --git a/apps/admin/public/locales/en-US/announcement.json b/apps/admin/public/locales/en-US/announcement.json new file mode 100644 index 0000000..11cafad --- /dev/null +++ b/apps/admin/public/locales/en-US/announcement.json @@ -0,0 +1,30 @@ +{ + "announcementList": "Announcement List", + "cancel": "Cancel", + "confirm": "Confirm", + "confirmDelete": "Confirm Delete", + "content": "Content", + "create": "Create", + "createAnnouncement": "Create Announcement", + "createSuccess": "Created successfully", + "delete": "Delete", + "deleteDescription": "This action cannot be undone.", + "deleteSuccess": "Deleted successfully", + "edit": "Edit", + "editAnnouncement": "Edit Announcement", + "enable": "Enable", + "form": { + "cancel": "Cancel", + "confirm": "Confirm", + "content": "Content", + "title": "Title", + "titlePlaceholder": "Enter title" + }, + "hide": "Hide", + "pinned": "Pinned", + "popup": "Popup", + "show": "Show", + "title": "Title", + "updatedAt": "Updated At", + "updateSuccess": "Updated successfully" +} diff --git a/apps/admin/public/locales/en-US/auth-control.json b/apps/admin/public/locales/en-US/auth-control.json new file mode 100644 index 0000000..d5e9a77 --- /dev/null +++ b/apps/admin/public/locales/en-US/auth-control.json @@ -0,0 +1,179 @@ +{ + "apple": { + "clientId": "Service ID", + "clientIdDescription": "Apple Service ID, available from Apple Developer Portal", + "clientSecret": "Private Key", + "clientSecretDescription": "Private key content (.p8 file) for authenticating with Apple", + "description": "Authenticate users with Apple accounts", + "enable": "Enable", + "enableDescription": "When enabled, users can sign in with their Apple ID", + "keyId": "Key ID", + "keyIdDescription": "Your private key ID from Apple Developer Portal", + "redirectUri": "Redirect URL", + "redirectUriDescription": "API address for redirect URL after successful Apple authentication. Do not end with /", + "teamId": "Team ID", + "teamIdDescription": "Apple Developer Team ID", + "title": "Apple Sign-In" + }, + "common": { + "cancel": "Cancel", + "save": "Save", + "saveFailed": "Save failed", + "saveSuccess": "Saved successfully" + }, + "communicationMethods": "Communication Methods", + "device": { + "blockVirtualMachine": "Block Virtual Machine", + "blockVirtualMachineDescription": "Block virtual machine login, only allow real device", + "communicationKey": "Communication Key", + "communicationKeyDescription": "The key used for secure communication between application and server", + "description": "Authenticate users with device", + "enable": "Enable", + "enableDescription": "When enabled, users can sign in with device", + "enableSecurity": "Enable Security", + "enableSecurityDescription": "When enabled, application requests must carry communication key", + "showAds": "Show Ads", + "showAdsDescription": "When enabled, ads will be shown", + "title": "Device Sign-In" + }, + "deviceAuthMethods": "Device Authentication Methods", + "email": { + "basicSettings": "Basic Settings", + "description": "Configure email authentication and templates", + "emailSuffixWhitelist": "Email Suffix Whitelist", + "emailSuffixWhitelistDescription": "Only allow emails from whitelisted domains", + "emailVerification": "Email Verification", + "emailVerificationDescription": "Require email verification for new users", + "enable": "Enable", + "enableDescription": "When enabled, users can sign in with email", + "expirationEmailTemplate": "Expiration Email Template", + "expirationTemplate": "Expiration Template", + "inputPlaceholder": "Please enter", + "maintenanceEmailTemplate": "Maintenance Email Template", + "maintenanceTemplate": "Maintenance Template", + "senderAddress": "Sender Address", + "senderAddressDescription": "The email address that appears in the From field", + "sendFailure": "Email send failed", + "sendSuccess": "Email sent successfully", + "sendTestEmail": "Send Test Email", + "sendTestEmailDescription": "Send a test email to verify your SMTP configuration", + "smtpAccount": "SMTP Account", + "smtpAccountDescription": "The SMTP authentication username", + "smtpEncryptionMethod": "SSL/TLS Encryption", + "smtpEncryptionMethodDescription": "Enable SSL/TLS encryption for SMTP connection", + "smtpPassword": "SMTP Password", + "smtpPasswordDescription": "The SMTP authentication password", + "smtpServerAddress": "SMTP Server Address", + "smtpServerAddressDescription": "The SMTP server hostname", + "smtpServerPort": "SMTP Server Port", + "smtpServerPortDescription": "The SMTP server port (usually 25, 465, or 587)", + "smtpSettings": "SMTP Settings", + "templateVariables": { + "code": { + "description": "Verification code" + }, + "expire": { + "description": "Code expiration time" + }, + "expireDate": { + "description": "Subscription expiration date" + }, + "maintenanceDate": { + "description": "Maintenance date" + }, + "maintenanceTime": { + "description": "Maintenance time" + }, + "siteLogo": { + "description": "Site logo URL" + }, + "siteName": { + "description": "Site name" + }, + "title": "Template Variables", + "type": { + "conditionalSyntax": "Use conditional syntax to display different content", + "description": "Email type (1: Register, 2: Reset Password)" + } + }, + "title": "Email Settings", + "trafficExceedEmailTemplate": "Traffic Exceed Email Template", + "trafficTemplate": "Traffic Template", + "verifyEmailTemplate": "Verify Email Template", + "verifyTemplate": "Verify Template", + "whitelistSuffixes": "Whitelist Suffixes", + "whitelistSuffixesDescription": "One domain suffix per line", + "whitelistSuffixesPlaceholder": "gmail.com, outlook.com" + }, + "facebook": { + "clientId": "App ID", + "clientIdDescription": "Facebook App ID, available from Facebook Developer Portal", + "clientSecret": "App Secret", + "clientSecretDescription": "Facebook App Secret, available from Facebook Developer Portal", + "description": "Authenticate users with Facebook accounts", + "enable": "Enable", + "enableDescription": "When enabled, users can sign in with their Facebook account", + "title": "Facebook Sign-In" + }, + "github": { + "clientId": "Client ID", + "clientIdDescription": "GitHub OAuth App Client ID, available from GitHub Developer Settings", + "clientSecret": "Client Secret", + "clientSecretDescription": "GitHub OAuth App Client Secret, available from GitHub Developer Settings", + "description": "Authenticate users with GitHub accounts", + "enable": "Enable", + "enableDescription": "When enabled, users can sign in with their GitHub account", + "title": "GitHub Sign-In" + }, + "google": { + "clientId": "Client ID", + "clientIdDescription": "Google OAuth Client ID, available from Google Cloud Console", + "clientSecret": "Client Secret", + "clientSecretDescription": "Google OAuth Client Secret, available from Google Cloud Console", + "description": "Authenticate users with Google accounts", + "enable": "Enable", + "enableDescription": "When enabled, users can sign in with their Google account", + "title": "Google Sign-In" + }, + "phone": { + "accessLabel": "Access Key", + "applyPlatform": "Apply", + "description": "Configure SMS authentication", + "enable": "Enable", + "enableTip": "When enabled, users can sign in with their phone number", + "endpointLabel": "Endpoint", + "phoneNumberLabel": "Phone Number", + "placeholders": { + "template": "Use {{code}} for verification code" + }, + "platform": "SMS Platform", + "platformConfigTip": "Please enter {{key}}", + "platformTip": "Select SMS service provider", + "secretLabel": "Secret Key", + "sendFailed": "SMS send failed", + "sendSuccess": "SMS sent successfully", + "signNameLabel": "Sign Name", + "template": "Template", + "templateCodeLabel": "Template Code", + "templateTip": "Use {{code}} variable for the verification code", + "testSms": "Test SMS", + "testSmsPhone": "Phone number", + "testSmsTip": "Send a test SMS to verify configuration", + "title": "SMS Settings", + "whitelistAreaCode": "Whitelist Area Codes", + "whitelistAreaCodeTip": "Enter area codes separated by commas", + "whitelistValidation": "Whitelist Validation", + "whitelistValidationTip": "Only allow phone numbers with whitelisted area codes" + }, + "socialAuthMethods": "Social Authentication Methods", + "telegram": { + "clientId": "Bot ID", + "clientIdDescription": "Telegram Bot ID, available from @BotFather", + "clientSecret": "Bot Token", + "clientSecretDescription": "Telegram Bot Token, available from @BotFather", + "description": "Authenticate users with Telegram accounts", + "enable": "Enable", + "enableDescription": "When enabled, users can sign in with their Telegram account", + "title": "Telegram Sign-In" + } +} diff --git a/apps/admin/public/locales/en-US/auth.json b/apps/admin/public/locales/en-US/auth.json new file mode 100644 index 0000000..76e61ea --- /dev/null +++ b/apps/admin/public/locales/en-US/auth.json @@ -0,0 +1,38 @@ +{ + "get": "Get Code", + "login": { + "email": "Please enter a valid email address", + "emailPlaceholder": "Enter your email...", + "forgotPassword": "Forgot Password?", + "passwordPlaceholder": "Enter your password...", + "registerAccount": "Register Account", + "success": "Login successful!", + "title": "Login" + }, + "logout": "Logout", + "register": { + "codePlaceholder": "Enter code...", + "email": "Please enter a valid email address", + "emailPlaceholder": "Enter your email...", + "existingAccount": "Already have an account?", + "invite": "Invitation Code (Optional)", + "message": "Registration is currently disabled", + "passwordMismatch": "Passwords do not match", + "passwordPlaceholder": "Enter your password...", + "repeatPasswordPlaceholder": "Enter password again...", + "success": "Registration successful!", + "switchToLogin": "Login", + "title": "Register", + "whitelist": "This email domain is not in the whitelist" + }, + "reset": { + "codePlaceholder": "Enter code...", + "email": "Please enter a valid email address", + "emailPlaceholder": "Enter your email...", + "existingAccount": "Remember your password?", + "passwordPlaceholder": "Enter your new password...", + "success": "Password reset successful!", + "switchToLogin": "Login", + "title": "Reset Password" + } +} diff --git a/apps/admin/public/locales/en-US/components.json b/apps/admin/public/locales/en-US/components.json new file mode 100644 index 0000000..dd65d5a --- /dev/null +++ b/apps/admin/public/locales/en-US/components.json @@ -0,0 +1,65 @@ +{ + "empty": { + "tips": { + "0": "Imagine this space filled with exciting content! For now, you'll have to use your imagination...", + "1": "This area mysteriously disappeared, but we're summoning it back!", + "2": "Oh no, nothing happened... Feel free to fill in the blank!", + "3": "It's like discovering an empty stage at a concert... Why not go up and perform?", + "4": "You've found a blank canvas! How about building a house?", + "5": "This area is currently empty, but creativity starts here!", + "6": "Nothing here... but don't worry, it's just the beginning!", + "7": "This place was supposed to have a big surprise, but the surprise slipped away!", + "8": "There's nothing here for now, like an empty snack cabinet.", + "9": "This empty space is waiting for its protagonist to take the stage!" + } + }, + "error": { + "400": "The request parameters are incorrect, please check and resubmit.", + "401": "Request is too frequent, please try again later.", + "500": "The server is having some issues, please try again later.", + "10001": "Query was not successful, please try again later or check your conditions.", + "10002": "Update operation was not successful, please try again later.", + "10003": "Insert operation cannot be completed at the moment, please try again later.", + "10004": "Deletion operation could not be completed, please try again later.", + "20001": "The user information already exists, please retry with different information.", + "20002": "User not found, please check the information and try again.", + "20003": "Incorrect password, please re-enter.", + "20004": "The user is disabled, please contact customer service if you have questions.", + "20005": "Insufficient balance, please recharge and try again.", + "20006": "The registration function is temporarily unavailable, please try again later.", + "20008": "User information is incorrect, please check and try again.", + "30001": "The node already exists, please do not add it again.", + "30002": "Related node not found, please check and try again.", + "30003": "Group already exists, please try using a different name.", + "30004": "Group not found, please verify the information and try again.", + "30005": "There is still content in the group, please clear it and try again.", + "40002": "Valid Token not found, please log in before retrying.", + "40003": "Current Token is invalid, please reacquire before trying again.", + "40004": "Token has expired, please log in again.", + "40005": "You do not have access permission, please contact the administrator if you have any questions.", + "50001": "Corresponding coupon information not found, please check and try again.", + "50002": "The coupon has been used, cannot be used again.", + "60001": "Subscription has expired, please renew before using.", + "60002": "Unable to use the subscription at the moment, please try again later.", + "60003": "An existing subscription is detected. Please cancel it before proceeding.", + "60004": "Unable to delete at the moment as the subscription has active users.", + "60005": "Single subscription mode has exceeded user limit", + "70001": "Incorrect verification code, please re-enter.", + "80001": "Task was not successfully queued, please try again later.", + "90001": "Please disable DEBUG mode and try again.", + "90015": "This account has reached the limit of sending times today, please try again tomorrow.", + "unknown": "An error occurred in the system, please try again later." + }, + "language": "Language", + "pagination": { + "pageInfo": "Page {{page}} of {{total}}", + "rowsPerPage": "Rows per page" + }, + "theme": { + "dark": "Dark", + "light": "Light", + "system": "System", + "toggle": "Toggle theme" + }, + "unlimited": "unlimited" +} diff --git a/apps/admin/public/locales/en-US/coupon.json b/apps/admin/public/locales/en-US/coupon.json new file mode 100644 index 0000000..a773604 --- /dev/null +++ b/apps/admin/public/locales/en-US/coupon.json @@ -0,0 +1,47 @@ +{ + "amount": "Amount", + "cancel": "Cancel", + "code": "Code", + "confirm": "Confirm", + "confirmDelete": "Are you sure you want to delete?", + "count": "Count", + "create": "Create", + "createCoupon": "Create Coupon", + "createSuccess": "Create Success", + "delete": "Delete", + "deleteSuccess": "Delete Success", + "deleteWarning": "Once deleted, data cannot be recovered. Please proceed with caution.", + "discount": "Discount", + "edit": "Edit", + "editCoupon": "Edit Coupon", + "enable": "Enable", + "form": { + "amountDiscount": "Amount Discount", + "cancel": "Cancel", + "confirm": "Confirm", + "count": "Max Usage Count", + "countPlaceholder": "Max Usage Count (leave blank for no limit)", + "customCouponCode": "Custom Coupon Code", + "customCouponCodePlaceholder": "Custom Coupon Code (leave blank for auto-generation)", + "enterCouponName": "Enter Coupon Name", + "enterValue": "Enter Value", + "expireTime": "Expire Time", + "name": "Name", + "percentageDiscount": "Percentage Discount", + "selectServer": "Select Subscription", + "specifiedServer": "Specified Subscription", + "startTime": "Start Time", + "type": "Coupon Type", + "userLimit": "Max Usage Count per User", + "userLimitPlaceholder": "Max Usage Count per User (leave blank for no limit)" + }, + "name": "Name", + "percentage": "Percentage", + "remainingTimes": "Remaining", + "subscribe": "Subscribe", + "type": "Type", + "unlimited": "Unlimited", + "updateSuccess": "Update Success", + "usedTimes": "Usage Times", + "validityPeriod": "Validity Period" +} diff --git a/apps/admin/public/locales/en-US/dashboard.json b/apps/admin/public/locales/en-US/dashboard.json new file mode 100644 index 0000000..666fd6b --- /dev/null +++ b/apps/admin/public/locales/en-US/dashboard.json @@ -0,0 +1,33 @@ +{ + "billing": { + "description": "Sponsoring helps PPanel to continue releasing updates!", + "title": "Sponsor" + }, + "currentlyOnline": "Currently Online", + "month": "Month", + "monthTraffic": "Month Traffic", + "newPurchase": "New Purchase", + "nodes": "Nodes", + "nodeTraffic": "Node Traffic", + "offline": "Offline", + "online": "Online", + "onlineUsersCount": "Online Users", + "pending": "Pending", + "pendingTickets": "Pending Tickets", + "register": "Register", + "repurchase": "Repurchase", + "revenueTitle": "Revenue Statistics", + "selectTypePlaceholder": "Select Type", + "today": "Today", + "todayTraffic": "Today Traffic", + "total": "Total", + "totalIncome": "Total Income", + "totalServers": "Total Servers", + "traffic": "Traffic", + "trafficRank": "Traffic Rank", + "type": "Type", + "users": "Users", + "userTitle": "User Statistics", + "userTraffic": "User Traffic", + "yesterday": "Yesterday" +} diff --git a/apps/admin/public/locales/en-US/document.json b/apps/admin/public/locales/en-US/document.json new file mode 100644 index 0000000..8ade5d8 --- /dev/null +++ b/apps/admin/public/locales/en-US/document.json @@ -0,0 +1,28 @@ +{ + "cancel": "Cancel", + "confirm": "Confirm", + "confirmDelete": "Confirm Delete", + "create": "Create", + "createDocument": "Create Document", + "createSuccess": "Created successfully", + "delete": "Delete", + "deleteDescription": "Are you sure you want to delete this document? This action cannot be undone.", + "deleteSuccess": "Deleted successfully", + "DocumentList": "Document List", + "edit": "Edit", + "editDocument": "Edit Document", + "form": { + "cancel": "Cancel", + "confirm": "Confirm", + "content": "Content", + "tags": "Tags", + "tagsPlaceholder": "Enter tags", + "title": "Title", + "titlePlaceholder": "Enter document title" + }, + "show": "Show", + "tags": "Tags", + "title": "Title", + "updatedAt": "Updated At", + "updateSuccess": "Updated successfully" +} diff --git a/apps/admin/public/locales/en-US/log.json b/apps/admin/public/locales/en-US/log.json new file mode 100644 index 0000000..57d6b3d --- /dev/null +++ b/apps/admin/public/locales/en-US/log.json @@ -0,0 +1,66 @@ +{ + "column": { + "amount": "Amount", + "balance": "Balance", + "content": "Content", + "date": "Date", + "download": "Download", + "identifier": "Identifier", + "ip": "IP", + "orderNo": "Order No.", + "platform": "Platform", + "remark": "Remark", + "server": "Server", + "serverId": "Server ID", + "status": "Status", + "subject": "Subject", + "subscribe": "Subscribe", + "subscribeId": "Subscribe ID", + "success": "Success", + "time": "Time", + "to": "To", + "total": "Total", + "type": "Type", + "upload": "Upload", + "user": "User", + "userAgent": "User Agent", + "userId": "User ID" + }, + "detail": "Detail", + "failed": "Failed", + "sent": "Sent", + "success": "Success", + "title": { + "balance": "Balance Log", + "commission": "Commission Log", + "email": "Email Log", + "gift": "Gift Log", + "login": "Login Log", + "mobile": "SMS Log", + "register": "Register Log", + "resetSubscribe": "Reset Subscribe Log", + "serverTraffic": "Server Traffic Log", + "subscribe": "Subscribe Log", + "subscribeTraffic": "Subscribe Traffic Log", + "trafficDetails": "Traffic Details" + }, + "type": { + "231": "Auto Reset", + "232": "Advance Reset", + "233": "Paid Reset", + "321": "Recharge", + "322": "Withdraw", + "323": "Payment", + "324": "Refund", + "325": "Reward", + "326": "Admin Adjust", + "331": "Purchase", + "332": "Renewal", + "333": "Refund", + "334": "Withdraw", + "335": "Admin Adjust", + "341": "Increase", + "342": "Reduce" + }, + "unknown": "Unknown" +} diff --git a/apps/admin/public/locales/en-US/marketing.json b/apps/admin/public/locales/en-US/marketing.json new file mode 100644 index 0000000..ee65671 --- /dev/null +++ b/apps/admin/public/locales/en-US/marketing.json @@ -0,0 +1,107 @@ +{ + "additional": "Additional", + "additionalRecipientEmails": "Additional recipient emails", + "additionalRecipients": "Additional Recipients", + "additionalRecipientsDescription": "These emails will receive the broadcast in addition to the user filter above", + "allUsers": "All Users", + "cancel": "Cancel", + "cannotBeEmpty": "cannot be empty", + "completed": "Completed", + "content": "Email Content", + "createAndSendQuotaTasks": "Create and Distribute Quota Tasks", + "createBroadcast": "Create Broadcast", + "createdAt": "Created At", + "createNewEmailBroadcastCampaign": "Create new email broadcast campaign", + "createQuotaTask": "Create Quota Task", + "dailyLimit": "Daily limit must be at least 1", + "dailySendLimit": "Daily Send Limit", + "days": "Days", + "emailAddedToScheduledQueue": "Email added to scheduled send queue", + "emailBroadcast": "Email Broadcast", + "emailBroadcastTaskCreatedSuccessfully": "Email broadcast task created successfully", + "emailBroadcastTasks": "Email Broadcast Tasks", + "emailContent": "Email Content", + "emailInterval": "Email Interval (seconds)", + "emailIntervalMinimum": "Email interval must be at least 0.1 seconds", + "emailMarketing": "Email Marketing", + "emailTaskManager": "Email Task Manager", + "endTime": "End Time", + "enterAmount": "Enter amount", + "enterPercentage": "Enter percentage", + "estimatedRecipients": "Estimated recipients", + "expiredSubscriptionUsersOnly": "Expired subscription users only", + "expiredUsers": "Expired Users", + "failedToCalculateRecipients": "Failed to calculate recipients", + "failedToCreateQuotaTask": "Failed to create quota task", + "failedToStopTask": "Failed to stop task", + "fixedAmount": "Fixed Amount", + "giftAmount": "Gift Amount", + "giftType": "Gift Amount Type", + "includeSubscriptionsValidAfter": "Include subscriptions valid on or after this date", + "includeSubscriptionsValidBefore": "Include subscriptions valid on or before this date", + "includeUsersRegisteredAfter": "Include users registered on or after this date", + "includeUsersRegisteredBefore": "Include users registered on or before this date", + "inProgress": "In Progress", + "intervalTimeBetweenEmails": "Interval time between each email", + "leaveEmptyForImmediateSend": "Leave empty for immediate send", + "maximumNumberPerDay": "Maximum number of emails to send per day", + "no": "No", + "nonSubscribers": "Non-subscribers", + "noSubscriptions": "No Subscriptions", + "noSubscriptionUsersOnly": "No subscription users only", + "noTimeLimit": "No Time Limit", + "notStarted": "Not Started", + "numberOfDaysForTheQuota": "Number of days to extend subscription expiration", + "onePerLine": "one per line", + "percentageAmount": "Percentage Amount", + "percentageAmountDescription": "Gift percentage amount based on current package price", + "pleaseEnter": "Please enter", + "pleaseEnterValidEmailAddresses": "Please enter valid email addresses, one per line", + "pleaseSelectSubscribers": "Please select packages", + "processing": "Processing...", + "progress": "Progress", + "quotaBroadcast": "Quota Distribution", + "quotaDays": "Extend Expiration Days", + "quotaService": "Quota Service", + "quotaTaskCreatedSuccessfully": "Quota task created successfully", + "quotaTaskManager": "Quota Task Manager", + "quotaTasks": "Quota Tasks", + "recipientType": "Recipient Type", + "registrationEndDate": "Registration End Date", + "registrationStartDate": "Registration Start Date", + "resetTraffic": "Reset Traffic", + "resetTrafficDescription": "Whether to reset subscription used traffic", + "scheduledSend": "Schedule Send", + "scheduledSendTimeMustBeLater": "Scheduled send time must be later than current time", + "scheduleSend": "Schedule Send", + "scope": "Send Scope", + "selectSendScope": "Select send scope", + "selectSendTime": "Select send time, leave empty for immediate send", + "selectValidSubscriptionsOnly": "Select currently valid subscriptions only", + "sendFailed": "Send failed, please try again", + "sendNow": "Send Now", + "sendScope": "Send Scope", + "sendScopeDescription": "Choose the user scope for email sending. Select \"Additional emails only\" to send only to the email addresses filled below", + "sendSettings": "Send Settings", + "sendTime": "Send Time", + "specificUsers": "Specific Users", + "specificUsersOnly": "Additional emails only (skip platform users)", + "startTime": "Start Time", + "status": "Status", + "stop": "Stop", + "subject": "Email Subject", + "subscribedUsers": "Subscribed Users", + "subscribedUsersOnly": "Subscribed users only", + "subscribers": "Packages", + "subscriptionCount": "Subscription Count", + "subscriptionValidityEndDate": "Subscription Validity End Date", + "subscriptionValidityStartDate": "Subscription Validity Start Date", + "taskStoppedSuccessfully": "Task stopped successfully", + "timeRange": "Time Range", + "useMarkdownEditor": "Use Markdown editor to write email content with preview functionality", + "users": "users", + "validOnly": "Valid Only", + "viewAndManageEmailBroadcastTasks": "View and manage email broadcast tasks", + "viewAndManageQuotaTasks": "View and manage quota tasks", + "yes": "Yes" +} diff --git a/apps/admin/public/locales/en-US/menu.json b/apps/admin/public/locales/en-US/menu.json new file mode 100644 index 0000000..3ffc716 --- /dev/null +++ b/apps/admin/public/locales/en-US/menu.json @@ -0,0 +1,35 @@ +{ + "ADS Config": "ADS Config", + "Announcement Management": "Announcement Management", + "Auth Control": "Auth Control", + "Balance": "Balance", + "Commerce": "Commerce", + "Commission": "Commission", + "Coupon Management": "Coupon Management", + "Dashboard": "Dashboard", + "Document Management": "Document Management", + "Email": "Email", + "Gift": "Gift", + "Login": "Login", + "Logs & Analytics": "Logs & Analytics", + "Maintenance": "Maintenance", + "Marketing Management": "Marketing Management", + "Mobile": "Mobile", + "Node Management": "Node Management", + "Order Management": "Order Management", + "Payment Config": "Payment Config", + "Product Management": "Product Management", + "Register": "Register", + "Reset Subscribe": "Reset Subscribe", + "Server Management": "Server Management", + "Server Traffic": "Server Traffic", + "Subscribe": "Subscribe", + "Subscribe Config": "Subscribe Config", + "Subscribe Traffic": "Subscribe Traffic", + "System": "System", + "System Config": "System Config", + "Ticket Management": "Ticket Management", + "Traffic Details": "Traffic Details", + "User Management": "User Management", + "Users & Support": "Users & Support" +} diff --git a/apps/admin/public/locales/en-US/nodes.json b/apps/admin/public/locales/en-US/nodes.json new file mode 100644 index 0000000..05ed877 --- /dev/null +++ b/apps/admin/public/locales/en-US/nodes.json @@ -0,0 +1,31 @@ +{ + "address": "Address", + "cancel": "Cancel", + "confirm": "Confirm", + "confirmDeleteDesc": "This action cannot be undone.", + "confirmDeleteTitle": "Delete this node?", + "copied": "Copied", + "copy": "Copy", + "create": "Create", + "created": "Created", + "delete": "Delete", + "deleted": "Deleted", + "drawerCreateTitle": "Create Node", + "drawerEditTitle": "Edit Node", + "edit": "Edit", + "enabled": "Enabled", + "enabled_off": "Disabled", + "enabled_on": "Enabled", + "name": "Name", + "pageTitle": "Nodes", + "port": "Port", + "protocol": "Protocol", + "select_protocol": "Select protocol…", + "select_server": "Select server…", + "server": "Server", + "sorted_success": "Sorted successfully", + "tags": "Tags", + "tags_description": "Permission grouping tag (incl. plan binding and delivery policies).", + "tags_placeholder": "Use Enter or comma (,) to add multiple tags", + "updated": "Updated" +} diff --git a/apps/admin/public/locales/en-US/order.json b/apps/admin/public/locales/en-US/order.json new file mode 100644 index 0000000..39ba88e --- /dev/null +++ b/apps/admin/public/locales/en-US/order.json @@ -0,0 +1,29 @@ +{ + "amount": "Amount", + "couponDiscount": "Coupon Discount", + "discount": "Discount Amount", + "feeAmount": "Fee Amount", + "method": "Payment Method", + "orderNumber": "Order Number", + "status": { + "0": "Status", + "1": "Pending", + "2": "Paid", + "3": "Cancelled", + "4": "Closed", + "5": "Completed" + }, + "subscribe": "Subscribe", + "subscribePrice": "Subscription Price", + "total": "Total", + "tradeNo": "Transaction Number", + "type": { + "0": "Type", + "1": "New Purchase", + "2": "Renewal", + "3": "Reset Traffic", + "4": "Recharge" + }, + "updateTime": "Update Time", + "user": "User" +} diff --git a/apps/admin/public/locales/en-US/payment.json b/apps/admin/public/locales/en-US/payment.json new file mode 100644 index 0000000..59eeda2 --- /dev/null +++ b/apps/admin/public/locales/en-US/payment.json @@ -0,0 +1,39 @@ +{ + "applyForPayment": "Apply for Payment", + "batchDelete": "Batch Delete", + "cancel": "Cancel", + "configPlaceholder": "Please fill in the provided {{field}} configuration", + "confirm": "Confirm", + "confirmDelete": "Confirm Delete", + "copy": "Copy", + "copySuccess": "Copied successfully", + "create": "Add Payment Method", + "createPayment": "Add Payment Method", + "createSuccess": "Created successfully", + "delete": "Delete", + "deleteSuccess": "Deleted successfully", + "deleteWarning": "Are you sure you want to delete this payment method? This action cannot be undone.", + "description": "Description", + "domain": "Domain", + "edit": "Edit", + "editPayment": "Edit Payment Method", + "enable": "Enable", + "feeAmount": "Fixed Amount", + "feePercent": "Fee Percentage", + "fixedFee": "Fixed Amount", + "handlingFee": "Handling Fee", + "icon": "Icon", + "iconPlaceholder": "Enter icon URL", + "name": "Name", + "namePlaceholder": "Enter payment method name", + "nameRequired": "Name is required", + "noFee": "No Fee", + "notify_url": "Notify URL", + "paymentManagement": "Payment Management", + "percentFee": "Percentage", + "platform": "Platform", + "searchPlaceholder": "Enter search terms", + "selectPlatform": "Select Platform", + "submit": "Submit", + "updateSuccess": "Updated successfully" +} diff --git a/apps/admin/public/locales/en-US/product.json b/apps/admin/public/locales/en-US/product.json new file mode 100644 index 0000000..a99f75e --- /dev/null +++ b/apps/admin/public/locales/en-US/product.json @@ -0,0 +1,73 @@ +{ + "cancel": "Cancel", + "confirm": "Confirm", + "confirmDelete": "Are you sure you want to delete?", + "copy": "Copy", + "copySuccess": "Copied successfully", + "create": "Create", + "createSubscribe": "Create Subscription", + "createSuccess": "Create Successful", + "delete": "Delete", + "deleteSuccess": "Delete Successful", + "deleteWarning": "Data cannot be recovered after deletion. Please proceed with caution.", + "deviceLimit": "Device Limit/Unit", + "edit": "Edit", + "editSubscribe": "Edit Subscription", + "form": { + "annualReset": "Annual Reset", + "basic": "Basic", + "cancel": "Cancel", + "confirm": "Confirm", + "Day": "Day", + "deductionRatio": "Automatic/Manual Deduction Configuration", + "deductionRatioDescription": "Used for deduction. By default, the system adopts an automatic calculation algorithm. When a manual ratio is provided, the system calculates proportions based on the time and traffic ratio, ensuring the total equals 100%.", + "description": "Description", + "deviceLimit": "Device Limit", + "discount": "Discount", + "discount_price": "Discount Price", + "discountDescription": "Set discount based on unit price", + "discountPercent": "Discount Percentage", + "Hour": "Hour", + "inventory": "Subscription Limit", + "language": "Language", + "languageDescription": "Leave empty for default without language restriction", + "languagePlaceholder": "Language identifier for the subscription, e.g., en-US, zh-CN", + "Minute": "Minute", + "Month": "Month", + "monthlyReset": "Monthly Reset", + "name": "Name", + "node": "Node", + "nodeGroup": "Node Group", + "nodes": "Nodes", + "noLimit": "No Limit", + "NoLimit": "No Limit", + "noReset": "No Reset", + "pricing": "Pricing", + "purchaseWithDiscount": "Allow Deduction", + "purchaseWithDiscountDescription": "Enable or disable unsubscribe functionality. After activation, the system will perform deduction processing according to the configured rules and proportions, and the remaining value will be returned to the balance", + "quota": "Purchase Limit", + "renewalReset": "Renewal Reset", + "renewalResetDescription": "Reset cycle upon renewal", + "replacement": "Reset Price (per time)", + "resetCycle": "Reset Cycle", + "resetOn1st": "Reset on the 1st", + "selectResetCycle": "Please select a reset cycle", + "selectUnitTime": "Please select a unit of time", + "speedLimit": "Speed Limit ", + "traffic": "Traffic", + "unitPrice": "Unit Price", + "unitTime": "Unit Time", + "Year": "Year" + }, + "inventory": "Subscription Limit", + "language": "Language", + "name": "Name", + "quota": "Purchase Limit/Time", + "replacement": "Reset Price/Time", + "sell": "Sell", + "show": "Display", + "sold": "Subscription Count", + "traffic": "Traffic", + "unitPrice": "Unit Price", + "updateSuccess": "Update Successful" +} diff --git a/apps/admin/public/locales/en-US/servers.json b/apps/admin/public/locales/en-US/servers.json new file mode 100644 index 0000000..57f59e0 --- /dev/null +++ b/apps/admin/public/locales/en-US/servers.json @@ -0,0 +1,156 @@ +{ + "actions": { + "cancel": "Cancel", + "save": "Save" + }, + "address": "Address", + "address_placeholder": "Server address", + "apiHost": "API Host", + "apiHostPlaceholder": "http(s)://example.com", + "bandwidth_placeholder": "Enter bandwidth, leave empty for BBR", + "basic": "Basic Configuration", + "cancel": "Cancel", + "cert_dns_env": "DNS Environment Variables", + "cert_dns_provider": "DNS Provider", + "cert_mode": "Certificate Mode", + "cipher": "Encryption Algorithm", + "city": "City", + "close": "Close", + "confirm": "Confirm", + "confirmDeleteDesc": "This action cannot be undone.", + "confirmDeleteTitle": "Delete this server?", + "congestion_controller": "Congestion Controller", + "connect": "Connect", + "copied": "Copied", + "copy": "Copy", + "copyAndClose": "Copy and Close", + "copyFailed": "Copy failed", + "country": "Country", + "cpu": "CPU", + "create": "Create", + "created": "Created", + "delete": "Delete", + "deleted": "Deleted", + "disable_sni": "Disable SNI", + "disabled": "Disabled", + "disk": "Disk", + "down_mbps": "Download Bandwidth", + "drawerCreateTitle": "Create Server", + "drawerEditTitle": "Edit Server", + "edit": "Edit", + "enabled": "Enabled", + "encryption": "Encryption", + "encryption_client_padding": "Client Padding", + "encryption_mode": "Mode", + "encryption_password": "Password", + "encryption_password_placeholder": "Leave empty for auto-generation", + "encryption_private_key": "Private Key", + "encryption_private_key_placeholder": "Leave empty for auto-generation", + "encryption_rtt": "RTT", + "encryption_server_padding": "Server Padding", + "encryption_ticket": "Ticket Time", + "expired": "Expired", + "expireTime": "Expire Time", + "extra": "Extra", + "flow": "Flow", + "generate_quantum_resistant_key": "Generate Quantum-Resistant Key", + "generate_standard_encryption_key": "Generate Standard Key", + "hop_interval": "Hop Interval", + "hop_ports": "Hop Ports", + "hop_ports_placeholder": "e.g. 1-65535", + "host": "Host", + "id": "ID", + "installCommand": "Install command", + "ipAddresses": "IP Addresses", + "memory": "Memory", + "mode": "Mode", + "multiplex": "Multiplex", + "name": "Name", + "notAvailable": "Not Available", + "obfs": "Obfuscation", + "obfs_password": "Obfuscation Password", + "obfs_password_placeholder": "Enter obfuscation password", + "offline": "Offline", + "oneClickInstall": "One-click Install", + "online": "Online", + "onlineUsers": "Online Users", + "padding_scheme": "Padding Scheme", + "padding_scheme_placeholder": "One padding rule per line, format: stop=8, 0=30-30", + "pageTitle": "Servers", + "path": "Path", + "port": "Port", + "protocol_configurations": "Protocol Configurations", + "protocol_configurations_desc": "Enable and configure the required protocol types", + "protocols": "Protocols", + "reality": "Reality", + "reduce_rtt": "Reduce RTT", + "security": "Security", + "security_allow_insecure": "Allow Insecure", + "security_fingerprint": "Fingerprint", + "security_private_key": "Reality Private Key", + "security_private_key_placeholder": "Enter private key", + "security_public_key": "Reality Public Key", + "security_public_key_placeholder": "Enter public key", + "security_server_address": "Reality Server Address", + "security_server_address_placeholder": "e.g. 1.2.3.4 or domain", + "security_server_port": "Reality Server Port", + "security_short_id": "Reality Short ID", + "security_sni": "SNI", + "server_config": { + "description": "Manage node communication keys, pull/push intervals.", + "dynamic_multiplier": "Dynamic multiplier", + "dynamic_multiplier_desc": "Define time slots and multipliers to adjust traffic accounting.", + "fields": { + "block_rules_placeholder": "One domain rule per line", + "communication_key": "Communication key", + "communication_key_desc": "Used for node authentication.", + "communication_key_placeholder": "Please enter", + "dns_config": "DNS Configuration", + "dns_domains_placeholder": "One domain rule per line", + "dns_proto_placeholder": "Select type", + "end_time": "End time", + "ip_strategy": "IP Strategy", + "ip_strategy_desc": "Choose IP version preference for network connections", + "ip_strategy_ipv4": "Prefer IPv4", + "ip_strategy_ipv6": "Prefer IPv6", + "ip_strategy_placeholder": "Select IP strategy", + "multiplier": "Multiplier", + "node_pull_interval": "Node pull interval", + "node_pull_interval_desc": "How often the node pulls configuration (seconds).", + "node_push_interval": "Node push interval", + "node_push_interval_desc": "How often the node pushes stats (seconds).", + "outbound_address_placeholder": "Server address", + "outbound_name_placeholder": "Configuration name", + "outbound_password_placeholder": "Password (optional)", + "outbound_port_placeholder": "Port number", + "outbound_protocol_placeholder": "Select protocol", + "outbound_rules_placeholder": "One rule per line", + "reset": "Reset", + "start_time": "Start time", + "traffic_report_threshold": "Traffic Report Threshold", + "traffic_report_threshold_desc": "Set the minimum threshold for traffic reporting." + }, + "saveSuccess": "Saved successfully", + "tabs": { + "basic": "Basic Configuration", + "block": "Block Rules", + "dns": "DNS Configuration", + "outbound": "Outbound Rules" + }, + "title": "Node configuration" + }, + "server_key": "Server Key", + "service_name": "Service Name", + "sorted_success": "Sorted successfully", + "status": "Status", + "subscribeId": "Subscribe ID", + "subscription": "Subscription", + "traffic": "Traffic", + "traffic_ratio": "Ratio", + "transport": "Transport", + "udp_relay_mode": "UDP Relay Mode", + "unlimited": "Unlimited", + "up_mbps": "Upload Bandwidth", + "updated": "Updated", + "user": "User" +} diff --git a/apps/admin/public/locales/en-US/subscribe.json b/apps/admin/public/locales/en-US/subscribe.json new file mode 100644 index 0000000..526e36d --- /dev/null +++ b/apps/admin/public/locales/en-US/subscribe.json @@ -0,0 +1,121 @@ +{ + "actions": { + "add": "Add", + "batchDelete": "Batch Delete", + "batchDeleteSuccess_one": "Successfully deleted {count} clients", + "batchDeleteSuccess_other": "Successfully deleted {count} clients", + "batchDeleteWarning_one": "Are you sure you want to delete the selected {count} clients?", + "batchDeleteWarning_other": "Are you sure you want to delete the selected {count} clients?", + "cancel": "Cancel", + "confirm": "Confirm", + "confirmDelete": "Confirm Delete", + "createSuccess": "Created successfully", + "delete": "Delete", + "deleteFailed": "Delete failed", + "deleteSuccess": "Deleted successfully", + "deleteWarning": "This operation cannot be undone. Are you sure you want to delete this client?", + "edit": "Edit", + "save": "Save", + "saveFailed": "Save failed", + "update": "Update", + "updateSuccess": "Updated successfully" + }, + "config": { + "description": "Manage subscription system settings", + "singleSubscriptionMode": "Single Subscription Mode", + "singleSubscriptionModeDescription": "Limit users to one active subscription. Existing subscriptions unaffected", + "subscriptionDomain": "Subscription Domain", + "subscriptionDomainDescription": "Custom domain for subscription links", + "subscriptionDomainPlaceholder": "Enter subscription domain, one per line", + "subscriptionPath": "Subscription Path", + "subscriptionPathDescription": "Custom path for subscription endpoints (better performance after system restart)", + "subscriptionPathPlaceholder": "Enter subscription path", + "title": "Subscription Configuration", + "updateError": "Update failed", + "updateSuccess": "Settings updated successfully", + "userAgentLimit": "{userAgent} Restriction", + "userAgentLimitDescription": "Enable access restrictions based on {userAgent}", + "userAgentList": "{userAgent} Whitelist", + "userAgentListDescription": "Allowed {userAgent} for subscription access, one per line. Configured application {userAgent} will be automatically included", + "userAgentListPlaceholder": "Enter allowed {userAgent}, one per line", + "wildcardResolution": "Wildcard Resolution", + "wildcardResolutionDescription": "Enable wildcard domain resolution for subscriptions" + }, + "form": { + "addTitle": "Add Client", + "descriptions": { + "description": "Detailed client description", + "downloadLink": "platform download URL", + "icon": "Icon URL or base64 encoding", + "name": "Client display name", + "outputFormat": "Subscription configuration file format", + "scheme": { + "base64Encoding": "Base64 encoding", + "functions": "Supports functions:", + "jsonStringify": "JSON object to string", + "nameVariable": "site name", + "title": "URL Scheme template", + "urlEncoding": "URL encoding", + "urlVariable": "subscription URL", + "variables": "Supports variables:" + }, + "template": { + "functions": "Template functions:", + "if": "conditional statements", + "nodes": "proxy nodes list", + "range": "iterate arrays", + "siteName": "site name", + "sprig": "Sprig function library (string processing, dates, etc.)", + "subscribeName": "subscription name", + "title": "Go Template Syntax", + "userInfo": "user info (traffic, expiry, etc.)", + "variables": "Available variables:" + }, + "userAgentPrefix": "Client identifier for distinguishing different clients" + }, + "editTitle": "Edit Client", + "fields": { + "description": "Description", + "icon": "Icon", + "name": "Name", + "outputFormat": "Output Format", + "scheme": "URL Scheme", + "template": "Subscription File Template" + }, + "tabs": { + "basic": "Basic Info", + "download": "Downloads", + "template": "Templates" + } + }, + "outputFormats": { + "base64": "Base64", + "conf": "CONF", + "json": "JSON", + "plain": "Plain Text", + "yaml": "YAML" + }, + "protocol": { + "title": "Client Management" + }, + "table": { + "columns": { + "default": "Default", + "description": "Description", + "name": "Client Name", + "outputFormat": "Output Format", + "supportedPlatforms": "Supported Platforms" + } + }, + "templatePreview": { + "base64": { + "decodedContent": "Decoded Content", + "decodeError": "Base64 decode error", + "originalContent": "Original Content" + }, + "failed": "Failed to load template", + "loading": "Loading...", + "preview": "Preview", + "title": "Template Preview" + } +} diff --git a/apps/admin/public/locales/en-US/system.json b/apps/admin/public/locales/en-US/system.json new file mode 100644 index 0000000..1bcd0fe --- /dev/null +++ b/apps/admin/public/locales/en-US/system.json @@ -0,0 +1,136 @@ +{ + "basicSettings": "Basic Settings", + "common": { + "cancel": "Cancel", + "save": "Save Settings", + "saveFailed": "Save Failed", + "saveSuccess": "Save Successful" + }, + "currency": { + "accessKey": "API Key", + "accessKeyDescription": "Free exchange rate API key provided by {{url}}", + "accessKeyPlaceholder": "Enter API key", + "currencySymbol": "Currency Symbol", + "currencySymbolDescription": "Used for display purposes only; changing this will affect all currency units in the system", + "currencySymbolPlaceholder": "$", + "currencyUnit": "Currency Unit", + "currencyUnitDescription": "Used for display purposes only; changing this will affect all currency units in the system", + "currencyUnitPlaceholder": "USD", + "description": "Configure currency units, symbols, and exchange rate API settings", + "title": "Currency Configuration" + }, + "invite": { + "description": "Configure user invitation and referral reward settings", + "forcedInvite": "Require Invitation to Register", + "forcedInviteDescription": "When enabled, users must register through an invitation link", + "inputPlaceholder": "Please enter", + "onlyFirstPurchase": "First Purchase Reward Only", + "onlyFirstPurchaseDescription": "When enabled, referrers only receive rewards for the first purchase by referred users", + "referralPercentage": "Referral Reward Percentage", + "referralPercentageDescription": "Percentage of reward given to referrers", + "saveFailed": "Save Failed", + "saveSuccess": "Save Successful", + "title": "Invitation Settings" + }, + "logCleanup": { + "autoClear": "Enable Auto Cleanup", + "autoClearDescription": "When enabled, the system will automatically clear expired log records", + "clearDays": "Retention Days", + "clearDaysDescription": "Number of days to retain logs; logs older than this will be cleaned up", + "clearDaysPlaceholder": "Enter retention days", + "description": "Configure automatic log cleanup rules and retention period", + "title": "Log Cleanup Settings" + }, + "logSettings": "Log Settings", + "privacyPolicy": { + "description": "Edit and manage privacy policy content", + "title": "Privacy Policy" + }, + "register": { + "day": "Day(s)", + "description": "Configure user registration related settings", + "enableTrial": "Enable Trial", + "enableTrialDescription": "When enabled, new users will receive a trial subscription upon registration", + "hour": "Hour(s)", + "inputPlaceholder": "Please enter", + "ipRegistrationLimit": "IP Registration Limit", + "ipRegistrationLimitDescription": "Limit the number of registrations from a single IP address", + "minute": "Minute(s)", + "month": "Month(s)", + "none": "None", + "registrationLimitCount": "Registration Limit Count", + "registrationLimitCountDescription": "Number of registrations allowed per IP within the limit period", + "registrationLimitExpire": "Limit Period", + "registrationLimitExpireDescription": "Duration for IP registration limit (minutes)", + "saveFailed": "Save Failed", + "saveSuccess": "Save Successful", + "selectPlaceholder": "Please select", + "stopNewUserRegistration": "Stop New User Registration", + "stopNewUserRegistrationDescription": "When enabled, new user registration will be disabled", + "title": "Registration Settings", + "trialConfig": "Trial Configuration", + "trialConfigDescription": "Configure trial subscription, duration and time unit for new users upon registration", + "year": "Year(s)" + }, + "site": { + "customData": "Custom Data", + "customDataDescription": "Custom data for website customization", + "customHtml": "Custom HTML", + "customHtmlDescription": "Custom HTML code to be injected into the bottom of the site's body tag", + "description": "Configure basic site information, logo, domain and other settings", + "keywords": "Keywords", + "keywordsDescription": "Used for SEO purposes", + "keywordsPlaceholder": "keyword1, keyword2, keyword3", + "logo": "Site Logo", + "logoDescription": "Used for displaying the logo in designated locations", + "logoPlaceholder": "Enter the URL of the logo, without ending with '/'", + "siteDesc": "Site Description", + "siteDescDescription": "Used for displaying the site description in designated locations", + "siteDescPlaceholder": "Enter site description", + "siteDomain": "Site Domain", + "siteDomainDescription": "Domain address of the current website, e.g., used in emails", + "siteDomainPlaceholder": "Please enter the domain address. For multiple domains, please enter one per line.", + "siteName": "Site Name", + "siteNameDescription": "Used for displaying the site name in designated locations", + "siteNamePlaceholder": "Enter site name", + "title": "Site Configuration" + }, + "tos": { + "description": "Edit and manage terms of service content", + "title": "Terms of Service" + }, + "userSecuritySettings": "User & Security", + "verify": { + "description": "Configure Turnstile CAPTCHA and verification settings", + "enableLoginVerify": "Enable Verification on Login", + "enableLoginVerifyDescription": "When enabled, users must pass human verification during login", + "enablePasswordVerify": "Enable Verification on Password Reset", + "enablePasswordVerifyDescription": "When enabled, users must pass human verification during password reset", + "enableRegisterVerify": "Enable Verification on Registration", + "enableRegisterVerifyDescription": "When enabled, users must pass human verification during registration", + "saveFailed": "Save Failed", + "saveSuccess": "Save Successful", + "title": "Security Verification", + "turnstileSecret": "Turnstile Secret Key", + "turnstileSecretDescription": "Cloudflare Turnstile secret key for backend verification", + "turnstileSecretPlaceholder": "Enter Turnstile secret key", + "turnstileSiteKey": "Turnstile Site Key", + "turnstileSiteKeyDescription": "Cloudflare Turnstile site key for frontend verification", + "turnstileSiteKeyPlaceholder": "Enter Turnstile site key" + }, + "verifyCode": { + "dailyLimit": "Daily Sending Limit", + "dailyLimitDescription": "Maximum number of verification codes each user can send per day", + "description": "Configure email verification code sending rules and limits", + "expireTime": "Verification Code Validity", + "expireTimeDescription": "Validity period of verification codes (seconds)", + "inputPlaceholder": "Please enter", + "interval": "Sending Interval", + "intervalDescription": "Minimum interval between two verification code sends (seconds)", + "saveFailed": "Save Failed", + "saveSuccess": "Save Successful", + "seconds": "seconds", + "times": "time(s)", + "title": "Verification Code Settings" + } +} diff --git a/apps/admin/public/locales/en-US/ticket.json b/apps/admin/public/locales/en-US/ticket.json new file mode 100644 index 0000000..34e4c7e --- /dev/null +++ b/apps/admin/public/locales/en-US/ticket.json @@ -0,0 +1,22 @@ +{ + "cancel": "Cancel", + "check": "Check", + "close": "Close", + "closeSuccess": "Closed successfully", + "closeWarning": "Once closed, the ticket cannot be operated on. Please proceed with caution.", + "confirm": "Confirm", + "confirmClose": "Are you sure you want to close?", + "inputPlaceholder": "Please enter your question, we will reply as soon as possible.", + "reply": "Reply", + "status": { + "0": "Status", + "1": "Pending Follow-up", + "2": "Pending Reply", + "3": "Resolved", + "4": "Closed" + }, + "ticketList": "Ticket List", + "title": "Title", + "updatedAt": "Updated At", + "user": "User" +} diff --git a/apps/admin/public/locales/en-US/tool.json b/apps/admin/public/locales/en-US/tool.json new file mode 100644 index 0000000..70e3a25 --- /dev/null +++ b/apps/admin/public/locales/en-US/tool.json @@ -0,0 +1,14 @@ +{ + "cancel": "Cancel", + "confirmReboot": "Confirm Reboot", + "confirmSystemReboot": "Confirm System Reboot", + "newVersionAvailable": "New Version Available", + "rebootDescription": "Are you sure you want to reboot the system? This action cannot be undone.", + "rebooting": "Rebooting...", + "refreshLogs": "Refresh Logs", + "serverVersion": "Server Version", + "systemLogs": "System Logs", + "systemReboot": "System Reboot", + "systemServices": "System Services", + "webVersion": "Web Version" +} diff --git a/apps/admin/public/locales/en-US/translation.json b/apps/admin/public/locales/en-US/translation.json new file mode 100644 index 0000000..d8c04fb --- /dev/null +++ b/apps/admin/public/locales/en-US/translation.json @@ -0,0 +1,16 @@ +{ + "errors": { + "nameRequired": "Please enter a name", + "portRange": "Port must be between 1 and 65535", + "protocolRequired": "Please select a protocol", + "serverAddrRequired": "Please enter an entry address", + "serverRequired": "Please select a server" + }, + "form": { + "validation": { + "nameRequired": "Client name is required", + "userAgentRequiredSuffix": "is required" + } + }, + "tos": "tos" +} diff --git a/apps/admin/public/locales/en-US/user.json b/apps/admin/public/locales/en-US/user.json new file mode 100644 index 0000000..f5a55e7 --- /dev/null +++ b/apps/admin/public/locales/en-US/user.json @@ -0,0 +1,108 @@ +{ + "accountEnable": "Account Enable", + "add": "Add", + "administrator": "Administrator", + "areaCodePlaceholder": "Area code", + "authMethodsTitle": "Auth Methods", + "avatar": "Avatar", + "balance": "Balance", + "balanceLogs": "Balance Logs", + "balanceNotifications": "Balance Notifications", + "balancePlaceholder": "Enter balance", + "basicInfoTitle": "Basic Info", + "cancel": "Cancel", + "commission": "Commission", + "commissionLogs": "Commission Logs", + "commissionPlaceholder": "Enter commission", + "confirm": "Confirm", + "confirmDelete": "Confirm Delete", + "confirmOffline": "Confirm Offline", + "copySubscription": "Copy Subscription", + "copySuccess": "Copied successfully", + "create": "Create", + "createdAt": "Created At", + "createSubscription": "Create Subscription", + "createSuccess": "Created successfully", + "createUser": "Create User", + "delete": "Delete", + "deleteDescription": "This action cannot be undone.", + "deleteSubscriptionDescription": "This action cannot be undone.", + "deleteSuccess": "Deleted successfully", + "deviceLimit": "Device Limit", + "download": "Download", + "downloadTraffic": "Download Traffic", + "edit": "Edit", + "editSubscription": "Edit Subscription", + "enable": "Enable", + "expiredAt": "Expired At", + "expireTime": "expireTime", + "giftAmount": "Gift Amount", + "giftAmountPlaceholder": "Enter gift amount", + "giftLogs": "Gift Logs", + "invalidEmailFormat": "Invalid email format", + "inviteCode": "Invite Code", + "inviteCodePlaceholder": "Enter invite code", + "kickOfflineConfirm": "kickOfflineConfirm", + "kickOfflineSuccess": "Device kicked offline", + "lastSeen": "Last Seen", + "loading": "Loading...", + "loginLogs": "Login Logs", + "loginNotifications": "Login Notifications", + "loginStatus": "Login Status", + "manager": "Administrator", + "more": "More", + "notifySettingsTitle": "Notify Settings", + "offline": "Offline", + "online": "Online", + "onlineDevices": "Online Devices", + "onlyFirstPurchase": "First Purchase Only", + "orderList": "Order List", + "password": "Password", + "passwordPlaceholder": "Enter password", + "permanent": "Permanent", + "pleaseEnterEmail": "Enter email", + "referer": "Referer", + "refererId": "Referer ID", + "refererIdPlaceholder": "Enter referer ID", + "referralCode": "Referral Code", + "referralPercentage": "Referral Percentage", + "referralPercentagePlaceholder": "Enter percentage", + "referrerUserId": "Referrer User ID", + "remove": "Remove", + "resetLogs": "Reset Logs", + "resetTime": "Reset Time", + "save": "Save", + "speedLimit": "Speed Limit", + "startTime": "startTime", + "subscription": "Subscription", + "subscriptionId": "subscriptionId", + "subscriptionInfo": "subscriptionInfo", + "subscriptionList": "Subscription List", + "subscriptionLogs": "Subscription Logs", + "subscriptionName": "subscriptionName", + "subscriptionNotifications": "Subscription Notifications", + "telephone": "Phone", + "telephonePlaceholder": "Enter phone number", + "token": "token", + "totalTraffic": "Total Traffic", + "tradeNotifications": "Trade Notifications", + "trafficDetails": "Traffic Details", + "trafficLimit": "Traffic Limit", + "trafficStats": "Traffic Stats", + "trafficUsage": "trafficUsage", + "unlimited": "unlimited", + "unverified": "Unverified", + "update": "Update", + "updateSuccess": "Updated successfully", + "upload": "Upload", + "uploadTraffic": "Upload Traffic", + "userAgent": "User Agent", + "userEmail": "Email", + "userEmailPlaceholder": "Enter email", + "userId": "userId", + "userInfo": "userInfo", + "userList": "User List", + "userName": "Username", + "userProfile": "User Profile", + "verified": "Verified" +} diff --git a/apps/admin/public/locales/zh-CN/ads.json b/apps/admin/public/locales/zh-CN/ads.json new file mode 100644 index 0000000..7bc1172 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/ads.json @@ -0,0 +1,39 @@ +{ + "cancel": "取消", + "confirm": "确认", + "confirmDelete": "确认删除", + "create": "创建", + "createAds": "创建广告", + "createSuccess": "创建成功", + "delete": "删除", + "deleteSuccess": "删除成功", + "deleteWarning": "确定要删除此广告吗?此操作无法撤销。", + "disabled": "已禁用", + "edit": "编辑", + "editAds": "编辑广告", + "enabled": "已启用", + "form": { + "cancel": "取消", + "confirm": "确认", + "content": "内容", + "description": "描述", + "endTime": "结束时间", + "enterDescription": "输入描述", + "enterEndTime": "选择结束时间", + "enterStartTime": "选择开始时间", + "enterTargetUrl": "输入目标链接", + "enterTitle": "输入标题", + "startTime": "开始时间", + "targetUrl": "目标链接", + "title": "标题", + "type": "类型", + "typeImage": "图片", + "typeVideo": "视频" + }, + "status": "状态", + "targetUrl": "目标链接", + "title": "标题", + "type": "类型", + "updateSuccess": "更新成功", + "validityPeriod": "有效期" +} diff --git a/apps/admin/public/locales/zh-CN/announcement.json b/apps/admin/public/locales/zh-CN/announcement.json new file mode 100644 index 0000000..8e64c33 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/announcement.json @@ -0,0 +1,30 @@ +{ + "announcementList": "公告列表", + "cancel": "取消", + "confirm": "确认", + "confirmDelete": "确认删除", + "content": "内容", + "create": "创建", + "createAnnouncement": "创建公告", + "createSuccess": "创建成功", + "delete": "删除", + "deleteDescription": "此操作无法撤销。", + "deleteSuccess": "删除成功", + "edit": "编辑", + "editAnnouncement": "编辑公告", + "enable": "启用", + "form": { + "cancel": "取消", + "confirm": "确认", + "content": "内容", + "title": "标题", + "titlePlaceholder": "输入标题" + }, + "hide": "隐藏", + "pinned": "置顶", + "popup": "弹窗", + "show": "显示", + "title": "标题", + "updatedAt": "更新时间", + "updateSuccess": "更新成功" +} diff --git a/apps/admin/public/locales/zh-CN/auth-control.json b/apps/admin/public/locales/zh-CN/auth-control.json new file mode 100644 index 0000000..a25dbb9 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/auth-control.json @@ -0,0 +1,179 @@ +{ + "apple": { + "clientId": "服务 ID", + "clientIdDescription": "Apple 服务 ID,可从 Apple 开发者门户获取", + "clientSecret": "私钥", + "clientSecretDescription": "用于 Apple 身份验证的私钥内容(.p8 文件)", + "description": "使用 Apple 账户验证用户身份", + "enable": "启用", + "enableDescription": "启用后,用户可以使用 Apple ID 登录", + "keyId": "密钥 ID", + "keyIdDescription": "Apple 开发者门户中的私钥 ID", + "redirectUri": "重定向 URL", + "redirectUriDescription": "Apple 认证成功后重定向 URL 的 API 地址,不要以 / 结尾", + "teamId": "团队 ID", + "teamIdDescription": "Apple 开发者团队 ID", + "title": "Apple 登录" + }, + "common": { + "cancel": "取消", + "save": "保存", + "saveFailed": "保存失败", + "saveSuccess": "保存成功" + }, + "communicationMethods": "通讯方式", + "device": { + "blockVirtualMachine": "阻止虚拟机", + "blockVirtualMachineDescription": "阻止虚拟机登录,只允许真实设备", + "communicationKey": "通讯密钥", + "communicationKeyDescription": "用于应用程序与服务器之间安全通信的密钥", + "description": "使用设备验证用户身份", + "enable": "启用", + "enableDescription": "启用后,用户可以使用设备登录", + "enableSecurity": "启用安全验证", + "enableSecurityDescription": "启用后,应用请求必须携带通讯密钥", + "showAds": "显示广告", + "showAdsDescription": "启用后,将显示广告", + "title": "设备登录" + }, + "deviceAuthMethods": "设备认证方式", + "email": { + "basicSettings": "基本设置", + "description": "配置邮箱认证和模板", + "emailSuffixWhitelist": "邮箱后缀白名单", + "emailSuffixWhitelistDescription": "只允许来自白名单域名的邮箱", + "emailVerification": "邮箱验证", + "emailVerificationDescription": "新用户需要邮箱验证", + "enable": "启用", + "enableDescription": "启用后,用户可以使用邮箱登录", + "expirationEmailTemplate": "到期邮件模板", + "expirationTemplate": "到期模板", + "inputPlaceholder": "请输入", + "maintenanceEmailTemplate": "维护邮件模板", + "maintenanceTemplate": "维护模板", + "senderAddress": "发件人地址", + "senderAddressDescription": "显示在发件人字段中的邮箱地址", + "sendFailure": "邮件发送失败", + "sendSuccess": "邮件发送成功", + "sendTestEmail": "发送测试邮件", + "sendTestEmailDescription": "发送测试邮件以验证您的 SMTP 配置", + "smtpAccount": "SMTP 账户", + "smtpAccountDescription": "SMTP 认证用户名", + "smtpEncryptionMethod": "SSL/TLS 加密", + "smtpEncryptionMethodDescription": "为 SMTP 连接启用 SSL/TLS 加密", + "smtpPassword": "SMTP 密码", + "smtpPasswordDescription": "SMTP 认证密码", + "smtpServerAddress": "SMTP 服务器地址", + "smtpServerAddressDescription": "SMTP 服务器主机名", + "smtpServerPort": "SMTP 服务器端口", + "smtpServerPortDescription": "SMTP 服务器端口(通常为 25、465 或 587)", + "smtpSettings": "SMTP 设置", + "templateVariables": { + "code": { + "description": "验证码" + }, + "expire": { + "description": "验证码过期时间" + }, + "expireDate": { + "description": "订阅到期日期" + }, + "maintenanceDate": { + "description": "维护日期" + }, + "maintenanceTime": { + "description": "维护时间" + }, + "siteLogo": { + "description": "网站 Logo URL" + }, + "siteName": { + "description": "网站名称" + }, + "title": "模板变量", + "type": { + "conditionalSyntax": "使用条件语法显示不同内容", + "description": "邮件类型(1:注册,2:重置密码)" + } + }, + "title": "邮箱设置", + "trafficExceedEmailTemplate": "流量超额邮件模板", + "trafficTemplate": "流量模板", + "verifyEmailTemplate": "验证邮件模板", + "verifyTemplate": "验证模板", + "whitelistSuffixes": "白名单后缀", + "whitelistSuffixesDescription": "每行一个域名后缀", + "whitelistSuffixesPlaceholder": "gmail.com, outlook.com" + }, + "facebook": { + "clientId": "应用 ID", + "clientIdDescription": "Facebook 应用 ID,可从 Facebook 开发者门户获取", + "clientSecret": "应用密钥", + "clientSecretDescription": "Facebook 应用密钥,可从 Facebook 开发者门户获取", + "description": "使用 Facebook 账户验证用户身份", + "enable": "启用", + "enableDescription": "启用后,用户可以使用 Facebook 账户登录", + "title": "Facebook 登录" + }, + "github": { + "clientId": "客户端 ID", + "clientIdDescription": "GitHub OAuth 应用客户端 ID,可从 GitHub 开发者设置获取", + "clientSecret": "客户端密钥", + "clientSecretDescription": "GitHub OAuth 应用客户端密钥,可从 GitHub 开发者设置获取", + "description": "使用 GitHub 账户验证用户身份", + "enable": "启用", + "enableDescription": "启用后,用户可以使用 GitHub 账户登录", + "title": "GitHub 登录" + }, + "google": { + "clientId": "客户端 ID", + "clientIdDescription": "Google OAuth 客户端 ID,可从 Google Cloud 控制台获取", + "clientSecret": "客户端密钥", + "clientSecretDescription": "Google OAuth 客户端密钥,可从 Google Cloud 控制台获取", + "description": "使用 Google 账户验证用户身份", + "enable": "启用", + "enableDescription": "启用后,用户可以使用 Google 账户登录", + "title": "Google 登录" + }, + "phone": { + "accessLabel": "访问密钥", + "applyPlatform": "申请", + "description": "配置短信认证", + "enable": "启用", + "enableTip": "启用后,用户可以使用手机号登录", + "endpointLabel": "端点", + "phoneNumberLabel": "手机号", + "placeholders": { + "template": "使用 {{code}} 表示验证码" + }, + "platform": "短信平台", + "platformConfigTip": "请输入 {{key}}", + "platformTip": "选择短信服务提供商", + "secretLabel": "密钥", + "sendFailed": "短信发送失败", + "sendSuccess": "短信发送成功", + "signNameLabel": "签名", + "template": "模板", + "templateCodeLabel": "模板代码", + "templateTip": "使用 {{code}} 变量表示验证码", + "testSms": "测试短信", + "testSmsPhone": "手机号", + "testSmsTip": "发送测试短信以验证配置", + "title": "短信设置", + "whitelistAreaCode": "区号白名单", + "whitelistAreaCodeTip": "输入区号,用逗号分隔", + "whitelistValidation": "白名单验证", + "whitelistValidationTip": "只允许白名单区号的手机号" + }, + "socialAuthMethods": "社交账号认证方式", + "telegram": { + "clientId": "机器人 ID", + "clientIdDescription": "Telegram 机器人 ID,可从 @BotFather 获取", + "clientSecret": "机器人令牌", + "clientSecretDescription": "Telegram 机器人令牌,可从 @BotFather 获取", + "description": "使用 Telegram 账户验证用户身份", + "enable": "启用", + "enableDescription": "启用后,用户可以使用 Telegram 账户登录", + "title": "Telegram 登录" + } +} diff --git a/apps/admin/public/locales/zh-CN/auth.json b/apps/admin/public/locales/zh-CN/auth.json new file mode 100644 index 0000000..2c5163e --- /dev/null +++ b/apps/admin/public/locales/zh-CN/auth.json @@ -0,0 +1,38 @@ +{ + "get": "获取验证码", + "login": { + "email": "请输入有效的邮箱地址", + "emailPlaceholder": "输入您的邮箱...", + "forgotPassword": "忘记密码?", + "passwordPlaceholder": "输入您的密码...", + "registerAccount": "注册账号", + "success": "登录成功!", + "title": "登录" + }, + "logout": "退出登录", + "register": { + "codePlaceholder": "输入验证码...", + "email": "请输入有效的邮箱地址", + "emailPlaceholder": "输入您的邮箱...", + "existingAccount": "已有账号?", + "invite": "邀请码(可选)", + "message": "注册功能暂时不可用", + "passwordMismatch": "两次密码输入不一致", + "passwordPlaceholder": "输入您的密码...", + "repeatPasswordPlaceholder": "再次输入密码...", + "success": "注册成功!", + "switchToLogin": "登录", + "title": "注册", + "whitelist": "该邮箱域名不在白名单中" + }, + "reset": { + "codePlaceholder": "输入验证码...", + "email": "请输入有效的邮箱地址", + "emailPlaceholder": "输入您的邮箱...", + "existingAccount": "记得密码了?", + "passwordPlaceholder": "输入您的新密码...", + "success": "密码重置成功!", + "switchToLogin": "登录", + "title": "重置密码" + } +} diff --git a/apps/admin/public/locales/zh-CN/components.json b/apps/admin/public/locales/zh-CN/components.json new file mode 100644 index 0000000..60fb6ff --- /dev/null +++ b/apps/admin/public/locales/zh-CN/components.json @@ -0,0 +1,65 @@ +{ + "empty": { + "tips": { + "0": "想象一下这里充满了精彩的内容!现在,你只能发挥你的想象力了...", + "1": "这个区域神秘消失了,但我们正在召唤它回来!", + "2": "哦不,什么都没发生... 随意填补空白吧!", + "3": "就像在音乐会上发现一个空舞台... 为什么不上去表演呢?", + "4": "你发现了一块空白画布!建个房子怎么样?", + "5": "这个区域目前是空的,但创造力从这里开始!", + "6": "这里什么都没有... 但别担心,这只是开始!", + "7": "这个地方本该有个大惊喜,但惊喜溜走了!", + "8": "暂时这里什么都没有,就像一个空的零食柜。", + "9": "这个空荡荡的空间正在等待它的主角登场!" + } + }, + "error": { + "400": "请求参数不正确,请检查后重新提交。", + "401": "请求过于频繁,请稍后再试。", + "500": "服务器出现了一些问题,请稍后再试。", + "10001": "查询不成功,请稍后再试或检查查询条件。", + "10002": "更新操作不成功,请稍后再试。", + "10003": "插入操作暂时无法完成,请稍后再试。", + "10004": "删除操作无法完成,请稍后再试。", + "20001": "用户信息已存在,请使用不同的信息重试。", + "20002": "找不到用户,请检查信息后重试。", + "20003": "密码不正确,请重新输入。", + "20004": "用户已被禁用,如有疑问请联系客服。", + "20005": "余额不足,请充值后再试。", + "20006": "注册功能暂时不可用,请稍后再试。", + "20008": "用户信息不正确,请检查后重试。", + "30001": "该节点已存在,请勿重复添加。", + "30002": "找不到相关节点,请检查后重试。", + "30003": "分组已存在,请尝试使用不同的名称。", + "30004": "找不到分组,请验证信息后重试。", + "30005": "分组中还有内容,请清空后再试。", + "40002": "未找到有效的 Token,请登录后再试。", + "40003": "当前 Token 无效,请重新获取后再试。", + "40004": "Token 已过期,请重新登录。", + "40005": "您没有访问权限,如有疑问请联系管理员。", + "50001": "找不到对应的优惠券信息,请检查后重试。", + "50002": "该优惠券已被使用,无法再次使用。", + "60001": "订阅已过期,请续费后使用。", + "60002": "暂时无法使用该订阅,请稍后再试。", + "60003": "检测到现有订阅,请先取消后再继续。", + "60004": "由于订阅有活跃用户,暂时无法删除。", + "60005": "单一订阅模式已超过用户限制", + "70001": "验证码不正确,请重新输入。", + "80001": "任务未成功加入队列,请稍后再试。", + "90001": "请禁用 DEBUG 模式后再试。", + "90015": "该账户今日已达到发送次数限制,请明天再试。", + "unknown": "系统发生错误,请稍后再试。" + }, + "language": "语言", + "pagination": { + "pageInfo": "第 {{page}} 页,共 {{total}} 页", + "rowsPerPage": "每页行数" + }, + "theme": { + "dark": "深色", + "light": "浅色", + "system": "系统", + "toggle": "切换主题" + }, + "unlimited": "无限制" +} diff --git a/apps/admin/public/locales/zh-CN/coupon.json b/apps/admin/public/locales/zh-CN/coupon.json new file mode 100644 index 0000000..64602d1 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/coupon.json @@ -0,0 +1,47 @@ +{ + "amount": "金额", + "cancel": "取消", + "code": "优惠码", + "confirm": "确认", + "confirmDelete": "确定要删除吗?", + "count": "数量", + "create": "创建", + "createCoupon": "创建优惠券", + "createSuccess": "创建成功", + "delete": "删除", + "deleteSuccess": "删除成功", + "deleteWarning": "删除后数据无法恢复,请谨慎操作。", + "discount": "折扣", + "edit": "编辑", + "editCoupon": "编辑优惠券", + "enable": "启用", + "form": { + "amountDiscount": "金额折扣", + "cancel": "取消", + "confirm": "确认", + "count": "最大使用次数", + "countPlaceholder": "最大使用次数(留空不限制)", + "customCouponCode": "自定义优惠码", + "customCouponCodePlaceholder": "自定义优惠码(留空自动生成)", + "enterCouponName": "输入优惠券名称", + "enterValue": "输入值", + "expireTime": "过期时间", + "name": "名称", + "percentageDiscount": "百分比折扣", + "selectServer": "选择订阅", + "specifiedServer": "指定订阅", + "startTime": "开始时间", + "type": "优惠券类型", + "userLimit": "每用户最大使用次数", + "userLimitPlaceholder": "每用户最大使用次数(留空不限制)" + }, + "name": "名称", + "percentage": "百分比", + "remainingTimes": "剩余次数", + "subscribe": "订阅", + "type": "类型", + "unlimited": "无限制", + "updateSuccess": "更新成功", + "usedTimes": "使用次数", + "validityPeriod": "有效期" +} diff --git a/apps/admin/public/locales/zh-CN/dashboard.json b/apps/admin/public/locales/zh-CN/dashboard.json new file mode 100644 index 0000000..7e5c4e0 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/dashboard.json @@ -0,0 +1,33 @@ +{ + "billing": { + "description": "赞助帮助 PPanel 继续发布更新!", + "title": "赞助" + }, + "currentlyOnline": "当前在线", + "month": "月", + "monthTraffic": "本月流量", + "newPurchase": "新购", + "nodes": "节点", + "nodeTraffic": "节点流量", + "offline": "离线", + "online": "在线", + "onlineUsersCount": "在线用户数", + "pending": "待处理", + "pendingTickets": "待处理工单", + "register": "注册", + "repurchase": "续费", + "revenueTitle": "收入统计", + "selectTypePlaceholder": "选择类型", + "today": "今日", + "todayTraffic": "今日流量", + "total": "总计", + "totalIncome": "总收入", + "totalServers": "服务器总数", + "traffic": "流量", + "trafficRank": "流量排行", + "type": "类型", + "users": "用户", + "userTitle": "用户统计", + "userTraffic": "用户流量", + "yesterday": "昨日" +} diff --git a/apps/admin/public/locales/zh-CN/document.json b/apps/admin/public/locales/zh-CN/document.json new file mode 100644 index 0000000..23d7582 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/document.json @@ -0,0 +1,28 @@ +{ + "cancel": "取消", + "confirm": "确认", + "confirmDelete": "确认删除", + "create": "创建", + "createDocument": "创建文档", + "createSuccess": "创建成功", + "delete": "删除", + "deleteDescription": "确定要删除此文档吗?此操作无法撤销。", + "deleteSuccess": "删除成功", + "DocumentList": "文档列表", + "edit": "编辑", + "editDocument": "编辑文档", + "form": { + "cancel": "取消", + "confirm": "确认", + "content": "内容", + "tags": "标签", + "tagsPlaceholder": "输入标签", + "title": "标题", + "titlePlaceholder": "输入文档标题" + }, + "show": "显示", + "tags": "标签", + "title": "标题", + "updatedAt": "更新时间", + "updateSuccess": "更新成功" +} diff --git a/apps/admin/public/locales/zh-CN/log.json b/apps/admin/public/locales/zh-CN/log.json new file mode 100644 index 0000000..2124368 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/log.json @@ -0,0 +1,66 @@ +{ + "column": { + "amount": "金额", + "balance": "余额", + "content": "内容", + "date": "日期", + "download": "下载", + "identifier": "标识符", + "ip": "IP", + "orderNo": "订单号", + "platform": "平台", + "remark": "备注", + "server": "服务器", + "serverId": "服务器 ID", + "status": "状态", + "subject": "主题", + "subscribe": "订阅", + "subscribeId": "订阅 ID", + "success": "成功", + "time": "时间", + "to": "收件人", + "total": "总计", + "type": "类型", + "upload": "上传", + "user": "用户", + "userAgent": "用户代理", + "userId": "用户 ID" + }, + "detail": "详情", + "failed": "失败", + "sent": "已发送", + "success": "成功", + "title": { + "balance": "余额日志", + "commission": "佣金日志", + "email": "邮件日志", + "gift": "赠送日志", + "login": "登录日志", + "mobile": "短信日志", + "register": "注册日志", + "resetSubscribe": "重置订阅日志", + "serverTraffic": "服务器流量日志", + "subscribe": "订阅日志", + "subscribeTraffic": "订阅流量日志", + "trafficDetails": "流量详情" + }, + "type": { + "231": "自动重置", + "232": "提前重置", + "233": "付费重置", + "321": "充值", + "322": "提现", + "323": "支付", + "324": "退款", + "325": "奖励", + "326": "管理员调整", + "331": "购买", + "332": "续费", + "333": "退款", + "334": "提现", + "335": "管理员调整", + "341": "增加", + "342": "减少" + }, + "unknown": "未知" +} diff --git a/apps/admin/public/locales/zh-CN/marketing.json b/apps/admin/public/locales/zh-CN/marketing.json new file mode 100644 index 0000000..f4c0b3c --- /dev/null +++ b/apps/admin/public/locales/zh-CN/marketing.json @@ -0,0 +1,107 @@ +{ + "additional": "附加", + "additionalRecipientEmails": "附加收件人邮箱", + "additionalRecipients": "附加收件人", + "additionalRecipientsDescription": "除上述用户筛选外,这些邮箱也将收到广播", + "allUsers": "所有用户", + "cancel": "取消", + "cannotBeEmpty": "不能为空", + "completed": "已完成", + "content": "邮件内容", + "createAndSendQuotaTasks": "创建并分发配额任务", + "createBroadcast": "创建广播", + "createdAt": "创建时间", + "createNewEmailBroadcastCampaign": "创建新的邮件广播活动", + "createQuotaTask": "创建配额任务", + "dailyLimit": "每日限制必须至少为 1", + "dailySendLimit": "每日发送限制", + "days": "天", + "emailAddedToScheduledQueue": "邮件已添加到定时发送队列", + "emailBroadcast": "邮件广播", + "emailBroadcastTaskCreatedSuccessfully": "邮件广播任务创建成功", + "emailBroadcastTasks": "邮件广播任务", + "emailContent": "邮件内容", + "emailInterval": "邮件间隔(秒)", + "emailIntervalMinimum": "邮件间隔必须至少为 0.1 秒", + "emailMarketing": "邮件营销", + "emailTaskManager": "邮件任务管理器", + "endTime": "结束时间", + "enterAmount": "输入金额", + "enterPercentage": "输入百分比", + "estimatedRecipients": "预计收件人", + "expiredSubscriptionUsersOnly": "仅订阅已过期用户", + "expiredUsers": "过期用户", + "failedToCalculateRecipients": "计算收件人失败", + "failedToCreateQuotaTask": "创建配额任务失败", + "failedToStopTask": "停止任务失败", + "fixedAmount": "固定金额", + "giftAmount": "赠送金额", + "giftType": "赠送金额类型", + "includeSubscriptionsValidAfter": "包含此日期及之后有效的订阅", + "includeSubscriptionsValidBefore": "包含此日期及之前有效的订阅", + "includeUsersRegisteredAfter": "包含此日期及之后注册的用户", + "includeUsersRegisteredBefore": "包含此日期及之前注册的用户", + "inProgress": "进行中", + "intervalTimeBetweenEmails": "每封邮件之间的间隔时间", + "leaveEmptyForImmediateSend": "留空立即发送", + "maximumNumberPerDay": "每日最大发送邮件数", + "no": "否", + "nonSubscribers": "未订阅用户", + "noSubscriptions": "无订阅", + "noSubscriptionUsersOnly": "仅无订阅用户", + "noTimeLimit": "无时间限制", + "notStarted": "未开始", + "numberOfDaysForTheQuota": "延长订阅到期的天数", + "onePerLine": "每行一个", + "percentageAmount": "百分比金额", + "percentageAmountDescription": "根据当前套餐价格计算赠送百分比金额", + "pleaseEnter": "请输入", + "pleaseEnterValidEmailAddresses": "请输入有效的邮箱地址,每行一个", + "pleaseSelectSubscribers": "请选择套餐", + "processing": "处理中...", + "progress": "进度", + "quotaBroadcast": "配额分发", + "quotaDays": "延长到期天数", + "quotaService": "配额服务", + "quotaTaskCreatedSuccessfully": "配额任务创建成功", + "quotaTaskManager": "配额任务管理器", + "quotaTasks": "配额任务", + "recipientType": "收件人类型", + "registrationEndDate": "注册结束日期", + "registrationStartDate": "注册开始日期", + "resetTraffic": "重置流量", + "resetTrafficDescription": "是否重置订阅已用流量", + "scheduledSend": "定时发送", + "scheduledSendTimeMustBeLater": "定时发送时间必须晚于当前时间", + "scheduleSend": "定时发送", + "scope": "发送范围", + "selectSendScope": "选择发送范围", + "selectSendTime": "选择发送时间,留空立即发送", + "selectValidSubscriptionsOnly": "仅选择当前有效订阅", + "sendFailed": "发送失败,请重试", + "sendNow": "立即发送", + "sendScope": "发送范围", + "sendScopeDescription": "选择邮件发送的用户范围。选择\"仅附加邮箱\"将只发送到下方填写的邮箱地址", + "sendSettings": "发送设置", + "sendTime": "发送时间", + "specificUsers": "特定用户", + "specificUsersOnly": "仅附加邮箱(跳过平台用户)", + "startTime": "开始时间", + "status": "状态", + "stop": "停止", + "subject": "邮件主题", + "subscribedUsers": "已订阅用户", + "subscribedUsersOnly": "仅已订阅用户", + "subscribers": "套餐", + "subscriptionCount": "订阅数量", + "subscriptionValidityEndDate": "订阅有效期结束日期", + "subscriptionValidityStartDate": "订阅有效期开始日期", + "taskStoppedSuccessfully": "任务停止成功", + "timeRange": "时间范围", + "useMarkdownEditor": "使用 Markdown 编辑器编写邮件内容,支持预览功能", + "users": "用户", + "validOnly": "仅有效", + "viewAndManageEmailBroadcastTasks": "查看和管理邮件广播任务", + "viewAndManageQuotaTasks": "查看和管理配额任务", + "yes": "是" +} diff --git a/apps/admin/public/locales/zh-CN/menu.json b/apps/admin/public/locales/zh-CN/menu.json new file mode 100644 index 0000000..d24feb6 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/menu.json @@ -0,0 +1,35 @@ +{ + "ADS Config": "广告配置", + "Announcement Management": "公告管理", + "Auth Control": "认证控制", + "Balance": "余额", + "Commerce": "商业", + "Commission": "佣金", + "Coupon Management": "优惠券管理", + "Dashboard": "仪表盘", + "Document Management": "文档管理", + "Email": "邮件", + "Gift": "赠送", + "Login": "登录", + "Logs & Analytics": "日志与分析", + "Maintenance": "维护", + "Marketing Management": "营销管理", + "Mobile": "短信", + "Node Management": "节点管理", + "Order Management": "订单管理", + "Payment Config": "支付配置", + "Product Management": "商品管理", + "Register": "注册", + "Reset Subscribe": "重置订阅", + "Server Management": "服务器管理", + "Server Traffic": "服务器流量", + "Subscribe": "订阅", + "Subscribe Config": "订阅配置", + "Subscribe Traffic": "订阅流量", + "System": "系统", + "System Config": "系统配置", + "Ticket Management": "工单管理", + "Traffic Details": "流量详情", + "User Management": "用户管理", + "Users & Support": "用户与支持" +} diff --git a/apps/admin/public/locales/zh-CN/nodes.json b/apps/admin/public/locales/zh-CN/nodes.json new file mode 100644 index 0000000..a2634e9 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/nodes.json @@ -0,0 +1,31 @@ +{ + "address": "地址", + "cancel": "取消", + "confirm": "确认", + "confirmDeleteDesc": "此操作无法撤销。", + "confirmDeleteTitle": "删除此节点?", + "copied": "已复制", + "copy": "复制", + "create": "创建", + "created": "已创建", + "delete": "删除", + "deleted": "已删除", + "drawerCreateTitle": "创建节点", + "drawerEditTitle": "编辑节点", + "edit": "编辑", + "enabled": "已启用", + "enabled_off": "已禁用", + "enabled_on": "已启用", + "name": "名称", + "pageTitle": "节点", + "port": "端口", + "protocol": "协议", + "select_protocol": "选择协议…", + "select_server": "选择服务器…", + "server": "服务器", + "sorted_success": "排序成功", + "tags": "标签", + "tags_description": "权限分组标签(包含计划绑定和投递策略)。", + "tags_placeholder": "使用回车或逗号 (,) 添加多个标签", + "updated": "已更新" +} diff --git a/apps/admin/public/locales/zh-CN/order.json b/apps/admin/public/locales/zh-CN/order.json new file mode 100644 index 0000000..65c4534 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/order.json @@ -0,0 +1,29 @@ +{ + "amount": "金额", + "couponDiscount": "优惠券折扣", + "discount": "折扣金额", + "feeAmount": "手续费", + "method": "支付方式", + "orderNumber": "订单编号", + "status": { + "0": "状态", + "1": "待支付", + "2": "已支付", + "3": "已取消", + "4": "已关闭", + "5": "已完成" + }, + "subscribe": "订阅", + "subscribePrice": "订阅价格", + "total": "总计", + "tradeNo": "交易号", + "type": { + "0": "类型", + "1": "新购", + "2": "续费", + "3": "重置流量", + "4": "充值" + }, + "updateTime": "更新时间", + "user": "用户" +} diff --git a/apps/admin/public/locales/zh-CN/payment.json b/apps/admin/public/locales/zh-CN/payment.json new file mode 100644 index 0000000..91560a8 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/payment.json @@ -0,0 +1,39 @@ +{ + "applyForPayment": "申请支付", + "batchDelete": "批量删除", + "cancel": "取消", + "configPlaceholder": "请填写提供的 {{field}} 配置", + "confirm": "确认", + "confirmDelete": "确认删除", + "copy": "复制", + "copySuccess": "复制成功", + "create": "添加支付方式", + "createPayment": "添加支付方式", + "createSuccess": "创建成功", + "delete": "删除", + "deleteSuccess": "删除成功", + "deleteWarning": "确定要删除此支付方式吗?此操作无法撤销。", + "description": "描述", + "domain": "域名", + "edit": "编辑", + "editPayment": "编辑支付方式", + "enable": "启用", + "feeAmount": "固定金额", + "feePercent": "手续费百分比", + "fixedFee": "固定金额", + "handlingFee": "手续费", + "icon": "图标", + "iconPlaceholder": "输入图标 URL", + "name": "名称", + "namePlaceholder": "输入支付方式名称", + "nameRequired": "名称为必填项", + "noFee": "无手续费", + "notify_url": "回调 URL", + "paymentManagement": "支付管理", + "percentFee": "百分比", + "platform": "平台", + "searchPlaceholder": "输入搜索内容", + "selectPlatform": "选择平台", + "submit": "提交", + "updateSuccess": "更新成功" +} diff --git a/apps/admin/public/locales/zh-CN/product.json b/apps/admin/public/locales/zh-CN/product.json new file mode 100644 index 0000000..5482838 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/product.json @@ -0,0 +1,73 @@ +{ + "cancel": "取消", + "confirm": "确认", + "confirmDelete": "确定要删除吗?", + "copy": "复制", + "copySuccess": "复制成功", + "create": "创建", + "createSubscribe": "创建订阅", + "createSuccess": "创建成功", + "delete": "删除", + "deleteSuccess": "删除成功", + "deleteWarning": "删除后数据无法恢复,请谨慎操作。", + "deviceLimit": "设备限制/单位", + "edit": "编辑", + "editSubscribe": "编辑订阅", + "form": { + "annualReset": "年度重置", + "basic": "基本", + "cancel": "取消", + "confirm": "确认", + "Day": "天", + "deductionRatio": "自动/手动扣减配置", + "deductionRatioDescription": "用于扣减。默认情况下,系统采用自动计算算法。当提供手动比例时,系统根据时间和流量比例计算比例,确保总和为 100%。", + "description": "描述", + "deviceLimit": "设备限制", + "discount": "折扣", + "discount_price": "折扣价格", + "discountDescription": "根据单价设置折扣", + "discountPercent": "折扣百分比", + "Hour": "小时", + "inventory": "订阅库存", + "language": "语言", + "languageDescription": "留空为默认无语言限制", + "languagePlaceholder": "订阅的语言标识符,例如 en-US、zh-CN", + "Minute": "分钟", + "Month": "月", + "monthlyReset": "每月重置", + "name": "名称", + "node": "节点", + "nodeGroup": "节点组", + "nodes": "节点", + "noLimit": "无限制", + "NoLimit": "无限制", + "noReset": "不重置", + "pricing": "定价", + "purchaseWithDiscount": "允许扣减", + "purchaseWithDiscountDescription": "启用或禁用退订功能。激活后,系统将根据配置的规则和比例进行扣减处理,剩余价值将返还到余额", + "quota": "购买限制", + "renewalReset": "续费重置", + "renewalResetDescription": "续费时重置周期", + "replacement": "重置价格(每次)", + "resetCycle": "重置周期", + "resetOn1st": "每月1日重置", + "selectResetCycle": "请选择重置周期", + "selectUnitTime": "请选择时间单位", + "speedLimit": "速度限制", + "traffic": "流量", + "unitPrice": "单价", + "unitTime": "时间单位", + "Year": "年" + }, + "inventory": "订阅库存", + "language": "语言", + "name": "名称", + "quota": "购买限制/次", + "replacement": "重置价格/次", + "sell": "销售", + "show": "显示", + "sold": "订阅数量", + "traffic": "流量", + "unitPrice": "单价", + "updateSuccess": "更新成功" +} diff --git a/apps/admin/public/locales/zh-CN/servers.json b/apps/admin/public/locales/zh-CN/servers.json new file mode 100644 index 0000000..eac5b5e --- /dev/null +++ b/apps/admin/public/locales/zh-CN/servers.json @@ -0,0 +1,156 @@ +{ + "actions": { + "cancel": "取消", + "save": "保存" + }, + "address": "地址", + "address_placeholder": "服务器地址", + "apiHost": "API 主机", + "apiHostPlaceholder": "http(s)://example.com", + "bandwidth_placeholder": "输入带宽,留空使用 BBR", + "basic": "基本配置", + "cancel": "取消", + "cert_dns_env": "DNS 环境变量", + "cert_dns_provider": "DNS 提供商", + "cert_mode": "证书模式", + "cipher": "加密算法", + "city": "城市", + "close": "关闭", + "confirm": "确认", + "confirmDeleteDesc": "此操作无法撤销。", + "confirmDeleteTitle": "删除此服务器?", + "congestion_controller": "拥塞控制器", + "connect": "连接", + "copied": "已复制", + "copy": "复制", + "copyAndClose": "复制并关闭", + "copyFailed": "复制失败", + "country": "国家", + "cpu": "CPU", + "create": "创建", + "created": "已创建", + "delete": "删除", + "deleted": "已删除", + "disable_sni": "禁用 SNI", + "disabled": "已禁用", + "disk": "磁盘", + "down_mbps": "下载带宽", + "drawerCreateTitle": "创建服务器", + "drawerEditTitle": "编辑服务器", + "edit": "编辑", + "enabled": "已启用", + "encryption": "加密", + "encryption_client_padding": "客户端填充", + "encryption_mode": "模式", + "encryption_password": "密码", + "encryption_password_placeholder": "留空自动生成", + "encryption_private_key": "私钥", + "encryption_private_key_placeholder": "留空自动生成", + "encryption_rtt": "RTT", + "encryption_server_padding": "服务器填充", + "encryption_ticket": "票据时间", + "expired": "已过期", + "expireTime": "过期时间", + "extra": "额外", + "flow": "流控", + "generate_quantum_resistant_key": "生成量子抗性密钥", + "generate_standard_encryption_key": "生成标准密钥", + "hop_interval": "跳跃间隔", + "hop_ports": "跳跃端口", + "hop_ports_placeholder": "例如 1-65535", + "host": "主机", + "id": "ID", + "installCommand": "安装命令", + "ipAddresses": "IP 地址", + "memory": "内存", + "mode": "模式", + "multiplex": "多路复用", + "name": "名称", + "notAvailable": "不可用", + "obfs": "混淆", + "obfs_password": "混淆密码", + "obfs_password_placeholder": "输入混淆密码", + "offline": "离线", + "oneClickInstall": "一键安装", + "online": "在线", + "onlineUsers": "在线用户", + "padding_scheme": "填充方案", + "padding_scheme_placeholder": "每行一条填充规则,格式:stop=8, 0=30-30", + "pageTitle": "服务器", + "path": "路径", + "port": "端口", + "protocol_configurations": "协议配置", + "protocol_configurations_desc": "启用并配置所需的协议类型", + "protocols": "协议", + "reality": "Reality", + "reduce_rtt": "减少 RTT", + "security": "安全", + "security_allow_insecure": "允许不安全", + "security_fingerprint": "指纹", + "security_private_key": "Reality 私钥", + "security_private_key_placeholder": "输入私钥", + "security_public_key": "Reality 公钥", + "security_public_key_placeholder": "输入公钥", + "security_server_address": "Reality 服务器地址", + "security_server_address_placeholder": "例如 1.2.3.4 或域名", + "security_server_port": "Reality 服务器端口", + "security_short_id": "Reality Short ID", + "security_sni": "SNI", + "server_config": { + "description": "管理节点通信密钥、拉取/推送间隔。", + "dynamic_multiplier": "动态倍率", + "dynamic_multiplier_desc": "定义时间段和倍率来调整流量计费。", + "fields": { + "block_rules_placeholder": "每行一条域名规则", + "communication_key": "通信密钥", + "communication_key_desc": "用于节点认证。", + "communication_key_placeholder": "请输入", + "dns_config": "DNS 配置", + "dns_domains_placeholder": "每行一条域名规则", + "dns_proto_placeholder": "选择类型", + "end_time": "结束时间", + "ip_strategy": "IP 策略", + "ip_strategy_desc": "选择网络连接的 IP 版本偏好", + "ip_strategy_ipv4": "优先 IPv4", + "ip_strategy_ipv6": "优先 IPv6", + "ip_strategy_placeholder": "选择 IP 策略", + "multiplier": "倍率", + "node_pull_interval": "节点拉取间隔", + "node_pull_interval_desc": "节点拉取配置的频率(秒)。", + "node_push_interval": "节点推送间隔", + "node_push_interval_desc": "节点推送统计的频率(秒)。", + "outbound_address_placeholder": "服务器地址", + "outbound_name_placeholder": "配置名称", + "outbound_password_placeholder": "密码(可选)", + "outbound_port_placeholder": "端口号", + "outbound_protocol_placeholder": "选择协议", + "outbound_rules_placeholder": "每行一条规则", + "reset": "重置", + "start_time": "开始时间", + "traffic_report_threshold": "流量上报阈值", + "traffic_report_threshold_desc": "设置流量上报的最小阈值。" + }, + "saveSuccess": "保存成功", + "tabs": { + "basic": "基本配置", + "block": "屏蔽规则", + "dns": "DNS 配置", + "outbound": "出站规则" + }, + "title": "节点配置" + }, + "server_key": "服务器密钥", + "service_name": "服务名称", + "sorted_success": "排序成功", + "status": "状态", + "subscribeId": "订阅 ID", + "subscription": "订阅", + "traffic": "流量", + "traffic_ratio": "倍率", + "transport": "传输", + "udp_relay_mode": "UDP 中继模式", + "unlimited": "无限制", + "up_mbps": "上传带宽", + "updated": "已更新", + "user": "用户" +} diff --git a/apps/admin/public/locales/zh-CN/subscribe.json b/apps/admin/public/locales/zh-CN/subscribe.json new file mode 100644 index 0000000..d3533b8 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/subscribe.json @@ -0,0 +1,119 @@ +{ + "actions": { + "add": "添加", + "batchDelete": "批量删除", + "batchDeleteSuccess_other": "成功删除 {count} 个客户端", + "batchDeleteWarning_other": "确定要删除选中的 {count} 个客户端吗?", + "cancel": "取消", + "confirm": "确认", + "confirmDelete": "确认删除", + "createSuccess": "创建成功", + "delete": "删除", + "deleteFailed": "删除失败", + "deleteSuccess": "删除成功", + "deleteWarning": "此操作无法撤销。确定要删除此客户端吗?", + "edit": "编辑", + "save": "保存", + "saveFailed": "保存失败", + "update": "更新", + "updateSuccess": "更新成功" + }, + "config": { + "description": "管理订阅系统设置", + "singleSubscriptionMode": "单一订阅模式", + "singleSubscriptionModeDescription": "限制用户只能有一个活跃订阅。现有订阅不受影响", + "subscriptionDomain": "订阅域名", + "subscriptionDomainDescription": "订阅链接的自定义域名", + "subscriptionDomainPlaceholder": "输入订阅域名,每行一个", + "subscriptionPath": "订阅路径", + "subscriptionPathDescription": "订阅端点的自定义路径(系统重启后性能更佳)", + "subscriptionPathPlaceholder": "输入订阅路径", + "title": "订阅配置", + "updateError": "更新失败", + "updateSuccess": "设置更新成功", + "userAgentLimit": "{userAgent} 限制", + "userAgentLimitDescription": "基于 {userAgent} 启用访问限制", + "userAgentList": "{userAgent} 白名单", + "userAgentListDescription": "允许访问订阅的 {userAgent},每行一个。已配置的应用程序 {userAgent} 将自动包含", + "userAgentListPlaceholder": "输入允许的 {userAgent},每行一个", + "wildcardResolution": "泛域名解析", + "wildcardResolutionDescription": "为订阅启用泛域名解析" + }, + "form": { + "addTitle": "添加客户端", + "descriptions": { + "description": "详细的客户端描述", + "downloadLink": "平台下载 URL", + "icon": "图标 URL 或 base64 编码", + "name": "客户端显示名称", + "outputFormat": "订阅配置文件格式", + "scheme": { + "base64Encoding": "Base64 编码", + "functions": "支持函数:", + "jsonStringify": "JSON 对象转字符串", + "nameVariable": "站点名称", + "title": "URL Scheme 模板", + "urlEncoding": "URL 编码", + "urlVariable": "订阅 URL", + "variables": "支持变量:" + }, + "template": { + "functions": "模板函数:", + "if": "条件语句", + "nodes": "代理节点列表", + "range": "遍历数组", + "siteName": "站点名称", + "sprig": "Sprig 函数库(字符串处理、日期等)", + "subscribeName": "订阅名称", + "title": "Go 模板语法", + "userInfo": "用户信息(流量、到期等)", + "variables": "可用变量:" + }, + "userAgentPrefix": "用于区分不同客户端的客户端标识符" + }, + "editTitle": "编辑客户端", + "fields": { + "description": "描述", + "icon": "图标", + "name": "名称", + "outputFormat": "输出格式", + "scheme": "URL Scheme", + "template": "订阅文件模板" + }, + "tabs": { + "basic": "基本信息", + "download": "下载", + "template": "模板" + } + }, + "outputFormats": { + "base64": "Base64", + "conf": "CONF", + "json": "JSON", + "plain": "纯文本", + "yaml": "YAML" + }, + "protocol": { + "title": "客户端管理" + }, + "table": { + "columns": { + "default": "默认", + "description": "描述", + "name": "客户端名称", + "outputFormat": "输出格式", + "supportedPlatforms": "支持的平台" + } + }, + "templatePreview": { + "base64": { + "decodedContent": "解码内容", + "decodeError": "Base64 解码错误", + "originalContent": "原始内容" + }, + "failed": "加载模板失败", + "loading": "加载中...", + "preview": "预览", + "title": "模板预览" + } +} diff --git a/apps/admin/public/locales/zh-CN/system.json b/apps/admin/public/locales/zh-CN/system.json new file mode 100644 index 0000000..0a9eaa0 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/system.json @@ -0,0 +1,136 @@ +{ + "basicSettings": "基本设置", + "common": { + "cancel": "取消", + "save": "保存设置", + "saveFailed": "保存失败", + "saveSuccess": "保存成功" + }, + "currency": { + "accessKey": "API 密钥", + "accessKeyDescription": "由 {{url}} 提供的免费汇率 API 密钥", + "accessKeyPlaceholder": "输入 API 密钥", + "currencySymbol": "货币符号", + "currencySymbolDescription": "仅用于显示;更改此项将影响系统中所有货币单位", + "currencySymbolPlaceholder": "¥", + "currencyUnit": "货币单位", + "currencyUnitDescription": "仅用于显示;更改此项将影响系统中所有货币单位", + "currencyUnitPlaceholder": "CNY", + "description": "配置货币单位、符号和汇率 API 设置", + "title": "货币配置" + }, + "invite": { + "description": "配置用户邀请和推荐奖励设置", + "forcedInvite": "强制邀请注册", + "forcedInviteDescription": "启用后,用户必须通过邀请链接注册", + "inputPlaceholder": "请输入", + "onlyFirstPurchase": "仅首次购买奖励", + "onlyFirstPurchaseDescription": "启用后,推荐人仅在被推荐用户首次购买时获得奖励", + "referralPercentage": "推荐奖励百分比", + "referralPercentageDescription": "给予推荐人的奖励百分比", + "saveFailed": "保存失败", + "saveSuccess": "保存成功", + "title": "邀请设置" + }, + "logCleanup": { + "autoClear": "启用自动清理", + "autoClearDescription": "启用后,系统将自动清理过期的日志记录", + "clearDays": "保留天数", + "clearDaysDescription": "日志保留的天数;超过此时间的日志将被清理", + "clearDaysPlaceholder": "输入保留天数", + "description": "配置自动日志清理规则和保留期限", + "title": "日志清理设置" + }, + "logSettings": "日志设置", + "privacyPolicy": { + "description": "编辑和管理隐私政策内容", + "title": "隐私政策" + }, + "register": { + "day": "天", + "description": "配置用户注册相关设置", + "enableTrial": "启用试用", + "enableTrialDescription": "启用后,新用户注册时将获得试用订阅", + "hour": "小时", + "inputPlaceholder": "请输入", + "ipRegistrationLimit": "IP 注册限制", + "ipRegistrationLimitDescription": "限制单个 IP 地址的注册次数", + "minute": "分钟", + "month": "月", + "none": "无", + "registrationLimitCount": "注册限制次数", + "registrationLimitCountDescription": "限制期内每个 IP 允许的注册次数", + "registrationLimitExpire": "限制期", + "registrationLimitExpireDescription": "IP 注册限制的持续时间(分钟)", + "saveFailed": "保存失败", + "saveSuccess": "保存成功", + "selectPlaceholder": "请选择", + "stopNewUserRegistration": "停止新用户注册", + "stopNewUserRegistrationDescription": "启用后,将禁止新用户注册", + "title": "注册设置", + "trialConfig": "试用配置", + "trialConfigDescription": "配置新用户注册时的试用订阅、时长和时间单位", + "year": "年" + }, + "site": { + "customData": "自定义数据", + "customDataDescription": "用于网站定制的自定义数据", + "customHtml": "自定义 HTML", + "customHtmlDescription": "注入到站点 body 标签底部的自定义 HTML 代码", + "description": "配置基本站点信息、Logo、域名和其他设置", + "keywords": "关键词", + "keywordsDescription": "用于 SEO 目的", + "keywordsPlaceholder": "关键词1, 关键词2, 关键词3", + "logo": "站点 Logo", + "logoDescription": "用于在指定位置显示 Logo", + "logoPlaceholder": "输入 Logo 的 URL,不要以 '/' 结尾", + "siteDesc": "站点描述", + "siteDescDescription": "用于在指定位置显示站点描述", + "siteDescPlaceholder": "输入站点描述", + "siteDomain": "站点域名", + "siteDomainDescription": "当前网站的域名地址,例如用于邮件中", + "siteDomainPlaceholder": "请输入域名地址。多个域名请每行输入一个。", + "siteName": "站点名称", + "siteNameDescription": "用于在指定位置显示站点名称", + "siteNamePlaceholder": "输入站点名称", + "title": "站点配置" + }, + "tos": { + "description": "编辑和管理服务条款内容", + "title": "服务条款" + }, + "userSecuritySettings": "用户与安全", + "verify": { + "description": "配置 Turnstile 验证码和验证设置", + "enableLoginVerify": "登录验证", + "enableLoginVerifyDescription": "启用后,用户登录时必须通过人机验证", + "enablePasswordVerify": "密码重置验证", + "enablePasswordVerifyDescription": "启用后,用户重置密码时必须通过人机验证", + "enableRegisterVerify": "注册验证", + "enableRegisterVerifyDescription": "启用后,用户注册时必须通过人机验证", + "saveFailed": "保存失败", + "saveSuccess": "保存成功", + "title": "安全验证", + "turnstileSecret": "Turnstile 密钥", + "turnstileSecretDescription": "用于后端验证的 Cloudflare Turnstile 密钥", + "turnstileSecretPlaceholder": "输入 Turnstile 密钥", + "turnstileSiteKey": "Turnstile 站点密钥", + "turnstileSiteKeyDescription": "用于前端验证的 Cloudflare Turnstile 站点密钥", + "turnstileSiteKeyPlaceholder": "输入 Turnstile 站点密钥" + }, + "verifyCode": { + "dailyLimit": "每日发送限制", + "dailyLimitDescription": "每个用户每天可发送的最大验证码数量", + "description": "配置邮件验证码发送规则和限制", + "expireTime": "验证码有效期", + "expireTimeDescription": "验证码的有效期(秒)", + "inputPlaceholder": "请输入", + "interval": "发送间隔", + "intervalDescription": "两次验证码发送之间的最小间隔(秒)", + "saveFailed": "保存失败", + "saveSuccess": "保存成功", + "seconds": "秒", + "times": "次", + "title": "验证码设置" + } +} diff --git a/apps/admin/public/locales/zh-CN/ticket.json b/apps/admin/public/locales/zh-CN/ticket.json new file mode 100644 index 0000000..5864685 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/ticket.json @@ -0,0 +1,22 @@ +{ + "cancel": "取消", + "check": "查看", + "close": "关闭", + "closeSuccess": "关闭成功", + "closeWarning": "一旦关闭,工单将无法操作,请谨慎操作。", + "confirm": "确认", + "confirmClose": "确定要关闭吗?", + "inputPlaceholder": "请输入您的问题,我们会尽快回复。", + "reply": "回复", + "status": { + "0": "状态", + "1": "待跟进", + "2": "待回复", + "3": "已解决", + "4": "已关闭" + }, + "ticketList": "工单列表", + "title": "标题", + "updatedAt": "更新时间", + "user": "用户" +} diff --git a/apps/admin/public/locales/zh-CN/tool.json b/apps/admin/public/locales/zh-CN/tool.json new file mode 100644 index 0000000..cd707fe --- /dev/null +++ b/apps/admin/public/locales/zh-CN/tool.json @@ -0,0 +1,14 @@ +{ + "cancel": "取消", + "confirmReboot": "确认重启", + "confirmSystemReboot": "确认系统重启", + "newVersionAvailable": "有新版本可用", + "rebootDescription": "确定要重启系统吗?此操作无法撤销。", + "rebooting": "重启中...", + "refreshLogs": "刷新日志", + "serverVersion": "服务器版本", + "systemLogs": "系统日志", + "systemReboot": "系统重启", + "systemServices": "系统服务", + "webVersion": "前端版本" +} diff --git a/apps/admin/public/locales/zh-CN/translation.json b/apps/admin/public/locales/zh-CN/translation.json new file mode 100644 index 0000000..bf51533 --- /dev/null +++ b/apps/admin/public/locales/zh-CN/translation.json @@ -0,0 +1,16 @@ +{ + "errors": { + "nameRequired": "请输入名称", + "portRange": "端口必须在 1 到 65535 之间", + "protocolRequired": "请选择协议", + "serverAddrRequired": "请输入入口地址", + "serverRequired": "请选择服务器" + }, + "form": { + "validation": { + "nameRequired": "客户端名称必填", + "userAgentRequiredSuffix": "是必填项" + } + }, + "tos": "服务条款" +} diff --git a/apps/admin/public/locales/zh-CN/user.json b/apps/admin/public/locales/zh-CN/user.json new file mode 100644 index 0000000..b97925e --- /dev/null +++ b/apps/admin/public/locales/zh-CN/user.json @@ -0,0 +1,108 @@ +{ + "accountEnable": "账户启用", + "add": "添加", + "administrator": "管理员", + "areaCodePlaceholder": "区号", + "authMethodsTitle": "认证方式", + "avatar": "头像", + "balance": "余额", + "balanceLogs": "余额日志", + "balanceNotifications": "余额通知", + "balancePlaceholder": "输入余额", + "basicInfoTitle": "基本信息", + "cancel": "取消", + "commission": "佣金", + "commissionLogs": "佣金日志", + "commissionPlaceholder": "输入佣金", + "confirm": "确认", + "confirmDelete": "确认删除", + "confirmOffline": "确认下线", + "copySubscription": "复制订阅", + "copySuccess": "复制成功", + "create": "创建", + "createdAt": "创建时间", + "createSubscription": "创建订阅", + "createSuccess": "创建成功", + "createUser": "创建用户", + "delete": "删除", + "deleteDescription": "此操作无法撤销。", + "deleteSubscriptionDescription": "此操作无法撤销。", + "deleteSuccess": "删除成功", + "deviceLimit": "设备限制", + "download": "下载", + "downloadTraffic": "下载流量", + "edit": "编辑", + "editSubscription": "编辑订阅", + "enable": "启用", + "expiredAt": "过期时间", + "expireTime": "过期时间", + "giftAmount": "赠送金额", + "giftAmountPlaceholder": "输入赠送金额", + "giftLogs": "赠送日志", + "invalidEmailFormat": "邮箱格式无效", + "inviteCode": "邀请码", + "inviteCodePlaceholder": "输入邀请码", + "kickOfflineConfirm": "确认踢下线", + "kickOfflineSuccess": "设备已踢下线", + "lastSeen": "最后上线", + "loading": "加载中...", + "loginLogs": "登录日志", + "loginNotifications": "登录通知", + "loginStatus": "登录状态", + "manager": "管理员", + "more": "更多", + "notifySettingsTitle": "通知设置", + "offline": "离线", + "online": "在线", + "onlineDevices": "在线设备", + "onlyFirstPurchase": "仅首次购买", + "orderList": "订单列表", + "password": "密码", + "passwordPlaceholder": "输入密码", + "permanent": "永久", + "pleaseEnterEmail": "输入邮箱", + "referer": "推荐人", + "refererId": "推荐人 ID", + "refererIdPlaceholder": "输入推荐人 ID", + "referralCode": "推荐码", + "referralPercentage": "推荐百分比", + "referralPercentagePlaceholder": "输入百分比", + "referrerUserId": "推荐人用户 ID", + "remove": "移除", + "resetLogs": "重置日志", + "resetTime": "重置时间", + "save": "保存", + "speedLimit": "速度限制", + "startTime": "开始时间", + "subscription": "订阅", + "subscriptionId": "订阅 ID", + "subscriptionInfo": "订阅信息", + "subscriptionList": "订阅列表", + "subscriptionLogs": "订阅日志", + "subscriptionName": "订阅名称", + "subscriptionNotifications": "订阅通知", + "telephone": "电话", + "telephonePlaceholder": "输入电话号码", + "token": "令牌", + "totalTraffic": "总流量", + "tradeNotifications": "交易通知", + "trafficDetails": "流量详情", + "trafficLimit": "流量限制", + "trafficStats": "流量统计", + "trafficUsage": "流量使用", + "unlimited": "无限制", + "unverified": "未验证", + "update": "更新", + "updateSuccess": "更新成功", + "upload": "上传", + "uploadTraffic": "上传流量", + "userAgent": "用户代理", + "userEmail": "邮箱", + "userEmailPlaceholder": "输入邮箱", + "userId": "用户 ID", + "userInfo": "用户信息", + "userList": "用户列表", + "userName": "用户名", + "userProfile": "用户资料", + "verified": "已验证" +} diff --git a/apps/admin/public/lotties/login.json b/apps/admin/public/lotties/login.json new file mode 100644 index 0000000..7df3dec --- /dev/null +++ b/apps/admin/public/lotties/login.json @@ -0,0 +1,19241 @@ +{ + "assets": [], + "ddd": 0, + "fr": 25, + "h": 512, + "ip": 0, + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 3, + "nm": "Null 1", + "sr": 1, + "ks": { + "o": { "a": 0, "k": 0, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [256, 256, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [50, 50, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 2, + "ty": 4, + "nm": "Layer 22", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [161.372, 35.102, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [111.372, -14.898, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 105, + "s": [0, 0, 100] + }, + { "t": 112, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [117.283, -14.897], + [111.372, -8.984], + [105.461, -14.897], + [111.372, -20.808] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [114.455, -16.852], + [108.546, -10.936], + [106.753, -11.219], + [105.46, -14.896], + [111.375, -20.811], + [113.161, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [117.284, -14.896], + [111.375, -8.987], + [106.753, -11.219], + [105.46, -14.896], + [111.375, -20.811], + [113.161, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 105, + "op": 330, + "st": 105, + "bm": 0 + }, + { + "ddd": 0, + "ind": 3, + "ty": 4, + "nm": "Layer 21", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [141.656, 35.102, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [91.656, -14.898, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 102, + "s": [0, 0, 100] + }, + { "t": 109, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [97.567, -14.897], + [91.657, -8.984], + [85.746, -14.897], + [91.657, -20.808] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [94.739, -16.852], + [88.83, -10.936], + [87.038, -11.219], + [85.744, -14.896], + [91.66, -20.811], + [93.446, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [97.569, -14.896], + [91.66, -8.987], + [87.038, -11.219], + [85.744, -14.896], + [91.66, -20.811], + [93.446, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 102, + "op": 327, + "st": 102, + "bm": 0 + }, + { + "ddd": 0, + "ind": 4, + "ty": 4, + "nm": "Layer 20", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [121.941, 35.102, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [71.941, -14.898, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 99, + "s": [0, 0, 100] + }, + { "t": 106, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [77.852, -14.897], + [71.941, -8.984], + [66.03, -14.897], + [71.941, -20.808] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [75.023, -16.852], + [69.114, -10.936], + [67.322, -11.219], + [66.029, -14.896], + [71.944, -20.811], + [73.73, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [77.853, -14.896], + [71.944, -8.987], + [67.322, -11.219], + [66.029, -14.896], + [71.944, -20.811], + [73.73, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 99, + "op": 324, + "st": 99, + "bm": 0 + }, + { + "ddd": 0, + "ind": 5, + "ty": 4, + "nm": "Layer 19", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [102.225, 35.102, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [52.225, -14.898, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 96, + "s": [0, 0, 100] + }, + { "t": 103, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [58.136, -14.897], + [52.225, -8.984], + [46.315, -14.897], + [52.225, -20.808] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [55.308, -16.852], + [49.399, -10.936], + [47.606, -11.219], + [46.313, -14.896], + [52.229, -20.811], + [54.014, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [58.138, -14.896], + [52.229, -8.987], + [47.606, -11.219], + [46.313, -14.896], + [52.229, -20.811], + [54.014, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 96, + "op": 321, + "st": 96, + "bm": 0 + }, + { + "ddd": 0, + "ind": 6, + "ty": 4, + "nm": "Layer 18", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [82.51, 35.102, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [32.51, -14.898, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 93, + "s": [0, 0, 100] + }, + { "t": 100, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [38.42, -14.897], + [32.51, -8.984], + [26.599, -14.897], + [32.51, -20.808] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [35.592, -16.852], + [29.683, -10.936], + [27.891, -11.219], + [26.597, -14.896], + [32.513, -20.811], + [34.299, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [38.422, -14.896], + [32.513, -8.987], + [27.891, -11.219], + [26.597, -14.896], + [32.513, -20.811], + [34.299, -20.535] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 93, + "op": 318, + "st": 93, + "bm": 0 + }, + { + "ddd": 0, + "ind": 7, + "ty": 4, + "nm": "Layer 17", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [161.372, -5.017, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [111.372, -55.017, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 85, + "s": [0, 0, 100] + }, + { "t": 92, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [117.283, -55.017], + [111.372, -49.104], + [105.461, -55.017], + [111.372, -60.928] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [114.455, -56.972], + [108.546, -51.056], + [106.753, -51.338], + [105.46, -55.015], + [111.375, -60.931], + [113.161, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [117.284, -55.015], + [111.375, -49.106], + [106.753, -51.338], + [105.46, -55.015], + [111.375, -60.931], + [113.161, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 85, + "op": 310, + "st": 85, + "bm": 0 + }, + { + "ddd": 0, + "ind": 8, + "ty": 4, + "nm": "Layer 16", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [141.656, -5.017, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [91.656, -55.017, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 82, + "s": [0, 0, 100] + }, + { "t": 89, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [97.567, -55.017], + [91.657, -49.104], + [85.746, -55.017], + [91.657, -60.928] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [94.739, -56.972], + [88.83, -51.056], + [87.038, -51.338], + [85.744, -55.015], + [91.66, -60.931], + [93.446, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [97.569, -55.015], + [91.66, -49.106], + [87.038, -51.338], + [85.744, -55.015], + [91.66, -60.931], + [93.446, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 82, + "op": 307, + "st": 82, + "bm": 0 + }, + { + "ddd": 0, + "ind": 9, + "ty": 4, + "nm": "Layer 15", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [121.941, -5.017, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [71.941, -55.017, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 79, + "s": [0, 0, 100] + }, + { "t": 86, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [77.852, -55.017], + [71.941, -49.104], + [66.03, -55.017], + [71.941, -60.928] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [75.023, -56.972], + [69.114, -51.056], + [67.322, -51.338], + [66.029, -55.015], + [71.944, -60.931], + [73.73, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [77.853, -55.015], + [71.944, -49.106], + [67.322, -51.338], + [66.029, -55.015], + [71.944, -60.931], + [73.73, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 79, + "op": 304, + "st": 79, + "bm": 0 + }, + { + "ddd": 0, + "ind": 10, + "ty": 4, + "nm": "Layer 14", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [102.225, -5.017, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [52.225, -55.017, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 76, + "s": [0, 0, 100] + }, + { "t": 83, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [58.136, -55.017], + [52.225, -49.104], + [46.315, -55.017], + [52.225, -60.928] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [55.308, -56.972], + [49.399, -51.056], + [47.606, -51.338], + [46.313, -55.015], + [52.229, -60.931], + [54.014, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [58.138, -55.015], + [52.229, -49.106], + [47.606, -51.338], + [46.313, -55.015], + [52.229, -60.931], + [54.014, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 76, + "op": 301, + "st": 76, + "bm": 0 + }, + { + "ddd": 0, + "ind": 11, + "ty": 4, + "nm": "Layer 13", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [82.51, -5.017, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [32.51, -55.017, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 73, + "s": [0, 0, 100] + }, + { "t": 80, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -3.264], [3.266, 0], [0, 3.266], [-3.264, 0]], + "o": [[0, 3.266], [-3.264, 0], [0, -3.264], [3.266, 0]], + "v": [ + [38.42, -55.017], + [32.51, -49.104], + [26.599, -55.017], + [32.51, -60.928] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.392], + [3.263, 0], + [0.565, 0.184], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.27], + [-0.624, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [0.808, 1.011] + ], + "v": [ + [35.592, -56.972], + [29.683, -51.056], + [27.891, -51.338], + [26.597, -55.015], + [32.513, -60.931], + [34.299, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.639], + [3.263, 0], + [1.077, 1.359], + [0, 1.385], + [-3.27, 0], + [-0.565, -0.177] + ], + "o": [ + [0, 3.263], + [-1.878, 0], + [-0.814, -1.005], + [0, -3.263], + [0.624, 0], + [2.39, 0.755] + ], + "v": [ + [38.422, -55.015], + [32.513, -49.106], + [27.891, -51.338], + [26.597, -55.015], + [32.513, -60.931], + [34.299, -60.655] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 73, + "op": 298, + "st": 73, + "bm": 0 + }, + { + "ddd": 0, + "ind": 12, + "ty": 4, + "nm": "Layer 10", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [164.355, 132.081, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [114.355, 82.081, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 69, + "s": [0, 0, 100] + }, + { "t": 76, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.197, 0], + [0, 0], + [-0.048, 0.189], + [0, 0], + [0, 0.627], + [-1.032, 0], + [0, -1.032], + [0.471, -0.334], + [0, 0] + ], + "o": [ + [0, 0], + [-0.197, 0], + [0, 0], + [-0.471, -0.334], + [0, -1.032], + [1.032, 0], + [0, 0.627], + [0, 0], + [0.048, 0.189] + ], + "v": [ + [146.367, 90.785], + [142.986, 90.785], + [142.696, 90.41], + [143.591, 86.985], + [142.811, 85.47], + [144.678, 83.604], + [146.541, 85.47], + [145.762, 86.985], + [146.656, 90.41] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { "a": 0, "k": [1, 1, 1, 1], "ix": 4 }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0], [0, 0], [-2.681, 0], [0, -2.674]], + "o": [[0, 0], [0, 0], [0, -2.674], [2.667, 0], [0, 0]], + "v": [ + [149.241, 77.672], + [139.545, 77.672], + [139.545, 74.82], + [144.397, 69.975], + [149.241, 74.82] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [0.88, 0], + [0, 0], + [0, 0], + [4.072, 0], + [0, -4.064], + [0, 0], + [0, 0], + [0, -0.88], + [0, 0], + [-0.88, 0], + [0, 0], + [0, 0.88], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0], + [0, -4.064], + [-4.064, 0], + [0, 0], + [0, 0], + [-0.88, 0], + [0, 0], + [0, 0.88], + [0, 0], + [0.88, 0], + [0, 0], + [0, -0.88] + ], + "v": [ + [154.136, 77.672], + [151.767, 77.672], + [151.767, 74.82], + [144.39, 67.443], + [137.02, 74.82], + [137.02, 77.672], + [135.218, 77.672], + [133.629, 79.26], + [133.629, 95.128], + [135.218, 96.717], + [154.136, 96.717], + [155.725, 95.128], + [155.725, 79.26] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.988235294819, 0.376470595598, 0.329411774874, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0], [0, 0], [-2.681, 0], [0, -2.674]], + "o": [[0, 0], [0, 0], [0, -2.674], [2.667, 0], [0, 0]], + "v": [ + [150.668, 79.195], + [140.971, 79.195], + [140.971, 76.344], + [145.823, 71.499], + [150.668, 76.344] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [0.88, 0], + [0, 0], + [0, 0], + [4.072, 0], + [0, -4.064], + [0, 0], + [0, 0], + [0, -0.88], + [0, 0], + [-0.88, 0], + [0, 0], + [0, 0.88], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0], + [0, -4.064], + [-4.064, 0], + [0, 0], + [0, 0], + [-0.88, 0], + [0, 0], + [0, 0.88], + [0, 0], + [0.88, 0], + [0, 0], + [0, -0.88] + ], + "v": [ + [155.562, 79.195], + [153.193, 79.195], + [153.193, 76.344], + [145.816, 68.967], + [138.446, 76.344], + [138.446, 79.195], + [136.645, 79.195], + [135.056, 80.784], + [135.056, 96.652], + [136.645, 98.24], + [155.562, 98.24], + [157.151, 96.652], + [157.151, 80.784] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.882352948189, 0.898039221764, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -3.681], + [0, 0], + [3.681, 0], + [0, 0], + [0, 3.681], + [0, 0], + [-3.681, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 3.681], + [0, 0], + [-3.681, 0], + [0, 0], + [0, -3.681], + [0, 0], + [3.681, 0] + ], + "v": [ + [174.997, 62.972], + [174.997, 101.188], + [168.332, 107.854], + [121.021, 107.854], + [114.355, 101.188], + [114.355, 62.972], + [121.021, 56.306], + [168.332, 56.306] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.667], + [0, 0], + [3.681, 0], + [0, 0], + [1.125, 2.097], + [-1.009, 0], + [0, 0], + [0, 3.681], + [0, 0], + [0.502, 0.94] + ], + "o": [ + [0, 0], + [0, 3.681], + [0, 0], + [-2.546, 0], + [0.861, 0.401], + [0, 0], + [3.681, 0], + [0, 0], + [0, -1.141], + [2.266, 1.062] + ], + "v": [ + [175, 62.971], + [175, 101.19], + [168.329, 107.855], + [121.021, 107.855], + [115.142, 104.332], + [117.973, 104.961], + [165.282, 104.961], + [171.947, 98.295], + [171.947, 60.082], + [171.16, 56.934] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.800000011921, 0.823529422283, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -3.681], + [0, 0], + [3.681, 0], + [0, 0], + [0, 3.681], + [0, 0], + [-3.681, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 3.681], + [0, 0], + [-3.681, 0], + [0, 0], + [0, -3.681], + [0, 0], + [3.681, 0] + ], + "v": [ + [174.997, 62.972], + [174.997, 101.188], + [168.332, 107.854], + [121.021, 107.854], + [114.355, 101.188], + [114.355, 62.972], + [121.021, 56.306], + [168.332, 56.306] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { "a": 0, "k": [1, 1, 1, 1], "ix": 4 }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 69, + "op": 294, + "st": 69, + "bm": 0 + }, + { + "ddd": 0, + "ind": 13, + "ty": 4, + "nm": "Layer 9", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [50, 50, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [0, 0, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0], [0, 0]], + "o": [[0, 0], [0, 0], [0, 0]], + "v": [[114.355, 82.395], [76.46, 82.395], [76.46, 21.906]], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tm", + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 54, + "s": [100] + }, + { "t": 69, "s": [0] } + ], + "ix": 1 + }, + "e": { "a": 0, "k": 100, "ix": 2 }, + "o": { "a": 0, "k": 0, "ix": 3 }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1", + "mn": "ADBE Vector Filter - Trim", + "hd": false + } + ], + "ip": 54, + "op": 279, + "st": 54, + "bm": 0 + }, + { + "ddd": 0, + "ind": 14, + "ty": 4, + "nm": "Layer 12", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [-9.278, -73.213, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [-59.278, -123.213, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 58, + "s": [0, 0, 100] + }, + { "t": 65, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-0.571, 3.333], + [0, 0], + [1.642, 0], + [0.893, -0.452], + [0.547, -0.869], + [0, -1.214], + [-0.762, -0.702], + [-1.214, 0] + ], + "o": [ + [0, 0], + [-1.047, -1.094], + [-1.024, 0], + [-0.893, 0.453], + [-0.547, 0.869], + [0, 1.381], + [0.761, 0.702], + [2.904, 0] + ], + "v": [ + [-55.352, -149.756], + [-54.781, -153.077], + [-58.815, -154.719], + [-61.689, -154.041], + [-63.85, -152.059], + [-64.671, -148.934], + [-63.528, -145.811], + [-60.565, -144.757] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [1.905, 1.13], + [1.035, 1.893], + [0, 2.166], + [-1.381, 2.333], + [-2.32, 1.393], + [-2.69, 0], + [-2.083, -1.059], + [-1.226, -1.869], + [0, -2.38], + [0.465, -1.332], + [0.987, -0.857], + [1.523, 0], + [0.666, 0.524], + [0.143, 0.714], + [1.023, -0.44], + [1.143, 0], + [1.071, 1.166], + [0, 1.857], + [-0.798, 1.31], + [-1.298, 0.69], + [-1.453, 0], + [-1.262, -1.214], + [0, 0], + [-0.25, 0.214], + [-0.334, 0], + [-0.25, -0.25], + [0, -0.381], + [0, 0], + [0, 0], + [0, -0.666], + [-0.298, -0.441], + [-0.595, 0], + [-0.798, 1.286], + [0, 2.19], + [1.119, 1.583], + [1.796, 0.81], + [1.951, 0], + [2.035, -1.214], + [1.214, -2.047], + [0, -2.357], + [-0.846, -1.607], + [-1.606, -1], + [-2.214, 0], + [-1.071, 0.273], + [-1.381, 0.547], + [-0.119, 0], + [-0.167, -0.166], + [0, -0.238], + [0.095, -0.155], + [0.143, -0.071], + [2.975, 0] + ], + "o": [ + [-1.905, -1.131], + [-1.035, -1.892], + [0, -2.69], + [1.38, -2.333], + [2.321, -1.393], + [2.451, 0], + [2.083, 1.059], + [1.226, 1.869], + [0, 1.499], + [-0.464, 1.333], + [-0.988, 0.856], + [-1.19, 0], + [-0.666, -0.523], + [-0.738, 0.905], + [-1.023, 0.441], + [-1.905, 0], + [-1.071, -1.166], + [0, -1.785], + [0.797, -1.308], + [1.297, -0.69], + [1.785, 0], + [0, 0], + [0.047, -0.309], + [0.25, -0.214], + [0.357, 0], + [0.25, 0.25], + [0, 0], + [0, 0], + [-0.167, 0.881], + [0, 0.666], + [0.297, 0.441], + [1.475, 0], + [0.798, -1.285], + [0, -2.19], + [-1.119, -1.582], + [-1.798, -0.809], + [-2.357, 0], + [-2.035, 1.214], + [-1.214, 2.047], + [0, 1.762], + [0.844, 1.607], + [1.607, 0.999], + [1.451, 0], + [1.071, -0.274], + [0.143, -0.047], + [0.262, 0], + [0.166, 0.167], + [0, 0.166], + [-0.095, 0.155], + [-2.523, 1.261], + [-2.476, 0] + ], + "v": [ + [-67.599, -137.67], + [-72.008, -142.205], + [-73.561, -148.292], + [-71.49, -155.826], + [-65.938, -161.413], + [-58.422, -163.502], + [-51.621, -161.913], + [-46.658, -157.521], + [-44.819, -151.148], + [-45.515, -146.9], + [-47.693, -143.615], + [-51.46, -142.33], + [-54.245, -143.115], + [-55.459, -144.972], + [-58.101, -142.954], + [-61.35, -142.293], + [-65.813, -144.043], + [-67.42, -148.578], + [-66.224, -153.22], + [-63.082, -156.218], + [-58.958, -157.254], + [-54.387, -155.433], + [-54.281, -156.04], + [-53.834, -156.825], + [-52.96, -157.147], + [-52.049, -156.772], + [-51.674, -155.826], + [-51.71, -155.433], + [-52.888, -148.649], + [-53.138, -146.328], + [-52.692, -144.668], + [-51.353, -144.008], + [-47.943, -145.936], + [-46.747, -151.148], + [-48.425, -156.808], + [-52.799, -160.396], + [-58.422, -161.61], + [-65.01, -159.789], + [-69.883, -154.897], + [-71.704, -148.292], + [-70.437, -143.24], + [-66.76, -139.33], + [-61.028, -137.831], + [-57.244, -138.241], + [-53.566, -139.473], + [-53.174, -139.544], + [-52.531, -139.295], + [-52.281, -138.688], + [-52.424, -138.206], + [-52.781, -137.866], + [-61.028, -135.974] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-0.571, 3.333], + [0, 0], + [1.642, 0], + [0.893, -0.452], + [0.547, -0.869], + [0, -1.214], + [-0.762, -0.702], + [-1.214, 0] + ], + "o": [ + [0, 0], + [-1.047, -1.094], + [-1.024, 0], + [-0.893, 0.453], + [-0.547, 0.869], + [0, 1.381], + [0.761, 0.702], + [2.904, 0] + ], + "v": [ + [-54.386, -148.849], + [-53.815, -152.17], + [-57.849, -153.812], + [-60.723, -153.133], + [-62.884, -151.151], + [-63.705, -148.027], + [-62.562, -144.904], + [-59.599, -143.85] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [1.905, 1.13], + [1.035, 1.893], + [0, 2.166], + [-1.381, 2.333], + [-2.32, 1.393], + [-2.69, 0], + [-2.083, -1.059], + [-1.226, -1.869], + [0, -2.38], + [0.465, -1.332], + [0.987, -0.857], + [1.523, 0], + [0.666, 0.524], + [0.143, 0.714], + [1.023, -0.44], + [1.143, 0], + [1.071, 1.166], + [0, 1.857], + [-0.798, 1.31], + [-1.298, 0.69], + [-1.453, 0], + [-1.262, -1.214], + [0, 0], + [-0.25, 0.214], + [-0.334, 0], + [-0.25, -0.25], + [0, -0.381], + [0, 0], + [0, 0], + [0, -0.666], + [-0.298, -0.441], + [-0.595, 0], + [-0.798, 1.286], + [0, 2.19], + [1.119, 1.583], + [1.796, 0.81], + [1.951, 0], + [2.035, -1.214], + [1.214, -2.047], + [0, -2.357], + [-0.846, -1.607], + [-1.606, -1], + [-2.214, 0], + [-1.071, 0.273], + [-1.381, 0.547], + [-0.119, 0], + [-0.167, -0.166], + [0, -0.238], + [0.095, -0.155], + [0.143, -0.071], + [2.975, 0] + ], + "o": [ + [-1.905, -1.131], + [-1.035, -1.892], + [0, -2.69], + [1.38, -2.333], + [2.321, -1.393], + [2.451, 0], + [2.083, 1.059], + [1.226, 1.869], + [0, 1.499], + [-0.464, 1.333], + [-0.988, 0.856], + [-1.19, 0], + [-0.666, -0.523], + [-0.738, 0.905], + [-1.023, 0.441], + [-1.905, 0], + [-1.071, -1.166], + [0, -1.785], + [0.797, -1.308], + [1.297, -0.69], + [1.785, 0], + [0, 0], + [0.047, -0.309], + [0.25, -0.214], + [0.357, 0], + [0.25, 0.25], + [0, 0], + [0, 0], + [-0.167, 0.881], + [0, 0.666], + [0.297, 0.441], + [1.475, 0], + [0.798, -1.285], + [0, -2.19], + [-1.119, -1.582], + [-1.798, -0.809], + [-2.357, 0], + [-2.035, 1.214], + [-1.214, 2.047], + [0, 1.762], + [0.844, 1.607], + [1.607, 0.999], + [1.451, 0], + [1.071, -0.274], + [0.143, -0.047], + [0.262, 0], + [0.166, 0.167], + [0, 0.166], + [-0.095, 0.155], + [-2.523, 1.261], + [-2.476, 0] + ], + "v": [ + [-66.633, -136.763], + [-71.042, -141.297], + [-72.595, -147.385], + [-70.524, -154.919], + [-64.973, -160.506], + [-57.456, -162.595], + [-50.655, -161.006], + [-45.692, -156.614], + [-43.853, -150.241], + [-44.549, -145.992], + [-46.727, -142.707], + [-50.494, -141.422], + [-53.279, -142.208], + [-54.493, -144.065], + [-57.135, -142.047], + [-60.384, -141.386], + [-64.847, -143.136], + [-66.454, -147.671], + [-65.258, -152.312], + [-62.116, -155.311], + [-57.992, -156.347], + [-53.421, -154.526], + [-53.315, -155.133], + [-52.868, -155.918], + [-51.994, -156.24], + [-51.083, -155.865], + [-50.708, -154.919], + [-50.744, -154.526], + [-51.922, -147.742], + [-52.172, -145.421], + [-51.726, -143.761], + [-50.387, -143.101], + [-46.977, -145.029], + [-45.781, -150.241], + [-47.459, -155.901], + [-51.833, -159.489], + [-57.456, -160.702], + [-64.044, -158.882], + [-68.917, -153.99], + [-70.738, -147.385], + [-69.471, -142.333], + [-65.794, -138.423], + [-60.063, -136.924], + [-56.278, -137.334], + [-52.6, -138.566], + [-52.208, -138.637], + [-51.565, -138.387], + [-51.315, -137.781], + [-51.458, -137.299], + [-51.815, -136.959], + [-60.063, -135.067] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.882352948189, 0.898039221764, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -3.681], + [0, 0], + [3.681, 0], + [0, 0], + [0, 3.681], + [0, 0], + [-3.681, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 3.681], + [0, 0], + [-3.681, 0], + [0, 0], + [0, -3.681], + [0, 0], + [3.681, 0] + ], + "v": [ + [-28.958, -168.096], + [-28.958, -129.88], + [-35.624, -123.214], + [-82.935, -123.214], + [-89.6, -129.88], + [-89.6, -168.096], + [-82.935, -174.762], + [-35.624, -174.762] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.667], + [0, 0], + [3.681, 0], + [0, 0], + [1.125, 2.097], + [-1.009, 0], + [0, 0], + [0, 3.681], + [0, 0], + [0.502, 0.94] + ], + "o": [ + [0, 0], + [0, 3.681], + [0, 0], + [-2.546, 0], + [0.861, 0.401], + [0, 0], + [3.681, 0], + [0, 0], + [0, -1.141], + [2.266, 1.062] + ], + "v": [ + [-28.955, -168.097], + [-28.955, -129.878], + [-35.626, -123.213], + [-82.935, -123.213], + [-88.813, -126.736], + [-85.982, -126.107], + [-38.674, -126.107], + [-32.008, -132.773], + [-32.008, -170.986], + [-32.795, -174.134] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.800000011921, 0.823529422283, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -3.681], + [0, 0], + [3.681, 0], + [0, 0], + [0, 3.681], + [0, 0], + [-3.681, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 3.681], + [0, 0], + [-3.681, 0], + [0, 0], + [0, -3.681], + [0, 0], + [3.681, 0] + ], + "v": [ + [-28.958, -168.096], + [-28.958, -129.88], + [-35.624, -123.214], + [-82.935, -123.214], + [-89.6, -129.88], + [-89.6, -168.096], + [-82.935, -174.762], + [-35.624, -174.762] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { "a": 0, "k": [1, 1, 1, 1], "ix": 4 }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 58, + "op": 283, + "st": 58, + "bm": 0 + }, + { + "ddd": 0, + "ind": 15, + "ty": 4, + "nm": "Layer 11", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [50, 50, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [0, 0, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0], [0, 0]], + "o": [[0, 0], [0, 0], [0, 0]], + "v": [ + [-59.279, -123.213], + [-59.279, -83.87], + [-4.302, -83.87] + ], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tm", + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 43, + "s": [100] + }, + { "t": 58, "s": [0] } + ], + "ix": 1 + }, + "e": { "a": 0, "k": 100, "ix": 2 }, + "o": { "a": 0, "k": 0, "ix": 3 }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1", + "mn": "ADBE Vector Filter - Trim", + "hd": false + } + ], + "ip": 43, + "op": 268, + "st": 43, + "bm": 0 + }, + { + "ddd": 0, + "ind": 16, + "ty": 4, + "nm": "Layer 8", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [130.376, 36.52, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [80.376, -13.48, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.332, 0.332, 0.667], "y": [1, 1, 1] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0] }, + "t": 42, + "s": [0, 0, 100] + }, + { "t": 51, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.916], + [0, 0], + [1.916, 0], + [0, 0], + [0, 1.916], + [0, 0], + [-1.916, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 1.916], + [0, 0], + [-1.916, 0], + [0, 0], + [0, -1.916], + [0, 0], + [1.916, 0] + ], + "v": [ + [145.529, -25.093], + [145.529, -4.702], + [142.06, -1.233], + [21.286, -1.233], + [17.816, -4.702], + [17.816, -25.093], + [21.286, -28.562], + [142.06, -28.562] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { "a": 0, "k": [1, 1, 1, 1], "ix": 4 }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.916], + [0, 0], + [1.916, 0], + [0, 0], + [0, 1.916], + [0, 0], + [-1.916, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 1.916], + [0, 0], + [-1.916, 0], + [0, 0], + [0, -1.916], + [0, 0], + [1.916, 0] + ], + "v": [ + [142.936, -22.258], + [142.936, -1.867], + [139.466, 1.602], + [18.692, 1.602], + [15.223, -1.867], + [15.223, -22.258], + [18.692, -25.727], + [139.466, -25.727] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.800000011921, 0.823529422283, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 42, + "op": 267, + "st": 42, + "bm": 0 + }, + { + "ddd": 0, + "ind": 17, + "ty": 4, + "nm": "Layer 7", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [130.376, -3.6, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [80.376, -53.6, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.332, 0.332, 0.667], "y": [1, 1, 1] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0] }, + "t": 38, + "s": [0, 0, 100] + }, + { "t": 47, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.916], + [0, 0], + [1.916, 0], + [0, 0], + [0, 1.916], + [0, 0], + [-1.916, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 1.916], + [0, 0], + [-1.916, 0], + [0, 0], + [0, -1.916], + [0, 0], + [1.916, 0] + ], + "v": [ + [145.529, -65.213], + [145.529, -44.822], + [142.06, -41.352], + [21.286, -41.352], + [17.816, -44.822], + [17.816, -65.213], + [21.286, -68.682], + [142.06, -68.682] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { "a": 0, "k": [1, 1, 1, 1], "ix": 4 }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.916], + [0, 0], + [1.916, 0], + [0, 0], + [0, 1.916], + [0, 0], + [-1.916, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 1.916], + [0, 0], + [-1.916, 0], + [0, 0], + [0, -1.916], + [0, 0], + [1.916, 0] + ], + "v": [ + [142.936, -62.378], + [142.936, -41.986], + [139.466, -38.517], + [18.692, -38.517], + [15.223, -41.986], + [15.223, -62.378], + [18.692, -65.847], + [139.466, -65.847] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.800000011921, 0.823529422283, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 38, + "op": 263, + "st": 38, + "bm": 0 + }, + { + "ddd": 0, + "ind": 18, + "ty": 4, + "nm": "Layer 6", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [129.267, -53.741, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [79.267, -103.741, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.667, 0.667, 0.667], "y": [1, 1, 1] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0] }, + "t": 28, + "s": [0, 0, 100] + }, + { "t": 34, "s": [100, 100, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0.106, 0.886], + [7.475, 0], + [0.867, -7.236], + [-0.893, 0] + ], + "o": [ + [0.893, 0], + [-0.866, -7.236], + [-7.47, 0], + [-0.106, 0.886], + [0, 0] + ], + "v": [ + [93.726, -91.881], + [95.21, -93.548], + [80.713, -106.397], + [66.216, -93.548], + [67.699, -91.881] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [ + 0.066666670144, 0.145098045468, + 0.266666680574, 1 + ], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.892, 0], + [0, 0], + [-7.199, 0], + [-1.566, -0.587], + [-0.457, -3.82] + ], + "o": [ + [0, 0], + [1.196, -6.851], + [1.769, 0], + [2.813, 2.32], + [0.101, 0.892] + ], + "v": [ + [89.466, -94.33], + [66.334, -94.33], + [80.716, -106.4], + [85.747, -105.501], + [90.952, -95.997] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 0.760784327984, 0.368627458811, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.892, 0], + [0, 0], + [-0.109, 0.884], + [-0.043, 0.261], + [-7.199, 0], + [-1.566, -0.587], + [-0.66, -5.524] + ], + "o": [ + [0, 0], + [-0.892, 0], + [0.029, -0.261], + [1.196, -6.851], + [1.769, 0], + [5.06, 1.849], + [0.109, 0.884] + ], + "v": [ + [93.729, -91.88], + [67.696, -91.88], + [66.218, -93.547], + [66.334, -94.33], + [80.716, -106.4], + [85.747, -105.501], + [95.208, -93.547] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.937254905701, 0.631372570992, + 0.188235297799, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -3.212], + [3.214, 0], + [0, 3.214], + [-3.212, 0] + ], + "o": [ + [0, 3.214], + [-3.212, 0], + [0, -3.212], + [3.214, 0] + ], + "v": [ + [86.53, -114.698], + [80.713, -108.879], + [74.896, -114.698], + [80.713, -120.515] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [ + 0.066666670144, 0.145098045468, + 0.266666680574, 1 + ], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -1.37], + [3.211, 0], + [0.556, 0.181], + [0, 1.363], + [-3.218, 0], + [-0.556, -0.174] + ], + "o": [ + [0, 3.218], + [-0.614, 0], + [-0.801, -0.989], + [0, -3.211], + [0.614, 0], + [0.795, 0.995] + ], + "v": [ + [83.746, -116.622], + [77.931, -110.8], + [76.167, -111.078], + [74.894, -114.696], + [80.716, -120.518], + [82.473, -120.247] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 0.760784327984, 0.368627458811, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -2.597], + [3.211, 0], + [1.06, 1.338], + [0, 1.363], + [-3.218, 0], + [-0.556, -0.174] + ], + "o": [ + [0, 3.211], + [-1.848, 0], + [-0.801, -0.989], + [0, -3.211], + [0.614, 0], + [2.352, 0.743] + ], + "v": [ + [86.531, -114.696], + [80.716, -108.881], + [76.167, -111.078], + [74.894, -114.696], + [80.716, -120.518], + [82.473, -120.247] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.937254905701, 0.631372570992, + 0.188235297799, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -14.04], [14.04, 0], [0, 14.04], [-14.04, 0]], + "o": [[0, 14.04], [-14.04, 0], [0, -14.04], [14.04, 0]], + "v": [ + [106.163, -105.17], + [80.744, -79.751], + [55.326, -105.17], + [80.744, -130.594] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { "a": 0, "k": [1, 1, 1, 1], "ix": 4 }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, -14.04], [14.04, 0], [0, 14.04], [-14.04, 0]], + "o": [[0, 14.04], [-14.04, 0], [0, -14.04], [14.04, 0]], + "v": [ + [103.208, -102.307], + [77.79, -76.888], + [52.371, -102.307], + [77.79, -127.731] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.800000011921, 0.823529422283, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 28, + "op": 253, + "st": 28, + "bm": 0 + }, + { + "ddd": 0, + "ind": 19, + "ty": 4, + "nm": "Layer 5", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.667, "y": 1 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 13, + "s": [130.714, -314.712, 0], + "to": [0, 50.179, 0], + "ti": [0, -50.179, 0] + }, + { "t": 24, "s": [130.714, -13.639, 0] } + ], + "ix": 2, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + }, + "a": { "a": 0, "k": [80.714, -63.639, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -4.774], + [0, 0], + [4.774, 0], + [0, 0], + [0, 4.774], + [0, 0], + [-4.774, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 4.774], + [0, 0], + [-4.774, 0], + [0, 0], + [0, -4.774], + [0, 0], + [4.774, 0] + ], + "v": [ + [157.526, -131.81], + [157.526, 4.531], + [148.882, 13.175], + [12.545, 13.175], + [3.901, 4.531], + [3.901, -131.81], + [12.545, -140.454], + [148.882, -140.454] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.882352948189, 0.898039221764, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, 9.289], + [0, 0], + [-9.289, 0], + [0, 0], + [0, -9.289], + [0, 0], + [9.289, 0] + ], + "o": [ + [-9.289, 0], + [0, 0], + [0, -9.289], + [0, 0], + [9.289, 0], + [0, 0], + [0, 9.289], + [0, 0] + ], + "v": [ + [12.545, 21.378], + [-4.302, 4.531], + [-4.302, -131.81], + [12.545, -148.657], + [148.882, -148.657], + [165.729, -131.81], + [165.729, 4.531], + [148.882, 21.378] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { "a": 0, "k": [1, 1, 1, 1], "ix": 4 }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 13, + "op": 237, + "st": 12, + "bm": 0 + }, + { + "ddd": 0, + "ind": 20, + "ty": 4, + "nm": "ara,m", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { + "a": 1, + "k": [ + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 30, + "s": [0] + }, + { "t": 98, "s": [0] } + ], + "ix": 10 + }, + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 5, + "s": [-2.078, 52.089, 0], + "to": [0.167, -2.583, 0], + "ti": [-0.167, 2.583, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 20, + "s": [-1.078, 36.589, 0], + "to": [0, 0, 0], + "ti": [0, 0, 0] + }, + { + "i": { "x": 0.417, "y": 1 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [-1.078, 36.589, 0], + "to": [-0.167, 2.583, 0], + "ti": [0.167, -2.583, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.333, "y": 0.333 }, + "t": 45, + "s": [-2.078, 52.089, 0], + "to": [0, 0, 0], + "ti": [0, 0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 73, + "s": [-2.078, 52.089, 0], + "to": [0.167, -2.583, 0], + "ti": [-0.167, 2.583, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 88, + "s": [-1.078, 36.589, 0], + "to": [0, 0, 0], + "ti": [0, 0, 0] + }, + { + "i": { "x": 0.417, "y": 1 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 98, + "s": [-1.078, 36.589, 0], + "to": [-0.167, 2.583, 0], + "ti": [0.167, -2.583, 0] + }, + { "t": 113, "s": [-2.078, 52.089, 0] } + ], + "ix": 2, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + }, + "a": { "a": 0, "k": [-59.828, 4.589, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [1.07, -1.02], + [1.879, 1.486], + [-1.76, 0.352], + [-0.844, -1.016], + [-1.009, 0.561], + [-0.966, -1.246], + [-0.844, 0.212], + [-1.117, -1.568], + [-0.887, 0.408], + [0, 0], + [-0.96, -0.798] + ], + "o": [ + [-1.793, 1.7], + [-0.935, -0.748], + [0.833, -0.167], + [-0.973, -2.096], + [0.757, -0.42], + [-0.94, -2.072], + [1.001, -0.251], + [-0.784, -1.879], + [1.787, -0.822], + [0, 0], + [1.405, 1.184] + ], + "v": [ + [-55.305, 7.805], + [-63.859, 10.193], + [-66.125, 3.996], + [-63.739, 6.113], + [-65.138, 1.49], + [-62.338, 3.864], + [-63.834, -0.453], + [-60.403, 2.43], + [-61.343, -1.445], + [-56.729, 4.923], + [-53.456, 3.136] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.988235294819, 0.733333349228, 0.643137276173, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 21, + "ty": 4, + "nm": "aram 2", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { + "a": 1, + "k": [ + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 5, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 20, + "s": [-16] + }, + { + "i": { "x": [0.417], "y": [1] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 30, + "s": [-16] + }, + { + "i": { "x": [0.833], "y": [1] }, + "o": { "x": [0.333], "y": [0] }, + "t": 45, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 73, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 88, + "s": [-16] + }, + { + "i": { "x": [0.417], "y": [1] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 98, + "s": [-16] + }, + { "t": 113, "s": [0] } + ], + "ix": 10, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + }, + "p": { "a": 0, "k": [-81.063, 14.415, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [-131.063, -35.585, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0.091, -0.723], + [-1.528, -4.691], + [0, 0], + [-0.479, -1.075], + [-9.386, -5.198], + [1.243, 6.002], + [0, 0] + ], + "o": [ + [-0.127, 0.534], + [-0.613, 4.895], + [0, 0], + [0.369, 1.135], + [6.571, -4.782], + [-4.502, -3.818], + [0, 0], + [0, 0] + ], + "v": [ + [-130.737, -36.374], + [-131.062, -34.46], + [-129.622, -19.903], + [-129.622, -19.903], + [-128.346, -16.589], + [-104.587, -16.589], + [-113.558, -31.664], + [-114.965, -38.458] + ], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, 0], + [-10.005, -2.524], + [0, 0], + [-1.404, -1.357], + [0, 0], + [-0.687, -2.571], + [2.079, 0.616], + [-0.284, -1.06], + [2.299, 0.764], + [-0.237, -0.889], + [2.328, 0.788], + [-0.207, -0.77], + [0, 0], + [0, 0], + [2.559, 0.752], + [3.934, 3.365], + [1.748, 5.373], + [-0.616, 4.899], + [-0.13, 0.533] + ], + "o": [ + [0, 0], + [2.091, 10.106], + [0, 0], + [0, 0], + [0.96, 0.924], + [0, 0], + [0.379, 1.422], + [1.783, 1.007], + [0.439, 1.635], + [1.428, 0.883], + [0.45, 1.706], + [1.167, 0.776], + [0.687, 2.571], + [0, 0], + [-2.654, -0.296], + [-5.213, -1.522], + [-3.934, -3.365], + [-1.528, -4.692], + [0.089, -0.723], + [0, 0] + ], + "v": [ + [-114.966, -38.46], + [-113.556, -31.666], + [-93.776, -11.009], + [-73.084, -5.743], + [-67.231, -8.071], + [-68.748, -4.404], + [-60.064, 0.37], + [-63.914, -0.109], + [-60.484, 2.947], + [-65.212, 2.1], + [-62.552, 4.588], + [-67.433, 3.836], + [-64.963, 5.382], + [-74.702, 4.612], + [-99.078, 1.97], + [-106.927, 0.453], + [-120.872, -6.839], + [-129.621, -19.901], + [-131.061, -34.462], + [-130.735, -36.375] + ], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.113, -0.752], + [0.107, -0.13], + [0, 0], + [0, 0], + [2.559, 0.752], + [3.934, 3.365], + [1.765, 5.154], + [-1.706, 0.284], + [-0.355, -1.505], + [-3.632, -2.938], + [-2.524, -0.735], + [-5.681, -0.308], + [-5.646, -2.909] + ], + "o": [ + [-0.03, 0.178], + [-0.8, -0.231], + [0, 0], + [-2.654, -0.296], + [-5.213, -1.522], + [-3.815, -3.264], + [0.231, -1.475], + [2.174, -0.361], + [1.078, 4.544], + [2.038, 1.659], + [5.468, 1.582], + [6.344, 0.338], + [0.675, 0.349] + ], + "v": [ + [-73.179, 4.547], + [-73.386, 5.009], + [-74.702, 4.612], + [-99.078, 1.97], + [-106.927, 0.453], + [-120.872, -6.839], + [-129.455, -19.427], + [-126.813, -22.484], + [-123.988, -18.456], + [-116.672, -6.863], + [-109.747, -3.196], + [-92.769, -2.064], + [-74.512, 2.882] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.949019610882, 0.627451002598, 0.486274510622, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [2.079, 0.616], + [-0.284, -1.06], + [2.299, 0.764], + [-0.237, -0.889], + [2.328, 0.788], + [-0.207, -0.77], + [2.778, 0.8], + [0, 0], + [0, 0], + [2.559, 0.752], + [3.934, 3.365], + [1.765, 5.154], + [0.054, 0.16], + [-0.616, 4.899], + [-0.13, 0.533], + [0, 0], + [0, 0], + [-10.005, -2.524], + [0, 0], + [-1.404, -1.357], + [0, 0], + [-0.687, -2.571] + ], + "o": [ + [1.783, 1.007], + [0.439, 1.635], + [1.428, 0.883], + [0.45, 1.706], + [1.167, 0.776], + [0.533, 1.996], + [-0.8, -0.231], + [0, 0], + [-2.654, -0.296], + [-5.213, -1.522], + [-3.815, -3.264], + [-0.059, -0.154], + [-1.528, -4.692], + [0.089, -0.723], + [0, 0], + [0, 0], + [2.091, 10.106], + [0, 0], + [0, 0], + [0.96, 0.924], + [0, 0], + [0.379, 1.422] + ], + "v": [ + [-63.914, -0.109], + [-60.484, 2.947], + [-65.212, 2.1], + [-62.552, 4.588], + [-67.433, 3.836], + [-64.963, 5.382], + [-73.386, 5.009], + [-74.702, 4.612], + [-99.078, 1.97], + [-106.927, 0.453], + [-120.872, -6.839], + [-129.455, -19.427], + [-129.621, -19.901], + [-131.061, -34.462], + [-130.735, -36.375], + [-114.966, -38.46], + [-113.556, -31.666], + [-93.776, -11.009], + [-73.084, -5.743], + [-67.231, -8.071], + [-68.748, -4.404], + [-60.064, 0.37] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.988235294819, 0.733333349228, 0.643137276173, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 22, + "ty": 4, + "nm": "key", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { + "a": 1, + "k": [ + { + "i": { "x": [0.573], "y": [1] }, + "o": { "x": [0.167], "y": [0] }, + "t": 5, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [1] }, + "o": { "x": [0.333], "y": [0] }, + "t": 45, + "s": [0] + }, + { + "i": { "x": [0.573], "y": [1] }, + "o": { "x": [0.167], "y": [0] }, + "t": 73, + "s": [0] + }, + { "t": 113, "s": [0] } + ], + "ix": 10 + }, + "p": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 5, + "s": [-19.672, 51.711, 0], + "to": [0.5, -2.75, 0], + "ti": [-0.5, 2.75, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 20, + "s": [-16.672, 35.211, 0], + "to": [0, 0, 0], + "ti": [0, 0, 0] + }, + { + "i": { "x": 0.417, "y": 1 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [-16.672, 35.211, 0], + "to": [1.345, -3.362, 0], + "ti": [0.5, -2.75, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.333, "y": 0.333 }, + "t": 45, + "s": [-19.672, 51.711, 0], + "to": [0, 0, 0], + "ti": [0, 0, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 73, + "s": [-19.672, 51.711, 0], + "to": [0.5, -2.75, 0], + "ti": [-0.5, 2.75, 0] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 88, + "s": [-16.672, 35.211, 0], + "to": [0, 0, 0], + "ti": [0, 0, 0] + }, + { + "i": { "x": 0.417, "y": 1 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 98, + "s": [-16.672, 35.211, 0], + "to": [1.345, -3.362, 0], + "ti": [0.5, -2.75, 0] + }, + { "t": 113, "s": [-19.672, 51.711, 0] } + ], + "ix": 2, + "l": 2, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + }, + "a": { "a": 0, "k": [-69.672, 1.711, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [2.358, -1.148], + [1.148, 2.357], + [0, 0], + [-2.364, 1.151], + [-1.153, -0.393], + [-0.574, -1.179], + [0, 0] + ], + "o": [ + [-2.364, 1.151], + [0, 0], + [-1.148, -2.357], + [1.172, -0.571], + [1.14, 0.399], + [0, 0], + [1.148, 2.357] + ], + "v": [ + [-146.371, 53.3], + [-152.72, 51.109], + [-159.892, 36.381], + [-157.698, 30.038], + [-154.069, 29.814], + [-151.353, 32.223], + [-144.18, 46.951] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [0.78, 1.602], + [0, 0], + [0, 0], + [2.124, 4.362], + [4.312, -2.1], + [0, 0], + [13.84, -6.74], + [-7.664, -15.739], + [-16.438, 8.005], + [1.881, 13.438], + [0, 0], + [0, 0], + [-1.616, 0.787], + [0, 0], + [0.756, 1.553], + [0, 0], + [0, 0], + [0, 0], + [-1.56, 0.76], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0], + [4.312, -2.1], + [-2.124, -4.362], + [0, 0], + [-9.313, -10.571], + [-16.438, 8.005], + [7.664, 15.739], + [13.389, -6.52], + [0, 0], + [0, 0], + [0.756, 1.553], + [0, 0], + [1.602, -0.78], + [0, 0], + [0, 0], + [0, 0], + [0.78, 1.602], + [0, 0], + [1.602, -0.78] + ], + "v": [ + [-12.768, 11.507], + [-23.536, -10.606], + [-12.413, -16.022], + [-8.368, -27.745], + [-20.087, -31.783], + [-115.697, 14.776], + [-154.853, 7.597], + [-170.78, 50.611], + [-127.093, 64.603], + [-108.383, 30.712], + [-74.611, 14.266], + [-68.613, 26.582], + [-64.31, 28.066], + [-55.481, 23.767], + [-54.003, 19.467], + [-60.001, 7.152], + [-38.096, -3.515], + [-27.328, 18.597], + [-23.075, 20.106], + [-14.238, 15.803] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [1.298, -1.391], + [0.546, -0.266], + [1.152, 2.356], + [0, 0], + [0, 0], + [-2.37, 1.152], + [-1.152, -0.393], + [-0.573, -1.178], + [0, 0] + ], + "o": [ + [-0.386, 0.419], + [-2.363, 1.152], + [0, 0], + [0, 0], + [-1.145, -2.356], + [1.172, -0.573], + [1.138, 0.399], + [0, 0], + [0.885, 1.811] + ], + "v": [ + [-144.974, 52.26], + [-146.372, 53.299], + [-152.722, 51.109], + [-159.099, 38.015], + [-159.891, 36.384], + [-157.694, 30.041], + [-154.067, 29.814], + [-151.351, 32.224], + [-144.182, 46.955] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [0.06, 0.12], + [4.307, -2.097], + [0, 0], + [13.839, -6.736], + [1.205, -10.797], + [-1.558, -3.189], + [-16.435, 8.008], + [-1.205, 10.777], + [-0.02, 0.299], + [0.32, 2.276], + [0, 0], + [0, 0], + [-1.618, 0.785], + [0, 0], + [-0.047, 0.027], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [-1.564, 0.759], + [0, 0], + [-0.047, 0.027], + [0, 0], + [0, 0], + [0, 0], + [-0.805, 1.871] + ], + "o": [ + [-2.123, -4.36], + [0, 0], + [-9.313, -10.571], + [-10.804, 5.265], + [0.379, 3.355], + [7.668, 15.743], + [10.824, -5.265], + [0.04, -0.299], + [0.193, -2.27], + [0, 0], + [0, 0], + [0.752, 1.551], + [0, 0], + [0.053, -0.027], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0.779, 1.604], + [0, 0], + [0.053, -0.027], + [0, 0], + [0, 0], + [0, 0], + [1.957, -0.952], + [-0.053, -0.12] + ], + "v": [ + [-8.369, -27.745], + [-20.085, -31.785], + [-115.7, 14.777], + [-154.853, 7.595], + [-173.658, 33.795], + [-170.783, 43.673], + [-127.096, 57.665], + [-108.284, 31.512], + [-108.198, 30.62], + [-108.384, 23.777], + [-74.609, 7.328], + [-68.611, 19.65], + [-64.311, 21.134], + [-55.478, 16.834], + [-55.331, 16.754], + [-60.004, 7.149], + [-60.004, 7.155], + [-62.733, 1.551], + [-38.097, -10.451], + [-27.327, 11.662], + [-23.074, 13.173], + [-14.24, 8.866], + [-14.094, 8.786], + [-23.533, -10.604], + [-26.262, -16.209], + [-12.41, -22.959], + [-8.203, -27.385] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 0.760784327984, 0.368627458811, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [2.356, -1.145], + [1.152, 2.356], + [0, 0], + [-1.298, 1.391], + [-0.546, 0.266], + [-1.152, -0.393], + [-0.572, -1.178], + [0, 0], + [0, 0] + ], + "o": [ + [-2.363, 1.152], + [0, 0], + [-0.879, -1.817], + [0.386, -0.419], + [1.172, -0.572], + [1.138, 0.399], + [0, 0], + [0, 0], + [1.152, 2.363] + ], + "v": [ + [-146.373, 53.299], + [-152.723, 51.109], + [-159.892, 36.384], + [-159.1, 31.079], + [-157.696, 30.041], + [-154.068, 29.814], + [-151.352, 32.224], + [-144.975, 45.324], + [-144.183, 46.948] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [1.857, 4.287], + [0.06, 0.12], + [4.307, -2.097], + [0, 0], + [13.839, -6.736], + [1.205, -10.797], + [-2.623, -5.385], + [-16.435, 8.008], + [1.498, 13.187], + [0.04, 0.266], + [0, 0], + [0, 0], + [0, 0], + [-1.618, 0.792], + [0, 0], + [0.759, 1.551], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [-1.564, 0.765], + [0, 0], + [0.779, 1.598], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "o": [ + [-0.053, -0.12], + [-2.123, -4.36], + [0, 0], + [-9.313, -10.571], + [-10.804, 5.265], + [-0.632, 5.625], + [7.668, 15.743], + [13.127, -6.39], + [-0.027, -0.266], + [0, 0], + [0, 0], + [0, 0], + [0.752, 1.558], + [0, 0], + [1.598, -0.779], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0.779, 1.604], + [0, 0], + [1.604, -0.779], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [4.187, -2.037] + ], + "v": [ + [-8.203, -27.385], + [-8.369, -27.745], + [-20.085, -31.785], + [-115.7, 14.777], + [-154.853, 7.595], + [-173.658, 33.795], + [-170.783, 50.609], + [-127.096, 64.601], + [-108.284, 31.512], + [-108.384, 30.713], + [-108.198, 30.62], + [-74.609, 14.265], + [-68.611, 26.579], + [-64.311, 28.064], + [-55.478, 23.763], + [-54.007, 19.47], + [-55.331, 16.754], + [-60.004, 7.149], + [-57.275, 5.824], + [-38.097, -3.515], + [-27.327, 18.598], + [-23.074, 20.102], + [-14.24, 15.802], + [-12.769, 11.509], + [-14.094, 8.786], + [-23.533, -10.604], + [-20.804, -11.936], + [-12.41, -16.023] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.937254905701, 0.631372570992, 0.188235297799, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 23, + "ty": 4, + "nm": "head", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { + "a": 1, + "k": [ + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 5, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 20, + "s": [-12] + }, + { + "i": { "x": [0.512], "y": [1] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 30, + "s": [-12] + }, + { + "i": { "x": [0.833], "y": [1] }, + "o": { "x": [0.333], "y": [0] }, + "t": 45, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 60, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 73, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 88, + "s": [-12] + }, + { + "i": { "x": [0.512], "y": [1] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 98, + "s": [-12] + }, + { + "i": { "x": [0.833], "y": [1] }, + "o": { "x": [0.333], "y": [0] }, + "t": 113, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 123, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 137, + "s": [8] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 151, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 165, + "s": [8] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 178, + "s": [0] + }, + { "t": 192, "s": [8] } + ], + "ix": 10, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + }, + "p": { "a": 0, "k": [-47.658, -4.128, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [-97.658, -54.128, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + }, + { + "ty": 5, + "nm": "Kleaner 2", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 2, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-0.124, -0.448], + [0.448, -0.124], + [0.124, 0.448], + [-0.448, 0.124] + ], + "o": [ + [0.124, 0.448], + [-0.448, 0.124], + [-0.124, -0.448], + [0.448, -0.124] + ], + "v": [ + [-93.489, -75.251], + [-94.094, -74.215], + [-95.146, -74.791], + [-94.547, -75.85] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [-94.318, -75.031], "ix": 2 }, + "a": { "a": 0, "k": [-94.318, -75.031], "ix": 1 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 0, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 5, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 10, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 20, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 25, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 30, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 40, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 45, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 50, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 60, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 65, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 70, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 80, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 85, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 90, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 100, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 105, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 110, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 120, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 125, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 130, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 140, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 145, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 150, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 160, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 165, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 170, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 180, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 185, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 190, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 200, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 205, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 210, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 220, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 225, + "s": [20, 20] + }, + { "t": 230, "s": [100, 100] } + ], + "ix": 3 + }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 20", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-0.124, -0.448], + [0.448, -0.124], + [0.124, 0.448], + [-0.448, 0.124] + ], + "o": [ + [0.124, 0.448], + [-0.448, 0.124], + [-0.124, -0.448], + [0.448, -0.124] + ], + "v": [ + [-84.433, -78.069], + [-85.038, -77.033], + [-86.09, -77.609], + [-85.491, -78.668] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [-85.261, -77.849], "ix": 2 }, + "a": { "a": 0, "k": [-85.261, -77.849], "ix": 1 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 0, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 5, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 10, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 20, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 25, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 30, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 40, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 45, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 50, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 60, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 65, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 70, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 80, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 85, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 90, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 100, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 105, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 110, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 120, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 125, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 130, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 140, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 145, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 150, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 160, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 165, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 170, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 180, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 185, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 190, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 200, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 205, + "s": [20, 20] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 210, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 220, + "s": [100, 100] + }, + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 225, + "s": [20, 20] + }, + { "t": 230, "s": [100, 100] } + ], + "ix": 3 + }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 21", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[2.052, 0.438], [-1.052, 0], [-0.313, 1.052]], + "o": [[0.365, 0.938], [1.125, 0], [-0.99, 0.323]], + "v": [ + [-90.19, -70.72], + [-87.877, -69.126], + [-85.481, -70.928] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { "a": 0, "k": [1, 1, 1, 1], "ix": 4 }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.383, -0.575], + [-0.521, -0.061], + [-0.054, 0], + [-0.383, 0.575], + [0.521, 0.061], + [0.054, 0] + ], + "o": [ + [0.322, 0.36], + [0.061, 0.008], + [0.651, 0], + [-0.322, -0.36], + [-0.061, -0.008], + [-0.651, 0] + ], + "v": [ + [-89.228, -67.299], + [-87.964, -66.617], + [-87.795, -66.61], + [-86.255, -67.613], + [-87.519, -68.295], + [-87.688, -68.303] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.988235294819, 0.376470595598, 0.329411774874, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, -0.052], + [-1.271, -1.354], + [-0.708, -0.083], + [-0.073, 0], + [-0.521, 0.781], + [-0.031, 0.146], + [0.052, 0.042], + [0.052, -0.021], + [0.625, -0.198], + [2.052, 0.438], + [0.333, 0.104], + [0.042, -0.031] + ], + "o": [ + [0.021, 0.135], + [0.438, 0.49], + [0.083, 0.01], + [0.885, 0], + [1.01, -1.479], + [0.01, -0.063], + [-0.052, -0.031], + [-0.01, 0], + [-0.99, 0.323], + [-0.323, -0.052], + [-0.052, -0.021], + [-0.031, 0.031] + ], + "v": [ + [-91.387, -70.803], + [-89.762, -66.938], + [-88.044, -66.011], + [-87.814, -66.001], + [-85.721, -67.366], + [-84.262, -71.168], + [-84.325, -71.324], + [-84.491, -71.335], + [-85.481, -70.928], + [-90.19, -70.72], + [-91.179, -70.97], + [-91.335, -70.939] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.066666670144, 0.145098045468, 0.266666680574, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [-87.824, -68.675], "ix": 2 }, + "a": { "a": 0, "k": [-87.824, -68.675], "ix": 1 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833], "y": [0.833, 0.833] }, + "o": { "x": [0.167, 0.167], "y": [0.167, 0.167] }, + "t": 123, + "s": [100, 20] + }, + { "t": 132, "s": [100, 100] } + ], + "ix": 3, + "x": "var $bm_rt;\nvar fx = effect('Kleaner 2');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 22", + "np": 1, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0]], + "o": [[0, 0], [0, 0]], + "v": [[-103.83, -72.097], [-103.26, -72.255]], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0]], + "o": [[0, 0], [0, 0]], + "v": [[-79.842, -78.747], [-79.272, -78.905]], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 5", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 5, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [1.061, 0.059], [0, 0]], + "o": [[0, 0], [-0.319, -0.018], [0, 0]], + "v": [ + [-89.925, -77.23], + [-87.799, -73.551], + [-89.166, -73.44] + ], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 6", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 6, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-0.106, -0.383], + [1.017, -0.282], + [0.109, 0.393], + [-1.017, 0.282] + ], + "o": [ + [0.109, 0.393], + [-1.017, 0.282], + [-0.106, -0.383], + [1.017, -0.282] + ], + "v": [ + [-92.918, -78.681], + [-94.899, -77.445], + [-97.434, -77.32], + [-95.287, -78.845] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 7", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 7, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-0.106, -0.383], + [1.017, -0.282], + [0.109, 0.393], + [-1.017, 0.282] + ], + "o": [ + [0.109, 0.393], + [-1.017, 0.282], + [-0.106, -0.383], + [1.017, -0.282] + ], + "v": [ + [-84.433, -81.257], + [-86.413, -80.021], + [-88.949, -79.896], + [-86.801, -81.421] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 8", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 8, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [1.045, 1.663]], + "o": [[-1.843, -0.555], [0, 0]], + "v": [[-90.932, -84.996], [-95.433, -88.421]], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 9", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 9, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [1.68, 0.939]], + "o": [[-1.982, 0.013], [0, 0]], + "v": [[-90.877, -62.826], [-96.465, -64.27]], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 10", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 10, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.77, -1.25], + [0.918, 0.042], + [5.651, -1.564], + [0.96, -0.006], + [0, 0], + [0, 0], + [3.252, 0.948], + [0.764, 1.368], + [-0.468, 1.617], + [0, 0], + [0, 0], + [0.859, 0.426], + [-0.669, 1.321], + [-1.001, -0.042], + [0, 0], + [0.054, 0.699], + [-1.854, 0.515], + [-1.025, 3.223], + [-1.528, 0.421], + [-0.77, 0.575], + [-0.45, -1.623], + [0, 0], + [-0.907, -0.61] + ], + "o": [ + [-0.551, 0.823], + [1.066, 5.663], + [-0.966, 0.272], + [0, 0], + [0, 0], + [-0.942, 3.246], + [-1.623, -0.468], + [-0.746, -1.374], + [0, 0], + [0, 0], + [-0.752, 0.45], + [-1.321, -0.664], + [0.468, -0.971], + [0, 0], + [-0.196, -0.705], + [1.73, 0.474], + [3.495, -0.971], + [1.404, 0.427], + [0.977, -0.272], + [1.019, 1.197], + [0, 0], + [0.859, -0.557], + [1.267, 0.788] + ], + "v": [ + [-77.603, -77.289], + [-79.979, -76.063], + [-87.982, -63.232], + [-90.879, -62.823], + [-91.199, -61.71], + [-92.01, -58.926], + [-99.587, -54.749], + [-103.254, -57.67], + [-103.763, -62.326], + [-101.974, -68.51], + [-101.524, -70.056], + [-104.083, -69.95], + [-105.291, -73.551], + [-102.839, -75.032], + [-103.111, -76.01], + [-103.485, -78.125], + [-98.029, -78.142], + [-90.932, -84.996], + [-86.459, -84.949], + [-83.823, -86.234], + [-81.578, -81.981], + [-81.365, -80.986], + [-78.439, -80.998] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 11", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 11, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.77, -1.25], + [0.918, 0.042], + [5.651, -1.564], + [0.96, -0.006], + [0, 0], + [0, 0], + [3.252, 0.948], + [0.764, 1.368], + [-0.468, 1.617], + [0, 0], + [0, 0], + [0.859, 0.426], + [-0.669, 1.321], + [-1.001, -0.042], + [0, 0], + [0.054, 0.699], + [-1.854, 0.515], + [-1.025, 3.223], + [-1.528, 0.421], + [-0.77, 0.575], + [-0.45, -1.623], + [0, 0], + [-0.907, -0.61] + ], + "o": [ + [-0.551, 0.823], + [1.066, 5.663], + [-0.966, 0.272], + [0, 0], + [0, 0], + [-0.942, 3.246], + [-1.623, -0.468], + [-0.746, -1.374], + [0, 0], + [0, 0], + [-0.752, 0.45], + [-1.321, -0.664], + [0.468, -0.971], + [0, 0], + [-0.196, -0.705], + [1.73, 0.474], + [3.495, -0.971], + [1.404, 0.427], + [0.977, -0.272], + [1.019, 1.197], + [0, 0], + [0.859, -0.557], + [1.267, 0.788] + ], + "v": [ + [-77.603, -77.289], + [-79.979, -76.063], + [-87.982, -63.232], + [-90.879, -62.823], + [-91.199, -61.71], + [-92.01, -58.926], + [-99.587, -54.749], + [-103.254, -57.67], + [-103.763, -62.326], + [-101.974, -68.51], + [-101.524, -70.056], + [-104.083, -69.95], + [-105.291, -73.551], + [-102.839, -75.032], + [-103.111, -76.01], + [-103.485, -78.125], + [-98.029, -78.142], + [-90.932, -84.996], + [-86.459, -84.949], + [-83.823, -86.234], + [-81.578, -81.981], + [-81.365, -80.986], + [-78.439, -80.998] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 12", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 12, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-0.456, -1.167], + [0.865, -0.498], + [2.115, -0.213], + [1.967, -0.794], + [0.119, -1.351], + [-0.148, -0.699], + [1.38, -1.214], + [0.681, -0.166], + [0, 0], + [0, 0], + [0.859, 0.426], + [-0.669, 1.321], + [-1.001, -0.042], + [0, 0], + [0.054, 0.699], + [-1.854, 0.515], + [-1.025, 3.223], + [-1.528, 0.421], + [-0.77, 0.575] + ], + "o": [ + [-0.569, 0.865], + [-1.843, 1.054], + [-2.109, 0.219], + [-1.262, 0.51], + [-0.059, 0.705], + [0.379, 1.801], + [-0.527, 0.468], + [0, 0], + [0, 0], + [-0.752, 0.45], + [-1.321, -0.664], + [0.468, -0.971], + [0, 0], + [-0.196, -0.705], + [1.73, 0.474], + [3.495, -0.971], + [1.404, 0.427], + [0.977, -0.272], + [0.776, 0.912] + ], + "v": [ + [-81.957, -83.112], + [-84.244, -81.027], + [-90.363, -79.458], + [-96.595, -78.296], + [-99.243, -75.483], + [-98.882, -73.392], + [-100.44, -68.362], + [-102.294, -67.402], + [-101.974, -68.51], + [-101.524, -70.056], + [-104.083, -69.95], + [-105.291, -73.551], + [-102.839, -75.032], + [-103.111, -76.01], + [-103.485, -78.125], + [-98.029, -78.142], + [-90.932, -84.996], + [-86.459, -84.949], + [-83.823, -86.234] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.949019610882, 0.627451002598, 0.486274510622, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 13", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 13, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[-1.345, -0.089], [0, 0], [0, 0], [0, 0], [0, 0]], + "o": [ + [0, 0], + [0, 0], + [0, 0], + [-2.672, -0.675], + [1.86, 0.586] + ], + "v": [ + [-90.825, -62.823], + [-90.879, -62.823], + [-91.199, -61.71], + [-91.761, -59.779], + [-95.659, -63.86] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.949019610882, 0.627451002598, 0.486274510622, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 14", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 14, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.77, -1.25], + [0.918, 0.042], + [5.651, -1.564], + [0.942, -0.012], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [3.252, 0.948], + [0.764, 1.368], + [-0.468, 1.617], + [0, 0], + [0, 0], + [0, 0], + [0.859, 0.426], + [-0.669, 1.321], + [-1.001, -0.042], + [0, 0], + [0.054, 0.699], + [-1.854, 0.515], + [-1.025, 3.223], + [-1.528, 0.421], + [-0.77, 0.575], + [-0.456, -1.167], + [-0.107, -0.391], + [0, 0], + [-0.907, -0.61] + ], + "o": [ + [-0.551, 0.823], + [1.066, 5.663], + [-0.948, 0.266], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [-0.942, 3.246], + [-1.623, -0.468], + [-0.746, -1.374], + [0, 0], + [0, 0], + [0, 0], + [-0.752, 0.45], + [-1.321, -0.664], + [0.468, -0.971], + [0, 0], + [-0.196, -0.705], + [1.73, 0.474], + [3.495, -0.971], + [1.404, 0.427], + [0.977, -0.272], + [0.776, 0.912], + [0.142, 0.361], + [0, 0], + [0.859, -0.557], + [1.267, 0.788] + ], + "v": [ + [-77.603, -77.289], + [-79.979, -76.063], + [-87.982, -63.232], + [-90.825, -62.823], + [-90.879, -62.823], + [-91.199, -61.71], + [-91.761, -59.779], + [-92.01, -58.926], + [-99.587, -54.749], + [-103.254, -57.67], + [-103.763, -62.326], + [-102.294, -67.402], + [-101.974, -68.51], + [-101.524, -70.056], + [-104.083, -69.95], + [-105.291, -73.551], + [-102.839, -75.032], + [-103.111, -76.01], + [-103.485, -78.125], + [-98.029, -78.142], + [-90.932, -84.996], + [-86.459, -84.949], + [-83.823, -86.234], + [-81.957, -83.112], + [-81.578, -81.981], + [-81.365, -80.986], + [-78.439, -80.998] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.988235294819, 0.733333349228, 0.643137276173, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 15", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 15, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [3.187, -0.889], + [0.889, 3.193], + [-0.089, 0.752], + [0.503, 0.154], + [2.991, -1.155], + [2.867, -0.794], + [0.883, 3.187], + [-0.794, 1.351], + [0.48, 1.736], + [-5.521, 1.528], + [-2.34, -1.41], + [-2.044, 0.569], + [-1.191, -4.307], + [0.693, -1.623], + [-0.521, -1.884] + ], + "o": [ + [-3.205, 0.883], + [-0.213, -0.776], + [-0.527, -0.047], + [-0.924, 2.915], + [0.302, 2.861], + [-3.199, 0.889], + [-0.45, -1.635], + [-1.173, -1.208], + [-1.528, -5.515], + [2.838, -0.788], + [1.025, -1.665], + [4.283, -1.185], + [0.51, 1.831], + [1.682, 0.669], + [0.883, 3.187] + ], + "v": [ + [-81.821, -78.196], + [-89.208, -82.378], + [-89.386, -84.694], + [-90.932, -84.996], + [-97.045, -78.474], + [-101.411, -72.071], + [-108.792, -76.247], + [-108.188, -80.885], + [-110.741, -85.34], + [-103.544, -98.052], + [-95.47, -96.957], + [-90.766, -100.481], + [-80.85, -94.865], + [-81.205, -89.552], + [-77.645, -85.583] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 16", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 16, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-1.321, -4.099], + [3.128, -0.865], + [1.025, -1.665], + [2.838, -0.788], + [-1.528, -5.515], + [-0.113, -0.272], + [0.367, 1.333], + [-5.521, 1.528], + [-2.34, -1.41], + [-2.044, 0.569] + ], + "o": [ + [-1.973, -2.328], + [-2.044, 0.569], + [-2.34, -1.41], + [-5.521, 1.528], + [0.077, 0.284], + [-0.8, -1.031], + [-1.528, -5.515], + [2.838, -0.788], + [1.025, -1.665], + [4.17, -1.155] + ], + "v": [ + [-80.95, -95.197], + [-89.261, -97.756], + [-93.965, -94.231], + [-102.039, -95.327], + [-109.237, -82.615], + [-108.958, -81.78], + [-110.741, -85.34], + [-103.544, -98.052], + [-95.47, -96.957], + [-90.766, -100.481] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.901960790157, 0.29411765933, 0.219607844949, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 17", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 17, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[1.331, 1.267], [-3.751, -1.976], [0, 0]], + "o": [[0, 0], [0, 0], [-1.921, -0.084]], + "v": [ + [-94.634, -87.36], + [-90.932, -82.062], + [-89.925, -84.996] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.901960790157, 0.29411765933, 0.219607844949, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 18", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 18, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [3.187, -0.889], + [0.889, 3.193], + [-0.089, 0.752], + [0.503, 0.154], + [2.991, -1.155], + [2.867, -0.794], + [0.883, 3.187], + [-0.794, 1.351], + [0.48, 1.736], + [-5.521, 1.528], + [-2.34, -1.41], + [-2.044, 0.569], + [-1.191, -4.307], + [0.693, -1.623], + [-0.521, -1.884] + ], + "o": [ + [-3.205, 0.883], + [-0.213, -0.776], + [-0.527, -0.047], + [-0.924, 2.915], + [0.302, 2.861], + [-3.199, 0.889], + [-0.45, -1.635], + [-1.173, -1.208], + [-1.528, -5.515], + [2.838, -0.788], + [1.025, -1.665], + [4.283, -1.185], + [0.51, 1.831], + [1.682, 0.669], + [0.883, 3.187] + ], + "v": [ + [-81.821, -78.196], + [-89.208, -82.378], + [-89.386, -84.694], + [-90.932, -84.996], + [-97.045, -78.474], + [-101.411, -72.071], + [-108.792, -76.247], + [-108.188, -80.885], + [-110.741, -85.34], + [-103.544, -98.052], + [-95.47, -96.957], + [-90.766, -100.481], + [-80.85, -94.865], + [-81.205, -89.552], + [-77.645, -85.583] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.988235294819, 0.376470595598, 0.329411774874, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 19", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 19, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 24, + "ty": 4, + "nm": "aram down", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [50, 50, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [0, 0, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 1, + "k": [ + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 5, + "s": [ + { + "i": [ + [2.876, 5.671], + [5.53, 8.773], + [5.713, -4.957], + [0, 0], + [-2.641, 1.427], + [0, 0] + ], + "o": [ + [-3.877, -7.646], + [-6.232, 0.435], + [0, 0], + [1.576, 2.555], + [0, 0], + [5.595, -3.022] + ], + "v": [ + [-44.21, -8.06], + [-59.164, -34.554], + [-77.068, -26.34], + [-57.203, 5.866], + [-49.69, 7.877], + [-49.103, 7.56] + ], + "c": true + } + ] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 20, + "s": [ + { + "i": [ + [2.876, 5.671], + [5.53, 8.773], + [5.713, -4.957], + [0, 0], + [-2.641, 1.427], + [0, 0] + ], + "o": [ + [-3.877, -7.646], + [-6.232, 0.435], + [0, 0], + [1.576, 2.555], + [0, 0], + [5.595, -3.022] + ], + "v": [ + [-51.085, -23.185], + [-59.164, -34.554], + [-77.068, -26.34], + [-64.078, -9.259], + [-56.565, -7.248], + [-55.978, -7.565] + ], + "c": true + } + ] + }, + { + "i": { "x": 0.417, "y": 1 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 30, + "s": [ + { + "i": [ + [2.876, 5.671], + [5.53, 8.773], + [5.713, -4.957], + [0, 0], + [-2.641, 1.427], + [0, 0] + ], + "o": [ + [-3.877, -7.646], + [-6.232, 0.435], + [0, 0], + [1.576, 2.555], + [0, 0], + [5.595, -3.022] + ], + "v": [ + [-51.085, -23.185], + [-59.164, -34.554], + [-77.068, -26.34], + [-64.078, -9.259], + [-56.565, -7.248], + [-55.978, -7.565] + ], + "c": true + } + ] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.333, "y": 0 }, + "t": 45, + "s": [ + { + "i": [ + [2.876, 5.671], + [5.53, 8.773], + [5.713, -4.957], + [0, 0], + [-2.641, 1.427], + [0, 0] + ], + "o": [ + [-3.877, -7.646], + [-6.232, 0.435], + [0, 0], + [1.576, 2.555], + [0, 0], + [5.595, -3.022] + ], + "v": [ + [-44.21, -8.06], + [-59.164, -34.554], + [-77.068, -26.34], + [-57.203, 5.866], + [-49.69, 7.877], + [-49.103, 7.56] + ], + "c": true + } + ] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 73, + "s": [ + { + "i": [ + [2.876, 5.671], + [5.53, 8.773], + [5.713, -4.957], + [0, 0], + [-2.641, 1.427], + [0, 0] + ], + "o": [ + [-3.877, -7.646], + [-6.232, 0.435], + [0, 0], + [1.576, 2.555], + [0, 0], + [5.595, -3.022] + ], + "v": [ + [-44.21, -8.06], + [-59.164, -34.554], + [-77.068, -26.34], + [-57.203, 5.866], + [-49.69, 7.877], + [-49.103, 7.56] + ], + "c": true + } + ] + }, + { + "i": { "x": 0.833, "y": 0.833 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 88, + "s": [ + { + "i": [ + [2.876, 5.671], + [5.53, 8.773], + [5.713, -4.957], + [0, 0], + [-2.641, 1.427], + [0, 0] + ], + "o": [ + [-3.877, -7.646], + [-6.232, 0.435], + [0, 0], + [1.576, 2.555], + [0, 0], + [5.595, -3.022] + ], + "v": [ + [-51.085, -23.185], + [-59.164, -34.554], + [-77.068, -26.34], + [-64.078, -9.259], + [-56.565, -7.248], + [-55.978, -7.565] + ], + "c": true + } + ] + }, + { + "i": { "x": 0.417, "y": 1 }, + "o": { "x": 0.167, "y": 0.167 }, + "t": 98, + "s": [ + { + "i": [ + [2.876, 5.671], + [5.53, 8.773], + [5.713, -4.957], + [0, 0], + [-2.641, 1.427], + [0, 0] + ], + "o": [ + [-3.877, -7.646], + [-6.232, 0.435], + [0, 0], + [1.576, 2.555], + [0, 0], + [5.595, -3.022] + ], + "v": [ + [-51.085, -23.185], + [-59.164, -34.554], + [-77.068, -26.34], + [-64.078, -9.259], + [-56.565, -7.248], + [-55.978, -7.565] + ], + "c": true + } + ] + }, + { + "t": 113, + "s": [ + { + "i": [ + [2.876, 5.671], + [5.53, 8.773], + [5.713, -4.957], + [0, 0], + [-2.641, 1.427], + [0, 0] + ], + "o": [ + [-3.877, -7.646], + [-6.232, 0.435], + [0, 0], + [1.576, 2.555], + [0, 0], + [5.595, -3.022] + ], + "v": [ + [-44.21, -8.06], + [-59.164, -34.554], + [-77.068, -26.34], + [-57.203, 5.866], + [-49.69, 7.877], + [-49.103, 7.56] + ], + "c": true + } + ] + } + ], + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.988235294819, 0.733333349228, 0.643137276173, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 25, + "ty": 4, + "nm": "Body", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [50, 50, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [0, 0, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0]], + "o": [[0, 0], [0, 0]], + "v": [[-77.205, -26.161], [-77.205, -31.49]], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [-7.63, 10.153], + [-6.208, 1.108], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [-4.431, -3.169], + [-7.712, -11.239] + ], + "o": [ + [0, 0], + [0, 0], + [-1.795, -15.153], + [4.532, -6.03], + [4.65, -0.829], + [0, 0], + [0, 0], + [0, 0], + [5.308, 1.22], + [5.894, 4.212], + [3.596, 5.241] + ], + "v": [ + [-77.207, -26.162], + [-77.456, 3.895], + [-129.734, 3.895], + [-126.482, -50.178], + [-107.531, -59.905], + [-99.351, -60.734], + [-89.357, -58.435], + [-88.51, -58.24], + [-87.082, -57.908], + [-72.332, -51.256], + [-59.147, -34.187] + ], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-2.34, -0.326], + [0, 0], + [0, 0], + [0.35, 8.696], + [-2.127, 0.45], + [-2.524, 2.097], + [-1.078, 2.298], + [-1.801, -0.266], + [-0.272, -1.268], + [-2.837, -3.418], + [-6.706, -0.942] + ], + "o": [ + [0, 0], + [0, 0], + [-0.74, -6.238], + [1.753, -1.22], + [3.211, -0.675], + [1.955, -1.617], + [0.569, -1.214], + [1.682, 0.243], + [0.936, 4.336], + [4.325, 5.207], + [2.316, 0.326] + ], + "v": [ + [-77.349, -9.149], + [-77.456, 3.895], + [-129.734, 3.895], + [-131.843, -19.7], + [-125.729, -22.039], + [-116.559, -25.298], + [-113.153, -29.995], + [-114.172, -34.989], + [-108.124, -28.218], + [-101.791, -19.528], + [-84.452, -9.866] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, 0], + [4.271, 0], + [0.883, 0.261], + [1.262, 2.257], + [0.095, 1.363], + [0, 0], + [0, 0] + ], + "o": [ + [0, 0], + [-1.191, 4.111], + [-0.912, 0], + [-2.458, -0.711], + [-0.681, -1.256], + [4.65, -0.829], + [0, 0], + [0, 0] + ], + "v": [ + [-88.51, -58.24], + [-88.599, -57.932], + [-97.875, -50.948], + [-100.583, -51.339], + [-106.358, -55.936], + [-107.531, -59.905], + [-99.351, -60.734], + [-89.357, -58.435] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { "a": 0, "k": [1, 1, 1, 1], "ix": 4 }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-3.353, -4.798], + [2.441, 1.546], + [4.402, 1.499], + [8.317, -0.675], + [3.916, -0.456], + [0.439, 0.391], + [0, 0], + [0, 0], + [0, 0], + [-4.431, -3.169] + ], + "o": [ + [-2.269, -1.795], + [-3.927, -2.494], + [-7.902, -2.683], + [-3.963, 0.32], + [-1.137, 0.13], + [10.047, -7.352], + [0, 0], + [0, 0], + [5.308, 1.22], + [1.973, 1.41] + ], + "v": [ + [-64.039, -41.375], + [-71.076, -46.44], + [-83.641, -52.441], + [-108.319, -55.497], + [-119.971, -53.507], + [-122.288, -53.957], + [-99.351, -60.734], + [-89.357, -58.435], + [-87.082, -57.908], + [-72.332, -51.256] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 5", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 5, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0.35, 8.696], + [-5, 5.557], + [-1.475, 1.078], + [0, 0], + [0, 0], + [0, 0], + [-4.431, -3.169], + [-3.353, -4.798], + [-5, -9.614] + ], + "o": [ + [0, 0], + [0, 0], + [0, 0], + [-0.74, -6.238], + [-0.503, -12.428], + [1.303, -1.451], + [10.047, -7.352], + [0, 0], + [0, 0], + [5.308, 1.22], + [1.973, 1.41], + [6.67, 9.531], + [2.932, 5.639] + ], + "v": [ + [-77.207, -26.162], + [-77.349, -9.149], + [-77.456, 3.895], + [-129.734, 3.895], + [-131.843, -19.7], + [-126.482, -50.178], + [-122.288, -53.957], + [-99.351, -60.734], + [-89.357, -58.435], + [-87.082, -57.908], + [-72.332, -51.256], + [-64.039, -41.375], + [-59.101, -33.846] + ], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 6", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 6, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 26, + "ty": 4, + "nm": "leg", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [50, 50, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [0, 0, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-5.735, 0], + [0, 0], + [-1.179, 2.739], + [0, 0], + [-0.653, 5.281], + [0, 0], + [0, 0], + [-0.733, -21.778], + [1.581, -2.829], + [0, 0] + ], + "o": [ + [0, 0], + [2.982, 0], + [0, 0], + [2.069, -4.902], + [0, 0], + [0, 0], + [-10.84, 27.144], + [0.109, 3.239], + [0, 0], + [-2.849, 4.977] + ], + "v": [ + [-167.522, 148.329], + [-138.87, 148.329], + [-132.013, 143.815], + [-109.531, 91.571], + [-105.429, 76.223], + [-96.483, 3.896], + [-129.749, 3.896], + [-141.226, 74.543], + [-143.466, 83.818], + [-174, 137.155] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [ + 0.066666670144, 0.145098045468, 0.266666680574, 1 + ], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, 0], + [5.663, -1.522], + [2.263, -8.175], + [-1.694, -10.58], + [16.433, -15.734], + [-5.041, -4.733], + [-3.868, -1.7], + [-0.865, -3.815], + [0.201, 0], + [0, 0], + [-2.849, 4.976], + [0, 0], + [0.107, 3.24], + [-10.835, 27.143] + ], + "o": [ + [0, 0], + [-4.567, -2.038], + [-8.193, 2.198], + [-2.849, 10.331], + [3.602, 22.463], + [-4.994, 4.775], + [3.081, 2.891], + [3.614, 1.588], + [-0.196, 0.018], + [0, 0], + [-5.734, 0], + [0, 0], + [1.582, -2.831], + [-0.735, -21.776], + [0, 0] + ], + "v": [ + [-96.483, 3.895], + [-97.378, 11.122], + [-112.442, 9.86], + [-129.704, 26.986], + [-126.766, 58.679], + [-147.665, 120.891], + [-158.352, 137.785], + [-145.924, 139.817], + [-138.27, 148.306], + [-138.868, 148.33], + [-167.522, 148.33], + [-174.003, 137.158], + [-143.465, 83.819], + [-141.226, 74.543], + [-129.752, 3.895] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.278431385756, 0.713725507259, 0.764705896378, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [2.073, -4.905], + [0, 0], + [2.737, -0.219], + [0.201, 0], + [0, 0], + [-2.849, 4.976], + [0, 0], + [0.107, 3.24], + [-10.835, 27.143] + ], + "o": [ + [0, 0], + [0, 0], + [-0.652, 5.278], + [0, 0], + [-1.102, 2.553], + [-0.196, 0.018], + [0, 0], + [-5.734, 0], + [0, 0], + [1.582, -2.831], + [-0.735, -21.776], + [0, 0] + ], + "v": [ + [-96.483, 3.895], + [-97.378, 11.122], + [-105.428, 76.225], + [-109.534, 91.574], + [-132.015, 143.816], + [-138.27, 148.306], + [-138.868, 148.33], + [-167.522, 148.33], + [-174.003, 137.158], + [-143.465, 83.819], + [-141.226, 74.543], + [-129.752, 3.895] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.40000000596, 0.827450990677, 0.847058832645, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.72, -3.465], + [0, 0], + [0.577, 0.12], + [0, 0], + [-0.162, 0.593], + [-0.485, 3.302], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "o": [ + [0, 0], + [-0.12, 0.577], + [0, 0], + [-0.602, -0.125], + [0.267, -0.978], + [0.914, -6.224], + [10.744, 8.861], + [0, 0], + [0, 0], + [3.156, 1.61] + ], + "v": [ + [-130.741, 173.83], + [-130.757, 173.911], + [-132.02, 174.739], + [-170.344, 166.772], + [-171.159, 165.454], + [-170.009, 159.357], + [-164.906, 152.228], + [-147.739, 154.602], + [-143.727, 160.519], + [-134.856, 165.234] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.066666670144, 0.145098045468, 0.266666680574, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [10.745, 8.859], [0, 0], [0, 0]], + "o": [[0, 0], [0, 0], [0, 0], [0, 0]], + "v": [ + [-147.737, 154.602], + [-164.906, 152.229], + [-163.695, 143.169], + [-146.859, 146.678] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [ + 0.066666670144, 0.145098045468, 0.266666680574, 1 + ], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, 0], + [1.641, 0.575], + [2.109, -1.066], + [1.137, -0.746], + [0.728, 0.604], + [0, 0] + ], + "o": [ + [0, 0], + [-1.7, -0.219], + [-2.233, -0.782], + [-1.232, 0.622], + [-0.687, -0.462], + [0, 0], + [0, 0] + ], + "v": [ + [-146.859, 146.677], + [-147.57, 153.116], + [-152.576, 151.635], + [-159.471, 151.357], + [-162.771, 153.827], + [-164.903, 152.228], + [-163.695, 143.17] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.949019610882, 0.627451002598, 0.486274510622, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [9.454, 6.409], + [0.728, 0.604], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0], + [0, 0], + [-0.687, -0.462], + [0, 0], + [0, 0] + ], + "v": [ + [-146.859, 146.677], + [-147.57, 153.116], + [-147.736, 154.603], + [-162.771, 153.827], + [-164.903, 152.228], + [-163.695, 143.17] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.988235294819, 0.733333349228, 0.643137276173, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [-128.741, 4.328], "ix": 2 }, + "a": { "a": 0, "k": [-128.741, 4.328], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { + "a": 1, + "k": [ + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 4, + "s": [0] + }, + { + "i": { "x": [0.833], "y": [0.833] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 20, + "s": [10] + }, + { + "i": { "x": [0.667], "y": [1] }, + "o": { "x": [0.167], "y": [0.167] }, + "t": 30, + "s": [10] + }, + { "t": 45, "s": [0] } + ], + "ix": 6, + "x": "var $bm_rt;\nvar fx = effect('Kleaner');\nvar doAnticipation = fx(1).value;\nvar doInterpolation = fx(2).value;\nvar doFollowThrough = fx(3).value;\nvar damping = $bm_div(fx(15).value, 10);\nvar elasticity = $bm_div(fx(13).value, 10);\nvar bounce = fx(17).value;\nvar anticipationDuration = fx(5).value;\nvar anticipationQuantity = $bm_div(fx(6).value, 100);\nvar slowIn = $bm_div(fx(9).value, 100);\nvar slowOut = $bm_div(fx(10).value, 100);\nvar spatialMode = fx(21).value;\nvar spatialDoInterpolation = fx(20).value;\nvar moBlurPrecision = fx(32).value;\nvar elasticityRandom = fx(14).value;\nvar dampingRandom = fx(16).value;\nvar softBody = fx(28).value;\nvar flexibility = $bm_div(fx(29).value, 100);\nvar doOverlap = fx(23).value;\nvar overlapDuration = fx(24).value;\nvar overlapRandom = fx(25).value;\nvar threshold = $bm_div($bm_div(1, moBlurPrecision), 1000);\nvar zeroValue;\nif ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n zeroValue = [\n 0,\n 0\n ];\n else if (value.length == 3)\n zeroValue = [\n 0,\n 0,\n 0\n ];\n else if (value.length == 4)\n zeroValue = [\n 0,\n 0,\n 0,\n 0\n ];\n} else\n zeroValue = 0;\nvar isThisSpatial = isSpatial(thisProperty);\nvar isThisPosition = thisProperty === $bm_transform.position;\nvar simulate = false;\nif (isThisSpatial) {\n doInterpolation = doInterpolation && spatialDoInterpolation;\n if (isThisPosition && thisProperty.numKeys > 0) {\n doOverlap = false;\n simulate = false;\n } else {\n simulate = spatialMode == 2;\n doOverlap = overlapDuration != 0 && doOverlap && simulate;\n }\n} else {\n doOverlap = false;\n}\nif (!doOverlap) {\n overlapDuration = 0;\n}\nif (simulate && softBody && isThisSpatial && !isThisPosition && (doFollowThrough || doOverlap)) {\n var distanceRatio = $bm_div(length(valueAtTime(0), $bm_transform.anchorPoint), $bm_div(thisLayer.width, 2));\n distanceRatio = $bm_div($bm_sum(1, $bm_mul(distanceRatio, flexibility)), 2);\n if (doFollowThrough) {\n elasticity = $bm_div(elasticity, distanceRatio);\n damping = $bm_div(damping, distanceRatio);\n }\n if (doOverlap) {\n overlapDuration = $bm_mul(overlapDuration, distanceRatio);\n }\n}\nseedRandom(0, true);\nif (doFollowThrough) {\n if (elasticityRandom > 0)\n elasticity = addNoise(elasticity, elasticityRandom);\n if (dampingRandom > 0)\n damping = addNoise(damping, dampingRandom);\n}\nif (doOverlap) {\n if (doOverlap && overlapRandom > 0)\n overlapDuration = addNoise(overlapDuration, overlapRandom);\n}\nvar result = value;\nfunction isSpatial(prop) {\n if (!(prop.value instanceof Array))\n return false;\n if (prop.value.length != 2 && prop.value.length != 3)\n return false;\n try {\n if (typeof prop.speed !== 'undefined')\n return true;\n } catch (e) {\n return false;\n }\n}\nfunction addNoise(val, quantity) {\n var randomValue = random(0.9, 1.1);\n var noiseValue = noise($bm_mul(valueAtTime(0), randomValue));\n noiseValue = $bm_mul(noiseValue, $bm_div(quantity, 100));\n return $bm_mul(val, $bm_sum(noiseValue, 1));\n}\nfunction isAfterLastKey() {\n if (numKeys == 0)\n return false;\n var nKey = nearestKey(time);\n return nKey.time <= time && nKey.index == numKeys;\n}\nfunction isStill(t, threshold) {\n var d = $bm_sub(valueAtTime(t), valueAtTime($bm_sum(t, framesToTime(1))));\n if ($bm_isInstanceOfArray(d)) {\n for (var i = 0; i < d.length; i++) {\n d[i] = Math.abs(d[i]);\n if (d[i] >= threshold) {\n return false;\n }\n }\n return true;\n } else {\n d = Math.abs(d);\n return d < threshold;\n }\n}\nfunction bezierInterpolation(t, tMin, tMax, value1, value2, bezierPoints) {\n if (arguments.length !== 5 && arguments.length !== 6)\n return t;\n var a = $bm_sub(value2, value1);\n var b = $bm_sub(tMax, tMin);\n if (b == 0)\n return t;\n var c = clamp($bm_div($bm_sub(t, tMin), b), 0, 1);\n if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4)\n bezierPoints = [\n 0.33,\n 0,\n 0.66,\n 1\n ];\n return $bm_sum($bm_mul(a, h(c, bezierPoints)), value1);\n function h(f, g) {\n var x = $bm_mul(3, g[0]);\n var j = $bm_sub($bm_mul(3, $bm_sub(g[2], g[0])), x);\n var k = $bm_sub($bm_sub(1, x), j);\n var l = $bm_mul(3, g[1]);\n var m = $bm_sub($bm_mul(3, $bm_sub(g[3], g[1])), l);\n var n = $bm_sub($bm_sub(1, l), m);\n var d = f;\n for (var i = 0; i < 5; i++) {\n var z = $bm_sub($bm_mul(d, $bm_sum(x, $bm_mul(d, $bm_sum(j, $bm_mul(d, k))))), f);\n if (Math.abs(z) < 0.001)\n break;\n d = $bm_sub(d, $bm_div(z, $bm_sum(x, $bm_mul(d, $bm_sum($bm_mul(2, j), $bm_mul($bm_mul(3, k), d))))));\n }\n return $bm_mul(d, $bm_sum(l, $bm_mul(d, $bm_sum(m, $bm_mul(d, n)))));\n }\n}\nfunction getPropWorldSpeed(t, prop) {\n return length(getPropWorldVelocity(t, prop));\n}\nfunction getPrevKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time <= t)\n return nKey;\n if (nKey.index > 1)\n return key($bm_sub(nKey.index, 1));\n return null;\n}\nfunction getNextKey(t) {\n if (numKeys == 0)\n return null;\n var nKey = nearestKey(t);\n if (nKey.time >= t)\n return nKey;\n if (nKey.index < numKeys)\n return key($bm_sum(nKey.index, 1));\n return null;\n}\nfunction getPropWorldVelocity(t, prop) {\n return $bm_mul($bm_sub(getPropWorldValue($bm_sum(t, 0.005), prop), getPropWorldValue($bm_sub(t, 0.005), prop)), 100);\n}\nfunction getLayerWorldPos(t, l) {\n return l.toWorld(l.anchorPoint, t);\n}\nfunction getPropWorldValue(t, prop) {\n if (isPosition(prop))\n return getLayerWorldPos(t, thisLayer);\n return thisLayer.toWorld(prop.valueAtTime(t), t);\n}\nfunction isPosition(prop) {\n return prop === $bm_transform.position;\n}\nfunction isKeyTop(k, axis) {\n var prevSpeed = velocityAtTime($bm_sub(k.time, threshold));\n var nextSpeed = velocityAtTime($bm_sum(k.time, threshold));\n if ($bm_isInstanceOfArray(value)) {\n prevSpeed = prevSpeed[axis];\n nextSpeed = nextSpeed[axis];\n }\n if (Math.abs(prevSpeed) < 0.01 || Math.abs(nextSpeed) < 0.01)\n return true;\n return $bm_mul(prevSpeed, nextSpeed) < 0;\n}\nfunction anticipate() {\n var anticipation = zeroValue;\n if (isAfterLastKey())\n return anticipation;\n if (numKeys < 2)\n return anticipation;\n var nextKey = getNextKey(time);\n var aKey = nextKey;\n if (!isStill(aKey.time - 0.1, 0.1)) {\n aKey = getPrevKey(time);\n if (!isStill(aKey.time - 0.1, 0.1))\n return anticipation;\n }\n if (aKey.index == numKeys)\n return anticipation;\n var anticipationMiddle = aKey.time;\n var anticipationStart = $bm_sub(anticipationMiddle, anticipationDuration);\n var anticipationEnd = key(aKey.index + 1).time;\n var startValue = anticipation;\n var midValue = $bm_mul($bm_sum($bm_neg(valueAtTime($bm_sum(anticipationMiddle, anticipationDuration))), aKey.value), anticipationQuantity);\n var endValue = anticipation;\n if (time < anticipationStart) {\n return anticipation;\n } else if (time < anticipationMiddle) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue[i], midValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationStart, anticipationMiddle, startValue, midValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else if (time <= anticipationEnd) {\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < value.length; i++) {\n anticipation[i] = bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue[i], endValue[i], [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n return anticipation;\n } else {\n return bezierInterpolation(time, anticipationMiddle, anticipationEnd, midValue, endValue, [\n slowOut,\n 0,\n slowIn,\n 1\n ]);\n }\n } else {\n return anticipation;\n }\n}\nfunction followThroughAtTime(t) {\n var fThrough = zeroValue;\n if (elasticity == 0)\n return fThrough;\n var propSpeed;\n if (!simulate) {\n if (numKeys < 2)\n return fThrough;\n if (nearestKey(t).index == 1)\n return fThrough;\n propSpeed = length(velocityAtTime(t));\n if (propSpeed >= threshold)\n return fThrough;\n } else {\n propSpeed = getPropWorldSpeed(t, thisProperty);\n if (propSpeed >= threshold)\n return fThrough;\n }\n var fThroughStart = 0;\n var fThroughTime = 0;\n if (simulate) {\n var speedI = getPropWorldSpeed(t, thisProperty);\n var i = t;\n while (speedI < threshold && i > 0) {\n i = $bm_sub(i, $bm_div(thisComp.frameDuration, moBlurPrecision));\n speedI = getPropWorldSpeed(i, thisProperty);\n }\n fThroughStart = i;\n } else {\n var fThroughKey = getPrevKey(t);\n fThroughStart = fThroughKey.time;\n }\n if (fThroughStart == 0)\n return fThrough;\n fThroughTime = $bm_sub(t, fThroughStart);\n if (simulate)\n fThrough = $bm_div(getPropWorldVelocity($bm_sub(fThroughStart, thisComp.frameDuration), thisProperty), 2);\n else\n fThrough = $bm_div(velocityAtTime($bm_sub(fThroughStart, thisComp.frameDuration)), 2);\n if (bounce) {\n var cycleDamp = Math.exp($bm_mul($bm_mul(fThroughTime, damping), 0.1));\n var damp = $bm_div(Math.exp($bm_mul(fThroughTime, damping)), $bm_div(elasticity, 2));\n var cycleDuration = $bm_div(1, $bm_mul(elasticity, 2));\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n cycleDuration = framesToTime(cycleDuration);\n var midDuration = $bm_div(cycleDuration, 2);\n var maxValue = $bm_mul(fThrough, midDuration);\n var cycvarime = fThroughTime;\n var numEndCycles = 1;\n while (cycvarime > cycleDuration) {\n cycvarime = $bm_sub(cycvarime, cycleDuration);\n cycleDuration = $bm_div(cycleDuration, cycleDamp);\n cycleDuration = Math.round(timeToFrames(cycleDuration));\n if (cycleDuration < 2) {\n cycleDuration = 2;\n numEndCycles++;\n }\n cycleDuration = framesToTime(cycleDuration);\n midDuration = $bm_div(cycleDuration, 2);\n maxValue = $bm_div($bm_mul(fThrough, midDuration), damp);\n if (numEndCycles > 100 / damping && maxValue < threshold)\n return zeroValue;\n }\n if (cycvarime < midDuration)\n fThrough = bezierInterpolation(cycvarime, 0, midDuration, 0, maxValue, [\n 0,\n 0.1,\n slowIn,\n 1\n ]);\n else\n fThrough = bezierInterpolation(cycvarime, midDuration, cycleDuration, maxValue, 0, [\n $bm_sub(1, slowIn),\n 0,\n 1,\n 0.9\n ]);\n } else {\n var damp = Math.exp($bm_mul(fThroughTime, damping));\n var sinus = $bm_mul($bm_mul($bm_mul(elasticity, fThroughTime), 2), Math.PI);\n sinus = Math.sin(sinus);\n sinus = $bm_mul($bm_div(0.3, elasticity), sinus);\n sinus = $bm_div(sinus, damp);\n if (Math.abs(sinus) < $bm_div(threshold, 100))\n return 0;\n fThrough = $bm_mul(fThrough, sinus);\n if (threshold > 0) {\n fThrough = $bm_mul(fThrough, $bm_sub(1, $bm_div(propSpeed, threshold)));\n }\n }\n if (bounce) {\n var prevValue = valueAtTime($bm_sub(fThroughStart, thisComp.frameDuration));\n var startValue = valueAtTime(fThroughStart);\n if ($bm_isInstanceOfArray(value)) {\n for (var i = 0; i < prevValue.length; i++) {\n if (prevValue[i] > startValue[i])\n fThrough[i] = Math.abs(fThrough[i]);\n if (prevValue[i] < startValue[i])\n fThrough[i] = $bm_neg(Math.abs(fThrough[i]));\n }\n } else {\n if (prevValue > startValue)\n fThrough = Math.abs(fThrough);\n if (prevValue < startValue)\n fThrough = $bm_neg(Math.abs(fThrough));\n }\n }\n if (simulate) {\n if (!isThisPosition) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer));\n fThrough = $bm_sub(thisLayer.fromWorld(fThrough), thisLayer.anchorPoint);\n } else if (thisLayer.hasParent) {\n fThrough = $bm_sum(fThrough, getLayerWorldPos(time, thisLayer.parent));\n fThrough = $bm_sub(thisLayer.parent.fromWorld(fThrough), thisLayer.parent.anchorPoint);\n }\n }\n return fThrough;\n}\nfunction followThrough() {\n var propSpeed = length(velocity);\n if (propSpeed < threshold)\n return followThroughAtTime($bm_sub(time, overlapDuration));\n var fThrough = zeroValue;\n var t = time;\n while (t > 0) {\n t = $bm_sub(t, thisComp.frameDuration);\n if (simulate)\n propSpeed = getPropWorldSpeed($bm_sub(t, overlapDuration), thisProperty);\n else\n propSpeed = length(velocityAtTime(t));\n if (propSpeed < threshold) {\n fThrough = followThroughAtTime($bm_sub(t, overlapDuration));\n break;\n }\n }\n return linear(time, t, $bm_sum(t, $bm_mul(anticipationDuration, 2)), fThrough, zeroValue);\n}\nfunction smartSmooth(axis) {\n var startKey = nearestKey(time);\n var endKey = startKey;\n if (time == startKey.time)\n return 0;\n if (time < startKey.time && startKey.index == 1)\n return 0;\n if (time > startKey.time && startKey.index == numKeys)\n return 0;\n if (time < startKey.time)\n startKey = key($bm_sub(startKey.index, 1));\n if (time > startKey.time)\n endKey = key($bm_sum(startKey.index, 1));\n var sI = 0.66;\n var sO = 0.33;\n var sIV = 1;\n var sOV = 0;\n var sVal = startKey.value;\n var eVal = endKey.value;\n if ($bm_isInstanceOfArray(value)) {\n sVal = sVal[axis];\n eVal = eVal[axis];\n }\n var sTime = startKey.time;\n var eTime = endKey.time;\n if (isKeyTop(startKey, axis))\n sO = slowOut;\n else {\n var prevKey = key($bm_sub(startKey.index, 1));\n var pVal = prevKey.value;\n if ($bm_isInstanceOfArray(value))\n pVal = pVal[axis];\n sOV = $bm_div($bm_sub(sVal, pVal), $bm_sub(eVal, pVal));\n }\n if (isKeyTop(endKey, axis)) {\n sI = slowIn;\n if (endKey.index != numKeys) {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n if (Math.abs(nVal - eVal) < 0.01 && doFollowThrough)\n sI = 1;\n }\n } else {\n var nextKey = key($bm_sum(endKey.index, 1));\n var nVal = nextKey.value;\n if ($bm_isInstanceOfArray(value))\n nVal = nVal[axis];\n sIV = $bm_div($bm_sub(eVal, sVal), $bm_sub(nVal, sVal));\n }\n if (endKey.index == numKeys && doFollowThrough) {\n sI = 1;\n }\n var val = value;\n if ($bm_isInstanceOfArray(value))\n val = val[axis];\n return $bm_sub(bezierInterpolation(time, sTime, eTime, sVal, eVal, [\n sO,\n sOV,\n sI,\n sIV\n ]), val);\n}\nfunction overlap() {\n var ol = zeroValue;\n if (isThisPosition && !hasParent)\n return zeroValue;\n ol = $bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisProperty), getPropWorldValue(time, thisProperty));\n var motionRatio = $bm_div($bm_div(length(zeroValue, ol), thisLayer.width), 2);\n if (isThisPosition) {\n var originalDistance = length(valueAtTime(0));\n motionRatio = $bm_div(length(zeroValue, ol), thisComp.width);\n }\n ol = $bm_sum(ol, getPropWorldValue(time, thisProperty));\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_sub(getPropWorldValue($bm_sub(time, overlapDuration), thisLayer.anchorPoint), ol), motionRatio), flexibility));\n ol = thisLayer.fromWorld(ol);\n if (!isThisPosition)\n ol = $bm_sub(ol, value);\n else {\n ol = linear(flexibility, 0, 100, $bm_div(ol, 2), 0);\n var prevParentWorldPos = getLayerWorldPos($bm_sub(time, overlapDuration), parent);\n ol = $bm_sum(ol, $bm_mul($bm_mul($bm_mul(thisLayer.fromWorld(prevParentWorldPos), motionRatio), flexibility), 5));\n }\n return ol;\n}\nvar okToGo = false;\nif (simulate && fx.enabled)\n okToGo = true;\nelse if (numKeys > 1 && fx.enabled)\n okToGo = true;\nif (okToGo) {\n var smartSmoothResult = zeroValue;\n if (doInterpolation) {\n if ($bm_isInstanceOfArray(value)) {\n if (value.length == 2)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1)\n ];\n else if (value.length == 3)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2)\n ];\n else if (value.length == 4)\n smartSmoothResult = [\n smartSmooth(0),\n smartSmooth(1),\n smartSmooth(2),\n smartSmooth(3)\n ];\n } else {\n smartSmoothResult = smartSmooth(0);\n }\n }\n if (doAnticipation)\n result = $bm_sum(result, anticipate());\n result = $bm_sum(result, smartSmoothResult);\n if (doFollowThrough)\n result = $bm_sum(result, followThrough());\n if (doOverlap)\n result = $bm_sum(result, overlap());\n}\n$bm_rt = result;" + }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.661, -2.796], + [0, 0], + [-4.817, 0], + [0, 0], + [-0.392, 3.807], + [0, 0], + [0.717, 4.425], + [0, 0], + [0, 0], + [-10.643, -27.599] + ], + "o": [ + [0, 0], + [-1.109, 4.688], + [0, 0], + [3.827, 0], + [0, 0], + [0.572, -4.446], + [0, 0], + [0, 0], + [-1.486, 20.659], + [1.034, 2.681] + ], + "v": [ + [-96.711, 84.843], + [-110.265, 142.168], + [-103.001, 151.351], + [-79.04, 151.351], + [-71.614, 144.65], + [-65.794, 88.147], + [-66.014, 74.772], + [-77.505, 3.896], + [-111.284, 3.896], + [-97.287, 76.434] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [ + 0.066666670144, 0.145098045468, 0.266666680574, 1 + ], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-4.348, -4.17], + [-0.361, -0.924], + [0.729, 0], + [0, 0], + [-1.108, 4.686], + [0, 0], + [1.037, 2.684], + [-1.487, 20.662], + [0, 0], + [0, 0], + [4.579, -5.616], + [-4.283, -10.29], + [-2.002, -10.965], + [6.576, -8.572], + [1.812, -3.773], + [-3.063, -2.855] + ], + "o": [ + [0.734, 0.699], + [-0.669, 0.195], + [0, 0], + [-4.816, 0], + [0, 0], + [0.657, -2.796], + [-10.639, -27.599], + [0, 0], + [0, 0], + [-5.995, 4.105], + [-7.044, 8.631], + [4.283, 10.284], + [1.931, 10.622], + [-2.547, 3.323], + [-1.813, 3.773], + [4.407, 4.117] + ], + "v": [ + [-78.57, 148.579], + [-76.929, 151.049], + [-79.038, 151.351], + [-102.999, 151.351], + [-110.268, 142.169], + [-96.709, 84.844], + [-97.289, 76.432], + [-111.281, 3.895], + [-77.504, 3.895], + [-75.566, 15.826], + [-93.367, 28.1], + [-94.475, 59.875], + [-81.638, 90.632], + [-89.031, 121.211], + [-96.507, 131.263], + [-95.393, 142.939] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.278431385756, 0.713725507259, 0.764705896378, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0.569, -4.449], + [0, 0], + [2.838, -0.835], + [0.729, 0], + [0, 0], + [-1.108, 4.686], + [0, 0], + [1.037, 2.684], + [-1.487, 20.662], + [0, 0], + [0, 0], + [0, 0] + ], + "o": [ + [0, 0], + [-0.314, 3.075], + [-0.669, 0.195], + [0, 0], + [-4.816, 0], + [0, 0], + [0.657, -2.796], + [-10.639, -27.599], + [0, 0], + [0, 0], + [0, 0], + [0.717, 4.425] + ], + "v": [ + [-65.792, 88.15], + [-71.615, 144.651], + [-76.929, 151.049], + [-79.038, 151.351], + [-102.999, 151.351], + [-110.268, 142.169], + [-96.709, 84.844], + [-97.289, 76.432], + [-111.281, 3.895], + [-77.504, 3.895], + [-75.566, 15.826], + [-66.011, 74.774] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.40000000596, 0.827450990677, 0.847058832645, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-0.002, -3.539], + [0, 0], + [0.59, 0], + [0, 0], + [-0.037, 0.613], + [0.199, 3.331], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0.59], + [0, 0], + [-0.614, 0], + [0.062, -1.012], + [-0.375, -6.279], + [12.326, 6.483], + [0, 0], + [0, 0], + [3.418, 0.932] + ], + "v": [ + [-60.524, 173.591], + [-60.524, 173.674], + [-61.591, 174.742], + [-100.735, 174.762], + [-101.801, 173.637], + [-101.92, 167.434], + [-98.378, 159.414], + [-81.088, 158.235], + [-75.953, 163.21], + [-66.307, 166.015] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.066666670144, 0.145098045468, 0.266666680574, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [12.326, 6.48], [0, 0], [0, 0]], + "o": [[0, 0], [0, 0], [0, 0], [0, 0]], + "v": [ + [-81.816, 158.235], + [-99.108, 159.414], + [-99.771, 150.299], + [-82.573, 150.299] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [ + 0.066666670144, 0.145098045468, 0.266666680574, 1 + ], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [0.231, 0.053], + [1.558, 0.065], + [0.752, -1.363], + [0.492, -0.865], + [1.445, -0.03], + [0.93, 0.361], + [0, 0], + [0, 0] + ], + "o": [ + [-0.231, -0.041], + [-1.523, -0.343], + [-1.552, -0.065], + [-0.486, 0.871], + [-0.717, 1.256], + [-1.001, 0.018], + [0, 0], + [0, 0], + [0, 0] + ], + "v": [ + [-82.26, 153.584], + [-82.953, 153.442], + [-87.515, 152.471], + [-91.537, 154.331], + [-92.538, 157.145], + [-96.258, 158.975], + [-99.179, 158.436], + [-99.771, 150.297], + [-82.574, 150.297] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.949019610882, 0.627451002598, 0.486274510622, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [12.328, 6.481], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "o": [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + "v": [ + [-81.816, 158.235], + [-99.108, 159.413], + [-99.179, 158.436], + [-99.771, 150.297], + [-82.574, 150.297], + [-82.26, 153.584] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.988235294819, 0.733333349228, 0.643137276173, 1 + ], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 27, + "ty": 4, + "nm": "Layer 4", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [96.667, 224.762, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [46.667, 174.762, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-3.381, -3.11], + [0, 0], + [3.079, 3.605], + [0, 0], + [5.457, 2.987], + [0, 0], + [9.326, -0.166], + [0, 0], + [8.239, -3.219], + [0, 0], + [6.132, -5.016] + ], + "o": [ + [0, 0], + [2.276, -3.709], + [-3.671, -4.297], + [0, 0], + [-6.398, -3.501], + [0, 0], + [-8.845, 0.158], + [0, 0], + [-8.933, 3.49], + [0, 0], + [-7.368, 6.028] + ], + "v": [ + [21.163, 174.762], + [79.279, 174.762], + [85.267, 155.688], + [71.748, 162.492], + [73.897, 144.05], + [58.871, 151.088], + [52.514, 127.115], + [42.183, 153.207], + [21.918, 124.201], + [27.084, 162.213], + [9.203, 150.293] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-1.654, -3.521], + [-0.24, 0.194], + [-0.416, -0.591], + [2.236, 7.624], + [3.521, -2.883] + ], + "o": [ + [0.185, -0.213], + [6.025, -4.926], + [-0.139, -0.342], + [-3.937, -4.232], + [-2.615, 2.144] + ], + "v": [ + [8.563, 159.264], + [9.201, 158.654], + [27.073, 170.556], + [22.028, 155.992], + [9.201, 150.291] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.882352948189, 0.898039221764, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [-8.844, 0.157], + [-0.425, -5.997], + [7.005, -0.129], + [0, 0], + [8.243, -3.225], + [-0.832, -5.794], + [-1.322, 0.518] + ], + "o": [ + [0, 0], + [4.648, -0.083], + [0.398, -6.765], + [-8.844, 0.157], + [0, 0], + [-3.04, 1.183], + [0.434, -1.673], + [8.243, -3.225] + ], + "v": [ + [42.183, 161.565], + [52.514, 135.477], + [59.186, 147.352], + [52.514, 127.114], + [42.183, 153.211], + [21.917, 124.203], + [19.339, 135.967], + [21.917, 132.566] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.882352948189, 0.898039221764, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [0, 0], + [-6.395, -3.493], + [-0.296, -0.471], + [2.541, 1.395], + [1.848, -2.07] + ], + "o": [ + [0, 0], + [0.508, 0.277], + [1.044, -3.983], + [-5.526, -3.031], + [0.055, 4.796] + ], + "v": [ + [58.872, 159.448], + [73.898, 152.407], + [75.099, 153.543], + [73.898, 144.053], + [59.316, 150.568] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.882352948189, 0.898039221764, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-3.381, -3.11], + [0, 0], + [3.079, 3.605], + [0, 0], + [5.457, 2.987], + [0, 0], + [9.326, -0.166], + [0, 0], + [8.239, -3.219], + [0, 0], + [6.132, -5.016] + ], + "o": [ + [0, 0], + [2.276, -3.709], + [-3.671, -4.297], + [0, 0], + [-6.398, -3.501], + [0, 0], + [-8.845, 0.158], + [0, 0], + [-8.933, 3.49], + [0, 0], + [-7.368, 6.028] + ], + "v": [ + [21.163, 174.762], + [79.279, 174.762], + [85.267, 155.688], + [71.748, 162.492], + [73.897, 144.05], + [58.871, 151.088], + [52.514, 127.115], + [42.183, 153.207], + [21.918, 124.201], + [27.084, 162.213], + [9.203, 150.293] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.72549021244, 0.764705896378, 0.988235294819, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 5", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 5, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 28, + "ty": 4, + "nm": "Layer 3", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [96.668, 224.762, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [46.668, 174.762, 0], "ix": 1, "l": 2 }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 0, + "s": [100, 105, 100] + }, + { + "i": { "x": [0.833, 0.833, 0.833], "y": [0.833, 0.833, 0.833] }, + "o": { "x": [0.167, 0.167, 0.167], "y": [0.167, 0.167, 0.167] }, + "t": 12.5, + "s": [100, 95, 100] + }, + { "t": 25, "s": [100, 105, 100] } + ], + "ix": 6, + "l": 2, + "x": "var $bm_rt;\n$bm_rt = loopOutDuration();" + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Kleaner", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + }, + { + "ty": 5, + "nm": "Kleaner 2", + "np": 34, + "mn": "Pseudo/Duik Kleaner v3.2", + "ix": 2, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0001", + "ix": 1, + "v": { "a": 0, "k": 0, "ix": 1 } + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0002", + "ix": 2, + "v": { "a": 0, "k": 0, "ix": 2 } + }, + { + "ty": 7, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0003", + "ix": 3, + "v": { "a": 0, "k": 1, "ix": 3 } + }, + { + "ty": 6, + "nm": "Anticipation", + "mn": "Pseudo/Duik Kleaner v3.2-0004", + "ix": 4, + "v": 0 + }, + { + "ty": 0, + "nm": "Duration (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0005", + "ix": 5, + "v": { "a": 0, "k": 0.3, "ix": 5 } + }, + { + "ty": 0, + "nm": "Amplitude", + "mn": "Pseudo/Duik Kleaner v3.2-0006", + "ix": 6, + "v": { "a": 0, "k": 50, "ix": 6 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0007", + "ix": 7, + "v": 0 + }, + { + "ty": 6, + "nm": "Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0008", + "ix": 8, + "v": 0 + }, + { + "ty": 0, + "nm": "Slow In", + "mn": "Pseudo/Duik Kleaner v3.2-0009", + "ix": 9, + "v": { "a": 0, "k": 60, "ix": 9 } + }, + { + "ty": 0, + "nm": "Slow Out", + "mn": "Pseudo/Duik Kleaner v3.2-0010", + "ix": 10, + "v": { "a": 0, "k": 25, "ix": 10 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0011", + "ix": 11, + "v": 0 + }, + { + "ty": 6, + "nm": "Follow Through", + "mn": "Pseudo/Duik Kleaner v3.2-0012", + "ix": 12, + "v": 0 + }, + { + "ty": 0, + "nm": "Elasticity", + "mn": "Pseudo/Duik Kleaner v3.2-0013", + "ix": 13, + "v": { "a": 0, "k": 10, "ix": 13 } + }, + { + "ty": 0, + "nm": "Elasticity random", + "mn": "Pseudo/Duik Kleaner v3.2-0014", + "ix": 14, + "v": { "a": 0, "k": 0, "ix": 14 } + }, + { + "ty": 0, + "nm": "Damping", + "mn": "Pseudo/Duik Kleaner v3.2-0015", + "ix": 15, + "v": { "a": 0, "k": 50, "ix": 15 } + }, + { + "ty": 0, + "nm": "Damping random", + "mn": "Pseudo/Duik Kleaner v3.2-0016", + "ix": 16, + "v": { "a": 0, "k": 0, "ix": 16 } + }, + { + "ty": 7, + "nm": "Bounce", + "mn": "Pseudo/Duik Kleaner v3.2-0017", + "ix": 17, + "v": { "a": 0, "k": 0, "ix": 17 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0018", + "ix": 18, + "v": 0 + }, + { + "ty": 6, + "nm": "Spatial Options", + "mn": "Pseudo/Duik Kleaner v3.2-0019", + "ix": 19, + "v": 0 + }, + { + "ty": 7, + "nm": "Smart Interpolation", + "mn": "Pseudo/Duik Kleaner v3.2-0020", + "ix": 20, + "v": { "a": 0, "k": 0, "ix": 20 } + }, + { + "ty": 7, + "nm": "Mode", + "mn": "Pseudo/Duik Kleaner v3.2-0021", + "ix": 21, + "v": { "a": 0, "k": 1, "ix": 21 } + }, + { + "ty": 6, + "nm": "Overlap (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0022", + "ix": 22, + "v": 0 + }, + { + "ty": 7, + "nm": "Overlap", + "mn": "Pseudo/Duik Kleaner v3.2-0023", + "ix": 23, + "v": { "a": 0, "k": 1, "ix": 23 } + }, + { + "ty": 0, + "nm": "Delay (s)", + "mn": "Pseudo/Duik Kleaner v3.2-0024", + "ix": 24, + "v": { "a": 0, "k": 0.05, "ix": 24 } + }, + { + "ty": 0, + "nm": "Overlap random", + "mn": "Pseudo/Duik Kleaner v3.2-0025", + "ix": 25, + "v": { "a": 0, "k": 0, "ix": 25 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0026", + "ix": 26, + "v": 0 + }, + { + "ty": 6, + "nm": "Soft Body (simulation)", + "mn": "Pseudo/Duik Kleaner v3.2-0027", + "ix": 27, + "v": 0 + }, + { + "ty": 7, + "nm": "Soft Body", + "mn": "Pseudo/Duik Kleaner v3.2-0028", + "ix": 28, + "v": { "a": 0, "k": 1, "ix": 28 } + }, + { + "ty": 0, + "nm": "Soft-Body Flexibility", + "mn": "Pseudo/Duik Kleaner v3.2-0029", + "ix": 29, + "v": { "a": 0, "k": 100, "ix": 29 } + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0030", + "ix": 30, + "v": 0 + }, + { + "ty": 6, + "nm": "", + "mn": "Pseudo/Duik Kleaner v3.2-0031", + "ix": 31, + "v": 0 + }, + { + "ty": 0, + "nm": "Precision", + "mn": "Pseudo/Duik Kleaner v3.2-0032", + "ix": 32, + "v": { "a": 0, "k": 1, "ix": 32 } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-6.299, -5.795], + [0, 0], + [5.737, 6.717], + [0, 0], + [10.167, 5.565], + [0, 0], + [17.378, -0.31], + [0, 0], + [15.353, -5.997], + [0, 0], + [11.427, -9.347] + ], + "o": [ + [0, 0], + [4.241, -6.911], + [-6.84, -8.006], + [0, 0], + [-11.921, -6.523], + [0, 0], + [-16.48, 0.294], + [0, 0], + [-16.645, 6.503], + [0, 0], + [-13.729, 11.232] + ], + "v": [ + [-0.855, 174.762], + [107.432, 174.762], + [118.591, 139.221], + [93.401, 151.899], + [97.405, 117.535], + [69.407, 130.65], + [57.561, 85.981], + [38.311, 134.599], + [0.552, 80.551], + [10.177, 151.38], + [-23.14, 129.168] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-8.446, -7.984], + [-10.378, 8.492], + [-6.349, -5.591], + [6.857, -5.6] + ], + "o": [ + [-10.387, -10.978], + [5.046, -4.131], + [-7.402, -8.188], + [-12.845, 10.516] + ], + "v": [ + [-2.322, 173.384], + [-16.757, 135.542], + [1.734, 140.865], + [-23.143, 129.165] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-5.064, -13.178], + [-0.268, -0.361], + [-16.449, 6.432], + [-2.699, -1.894], + [4.371, -1.71] + ], + "o": [ + [4.334, 4.898], + [-0.61, -1.488], + [2.449, -0.961], + [-4.833, -6.099], + [-14.379, 5.619] + ], + "v": [ + [8.887, 148.11], + [16.548, 157.73], + [6.928, 86.924], + [14.709, 88.588], + [0.551, 80.548] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [1.534, -13.566], + [0, 0], + [-16.477, 0.296], + [-0.85, -0.277], + [4.316, -0.074] + ], + "o": [ + [3.493, 7.92], + [0, 0], + [0.998, -0.018], + [-1.931, -4.131], + [-12.392, 0.222] + ], + "v": [ + [38.994, 127.16], + [44.687, 140.975], + [63.936, 92.358], + [66.708, 92.746], + [57.56, 85.982] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 4", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 4, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [5.757, -4.824], + [0, 0], + [-11.45, -2.384], + [1.922, 1.053] + ], + "o": [ + [-0.092, 7.578], + [0, 0], + [-0.434, -2.366], + [-6.838, -3.733] + ], + "v": [ + [76.615, 123.482], + [75.783, 137.03], + [100.817, 122.826], + [97.407, 117.531] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.458823531866, 0.482352942228, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 5", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 5, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [-6.299, -5.795], + [0, 0], + [5.737, 6.717], + [0, 0], + [10.167, 5.565], + [0, 0], + [17.378, -0.31], + [0, 0], + [15.353, -5.997], + [0, 0], + [11.427, -9.347] + ], + "o": [ + [0, 0], + [4.241, -6.911], + [-6.84, -8.006], + [0, 0], + [-11.921, -6.523], + [0, 0], + [-16.48, 0.294], + [0, 0], + [-16.645, 6.503], + [0, 0], + [-13.729, 11.232] + ], + "v": [ + [-0.855, 174.762], + [107.432, 174.762], + [118.591, 139.221], + [93.401, 151.899], + [97.405, 117.535], + [69.407, 130.65], + [57.561, 85.981], + [38.311, 134.599], + [0.552, 80.551], + [10.177, 151.38], + [-23.14, 129.168] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.552941203117, 0.584313750267, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 6", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 6, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 29, + "ty": 4, + "nm": "Layer 2", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [50, 50, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [0, 0, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0]], + "o": [[0, 0], [0, 0]], + "v": [[136.775, 174.762], [145.314, 174.762]], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.882352948189, 0.898039221764, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0]], + "o": [[0, 0], [0, 0]], + "v": [[107.432, 174.762], [128.526, 174.762]], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.882352948189, 0.898039221764, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [[0, 0], [0, 0]], + "o": [[0, 0], [0, 0]], + "v": [[-22.042, 174.762], [-33.881, 174.762]], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [0.066666670144, 0.145098045468, 0.266666680574, 1], + "ix": 3 + }, + "o": { "a": 0, "k": 100, "ix": 4 }, + "w": { "a": 0, "k": 1.025, "ix": 5 }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.882352948189, 0.898039221764, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 3", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 3, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 30, + "ty": 4, + "nm": "Layer 1", + "parent": 1, + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": 0, "ix": 10 }, + "p": { "a": 0, "k": [50, 50, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [0, 0, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [100, 100, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [4.864, -30.745], + [17.418, -10.523], + [14.881, 0.014], + [14.65, -2.638], + [5.977, -7.9], + [16.363, -3.014], + [16.384, 2.905], + [13.428, 8.405], + [-0.52, 15.828], + [-0.173, 21.697], + [10.776, 19.131], + [-11.983, 21.429], + [-24.537, 0.947], + [-36.556, -8.124], + [-15.987, -3.115], + [-17.859, -25.498] + ], + "o": [ + [-3.173, 20.107], + [-12.742, 7.697], + [-14.881, -0.014], + [-9.873, 1.778], + [-10.033, 13.262], + [-16.363, 3.021], + [-15.604, -2.761], + [-13.421, -8.405], + [0.715, -21.689], + [0.181, -21.95], + [-12.041, -21.4], + [11.983, -21.436], + [37.416, -1.438], + [15.9, 3.534], + [30.557, 5.941], + [17.859, 25.491] + ], + "v": [ + [159.609, 37.383], + [129.731, 88.408], + [86.627, 97.631], + [42.071, 98.895], + [14.758, 111.052], + [-24.71, 139.477], + [-74.297, 137.157], + [-119.237, 122.666], + [-142.777, 83.877], + [-121.369, 23.102], + [-151.999, -33.944], + [-152.1, -104.44], + [-91.99, -141.278], + [14.289, -107.533], + [62.69, -101.007], + [139.098, -51.383] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.933333337307, 0.956862747669, 1, 1], + "ix": 4 + }, + "o": { "a": 0, "k": 100, "ix": 5 }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 225, + "st": 0, + "bm": 0 + } + ], + "markers": [], + "nm": "Comp 20", + "op": 200, + "v": "5.7.11", + "w": 512 +} diff --git a/apps/admin/public/payment/alipay.svg b/apps/admin/public/payment/alipay.svg new file mode 100644 index 0000000..6cdeac6 --- /dev/null +++ b/apps/admin/public/payment/alipay.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/apps/admin/public/payment/alipay_f2f.svg b/apps/admin/public/payment/alipay_f2f.svg new file mode 100644 index 0000000..b33c4e1 --- /dev/null +++ b/apps/admin/public/payment/alipay_f2f.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/apps/admin/public/payment/balance.svg b/apps/admin/public/payment/balance.svg new file mode 100644 index 0000000..5921da9 --- /dev/null +++ b/apps/admin/public/payment/balance.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/apps/admin/public/payment/epay.svg b/apps/admin/public/payment/epay.svg new file mode 100644 index 0000000..a257b93 --- /dev/null +++ b/apps/admin/public/payment/epay.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/apps/admin/public/payment/stripe_alipay.svg b/apps/admin/public/payment/stripe_alipay.svg new file mode 100644 index 0000000..cccb0f2 --- /dev/null +++ b/apps/admin/public/payment/stripe_alipay.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/apps/admin/public/payment/stripe_wechat_pay.svg b/apps/admin/public/payment/stripe_wechat_pay.svg new file mode 100644 index 0000000..5ee3a5a --- /dev/null +++ b/apps/admin/public/payment/stripe_wechat_pay.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/apps/admin/public/payment/wechat_pay.svg b/apps/admin/public/payment/wechat_pay.svg new file mode 100644 index 0000000..3b518f1 --- /dev/null +++ b/apps/admin/public/payment/wechat_pay.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/apps/admin/public/pwa-192x192.png b/apps/admin/public/pwa-192x192.png new file mode 100644 index 0000000..e1580e0 Binary files /dev/null and b/apps/admin/public/pwa-192x192.png differ diff --git a/apps/admin/public/pwa-512x512.png b/apps/admin/public/pwa-512x512.png new file mode 100644 index 0000000..5f3c019 Binary files /dev/null and b/apps/admin/public/pwa-512x512.png differ diff --git a/apps/admin/public/pwa-maskable-192x192.png b/apps/admin/public/pwa-maskable-192x192.png new file mode 100644 index 0000000..b1c042f Binary files /dev/null and b/apps/admin/public/pwa-maskable-192x192.png differ diff --git a/apps/admin/public/pwa-maskable-512x512.png b/apps/admin/public/pwa-maskable-512x512.png new file mode 100644 index 0000000..316f1a3 Binary files /dev/null and b/apps/admin/public/pwa-maskable-512x512.png differ diff --git a/apps/admin/public/robots.txt b/apps/admin/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/apps/admin/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/apps/admin/public/site.webmanifest b/apps/admin/public/site.webmanifest new file mode 100644 index 0000000..eeb8be1 --- /dev/null +++ b/apps/admin/public/site.webmanifest @@ -0,0 +1,34 @@ +{ + "name": "PPanel", + "short_name": "PPanel", + "icons": [ + { + "src": "/pwa-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/pwa-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/pwa-maskable-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/pwa-maskable-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "start_url": "/", + "display": "standalone", + "background_color": "#FFFFFF", + "theme_color": "#FFFFFF" +} diff --git a/apps/admin/src/components/display.tsx b/apps/admin/src/components/display.tsx new file mode 100644 index 0000000..d7ec6bf --- /dev/null +++ b/apps/admin/src/components/display.tsx @@ -0,0 +1,49 @@ +import { formatBytes } from "@workspace/ui/utils/formatting"; +import { unitConversion } from "@workspace/ui/utils/unit-conversions"; +import { useTranslation } from "react-i18next"; +import { useGlobalStore } from "@/stores/global"; + +type DisplayType = "currency" | "traffic" | "number" | "trafficSpeed"; + +interface DisplayProps { + value?: T; + unlimited?: boolean; + type?: DisplayType; +} + +export function Display({ + value = 0, + unlimited = false, + type = "number", +}: DisplayProps): string { + const { t } = useTranslation("components"); + const { common } = useGlobalStore(); + const { currency } = common; + + if (type === "currency") { + const formattedValue = `${currency?.currency_symbol ?? ""}${unitConversion("centsToDollars", value as number)?.toFixed(2) ?? "0.00"}`; + return formattedValue; + } + + if ( + ["traffic", "trafficSpeed", "number"].includes(type) && + unlimited && + !value + ) { + return t("unlimited"); + } + + if (type === "traffic") { + return value ? formatBytes(value) : "0"; + } + + if (type === "trafficSpeed") { + return value ? `${formatBytes(value).replace("B", "b")}ps` : "0"; + } + + if (type === "number") { + return value ? value.toString() : "0"; + } + + return "0"; +} diff --git a/apps/admin/src/components/ip-link.tsx b/apps/admin/src/components/ip-link.tsx new file mode 100644 index 0000000..3abc74f --- /dev/null +++ b/apps/admin/src/components/ip-link.tsx @@ -0,0 +1,32 @@ +"use client"; + +import { ExternalLink } from "lucide-react"; +import type React from "react"; + +interface IpLinkProps { + ip: string; + children?: React.ReactNode; + className?: string; + target?: "_blank" | "_self"; +} + +export function IpLink({ + ip, + children, + className = "", + target = "_blank", +}: IpLinkProps) { + const url = `https://ipinfo.io/${ip}`; + + return ( + + {children || ip} + + + ); +} diff --git a/apps/admin/src/components/order-link.tsx b/apps/admin/src/components/order-link.tsx new file mode 100644 index 0000000..60d6989 --- /dev/null +++ b/apps/admin/src/components/order-link.tsx @@ -0,0 +1,19 @@ +import { Link } from "@tanstack/react-router"; +import { Button } from "@workspace/ui/components/button"; + +interface OrderLinkProps { + orderId?: string | number; + className?: string; +} + +export function OrderLink({ orderId, className }: OrderLinkProps) { + if (!orderId) return --; + + return ( + + ); +} diff --git a/apps/admin/src/config/index.ts b/apps/admin/src/config/index.ts new file mode 100644 index 0000000..09a90dd --- /dev/null +++ b/apps/admin/src/config/index.ts @@ -0,0 +1,10 @@ +export const fallbackLng = "en-US"; +export const supportedLngs = ["en-US", "zh-CN"]; + +export const CDN_URL = + import.meta.env.VITE_CDN_URL || "https://cdn.jsdmirror.com"; +export const TUTORIAL_DOCUMENT = + import.meta.env.VITE_TUTORIAL_DOCUMENT || "true"; + +export const USER_EMAIL = import.meta.env.VITE_USER_EMAIL; +export const USER_PASSWORD = import.meta.env.VITE_USER_PASSWORD; diff --git a/apps/admin/src/layout/header.tsx b/apps/admin/src/layout/header.tsx new file mode 100644 index 0000000..0dfea8a --- /dev/null +++ b/apps/admin/src/layout/header.tsx @@ -0,0 +1,56 @@ +import { Link, useLocation } from "@tanstack/react-router"; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "@workspace/ui/components/breadcrumb"; +import { Separator } from "@workspace/ui/components/separator"; +import { SidebarTrigger } from "@workspace/ui/components/sidebar"; +import { LanguageSwitch } from "@workspace/ui/composed/language-switch"; +import { ThemeSwitch } from "@workspace/ui/composed/theme-switch"; +import { Fragment, useMemo } from "react"; +import { findNavByUrl, useNavs } from "./navs"; +import TimezoneSwitch from "./timezone-switch"; +import { UserNav } from "./user-nav"; + +export function Header() { + const pathname = useLocation({ select: (location) => location.pathname }); + const navs = useNavs(); + const items = useMemo(() => findNavByUrl(navs, pathname), [pathname]); + return ( +
+
+ + + + + {items.map((item, index) => ( + + {index !== items.length - 1 && ( + + + {item?.title} + + + )} + {index < items.length - 1 && } + {index === items.length - 1 && ( + {item?.title} + )} + + ))} + + +
+
+ + + + +
+
+ ); +} diff --git a/apps/admin/src/layout/index.tsx b/apps/admin/src/layout/index.tsx new file mode 100644 index 0000000..5a69e71 --- /dev/null +++ b/apps/admin/src/layout/index.tsx @@ -0,0 +1,32 @@ +import { Outlet } from "@tanstack/react-router"; +import { + SidebarInset, + SidebarProvider, +} from "@workspace/ui/components/sidebar"; +import { getCookie } from "@workspace/ui/lib/cookies"; +import { useEffect, useState } from "react"; +import { Header } from "@/layout/header"; +import { SidebarLeft } from "./sidebar-left"; + +export default function DashboardLayout() { + const [open, setOpen] = useState(true); + + useEffect(() => { + const sidebarState = getCookie("sidebar_state"); + if (sidebarState !== undefined) { + setOpen(sidebarState === "true"); + } + }, []); + + return ( + + + +
+
+ +
+ + + ); +} diff --git a/apps/admin/src/layout/navs.ts b/apps/admin/src/layout/navs.ts new file mode 100644 index 0000000..e9be2a8 --- /dev/null +++ b/apps/admin/src/layout/navs.ts @@ -0,0 +1,226 @@ +import { useMemo } from "react"; +import { useTranslation } from "react-i18next"; + +export interface NavItem { + title: string; + url?: string; + icon?: string; + items?: NavItem[]; + defaultOpen?: boolean; +} + +export function useNavs() { + const { t } = useTranslation("menu"); + + const navs: NavItem[] = useMemo( + () => [ + { + title: t("Dashboard", "Dashboard"), + url: "/dashboard", + icon: "flat-color-icons:globe", + }, + + { + title: t("Maintenance", "Maintenance"), + icon: "flat-color-icons:data-protection", + items: [ + { + title: t("Server Management", "Server Management"), + url: "/dashboard/servers", + icon: "flat-color-icons:data-protection", + }, + { + title: t("Node Management", "Node Management"), + url: "/dashboard/nodes", + icon: "flat-color-icons:mind-map", + }, + { + title: t("Subscribe Config", "Subscribe Config"), + url: "/dashboard/subscribe", + icon: "flat-color-icons:ruler", + }, + { + title: t("Product Management", "Product Management"), + url: "/dashboard/product", + icon: "flat-color-icons:shop", + }, + ], + }, + + { + title: t("Commerce", "Commerce"), + icon: "flat-color-icons:sales-performance", + items: [ + { + title: t("Order Management", "Order Management"), + url: "/dashboard/order", + icon: "flat-color-icons:todo-list", + }, + { + title: t("Coupon Management", "Coupon Management"), + url: "/dashboard/coupon", + icon: "flat-color-icons:bookmark", + }, + { + title: t("Marketing Management", "Marketing Management"), + url: "/dashboard/marketing", + icon: "flat-color-icons:bullish", + }, + { + title: t("Announcement Management", "Announcement Management"), + url: "/dashboard/announcement", + icon: "flat-color-icons:advertising", + }, + ], + }, + + { + title: t("Users & Support", "Users & Support"), + icon: "flat-color-icons:collaboration", + items: [ + { + title: t("User Management", "User Management"), + url: "/dashboard/user", + icon: "flat-color-icons:conference-call", + }, + { + title: t("Ticket Management", "Ticket Management"), + url: "/dashboard/ticket", + icon: "flat-color-icons:collaboration", + }, + { + title: t("Document Management", "Document Management"), + url: "/dashboard/document", + icon: "flat-color-icons:document", + }, + ], + }, + + { + defaultOpen: false, + title: t("System", "System"), + icon: "flat-color-icons:services", + items: [ + { + title: t("System Config", "System Config"), + url: "/dashboard/system", + icon: "flat-color-icons:services", + }, + { + title: t("Auth Control", "Auth Control"), + url: "/dashboard/auth-control", + icon: "flat-color-icons:lock-portrait", + }, + { + title: t("Payment Config", "Payment Config"), + url: "/dashboard/payment", + icon: "flat-color-icons:currency-exchange", + }, + { + title: t("ADS Config", "ADS Config"), + url: "/dashboard/ads", + icon: "flat-color-icons:electrical-sensor", + }, + ], + }, + + { + defaultOpen: false, + title: t("Logs & Analytics", "Logs & Analytics"), + icon: "flat-color-icons:statistics", + items: [ + { + title: t("Login", "Login"), + url: "/dashboard/log/login", + icon: "flat-color-icons:unlock", + }, + { + title: t("Register", "Register"), + url: "/dashboard/log/register", + icon: "flat-color-icons:contacts", + }, + { + title: t("Email", "Email"), + url: "/dashboard/log/email", + icon: "flat-color-icons:feedback", + }, + { + title: t("Mobile", "Mobile"), + url: "/dashboard/log/mobile", + icon: "flat-color-icons:sms", + }, + { + title: t("Subscribe", "Subscribe"), + url: "/dashboard/log/subscribe", + icon: "flat-color-icons:workflow", + }, + { + title: t("Reset Subscribe", "Reset Subscribe"), + url: "/dashboard/log/reset-subscribe", + icon: "flat-color-icons:refresh", + }, + { + title: t("Subscribe Traffic", "Subscribe Traffic"), + url: "/dashboard/log/subscribe-traffic", + icon: "flat-color-icons:statistics", + }, + { + title: t("Server Traffic", "Server Traffic"), + url: "/dashboard/log/server-traffic", + icon: "flat-color-icons:statistics", + }, + { + title: t("Traffic Details", "Traffic Details"), + url: "/dashboard/log/traffic-details", + icon: "flat-color-icons:combo-chart", + }, + { + title: t("Balance", "Balance"), + url: "/dashboard/log/balance", + icon: "flat-color-icons:sales-performance", + }, + { + title: t("Commission", "Commission"), + url: "/dashboard/log/commission", + icon: "flat-color-icons:debt", + }, + { + title: t("Gift", "Gift"), + url: "/dashboard/log/gift", + icon: "flat-color-icons:donate", + }, + ], + }, + ], + [t] + ); + + return navs; +} + +export function findNavByUrl(navs: NavItem[], url: string) { + function matchDynamicRoute(pattern: string, path: string): boolean { + const regexPattern = pattern + .replace(/:[^/]+/g, "[^/]+") + .replace(/\//g, "\\/"); + const regex = new RegExp(`^${regexPattern}$`); + return regex.test(path); + } + function findNav( + items: NavItem[], + url: string, + path: NavItem[] = [] + ): NavItem[] { + for (const item of items) { + if (item.url === url || (item.url && matchDynamicRoute(item.url, url))) { + return [...path, item]; + } + if (item.items) { + const result = findNav(item.items, url, [...path, item]); + if (result.length) return result; + } + } + return []; + } + return findNav(navs, url); +} diff --git a/apps/admin/src/layout/sidebar-left.tsx b/apps/admin/src/layout/sidebar-left.tsx new file mode 100644 index 0000000..4bff40f --- /dev/null +++ b/apps/admin/src/layout/sidebar-left.tsx @@ -0,0 +1,294 @@ +import { Link, useLocation } from "@tanstack/react-router"; +import { + HoverCard, + HoverCardContent, + HoverCardTrigger, +} from "@workspace/ui/components/hover-card"; +import { + Sidebar, + SidebarContent, + SidebarGroup, + SidebarGroupContent, + SidebarHeader, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@workspace/ui/components/sidebar"; +import { Icon } from "@workspace/ui/composed/icon"; +import { cn } from "@workspace/ui/lib/utils"; +import React, { useState } from "react"; +import { useGlobalStore } from "@/stores/global"; +import { type NavItem, useNavs } from "./navs"; + +function hasChildren(obj: any): obj is { items: any[] } { + return ( + obj && Array.isArray((obj as any).items) && (obj as any).items.length > 0 + ); +} + +export function SidebarLeft({ + ...props +}: React.ComponentProps) { + const { common } = useGlobalStore(); + const { site } = common; + const navs = useNavs(); + const pathname = useLocation({ select: (location) => location.pathname }); + const { state, isMobile } = useSidebar(); + + const [openGroups, setOpenGroups] = useState>({}); + + React.useEffect(() => { + setOpenGroups((prev) => { + const next: Record = { ...prev }; + navs.forEach((nav) => { + if (hasChildren(nav) && next[nav.title] === undefined) { + next[nav.title] = nav.defaultOpen ?? true; + } + }); + return next; + }); + }, [navs]); + + const handleToggleGroup = (title: string) => { + setOpenGroups((prev) => ({ ...prev, [title]: !prev[title] })); + }; + + const normalize = (p: string) => + p.endsWith("/") && p !== "/" ? p.replace(/\/+$/, "") : p; + const isActiveUrl = (url: string) => { + const path = normalize(pathname); + const target = normalize(url); + if (target === "/dashboard") return path === target; + if (path === target) return true; + return path.startsWith(`${target}/`); + }; + + const isGroupActive = (nav: NavItem) => + (hasChildren(nav) && nav.items?.some((i: any) => isActiveUrl(i.url))) || + ("url" in nav && nav.url ? isActiveUrl(nav.url as string) : false); + + React.useEffect(() => { + setOpenGroups((prev) => { + const next: Record = { ...prev }; + navs.forEach((nav) => { + if (hasChildren(nav) && isGroupActive(nav)) next[nav.title] = true; + }); + return next; + }); + }, [pathname, navs]); + + const renderCollapsedFlyout = (nav: NavItem) => { + const ParentButton = ( + + {"url" in nav && nav.url ? ( + + {"icon" in nav && (nav as any).icon ? ( + + ) : null} + + ) : "icon" in nav && (nav as any).icon ? ( + + ) : null} + + ); + + if (!hasChildren(nav)) return ParentButton; + + return ( + + {ParentButton} + +
+ {"icon" in nav && (nav as any).icon ? ( + + ) : null} + + {nav.title} + +
+ +
    + {nav.items?.map((item: any) => ( +
  • + + {item.icon && } + {item.title} + +
  • + ))} +
+
+
+ ); + }; + + return ( + + + + + + +
+ logo +
+
+ + {site.site_name} + + + {site.site_desc} + +
+ +
+
+
+
+ + + + {!isMobile && state === "collapsed" + ? navs.map((nav) => ( + + {renderCollapsedFlyout(nav)} + + )) + : navs.map((nav) => { + if (hasChildren(nav)) { + const isOpen = openGroups[nav.title] ?? false; + return ( + + handleToggleGroup(nav.title)} + size="sm" + style={{ fontWeight: 500 }} + tabIndex={0} + > + + {"icon" in nav && (nav as any).icon ? ( + + ) : null} + {nav.title} + + + + {isOpen && ( + + + {nav.items?.map((item: any) => ( + + + + {item.icon && ( + + )} + + {item.title} + + + + + ))} + + + )} + + ); + } + + return ( + + + + + + {"url" in nav && (nav as any).url ? ( + + {"icon" in nav && (nav as any).icon ? ( + + ) : null} + {nav.title} + + ) : ( + <> + {"icon" in nav && (nav as any).icon ? ( + + ) : null} + {nav.title} + + )} + + + + + + ); + })} + + +
+ ); +} diff --git a/apps/admin/src/layout/timezone-switch.tsx b/apps/admin/src/layout/timezone-switch.tsx new file mode 100644 index 0000000..82f40b1 --- /dev/null +++ b/apps/admin/src/layout/timezone-switch.tsx @@ -0,0 +1,315 @@ +import { Button } from "@workspace/ui/components/button"; +import { + Command, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@workspace/ui/components/command"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@workspace/ui/components/popover"; +import { Icon } from "@workspace/ui/composed/icon"; +import { useEffect, useMemo, useState } from "react"; +import { useTranslation } from "react-i18next"; + +interface TimezoneOption { + value: string; + label: string; + timezone: string; +} + +function getCurrentTime(timezone: string): string { + try { + const now = new Date(); + return now.toLocaleTimeString("en-US", { + timeZone: timezone, + hour12: false, + hour: "2-digit", + minute: "2-digit", + }); + } catch { + return "--:--"; + } +} + +function getAllTimezones(locale = "en-US"): TimezoneOption[] { + try { + const timeZones = Intl.supportedValuesOf("timeZone"); + + const processed = timeZones + .map((tz) => { + try { + return { + value: tz, + label: tz, + timezone: getTimezoneOffset(tz), + }; + } catch { + return { + value: tz, + label: tz, + timezone: "UTC+00:00", + }; + } + }) + .filter(Boolean) + .sort((a, b) => a.label.localeCompare(b.label, locale)); + + const hasUTC = processed.some((tz) => tz.value === "UTC"); + if (!hasUTC) { + processed.unshift({ + value: "UTC", + label: "UTC", + timezone: "UTC+00:00", + }); + } + + return processed; + } catch { + return [ + { + value: "UTC", + label: "UTC", + timezone: "UTC+00:00", + }, + ]; + } +} + +function getServerTimezones(): string[] { + return ["UTC"]; +} + +function getRecommendedTimezones(): string[] { + try { + const browserTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + + if (browserTimezone.startsWith("Asia/")) { + return [ + "Asia/Shanghai", + "Asia/Tokyo", + "Asia/Kolkata", + "Asia/Singapore", + "Asia/Seoul", + ]; + } + if (browserTimezone.startsWith("Europe/")) { + return [ + "Europe/London", + "Europe/Paris", + "Europe/Berlin", + "Europe/Rome", + "Europe/Madrid", + ]; + } + if (browserTimezone.startsWith("America/")) { + return [ + "America/New_York", + "America/Los_Angeles", + "America/Chicago", + "America/Denver", + "America/Toronto", + ]; + } + if (browserTimezone.startsWith("Australia/")) { + return [ + "Australia/Sydney", + "Australia/Melbourne", + "Australia/Perth", + "Australia/Brisbane", + ]; + } + return [ + "America/New_York", + "Europe/London", + "Asia/Shanghai", + "Asia/Tokyo", + "Australia/Sydney", + ]; + } catch { + return [ + "America/New_York", + "Europe/London", + "Asia/Shanghai", + "Asia/Tokyo", + "Australia/Sydney", + ]; + } +} + +function getTimezoneOffset(timezone: string): string { + try { + const now = new Date(); + + const utc = new Date(now.getTime() + now.getTimezoneOffset() * 60_000); + const targetTime = new Date( + utc.toLocaleString("en-US", { timeZone: timezone }) + ); + const offset = (targetTime.getTime() - utc.getTime()) / (1000 * 60 * 60); + const sign = offset >= 0 ? "+" : "-"; + const hours = Math.floor(Math.abs(offset)); + const minutes = Math.floor((Math.abs(offset) - hours) * 60); + + return `UTC${sign}${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`; + } catch { + return "UTC+00:00"; + } +} + +export default function TimezoneSwitch() { + const { i18n } = useTranslation(); + const locale = i18n.language; + const [timezone, setTimezone] = useState("UTC"); + const [open, setOpen] = useState(false); + + const timezoneOptions = useMemo(() => getAllTimezones(locale), [locale]); + + useEffect(() => { + const savedTimezone = localStorage.getItem("timezone"); + if (savedTimezone) { + setTimezone(savedTimezone); + } else { + try { + const browserTimezone = + Intl.DateTimeFormat().resolvedOptions().timeZone; + setTimezone(browserTimezone); + localStorage.setItem("timezone", browserTimezone); + } catch { + setTimezone("UTC"); + } + } + }, []); + + const handleTimezoneChange = (newTimezone: string) => { + setTimezone(newTimezone); + localStorage.setItem("timezone", newTimezone); + setOpen(false); + + window.dispatchEvent( + new CustomEvent("timezoneChanged", { + detail: { timezone: newTimezone }, + }) + ); + }; + const serverTimezones = timezoneOptions.filter( + (option) => + getServerTimezones().includes(option.value) && option.value !== timezone + ); + + return ( + + + + + + + + + + {timezoneOptions + .filter((option) => option.value === timezone) + .map((option) => ( + handleTimezoneChange(option.value)} + value={`${option.label} ${option.value}`} + > +
+
+ {option.value} + + {option.timezone} • {getCurrentTime(option.value)} + +
+ +
+
+ ))} +
+ {serverTimezones.length > 0 && ( + + {serverTimezones.map((option) => ( + handleTimezoneChange(option.value)} + value={`${option.label} ${option.value}`} + > +
+
+ {option.value} + + {option.timezone} • {getCurrentTime(option.value)} + +
+ +
+
+ ))} +
+ )} + + + {timezoneOptions + .filter( + (option) => + getRecommendedTimezones().includes(option.value) && + option.value !== timezone + ) + .map((option) => ( + handleTimezoneChange(option.value)} + value={`${option.label} ${option.value}`} + > +
+
+ {option.value} + + {option.timezone} • {getCurrentTime(option.value)} + +
+ +
+
+ ))} +
+ + + {timezoneOptions + .filter( + (option) => + !( + getServerTimezones().includes(option.value) || + getRecommendedTimezones().includes(option.value) + ) && option.value !== timezone + ) + .map((option) => ( + handleTimezoneChange(option.value)} + value={`${option.label} ${option.value}`} + > +
+
+ {option.value} + + {option.timezone} • {getCurrentTime(option.value)} + +
+ +
+
+ ))} +
+
+
+
+
+ ); +} diff --git a/apps/admin/src/layout/user-nav.tsx b/apps/admin/src/layout/user-nav.tsx new file mode 100644 index 0000000..ecac3b2 --- /dev/null +++ b/apps/admin/src/layout/user-nav.tsx @@ -0,0 +1,73 @@ +import { + Avatar, + AvatarFallback, + AvatarImage, +} from "@workspace/ui/components/avatar"; +import { Button } from "@workspace/ui/components/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuTrigger, +} from "@workspace/ui/components/dropdown-menu"; +import { useTranslation } from "react-i18next"; +import { useGlobalStore } from "@/stores/global"; +import { Logout } from "@/utils/common"; + +export function UserNav() { + const { t } = useTranslation("auth"); + const { user } = useGlobalStore(); + + if (user) { + return ( + + + + + + +
+

+ {user?.auth_methods?.[0]?.auth_identifier} +

+ {/*

ID: {user?.id}

*/} +
+
+ {/* + + + Profile + ⇧⌘P + + + Billing + ⌘B + + + Settings + ⌘S + + New Team + */} + + + {t("logout", "Logout")} + ⇧⌘Q + +
+
+ ); + } +} diff --git a/apps/admin/src/main.tsx b/apps/admin/src/main.tsx new file mode 100644 index 0000000..040d57b --- /dev/null +++ b/apps/admin/src/main.tsx @@ -0,0 +1,95 @@ +import { createRouter, RouterProvider } from "@tanstack/react-router"; +import { + TanStackQueryContext, + TanStackQueryProvider, +} from "@workspace/ui/integrations/tanstack-query"; +import { StrictMode } from "react"; +import ReactDOM from "react-dom/client"; +// Import the generated route tree +import { routeTree } from "./routeTree.gen"; +// Styles +import "@workspace/ui/globals.css"; +import { DirectionProvider } from "@workspace/ui/integrations/direction"; +import { LanguageProvider } from "@workspace/ui/integrations/language"; +import { ThemeProvider } from "@workspace/ui/integrations/theme"; +import { initializeI18n } from "@workspace/ui/lib/i18n"; +import { fallbackLng, supportedLngs } from "./config/index.ts"; +// Report web vitals +import reportWebVitals from "./reportWebVitals.ts"; +// Common utilities +import { Logout } from "./utils/common.ts"; + +initializeI18n({ + supportedLngs, + fallbackLng, + ns: [ + "ads", + "announcement", + "auth-control", + "auth", + "components", + "coupon", + "dashboard", + "document", + "log", + "marketing", + "menu", + "nodes", + "order", + "payment", + "product", + "servers", + "subscribe", + "system", + "ticket", + "tool", + "translation", + "user", + ], +}); + +window.logout = Logout; + +// Create a new router instance +const TanStackQueryProviderContext = TanStackQueryContext(); +const router = createRouter({ + routeTree, + context: { + ...TanStackQueryProviderContext, + }, + defaultPreload: "intent", + scrollRestoration: true, + defaultStructuralSharing: true, + defaultPreloadStaleTime: 0, +}); + +// Register the router instance for type safety +declare module "@tanstack/react-router" { + interface Register { + router: typeof router; + } +} + +// Render the app +const rootElement = document.getElementById("app"); +if (rootElement && !rootElement.innerHTML) { + const root = ReactDOM.createRoot(rootElement); + root.render( + + + + + + + + + + + + ); +} + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals(); diff --git a/apps/admin/src/reportWebVitals.ts b/apps/admin/src/reportWebVitals.ts new file mode 100644 index 0000000..d0b6037 --- /dev/null +++ b/apps/admin/src/reportWebVitals.ts @@ -0,0 +1,13 @@ +const reportWebVitals = (onPerfEntry?: () => void) => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import("web-vitals").then(({ onCLS, onINP, onFCP, onLCP, onTTFB }) => { + onCLS(onPerfEntry); + onINP(onPerfEntry); + onFCP(onPerfEntry); + onLCP(onPerfEntry); + onTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/apps/admin/src/routeTree.gen.ts b/apps/admin/src/routeTree.gen.ts new file mode 100644 index 0000000..4f6dcff --- /dev/null +++ b/apps/admin/src/routeTree.gen.ts @@ -0,0 +1,799 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { createFileRoute } from '@tanstack/react-router' + +import { Route as rootRouteImport } from './routes/__root' + +const DashboardRouteLazyRouteImport = createFileRoute('/dashboard')() +const IndexLazyRouteImport = createFileRoute('/')() +const DashboardIndexLazyRouteImport = createFileRoute('/dashboard/')() +const DashboardServersLazyRouteImport = createFileRoute('/dashboard/servers')() +const DashboardNodesLazyRouteImport = createFileRoute('/dashboard/nodes')() +const DashboardUserIndexLazyRouteImport = createFileRoute('/dashboard/user/')() +const DashboardTicketIndexLazyRouteImport = + createFileRoute('/dashboard/ticket/')() +const DashboardSystemIndexLazyRouteImport = + createFileRoute('/dashboard/system/')() +const DashboardSubscribeIndexLazyRouteImport = createFileRoute( + '/dashboard/subscribe/', +)() +const DashboardProductIndexLazyRouteImport = createFileRoute( + '/dashboard/product/', +)() +const DashboardPaymentIndexLazyRouteImport = createFileRoute( + '/dashboard/payment/', +)() +const DashboardOrderIndexLazyRouteImport = + createFileRoute('/dashboard/order/')() +const DashboardMarketingIndexLazyRouteImport = createFileRoute( + '/dashboard/marketing/', +)() +const DashboardDocumentIndexLazyRouteImport = createFileRoute( + '/dashboard/document/', +)() +const DashboardCouponIndexLazyRouteImport = + createFileRoute('/dashboard/coupon/')() +const DashboardAuthControlIndexLazyRouteImport = createFileRoute( + '/dashboard/auth-control/', +)() +const DashboardAnnouncementIndexLazyRouteImport = createFileRoute( + '/dashboard/announcement/', +)() +const DashboardAdsIndexLazyRouteImport = createFileRoute('/dashboard/ads/')() +const DashboardLogTrafficDetailsLazyRouteImport = createFileRoute( + '/dashboard/log/traffic-details', +)() +const DashboardLogSubscribeTrafficLazyRouteImport = createFileRoute( + '/dashboard/log/subscribe-traffic', +)() +const DashboardLogSubscribeLazyRouteImport = createFileRoute( + '/dashboard/log/subscribe', +)() +const DashboardLogServerTrafficLazyRouteImport = createFileRoute( + '/dashboard/log/server-traffic', +)() +const DashboardLogResetSubscribeLazyRouteImport = createFileRoute( + '/dashboard/log/reset-subscribe', +)() +const DashboardLogRegisterLazyRouteImport = createFileRoute( + '/dashboard/log/register', +)() +const DashboardLogMobileLazyRouteImport = createFileRoute( + '/dashboard/log/mobile', +)() +const DashboardLogLoginLazyRouteImport = createFileRoute( + '/dashboard/log/login', +)() +const DashboardLogGiftLazyRouteImport = createFileRoute('/dashboard/log/gift')() +const DashboardLogEmailLazyRouteImport = createFileRoute( + '/dashboard/log/email', +)() +const DashboardLogCommissionLazyRouteImport = createFileRoute( + '/dashboard/log/commission', +)() +const DashboardLogBalanceLazyRouteImport = createFileRoute( + '/dashboard/log/balance', +)() + +const DashboardRouteLazyRoute = DashboardRouteLazyRouteImport.update({ + id: '/dashboard', + path: '/dashboard', + getParentRoute: () => rootRouteImport, +} as any).lazy(() => + import('./routes/dashboard/route.lazy').then((d) => d.Route), +) +const IndexLazyRoute = IndexLazyRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any).lazy(() => import('./routes/index.lazy').then((d) => d.Route)) +const DashboardIndexLazyRoute = DashboardIndexLazyRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/index.lazy').then((d) => d.Route), +) +const DashboardServersLazyRoute = DashboardServersLazyRouteImport.update({ + id: '/servers', + path: '/servers', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/servers.lazy').then((d) => d.Route), +) +const DashboardNodesLazyRoute = DashboardNodesLazyRouteImport.update({ + id: '/nodes', + path: '/nodes', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/nodes.lazy').then((d) => d.Route), +) +const DashboardUserIndexLazyRoute = DashboardUserIndexLazyRouteImport.update({ + id: '/user/', + path: '/user/', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/user/index.lazy').then((d) => d.Route), +) +const DashboardTicketIndexLazyRoute = + DashboardTicketIndexLazyRouteImport.update({ + id: '/ticket/', + path: '/ticket/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/ticket/index.lazy').then((d) => d.Route), + ) +const DashboardSystemIndexLazyRoute = + DashboardSystemIndexLazyRouteImport.update({ + id: '/system/', + path: '/system/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/system/index.lazy').then((d) => d.Route), + ) +const DashboardSubscribeIndexLazyRoute = + DashboardSubscribeIndexLazyRouteImport.update({ + id: '/subscribe/', + path: '/subscribe/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/subscribe/index.lazy').then((d) => d.Route), + ) +const DashboardProductIndexLazyRoute = + DashboardProductIndexLazyRouteImport.update({ + id: '/product/', + path: '/product/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/product/index.lazy').then((d) => d.Route), + ) +const DashboardPaymentIndexLazyRoute = + DashboardPaymentIndexLazyRouteImport.update({ + id: '/payment/', + path: '/payment/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/payment/index.lazy').then((d) => d.Route), + ) +const DashboardOrderIndexLazyRoute = DashboardOrderIndexLazyRouteImport.update({ + id: '/order/', + path: '/order/', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/order/index.lazy').then((d) => d.Route), +) +const DashboardMarketingIndexLazyRoute = + DashboardMarketingIndexLazyRouteImport.update({ + id: '/marketing/', + path: '/marketing/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/marketing/index.lazy').then((d) => d.Route), + ) +const DashboardDocumentIndexLazyRoute = + DashboardDocumentIndexLazyRouteImport.update({ + id: '/document/', + path: '/document/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/document/index.lazy').then((d) => d.Route), + ) +const DashboardCouponIndexLazyRoute = + DashboardCouponIndexLazyRouteImport.update({ + id: '/coupon/', + path: '/coupon/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/coupon/index.lazy').then((d) => d.Route), + ) +const DashboardAuthControlIndexLazyRoute = + DashboardAuthControlIndexLazyRouteImport.update({ + id: '/auth-control/', + path: '/auth-control/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/auth-control/index.lazy').then((d) => d.Route), + ) +const DashboardAnnouncementIndexLazyRoute = + DashboardAnnouncementIndexLazyRouteImport.update({ + id: '/announcement/', + path: '/announcement/', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/announcement/index.lazy').then((d) => d.Route), + ) +const DashboardAdsIndexLazyRoute = DashboardAdsIndexLazyRouteImport.update({ + id: '/ads/', + path: '/ads/', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/ads/index.lazy').then((d) => d.Route), +) +const DashboardLogTrafficDetailsLazyRoute = + DashboardLogTrafficDetailsLazyRouteImport.update({ + id: '/log/traffic-details', + path: '/log/traffic-details', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/log/traffic-details.lazy').then((d) => d.Route), + ) +const DashboardLogSubscribeTrafficLazyRoute = + DashboardLogSubscribeTrafficLazyRouteImport.update({ + id: '/log/subscribe-traffic', + path: '/log/subscribe-traffic', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/log/subscribe-traffic.lazy').then( + (d) => d.Route, + ), + ) +const DashboardLogSubscribeLazyRoute = + DashboardLogSubscribeLazyRouteImport.update({ + id: '/log/subscribe', + path: '/log/subscribe', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/log/subscribe.lazy').then((d) => d.Route), + ) +const DashboardLogServerTrafficLazyRoute = + DashboardLogServerTrafficLazyRouteImport.update({ + id: '/log/server-traffic', + path: '/log/server-traffic', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/log/server-traffic.lazy').then((d) => d.Route), + ) +const DashboardLogResetSubscribeLazyRoute = + DashboardLogResetSubscribeLazyRouteImport.update({ + id: '/log/reset-subscribe', + path: '/log/reset-subscribe', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/log/reset-subscribe.lazy').then((d) => d.Route), + ) +const DashboardLogRegisterLazyRoute = + DashboardLogRegisterLazyRouteImport.update({ + id: '/log/register', + path: '/log/register', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/log/register.lazy').then((d) => d.Route), + ) +const DashboardLogMobileLazyRoute = DashboardLogMobileLazyRouteImport.update({ + id: '/log/mobile', + path: '/log/mobile', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/log/mobile.lazy').then((d) => d.Route), +) +const DashboardLogLoginLazyRoute = DashboardLogLoginLazyRouteImport.update({ + id: '/log/login', + path: '/log/login', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/log/login.lazy').then((d) => d.Route), +) +const DashboardLogGiftLazyRoute = DashboardLogGiftLazyRouteImport.update({ + id: '/log/gift', + path: '/log/gift', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/log/gift.lazy').then((d) => d.Route), +) +const DashboardLogEmailLazyRoute = DashboardLogEmailLazyRouteImport.update({ + id: '/log/email', + path: '/log/email', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/log/email.lazy').then((d) => d.Route), +) +const DashboardLogCommissionLazyRoute = + DashboardLogCommissionLazyRouteImport.update({ + id: '/log/commission', + path: '/log/commission', + getParentRoute: () => DashboardRouteLazyRoute, + } as any).lazy(() => + import('./routes/dashboard/log/commission.lazy').then((d) => d.Route), + ) +const DashboardLogBalanceLazyRoute = DashboardLogBalanceLazyRouteImport.update({ + id: '/log/balance', + path: '/log/balance', + getParentRoute: () => DashboardRouteLazyRoute, +} as any).lazy(() => + import('./routes/dashboard/log/balance.lazy').then((d) => d.Route), +) + +export interface FileRoutesByFullPath { + '/': typeof IndexLazyRoute + '/dashboard': typeof DashboardRouteLazyRouteWithChildren + '/dashboard/nodes': typeof DashboardNodesLazyRoute + '/dashboard/servers': typeof DashboardServersLazyRoute + '/dashboard/': typeof DashboardIndexLazyRoute + '/dashboard/log/balance': typeof DashboardLogBalanceLazyRoute + '/dashboard/log/commission': typeof DashboardLogCommissionLazyRoute + '/dashboard/log/email': typeof DashboardLogEmailLazyRoute + '/dashboard/log/gift': typeof DashboardLogGiftLazyRoute + '/dashboard/log/login': typeof DashboardLogLoginLazyRoute + '/dashboard/log/mobile': typeof DashboardLogMobileLazyRoute + '/dashboard/log/register': typeof DashboardLogRegisterLazyRoute + '/dashboard/log/reset-subscribe': typeof DashboardLogResetSubscribeLazyRoute + '/dashboard/log/server-traffic': typeof DashboardLogServerTrafficLazyRoute + '/dashboard/log/subscribe': typeof DashboardLogSubscribeLazyRoute + '/dashboard/log/subscribe-traffic': typeof DashboardLogSubscribeTrafficLazyRoute + '/dashboard/log/traffic-details': typeof DashboardLogTrafficDetailsLazyRoute + '/dashboard/ads': typeof DashboardAdsIndexLazyRoute + '/dashboard/announcement': typeof DashboardAnnouncementIndexLazyRoute + '/dashboard/auth-control': typeof DashboardAuthControlIndexLazyRoute + '/dashboard/coupon': typeof DashboardCouponIndexLazyRoute + '/dashboard/document': typeof DashboardDocumentIndexLazyRoute + '/dashboard/marketing': typeof DashboardMarketingIndexLazyRoute + '/dashboard/order': typeof DashboardOrderIndexLazyRoute + '/dashboard/payment': typeof DashboardPaymentIndexLazyRoute + '/dashboard/product': typeof DashboardProductIndexLazyRoute + '/dashboard/subscribe': typeof DashboardSubscribeIndexLazyRoute + '/dashboard/system': typeof DashboardSystemIndexLazyRoute + '/dashboard/ticket': typeof DashboardTicketIndexLazyRoute + '/dashboard/user': typeof DashboardUserIndexLazyRoute +} +export interface FileRoutesByTo { + '/': typeof IndexLazyRoute + '/dashboard/nodes': typeof DashboardNodesLazyRoute + '/dashboard/servers': typeof DashboardServersLazyRoute + '/dashboard': typeof DashboardIndexLazyRoute + '/dashboard/log/balance': typeof DashboardLogBalanceLazyRoute + '/dashboard/log/commission': typeof DashboardLogCommissionLazyRoute + '/dashboard/log/email': typeof DashboardLogEmailLazyRoute + '/dashboard/log/gift': typeof DashboardLogGiftLazyRoute + '/dashboard/log/login': typeof DashboardLogLoginLazyRoute + '/dashboard/log/mobile': typeof DashboardLogMobileLazyRoute + '/dashboard/log/register': typeof DashboardLogRegisterLazyRoute + '/dashboard/log/reset-subscribe': typeof DashboardLogResetSubscribeLazyRoute + '/dashboard/log/server-traffic': typeof DashboardLogServerTrafficLazyRoute + '/dashboard/log/subscribe': typeof DashboardLogSubscribeLazyRoute + '/dashboard/log/subscribe-traffic': typeof DashboardLogSubscribeTrafficLazyRoute + '/dashboard/log/traffic-details': typeof DashboardLogTrafficDetailsLazyRoute + '/dashboard/ads': typeof DashboardAdsIndexLazyRoute + '/dashboard/announcement': typeof DashboardAnnouncementIndexLazyRoute + '/dashboard/auth-control': typeof DashboardAuthControlIndexLazyRoute + '/dashboard/coupon': typeof DashboardCouponIndexLazyRoute + '/dashboard/document': typeof DashboardDocumentIndexLazyRoute + '/dashboard/marketing': typeof DashboardMarketingIndexLazyRoute + '/dashboard/order': typeof DashboardOrderIndexLazyRoute + '/dashboard/payment': typeof DashboardPaymentIndexLazyRoute + '/dashboard/product': typeof DashboardProductIndexLazyRoute + '/dashboard/subscribe': typeof DashboardSubscribeIndexLazyRoute + '/dashboard/system': typeof DashboardSystemIndexLazyRoute + '/dashboard/ticket': typeof DashboardTicketIndexLazyRoute + '/dashboard/user': typeof DashboardUserIndexLazyRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexLazyRoute + '/dashboard': typeof DashboardRouteLazyRouteWithChildren + '/dashboard/nodes': typeof DashboardNodesLazyRoute + '/dashboard/servers': typeof DashboardServersLazyRoute + '/dashboard/': typeof DashboardIndexLazyRoute + '/dashboard/log/balance': typeof DashboardLogBalanceLazyRoute + '/dashboard/log/commission': typeof DashboardLogCommissionLazyRoute + '/dashboard/log/email': typeof DashboardLogEmailLazyRoute + '/dashboard/log/gift': typeof DashboardLogGiftLazyRoute + '/dashboard/log/login': typeof DashboardLogLoginLazyRoute + '/dashboard/log/mobile': typeof DashboardLogMobileLazyRoute + '/dashboard/log/register': typeof DashboardLogRegisterLazyRoute + '/dashboard/log/reset-subscribe': typeof DashboardLogResetSubscribeLazyRoute + '/dashboard/log/server-traffic': typeof DashboardLogServerTrafficLazyRoute + '/dashboard/log/subscribe': typeof DashboardLogSubscribeLazyRoute + '/dashboard/log/subscribe-traffic': typeof DashboardLogSubscribeTrafficLazyRoute + '/dashboard/log/traffic-details': typeof DashboardLogTrafficDetailsLazyRoute + '/dashboard/ads/': typeof DashboardAdsIndexLazyRoute + '/dashboard/announcement/': typeof DashboardAnnouncementIndexLazyRoute + '/dashboard/auth-control/': typeof DashboardAuthControlIndexLazyRoute + '/dashboard/coupon/': typeof DashboardCouponIndexLazyRoute + '/dashboard/document/': typeof DashboardDocumentIndexLazyRoute + '/dashboard/marketing/': typeof DashboardMarketingIndexLazyRoute + '/dashboard/order/': typeof DashboardOrderIndexLazyRoute + '/dashboard/payment/': typeof DashboardPaymentIndexLazyRoute + '/dashboard/product/': typeof DashboardProductIndexLazyRoute + '/dashboard/subscribe/': typeof DashboardSubscribeIndexLazyRoute + '/dashboard/system/': typeof DashboardSystemIndexLazyRoute + '/dashboard/ticket/': typeof DashboardTicketIndexLazyRoute + '/dashboard/user/': typeof DashboardUserIndexLazyRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: + | '/' + | '/dashboard' + | '/dashboard/nodes' + | '/dashboard/servers' + | '/dashboard/' + | '/dashboard/log/balance' + | '/dashboard/log/commission' + | '/dashboard/log/email' + | '/dashboard/log/gift' + | '/dashboard/log/login' + | '/dashboard/log/mobile' + | '/dashboard/log/register' + | '/dashboard/log/reset-subscribe' + | '/dashboard/log/server-traffic' + | '/dashboard/log/subscribe' + | '/dashboard/log/subscribe-traffic' + | '/dashboard/log/traffic-details' + | '/dashboard/ads' + | '/dashboard/announcement' + | '/dashboard/auth-control' + | '/dashboard/coupon' + | '/dashboard/document' + | '/dashboard/marketing' + | '/dashboard/order' + | '/dashboard/payment' + | '/dashboard/product' + | '/dashboard/subscribe' + | '/dashboard/system' + | '/dashboard/ticket' + | '/dashboard/user' + fileRoutesByTo: FileRoutesByTo + to: + | '/' + | '/dashboard/nodes' + | '/dashboard/servers' + | '/dashboard' + | '/dashboard/log/balance' + | '/dashboard/log/commission' + | '/dashboard/log/email' + | '/dashboard/log/gift' + | '/dashboard/log/login' + | '/dashboard/log/mobile' + | '/dashboard/log/register' + | '/dashboard/log/reset-subscribe' + | '/dashboard/log/server-traffic' + | '/dashboard/log/subscribe' + | '/dashboard/log/subscribe-traffic' + | '/dashboard/log/traffic-details' + | '/dashboard/ads' + | '/dashboard/announcement' + | '/dashboard/auth-control' + | '/dashboard/coupon' + | '/dashboard/document' + | '/dashboard/marketing' + | '/dashboard/order' + | '/dashboard/payment' + | '/dashboard/product' + | '/dashboard/subscribe' + | '/dashboard/system' + | '/dashboard/ticket' + | '/dashboard/user' + id: + | '__root__' + | '/' + | '/dashboard' + | '/dashboard/nodes' + | '/dashboard/servers' + | '/dashboard/' + | '/dashboard/log/balance' + | '/dashboard/log/commission' + | '/dashboard/log/email' + | '/dashboard/log/gift' + | '/dashboard/log/login' + | '/dashboard/log/mobile' + | '/dashboard/log/register' + | '/dashboard/log/reset-subscribe' + | '/dashboard/log/server-traffic' + | '/dashboard/log/subscribe' + | '/dashboard/log/subscribe-traffic' + | '/dashboard/log/traffic-details' + | '/dashboard/ads/' + | '/dashboard/announcement/' + | '/dashboard/auth-control/' + | '/dashboard/coupon/' + | '/dashboard/document/' + | '/dashboard/marketing/' + | '/dashboard/order/' + | '/dashboard/payment/' + | '/dashboard/product/' + | '/dashboard/subscribe/' + | '/dashboard/system/' + | '/dashboard/ticket/' + | '/dashboard/user/' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexLazyRoute: typeof IndexLazyRoute + DashboardRouteLazyRoute: typeof DashboardRouteLazyRouteWithChildren +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/dashboard': { + id: '/dashboard' + path: '/dashboard' + fullPath: '/dashboard' + preLoaderRoute: typeof DashboardRouteLazyRouteImport + parentRoute: typeof rootRouteImport + } + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexLazyRouteImport + parentRoute: typeof rootRouteImport + } + '/dashboard/': { + id: '/dashboard/' + path: '/' + fullPath: '/dashboard/' + preLoaderRoute: typeof DashboardIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/servers': { + id: '/dashboard/servers' + path: '/servers' + fullPath: '/dashboard/servers' + preLoaderRoute: typeof DashboardServersLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/nodes': { + id: '/dashboard/nodes' + path: '/nodes' + fullPath: '/dashboard/nodes' + preLoaderRoute: typeof DashboardNodesLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/user/': { + id: '/dashboard/user/' + path: '/user' + fullPath: '/dashboard/user' + preLoaderRoute: typeof DashboardUserIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/ticket/': { + id: '/dashboard/ticket/' + path: '/ticket' + fullPath: '/dashboard/ticket' + preLoaderRoute: typeof DashboardTicketIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/system/': { + id: '/dashboard/system/' + path: '/system' + fullPath: '/dashboard/system' + preLoaderRoute: typeof DashboardSystemIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/subscribe/': { + id: '/dashboard/subscribe/' + path: '/subscribe' + fullPath: '/dashboard/subscribe' + preLoaderRoute: typeof DashboardSubscribeIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/product/': { + id: '/dashboard/product/' + path: '/product' + fullPath: '/dashboard/product' + preLoaderRoute: typeof DashboardProductIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/payment/': { + id: '/dashboard/payment/' + path: '/payment' + fullPath: '/dashboard/payment' + preLoaderRoute: typeof DashboardPaymentIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/order/': { + id: '/dashboard/order/' + path: '/order' + fullPath: '/dashboard/order' + preLoaderRoute: typeof DashboardOrderIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/marketing/': { + id: '/dashboard/marketing/' + path: '/marketing' + fullPath: '/dashboard/marketing' + preLoaderRoute: typeof DashboardMarketingIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/document/': { + id: '/dashboard/document/' + path: '/document' + fullPath: '/dashboard/document' + preLoaderRoute: typeof DashboardDocumentIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/coupon/': { + id: '/dashboard/coupon/' + path: '/coupon' + fullPath: '/dashboard/coupon' + preLoaderRoute: typeof DashboardCouponIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/auth-control/': { + id: '/dashboard/auth-control/' + path: '/auth-control' + fullPath: '/dashboard/auth-control' + preLoaderRoute: typeof DashboardAuthControlIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/announcement/': { + id: '/dashboard/announcement/' + path: '/announcement' + fullPath: '/dashboard/announcement' + preLoaderRoute: typeof DashboardAnnouncementIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/ads/': { + id: '/dashboard/ads/' + path: '/ads' + fullPath: '/dashboard/ads' + preLoaderRoute: typeof DashboardAdsIndexLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/traffic-details': { + id: '/dashboard/log/traffic-details' + path: '/log/traffic-details' + fullPath: '/dashboard/log/traffic-details' + preLoaderRoute: typeof DashboardLogTrafficDetailsLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/subscribe-traffic': { + id: '/dashboard/log/subscribe-traffic' + path: '/log/subscribe-traffic' + fullPath: '/dashboard/log/subscribe-traffic' + preLoaderRoute: typeof DashboardLogSubscribeTrafficLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/subscribe': { + id: '/dashboard/log/subscribe' + path: '/log/subscribe' + fullPath: '/dashboard/log/subscribe' + preLoaderRoute: typeof DashboardLogSubscribeLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/server-traffic': { + id: '/dashboard/log/server-traffic' + path: '/log/server-traffic' + fullPath: '/dashboard/log/server-traffic' + preLoaderRoute: typeof DashboardLogServerTrafficLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/reset-subscribe': { + id: '/dashboard/log/reset-subscribe' + path: '/log/reset-subscribe' + fullPath: '/dashboard/log/reset-subscribe' + preLoaderRoute: typeof DashboardLogResetSubscribeLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/register': { + id: '/dashboard/log/register' + path: '/log/register' + fullPath: '/dashboard/log/register' + preLoaderRoute: typeof DashboardLogRegisterLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/mobile': { + id: '/dashboard/log/mobile' + path: '/log/mobile' + fullPath: '/dashboard/log/mobile' + preLoaderRoute: typeof DashboardLogMobileLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/login': { + id: '/dashboard/log/login' + path: '/log/login' + fullPath: '/dashboard/log/login' + preLoaderRoute: typeof DashboardLogLoginLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/gift': { + id: '/dashboard/log/gift' + path: '/log/gift' + fullPath: '/dashboard/log/gift' + preLoaderRoute: typeof DashboardLogGiftLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/email': { + id: '/dashboard/log/email' + path: '/log/email' + fullPath: '/dashboard/log/email' + preLoaderRoute: typeof DashboardLogEmailLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/commission': { + id: '/dashboard/log/commission' + path: '/log/commission' + fullPath: '/dashboard/log/commission' + preLoaderRoute: typeof DashboardLogCommissionLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + '/dashboard/log/balance': { + id: '/dashboard/log/balance' + path: '/log/balance' + fullPath: '/dashboard/log/balance' + preLoaderRoute: typeof DashboardLogBalanceLazyRouteImport + parentRoute: typeof DashboardRouteLazyRoute + } + } +} + +interface DashboardRouteLazyRouteChildren { + DashboardNodesLazyRoute: typeof DashboardNodesLazyRoute + DashboardServersLazyRoute: typeof DashboardServersLazyRoute + DashboardIndexLazyRoute: typeof DashboardIndexLazyRoute + DashboardLogBalanceLazyRoute: typeof DashboardLogBalanceLazyRoute + DashboardLogCommissionLazyRoute: typeof DashboardLogCommissionLazyRoute + DashboardLogEmailLazyRoute: typeof DashboardLogEmailLazyRoute + DashboardLogGiftLazyRoute: typeof DashboardLogGiftLazyRoute + DashboardLogLoginLazyRoute: typeof DashboardLogLoginLazyRoute + DashboardLogMobileLazyRoute: typeof DashboardLogMobileLazyRoute + DashboardLogRegisterLazyRoute: typeof DashboardLogRegisterLazyRoute + DashboardLogResetSubscribeLazyRoute: typeof DashboardLogResetSubscribeLazyRoute + DashboardLogServerTrafficLazyRoute: typeof DashboardLogServerTrafficLazyRoute + DashboardLogSubscribeLazyRoute: typeof DashboardLogSubscribeLazyRoute + DashboardLogSubscribeTrafficLazyRoute: typeof DashboardLogSubscribeTrafficLazyRoute + DashboardLogTrafficDetailsLazyRoute: typeof DashboardLogTrafficDetailsLazyRoute + DashboardAdsIndexLazyRoute: typeof DashboardAdsIndexLazyRoute + DashboardAnnouncementIndexLazyRoute: typeof DashboardAnnouncementIndexLazyRoute + DashboardAuthControlIndexLazyRoute: typeof DashboardAuthControlIndexLazyRoute + DashboardCouponIndexLazyRoute: typeof DashboardCouponIndexLazyRoute + DashboardDocumentIndexLazyRoute: typeof DashboardDocumentIndexLazyRoute + DashboardMarketingIndexLazyRoute: typeof DashboardMarketingIndexLazyRoute + DashboardOrderIndexLazyRoute: typeof DashboardOrderIndexLazyRoute + DashboardPaymentIndexLazyRoute: typeof DashboardPaymentIndexLazyRoute + DashboardProductIndexLazyRoute: typeof DashboardProductIndexLazyRoute + DashboardSubscribeIndexLazyRoute: typeof DashboardSubscribeIndexLazyRoute + DashboardSystemIndexLazyRoute: typeof DashboardSystemIndexLazyRoute + DashboardTicketIndexLazyRoute: typeof DashboardTicketIndexLazyRoute + DashboardUserIndexLazyRoute: typeof DashboardUserIndexLazyRoute +} + +const DashboardRouteLazyRouteChildren: DashboardRouteLazyRouteChildren = { + DashboardNodesLazyRoute: DashboardNodesLazyRoute, + DashboardServersLazyRoute: DashboardServersLazyRoute, + DashboardIndexLazyRoute: DashboardIndexLazyRoute, + DashboardLogBalanceLazyRoute: DashboardLogBalanceLazyRoute, + DashboardLogCommissionLazyRoute: DashboardLogCommissionLazyRoute, + DashboardLogEmailLazyRoute: DashboardLogEmailLazyRoute, + DashboardLogGiftLazyRoute: DashboardLogGiftLazyRoute, + DashboardLogLoginLazyRoute: DashboardLogLoginLazyRoute, + DashboardLogMobileLazyRoute: DashboardLogMobileLazyRoute, + DashboardLogRegisterLazyRoute: DashboardLogRegisterLazyRoute, + DashboardLogResetSubscribeLazyRoute: DashboardLogResetSubscribeLazyRoute, + DashboardLogServerTrafficLazyRoute: DashboardLogServerTrafficLazyRoute, + DashboardLogSubscribeLazyRoute: DashboardLogSubscribeLazyRoute, + DashboardLogSubscribeTrafficLazyRoute: DashboardLogSubscribeTrafficLazyRoute, + DashboardLogTrafficDetailsLazyRoute: DashboardLogTrafficDetailsLazyRoute, + DashboardAdsIndexLazyRoute: DashboardAdsIndexLazyRoute, + DashboardAnnouncementIndexLazyRoute: DashboardAnnouncementIndexLazyRoute, + DashboardAuthControlIndexLazyRoute: DashboardAuthControlIndexLazyRoute, + DashboardCouponIndexLazyRoute: DashboardCouponIndexLazyRoute, + DashboardDocumentIndexLazyRoute: DashboardDocumentIndexLazyRoute, + DashboardMarketingIndexLazyRoute: DashboardMarketingIndexLazyRoute, + DashboardOrderIndexLazyRoute: DashboardOrderIndexLazyRoute, + DashboardPaymentIndexLazyRoute: DashboardPaymentIndexLazyRoute, + DashboardProductIndexLazyRoute: DashboardProductIndexLazyRoute, + DashboardSubscribeIndexLazyRoute: DashboardSubscribeIndexLazyRoute, + DashboardSystemIndexLazyRoute: DashboardSystemIndexLazyRoute, + DashboardTicketIndexLazyRoute: DashboardTicketIndexLazyRoute, + DashboardUserIndexLazyRoute: DashboardUserIndexLazyRoute, +} + +const DashboardRouteLazyRouteWithChildren = + DashboardRouteLazyRoute._addFileChildren(DashboardRouteLazyRouteChildren) + +const rootRouteChildren: RootRouteChildren = { + IndexLazyRoute: IndexLazyRoute, + DashboardRouteLazyRoute: DashboardRouteLazyRouteWithChildren, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() diff --git a/apps/admin/src/routes/__root.tsx b/apps/admin/src/routes/__root.tsx new file mode 100644 index 0000000..6c96f85 --- /dev/null +++ b/apps/admin/src/routes/__root.tsx @@ -0,0 +1,79 @@ +import { TanStackDevtools } from "@tanstack/react-devtools"; +import { createRootRouteWithContext, Outlet } from "@tanstack/react-router"; +import { TanStackRouterDevtoolsPanel } from "@tanstack/react-router-devtools"; +import { Toaster } from "@workspace/ui/components/sonner"; +import { NavigationProgress } from "@workspace/ui/composed/navigation-progress"; +import { TanStackQueryDevtools } from "@workspace/ui/integrations/tanstack-query-devtools"; +import { getCookie } from "@workspace/ui/lib/cookies"; +import { getGlobalConfig } from "@workspace/ui/services/common/common"; +import { isBrowser } from "@workspace/ui/utils/index"; +import { useEffect } from "react"; +import { Helmet, HelmetProvider } from "react-helmet-async"; +import { useGlobalStore } from "@/stores/global"; + +export const Route = createRootRouteWithContext()({ + component: () => { + const { common, setCommon, getUserInfo } = useGlobalStore(); + useEffect(() => { + const initializeApp = async () => { + try { + const configResponse = await getGlobalConfig(); + if (configResponse.data?.data) { + setCommon(configResponse.data.data); + } + try { + if (getCookie("Authorization")) { + await getUserInfo(); + } + } catch { + /* empty */ + } + } catch (error) { + console.error("Failed to initialize app:", error); + } + }; + + initializeApp(); + }, []); + + const { site } = common; + const title = site.site_name || "Loading..."; + const description = site.site_desc || ""; + const keywords = site.keywords || ""; + const logo = site.site_logo || ""; + const url = isBrowser() ? window.location.href : ""; + + return ( + + + {title} + + + + + + + + + + +
+ , + }, + TanStackQueryDevtools, + ]} + /> + + ); + }, +}); diff --git a/apps/admin/src/routes/dashboard/ads/index.lazy.tsx b/apps/admin/src/routes/dashboard/ads/index.lazy.tsx new file mode 100644 index 0000000..3a21dc6 --- /dev/null +++ b/apps/admin/src/routes/dashboard/ads/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Ads from "@/sections/ads"; + +export const Route = createLazyFileRoute("/dashboard/ads/")({ + component: Ads, +}); diff --git a/apps/admin/src/routes/dashboard/announcement/index.lazy.tsx b/apps/admin/src/routes/dashboard/announcement/index.lazy.tsx new file mode 100644 index 0000000..db8e061 --- /dev/null +++ b/apps/admin/src/routes/dashboard/announcement/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Announcement from "@/sections/announcement"; + +export const Route = createLazyFileRoute("/dashboard/announcement/")({ + component: Announcement, +}); diff --git a/apps/admin/src/routes/dashboard/auth-control/index.lazy.tsx b/apps/admin/src/routes/dashboard/auth-control/index.lazy.tsx new file mode 100644 index 0000000..c82674c --- /dev/null +++ b/apps/admin/src/routes/dashboard/auth-control/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import AuthControl from "@/sections/auth-control"; + +export const Route = createLazyFileRoute("/dashboard/auth-control/")({ + component: AuthControl, +}); diff --git a/apps/admin/src/routes/dashboard/coupon/index.lazy.tsx b/apps/admin/src/routes/dashboard/coupon/index.lazy.tsx new file mode 100644 index 0000000..5a36871 --- /dev/null +++ b/apps/admin/src/routes/dashboard/coupon/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Coupon from "@/sections/coupon"; + +export const Route = createLazyFileRoute("/dashboard/coupon/")({ + component: Coupon, +}); diff --git a/apps/admin/src/routes/dashboard/document/index.lazy.tsx b/apps/admin/src/routes/dashboard/document/index.lazy.tsx new file mode 100644 index 0000000..4c6f9ed --- /dev/null +++ b/apps/admin/src/routes/dashboard/document/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Document from "@/sections/document"; + +export const Route = createLazyFileRoute("/dashboard/document/")({ + component: Document, +}); diff --git a/apps/admin/src/routes/dashboard/index.lazy.tsx b/apps/admin/src/routes/dashboard/index.lazy.tsx new file mode 100644 index 0000000..3725f95 --- /dev/null +++ b/apps/admin/src/routes/dashboard/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Dashboard from "@/sections/dashboard"; + +export const Route = createLazyFileRoute("/dashboard/")({ + component: Dashboard, +}); diff --git a/apps/admin/src/routes/dashboard/log/balance.lazy.tsx b/apps/admin/src/routes/dashboard/log/balance.lazy.tsx new file mode 100644 index 0000000..7adb0e5 --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/balance.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import BalanceLogPage from "@/sections/log/balance"; + +export const Route = createLazyFileRoute("/dashboard/log/balance")({ + component: BalanceLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/commission.lazy.tsx b/apps/admin/src/routes/dashboard/log/commission.lazy.tsx new file mode 100644 index 0000000..158efd8 --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/commission.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import CommissionLogPage from "@/sections/log/commission"; + +export const Route = createLazyFileRoute("/dashboard/log/commission")({ + component: CommissionLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/email.lazy.tsx b/apps/admin/src/routes/dashboard/log/email.lazy.tsx new file mode 100644 index 0000000..a182532 --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/email.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import EmailLogPage from "@/sections/log/email"; + +export const Route = createLazyFileRoute("/dashboard/log/email")({ + component: EmailLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/gift.lazy.tsx b/apps/admin/src/routes/dashboard/log/gift.lazy.tsx new file mode 100644 index 0000000..dc05eda --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/gift.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import GiftLogPage from "@/sections/log/gift"; + +export const Route = createLazyFileRoute("/dashboard/log/gift")({ + component: GiftLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/login.lazy.tsx b/apps/admin/src/routes/dashboard/log/login.lazy.tsx new file mode 100644 index 0000000..73d16a4 --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/login.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import LoginLogPage from "@/sections/log/login"; + +export const Route = createLazyFileRoute("/dashboard/log/login")({ + component: LoginLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/mobile.lazy.tsx b/apps/admin/src/routes/dashboard/log/mobile.lazy.tsx new file mode 100644 index 0000000..e4a5f64 --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/mobile.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import MobileLogPage from "@/sections/log/mobile"; + +export const Route = createLazyFileRoute("/dashboard/log/mobile")({ + component: MobileLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/register.lazy.tsx b/apps/admin/src/routes/dashboard/log/register.lazy.tsx new file mode 100644 index 0000000..29c256d --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/register.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import RegisterLogPage from "@/sections/log/register"; + +export const Route = createLazyFileRoute("/dashboard/log/register")({ + component: RegisterLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/reset-subscribe.lazy.tsx b/apps/admin/src/routes/dashboard/log/reset-subscribe.lazy.tsx new file mode 100644 index 0000000..03cdcf9 --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/reset-subscribe.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import ResetSubscribeLogPage from "@/sections/log/reset-subscribe"; + +export const Route = createLazyFileRoute("/dashboard/log/reset-subscribe")({ + component: ResetSubscribeLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/server-traffic.lazy.tsx b/apps/admin/src/routes/dashboard/log/server-traffic.lazy.tsx new file mode 100644 index 0000000..ee2882d --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/server-traffic.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import ServerTrafficLogPage from "@/sections/log/server-traffic"; + +export const Route = createLazyFileRoute("/dashboard/log/server-traffic")({ + component: ServerTrafficLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/subscribe-traffic.lazy.tsx b/apps/admin/src/routes/dashboard/log/subscribe-traffic.lazy.tsx new file mode 100644 index 0000000..374ff7b --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/subscribe-traffic.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import SubscribeTrafficLogPage from "@/sections/log/subscribe-traffic"; + +export const Route = createLazyFileRoute("/dashboard/log/subscribe-traffic")({ + component: SubscribeTrafficLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/subscribe.lazy.tsx b/apps/admin/src/routes/dashboard/log/subscribe.lazy.tsx new file mode 100644 index 0000000..755bbc0 --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/subscribe.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import SubscribeLogPage from "@/sections/log/subscribe"; + +export const Route = createLazyFileRoute("/dashboard/log/subscribe")({ + component: SubscribeLogPage, +}); diff --git a/apps/admin/src/routes/dashboard/log/traffic-details.lazy.tsx b/apps/admin/src/routes/dashboard/log/traffic-details.lazy.tsx new file mode 100644 index 0000000..cc3ba77 --- /dev/null +++ b/apps/admin/src/routes/dashboard/log/traffic-details.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import TrafficDetailsPage from "@/sections/log/traffic-details"; + +export const Route = createLazyFileRoute("/dashboard/log/traffic-details")({ + component: TrafficDetailsPage, +}); diff --git a/apps/admin/src/routes/dashboard/marketing/index.lazy.tsx b/apps/admin/src/routes/dashboard/marketing/index.lazy.tsx new file mode 100644 index 0000000..15cb07a --- /dev/null +++ b/apps/admin/src/routes/dashboard/marketing/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import MarketingPage from "@/sections/marketing"; + +export const Route = createLazyFileRoute("/dashboard/marketing/")({ + component: MarketingPage, +}); diff --git a/apps/admin/src/routes/dashboard/nodes.lazy.tsx b/apps/admin/src/routes/dashboard/nodes.lazy.tsx new file mode 100644 index 0000000..f9ad7d6 --- /dev/null +++ b/apps/admin/src/routes/dashboard/nodes.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Nodes from "@/sections/nodes"; + +export const Route = createLazyFileRoute("/dashboard/nodes")({ + component: Nodes, +}); diff --git a/apps/admin/src/routes/dashboard/order/index.lazy.tsx b/apps/admin/src/routes/dashboard/order/index.lazy.tsx new file mode 100644 index 0000000..7d58266 --- /dev/null +++ b/apps/admin/src/routes/dashboard/order/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Order from "@/sections/order"; + +export const Route = createLazyFileRoute("/dashboard/order/")({ + component: Order, +}); diff --git a/apps/admin/src/routes/dashboard/payment/index.lazy.tsx b/apps/admin/src/routes/dashboard/payment/index.lazy.tsx new file mode 100644 index 0000000..64b5947 --- /dev/null +++ b/apps/admin/src/routes/dashboard/payment/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Payment from "@/sections/payment"; + +export const Route = createLazyFileRoute("/dashboard/payment/")({ + component: Payment, +}); diff --git a/apps/admin/src/routes/dashboard/product/index.lazy.tsx b/apps/admin/src/routes/dashboard/product/index.lazy.tsx new file mode 100644 index 0000000..dcaae1c --- /dev/null +++ b/apps/admin/src/routes/dashboard/product/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Product from "@/sections/product"; + +export const Route = createLazyFileRoute("/dashboard/product/")({ + component: Product, +}); diff --git a/apps/admin/src/routes/dashboard/route.lazy.tsx b/apps/admin/src/routes/dashboard/route.lazy.tsx new file mode 100644 index 0000000..2559226 --- /dev/null +++ b/apps/admin/src/routes/dashboard/route.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import DashboardLayout from "@/layout"; + +export const Route = createLazyFileRoute("/dashboard")({ + component: DashboardLayout, +}); diff --git a/apps/admin/src/routes/dashboard/servers.lazy.tsx b/apps/admin/src/routes/dashboard/servers.lazy.tsx new file mode 100644 index 0000000..fef7aa5 --- /dev/null +++ b/apps/admin/src/routes/dashboard/servers.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Servers from "@/sections/servers"; + +export const Route = createLazyFileRoute("/dashboard/servers")({ + component: Servers, +}); diff --git a/apps/admin/src/routes/dashboard/subscribe/index.lazy.tsx b/apps/admin/src/routes/dashboard/subscribe/index.lazy.tsx new file mode 100644 index 0000000..120370b --- /dev/null +++ b/apps/admin/src/routes/dashboard/subscribe/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Subscribe from "@/sections/subscribe"; + +export const Route = createLazyFileRoute("/dashboard/subscribe/")({ + component: Subscribe, +}); diff --git a/apps/admin/src/routes/dashboard/system/index.lazy.tsx b/apps/admin/src/routes/dashboard/system/index.lazy.tsx new file mode 100644 index 0000000..90f1b3e --- /dev/null +++ b/apps/admin/src/routes/dashboard/system/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import System from "@/sections/system"; + +export const Route = createLazyFileRoute("/dashboard/system/")({ + component: System, +}); diff --git a/apps/admin/src/routes/dashboard/ticket/index.lazy.tsx b/apps/admin/src/routes/dashboard/ticket/index.lazy.tsx new file mode 100644 index 0000000..195df48 --- /dev/null +++ b/apps/admin/src/routes/dashboard/ticket/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Ticket from "@/sections/ticket"; + +export const Route = createLazyFileRoute("/dashboard/ticket/")({ + component: Ticket, +}); diff --git a/apps/admin/src/routes/dashboard/user/index.lazy.tsx b/apps/admin/src/routes/dashboard/user/index.lazy.tsx new file mode 100644 index 0000000..0b0a21f --- /dev/null +++ b/apps/admin/src/routes/dashboard/user/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import User from "@/sections/user"; + +export const Route = createLazyFileRoute("/dashboard/user/")({ + component: User, +}); diff --git a/apps/admin/src/routes/index.lazy.tsx b/apps/admin/src/routes/index.lazy.tsx new file mode 100644 index 0000000..2bc96ef --- /dev/null +++ b/apps/admin/src/routes/index.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import Auth from "@/sections/auth"; + +export const Route = createLazyFileRoute("/")({ + component: Auth, +}); diff --git a/apps/admin/src/sections/ads/ads-form.tsx b/apps/admin/src/sections/ads/ads-form.tsx new file mode 100644 index 0000000..7b212f4 --- /dev/null +++ b/apps/admin/src/sections/ads/ads-form.tsx @@ -0,0 +1,328 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { Button } from "@workspace/ui/components/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@workspace/ui/components/form"; +import { + RadioGroup, + RadioGroupItem, +} from "@workspace/ui/components/radio-group"; +import { ScrollArea } from "@workspace/ui/components/scroll-area"; +import { + Sheet, + SheetContent, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@workspace/ui/components/sheet"; +import { EnhancedInput } from "@workspace/ui/composed/enhanced-input"; +import { Icon } from "@workspace/ui/composed/icon"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { z } from "zod"; + +const formSchema = z.object({ + title: z.string(), + type: z.enum(["image", "video"]), + content: z.string(), + description: z.string(), + target_url: z.string().url(), + start_time: z.number(), + end_time: z.number(), +}); + +interface AdsFormProps { + onSubmit: (data: T) => Promise | boolean; + initialValues?: T; + loading?: boolean; + trigger: string; + title: string; +} + +export default function AdsForm>({ + onSubmit, + initialValues, + loading, + trigger, + title, +}: AdsFormProps) { + const { t } = useTranslation("ads"); + const [open, setOpen] = useState(false); + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + ...initialValues, + } as any, + }); + + useEffect(() => { + form?.reset(initialValues); + }, [form, initialValues]); + + const type = form.watch("type"); + const startTime = form.watch("start_time"); + + const renderContentField = () => ( + ( + + {t("form.content", "Content")} + + { + form.setValue("content", value); + }} + placeholder={ + type === "image" + ? "https://example.com/image.jpg" + : "https://example.com/video.mp4" + } + value={field.value} + /> + + + + )} + /> + ); + + async function handleSubmit(data: { [x: string]: any }) { + const bool = await onSubmit(data as T); + if (bool) setOpen(false); + } + + return ( + + + + + + + {title} + + +
+ + ( + + {t("form.title", "Title")} + + { + form.setValue(field.name, value); + }} + placeholder={t("form.enterTitle", "Enter title")} + value={field.value} + /> + + + + )} + /> + + ( + + {t("form.type", "Type")} + + { + form.setValue(field.name, value); + }} + > + + + + + + {t("form.typeImage", "Image")} + + + + + + + + {t("form.typeVideo", "Video")} + + + + + + + )} + /> + + {renderContentField()} + + ( + + + {t("form.description", "Description")} + + + { + form.setValue(field.name, value); + }} + placeholder={t( + "form.enterDescription", + "Enter description" + )} + value={field.value} + /> + + + + )} + /> + + ( + + {t("form.targetUrl", "Target URL")} + + { + form.setValue(field.name, value); + }} + placeholder={t( + "form.enterTargetUrl", + "Enter target URL" + )} + value={field.value} + /> + + + + )} + /> + + ( + + {t("form.startTime", "Start Time")} + + { + const timestamp = value + ? new Date(value).getTime() + : 0; + form.setValue(field.name, timestamp); + const endTime = form.getValues("end_time"); + if (endTime && timestamp > endTime) { + form.setValue("end_time", ""); + } + }} + placeholder={t( + "form.enterStartTime", + "Select start time" + )} + step="1" + type="datetime-local" + value={ + field.value + ? new Date(field.value).toISOString().slice(0, 16) + : "" + } + /> + + + + )} + /> + + ( + + {t("form.endTime", "End Time")} + + { + const timestamp = value + ? new Date(value).getTime() + : 0; + if (!startTime || timestamp < startTime) return; + form.setValue(field.name, timestamp); + }} + placeholder={t("form.enterEndTime", "Select end time")} + step="1" + type="datetime-local" + value={ + field.value + ? new Date(field.value).toISOString().slice(0, 16) + : "" + } + /> + + + + )} + /> + + +
+ + + + +
+
+ ); +} diff --git a/apps/admin/src/sections/ads/index.tsx b/apps/admin/src/sections/ads/index.tsx new file mode 100644 index 0000000..42794e7 --- /dev/null +++ b/apps/admin/src/sections/ads/index.tsx @@ -0,0 +1,171 @@ +import { Badge } from "@workspace/ui/components/badge"; +import { Button } from "@workspace/ui/components/button"; +import { Switch } from "@workspace/ui/components/switch"; +import { ConfirmButton } from "@workspace/ui/composed/confirm-button"; +import { + ProTable, + type ProTableActions, +} from "@workspace/ui/composed/pro-table/pro-table"; +import { + createAds, + deleteAds, + getAdsList, + updateAds, +} from "@workspace/ui/services/admin/ads"; +import { useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { toast } from "sonner"; +import { formatDate } from "@/utils/common"; +import AdsForm from "./ads-form"; + +export default function Ads() { + const { t } = useTranslation("ads"); + const [loading, setLoading] = useState(false); + const ref = useRef(null); + + return ( + > + action={ref} + actions={{ + render: (row) => [ + + initialValues={row} + key="edit" + loading={loading} + onSubmit={async (values) => { + setLoading(true); + try { + await updateAds({ ...row, ...values }); + toast.success(t("updateSuccess", "Updated successfully")); + ref.current?.refresh(); + return true; + } catch { + return false; + } finally { + setLoading(false); + } + }} + title={t("editAds", "Edit Ad")} + trigger={t("edit", "Edit")} + />, + { + await deleteAds({ id: row.id }); + toast.success(t("deleteSuccess", "Deleted successfully")); + ref.current?.refresh(); + }} + title={t("confirmDelete", "Confirm Delete")} + trigger={ + + } + />, + ], + }} + columns={[ + { + accessorKey: "status", + header: t("status", "Status"), + cell: ({ row }) => ( + { + await updateAds({ + ...row.original, + status: checked ? 1 : 0, + }); + ref.current?.refresh(); + }} + /> + ), + }, + { + accessorKey: "title", + header: t("title", "Title"), + }, + { + accessorKey: "type", + header: t("type", "Type"), + cell: ({ row }) => { + const type = row.original.type; + return {type}; + }, + }, + { + accessorKey: "target_url", + header: t("targetUrl", "Target URL"), + }, + { + accessorKey: "description", + header: t("form.description", "Description"), + }, + { + accessorKey: "period", + header: t("validityPeriod", "Validity Period"), + cell: ({ row }) => { + const { start_time, end_time } = row.original; + return ( + <> + {formatDate(start_time)} - {formatDate(end_time)} + + ); + }, + }, + ]} + header={{ + toolbar: ( + + loading={loading} + onSubmit={async (values) => { + setLoading(true); + try { + await createAds({ + ...values, + status: 0, + }); + toast.success(t("createSuccess", "Created successfully")); + ref.current?.refresh(); + return true; + } catch { + return false; + } finally { + setLoading(false); + } + }} + title={t("createAds", "Create Ad")} + trigger={t("create", "Create")} + /> + ), + }} + params={[ + { + key: "status", + placeholder: t("status", "Status"), + options: [ + { label: t("enabled", "Enabled"), value: "1" }, + { label: t("disabled", "Disabled"), value: "0" }, + ], + }, + { + key: "search", + }, + ]} + request={async (pagination, filters) => { + const { data } = await getAdsList({ + ...pagination, + ...filters, + }); + return { + list: data.data?.list || [], + total: data.data?.total || 0, + }; + }} + /> + ); +} diff --git a/apps/admin/src/sections/announcement/index.tsx b/apps/admin/src/sections/announcement/index.tsx new file mode 100644 index 0000000..6688b4d --- /dev/null +++ b/apps/admin/src/sections/announcement/index.tsx @@ -0,0 +1,213 @@ +import { Button } from "@workspace/ui/components/button"; +import { Switch } from "@workspace/ui/components/switch"; +import { ConfirmButton } from "@workspace/ui/composed/confirm-button"; +import { + ProTable, + type ProTableActions, +} from "@workspace/ui/composed/pro-table/pro-table"; +import { + createAnnouncement, + deleteAnnouncement, + getAnnouncementList, + updateAnnouncement, +} from "@workspace/ui/services/admin/announcement"; +import { format } from "date-fns"; +import { useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { toast } from "sonner"; +import NoticeForm from "./notice-form"; + +export default function Page() { + const { t } = useTranslation("announcement"); + const [loading, setLoading] = useState(false); + const ref = useRef(null); + + return ( + + action={ref} + actions={{ + render(row) { + return [ + + initialValues={row} + key="edit" + loading={loading} + onSubmit={async (values) => { + setLoading(true); + try { + await updateAnnouncement({ + ...row, + ...values, + }); + toast.success(t("updateSuccess", "Updated successfully")); + ref.current?.refresh(); + setLoading(false); + return true; + } catch { + setLoading(false); + return false; + } + }} + title={t("editAnnouncement", "Edit Announcement")} + trigger={t("edit", "Edit")} + />, + { + await deleteAnnouncement({ + id: row.id, + }); + toast.success(t("deleteSuccess", "Deleted successfully")); + ref.current?.refresh(); + }} + title={t("confirmDelete", "Confirm Delete")} + trigger={ + + } + />, + ]; + }, + batchRender(rows) { + return [ + { + for (const element of rows) { + await deleteAnnouncement({ + id: element.id!, + }); + } + toast.success(t("deleteSuccess", "Deleted successfully")); + ref.current?.refresh(); + }} + title={t("confirmDelete", "Confirm Delete")} + trigger={ + + } + />, + ]; + }, + }} + columns={[ + { + accessorKey: "show", + header: t("show", "Show"), + cell: ({ row }) => ( + { + await updateAnnouncement({ + ...row.original, + show: checked, + }); + ref.current?.refresh(); + }} + /> + ), + }, + { + accessorKey: "pinned", + header: t("pinned", "Pinned"), + cell: ({ row }) => ( + { + await updateAnnouncement({ + ...row.original, + pinned: checked, + }); + ref.current?.refresh(); + }} + /> + ), + }, + { + accessorKey: "popup", + header: t("popup", "Popup"), + cell: ({ row }) => ( + { + await updateAnnouncement({ + ...row.original, + popup: checked, + }); + ref.current?.refresh(); + }} + /> + ), + }, + { + accessorKey: "title", + header: t("title", "Title"), + }, + { + accessorKey: "content", + header: t("content", "Content"), + }, + { + accessorKey: "updated_at", + header: t("updatedAt", "Updated At"), + cell: ({ row }) => + format(row.getValue("updated_at"), "yyyy-MM-dd HH:mm:ss"), + }, + ]} + header={{ + title: t("announcementList", "Announcement List"), + toolbar: ( + + loading={loading} + onSubmit={async (values) => { + setLoading(true); + try { + await createAnnouncement(values); + toast.success(t("createSuccess", "Created successfully")); + ref.current?.refresh(); + setLoading(false); + return true; + } catch { + setLoading(false); + return false; + } + }} + title={t("createAnnouncement", "Create Announcement")} + trigger={t("create", "Create")} + /> + ), + }} + params={[ + { + key: "enable", + placeholder: t("enable", "Enable"), + options: [ + { label: t("show", "Show"), value: "false" }, + { label: t("hide", "Hide"), value: "true" }, + ], + }, + { key: "search" }, + ]} + request={async (pagination, filter) => { + const { data } = await getAnnouncementList({ + ...pagination, + ...filter, + }); + return { + list: data.data?.list || [], + total: data.data?.total || 0, + }; + }} + /> + ); +} diff --git a/apps/admin/src/sections/announcement/notice-form.tsx b/apps/admin/src/sections/announcement/notice-form.tsx new file mode 100644 index 0000000..ac4b579 --- /dev/null +++ b/apps/admin/src/sections/announcement/notice-form.tsx @@ -0,0 +1,149 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { Button } from "@workspace/ui/components/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@workspace/ui/components/form"; +import { Input } from "@workspace/ui/components/input"; +import { ScrollArea } from "@workspace/ui/components/scroll-area"; +import { + Sheet, + SheetContent, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@workspace/ui/components/sheet"; +import { MarkdownEditor } from "@workspace/ui/composed/editor/markdown"; +import { Icon } from "@workspace/ui/composed/icon"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { z } from "zod"; + +const formSchema = z.object({ + title: z.string(), + content: z.string().optional(), +}); + +interface AnnouncementFormProps { + onSubmit: (data: T) => Promise | boolean; + initialValues?: T; + loading?: boolean; + trigger: string; + title: string; +} + +export default function AnnouncementForm>({ + onSubmit, + initialValues, + loading, + trigger, + title, +}: AnnouncementFormProps) { + const { t } = useTranslation("announcement"); + const [open, setOpen] = useState(false); + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + title: "", + content: "", + ...initialValues, + }, + }); + + useEffect(() => { + form?.reset(initialValues); + }, [form, initialValues]); + + async function handleSubmit(data: { [x: string]: any }) { + const bool = await onSubmit(data as T); + if (bool) setOpen(false); + } + + return ( + + + + + + + {title} + + +
+ + ( + + {t("form.title", "Title")} + + + + + + )} + /> + + ( + + {t("form.content", "Content")} + + { + form.setValue(field.name, value || ""); + }} + value={field.value} + /> + + + + )} + /> + + +
+ + + + +
+
+ ); +} diff --git a/apps/admin/src/sections/auth-control/forms/apple-form.tsx b/apps/admin/src/sections/auth-control/forms/apple-form.tsx new file mode 100644 index 0000000..fa71615 --- /dev/null +++ b/apps/admin/src/sections/auth-control/forms/apple-form.tsx @@ -0,0 +1,318 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useQuery } from "@tanstack/react-query"; +import { Button } from "@workspace/ui/components/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@workspace/ui/components/form"; +import { ScrollArea } from "@workspace/ui/components/scroll-area"; +import { + Sheet, + SheetContent, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@workspace/ui/components/sheet"; +import { Switch } from "@workspace/ui/components/switch"; +import { Textarea } from "@workspace/ui/components/textarea"; +import { EnhancedInput } from "@workspace/ui/composed/enhanced-input"; +import { Icon } from "@workspace/ui/composed/icon"; +import { + getAuthMethodConfig, + updateAuthMethodConfig, +} from "@workspace/ui/services/admin/authMethod"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { toast } from "sonner"; +import { z } from "zod"; + +const appleSchema = z.object({ + enabled: z.boolean(), + config: z + .object({ + team_id: z.string().optional(), + key_id: z.string().optional(), + client_id: z.string().optional(), + client_secret: z.string().optional(), + redirect_url: z.string().optional(), + }) + .optional(), +}); + +type AppleFormData = z.infer; + +export default function AppleForm() { + const { t } = useTranslation("auth-control"); + const [open, setOpen] = useState(false); + const [loading, setLoading] = useState(false); + + const { data, refetch } = useQuery({ + queryKey: ["getAuthMethodConfig", "apple"], + queryFn: async () => { + const { data } = await getAuthMethodConfig({ + method: "apple", + }); + + return data.data; + }, + enabled: open, + }); + + const form = useForm({ + resolver: zodResolver(appleSchema), + defaultValues: { + enabled: false, + config: { + team_id: "", + key_id: "", + client_id: "", + client_secret: "", + redirect_url: "", + }, + }, + }); + + useEffect(() => { + if (data) { + form.reset({ + enabled: data.enabled, + config: { + team_id: data.config?.team_id || "", + key_id: data.config?.key_id || "", + client_id: data.config?.client_id || "", + client_secret: data.config?.client_secret || "", + redirect_url: data.config?.redirect_url || "", + }, + }); + } + }, [data, form]); + + async function onSubmit(values: AppleFormData) { + setLoading(true); + try { + await updateAuthMethodConfig({ + ...data, + enabled: values.enabled, + config: { + ...data?.config, + ...values.config, + }, + } as API.UpdateAuthMethodConfigRequest); + toast.success(t("common.saveSuccess", "Saved successfully")); + refetch(); + setOpen(false); + } catch (_error) { + toast.error(t("common.saveFailed", "Save failed")); + } finally { + setLoading(false); + } + } + + return ( + + +
+
+
+ +
+
+

{t("apple.title", "Apple Sign-In")}

+

+ {t( + "apple.description", + "Authenticate users with Apple accounts" + )} +

+
+
+ +
+
+ + + {t("apple.title", "Apple Sign-In")} + + +
+ + ( + + {t("apple.enable", "Enable")} + + + + + {t( + "apple.enableDescription", + "When enabled, users can sign in with their Apple ID" + )} + + + + )} + /> + + ( + + {t("apple.teamId", "Team ID")} + + + + + {t("apple.teamIdDescription", "Apple Developer Team ID")} + + + + )} + /> + + ( + + {t("apple.keyId", "Key ID")} + + + + + {t( + "apple.keyIdDescription", + "Your private key ID from Apple Developer Portal" + )} + + + + )} + /> + + ( + + {t("apple.clientId", "Service ID")} + + + + + {t( + "apple.clientIdDescription", + "Apple Service ID, available from Apple Developer Portal" + )} + + + + )} + /> + + ( + + + {t("apple.clientSecret", "Private Key")} + + +