├── .github └── workflows │ └── build.yml ├── .gitignore ├── LICENCE.txt ├── README.md ├── install.sh ├── package.json ├── src ├── commands │ ├── about.ts │ ├── export.ts │ ├── rasterize_current_screen.ts │ └── update.ts └── lib │ ├── dialogs │ └── export_settings.ts │ ├── path.ts │ ├── rasterizer.ts │ ├── tools.ts │ ├── types.ts │ └── version.ts ├── toolkit ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ ├── compress.rs │ ├── main.rs │ ├── prelude.rs │ └── update.rs ├── tools ├── compile.js └── install.js ├── tsconfig.json └── types ├── jsfl.d.ts └── zipfile.d.ts /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | push: 4 | # Sequence of patterns matched against refs/tags 5 | tags: 6 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 7 | jobs: 8 | build-node: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v1 13 | - uses: actions/cache@v2 14 | with: 15 | path: ~/.npm 16 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 17 | restore-keys: | 18 | ${{ runner.os }}-node- 19 | - run: | 20 | export VERSION=$(echo "${{ github.ref }}" | sed "s|refs/tags/v||") 21 | echo "export const STRING = \"$VERSION\"" > src/lib/version.ts 22 | - run: npm run build 23 | - name: Upload node files 24 | uses: actions/upload-artifact@v2 25 | with: 26 | name: tools 27 | path: out/compiled/* 28 | build-toolkit-win: 29 | runs-on: ubuntu-latest 30 | steps: 31 | - name: Install mingw 32 | run: sudo apt-get install gcc-mingw-w64 33 | - uses: actions/checkout@v2 34 | - uses: actions/cache@v2 35 | with: 36 | path: | 37 | ~/.cargo/registry 38 | ~/.cargo/git 39 | toolkit/target 40 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 41 | - uses: actions-rs/toolchain@v1 42 | with: 43 | toolchain: stable 44 | target: x86_64-pc-windows-gnu 45 | - uses: actions-rs/cargo@v1 46 | with: 47 | use-cross: true 48 | command: build 49 | args: --release --target x86_64-pc-windows-gnu --manifest-path=toolkit/Cargo.toml 50 | - name: Show content 51 | run: find . 52 | - name: Upload library 53 | uses: actions/upload-artifact@v2 54 | with: 55 | name: toolkit.win 56 | path: toolkit/target/x86_64-pc-windows-gnu/release/toolkit.exe 57 | 58 | build-toolkit-osx: 59 | runs-on: macos-10.15 60 | steps: 61 | - uses: actions/checkout@v2 62 | - uses: actions/cache@v2 63 | with: 64 | path: | 65 | ~/.cargo/registry 66 | ~/.cargo/git 67 | toolkit/target 68 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 69 | - uses: actions-rs/toolchain@v1 70 | with: 71 | toolchain: stable 72 | - uses: actions-rs/cargo@v1 73 | with: 74 | command: build 75 | args: --release --manifest-path=toolkit/Cargo.toml 76 | - name: Upload library 77 | uses: actions/upload-artifact@v2 78 | with: 79 | name: toolkit.osx 80 | path: toolkit/target/release/toolkit 81 | archive: 82 | runs-on: ubuntu-latest 83 | needs: [build-node, build-toolkit-win, build-toolkit-osx] 84 | steps: 85 | - run: mkdir -p "funexpected-tools/Funexpected Tools" 86 | - uses: actions/checkout@v2 87 | - name: Download compiled js 88 | uses: actions/download-artifact@v2 89 | with: 90 | name: tools 91 | path: funexpected-tools/Funexpected Tools 92 | - name: Download toolkit.win 93 | uses: actions/download-artifact@v2 94 | with: 95 | name: toolkit.win 96 | path: funexpected-tools/Funexpected Tools 97 | - name: Download toolkit.osx 98 | uses: actions/download-artifact@v2 99 | with: 100 | name: toolkit.osx 101 | path: funexpected-tools/Funexpected Tools 102 | 103 | - name: Compress release 104 | run: zip -r funexpected-tools funexpected-tools 105 | 106 | - name: Create Release 107 | id: create_release 108 | uses: actions/create-release@v1 109 | env: 110 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 111 | with: 112 | tag_name: ${{ github.ref }} 113 | release_name: Release ${{ github.ref }} 114 | draft: false 115 | prerelease: false 116 | 117 | - name: Upload Release Asset 118 | id: upload-release-asset 119 | uses: actions/upload-release-asset@v1 120 | env: 121 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 122 | with: 123 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 124 | asset_path: ./funexpected-tools.zip 125 | asset_name: funexpected-tools.zip 126 | asset_content_type: application/zip 127 | 128 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | package-lock.json 4 | tsconfig.tsbuildinfo 5 | .vscode 6 | -------------------------------------------------------------------------------- /LICENCE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Funexpected Flash Tools 2 | 3 | Performs Adobe Animate project rasterization && exporting for using with Godot Engine + [Flash Module](https://github.com/funexpected/godot-flash-module) 4 | 5 | ## Installation 6 | 7 | ### MacOS 8 | Open Terminal application, paste this code, press `Enter`: 9 | ``` 10 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/funexpected/flash-tools/master/install.sh)" 11 | ``` 12 | ### Windows 13 | [Download](https://github.com/funexpected/flash-tools/releases/latest/download/funexpected-tools.zip) latest Flash Tools release, unzip, copy `Funexpected Tools` folder into Adobe Animate `Configuration\Commands` directory: 14 | ``` 15 | \Users\username\AppData\Local\Adobe\Animate \\Configuration\Commands 16 | ``` 17 | 18 | ## Usage 19 | 20 | ### Export 21 | Export command prepare project for using it with Godot Engine. It runs in several phases 22 | - save current project into temporary location 23 | - rasterizes all assets (Symbols and Shapes) 24 | - generate SpriteSheetes of rasterized assets 25 | - removes unused data 26 | - comress result 27 | 28 | Source project leaves untouched, so this command is pretty safe. 29 | 30 | Export can be done in three ways: 31 | - **Document** exports main document and all dependencies. 32 | - **Library** exports every root item of your library 33 | - **Selected** exports current edited screen (scene or library item). 34 | 35 | ### Rasterize Current Screen 36 | While `Export` command do not change your project, `Rasterize Current Screen` chnage your current project and prepare exacly same rastersization. It may be useful for speeding up export process of big projects. 37 | 38 | ## Roadmap 39 | 40 | - [ ] add docs and tutorials 41 | - [x] convert Canvas-based documents into legacy before exporting 42 | - [x] add `About` and `Check For Updates` commands 43 | - [ ] add ability to automaticaly open exported project in godot for testing purposes 44 | - [ ] support Warp Tool 45 | - [ ] support sounds -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | # Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | TMPDIR=`mktemp -d` 24 | cd $TMPDIR 25 | curl -# -L https://github.com/funexpected/flash-tools/releases/latest/download/funexpected-tools.zip -o funexpected-tools.zip 26 | unzip -qq funexpected-tools.zip 27 | cd funexpected-tools/ 28 | chmod a+x "Funexpected Tools/toolkit" 29 | ls -d $HOME/Library/Application\ Support/Adobe/Animate*/*/Configuration/Commands/ | xargs -I{} cp -R ./* "{}" 30 | ls -d $HOME/Library/Application\ Support/Adobe/Animate*/*/Configuration/Commands/Funexpected\ Tools/toolkit | xargs -I{} chmod a+x "{}" 31 | echo "Funexpected Flash Tools installed. Restart Adobe Animate and inspect 'Commands/Funexpected Tools' menu." -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flash-godot-exporter", 3 | "version": "1.0.0", 4 | "description": "Export Flash project to use them wuth godot-flash-module", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build-ts": "rm -rf ./out/tsc/* && npx tsc -b", 9 | "build-closure": "node ./tools/compile.js", 10 | "build": "npm run build-ts && npm run build-closure", 11 | "install": "npm run build && node ./tools/install.js" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "@types/jszip": "^3.4.1", 17 | "babel-preset-es3": "^1.0.1", 18 | "google-closure-compiler": "^20210106.0.0", 19 | "jszip": "^3.5.0", 20 | "typescript": "^4.1.3", 21 | "glob": "7.1.6" 22 | }, 23 | "dependencies": { 24 | "glob": "^7.1.6" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/commands/about.ts: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import * as version from "../lib/version"; 24 | let panel = ` 25 | ` 29 | fl.xmlPanelFromString(panel) -------------------------------------------------------------------------------- /src/commands/export.ts: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | import * as path from "../lib/path"; 25 | import { Rasterizer } from "../lib/rasterizer"; 26 | import { ExportSettingsDialog } from "../lib/dialogs/export_settings" 27 | import { cleanUpProject, generateSpriteSheets, invoke, convertFromCanvas } from "../lib/tools"; 28 | 29 | let dialog = new ExportSettingsDialog(); 30 | let settings = dialog.prompt(); 31 | if (settings) { 32 | let doc = fl.getDocumentDOM(); 33 | let editedItemName = doc.getTimeline().libraryItem?.name || "document"; 34 | 35 | fl.outputPanel.clear(); 36 | fl.showIdleMessage(false); 37 | 38 | let originalDoc = fl.getDocumentDOM(); 39 | let originalUri = FLfile.platformPathToURI(originalDoc.path); 40 | originalDoc.save(false); 41 | 42 | let exportProjectArchive = settings.exportPath; 43 | let exportProjectDir = path.getProjectPrefix() + ".fnx.export/"; 44 | let exportProjectPath = exportProjectDir + path.file(exportProjectDir) + ".xfl"; 45 | let exportProjectDirUri = FLfile.platformPathToURI(exportProjectDir); 46 | let exportProjectPathUri = FLfile.platformPathToURI(exportProjectPath); 47 | fl.trace("Export Project URI: " + exportProjectPathUri); 48 | if (FLfile.exists(exportProjectDirUri)) FLfile.remove(exportProjectDirUri); 49 | FLfile.createFolder(exportProjectDirUri); 50 | fl.trace("Exporting project"); 51 | fl.trace("Worrrking with " + exportProjectPathUri); 52 | fl.saveDocument(originalDoc, exportProjectPathUri); 53 | fl.saveDocument(originalDoc, originalUri); 54 | 55 | convertFromCanvas(exportProjectPath); 56 | //convertFromCanvas(exportProjectPath); 57 | //alert("Document has been converted from Canvas"); 58 | fl.openDocument(exportProjectPathUri); 59 | doc = fl.getDocumentDOM(); 60 | 61 | let editedItem: "document"|FlashItem = editedItemName == "document" ? "document" : (doc.library.items.filter(i => i.name == editedItemName)[0] as FlashItem); 62 | let rasterizer = new Rasterizer(); 63 | let bitmaps = rasterizer.rasterize(settings.exportType == "library" ? null : editedItem, settings.exportType == "library"); 64 | generateSpriteSheets(bitmaps, settings.padding, settings.pageSize); 65 | 66 | fl.saveDocument(doc); 67 | 68 | // cleanup exported project 69 | cleanUpProject(exportProjectDir); 70 | invoke("compress", { 71 | source: exportProjectDir, 72 | destination: exportProjectArchive 73 | }); 74 | fl.closeDocument(doc, false); 75 | fl.openDocument(originalUri); 76 | alert("Document exported to " + exportProjectArchive); 77 | } 78 | -------------------------------------------------------------------------------- /src/commands/rasterize_current_screen.ts: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | 25 | import { Rasterizer } from "../lib/rasterizer" 26 | 27 | if (confirm("Raterize current timeline?")) { 28 | let rasterizer = new Rasterizer(); 29 | let root = fl.getDocumentDOM().getTimeline().libraryItem; 30 | if (root) { 31 | rasterizer.rasterize(root); 32 | fl.getDocumentDOM().library.editItem(root.name); 33 | } else { 34 | rasterizer.rasterize("document"); 35 | fl.getDocumentDOM().editScene(0); 36 | } 37 | } -------------------------------------------------------------------------------- /src/commands/update.ts: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import { invoke } from "../lib/tools"; 24 | import * as version from "../lib/version"; 25 | 26 | interface UpdateResult { 27 | status: 'updated'|'already_latest'; 28 | path: string|null; 29 | version: string|null; 30 | } 31 | 32 | let updateResult = invoke("update", { from_version: version.STRING }) as UpdateResult; 33 | 34 | if (updateResult.status == 'already_latest') { 35 | alert("You have latest version of Funexpected Tools"); 36 | } else { 37 | let updatedFolderURI = FLfile.platformPathToURI(updateResult.path as string); 38 | let targetFolderURI = FLfile.platformPathToURI(`${fl.configDirectory}Commands/Funexpected Tools/`); 39 | for (let file of FLfile.listFolder(targetFolderURI, 'files')) { 40 | let targetURI = FLfile.platformPathToURI(`${fl.configDirectory}Commands/Funexpected Tools/${file}`); 41 | FLfile.remove(targetURI); 42 | } 43 | for (let file of FLfile.listFolder(updatedFolderURI, 'files')) { 44 | let targetURI = FLfile.platformPathToURI(`${fl.configDirectory}Commands/Funexpected Tools/${file}`); 45 | FLfile.copy(`${updatedFolderURI}/${file}`, targetURI); 46 | } 47 | 48 | let isOSX = (fl.version.indexOf("MAC") != -1); 49 | if (isOSX) { 50 | let toolkitPath = FLfile.platformPathToURI(`${fl.configDirectory}Commands/Funexpected Tools/toolkit`); 51 | FLfile.runCommandLine(`chmod a+x "${toolkitPath}"`); 52 | } 53 | FLfile.remove(updatedFolderURI); 54 | alert(`Funexpected Tools updated to ${updateResult.version}`); 55 | } -------------------------------------------------------------------------------- /src/lib/dialogs/export_settings.ts: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | 25 | import * as path from "../path"; 26 | 27 | class ExportSettings { 28 | exportType: "document"|"library"|"selected" = "library"; 29 | exportPath: string = ""; 30 | padding: number = 8; 31 | pageSize: 256|512|1024|2048|4096 = 4096; 32 | } 33 | export class ExportSettingsDialog { 34 | 35 | public prompt(): ExportSettings|null { 36 | let doc = fl.getDocumentDOM(); 37 | let save = { 38 | exportType: doc.documentHasData("fnx.export.exportType") ? doc.getDataFromDocument("fnx.export.exportType") : "library", 39 | exportPath: doc.documentHasData("fnx.export.exportPath") ? doc.getDataFromDocument("fnx.export.exportPath") : path.getProjectPrefix() + ".zfl", 40 | padding: doc.documentHasData("fnx.export.padding") ? doc.getDataFromDocument("fnx.export.padding") : "8", 41 | pageSize: doc.documentHasData("fnx.export.pageSize") ? doc.getDataFromDocument("fnx.export.pageSize") : "4096" 42 | } 43 | 44 | let panel = ` 45 | 52 | 53 | `; 98 | 99 | let dialogResponse = fl.xmlPanelFromString(panel) 100 | doc.addDataToDocument("fnx.export.exportType", "string", dialogResponse["exportType"]); 101 | doc.addDataToDocument("fnx.export.exportPath", "string", dialogResponse["exportPath"]); 102 | doc.addDataToDocument("fnx.export.padding", "string", dialogResponse["padding"]); 103 | doc.addDataToDocument("fnx.export.pageSize", "string", dialogResponse["pageSize"]); 104 | 105 | if (dialogResponse["dismiss"] == "cancel") { 106 | return null; 107 | } 108 | 109 | let settings = new ExportSettings(); 110 | settings.exportPath = dialogResponse["exportPath"] as string; 111 | settings.padding = Number(dialogResponse["padding"]) || 8; 112 | switch (Number(dialogResponse["pageSize"])) { 113 | case 256: settings.pageSize = 256; break; 114 | case 512: settings.pageSize = 512; break; 115 | case 1024: settings.pageSize = 1024; break; 116 | case 2048: settings.pageSize = 2048; break; 117 | case 4096: settings.pageSize = 4096; break; 118 | default: settings.pageSize = 4096; 119 | } 120 | switch (dialogResponse["exportType"]) { 121 | case "document": settings.exportType = "document"; break; 122 | case "library": settings.exportType = "library"; break; 123 | case "selected": settings.exportType = "selected"; break; 124 | default: settings.exportType = "library"; 125 | } 126 | return settings; 127 | } 128 | } -------------------------------------------------------------------------------- /src/lib/path.ts: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | 25 | export function normalize(path: string): string { 26 | while (path.indexOf("\\") >= 0) { 27 | path = path.replace("\\", "/"); 28 | } 29 | while (path.indexOf("//") >= 0) { 30 | path = path.replace("//", "/"); 31 | } 32 | while (path.endsWith("/")) { 33 | path = path.substr(0, path.length-1); 34 | } 35 | return path 36 | } 37 | export function base(path: string): string { 38 | let parts = normalize(path).split("/"); 39 | parts.pop(); 40 | return parts.join("/"); 41 | } 42 | 43 | export function file(path: string): string { 44 | let parts = normalize(path).split("/"); 45 | return parts[parts.length-1]; 46 | } 47 | 48 | // returns current project path prefix based on project format (fla or xfl): 49 | // `/path/to/project` for `/path/to/project/project.xfl 50 | // `/path/ro/project` for `/path/to/project.fla` 51 | 52 | export function getProjectPrefix(): string { 53 | let doc = fl.getDocumentDOM(); 54 | if (doc.path.endsWith(".fla")) { 55 | let fileName = file(doc.path); 56 | return base(doc.path) + "/" + fileName.substr(0, fileName.length - 4); 57 | } else { 58 | return base(doc.path); 59 | } 60 | } -------------------------------------------------------------------------------- /src/lib/rasterizer.ts: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | 25 | import * as path from "./path"; 26 | import { canExportItem, canExportLayer } from "./types"; 27 | 28 | export class Rasterizer { 29 | itemsToRasterize: FlashItem[] = []; 30 | rasterizedItems: { [id: string] : boolean; } = {}; 31 | bitmapItems: { [id: string] : boolean; } = {}; 32 | 33 | public rasterize(rootItem: FlashItem|"document"|null = null, withLibraryRootItems: boolean = false, exportBitmaps: boolean = false): FlashBitmapItem[] { 34 | let doc = fl.getDocumentDOM(); 35 | 36 | if (withLibraryRootItems) { 37 | this.itemsToRasterize = doc.library.items 38 | .filter(item => item.name.indexOf("/") < 0) 39 | .filter(canExportItem); 40 | } 41 | 42 | if (rootItem == "document") { 43 | doc.editScene(0); 44 | this.rasterizeItem("document"); 45 | } else if (rootItem != null) { 46 | this.itemsToRasterize.push(rootItem); 47 | } 48 | 49 | // rasterize rest items 50 | while (this.itemsToRasterize.length) { 51 | let item = this.itemsToRasterize.pop() as FlashItem; 52 | if (item.name in this.rasterizedItems) continue; 53 | this.rasterizedItems[item.name] = true; 54 | doc.library.editItem(item.name); 55 | this.rasterizeItem(item.name); 56 | } 57 | 58 | let baseUri = FLfile.platformPathToURI(path.base(fl.getDocumentDOM().path) + "/LIBRARY/"); 59 | let result: FlashBitmapItem[] = []; 60 | for (let item of fl.getDocumentDOM().library.items.filter(item => item.name in this.bitmapItems)) { 61 | let bitmap = item as FlashBitmapItem; 62 | let bitmapUri = baseUri + bitmap.name; 63 | if (!bitmapUri.endsWith(".png")) bitmapUri += ".png"; 64 | if (exportBitmaps) bitmap.exportToFile(bitmapUri); 65 | 66 | result.push(bitmap); 67 | } 68 | 69 | return result; 70 | } 71 | 72 | rasterizeItem(itemName: string) { 73 | let doc = fl.getDocumentDOM(); 74 | let timeline = doc.getTimeline(); 75 | 76 | for (let layerIdx = 0; layerIdx < timeline.layers.length; layerIdx++) { 77 | let layer = timeline.layers[layerIdx]; 78 | if (!canExportLayer(layer)) continue; 79 | layer.locked = false; 80 | layer.visible = true; 81 | layer.outline = false; 82 | 83 | 84 | for (let frameIdx = 0; frameIdx < layer.frames.length; frameIdx++) { 85 | let frame = layer.frames[frameIdx]; 86 | if (frameIdx != frame.startFrame) continue; 87 | 88 | if (frame.tweenType == "shape" && frame.duration > 1) { 89 | timeline.convertToKeyframes(frameIdx, frameIdx+frame.duration); 90 | } 91 | 92 | if (frame.tweenType == "shape") { 93 | frame.tweenType = "none"; 94 | } 95 | 96 | let hasShapes = frame.elements.some(e => e.elementType == "shape"); 97 | 98 | while (hasShapes) { 99 | timeline.setSelectedLayers(layerIdx, true); 100 | timeline.setSelectedFrames(frameIdx, frameIdx, true); 101 | 102 | let shapes = doc.selection.filter(e => e.elementType == "shape").map(e => e as FlashShape); 103 | // no shapes left in the frame, go next 104 | if (shapes.length == 0) break; 105 | 106 | // DrawingObjects and groups with Instances should be splited 107 | let shapesToBreak = shapes.filter(e => e.isDrawingObject || e.isGroup && e.members.some(m => m.elementType == "instance")) 108 | if (shapesToBreak.length > 0) { 109 | doc.selectNone(); 110 | doc.selection = [shapesToBreak[0]]; 111 | doc.breakApart(); 112 | continue; 113 | } 114 | 115 | 116 | let converted = false; 117 | // only single shape in the frame 118 | if (doc.selection.length == 1) { 119 | converted = fl.getDocumentDOM().convertSelectionToBitmap(); 120 | 121 | // some black magic needed otherwise 122 | } else { 123 | doc.selection.forEach(e => e.selected = false); 124 | let shape = shapes[0]; 125 | doc.selection = [shape]; 126 | let depth = shape.depth; 127 | converted = fl.getDocumentDOM().convertSelectionToBitmap(); 128 | 129 | // after rasterization element moves to the front 130 | // move it to original position here 131 | let lastDepth = doc.selection.length > 0 ? doc.selection[0].depth : 0; 132 | while (doc.selection.length > 0 && doc.selection[0].depth < depth) { 133 | doc.arrange("back"); 134 | if (doc.selection[0].depth == lastDepth) { 135 | break; 136 | } 137 | } 138 | } 139 | 140 | if (converted) { 141 | if (doc.selection.length && doc.selection[0].elementType == "instance") { 142 | let instance = doc.selection[0] as FlashInstance; 143 | if (instance.libraryItem?.itemType == "bitmap") { 144 | let item = instance.libraryItem as FlashBitmapItem; 145 | item.addData("originalSource", "string", `${itemName}@${layer.name} at frame ${frame.startFrame}`); 146 | } 147 | } 148 | } else { 149 | fl.trace(`Can't convert to bitmap elements from ${itemName}@${layer.name} at frame ${frame.startFrame}`); 150 | } 151 | } 152 | for (let element of frame.elements) { 153 | if (element.elementType == "instance") { 154 | let instance = element as FlashInstance; 155 | if (canExportItem(instance.libraryItem)) { 156 | this.itemsToRasterize.push(instance.libraryItem as FlashItem); 157 | } else if (instance.libraryItem?.itemType == "bitmap") { 158 | let item = instance.libraryItem as FlashBitmapItem; 159 | this.bitmapItems[item.name] = true; 160 | } 161 | } 162 | } 163 | } 164 | } 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/lib/tools.ts: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import * as path from "./path"; 24 | 25 | function createSpritesheetExporter(width: number, height: number, padding: number=8):SpriteSheetExporter { 26 | let spg = new SpriteSheetExporter(); 27 | spg.algorithm = "maxRects"; 28 | spg.allowRotate = false; 29 | spg.allowTrimming = false; 30 | spg.borderPadding = 2; 31 | spg.shapePadding = padding; 32 | spg.layoutFormat = "JSON"; 33 | spg.autoSize = false; 34 | spg.sheetWidth = width; 35 | spg.sheetHeight = height; 36 | // if (limitSize) { 37 | // } else { 38 | // spg.autoSize = true; 39 | // spg.maxSheetHeight = width; 40 | // spg.maxSheetWidth = height; 41 | // } 42 | return spg; 43 | } 44 | 45 | class SpriteSheetGenerationAttempt { 46 | public width: number = 0; 47 | public height: number = 0; 48 | public exporters: SpriteSheetExporter[] = []; 49 | public valid: boolean = true; 50 | 51 | public getSquare(): number { 52 | return (this.width * this.height) * Math.pow(this.exporters.length, 1.1); 53 | } 54 | } 55 | 56 | export function generateSpriteSheets(bitmaps: FlashBitmapItem[], padding: number = 8, maxPageSize: number = 4096){ 57 | if (bitmaps.length == 0) return; 58 | normalizeLibrary(bitmaps); 59 | bitmaps = bitmaps.sort( (a, b) => b.hPixels * b.vPixels - a.hPixels * a.hPixels); 60 | 61 | let attempts: SpriteSheetGenerationAttempt[] = []; 62 | let sizes: number[] = [256, 512, 1024, 2048, 4096]; 63 | while (sizes.length > 1 && sizes[sizes.length-1] > maxPageSize) { 64 | sizes.pop() 65 | } 66 | while (sizes.length > 1) { 67 | let size = sizes[0]; 68 | if (bitmaps.some(b => b.hPixels > size - 4 || b.vPixels > size - 4)) { 69 | sizes.shift(); 70 | } else { 71 | break; 72 | } 73 | } 74 | while (sizes.length > 2) { 75 | sizes.pop(); 76 | } 77 | 78 | // try to pack atlases with different page size and choose best shot 79 | for (let width of sizes) { 80 | for (let height of sizes) { 81 | let attempt = new SpriteSheetGenerationAttempt(); 82 | attempt.width = width; 83 | attempt.height = height; 84 | 85 | for (let bitmap of bitmaps) { 86 | if (bitmap.hPixels > width - 4 || bitmap.vPixels > height - 4) { 87 | let itemSrcString = bitmap.hasData("originalSource") ? 88 | `item rasterized from ${bitmap.getData("originalSource")}` : 89 | `bitmap ${bitmap.sourceFilePath}`; 90 | fl.trace(`Skipping big bitmap, cant pack ${itemSrcString}`); 91 | continue; 92 | } 93 | let exporter: null|SpriteSheetExporter = null; 94 | 95 | for (let i=attempt.exporters.length-1; i >= 0; i--) { 96 | let exp = attempt.exporters[i]; 97 | exp.addBitmap(bitmap); 98 | if (exp.overflowed) { 99 | exp.removeBitmap(bitmap); 100 | } else { 101 | exporter = exp; 102 | break; 103 | } 104 | } 105 | if (!exporter) { 106 | //fl.trace(`creating exporter ${maxWidth}x${maxHeight}`); 107 | exporter = createSpritesheetExporter(width, height, padding); 108 | attempt.exporters.push(exporter); 109 | exporter.addBitmap(bitmap); 110 | //fl.trace("creating new exporter"); 111 | } 112 | if (attempt.exporters.length > 1024) { 113 | attempt.valid = false; 114 | fl.trace(`Too many spritesheets for size ${width}x${height}, skipping`); 115 | break; 116 | } 117 | } 118 | 119 | if (attempt.valid) { 120 | attempts.push(attempt); 121 | } 122 | } 123 | } 124 | 125 | let exporters = attempts.sort( (a, b) => a.getSquare() - b.getSquare())[0].exporters; 126 | let baseUri = FLfile.platformPathToURI(path.base(fl.getDocumentDOM().path)); 127 | let idx = 0; 128 | let exportedSpriteSheets = ""; 129 | //fl.trace(`created ${exporters.length} spritesheets`); 130 | 131 | for (let exporter of exporters) { 132 | let spriteSheetData = exporter.exportSpriteSheet(`${baseUri}/spritesheet_${idx}`, { 133 | format: "png", 134 | backgroundColor: "#00000000", 135 | bitDepth: 32 136 | }, true); 137 | //FLfile.write(`${baseUri}/spritesheet_${idx}.json`, spriteSheetData); 138 | //fl.trace(`layout ${idx}: ${spriteSheetData}`); 139 | exportedSpriteSheets += `spritesheet_${idx}\n` 140 | idx += 1; 141 | } 142 | if (exportedSpriteSheets) { 143 | FLfile.write(`${baseUri}/spritesheets.list`, exportedSpriteSheets); 144 | } 145 | } 146 | 147 | // as far as SpriteSheetExporter cuts folders names, we need 148 | // to rename and move bitmaps to own folder 149 | function normalizeLibrary(bitmaps: FlashBitmapItem[]) { 150 | let lib = fl.getDocumentDOM().library; 151 | let basePath = FLfile.platformPathToURI(`${path.base(fl.getDocumentDOM().path)}/LIBRARY`); 152 | let idx = 0; 153 | lib.newFolder("gdexp"); 154 | for (let bitmap of bitmaps) { 155 | if (!bitmap.hasData("originalSource")) bitmap.addData("originalSource", "string", `bitmap at ${bitmap.name}`); 156 | lib.selectItem(bitmap.name, true); 157 | let itemName = `bitmap.exported.${idx.toString().padStart(4, '0')}`; 158 | lib.renameItem(itemName); 159 | lib.moveToFolder("gdexp"); 160 | idx += 1; 161 | } 162 | } 163 | 164 | 165 | // removes bin folder & clears images from library (all required images are stored in atlases already) 166 | export function cleanUpProject(path: String) { 167 | FLfile.remove(FLfile.platformPathToURI(`${path}bin/`)) 168 | let rootUri = FLfile.platformPathToURI(`${path}LIBRARY/`); 169 | let dirs = [""]; 170 | 171 | while (dirs.length) { 172 | let currentDir = dirs.pop() as string; 173 | let currentUri = rootUri + currentDir; 174 | for (let dir of FLfile.listFolder(currentUri, "directories")) { 175 | dirs.push(`${currentDir}${dir}/`); 176 | } 177 | for (let file of FLfile.listFolder(currentUri, "files")) { 178 | if (file.endsWith(".png") || file.endsWith(".jpeg") || file.endsWith(".jpg")) { 179 | //fl.trace(`remofing ${currentUri}${file}`); 180 | FLfile.remove(`${currentUri}${file}`); 181 | } 182 | } 183 | } 184 | } 185 | 186 | function handleInfocation(command: string): object { 187 | let invokeOutput = FLfile.platformPathToURI(`${fl.configDirectory}Commands/Funexpected Tools/result.json`); 188 | if (!FLfile.exists(invokeOutput)) { 189 | fl.trace(`Error invocating ${command}: unable to execute native toolkit.`); 190 | throw(`Error invocating ${command}: unable to execute native toolkit.`); 191 | } 192 | let invokeResult = eval(`(${FLfile.read(invokeOutput)})`); 193 | if (invokeResult.success) { 194 | FLfile.remove(invokeOutput); 195 | return invokeResult.result; 196 | } else { 197 | fl.trace(`Error invocating ${command}: ${invokeResult.message}`); 198 | throw(`Error invocating ${command}: ${invokeResult.message}`); 199 | } 200 | } 201 | 202 | // invokes toolkig command 203 | export function invoke(command: string, args:{ [id: string] : string; } = { }): object { 204 | let isOSX = (fl.version.indexOf("MAC") != -1); 205 | let toolkitPath = `${fl.configDirectory}Commands/Funexpected Tools/toolkit`; 206 | if (!isOSX) toolkitPath += ".exe"; 207 | let cmd = `"${toolkitPath}" ${command}`; 208 | for (let arg in args) { 209 | let value = args[arg]; 210 | while (arg.indexOf("_") >= 0) arg = arg.replace("_", "-"); 211 | cmd += ` --${arg} "${value}"`; 212 | } 213 | if (isOSX) { 214 | FLfile.runCommandLine(cmd); 215 | return handleInfocation(command); 216 | } 217 | 218 | // there is smthing wrong with FLfile.runCommandLine 219 | // see https://stackoverflow.com/questions/9116828/jsfl-flfile-runcommandline-properly-escaping-spaces-for-windows-commandline-a 220 | let tmpBatDir = FLfile.platformPathToURI("c:/temp"); 221 | if (!FLfile.exists(tmpBatDir)) { 222 | FLfile.createFolder(tmpBatDir) 223 | } 224 | let tmpBat = "c:/temp/fnxcmd.bat" 225 | FLfile.write(FLfile.platformPathToURI(tmpBat), cmd); 226 | FLfile.runCommandLine(tmpBat); 227 | return handleInfocation(command); 228 | } 229 | 230 | export function convertFromCanvas(projectPath: string) { 231 | let docURI = FLfile.platformPathToURI(path.base(projectPath) + "/DOMDocument.xml"); 232 | if (!FLfile.exists(docURI)) { 233 | return; 234 | } 235 | let docString = FLfile.read(docURI); 236 | let docMatch = docString.match('filetypeGUID="(.+?)"'); 237 | if (!docMatch) { 238 | return; 239 | } 240 | docString = docString.replace(docMatch[0]+'', 'filetypeGUID="DD0DDBBF-5BEF-45B2-9F24-A3048D2A676F"'); 241 | FLfile.write(docURI, docString); 242 | } -------------------------------------------------------------------------------- /src/lib/types.ts: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | 25 | export const EditableItemTypes: FlashItemType[] = [ 26 | "movie clip", 27 | "graphic" 28 | ]; 29 | 30 | 31 | export const IgnorableLabelTypes: FlashLayerType[] = [ 32 | "guide", 33 | "guided", 34 | "folder" 35 | ] 36 | 37 | export function canExportLayer(layer: FlashLayer): boolean { 38 | return !IgnorableLabelTypes.some(t => layer.layerType == t); 39 | } 40 | 41 | export function canExportItem(item: FlashItem|undefined): boolean { 42 | if (!item) return false; 43 | return EditableItemTypes.some(t => item.itemType == t); 44 | } -------------------------------------------------------------------------------- /src/lib/version.ts: -------------------------------------------------------------------------------- 1 | export const STRING = "0.0.1.dev"; -------------------------------------------------------------------------------- /toolkit/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /toolkit/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "adler32" 5 | version = "1.2.0" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" 8 | 9 | [[package]] 10 | name = "atty" 11 | version = "0.2.14" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 14 | dependencies = [ 15 | "hermit-abi", 16 | "libc", 17 | "winapi", 18 | ] 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.0.1" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 25 | 26 | [[package]] 27 | name = "base64" 28 | version = "0.13.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 31 | 32 | [[package]] 33 | name = "bitflags" 34 | version = "1.2.1" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 37 | 38 | [[package]] 39 | name = "bumpalo" 40 | version = "3.6.1" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" 43 | 44 | [[package]] 45 | name = "byteorder" 46 | version = "1.4.2" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" 49 | 50 | [[package]] 51 | name = "bytes" 52 | version = "1.0.1" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" 55 | 56 | [[package]] 57 | name = "bzip2" 58 | version = "0.3.3" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" 61 | dependencies = [ 62 | "bzip2-sys", 63 | "libc", 64 | ] 65 | 66 | [[package]] 67 | name = "bzip2-sys" 68 | version = "0.1.10+1.0.8" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "17fa3d1ac1ca21c5c4e36a97f3c3eb25084576f6fc47bf0139c1123434216c6c" 71 | dependencies = [ 72 | "cc", 73 | "libc", 74 | "pkg-config", 75 | ] 76 | 77 | [[package]] 78 | name = "cc" 79 | version = "1.0.67" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" 82 | 83 | [[package]] 84 | name = "cfg-if" 85 | version = "0.1.10" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 88 | 89 | [[package]] 90 | name = "cfg-if" 91 | version = "1.0.0" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 94 | 95 | [[package]] 96 | name = "clap" 97 | version = "3.0.0-beta.2" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" 100 | dependencies = [ 101 | "atty", 102 | "bitflags", 103 | "clap_derive", 104 | "indexmap", 105 | "lazy_static", 106 | "os_str_bytes", 107 | "strsim", 108 | "termcolor", 109 | "textwrap", 110 | "unicode-width", 111 | "vec_map", 112 | ] 113 | 114 | [[package]] 115 | name = "clap_derive" 116 | version = "3.0.0-beta.2" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" 119 | dependencies = [ 120 | "heck", 121 | "proc-macro-error", 122 | "proc-macro2", 123 | "quote", 124 | "syn", 125 | ] 126 | 127 | [[package]] 128 | name = "core-foundation" 129 | version = "0.9.1" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" 132 | dependencies = [ 133 | "core-foundation-sys", 134 | "libc", 135 | ] 136 | 137 | [[package]] 138 | name = "core-foundation-sys" 139 | version = "0.8.2" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" 142 | 143 | [[package]] 144 | name = "crc32fast" 145 | version = "1.2.1" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" 148 | dependencies = [ 149 | "cfg-if 1.0.0", 150 | ] 151 | 152 | [[package]] 153 | name = "encoding_rs" 154 | version = "0.8.28" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" 157 | dependencies = [ 158 | "cfg-if 1.0.0", 159 | ] 160 | 161 | [[package]] 162 | name = "flate2" 163 | version = "1.0.14" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" 166 | dependencies = [ 167 | "cfg-if 0.1.10", 168 | "crc32fast", 169 | "libc", 170 | "miniz_oxide", 171 | ] 172 | 173 | [[package]] 174 | name = "fnv" 175 | version = "1.0.7" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 178 | 179 | [[package]] 180 | name = "foreign-types" 181 | version = "0.3.2" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 184 | dependencies = [ 185 | "foreign-types-shared", 186 | ] 187 | 188 | [[package]] 189 | name = "foreign-types-shared" 190 | version = "0.1.1" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 193 | 194 | [[package]] 195 | name = "form_urlencoded" 196 | version = "1.0.1" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" 199 | dependencies = [ 200 | "matches", 201 | "percent-encoding", 202 | ] 203 | 204 | [[package]] 205 | name = "futures-channel" 206 | version = "0.3.13" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939" 209 | dependencies = [ 210 | "futures-core", 211 | ] 212 | 213 | [[package]] 214 | name = "futures-core" 215 | version = "0.3.13" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94" 218 | 219 | [[package]] 220 | name = "futures-io" 221 | version = "0.3.13" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59" 224 | 225 | [[package]] 226 | name = "futures-sink" 227 | version = "0.3.13" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3" 230 | 231 | [[package]] 232 | name = "futures-task" 233 | version = "0.3.13" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80" 236 | 237 | [[package]] 238 | name = "futures-util" 239 | version = "0.3.13" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1" 242 | dependencies = [ 243 | "futures-core", 244 | "futures-io", 245 | "futures-task", 246 | "memchr", 247 | "pin-project-lite", 248 | "pin-utils", 249 | "slab", 250 | ] 251 | 252 | [[package]] 253 | name = "getrandom" 254 | version = "0.2.2" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" 257 | dependencies = [ 258 | "cfg-if 1.0.0", 259 | "libc", 260 | "wasi", 261 | ] 262 | 263 | [[package]] 264 | name = "h2" 265 | version = "0.3.1" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "d832b01df74254fe364568d6ddc294443f61cbec82816b60904303af87efae78" 268 | dependencies = [ 269 | "bytes", 270 | "fnv", 271 | "futures-core", 272 | "futures-sink", 273 | "futures-util", 274 | "http", 275 | "indexmap", 276 | "slab", 277 | "tokio", 278 | "tokio-util", 279 | "tracing", 280 | ] 281 | 282 | [[package]] 283 | name = "hashbrown" 284 | version = "0.9.1" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" 287 | 288 | [[package]] 289 | name = "heck" 290 | version = "0.3.2" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" 293 | dependencies = [ 294 | "unicode-segmentation", 295 | ] 296 | 297 | [[package]] 298 | name = "hermit-abi" 299 | version = "0.1.18" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" 302 | dependencies = [ 303 | "libc", 304 | ] 305 | 306 | [[package]] 307 | name = "http" 308 | version = "0.2.3" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747" 311 | dependencies = [ 312 | "bytes", 313 | "fnv", 314 | "itoa", 315 | ] 316 | 317 | [[package]] 318 | name = "http-body" 319 | version = "0.4.0" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994" 322 | dependencies = [ 323 | "bytes", 324 | "http", 325 | ] 326 | 327 | [[package]] 328 | name = "httparse" 329 | version = "1.3.5" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691" 332 | 333 | [[package]] 334 | name = "httpdate" 335 | version = "0.3.2" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" 338 | 339 | [[package]] 340 | name = "hyper" 341 | version = "0.14.4" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "e8e946c2b1349055e0b72ae281b238baf1a3ea7307c7e9f9d64673bdd9c26ac7" 344 | dependencies = [ 345 | "bytes", 346 | "futures-channel", 347 | "futures-core", 348 | "futures-util", 349 | "h2", 350 | "http", 351 | "http-body", 352 | "httparse", 353 | "httpdate", 354 | "itoa", 355 | "pin-project", 356 | "socket2", 357 | "tokio", 358 | "tower-service", 359 | "tracing", 360 | "want", 361 | ] 362 | 363 | [[package]] 364 | name = "hyper-tls" 365 | version = "0.5.0" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 368 | dependencies = [ 369 | "bytes", 370 | "hyper", 371 | "native-tls", 372 | "tokio", 373 | "tokio-native-tls", 374 | ] 375 | 376 | [[package]] 377 | name = "idna" 378 | version = "0.2.2" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" 381 | dependencies = [ 382 | "matches", 383 | "unicode-bidi", 384 | "unicode-normalization", 385 | ] 386 | 387 | [[package]] 388 | name = "indexmap" 389 | version = "1.6.1" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b" 392 | dependencies = [ 393 | "autocfg", 394 | "hashbrown", 395 | ] 396 | 397 | [[package]] 398 | name = "ipnet" 399 | version = "2.3.0" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" 402 | 403 | [[package]] 404 | name = "itoa" 405 | version = "0.4.7" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" 408 | 409 | [[package]] 410 | name = "js-sys" 411 | version = "0.3.48" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78" 414 | dependencies = [ 415 | "wasm-bindgen", 416 | ] 417 | 418 | [[package]] 419 | name = "lazy_static" 420 | version = "1.4.0" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 423 | 424 | [[package]] 425 | name = "libc" 426 | version = "0.2.86" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" 429 | 430 | [[package]] 431 | name = "log" 432 | version = "0.4.14" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" 435 | dependencies = [ 436 | "cfg-if 1.0.0", 437 | ] 438 | 439 | [[package]] 440 | name = "matches" 441 | version = "0.1.8" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 444 | 445 | [[package]] 446 | name = "memchr" 447 | version = "2.3.4" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" 450 | 451 | [[package]] 452 | name = "mime" 453 | version = "0.3.16" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 456 | 457 | [[package]] 458 | name = "miniz_oxide" 459 | version = "0.3.7" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" 462 | dependencies = [ 463 | "adler32", 464 | ] 465 | 466 | [[package]] 467 | name = "mio" 468 | version = "0.7.9" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a" 471 | dependencies = [ 472 | "libc", 473 | "log", 474 | "miow", 475 | "ntapi", 476 | "winapi", 477 | ] 478 | 479 | [[package]] 480 | name = "miow" 481 | version = "0.3.6" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" 484 | dependencies = [ 485 | "socket2", 486 | "winapi", 487 | ] 488 | 489 | [[package]] 490 | name = "native-tls" 491 | version = "0.2.7" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4" 494 | dependencies = [ 495 | "lazy_static", 496 | "libc", 497 | "log", 498 | "openssl", 499 | "openssl-probe", 500 | "openssl-sys", 501 | "schannel", 502 | "security-framework", 503 | "security-framework-sys", 504 | "tempfile", 505 | ] 506 | 507 | [[package]] 508 | name = "ntapi" 509 | version = "0.3.6" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" 512 | dependencies = [ 513 | "winapi", 514 | ] 515 | 516 | [[package]] 517 | name = "num_cpus" 518 | version = "1.13.0" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 521 | dependencies = [ 522 | "hermit-abi", 523 | "libc", 524 | ] 525 | 526 | [[package]] 527 | name = "openssl" 528 | version = "0.10.32" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70" 531 | dependencies = [ 532 | "bitflags", 533 | "cfg-if 1.0.0", 534 | "foreign-types", 535 | "lazy_static", 536 | "libc", 537 | "openssl-sys", 538 | ] 539 | 540 | [[package]] 541 | name = "openssl-probe" 542 | version = "0.1.2" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 545 | 546 | [[package]] 547 | name = "openssl-sys" 548 | version = "0.9.60" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6" 551 | dependencies = [ 552 | "autocfg", 553 | "cc", 554 | "libc", 555 | "pkg-config", 556 | "vcpkg", 557 | ] 558 | 559 | [[package]] 560 | name = "os_str_bytes" 561 | version = "2.4.0" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" 564 | 565 | [[package]] 566 | name = "percent-encoding" 567 | version = "2.1.0" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 570 | 571 | [[package]] 572 | name = "pin-project" 573 | version = "1.0.5" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "96fa8ebb90271c4477f144354485b8068bd8f6b78b428b01ba892ca26caf0b63" 576 | dependencies = [ 577 | "pin-project-internal", 578 | ] 579 | 580 | [[package]] 581 | name = "pin-project-internal" 582 | version = "1.0.5" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "758669ae3558c6f74bd2a18b41f7ac0b5a195aea6639d6a9b5e5d1ad5ba24c0b" 585 | dependencies = [ 586 | "proc-macro2", 587 | "quote", 588 | "syn", 589 | ] 590 | 591 | [[package]] 592 | name = "pin-project-lite" 593 | version = "0.2.4" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827" 596 | 597 | [[package]] 598 | name = "pin-utils" 599 | version = "0.1.0" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 602 | 603 | [[package]] 604 | name = "pkg-config" 605 | version = "0.3.19" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" 608 | 609 | [[package]] 610 | name = "ppv-lite86" 611 | version = "0.2.10" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" 614 | 615 | [[package]] 616 | name = "proc-macro-error" 617 | version = "1.0.4" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 620 | dependencies = [ 621 | "proc-macro-error-attr", 622 | "proc-macro2", 623 | "quote", 624 | "syn", 625 | "version_check", 626 | ] 627 | 628 | [[package]] 629 | name = "proc-macro-error-attr" 630 | version = "1.0.4" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 633 | dependencies = [ 634 | "proc-macro2", 635 | "quote", 636 | "version_check", 637 | ] 638 | 639 | [[package]] 640 | name = "proc-macro2" 641 | version = "1.0.24" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" 644 | dependencies = [ 645 | "unicode-xid", 646 | ] 647 | 648 | [[package]] 649 | name = "quote" 650 | version = "1.0.9" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" 653 | dependencies = [ 654 | "proc-macro2", 655 | ] 656 | 657 | [[package]] 658 | name = "rand" 659 | version = "0.8.3" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" 662 | dependencies = [ 663 | "libc", 664 | "rand_chacha", 665 | "rand_core", 666 | "rand_hc", 667 | ] 668 | 669 | [[package]] 670 | name = "rand_chacha" 671 | version = "0.3.0" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" 674 | dependencies = [ 675 | "ppv-lite86", 676 | "rand_core", 677 | ] 678 | 679 | [[package]] 680 | name = "rand_core" 681 | version = "0.6.2" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" 684 | dependencies = [ 685 | "getrandom", 686 | ] 687 | 688 | [[package]] 689 | name = "rand_hc" 690 | version = "0.3.0" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" 693 | dependencies = [ 694 | "rand_core", 695 | ] 696 | 697 | [[package]] 698 | name = "redox_syscall" 699 | version = "0.2.5" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" 702 | dependencies = [ 703 | "bitflags", 704 | ] 705 | 706 | [[package]] 707 | name = "remove_dir_all" 708 | version = "0.5.3" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 711 | dependencies = [ 712 | "winapi", 713 | ] 714 | 715 | [[package]] 716 | name = "reqwest" 717 | version = "0.11.1" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "0460542b551950620a3648c6aa23318ac6b3cd779114bd873209e6e8b5eb1c34" 720 | dependencies = [ 721 | "base64", 722 | "bytes", 723 | "encoding_rs", 724 | "futures-core", 725 | "futures-util", 726 | "http", 727 | "http-body", 728 | "hyper", 729 | "hyper-tls", 730 | "ipnet", 731 | "js-sys", 732 | "lazy_static", 733 | "log", 734 | "mime", 735 | "native-tls", 736 | "percent-encoding", 737 | "pin-project-lite", 738 | "serde", 739 | "serde_urlencoded", 740 | "tokio", 741 | "tokio-native-tls", 742 | "url", 743 | "wasm-bindgen", 744 | "wasm-bindgen-futures", 745 | "web-sys", 746 | "winreg", 747 | ] 748 | 749 | [[package]] 750 | name = "ryu" 751 | version = "1.0.5" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 754 | 755 | [[package]] 756 | name = "same-file" 757 | version = "1.0.6" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 760 | dependencies = [ 761 | "winapi-util", 762 | ] 763 | 764 | [[package]] 765 | name = "schannel" 766 | version = "0.1.19" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 769 | dependencies = [ 770 | "lazy_static", 771 | "winapi", 772 | ] 773 | 774 | [[package]] 775 | name = "security-framework" 776 | version = "2.1.1" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "2dfd318104249865096c8da1dfabf09ddbb6d0330ea176812a62ec75e40c4166" 779 | dependencies = [ 780 | "bitflags", 781 | "core-foundation", 782 | "core-foundation-sys", 783 | "libc", 784 | "security-framework-sys", 785 | ] 786 | 787 | [[package]] 788 | name = "security-framework-sys" 789 | version = "2.1.1" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "dee48cdde5ed250b0d3252818f646e174ab414036edb884dde62d80a3ac6082d" 792 | dependencies = [ 793 | "core-foundation-sys", 794 | "libc", 795 | ] 796 | 797 | [[package]] 798 | name = "serde" 799 | version = "1.0.123" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" 802 | dependencies = [ 803 | "serde_derive", 804 | ] 805 | 806 | [[package]] 807 | name = "serde_derive" 808 | version = "1.0.123" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" 811 | dependencies = [ 812 | "proc-macro2", 813 | "quote", 814 | "syn", 815 | ] 816 | 817 | [[package]] 818 | name = "serde_json" 819 | version = "1.0.64" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" 822 | dependencies = [ 823 | "itoa", 824 | "ryu", 825 | "serde", 826 | ] 827 | 828 | [[package]] 829 | name = "serde_urlencoded" 830 | version = "0.7.0" 831 | source = "registry+https://github.com/rust-lang/crates.io-index" 832 | checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" 833 | dependencies = [ 834 | "form_urlencoded", 835 | "itoa", 836 | "ryu", 837 | "serde", 838 | ] 839 | 840 | [[package]] 841 | name = "slab" 842 | version = "0.4.2" 843 | source = "registry+https://github.com/rust-lang/crates.io-index" 844 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 845 | 846 | [[package]] 847 | name = "socket2" 848 | version = "0.3.19" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" 851 | dependencies = [ 852 | "cfg-if 1.0.0", 853 | "libc", 854 | "winapi", 855 | ] 856 | 857 | [[package]] 858 | name = "strsim" 859 | version = "0.10.0" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 862 | 863 | [[package]] 864 | name = "syn" 865 | version = "1.0.60" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" 868 | dependencies = [ 869 | "proc-macro2", 870 | "quote", 871 | "unicode-xid", 872 | ] 873 | 874 | [[package]] 875 | name = "tempfile" 876 | version = "3.2.0" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" 879 | dependencies = [ 880 | "cfg-if 1.0.0", 881 | "libc", 882 | "rand", 883 | "redox_syscall", 884 | "remove_dir_all", 885 | "winapi", 886 | ] 887 | 888 | [[package]] 889 | name = "termcolor" 890 | version = "1.1.2" 891 | source = "registry+https://github.com/rust-lang/crates.io-index" 892 | checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" 893 | dependencies = [ 894 | "winapi-util", 895 | ] 896 | 897 | [[package]] 898 | name = "textwrap" 899 | version = "0.12.1" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" 902 | dependencies = [ 903 | "unicode-width", 904 | ] 905 | 906 | [[package]] 907 | name = "thiserror" 908 | version = "1.0.24" 909 | source = "registry+https://github.com/rust-lang/crates.io-index" 910 | checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" 911 | dependencies = [ 912 | "thiserror-impl", 913 | ] 914 | 915 | [[package]] 916 | name = "thiserror-impl" 917 | version = "1.0.24" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" 920 | dependencies = [ 921 | "proc-macro2", 922 | "quote", 923 | "syn", 924 | ] 925 | 926 | [[package]] 927 | name = "time" 928 | version = "0.1.44" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" 931 | dependencies = [ 932 | "libc", 933 | "wasi", 934 | "winapi", 935 | ] 936 | 937 | [[package]] 938 | name = "tinyvec" 939 | version = "1.1.1" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023" 942 | dependencies = [ 943 | "tinyvec_macros", 944 | ] 945 | 946 | [[package]] 947 | name = "tinyvec_macros" 948 | version = "0.1.0" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 951 | 952 | [[package]] 953 | name = "tokio" 954 | version = "1.2.0" 955 | source = "registry+https://github.com/rust-lang/crates.io-index" 956 | checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a" 957 | dependencies = [ 958 | "autocfg", 959 | "bytes", 960 | "libc", 961 | "memchr", 962 | "mio", 963 | "num_cpus", 964 | "pin-project-lite", 965 | ] 966 | 967 | [[package]] 968 | name = "tokio-native-tls" 969 | version = "0.3.0" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" 972 | dependencies = [ 973 | "native-tls", 974 | "tokio", 975 | ] 976 | 977 | [[package]] 978 | name = "tokio-util" 979 | version = "0.6.3" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "ebb7cb2f00c5ae8df755b252306272cd1790d39728363936e01827e11f0b017b" 982 | dependencies = [ 983 | "bytes", 984 | "futures-core", 985 | "futures-sink", 986 | "log", 987 | "pin-project-lite", 988 | "tokio", 989 | ] 990 | 991 | [[package]] 992 | name = "toolkit" 993 | version = "0.1.0" 994 | dependencies = [ 995 | "clap", 996 | "reqwest", 997 | "serde", 998 | "serde_json", 999 | "walkdir", 1000 | "zip", 1001 | ] 1002 | 1003 | [[package]] 1004 | name = "tower-service" 1005 | version = "0.3.1" 1006 | source = "registry+https://github.com/rust-lang/crates.io-index" 1007 | checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" 1008 | 1009 | [[package]] 1010 | name = "tracing" 1011 | version = "0.1.25" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" 1014 | dependencies = [ 1015 | "cfg-if 1.0.0", 1016 | "pin-project-lite", 1017 | "tracing-core", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "tracing-core" 1022 | version = "0.1.17" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" 1025 | dependencies = [ 1026 | "lazy_static", 1027 | ] 1028 | 1029 | [[package]] 1030 | name = "try-lock" 1031 | version = "0.2.3" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 1034 | 1035 | [[package]] 1036 | name = "unicode-bidi" 1037 | version = "0.3.4" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1040 | dependencies = [ 1041 | "matches", 1042 | ] 1043 | 1044 | [[package]] 1045 | name = "unicode-normalization" 1046 | version = "0.1.17" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" 1049 | dependencies = [ 1050 | "tinyvec", 1051 | ] 1052 | 1053 | [[package]] 1054 | name = "unicode-segmentation" 1055 | version = "1.7.1" 1056 | source = "registry+https://github.com/rust-lang/crates.io-index" 1057 | checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" 1058 | 1059 | [[package]] 1060 | name = "unicode-width" 1061 | version = "0.1.8" 1062 | source = "registry+https://github.com/rust-lang/crates.io-index" 1063 | checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" 1064 | 1065 | [[package]] 1066 | name = "unicode-xid" 1067 | version = "0.2.1" 1068 | source = "registry+https://github.com/rust-lang/crates.io-index" 1069 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 1070 | 1071 | [[package]] 1072 | name = "url" 1073 | version = "2.2.1" 1074 | source = "registry+https://github.com/rust-lang/crates.io-index" 1075 | checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" 1076 | dependencies = [ 1077 | "form_urlencoded", 1078 | "idna", 1079 | "matches", 1080 | "percent-encoding", 1081 | ] 1082 | 1083 | [[package]] 1084 | name = "vcpkg" 1085 | version = "0.2.11" 1086 | source = "registry+https://github.com/rust-lang/crates.io-index" 1087 | checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" 1088 | 1089 | [[package]] 1090 | name = "vec_map" 1091 | version = "0.8.2" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1094 | 1095 | [[package]] 1096 | name = "version_check" 1097 | version = "0.9.2" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" 1100 | 1101 | [[package]] 1102 | name = "walkdir" 1103 | version = "2.3.1" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" 1106 | dependencies = [ 1107 | "same-file", 1108 | "winapi", 1109 | "winapi-util", 1110 | ] 1111 | 1112 | [[package]] 1113 | name = "want" 1114 | version = "0.3.0" 1115 | source = "registry+https://github.com/rust-lang/crates.io-index" 1116 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1117 | dependencies = [ 1118 | "log", 1119 | "try-lock", 1120 | ] 1121 | 1122 | [[package]] 1123 | name = "wasi" 1124 | version = "0.10.0+wasi-snapshot-preview1" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 1127 | 1128 | [[package]] 1129 | name = "wasm-bindgen" 1130 | version = "0.2.71" 1131 | source = "registry+https://github.com/rust-lang/crates.io-index" 1132 | checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7" 1133 | dependencies = [ 1134 | "cfg-if 1.0.0", 1135 | "serde", 1136 | "serde_json", 1137 | "wasm-bindgen-macro", 1138 | ] 1139 | 1140 | [[package]] 1141 | name = "wasm-bindgen-backend" 1142 | version = "0.2.71" 1143 | source = "registry+https://github.com/rust-lang/crates.io-index" 1144 | checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8" 1145 | dependencies = [ 1146 | "bumpalo", 1147 | "lazy_static", 1148 | "log", 1149 | "proc-macro2", 1150 | "quote", 1151 | "syn", 1152 | "wasm-bindgen-shared", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "wasm-bindgen-futures" 1157 | version = "0.4.21" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "8e67a5806118af01f0d9045915676b22aaebecf4178ae7021bc171dab0b897ab" 1160 | dependencies = [ 1161 | "cfg-if 1.0.0", 1162 | "js-sys", 1163 | "wasm-bindgen", 1164 | "web-sys", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "wasm-bindgen-macro" 1169 | version = "0.2.71" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b" 1172 | dependencies = [ 1173 | "quote", 1174 | "wasm-bindgen-macro-support", 1175 | ] 1176 | 1177 | [[package]] 1178 | name = "wasm-bindgen-macro-support" 1179 | version = "0.2.71" 1180 | source = "registry+https://github.com/rust-lang/crates.io-index" 1181 | checksum = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e" 1182 | dependencies = [ 1183 | "proc-macro2", 1184 | "quote", 1185 | "syn", 1186 | "wasm-bindgen-backend", 1187 | "wasm-bindgen-shared", 1188 | ] 1189 | 1190 | [[package]] 1191 | name = "wasm-bindgen-shared" 1192 | version = "0.2.71" 1193 | source = "registry+https://github.com/rust-lang/crates.io-index" 1194 | checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1" 1195 | 1196 | [[package]] 1197 | name = "web-sys" 1198 | version = "0.3.48" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b" 1201 | dependencies = [ 1202 | "js-sys", 1203 | "wasm-bindgen", 1204 | ] 1205 | 1206 | [[package]] 1207 | name = "winapi" 1208 | version = "0.3.9" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1211 | dependencies = [ 1212 | "winapi-i686-pc-windows-gnu", 1213 | "winapi-x86_64-pc-windows-gnu", 1214 | ] 1215 | 1216 | [[package]] 1217 | name = "winapi-i686-pc-windows-gnu" 1218 | version = "0.4.0" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1221 | 1222 | [[package]] 1223 | name = "winapi-util" 1224 | version = "0.1.5" 1225 | source = "registry+https://github.com/rust-lang/crates.io-index" 1226 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1227 | dependencies = [ 1228 | "winapi", 1229 | ] 1230 | 1231 | [[package]] 1232 | name = "winapi-x86_64-pc-windows-gnu" 1233 | version = "0.4.0" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1236 | 1237 | [[package]] 1238 | name = "winreg" 1239 | version = "0.7.0" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" 1242 | dependencies = [ 1243 | "winapi", 1244 | ] 1245 | 1246 | [[package]] 1247 | name = "zip" 1248 | version = "0.5.10" 1249 | source = "registry+https://github.com/rust-lang/crates.io-index" 1250 | checksum = "5a8977234acab718eb2820494b2f96cbb16004c19dddf88b7445b27381450997" 1251 | dependencies = [ 1252 | "byteorder", 1253 | "bzip2", 1254 | "crc32fast", 1255 | "flate2", 1256 | "thiserror", 1257 | "time", 1258 | ] 1259 | -------------------------------------------------------------------------------- /toolkit/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "toolkit" 3 | version = "0.1.0" 4 | authors = ["Yakov Borevich "] 5 | edition = "2018" 6 | license = "MIT" 7 | 8 | 9 | [dependencies] 10 | clap = "3.0.0-beta.2" 11 | zip = "0.5" 12 | walkdir = "2.3.1" 13 | serde = { version = "1.0.123", features = ["derive"] } 14 | serde_json = "1.0" 15 | reqwest = { version = "0.11.1", features = ["blocking"] } 16 | -------------------------------------------------------------------------------- /toolkit/src/compress.rs: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use crate::prelude::*; 24 | 25 | 26 | use std::io::prelude::*; 27 | use std::iter::Iterator; 28 | use zip::write::FileOptions; 29 | use zip; 30 | 31 | /// Compress `source` dirrectory into `destination` file using zip 32 | #[derive(Clap)] 33 | pub struct Compress { 34 | /// Source folder 35 | #[clap(long, short)] 36 | source: String, 37 | /// Destination file 38 | #[clap(long, short)] 39 | destination: String, 40 | } 41 | 42 | impl Compress { 43 | pub fn execute(&self) -> Res { 44 | let file = File::create(&self.destination)?; 45 | let method = zip::CompressionMethod::Deflated; 46 | let walkdir = WalkDir::new(&self.source); 47 | let it = walkdir.into_iter(); 48 | compress(&mut it.filter_map(|e| e.ok()), &self.source, &file, method)?; 49 | return Ok(Value::Null); 50 | } 51 | } 52 | 53 | pub fn compress( 54 | it: &mut dyn Iterator, 55 | prefix: &str, 56 | writer: T, 57 | method: zip::CompressionMethod, 58 | ) -> zip::result::ZipResult<()> 59 | where 60 | T: Write + Seek, 61 | { 62 | //return Result::Ok(()); 63 | let mut zip = zip::ZipWriter::new(writer); 64 | let options = FileOptions::default() 65 | .compression_method(method) 66 | .unix_permissions(0o755); 67 | 68 | let mut buffer = Vec::new(); 69 | for entry in it { 70 | let path = entry.path(); 71 | let name = path.strip_prefix(Path::new(prefix)).unwrap(); 72 | 73 | // Write file or directory explicitly 74 | // Some unzip tools unzip files with directory paths correctly, some do not! 75 | if path.is_file() { 76 | #[allow(deprecated)] 77 | zip.start_file_from_path(name, options)?; 78 | let mut f = File::open(path)?; 79 | 80 | f.read_to_end(&mut buffer)?; 81 | zip.write_all(&*buffer)?; 82 | buffer.clear(); 83 | } else if name.as_os_str().len() != 0 { 84 | // Only if not root! Avoids path spec / warning 85 | // and mapname conversion failed error on unzip 86 | #[allow(deprecated)] 87 | zip.add_directory_from_path(name, options)?; 88 | } 89 | } 90 | zip.finish()?; 91 | Result::Ok(()) 92 | } 93 | 94 | 95 | pub fn decompress(path: &std::path::Path, outdir: &std::path::Path) { 96 | let file = File::open(path).unwrap(); 97 | 98 | let mut archive = zip::ZipArchive::new(file).unwrap(); 99 | 100 | for i in 0..archive.len() { 101 | let mut file = archive.by_index(i).unwrap(); 102 | let outpath = match file.enclosed_name() { 103 | Some(path) => outdir.join(path).to_owned(), 104 | None => continue, 105 | }; 106 | 107 | if (&*file.name()).ends_with('/') { 108 | std::fs::create_dir_all(&outpath).unwrap(); 109 | } else { 110 | if let Some(p) = outpath.parent() { 111 | if !p.exists() { 112 | std::fs::create_dir_all(&p).unwrap(); 113 | } 114 | } 115 | let mut outfile = File::create(&outpath).unwrap(); 116 | std::io::copy(&mut file, &mut outfile).unwrap(); 117 | } 118 | 119 | // Get and Set permissions 120 | #[cfg(unix)] 121 | { 122 | use std::os::unix::fs::PermissionsExt; 123 | 124 | if let Some(mode) = file.unix_mode() { 125 | std::fs::set_permissions(&outpath, std::fs::Permissions::from_mode(mode)).unwrap(); 126 | } 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /toolkit/src/main.rs: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | mod prelude; 24 | mod update; 25 | mod compress; 26 | 27 | 28 | //use clap::Clap; 29 | // use std::fs::File; 30 | // use std::path::Path; 31 | // use walkdir::{DirEntry, WalkDir}; 32 | // use std::error::Error; 33 | 34 | // use github_rs::client::{Executor, Github}; 35 | //use serde::{Deserialize, Serialize}; 36 | //use serde_json::Value; 37 | // use reqwest; 38 | 39 | use crate::prelude::*; 40 | 41 | /// Command-line toolkit for interacting between Funexpected Tools 42 | /// jsfl extention and native stuff 43 | #[derive(Clap)] 44 | #[clap(version = "1.0", author = "Yakov Borevich ")] 45 | struct Opts { 46 | #[clap(subcommand)] 47 | subcmd: SubCommand, 48 | } 49 | 50 | #[derive(Clap)] 51 | enum SubCommand { 52 | Compress(compress::Compress), 53 | Update(update::Update), 54 | } 55 | 56 | /// Copress target folder into destination path using zip 57 | // #[derive(Clap)] 58 | // struct Compress { 59 | // /// Source folder 60 | // #[clap(long, short)] 61 | // source: String, 62 | // /// Destination file 63 | // #[clap(long, short)] 64 | // destination: String, 65 | 66 | // } 67 | 68 | fn main() { 69 | let opts: Opts = Opts::parse(); 70 | match opts.subcmd { 71 | SubCommand::Compress(cmd) => { 72 | match cmd.execute() { 73 | Ok(value) => success(serde_json::to_value(value).unwrap()), 74 | Err(msg) => error(msg.to_string()) 75 | } 76 | }, 77 | SubCommand::Update(cmd) => { 78 | match cmd.execute() { 79 | Ok(value) => success(serde_json::to_value(value).unwrap()), 80 | Err(msg) => error(msg.to_string()) 81 | } 82 | } 83 | } 84 | } 85 | 86 | // fn compress( 87 | // it: &mut dyn Iterator, 88 | // prefix: &str, 89 | // writer: T, 90 | // method: zip::CompressionMethod, 91 | // ) -> zip::result::ZipResult<()> 92 | // where 93 | // T: Write + Seek, 94 | // { 95 | // //return Result::Ok(()); 96 | // let mut zip = zip::ZipWriter::new(writer); 97 | // let options = FileOptions::default() 98 | // .compression_method(method) 99 | // .unix_permissions(0o755); 100 | 101 | // let mut buffer = Vec::new(); 102 | // for entry in it { 103 | // let path = entry.path(); 104 | // let name = path.strip_prefix(Path::new(prefix)).unwrap(); 105 | 106 | // // Write file or directory explicitly 107 | // // Some unzip tools unzip files with directory paths correctly, some do not! 108 | // if path.is_file() { 109 | // #[allow(deprecated)] 110 | // zip.start_file_from_path(name, options)?; 111 | // let mut f = File::open(path)?; 112 | 113 | // f.read_to_end(&mut buffer)?; 114 | // zip.write_all(&*buffer)?; 115 | // buffer.clear(); 116 | // } else if name.as_os_str().len() != 0 { 117 | // // Only if not root! Avoids path spec / warning 118 | // // and mapname conversion failed error on unzip 119 | // #[allow(deprecated)] 120 | // zip.add_directory_from_path(name, options)?; 121 | // } 122 | // } 123 | // zip.finish()?; 124 | // Result::Ok(()) 125 | // } 126 | 127 | 128 | // fn decompress(path: &std::path::Path, outdir: &std::path::Path) { 129 | // // let args: Vec<_> = std::env::args().collect(); 130 | // // if args.len() < 2 { 131 | // // println!("Usage: {} ", args[0]); 132 | // // return 1; 133 | // // } 134 | // // let path = std::path::Path::new(&*args[1]); 135 | // let file = File::open(path).unwrap(); 136 | 137 | // let mut archive = zip::ZipArchive::new(file).unwrap(); 138 | 139 | // for i in 0..archive.len() { 140 | // let mut file = archive.by_index(i).unwrap(); 141 | // let outpath = match file.enclosed_name() { 142 | // Some(path) => outdir.join(path).to_owned(), 143 | // None => continue, 144 | // }; 145 | 146 | // { 147 | // let comment = file.comment(); 148 | // if !comment.is_empty() { 149 | // println!("File {} comment: {}", i, comment); 150 | // } 151 | // } 152 | 153 | // if (&*file.name()).ends_with('/') { 154 | // println!("File {} extracted to \"{}\"", i, outpath.display()); 155 | // std::fs::create_dir_all(&outpath).unwrap(); 156 | // } else { 157 | // println!( 158 | // "File {} extracted to \"{}\" ({} bytes)", 159 | // i, 160 | // outpath.display(), 161 | // file.size() 162 | // ); 163 | // if let Some(p) = outpath.parent() { 164 | // if !p.exists() { 165 | // std::fs::create_dir_all(&p).unwrap(); 166 | // } 167 | // } 168 | // let mut outfile = File::create(&outpath).unwrap(); 169 | // std::io::copy(&mut file, &mut outfile).unwrap(); 170 | // } 171 | 172 | // // Get and Set permissions 173 | // #[cfg(unix)] 174 | // { 175 | // use std::os::unix::fs::PermissionsExt; 176 | 177 | // if let Some(mode) = file.unix_mode() { 178 | // std::fs::set_permissions(&outpath, std::fs::Permissions::from_mode(mode)).unwrap(); 179 | // } 180 | // } 181 | // } 182 | // } -------------------------------------------------------------------------------- /toolkit/src/prelude.rs: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | pub use std::fs::File; 24 | pub use std::path::Path; 25 | pub use std::error::Error; 26 | pub use std::io::{Seek, Write}; 27 | 28 | pub use clap::Clap; 29 | pub use serde::{Deserialize, Serialize}; 30 | pub use serde_json::Value; 31 | pub use walkdir::{DirEntry, WalkDir}; 32 | 33 | pub type Res = std::result::Result>; 34 | 35 | #[derive(Serialize, Deserialize)] 36 | struct ToolkitResult { 37 | success: bool, 38 | message: Option, 39 | result: Option 40 | } 41 | 42 | fn write_result(success: bool, message: Option, result: Option) { 43 | let current_exe = std::env::current_exe().unwrap(); 44 | let working_dir = current_exe.parent().unwrap(); 45 | let mut file = File::create(working_dir.join("result.json").as_path()).unwrap(); 46 | let result = ToolkitResult { 47 | success, message, result 48 | }; 49 | file.write_all(serde_json::to_string(&result).unwrap().as_bytes()).unwrap(); 50 | } 51 | 52 | pub fn success(result: Value) { 53 | write_result(true, None, Some(result)); 54 | } 55 | 56 | pub fn error(message: String) { 57 | write_result(false, Some(message), None); 58 | } 59 | 60 | 61 | #[derive(Debug)] 62 | struct InvokeError { 63 | message: String 64 | } 65 | 66 | impl std::fmt::Display for InvokeError { 67 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 68 | write!(f, "{}", self.message) 69 | } 70 | } 71 | 72 | 73 | impl Error for InvokeError {} 74 | 75 | pub fn err(message: &str) -> Res { 76 | return Err(Box::new(InvokeError { message: message.to_string() })); 77 | } -------------------------------------------------------------------------------- /toolkit/src/update.rs: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2021 Yakov Borevich, Funexpected LLC 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use crate::prelude::*; 24 | use crate::compress::decompress; 25 | 26 | use reqwest; 27 | 28 | /// Update to the latest version 29 | #[derive(Clap)] 30 | pub struct Update { 31 | /// Current app version 32 | #[clap(long, short)] 33 | from_version: String 34 | } 35 | 36 | impl Update { 37 | pub fn execute(&self) -> Res { 38 | let release_url = "https://api.github.com/repos/funexpected/flash-tools/releases/latest"; 39 | let mut headers = reqwest::header::HeaderMap::new(); 40 | headers.insert("User-Agent", reqwest::header::HeaderValue::from_static("reqwest")); 41 | let client = reqwest::blocking::Client::builder() 42 | .default_headers(headers) 43 | .build()?; 44 | 45 | let response = client.get(release_url).send()?; 46 | if response.status() != 200 { 47 | return err(&format!("Can't fetch release (response code: {})", response.status())); 48 | } 49 | let release: Release = serde_json::from_str(&response.text()?)?; 50 | 51 | 52 | // if status != 200 { 53 | // return err("No release found"); 54 | // } 55 | // let release: Release = serde_json::from_value(json.unwrap()).unwrap(); 56 | if !release.is_version_higher(&self.from_version) { 57 | return Ok(UpdateResult::create("already_latest", None, None)); 58 | } 59 | if let Some(asset) = release.assets.iter().find(|a| a.name == "funexpected-tools.zip") { 60 | let current_exe = std::env::current_exe()?; 61 | let working_dir = current_exe.parent().unwrap(); 62 | let extract_dir = working_dir.join("out"); 63 | let update_dir = working_dir.join("update"); 64 | let zip_path = working_dir.join("funexpected.zip"); 65 | let mut file = File::create(zip_path.as_path())?; 66 | file.write_all(reqwest::blocking::get(asset.browser_download_url.as_str())?.bytes()?.as_ref())?; 67 | decompress(zip_path.as_path(), extract_dir.as_path()); 68 | if let Some(fntools_dir) = WalkDir::new(&extract_dir).into_iter().filter_map(|e| e.ok()).find(|e| e.file_name() == "Funexpected Tools") { 69 | if update_dir.exists() { 70 | std::fs::remove_dir_all(&update_dir)?; 71 | } 72 | std::fs::rename(fntools_dir.path(), &update_dir)?; 73 | std::fs::remove_dir_all(extract_dir)?; 74 | std::fs::remove_file(zip_path)?; 75 | #[cfg(unix)] 76 | { 77 | use std::os::unix::fs::PermissionsExt; 78 | std::fs::set_permissions(&update_dir.join("toolkit"), std::fs::Permissions::from_mode(0o755)).unwrap(); 79 | } 80 | return Ok(UpdateResult::create("updated", Some(&update_dir), Some(release.version()))); 81 | } else { 82 | return err("No `Funexpected Tools` folder found in update"); 83 | } 84 | 85 | } else { 86 | return err("No `funexpected-tools.zip` asset found in released update"); 87 | } 88 | } 89 | } 90 | 91 | #[derive(Serialize, Deserialize)] 92 | struct Asset { 93 | name: String, 94 | browser_download_url: String 95 | } 96 | #[derive(Serialize, Deserialize)] 97 | struct Release { 98 | tag_name: String, 99 | assets: Vec 100 | } 101 | impl Release { 102 | 103 | fn version(&self) -> String { 104 | self.tag_name.trim_start_matches('v').to_string() 105 | } 106 | 107 | fn is_version_higher(&self, version: &String) -> bool { 108 | let release_parts = self.tag_name.trim_start_matches('v').split('.').map(|p| p.parse::().unwrap_or(0)).collect::>(); 109 | let current_parts = version.trim_start_matches('v').split('.').map(|p| p.parse::().unwrap_or(0)).collect::>(); 110 | for i in 0..release_parts.len() { 111 | if i >= current_parts.len() { 112 | return true; 113 | } 114 | if release_parts[i] > current_parts[i] { 115 | return true; 116 | } 117 | 118 | if release_parts[i] < current_parts[i] { 119 | return false; 120 | } 121 | } 122 | return false; 123 | } 124 | } 125 | 126 | #[derive(Serialize, Deserialize)] 127 | pub struct UpdateResult { 128 | status: String, 129 | path: Option, 130 | version: Option 131 | } 132 | 133 | impl UpdateResult { 134 | fn create(status: &str, path: Option<&Path>, version: Option) -> UpdateResult { 135 | UpdateResult { 136 | status: status.to_string(), 137 | path: path.map(|p| p.to_str().unwrap().to_string()), 138 | version 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /tools/compile.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const { execSync } = require('child_process'); 3 | const { exit } = require('process'); 4 | 5 | const SrcDir = 'out/tsc' 6 | const DestDir = 'out/compiled' 7 | 8 | String.prototype.capitalize = function() { 9 | return this.charAt(0).toUpperCase() + this.slice(1); 10 | } 11 | 12 | if (fs.existsSync(DestDir)) fs.rmdirSync(DestDir, { recursive: true }); 13 | fs.readdirSync(SrcDir + '/commands').forEach(cmd => { 14 | let destFileName = cmd.substr(0, cmd.length-3).split("_").map(p => p.capitalize()).join(" ") + ".jsfl"; 15 | let command = `npx google-closure-compiler --js=${SrcDir}/lib/** --js=${SrcDir}/commands/${cmd} --language_out ECMASCRIPT3 --js_output_file=${DestDir}/${cmd} --force_inject_library=es6_runtime --module_resolution=node --process_common_js_modules=true` 16 | console.log(`comiling ${cmd}`) 17 | let result = execSync(command); 18 | if (result.exitCode) { 19 | console.warn(result.stderr); 20 | exit(result.exitCode); 21 | } 22 | fs.renameSync(`${DestDir}/${cmd}`, `${DestDir}/${destFileName}`); 23 | }) -------------------------------------------------------------------------------- /tools/install.js: -------------------------------------------------------------------------------- 1 | const glob = require('glob'); 2 | const home = require('os').homedir(); 3 | const fs = require('fs'); 4 | 5 | const compiledDir = 'out/compiled' 6 | 7 | String.prototype.capitalize = function() { 8 | return this.charAt(0).toUpperCase() + this.slice(1); 9 | } 10 | 11 | let targetDirs = glob.sync(`${home}/Library/ApplicationSupport/Adobe/Animate*/*/Configuration/Commands/`); 12 | targetDirs.forEach(target => { 13 | let toolsDir = `${target}/Funexpected Tools` 14 | if (fs.existsSync(toolsDir)) { 15 | fs.rmdirSync(toolsDir, { recursive: true }); 16 | } 17 | fs.mkdirSync(toolsDir); 18 | 19 | fs.readdirSync(compiledDir).forEach(cmd => { 20 | //let destFileName = cmd.substr(0, cmd.length-3).split("_").map(p => p.capitalize()).join(" ") + ".jsfl"; 21 | console.log(`cp ${compiledDir}/${cmd} ${toolsDir}/${cmd}`); 22 | fs.copyFileSync(`${compiledDir}/${cmd}`, `${toolsDir}/${cmd}`); 23 | }) 24 | }) 25 | 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "./src/**/*.ts" 4 | ], 5 | "exclude": [ 6 | "node_modules/**/*" 7 | ], 8 | "files": [ 9 | "./types/jsfl.d.ts", 10 | "./types/zipfile.d.ts" 11 | ], 12 | "compilerOptions": { 13 | 14 | 15 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 16 | 17 | /* Basic Options */ 18 | // "incremental": true, /* Enable incremental compilation */ 19 | "target": "ES2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 20 | "module": "ESNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 21 | // "lib": [], /* Specify library files to be included in the compilation. */ 22 | // "allowJs": true, /* Allow javascript files to be compiled. */ 23 | // "checkJs": true, /* Report errors in .js files. */ 24 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 25 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 26 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 27 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 28 | //"outFile": "./export.js", /* Concatenate and emit output to single file. */ 29 | "outDir": "./out/tsc", /* Redirect output structure to the directory. */ 30 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 31 | // "composite": true, /* Enable project compilation */ 32 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 33 | // "removeComments": true, /* Do not emit comments to output. */ 34 | // "noEmit": true, /* Do not emit outputs. */ 35 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 36 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 37 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 38 | 39 | /* Strict Type-Checking Options */ 40 | "strict": true, /* Enable all strict type-checking options. */ 41 | "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 42 | // "strictNullChecks": true, /* Enable strict null checks. */ 43 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 44 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 45 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 46 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 47 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 48 | 49 | /* Additional Checks */ 50 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 51 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 52 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 53 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 54 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 55 | 56 | /* Module Resolution Options */ 57 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 58 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 59 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 60 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 61 | // "typeRoots": [ 62 | // "./node_modules/@types", 63 | // "./types" 64 | // ], /* List of folders to include type definitions from. */ 65 | // "types": [ 66 | 67 | // "jsfl" 68 | // ], /* Type declaration files to be included in compilation. */ 69 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 70 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 71 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 72 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 73 | 74 | /* Source Map Options */ 75 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 76 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 77 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 78 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 79 | 80 | /* Experimental Options */ 81 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 82 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 83 | 84 | /* Advanced Options */ 85 | "skipLibCheck": true, /* Skip type checking of declaration files. */ 86 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /types/jsfl.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for JSFL 2 | // Project: https://adobe.com 3 | // Definitions by: soywiz 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | 6 | declare type FlashItemType = 7 | "undefined"| 8 | "component"| 9 | "movie clip"| 10 | "graphic"| 11 | "button"| 12 | "folder"| 13 | "font"| 14 | "sound"| 15 | "bitmap"| 16 | "compiled clip"| 17 | "screen"| 18 | "video"; 19 | 20 | declare type FlashElementType = 21 | "shape"| 22 | "text"| 23 | "tlfText"| 24 | "instance"| 25 | "shapeObj"; 26 | 27 | declare type FlashLayerType = 28 | "normal"| 29 | "guide"| 30 | "guided"| 31 | "mask"| 32 | "masked"| 33 | "folder"; 34 | 35 | interface FlashPoint { 36 | x: number; 37 | y: number; 38 | } 39 | 40 | interface FlashPoint3D extends FlashPoint { 41 | z: number; 42 | } 43 | 44 | interface FlashRectangle { 45 | top: number; 46 | right: number; 47 | bottom: number; 48 | left: number; 49 | } 50 | 51 | interface FlashMatrix { 52 | a: number; 53 | b: number; 54 | c: number; 55 | d: number; 56 | tx: number; 57 | ty: number; 58 | } 59 | 60 | interface FlashFilter { 61 | angle: number; 62 | blurX: number; 63 | blurY: number; 64 | brightness: number; 65 | color: any; 66 | contrast: number; 67 | distance: number; 68 | enabled: boolean; 69 | hideObject: boolean; 70 | highlightColor: any; 71 | hue: number; 72 | inner: boolean; 73 | knockout: boolean; 74 | name: string; 75 | quality: string; 76 | saturation: number; 77 | shadowColor: any; 78 | strength: number; 79 | type: string; 80 | } 81 | 82 | interface FlashDocument { 83 | // "integer", "integerArray", "double", "doubleArray", "string", and "byteArray" 84 | addDataToDocument(name: string, type: string, data: any): void; // Stores specified data with a document. 85 | addDataToSelection(name: string, type: string, data: any): void; // Stores specified data with the selected object(s). 86 | addFilter(filterName: string): void; // Applies a filter to the selected objects. 87 | addItem(position: FlashPoint, item: FlashItem): boolean; // Adds an item from any open document or library 88 | addNewLine(startPoint: FlashPoint, endpoint: FlashPoint):void; // Adds a new path between two points. 89 | addNewOval(boundingRectangle: FlashRectangle, bSuppressFill?: boolean, bSuppressStroke?: boolean): void; // Adds a new Oval object in the specified 90 | addNewPrimitiveOval(boundingRectangle: FlashRectangle, bSpupressFill?: boolean, bSuppressStroke?: boolean): void; 91 | addNewRectangle(boundingRectangle: FlashRectangle, roundness: number, bSuppressFill?: boolean, bSuppressStroke?: boolean); // Adds a new rectangle or rounded rectangle, 92 | addNewPrimitiveRectangle(boundingRectangle: FlashRectangle, roundness: number, bSuppressFill?: boolean, bSuppressStroke?: boolean); // Adds a new rectangle or rounded rectangle, 93 | addNewPublishProfile(profileName?: string): void; 94 | addNewScene(name: string): boolean; // Adds a new scene (Timeline object) as the next 95 | addNewText(boundingRectangle: FlashRectangle, text?: string): void; // Inserts a new empty text field. 96 | align(alignmode: string, bUseDocumentBounds?: boolean); // Aligns the selection. 97 | allowScreens(): void; // Use this method before using the 98 | /** Arranges the selection on the Stage. "back", "backward", "forward", and "front" */ 99 | arrange(arrangeMode: string): void; 100 | 101 | /** Performs a break-apart operation on the current */ 102 | breakApart(): void; 103 | 104 | /** Indicates whether the Edit Symbols menu and */ 105 | canEditSymbol(): boolean; 106 | 107 | /** Determines whether you can use the */ 108 | canRevert(): boolean; 109 | 110 | ///** Determines whether a version of the specified */ 111 | //canSaveAVersion(): boolean; 112 | 113 | /** Determines whether you can use the */ 114 | canTestMovie(): boolean; 115 | 116 | /** Determines whether you can use the */ 117 | canTestScene(): boolean; 118 | 119 | /** Changes the index of the filter in the Filter list. */ 120 | changeFilterOrder(oldIndex: number, newIndex: number): void; 121 | 122 | /** Copies the current selection from the document */ 123 | clipCopy(): void; 124 | 125 | /** Cuts the current selection from the document */ 126 | clipCut(): void; 127 | 128 | /** Pastes the contents of the Clipboard into the document. */ 129 | clipPaste(bInPlace?: boolean): void; 130 | 131 | /** Closes the specified document. */ 132 | close(bPromptToSaveChanges?: boolean): void; 133 | 134 | /** Converts lines to fills on the selected objects. */ 135 | convertLinesToFills(): void; 136 | 137 | /** Converts the selected Stage item(s) to a new */ 138 | convertToSymbol(type: string, name: string, registrationPoint: string): FlashSymbolInstance; 139 | 140 | convertSelectionToBitmap(); 141 | 142 | /** Uses the top selected drawing object to crop all */ 143 | crop(): void; 144 | 145 | /** Method; Invokes the Debug Movie command on the document. */ 146 | debugMovie(abortIfErrorsExist?: boolean): void; 147 | 148 | /** Deletes the envelope (bounding box that */ 149 | deleteEnvelope(): boolean; 150 | 151 | /** Deletes the currently active profile, if there is */ 152 | deletePublishProfile(): boolean; 153 | 154 | /** Deletes the current scene (Timeline object), and */ 155 | deleteScene(): boolean; 156 | 157 | /** Deletes the current selection on the Stage. */ 158 | deleteSelection(): void; 159 | 160 | /** Disables all filters on the selected objects. */ 161 | disableAllFilters(): void; 162 | 163 | /** Disables the specified filter in the Filters list. */ 164 | disableFilter(filterIndex: number): void; 165 | 166 | /** Disables all filters except the one at the specified */ 167 | disableOtherFilters(enabledFilterIndex: number): void; 168 | 169 | /** Distributes the selection. */ 170 | distribute(distributemode: string, bUseDocumentBounds?: boolean): void; 171 | 172 | /** Performs a distribute-to-layers operation on the */ 173 | distributeToLayers(): void; 174 | 175 | /** Checks the document for persistent data with the */ 176 | documentHasData(name: string): boolean; 177 | 178 | /** Duplicates the currently active profile and gives */ 179 | duplicatePublishProfile(profileName?: string): number; 180 | 181 | /** Makes a copy of the currently selected scene, */ 182 | duplicateScene(): boolean; 183 | 184 | /** Duplicates the selection on the Stage. */ 185 | duplicateSelection(): void; 186 | 187 | /** Makes the specified scene the currently selected */ 188 | editScene(index: number): void; 189 | 190 | /** Enables all the filters on the Filters list for the */ 191 | enableAllFilters(): void; 192 | 193 | /** Enables the specified filter for the selected */ 194 | enableFilter(filterIndex: number): void; 195 | 196 | /** Switches the authoring tool into the editing mode */ 197 | enterEditMode(editMode?: string): void; 198 | 199 | /** Exits from symbol-editing mode and returns */ 200 | exitEditMode(): void; 201 | 202 | exportInstanceToLibrary(frameNumber:number, bitmapName:string); 203 | 204 | /** Exports the document as one or more PNG files. */ 205 | exportPNG(fileURI: string, bCurrentPNGSettings?: boolean, bCurrentFrame?: boolean): boolean; 206 | 207 | /** Exports the currently active profile to an XML */ 208 | exportPublishProfile(fileURI: string): void; 209 | 210 | /** returns a string that specifies, in XML format, the specified profile. If you don't pass a value for profileName, the current profile is exported. */ 211 | exportPublishProfileString(profileName?: string): string; 212 | 213 | /** Exports the document in the Flash SWF format. */ 214 | exportSWF(fileURI: string, bCurrentSettings?: boolean): void; 215 | 216 | /** Identical to retrieving the value of the To Stage */ 217 | getAlignToDocument(): boolean; 218 | 219 | /** Returns a string that specifies the blending mode */ 220 | getBlendMode(): string; 221 | 222 | /** Retrieves the fill object of the selected shape, or */ 223 | getCustomFill(objectToFill?: string): FlashFill; 224 | 225 | /** Returns the stroke object of the selected shape, */ 226 | getCustomStroke(locationOfStroke?: string): FlashStroke; 227 | 228 | /** Retrieves the value of the specified data. */ 229 | getDataFromDocument(name: string): any; 230 | 231 | /** Gets the specified Element property for the */ 232 | getElementProperty(propertyName: string): any; 233 | 234 | /** Gets a specified TextAttrs property of the*/ 235 | getElementTextAttr(attrName: string, startIndex?: number, endIndex?: number): FlashTextAttrs; 236 | 237 | /** Returns an array that contains the list of filters*/ 238 | getFilters(): FlashFilter[]; 239 | 240 | /** Returns a string containing the XML metadata */ 241 | getMetadata(): string; 242 | 243 | /** returns the mobile XML settings for the document. */ 244 | getMobileSettings(): string; 245 | 246 | /** Returns a string that represents the targeted */ 247 | getPlayerVersion(): string; 248 | 249 | /** Gets the bounding rectangle of the current */ 250 | getSelectionRect(): FlashRectangle; 251 | 252 | /** Gets the currently selected text. */ 253 | getTextString(startIndex?: number, endIndex?: number): string; 254 | 255 | /** Retrieves the current Timeline object in the */ 256 | getTimeline(): FlashTimeline; 257 | 258 | /** gets the location of the transformation point of the current selection. You can use the transformation point for commutations such as rotate and skew. */ 259 | getTransformationPoint(): FlashPoint; 260 | 261 | /** Converts the current selection to a group.*/ 262 | group(): void; 263 | 264 | /** Imports a file into the document. */ 265 | importFile(fileURI: string, importToLibrary?: boolean): void; 266 | 267 | /** Imports a profile from a file. */ 268 | importPublishProfile(fileURI: string): number; 269 | 270 | /** imports an XML string that represents a publish profile and sets it as the current profile. To generate an XML string to import, use document.exportPublishProfileString() before using this method. */ 271 | importPublishProfileString(xmlString: string): number; 272 | 273 | /** Imports a SWF file into the document.*/ 274 | importSWF(fileURI: string): void; 275 | 276 | /** creates an intersection drawing object from all selected drawing objects. This method returns false if there are no drawing objects selected, or if any of the selected items are not drawing objects. */ 277 | intersect(): boolean; 278 | 279 | /** loads a cue point XML file. The format and DTD of the XML file is the same as the one imported and exported by the Cue Points Property inspector. The return value is the same as the string serialized in the Cue Point property of the object containing the instance of an FLVPlayback Component. */ 280 | loadCuepointXML(uri: string): any[]; 281 | 282 | /** Makes the size of the selected objects the same. */ 283 | match(bWidth: boolean, bHeight: boolean, bUseDocumentBounds?: boolean): void; 284 | 285 | /** Performs a mouse click from the Selection tool. */ 286 | mouseClick(position: FlashPoint, bToggleSel: boolean, bShiftSel: boolean): void; 287 | 288 | /** Performs a double mouse click from the */ 289 | mouseDblClk(position: FlashPoint, bAltDown: boolean, bShiftDown: boolean, bShiftSelect: boolean): void; 290 | 291 | /** If the selection contains at least one path with at */ 292 | moveSelectedBezierPointsBy(delta: FlashPoint): void; 293 | 294 | /** Moves selected objects by a specified distance. */ 295 | moveSelectionBy(distanceToMove: FlashPoint): void; 296 | 297 | /** Optimizes smoothing for the current selection, */ 298 | optimizeCurves(smoothing: number, bUseMultiplePasses: boolean): void; 299 | 300 | /** Publishes the document according to the active */ 301 | publish(): void; 302 | 303 | /** uses the top selected drawing object to punch through all selected drawing objects underneath it. This method returns false if there are no drawing objects selected or if any of the selected items are not drawing objects. */ 304 | punch(): boolean; 305 | 306 | /** Removes all filters from the selected object(s).*/ 307 | removeAllFilters(): void; 308 | 309 | /** Removes persistent data with the specified*/ 310 | removeDataFromDocument(name: string): void; 311 | 312 | /** Removes persistent data with the specified */ 313 | removeDataFromSelection(name: string): void; 314 | 315 | /** Removes the specified filter from the Filters list*/ 316 | removeFilter(filterIndex: number): void; 317 | 318 | /** Renames the current profile.*/ 319 | renamePublishProfile(profileNewName?: string): boolean; 320 | 321 | /** Renames the currently selected scene in the */ 322 | renameScene(name: string): boolean; 323 | 324 | /** Moves the specified scene before another */ 325 | reorderScene(sceneToMove: number, sceneToPutItBefore: number): void; 326 | 327 | /** Sets all values in the Property inspector to */ 328 | resetOvalObject(): void; 329 | 330 | /** Sets all values in the Property inspector to */ 331 | resetRectangleObject(): void; 332 | 333 | /** Resets the transformation matrix; equivalent to */ 334 | resetTransformation(): void; 335 | 336 | /** Method; reverts the specified document to its previously saved version. This method is equivalent to selecting File > Revert. */ 337 | revert(): void; 338 | 339 | ///** Reverts the specified document to the version */ 340 | //revertToLastVersion(); 341 | 342 | /** applies a 3D rotation to the selection. This method is available only for movie clips. */ 343 | rotate3DSelection(xyzCoordinate: FlashPoint3D, bGlobalTransform: boolean): void; 344 | 345 | /** Rotates the selection by a specified number of */ 346 | rotateSelection(angle: number, rotationPoint?: string): void; 347 | 348 | /** Saves the document in its default location;*/ 349 | save(bOkToSaveAs?: boolean): boolean; 350 | 351 | /** saves and compacts the file. This method is equivalent to selecting File > Save and Compact. */ 352 | saveAndCompact(bOkToSaveAs?: boolean): boolean; 353 | 354 | //saveAsVersion(); // Saves a version of the specified document to the 355 | 356 | /** Scales the selection by a specified amount;*/ 357 | scaleSelection(xScale: number, yScale: number, whichCorner?: string): void; 358 | 359 | /** Selects all items on the Stage; equivalent to*/ 360 | selectAll(): void; 361 | 362 | /** Deselects any selected items. */ 363 | selectNone(): void; 364 | 365 | /** Sets the preferences for document.align(),*/ 366 | setAlignToDocument(bToStage?: boolean): void; 367 | 368 | /** Sets the blending mode for the selected objects.*/ 369 | setBlendMode(mode: string): void; 370 | 371 | /** Sets the fill settings for the Tools panel, Property */ 372 | setCustomFill(fill: FlashFill): void; 373 | 374 | /** Sets the stroke settings for the Tools panel,*/ 375 | setCustomStroke(stroke: FlashStroke): void; 376 | 377 | /** Sets the specified Element property on selected */ 378 | setElementProperty(property: string, value: number): void; 379 | 380 | /** Sets the specified TextAttrs property of the */ 381 | setElementTextAttr(attrName: string, attrValue: FlashTextAttrs, startIndex?: number, endIndex?: number): boolean; 382 | 383 | /** Changes the fill color of the selection to the */ 384 | setFillColor(color: any): void; 385 | 386 | /** Sets a specified filter property for the currently */ 387 | setFilterProperty(property: string, filterIndex: number, value: any): void; 388 | 389 | /** Applies filters to the selected objects .*/ 390 | setFilters(filterArray: FlashFilter[]): void; 391 | 392 | /** Sets the opacity of the instance. */ 393 | setInstanceAlpha(opacity: number): void; 394 | 395 | /** Sets the brightness for the instance. */ 396 | setInstanceBrightness(brightness: number): void; 397 | 398 | /** Sets the tint for the instance.*/ 399 | setInstanceTint(color: any, strength: number): void; 400 | 401 | /** Sets the XML metadata for the specified */ 402 | setMetadata(strMetadata: string): boolean; 403 | 404 | /** Sets the value of an XML settings string in a */ 405 | setMobileSettings(xmlString: string): boolean; 406 | 407 | /** Specifies a value for a specified property of*/ 408 | setOvalObjectProperty(propertyName: string, value: any): void; 409 | 410 | /** Sets the version of the Flash Player targeted by*/ 411 | setPlayerVersion(version: string): boolean; 412 | 413 | /** Specifies a value for a specified property of*/ 414 | setRectangleObjectProperty(propertyName: string, value: any): void; 415 | 416 | /** Moves and resizes the selection in a single */ 417 | setSelectionBounds(boundingRectangle: FlashRectangle, bContactSensitiveSelection?: boolean): void; 418 | 419 | /** Draws a rectangular selection marquee relative */ 420 | setSelectionRect(rect: FlashRectangle, bReplaceCurrentSelection?: boolean, bContactSensitiveSelection?: boolean): void; 421 | 422 | /** Specifies the vanishing point for viewing 3D objects. */ 423 | setStageVanishingPoint(point: FlashPoint): void; 424 | 425 | setStageViewAngle(angle: number): void; 426 | 427 | /** Sets the color, width, and style of the selected */ 428 | setStroke(color: any, size: number, strokeType: string): void; 429 | 430 | /** Changes the stroke color of the selection to the*/ 431 | setStrokeColor(color: any): void; 432 | 433 | /** Changes the stroke size of the selection to the*/ 434 | setStrokeSize(size: number): void; 435 | 436 | /** Changes the stroke style of the selection to the */ 437 | setStrokeStyle(strokeType: string): void; 438 | 439 | /** Changes the bounding rectangle for the selected */ 440 | setTextRectangle(boundingRectangle: FlashRectangle): boolean; 441 | 442 | /** Sets the text selection of the currently selected */ 443 | setTextSelection(startIndex: number, endIndex: number): boolean; 444 | 445 | /** Inserts a string of text. */ 446 | setTextString(text: string, startIndex?: number, endIndex?: number): boolean; 447 | 448 | /** Moves the transformation point of the current */ 449 | setTransformationPoint(transformationPoint: FlashPoint): void; 450 | 451 | /** Skews the selection by a specified amount. */ 452 | skewSelection(xSkew: number, ySkew: number, whichEdge?: string): void; 453 | 454 | /** Smooths the curve of each selected fill outline or */ 455 | smoothSelection(): void; 456 | 457 | /** Spaces the objects in the selection evenly. */ 458 | space(direction: string, bUseDocumentBounds?: boolean): void; 459 | 460 | /** Straightens the currently selected strokes; */ 461 | straightenSelection(): void; 462 | 463 | /** Swaps the current selection with the specified */ 464 | swapElement(name: string): void; 465 | 466 | /** Swaps the Stroke and Fill colors. */ 467 | swapStrokeAndFill(): void; 468 | //synchronizeWithHeadVersion(); // Synchronizes the specified document with the 469 | 470 | /** Executes a Test Movie operation on the */ 471 | testMovie(): void; 472 | 473 | /** Executes a Test Scene operation on the current */ 474 | testScene(): void; 475 | 476 | /** Performs a trace bitmap on the current selection; */ 477 | traceBitmap(threshold: number, minimumArea: number, curveFit: string, cornerThreshold: string): void; 478 | transformSelection(a: number, b: number, c: number, d: number): void; // Performs a general transformation on the current 479 | unGroup(): void; // Ungroups the current selection. 480 | union(): void; // Combines all selected shapes into a drawing 481 | unlockAllElements(): void; // Unlocks all locked elements on the currently 482 | xmlPanel(fileURI: string): any; // Posts a XMLUI dialog box. 483 | accName: string; // A string that is equivalent to the Name field in the 484 | as3AutoDeclare: boolean; // A Boolean value that describes whether the 485 | as3Dialect: string; // A string that describes the ActionScript 3.0 486 | as3ExportFrame: number; // An integer that specifies in which frame to export 487 | as3StrictMode: boolean; // A Boolean value that specifies whether the 488 | as3WarningsMode: boolean; // A Boolean value that specifies whether the 489 | asVersion: number; // An integer that specifies which version of 490 | autoLabel: boolean; // A Boolean value that is equivalent to the Auto 491 | backgroundColor: any; // A string, hexadecimal value, or integer that 492 | currentPublishProfile: string; // A string that specifies the name of the active 493 | currentTimeline: FlashTimeline; // An integer that specifies the index of the active 494 | description: string; // A string that is equivalent to the Description field in 495 | docClass; // Specifies the top-level ActionScript 3.0 class 496 | forceSimple: boolean; // A Boolean value that specifies whether the children 497 | frameRate: number; // A float value that specifies the number of frames 498 | height: number; // An integer that specifies the height of the 499 | id: number; // A unique integer (assigned automatically) that 500 | library: FlashLibrary; // Read-only; the library object for a document. 501 | livePreview: boolean; // A Boolean value that specifies if Live Preview is 502 | name: string; // Read-only; a string that represents the name of a 503 | path: string; // Read-only; a string that represents the path of the 504 | pathURI: string; // Read-only property; a string that represents the path of the document, expressed as a file:/// URI. If the document has never been saved, this property is undefined. 505 | publishProfiles: string[]; // Read-only; an array of the publish profile names for 506 | 507 | /** Read-only; the current ScreenOutline object for the */ 508 | // Not available in CS5 509 | //screenOutline: FlashScreenOutline; 510 | 511 | /** An array of the selected objects in the document. */ 512 | selection: FlashElement[]; 513 | 514 | /** A Boolean value that specifies whether the object */ 515 | silent: boolean; 516 | 517 | /** Read-only; an array of Timeline objects (see */ 518 | timelines: FlashTimeline[]; 519 | 520 | /** Read-only; a Matrix object. */ 521 | viewMatrix: FlashMatrix; 522 | 523 | /** An integer that specifies the width of the document */ 524 | width: number; 525 | 526 | /** Specifies the zoom percent of the Stage at author */ 527 | zoomFactor: number; 528 | } 529 | 530 | interface FlashText { 531 | getTextAttr(); 532 | getTextString(); 533 | setTextAttr(); 534 | setTextString(); 535 | accName: string; 536 | antiAliasSharpness: number; 537 | antiAliasThickness: number; 538 | autoExpand: boolean; 539 | border: boolean; 540 | description: string; 541 | embeddedCharacters: string; 542 | } 543 | 544 | interface FlashTextAttrs extends FlashText { 545 | aliasText: boolean; 546 | alignment: string; 547 | autoKern: boolean; 548 | bold: boolean; 549 | characterPosition: string; 550 | characterSpacing: number; 551 | face: string; 552 | fillColor: any; 553 | indent: number; 554 | italic: boolean; 555 | leftMargin: number; 556 | letterSpacing: number; 557 | lineSpacing: number; 558 | rightMargin: number; 559 | rotation: boolean; 560 | size: number; 561 | target: string; 562 | url: string; 563 | } 564 | 565 | interface FlashFLfile { 566 | copy(fileURI:string, copyURI:string): boolean; 567 | createFolder(folderURI:string): boolean; 568 | exists(fileURI:string): boolean; 569 | getAttributes(fileOrFolderURI:string): string; 570 | getCreationDate(fileOrFolderURI:string): string; 571 | getCreationDateObj(fileOrFolderURI:string): Date; 572 | getModificationDate(fileOrFolderURI:string): string; 573 | getModificationDateObj(fileOrFolderURI: string): Date; 574 | getSize(fileURI: string): number; 575 | listFolder(folderURI: string, filesOrDirectories?: string): string[]; 576 | platformPathToURI(fileName: string): string; 577 | read(fileOrFolderURI: string): string; 578 | remove(fileOrFolderURI: string): boolean; 579 | setAttributes(fileURI: string, strAttrs: string): boolean; 580 | uriToPlatformPath(fileURI: string): string; 581 | write(fileURI: string, textToWrite: string, strAppendMode?: string): boolean; 582 | runCommandLine(command: string): object; 583 | } 584 | 585 | interface FlashSoundItem { 586 | } 587 | 588 | // if FlashElement.elementType == 'instance' 589 | interface FlashInstance extends FlashElement { 590 | instanceType?: string; 591 | libraryItem?: FlashItem; 592 | } 593 | 594 | interface _FlashBitmap { 595 | width; height; depth; bits; cTab?: string[]; 596 | } 597 | 598 | // if FlashElement.elementType == 'instance' 599 | interface FlashBitmapInstance extends Element { 600 | getBits(): _FlashBitmap; 601 | setBits(bitmap: _FlashBitmap): void; 602 | hPixels: number; 603 | vPixels: number; 604 | 605 | } 606 | 607 | interface FlashCompiledClipInstance extends FlashElement { 608 | accName: string; 609 | actionScript: string; 610 | description: string; 611 | forceSimple: boolean; 612 | shortcut: string; 613 | silent: boolean; 614 | tabIndex: number; 615 | } 616 | 617 | interface FlashSymbolInstance extends FlashElement { 618 | accName: string; 619 | actionScript: string; 620 | backgroundColor: string; 621 | bitmapRenderMode: string; 622 | blendMode: string; 623 | buttonTracking: string; 624 | cacheAsBitmap: boolean; 625 | colorAlphaAmount: number; 626 | colorAlphaPercent: number; 627 | colorBlueAmount: number; 628 | colorBluePercent: number; 629 | colorGreenAmount: number; 630 | colorGreenPercent: number; 631 | colorMode: string; 632 | colorRedAmount: number; 633 | colorRedPercent: number; 634 | description: string; 635 | filters: FlashFilter[]; 636 | firstFrame: number; 637 | forceSimple: boolean; 638 | loop: string; 639 | shortcut: string; 640 | silent: boolean; 641 | symbolType: string; 642 | tabIndex: number; 643 | useBackgroundColor: boolean; 644 | visible: boolean; 645 | } 646 | 647 | interface FlashComponentInstance extends FlashElement { 648 | parameters: any[]; 649 | } 650 | 651 | /** 652 | * The Shape object is a subclass of the Element object. The Shape object provides more precise control 653 | * than the drawing APIs when manipulating or creating geometry on the Stage. This control is necessary 654 | * so that scripts can create useful effects and other drawing commands (seeElement object). 655 | * All Shape methods and properties that change a shape or any of its subordinate parts must be placed between 656 | * shape.beginEdit() and shape.endEdit() calls to function correctly. 657 | */ 658 | interface FlashShape extends FlashElement { 659 | getCubicSegmentPoints(cubicSegmentIndex: number): FlashPoint[]; 660 | beginEdit(): void; 661 | deleteEdge(index: number): void; 662 | endEdit(): void; 663 | contours: FlashContour[]; 664 | edges: FlashEdge[]; 665 | isDrawingObject: boolean; 666 | isGroup: boolean; 667 | isFloating: boolean; 668 | isOvalObject: boolean; 669 | isRectangleObject: boolean; 670 | members: FlashShape[]; 671 | numCubicSegments: number; 672 | vertices: FlashVertex[]; 673 | } 674 | 675 | interface FlashElement { 676 | getPersistentData(name: string): any; 677 | getTransformationPoint(): FlashPoint; 678 | hasPersistentData(name:string): boolean; 679 | removePersistentData(name:string): void; 680 | setPersistentData(name:string, type:string, value: any):void; 681 | setTransformationPoint(transformationPoint: FlashPoint): void; 682 | depth: number; 683 | 684 | /** 685 | * Read-only property; a string that represents the type of the specified element. 686 | * The value is one of the following: "shape", "text", "instance", or "shapeObj". 687 | * A "shapeObj" is created with an extensible tool. 688 | */ 689 | elementType: FlashElementType; 690 | height: number; 691 | layer: FlashLayer; 692 | left: number; 693 | locked: boolean; 694 | matrix: FlashMatrix; 695 | name: string; 696 | rotation: number; 697 | scaleX: number; 698 | scaleY: number; 699 | selected: boolean; 700 | skewX: number; 701 | skewY: number; 702 | top: number; 703 | transformX: number; 704 | transformY: number; 705 | width: number; 706 | x: number; 707 | y: number; 708 | } 709 | 710 | interface FlashFrame { 711 | getCustomEase(); 712 | setCustomEase(); 713 | actionScript; 714 | duration; 715 | elements: FlashElement[]; 716 | hasCustomEase; 717 | labelType; 718 | motionTweenOrientToPath; 719 | motionTweenRotate; 720 | motionTweenRotateTimes; 721 | motionTweenScale; 722 | motionTweenSnap; 723 | motionTweenSync; 724 | name; 725 | shapeTweenBlend; 726 | soundEffect; 727 | soundLibraryItem:FlashSoundItem; 728 | soundLoop; 729 | soundLoopMode; 730 | soundName; 731 | soundSync; 732 | startFrame; 733 | tweenEasing; 734 | tweenType; 735 | useSingleEaseCurve; 736 | } 737 | 738 | interface FlashSymbolItem extends FlashItem { 739 | convertToCompiledClip(): void; 740 | exportSWC(outputURI: string): void; 741 | exportSWF(outputURI: string): void; 742 | scalingGrid: boolean; 743 | scalingGridRect: FlashRectangle; 744 | sourceAutoUpdate: boolean; 745 | sourceFilePath: string; 746 | sourceLibraryName: string; 747 | symbolType: string; 748 | timeline: FlashTimeline; 749 | } 750 | 751 | interface FlashFolderItem extends FlashItem { 752 | } 753 | 754 | interface FlashFontItem extends FlashItem { 755 | // Specifies whether the Font item is bitmapped. 756 | bitmap: boolean; 757 | // Specifies whether the Font item is bold. 758 | bold: boolean; 759 | // Specifies characters to embed. 760 | embeddedCharacters: string; 761 | // Specifies items that can be selected in the Font Embedding dialog. 762 | embedRanges: string; 763 | // Specifies whether variant glyphs should be output in the font when publishing a SWF file. 764 | embedVariantGlyphs: boolean; 765 | // The name of the device font associated with the Font item. 766 | font: string; 767 | // Specifies the format of the font that is output when publishing a SWF filem. 768 | isDefineFont4Symbol: boolean; 769 | // Specifies whether the Font item is italic. 770 | italic: boolean; 771 | // The size of the Font item, in points. 772 | size: number; 773 | } 774 | 775 | interface FlashSoundItem extends FlashItem { 776 | exportToFile(fileURI: string): boolean; 777 | bitRate: string; 778 | bits: string; 779 | compressionType: string; 780 | convertStereoToMono: boolean; 781 | fileLastModifiedDate: string; 782 | originalCompressionType: string; 783 | quality: string; 784 | sampleRate: string; 785 | sourceFileExists: boolean; 786 | } 787 | 788 | interface FlashVideoItem extends FlashItem { 789 | exportToFLV(fileURI: string): boolean; 790 | fileLastModifiedDate: string; 791 | sourceFileExists: boolean; 792 | sourceFileIsCurrent: boolean; 793 | sourceFilePath: string; 794 | videoType: string; 795 | } 796 | 797 | interface FlashBitmapItem extends FlashItem { 798 | exportToFile(fileURI: string): boolean; 799 | allowSmoothing: boolean; 800 | compressionType: string; 801 | fileLastModifiedDate: string; 802 | originalCompressionType: string; 803 | sourceFileExists: boolean; 804 | sourceFileIsCurrent: boolean; 805 | sourceFilePath: string; 806 | useDeblocking: boolean; 807 | useImportedJPEGQuality: boolean; 808 | hPixels: number; 809 | vPixels: number; 810 | } 811 | 812 | interface FlashItem { 813 | addData(name: string, type: string, data: any): void; 814 | getData(name: string): any; 815 | hasData(name: string): boolean; 816 | removeData(name: string): void; 817 | 818 | /** Read-only; a string that specifies the type of element. "undefined", "component", "movie clip", "graphic", "button", "folder", "font", "sound", "bitmap", "compiled clip", "screen", or "video" */ 819 | itemType: FlashItemType; 820 | linkageBaseClass: string; 821 | linkageClassName: string; 822 | linkageExportForAS: boolean; 823 | linkageExportForRS: boolean; 824 | linkageExportInFirstFrame: boolean; 825 | linkageIdentifier: string; 826 | linkageImportForRS: boolean; 827 | linkageURL: string; 828 | /** A string that specifies the name of the library item, which includes the folder structure. */ 829 | name: string; 830 | } 831 | 832 | interface FlashLayer { 833 | color: any; 834 | frameCount: number; 835 | frames: FlashFrame[]; 836 | height: number; 837 | layerType: FlashLayerType; 838 | locked: boolean; 839 | name: string; 840 | outline: boolean; 841 | parentLayer: FlashLayer; 842 | visible:boolean; 843 | } 844 | 845 | interface FlashLibrary { 846 | addItemToDocument(position: FlashPoint, namePath?: string): boolean; 847 | /** "video", "movie clip", "button", "graphic", "bitmap", "screen", and "folder" */ 848 | addNewItem(type: string, namePath?: string): boolean; 849 | deleteItem(namePath?: string): boolean; 850 | /** Method; makes a copy of the currently selected or specified item. The new item has a default name (such as item copy) and is set as the currently selected item. If more than one item is selected, the command fails. */ 851 | duplicateItem(namePath: string): boolean; 852 | editItem(namePath?: string): boolean; 853 | expandFolder(bExpand: boolean, bRecurseNestedParents?: boolean, namePath?: string): boolean; 854 | findItemIndex(namePath: string): number; 855 | getItemProperty(property: string): string; 856 | getItemType(namePath?: string): string; 857 | 858 | /** An array of values for all currently selected items in the library. */ 859 | getSelectedItems(): FlashItem[]; 860 | 861 | importEmbeddedSWF(linkageName: string, swfData: any[], libName?: string): void; 862 | 863 | itemExists(namePath: string): boolean; 864 | 865 | moveToFolder(folderPath: string, itemToMove?: string, bReplace?: boolean): boolean; 866 | 867 | /** Method; creates a new folder with the specified name, or a default name ("untitled folder #" ) if no folderName parameter is provided, in the currently selected folder. */ 868 | newFolder(folderPath?: string): boolean; 869 | 870 | /** Method; renames the currently selected library item in the Library panel. */ 871 | renameItem(name: string): boolean; 872 | 873 | /** Method; selects or deselects all items in the library. */ 874 | selectAll(bSelectAll?: boolean): void; 875 | 876 | /** Method; selects a specified library item. */ 877 | selectItem(namePath: string, bReplaceCurrentSelection?: boolean, bSelect?: boolean): boolean; 878 | 879 | /** Method; deselects all the library items. */ 880 | selectNone(): void; 881 | 882 | /** Method; sets the property for all selected library items (ignoring folders). */ 883 | setItemProperty(property: string, value: any): void; 884 | 885 | /** Method; updates the specified item. */ 886 | updateItem(namePath: string): boolean; 887 | 888 | /** Property; an array of item objects in the library. */ 889 | items: FlashItem[]; 890 | } 891 | 892 | interface FlashMath { 893 | /** Method; performs a matrix concatenation and returns the result. */ 894 | concatMatrix(mat1: FlashMatrix, mat2: FlashMatrix): FlashMatrix; 895 | 896 | /** A Matrix object that is the inverse of the original matrix. */ 897 | invertMatrix(mat: FlashMatrix): FlashMatrix; 898 | 899 | /** A floating-point value that represents the distance between the points. */ 900 | pointDistance(pt1: FlashPoint, pt2: FlashPoint): number; 901 | } 902 | 903 | interface FlashOutputPanel { 904 | /** Method; clears the contents of the Output panel. You can use this method in a batch processing application to clear a list of errors, or to save them incrementally by using this method withoutputPanel.save(). */ 905 | clear(): void; 906 | 907 | save(fileURI: string, bAppendToFile?: boolean, bUseSystemEncoding?: boolean): void; 908 | 909 | trace(message:string):void; 910 | } 911 | 912 | /** 913 | * The HalfEdge object is the directed side of the edge of a Shape object. 914 | * An edge has two half edges. You can transverse the contours of a shape by "walking around" 915 | * these half edges. For example, starting from a half edge, you can trace all the half edges 916 | * around a contour of a shape, and return to the original half edge. Half edges are ordered. 917 | * One half edge represents one side of the edge; the other half edge represents the other side. 918 | */ 919 | interface FlashHalfEdge { 920 | getEdge(): FlashEdge; 921 | getNext(): FlashHalfEdge; 922 | getOppositeHalfEdge(): FlashHalfEdge; 923 | getPrev(): FlashHalfEdge; 924 | getVertex(): FlashVertex; 925 | id: number; 926 | index: number; 927 | } 928 | 929 | /** The Oval object is a shape that is drawn using the Oval Primitive tool. To determine if an item is an Oval object, use shape.isOvalObject. */ 930 | interface FlashOval extends FlashShape { 931 | /** Read-only property; a Boolean value that specifies whether the Close Path check box in the Property inspector is selected. If the start angle and end angle values for the object are the same, setting this property has no effect until the values change. To set this value, use document.setOvalObjectProperty(). */ 932 | closePath: boolean; 933 | /** Read-only property; a float value that specifies the end angle of the Oval object. Acceptable values are from 0 to 360. */ 934 | endAngle: number; 935 | /** Read-only property; a float value that specifies the inner radius of the Oval object as a percentage. Acceptable values are from 0 to 99. */ 936 | innerRadius: number; 937 | /** Read-only property; a float value that specifies the start angle of the Oval object. Acceptable values are from 0 to 360. To set this value, use document.setOvalObjectProperty(). */ 938 | startAngle: number; 939 | } 940 | 941 | /** 942 | * This object contains all the properties of the Fill color setting of the Tools panel or of a selected shape. To retrieve a Fill object, use document.getCustomFill(). 943 | */ 944 | interface FlashFill { 945 | bitmapIsClipped: boolean; 946 | bitmapPath: string; 947 | /** Property; the color of the fill, in one of the following formats: 948 | * - A string in the format "#RRGGBB" or "#RRGGBBAA" 949 | * - A hexadecimal number in the format 0xRRGGBB 950 | * - An integer that represents the decimal equivalent of a hexadecimal number 951 | */ 952 | color: any; 953 | /** Property; an array of colors in the gradient, expressed as integers. This property is available only if the value of the fill.style property is either "radialGradient" or "linearGradient". See fill.style */ 954 | colorArray: any[]; 955 | focalPoint: number; 956 | linearRGB: boolean; 957 | matrix: FlashMatrix; 958 | overflow: string; 959 | posArray: number[]; 960 | style: string; 961 | } 962 | 963 | interface FlashContour { 964 | getHalfEdge(): FlashHalfEdge; 965 | fill: FlashFill; 966 | interior: boolean; 967 | orientation: number; 968 | } 969 | 970 | interface FlashStroke { 971 | /// A Boolean value, same as the Sharp Corners setting in the custom Stroke Style dialog box. 972 | breakAtCorners: boolean; 973 | /// A string that specifies the type of cap for the stroke. 974 | capType: string; 975 | /// A string, hexadecimal value, or integer that represents the stroke color. 976 | color: any; 977 | /// A string that specifies the type of hatching for the stroke. 978 | curve: string; 979 | /// An integer that specifies the lengths of the solid part of a dashed line. 980 | dash1: number; 981 | /// An integer that specifies the lengths of the blank part of a dashed line. 982 | dash2: number; 983 | /// A string that specifies the density of a stippled line. 984 | density: string; 985 | /// A string that specifies the dot size of a stippled line. 986 | dotSize: string; 987 | /// An integer that specifies the spacing between dots in a dotted line. 988 | dotSpace: number; 989 | /// A string that specifies the thickness of a hatch line. 990 | hatchThickness: string; 991 | /// A string that specifies the jiggle property of a hatched line. 992 | jiggle: string; 993 | /// A string that specifies the type of join for the stroke. 994 | joinType: string; 995 | /// A string that specifies the length of a hatch line. 996 | length: string; 997 | /// A float value that specifies the angle above which the tip of the miter will be truncated by a segment. 998 | miterLimit: number; 999 | /// A string that specifies the pattern of a ragged line. 1000 | pattern: string; 1001 | /// A string that specifies the rotation of a hatch line. 1002 | rotate: string; 1003 | /// A string that specifies the type of scale to be applied to the stroke. 1004 | scaleType: string; 1005 | /// A Fill object that represents the fill settings of the stroke. 1006 | shapeFill: FlashFill; 1007 | /// A string that specifies the spacing of a hatched line. 1008 | space: string; 1009 | /// A Boolean value that specifies whether stroke hinting is set on the stroke. 1010 | strokeHinting: boolean; 1011 | /// A string that describes the stroke style. 1012 | style: string; 1013 | /// An integer that specifies the stroke size. 1014 | thickness: number; 1015 | /// A string that specifies the variation of a stippled line. 1016 | variation: string; 1017 | /// A string that specifies the wave height of a ragged line. 1018 | waveHeight: string; 1019 | /// A string that specifies the wave length of a ragged line. 1020 | waveLength: string; 1021 | } 1022 | 1023 | interface FlashEdge { 1024 | getControl(i: number): FlashPoint; 1025 | getHalfEdge(index: number): FlashHalfEdge; 1026 | setControl(index: number, x:number, y:number): void; 1027 | splitEdge(t: number): void; 1028 | cubicSegmentIndex: number; 1029 | id: number; 1030 | isLine: boolean; 1031 | stroke: FlashStroke; 1032 | } 1033 | 1034 | interface FlashVertex { 1035 | getHalfEdge(): FlashHalfEdge; 1036 | setLocation(x: number, y: number); 1037 | x: number; 1038 | y: number; 1039 | } 1040 | 1041 | 1042 | interface FlashTimeline { 1043 | /** Adds a motion guide layer above the current layer and attaches the current layer to the newly added guide layer. */ 1044 | addMotionGuide(): number; 1045 | 1046 | /** Adds a new layer to the document and makes it the current layer. */ 1047 | addNewLayer(name?: string, layerType?: string, bAddAbove?: boolean); 1048 | 1049 | /** Deletes all the contents from a frame or range of frames on the current layer. */ 1050 | clearFrames(startFrameIndex?: number, endFrameIndex?: number): void; 1051 | 1052 | /** Converts a keyframe to a regular frame and deletes its contents on the current layer. */ 1053 | clearKeyframes(startFrameIndex?: number, endFrameIndex?: number): void; 1054 | 1055 | /** Converts frames to blank keyframes on the current layer. */ 1056 | convertToBlankKeyframes(startFrameIndex?: number, endFrameIndex?: number): void; 1057 | 1058 | /** Converts a range of frames to keyframes (or converts the selection if no frames are specified) on the current layer. */ 1059 | convertToKeyframes(startFrameIndex?: number, endFrameIndex?: number): void; 1060 | 1061 | /** Copies a range of frames on the current layer to the clipboard. */ 1062 | copyFrames(startFrameIndex?: number, endFrameIndex?: number): void; 1063 | 1064 | /** Copies a range of Timeline layers to the clipboard. */ 1065 | copyLayers(startFrameIndex?: number, endFrameIndex?: number): void; 1066 | 1067 | /** Copies motion on selected frames, either from a motion tween or from frame - by - frame animation, so it can be applied to other frames. */ 1068 | copyMotion(): void; 1069 | 1070 | /** Copies motion on selected frames, either from a motion tween or from frame - by - frame animation, to the clipboard as ActionScript 3.0 code. */ 1071 | copyMotionAsAS3(): void; 1072 | 1073 | /** Creates a new motion object at a designated start and end frame. */ 1074 | createMotionObject(startFrameIndex?: number, endFrameIndex?: number): void; 1075 | 1076 | /** Sets the frame.tweenType property to motion for each selected keyframe on the current layer, and converts each frame's contents to a single symbol instance if necessary. */ 1077 | createMotionTween(startFrameIndex?: number, endFrameIndex?: number): void; 1078 | 1079 | /** Cuts a range of frames on the current layer from the timeline and saves them to the clipboard. */ 1080 | cutFrames(startFrameIndex?: number, endFrameIndex?: number): void; 1081 | 1082 | /** Cuts a range of Timeline layers and saves them to the clipboard. */ 1083 | cutLayers(startLayerIndex?: number, endLayerIndex?: number): void; 1084 | 1085 | /** Deletes a layer. */ 1086 | deleteLayer(index: number): void; 1087 | 1088 | /** Duplicates the selected layers or specified layers. */ 1089 | duplicateLayers(startFrameIndex?: number, endFrameIndex?: number): void; 1090 | 1091 | /** Expands or collapses the specified folder or folders. */ 1092 | expandFolder(bExpand: boolean, bRecurseNestedParents?: boolean, index?: number): void; 1093 | 1094 | /** Finds an array of indexes for the layers with the given name. */ 1095 | findLayerIndex(name: string): number[]; 1096 | 1097 | /** Retrieves the specified property's value for the selected frames. */ 1098 | getFrameProperty(property: string, startframeIndex?: number, endFrameIndex?: number): any; 1099 | 1100 | /** Returns an XML string that represents the current positions of the horizontal and vertical guide lines for a timeline(View > Guides > Show Guides). */ 1101 | getGuidelines(): string; 1102 | 1103 | /** Retrieves the specified property's value for the selected layers. */ 1104 | getLayerProperty(property: string): any; 1105 | 1106 | /** Retrieves the currently selected frames in an array. */ 1107 | getSelectedFrames(): FlashFrame[]; 1108 | 1109 | /** Retrieves the zero - based index values of the currently selected layers. */ 1110 | getSelectedLayers(): FlashLayer[]; 1111 | 1112 | /** Inserts a blank keyframe at the specified frame index; if the index is not specified, inserts the blank keyframe by using the playhead / selection. */ 1113 | insertBlankKeyframe(frameNumIndex?: number): void; 1114 | 1115 | /** Inserts the specified number of frames at the given frame number. */ 1116 | insertFrames(numFrames?: number, bAllLayers?: boolean, frameNumIndex?: number): void; 1117 | 1118 | /** Inserts a keyframe at the specified frame. */ 1119 | insertKeyframe(frameNumIndex?: number): void; 1120 | 1121 | /** Pastes the range of frames from the clipboard into the specified frames. */ 1122 | pasteFrames(startFrameIndex?: number, endFrameIndex?: number): void; 1123 | 1124 | /** Pastes copied layers to the Timeline above the specified layer index. */ 1125 | pasteLayers(layerIndex: number): number; 1126 | 1127 | /** Pastes the range of motion frames retrieved by */ 1128 | pasteMotion(): void; 1129 | 1130 | /** Deletes the frame. */ 1131 | removeFrames(startFrameIndex?: number, endFrameIndex?: number): void; 1132 | 1133 | /** Removes the motion object created with timeline.createMotionObject(), and converts the frame(s) to static frames. */ 1134 | removeMotionObject(startFrame: number, endFrame: number):void 1135 | 1136 | /** Moves the first specified layer before or after the second specified layer. */ 1137 | reorderLayer(layerToMove: number, layerToPutItBy: number, bAddBefore?: boolean): void; 1138 | 1139 | /** Reverses a range of frames. */ 1140 | reverseFrames(startFrameIndex?: number, endFrameIndex?: number): void 1141 | 1142 | /** Selects all the frames in the current timeline. */ 1143 | selectAllFrames(): void; 1144 | 1145 | /** Sets the property of the Frame object for the selected frames. */ 1146 | setFrameProperty(property: string, value: any, startFrameIndex?: number, endFrameIndex?: number): void; 1147 | 1148 | /** Replaces the guide lines for the timeline with the information specified. */ 1149 | setGuidelines(xmlString: string): boolean; 1150 | 1151 | /** Sets the specified property on all the selected layers to a specified value. */ 1152 | setLayerProperty(property: string, value: any, layersToChange?: string): void; 1153 | 1154 | /** Selects a range of frames in the current layer or sets the selected frames to the selection array passed into this method. */ 1155 | setSelectedFrames(startFrameIndex: number, endFrameIndex: number, bReplaceCurrentSelection?: boolean): void; 1156 | setSelectedFrames(selectionList: number[], bReplaceCurrentSelection?: boolean): void; 1157 | 1158 | /** Sets the layer to be selected; also makes the specified layer the current layer. */ 1159 | setSelectedLayers(index: number, bReplaceCurrentSelection?: boolean): void; 1160 | 1161 | /** Shows the layer masking during authoring by locking the mask and masked layers. */ 1162 | showLayerMasking(layer: number): void; 1163 | 1164 | /** Starts automatic playback of the timeline if it is not currently playing. */ 1165 | startPlayback(): void; 1166 | 1167 | /** Stops autoumatic playback of the timeline if it is currently playing. */ 1168 | stopPlayback(): void; 1169 | 1170 | /** A zero-based index for the frame at the current */ 1171 | currentFrame: number; 1172 | 1173 | /** A zero-based index for the currently active layer. */ 1174 | currentLayer: number; 1175 | 1176 | /** Read-only; an integer that represents the number of */ 1177 | frameCount: number; 1178 | 1179 | /** Read-only; an integer that represents the number of */ 1180 | layerCount: number; 1181 | 1182 | /** Read-only; an array of layer objects. */ 1183 | layers: FlashLayer[]; 1184 | 1185 | /** A string that represents the name of the current */ 1186 | name: string; 1187 | 1188 | libraryItem:FlashItem; 1189 | } 1190 | 1191 | interface FlashPath { 1192 | /// Appends a cubic Bézier curve segment to the path. 1193 | addCubicCurve(xAnchor: number, yAnchor: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number): void; 1194 | /// Appends a quadratic Bézier segment to the path. 1195 | addCurve(xAnchor: number, yAnchor: number, x2: number, y2: number, x3: number, y3: number): void; 1196 | /// Adds a point to the path. 1197 | addPoint(x: number, y: number): void; 1198 | /// Removes all points from the path. 1199 | clear(): void; 1200 | /// Appends a point at the location of the first point of the path and extends the path to that point, which closes the path. 1201 | close(); void; 1202 | /// Creates a shape on the Stage by using the current stroke and fill settings. 1203 | makeShape(bSupressFill?: boolean, bSupressStroke?: boolean): void; 1204 | /// Starts a new contour in the path. 1205 | newContour(): void; 1206 | /// Read-only; an integer representing the number of points in the path. 1207 | nPts: number; 1208 | } 1209 | 1210 | interface FlashDrawingLayer { 1211 | /// Puts Flash in drawing mode. 1212 | beginDraw(persistentDraw?: boolean): void; 1213 | /// Erases what was previously drawn using the drawingLayer and prepares for more drawing commands. 1214 | beginFrame(): void; 1215 | /// Draws a cubic curve from the current pen location using the parameters as the coordinates of the cubic segment. 1216 | cubicCurveTo(x1Ctrl: number, y1Ctrl: number, x2Ctl: number, y2Ctl: number, xEnd: number, yEnd: number): void; 1217 | /// Draws a quadratic curve segment starting at the current drawing position and ending at a specified point. 1218 | curveTo(xCtl: number, yCtl: number, xEnd: number, yEnd: number): void; 1219 | /// Draws the specified path. 1220 | drawPath(path: FlashPath): void; 1221 | /// Exits drawing mode. 1222 | endDraw(): void; 1223 | /// Signals the end of a group of drawing commands. 1224 | endFrame(): void; 1225 | /// Draws a line from the current drawing position to the point (x,y). 1226 | lineTo(x: number, y: number): void; 1227 | /// Sets the current drawing position. 1228 | moveTo(x: number, y: number): void; 1229 | /// Returns a new Path object. 1230 | newPath(): void; 1231 | /// Sets the color of subsequently drawn data. 1232 | setColor(color: any): void; 1233 | /// This method is not available. 1234 | setFill(): void; 1235 | /// This method is not available. 1236 | setStroke(): void; 1237 | } 1238 | 1239 | interface FlashXMLUI { 1240 | accept(); 1241 | cancel(); 1242 | get(); 1243 | getControlItemElement(); 1244 | getEnabled(); 1245 | getVisible(); 1246 | set(); 1247 | setControItemElement(); 1248 | setControItemElements(); 1249 | setEnabled(); 1250 | setVisible(); 1251 | } 1252 | 1253 | interface FlashActionsPanel { 1254 | getClassForObject(); 1255 | getScriptAssistMode(); 1256 | getSelectedText(); 1257 | getText(); 1258 | hasSelection(); 1259 | replaceSelectedText(); 1260 | setScriptAssistMode(); 1261 | setSelection(); 1262 | setText(); 1263 | } 1264 | 1265 | interface FlashCompilerErrors { 1266 | clear(); 1267 | save(); 1268 | } 1269 | 1270 | interface FlashComponentsPanel { 1271 | addItemToDocument(); 1272 | reload(); 1273 | } 1274 | 1275 | interface FlashPresetPanel { 1276 | addNewItem(); 1277 | applyPreset(); 1278 | deleteFolder(); 1279 | deleteItem(); 1280 | expandFolder(); 1281 | exportItem(); 1282 | findItemIndex(); 1283 | getSelectedItems(); 1284 | importItem(); 1285 | moveToFolder(); 1286 | newFolder(); 1287 | renameItem(); 1288 | selectItem(); 1289 | } 1290 | 1291 | interface FlashSwfPanel { 1292 | call(); 1293 | setFocus(); 1294 | name; 1295 | path; 1296 | } 1297 | 1298 | interface FlashTools { 1299 | constraintPoint(); 1300 | getKeyDown(); 1301 | setCreatingBbox(); 1302 | setCursor(); 1303 | snapPoint(); 1304 | activeTool; 1305 | altIsDown; 1306 | ctlIsDown; 1307 | mouseIsDown; 1308 | penDownLoc; 1309 | penLoc; 1310 | shiftIsDown; 1311 | toolObjs; 1312 | } 1313 | 1314 | declare type SpriteSheetAlgorithm = "basic" | "maxRects"; 1315 | declare type FlashImageFormat = "png" | "jpg"; 1316 | declare type FlashBitDepth = 8 | 24 | 32; 1317 | 1318 | declare class SpriteSheetOptions { 1319 | format: FlashImageFormat; 1320 | backgroundColor?: any; 1321 | quality?: number; 1322 | bitDepth?: FlashBitDepth; 1323 | 1324 | } 1325 | 1326 | declare class SpriteSheetExporter { 1327 | addBitmap(item:FlashItem); 1328 | addSymbol(item:FlashItem, name?:string, beginFrame?:number, endFrame?:number); 1329 | algorithm:SpriteSheetAlgorithm; 1330 | allowRotate:boolean; 1331 | allowTrimming:boolean; 1332 | app:string; 1333 | autoSize:boolean; 1334 | beginExport(); 1335 | borderPadding:number; 1336 | canBorderPad:boolean; 1337 | canRotate:boolean; 1338 | canTrim:boolean; 1339 | canShapePad:boolean; 1340 | canStackDuplicateFrames:boolean; 1341 | changeSymbol(); 1342 | exportSpriteSheet(fileURL:string, format: FlashImageFormat|SpriteSheetOptions, writeMetaData?:boolean):string; 1343 | format:string; 1344 | image:string; 1345 | layoutFormat:string; 1346 | maxSheetHeight:number; 1347 | maxSheetWidth:number; 1348 | overflowed:boolean; 1349 | removeBitmap(bitmap: FlashBitmapItem); 1350 | removeSymbol(); 1351 | shapePadding:number; 1352 | sheetHeight:number; 1353 | sheetWidth:number; 1354 | stackDuplicateFrames:boolean; 1355 | version:string; 1356 | } 1357 | 1358 | 1359 | interface FlashFL { 1360 | addEventListener(eventType, callbackFunction); 1361 | browseForFileURL(browseType, title?, previewArea?, fileFilter?); 1362 | browseForFolderURL(description: string); 1363 | clearPublishCache(): void; 1364 | clipCopyString(string: string): void; 1365 | closeAll(bPromptToSave?: boolean): void; 1366 | closeAllPlayerDocuments(): boolean; 1367 | closeDocument(documentObject: FlashDocument, bPromptToSaveChanges?: boolean); 1368 | //closeProject(); 1369 | /** A string that specifies the type of document to create. Acceptable values are "timeline", "presentation", and "application". The default value is "timeline", which has the same effect as choosing File > New > Flash File (ActionScript 3.0). This parameter is optional. */ 1370 | createDocument(document?: string): FlashDocument; 1371 | 1372 | exportPublishProfileString(ucfURI: string, profileName: string): string; 1373 | 1374 | //createProject(); 1375 | //downloadLatestVersion(); // Not in CS5 1376 | //enableImmediateUpdates(); 1377 | 1378 | fileExists(fileURI: string): boolean; 1379 | findDocumentDOM(id: number): FlashDocument; 1380 | findDocumentIndex(name: string): number[]; 1381 | findObjectInDocByName(instanceName: string, document: FlashDocument): { keyframe: FlashFrame; layer: FlashLayer; timeline: FlashTimeline; parent; }[]; 1382 | /** elementType = "shape", "text", "instance", or "shapeObj". */ 1383 | findObjectInDocByType(elementType: string, document: FlashDocument): any[]; 1384 | getAppMemoryInfo(memType: number); 1385 | 1386 | /* 1387 | * Method; retrieves the DOM (Document object) of the currently active document (FLA file). 1388 | * If one or more documents are open but a document does not currently have focus (for 1389 | * example, if a JSFL file has focus), retrieves the DOM of the most recently active document. 1390 | * getDocumentDOM(): Document; 1391 | */ 1392 | getDocumentDOM(): FlashDocument; 1393 | 1394 | //getProject(); 1395 | 1396 | getSwfPanel(); 1397 | 1398 | isFontInstalled(); 1399 | 1400 | 1401 | mapPlayerURL(URI: string, returnMBCS?: boolean): string; 1402 | 1403 | /** Method; opens a Flash document (FLA file) for editing in a new Flash Document window and gives it focus. For a user, the effect is the same as selecting File > Open and then selecting a file. If the specified file is already open, the window that contains the document comes to the front. The window that contains the specified file becomes the currently selected document. */ 1404 | openDocument(fileURI: string): FlashDocument; 1405 | 1406 | //openProject(); 1407 | 1408 | openScript(fileURI: string, createExtension?: string, className?: string): void; 1409 | 1410 | quit(bPromptIfNeeded?: boolean): void; 1411 | 1412 | //reloadEffects(): void; 1413 | 1414 | reloadTools(): void; 1415 | 1416 | /** documentNew", "documentOpened", "documentClosed", "mouseMove", "documentChanged", "layerChanged", and "frameChanged". */ 1417 | removeEventListener(eventType: string): boolean; 1418 | resetAS3PackagePaths(): void; 1419 | resetPackagePaths(): void; 1420 | revertDocument(document: FlashDocument): void; 1421 | //revertDocumentToLastVersion(); 1422 | 1423 | runScript(fileURI: string, funcName?: Function, args?: any[]): any; 1424 | 1425 | saveAll(): void; 1426 | 1427 | //saveVersionOfDocument(); 1428 | saveDocument(document: FlashDocument, fileURI?: string): boolean; 1429 | saveDocumentAs(document: FlashDocument): boolean; 1430 | 1431 | /** Method; enables selection or editing of an element. Generally, you will use this method on objects returned by fl.findObjectInDocByName() or fl.findObjectInDocByType(). */ 1432 | selectElement(elementObject: FlashElement, editMode: boolean): boolean; 1433 | 1434 | /** "arrow","bezierSelect","freeXform","fillXform","lasso","pen","penplus","penminus","penmodify","text","line","rect","oval","rectPrimitive","ovalPrimitive","polystar","pencil","brush","inkBottle","bucket","eyeDropper","eraser","hand", and "magnifier". */ 1435 | selectTool(toolName: string): void; 1436 | 1437 | selectActiveWindow(document: FlashDocument, bActivateFrame?: boolean): void; 1438 | 1439 | showIdleMessage(show: boolean): void; 1440 | 1441 | toggleBreakpoint(); 1442 | 1443 | xmlPanelFromString(xml: string): any; 1444 | 1445 | //synchronizeDocumentWithHeadVersion(); 1446 | trace(message: any): void; 1447 | 1448 | actionsPanel: FlashActionsPanel; 1449 | //activeEffect; 1450 | as3PackagePaths: string; 1451 | compilerErrors: FlashCompilerErrors; 1452 | componentsPanel: FlashComponentsPanel; 1453 | configDirectory: string; 1454 | configURI: string; 1455 | contactSensitiveSelection: boolean; 1456 | createNewDocList: string[]; 1457 | createNewDocListType: string[]; 1458 | createNewTemplateList: string[]; 1459 | documents: FlashDocument[]; 1460 | drawingLayer: FlashDrawingLayer; 1461 | //effects; 1462 | externalLibraryPath: string; 1463 | flexSDKPath: string; 1464 | installedPlayers: any[]; 1465 | languageCode: string; 1466 | libraryPath: string; 1467 | Math: FlashMath; 1468 | mruRecentFileList: string[]; 1469 | mruRecentFileListType: string[]; 1470 | packagePaths: string[]; 1471 | publishCacheDiskSizeMax: number; 1472 | publishCacheEnabled: boolean; 1473 | publishCacheMemoryEntrySizeLimit: number; 1474 | publishCacheMemorySizeMax: number; 1475 | 1476 | objectDrawingMode: number; 1477 | outputPanel: FlashOutputPanel; 1478 | presetPanel: FlashPresetPanel; 1479 | scriptURI: string; 1480 | sourcePath: string; 1481 | spriteSheetExporter: SpriteSheetExporter; 1482 | swfPanels: FlashSwfPanel[]; 1483 | tools: FlashTools[]; 1484 | version: string; 1485 | xmlui: FlashXMLUI; 1486 | } 1487 | 1488 | declare var fl: FlashFL; 1489 | declare var FLfile: FlashFLfile; 1490 | declare function alert(alertText: string): void; 1491 | declare function confirm(strAlert: string): boolean; 1492 | declare function prompt(promptMsg: string, text?: string): string; -------------------------------------------------------------------------------- /types/zipfile.d.ts: -------------------------------------------------------------------------------- 1 | declare class ZipFile { 2 | static compress(srcPath: String, dstPath: String); 3 | static name: String; 4 | static MM_path: String; 5 | static MM_loaded: String; 6 | } --------------------------------------------------------------------------------