diff --git a/CHANGELOG.md b/CHANGELOG.md index 1758ee91..685e635f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +**2018-09-26** version 9.5.0 + +- Bug Fixes + * UserConfiguration import not consistent across OS's (#235) + * Exporter when Totals disabled producing error (#238) + * Account options changes not updating totals (#245) + +- New Features + * Character portraits show clothing and accessory texture info (#144) + * White Bag Tracker (#168) + * Skin Wardrobe (#227) + * Automatic disable/delete of invalid/banned accounts (#230) + * Muledump CORS Adapter for Firefox (#232) + * Added new Option for Shrinking Mules (#237) + * Added new Standard Filter for White Bag Items (#239) + +- Improvements + * Mac OS key bindings added (#240) + * Empty equipment slots now optionally show item silhouette (#241) + +- Settings Manager reorganized +- Wawawa's Progress Tracker updated to 0.8.4 +- html2canvas updated to 1.0.0-alpha.12 +- Masonry updated to 4.2.2 +- Renders updated to X29.0.1 + **2018-08-06** version 9.4.0 - Bug Fixes diff --git a/README.md b/README.md index 5502c383..83fbf488 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ See the [Requirements](REQUIREMENTS.md) page for more information. ## Release Information -The current version is Jakcodex/Muledump v9.4. +The current version is Jakcodex/Muledump v9.5. Muledump Online is available hosted on Github [here](https://jakcodex.github.io/muledump/muledump.html). @@ -49,11 +49,13 @@ All released versions are available for download [here](https://github.com/jakco - Manage all of your ROTMG accounts from a single interface - [SetupTools](docs/setuptools/index.md) - An easy to use, browser-based user interface for managing Muledump -- [Groups Manager](docs/setuptools/groups-manager/manager.md) - Account grouping and ordering utility to customize the Muledump accounts list +- [Groups Manager](docs/setuptools/help/groups-manager/manager.md) - Account grouping and ordering utility to customize the Muledump accounts list - [Muledump Online](https://jakcodex.github.io/muledump/muledump.html) - Load Muledump directly from Github using SetupTools - [One Click Login](https://github.com/jakcodex/muledump/wiki/One-Click-Login) - Login to your accounts via the browser or Flash Projector with one click - [Storage Compression](https://github.com/jakcodex/muledump/wiki/Storage-Compression) - Store more data in the browser than previously possible - [Muledump Totals](https://github.com/jakcodex/muledump/wiki/Totals) - Filtering on fame bonus, feed power, soulbound, tradeable, ut, and st, and specified accounts, and easy switching between pre-defined totals configs +- [White Bag Tracker](docs/muledump/whitebags.md) - Track your white bag collection the way you want to +- Skin Wardrobe - View all skins owned by your accounts - MuleQueue - Task queuing to control the flow of requests from Muledump - Vault display is fully customizable and comes with four pre-defined layouts - Full character skin and dye support in portraits @@ -85,9 +87,9 @@ All released versions are available for download [here](https://github.com/jakco ## Support and Contributions -Jakcodex/Muledump operates its own support Discord server - [https://discord.gg/JFS5fqW](https://discord.gg/JFS5fqW). +Jakcodex/Muledump operates its own Discord server - [https://discord.gg/JFS5fqW](https://discord.gg/JFS5fqW). -Feel free to join and ask for help getting setup, hear about new updates, offer your suggestions and feedback, or just say hi. +Feel free to join and ask for help getting setup, hear about new updates, offer your suggestions and feedback, or just say hi. We love to hear from the community! If you encounter a bug, have a feature request, or have any other feedback you can also check out the [issue tracker](https://github.com/jakcodex/muledump/issues) to see if it's already being discussed. If not then you can [submit a new issue](https://github.com/jakcodex/muledump/issues/new). @@ -107,9 +109,13 @@ Muledump Online always runs the latest version of Muledump with all patches. Muledump Renders are maintained by [tuvior](https://github.com/tuvior). +Thanks to [Atomizer](https://github.com/atomizer) for all the original Muledump work and for his [endorsement](https://github.com/atomizer/muledump#on-indefinite-hiatus-an-active-fork-is-here). + +Thanks to [Wawawa](https://github.com/wawawawawawawa) for his progress tracking feature. + This project uses open source libraries from many projects. See our dependencies to check them out. -This project uses textures and animated graphics courtesey of [Loading.io](https://www.loading.io). +This project uses textures and animated graphics courtesy of [Loading.io](https://www.loading.io). ## FYI diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index 98af1a69..ed939f21 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -5,15 +5,14 @@ In order to get around browser restrictions when attempting to contact Deca servers, Muledump presently needs a browser extension to make its requests work. #### Google Chrome (recommended) -- Requires the extension **[Jakcodex/Muledump CORS Adapter](https://chrome.google.com/webstore/detail/jakcodexmuledump-cors-ada/iimhkldbldnmapepklmeeinclchfkddd)** +- Requires the extension **[Jakcodex/Muledump CORS Adapter for Chrome](https://chrome.google.com/webstore/detail/jakcodexmuledump-cors-ada/iimhkldbldnmapepklmeeinclchfkddd)** #### Opera - Requires the Opera extension **[Download Chrome Extension](https://addons.opera.com/en/extensions/details/download-chrome-extension-9/?display=en)** -- Requires the Chrome extension **[Jakcodex/Muledump CORS Adapter](https://chrome.google.com/webstore/detail/jakcodexmuledump-cors-ada/iimhkldbldnmapepklmeeinclchfkddd)** +- Requires the Chrome extension **[Jakcodex/Muledump CORS Adapter for Chrome](https://chrome.google.com/webstore/detail/jakcodexmuledump-cors-ada/iimhkldbldnmapepklmeeinclchfkddd)** #### Firefox -- Requires the extension **[CORS Everywhere](https://addons.mozilla.org/en-us/firefox/addon/cors-everywhere/)** -- When you wish to run Muledump, turn on this extension as described [here](https://github.com/spenibus/cors-everywhere-firefox-addon/blob/master/README.md). +- Requires the extension **[Jakcodex/Muledump CORS Adapter for Firefox](https://addons.mozilla.org/en-US/firefox/addon/muledump-cors-adapter/)** #### IE and Edge - Please join us in the 21st century and choose a new browser from the above list. diff --git a/THANKS.md b/THANKS.md index 840bf59e..e62f5518 100644 --- a/THANKS.md +++ b/THANKS.md @@ -14,4 +14,6 @@ tuvior Curlip +Lovens + Numerous others from the community who offered feedback. diff --git a/docs/muledump/wardrobe.md b/docs/muledump/wardrobe.md new file mode 100644 index 00000000..4f4d36bd --- /dev/null +++ b/docs/muledump/wardrobe.md @@ -0,0 +1,13 @@ +# Skin Wardrobe + +Displays your presently owned skins sorted by class. All owned skins are highlighted. + +Mouse over skins to see their name. + +The following skins are not included in this list: + +1. Set Skins +1. Christmas Class Skins +1. Experimental / Test Skins + +Click the Large or Small dye icons to change the display. diff --git a/docs/muledump/whitebags.md b/docs/muledump/whitebags.md new file mode 100644 index 00000000..64bc2ea9 --- /dev/null +++ b/docs/muledump/whitebags.md @@ -0,0 +1,72 @@ +# White Bag Tracker + +Welcome to the White Bag Tracker! This tool is designed to let you keep track of your white bags with several different ways to go about the task. + +In the Totals mode, the White Bag Tracker shows your owned white bags and a quantity. You can change the quantity if desired to set the data however you want. + +In the Owned mode, the White Bag Tracker shows your owned skins without the quantity. + +#### Notice + +Importing white bag counts should be done with Custom Character Sorting Lists turned off unless you want to import the white bag data from just those characters. + +## UI Usage + +[Actions](#act) + +[Exporter](#exp) + +[Controls](#ctrl) + +## Actions + +### Enable / Disable Totals + +Whether to be in Totals or Owned Mode. + +### Save + +Save current changes immediately. An auto-save occurs when closing the white bag tracker. + +### Clear + +Erases all White Bag Tracker data. This implies a save and cannot be undone. + +### Import + +Import White Bag Tracker data by scanning the account's inventory. + +#### Import Modes + +##### Keep Existing Data +The discovered white bags in inventory are added to the existing counters. + +##### Reset Counters +Counters are reset to zero while owned white bag data remains before importing. + +##### Reset Counters and Owned +Counters and owned white bag data is reset before importing. + +### Reset + +Undoes any recent changes since the last save. + +### Cancel + +Closes the UI and skips the auto save. + +## Exporter + +A modified version of the Totals Export, it supports the same output formats. + +## Controls + +### Totals Mode + +1. Shift+Click on an unowned item or item of zero quantity to add or remove it from the owned list. +1. Click on an item to increase its value by 1. Automatically adds new items to owned list. +1. Ctrl+Click on an item to decrease its value by 1. + +### Owned Mode + +1. Shift+Click on an item to add or remove it from the owned list. diff --git a/docs/setuptools/dev/setuptools-object-ref.md b/docs/setuptools/dev/setuptools-object-ref.md index 591dde65..da374347 100644 --- a/docs/setuptools/dev/setuptools-object-ref.md +++ b/docs/setuptools/dev/setuptools-object-ref.md @@ -95,6 +95,26 @@ Full URL for Appspot testing server endpoint. Delay before Backup Assistant will popup on screen. +#### compressionMinimum +`[default:number|1000]` + +Minimum size in bytes a string must be before it gets compressed for SetupTools Compression. + +#### compressionFormat +`[default:number|0]` + +Compression format to utilize. Presently supports SnappyJS with id 0. + +#### compressionLibraries +`[default:object|{snappy: {}}]` + +Each compression algorithm should be defined as an key with an empty object for its data. The key order determines the ids used in `compressionFormat`. + +#### corsURL +`[default:object|{...}]` + +Browser-specific URLs to their respective Muledump CORS Adapter browser extension page. + #### setuptools.config.defaultSlotOrder `[default: object|...]` @@ -122,6 +142,11 @@ Whether or not Mulecrypt is enabled. Hex color used for error texts outside of css +#### exporterStoredLinks +`[default: number|10]` + +How many recent links to store in history when uploading to Jakcodex/Paste. + #### setuptools.config.ga `[default: string|empty]` @@ -260,11 +285,21 @@ Minimum number of recommended CPU cores. URL to the Rate Limiting information wiki page. +#### setuptools.config.remotePasteUrl +`[default: string|https://paste.jakcodex.io/api/create]` + +URL to the remote Paste REST API endpoint. + #### setuptools.config.realmApiParams `[default: object|...]` Default request parameters added to all RealmAPI requests. +#### setuptools.config.realmApiTimeout +`[default: number|10000]` + +Request timeout in milliseconds for all RealmAPI AJAX calls. + #### setuptools.config.realmeyeUrl `[default: string|https://www.realmeye.com]` @@ -283,6 +318,16 @@ A list of RegExp objects used throughout the program How many seconds to wait before triggering automatic window reloads +#### setuptools.config.timesyncTtl +`[default: number|2500]` + +Time in milliseconds before the Time Sync API request times out. + +#### setuptools.config.timesyncUrl +`[default: string|https://time.jakcodex.io/api/time]` + +URL to the remote Time REST API endpoint. + #### setuptools.config.totalsDefaultIcon `[default: array|[880, 40]]` @@ -294,7 +339,7 @@ Default icon position for Totals Settings Manager - Item Group Sorting menu. Width of each item in the totals block. #### setuptools.config.totalsFilterKeysIndex -`[default: number|9]` +`[default: number|11]` Position on setuptools.config.totalsSaveKeys where totalsFilter keys begins (typically setuptools.config.totalsSaveKeys.length) @@ -381,6 +426,37 @@ How old cache data can be before it is considered stale (only applies to account How many days between backup assistant alerts. +#### setuptools.data.config.badaccounts +`[default: number|-1]` + +How to create to accounts that are detected as being bad. + +##### -1 +The feature is disabled + +##### 0 +Disable invalid accounts + +##### 1 +Disable banned accounts + +##### 2 +Delete invalid accounts + +##### 3 +Delete banned accounts + +##### 4 +Disable both invalid and banned accounts + +##### 5 +Delete both invalid and banned accounts + +#### setuptools.data.config.compression +`[default: boolean|false]` + +Whether or not the SetupTools Compression feature is enabled. + #### setuptools.data.config.corsAssistant `[default: number|1]` @@ -389,12 +465,40 @@ Whether or not the CORS assistant is enabled. #### setuptools.data.config.debugging `[default: boolean|false]` -Whether or not to log debugging information to the browser console +Whether or not to log debugging information to the browser console. #### setuptools.data.config.enabled `[default: boolean|false]` -Whether or not SetupTools is enabled +Whether or not SetupTools is enabled. + +#### setuptools.data.config.equipSilhouettes +`[default: boolean|true]` + +Whether or not empty equipment slots have item type silhouettes displayed. + +#### setuptools.data.config.exportDefault +`[default: number|4]` + +Default action when clicking the Export button. + +##### 0 +None, just open the Muledump Exporter menu + +##### 1 +Text + +##### 2 +CSV + +##### 3 +JSON + +##### 4 +Image + +##### 5 +Imgur #### setuptools.data.config.errors `[default: boolean|true]` @@ -441,6 +545,17 @@ How to merge accounts configured in the groups manager (0=off, 1=parallel, 2=ser Whether or not to hide the Muledump product information from the top bar. +#### setuptools.data.config.keyBindings +`[default: number|0]` + +Which keyboard key binding map to utilize. + +##### 0 +Standard - compatible with Windows and Linux + +##### 1 +Mac OS - replaces Ctrl with Command key + #### setuptools.data.config.lazySave `[default: number|10000]` @@ -511,16 +626,37 @@ Whether or not to prevent browser automatic, no-confirm downloads (dangerous giv Number of items to display in a single row in Muledump (combo of chars+accounts) +#### setuptools.data.config.timesync +`[default: boolean|false]` + +Whether or not to use the Time Sync feature to check the correctness of the system clock using a remote REST API service. + #### setuptools.data.config.tooltip `[default: number|500]` Time to wait in milliseconds before displaying a tooltip on hover. +#### setuptools.data.config.totalsExportWidth +`[default: number|0]` + +Size of the Totals export image. Values -1 and 0 are special. + +##### -1 +Set to `setuptools.data.config.totalswidth` + +##### 0 +Whole screen width + #### setuptools.data.config.totalswidth `[default: number|0]` Number of items to display per row in totals. A value of 0 will default to whole screen usable width. +#### setuptools.data.config.wbTotals +`[default: boolean|true]` + +Whether or not the White Bag Tracker is in Totals or Owned mode. + ## Muledump Accounts Configuration - setuptools.data.accounts SetupTools replaces the need for an accounts.js file by importing that data and restructuring it. Muledump is still provided the original structure for the `accounts` variable by means of `setuptools.app.config.convert()`. diff --git a/docs/setuptools/help/accounts-manager/manager.md b/docs/setuptools/help/accounts-manager/manager.md index 4d88b270..efb3d57e 100644 --- a/docs/setuptools/help/accounts-manager/manager.md +++ b/docs/setuptools/help/accounts-manager/manager.md @@ -31,6 +31,11 @@ Account data is stored on your PC to prevent having to reload it every time you Accounts set to login only will reload their data from ROTMG but not display in the window. +#### ```Testing Server``` +[default: disabled] + +Account will be loaded from the public testing server instead of prod. + #### ```Export Deep Copy``` Download the account data stored on your browser for this account. diff --git a/docs/setuptools/help/settings-manager.md b/docs/setuptools/help/settings-manager.md index 028daa2f..aca48350 100644 --- a/docs/setuptools/help/settings-manager.md +++ b/docs/setuptools/help/settings-manager.md @@ -1,158 +1,168 @@ # Settings Manager -[Muledump Settings](#ms) +[Muledump](#ms) -[SetupTools Settings](#sts) +[SetupTools](#sts) + +[Advanced](#advs) [Assistants](#as) -[System Settings](#ss) +[System](#ss) -### Muledump Settings +## Muledump Settings -#### ```Account Load Delay in Seconds``` +### ```Account Load Delay in Seconds``` Delay between account load times when contacting Deca servers. -#### ```Characters Displayed per Row``` +### ```Characters Displayed per Row``` The maximum numbers of characters to be displayed in on the webpage per row. -#### ```Display Errors``` +### ```Display Errors``` Display error messages when encountered. -#### ```Enable One Click Login``` +### ```Enable One Click Login``` Whether or not to enable the support of muledump:// links. -#### ```Export Default Mode``` +### ```Equipment Silhouettes``` +Whether or not to display equipment silhouettes in empty slots. + +### ```Export Default Mode``` What export mode to utilize if you click the Export button without selecting a format. -#### ```Gift Chests Width``` +### ```Gift Chests Width``` Numbers of gift chests to display per row. -#### ```Mule Menu``` -Whether or not to display the Mule Menu icon on mules. - -#### ```Page Search``` +### ```Page Search``` Format to display page search: Full width, shortened, or off. -#### ```Totals Display Width``` +### ```Totals Display Width``` Number of items to display per row in totals. Whole screen automatically adjusts to current size of the browser window. -#### ```Totals Export Width``` +### ```Totals Export Width``` Number of items to display per row in totals when exporting an image. -#### ```Use Smart Layout``` -Whether or not to use Masonry to generate the page layout. - -### SetupTools Settings +## SetupTools Settings -#### ```SetupTools Enabled``` +### ```SetupTools Enabled``` Whether or not to utilize SetupTools features or fallback on the traditional accounts.js format. Setting this to Automatic will determine the value based on number of enabled accounts. Muledump Local only -#### ```Accounts Displayed per Page``` +### ```Accounts Displayed per Page``` Number of accounts to display per page in UI managers. -#### ```Alert on New Version``` +### ```Alert on New Version``` Whether or not to display a notice on a new version or patch release. Muledump Online only -#### ```Animations``` -Whether or not to display all animations, reduced animations, or minimal animations. - -#### ```Auto Complete for Password Managers``` -When disabled this prevents passwords managers from interfering with username and password fields. - Warning: This setting might get ignored by your browser making the setting useless. -#### ```Automatic Backups``` -Automatically create daily backups of your configuration stored in browser local storage. - -#### ```Automatically Reload Account Data``` +### ```Automatically Reload Account Data``` Whether or not accounts set to Automatic Reload will execute the action. -#### ```Debug Logging``` -Whether or not to output the debug logs to the browser console. +### ```Bad Account Actions``` +How to handle bad accounts (invalid credentials, banned). -#### ```Groups Manager Mode``` +### ```Groups Manager Mode``` Which mode Groups Manager is running in. Possible modes are: -##### Off +#### Off Groups Manager configuration is not loaded. -##### On, Parallel +#### On, Parallel Groups Manager accounts are merged with their order preserved Example: [a, b, c] + [d, e, f] + [g, h, i] = [a, d, g, b, e, h, c, f, i] -##### On, Serial +#### On, Serial Groups Manager accounts are merged with their order arranged by overall order Example: [a, b, c] + [d, e, f] + [g, h, i] = [a, b, c, d, e, f, g, h, i] -#### ```Hide Muledump Version Text``` +### ```Hide Muledump Version Text``` Hides the `Jakcodex / Muledump v1.2.3` text in the Muledump header. -#### ```Lazily Save Minor Config Changes``` +### ```Maximum Backups in Local Storage``` +SetupTools stores backups in your browser's local storage. This utilizes disk space on your computer. This feature limits the maximum number of exposed backups to keep before auto-deleting the oldest. + +### ```Menu Position``` +Position of the Muledump menu. + +## Advanced Settings + +### ```Animations``` +Whether or not to display all animations, reduced animations, or minimal animations. + +### ```Auto Complete for Password Managers``` +When disabled this prevents passwords managers from interfering with username and password fields. + +### ```Automatic Backups``` +Automatically create daily backups of your configuration stored in browser local storage. + +### ```Debug Logging``` +Whether or not to output the debug logs to the browser console. + +### ```Lazily Save Minor Config Changes``` Length of time between lazySave requests (to reduce storage write volume on auto saving features). -#### ```Longpress Length in Seconds``` +### ```Longpress Length in Seconds``` Length of time that a long left click takes to activate. -#### ```Low Storage Space Check``` +### ```Low Storage Space Check``` Whether or not to warn you if browser storage space is running out. -#### ```Maximum Backups in Local Storage``` -SetupTools stores backups in your browser's local storage. This utilizes disk space on your computer. This feature limits the maximum number of exposed backups to keep before auto-deleting the oldest. - -#### ```Menu Position``` -Position of the Muledump menu. +### ```Mule Menu``` +Whether or not to display the Mule Menu icon on mules. -#### ```Prevent Auto Download``` +### ```Prevent Auto Download``` When downloading data from SetupTools, this feature prevents you from accidentally downloading a backup of sensitive account information to your Downloads folder. -#### ```Storage Compression``` +### ```Storage Compression``` Whether or not to use SetupTools Compression to reduce size of data stored in browser storage. -#### ```Time Synchronize``` +### ```Time Synchronize``` Whether or not to check if your computer clock's time is correct. -### Assistants Settings +### ```Use Smart Layout``` +Whether or not to use Masonry to generate the page layout. + +## Assistants Settings -#### ```Account Assistant``` +### ```Account Assistant``` Displays an assistant when account issues are detected (TOS, migration, age verification). -#### ```Backup Assistant``` +### ```Backup Assistant``` Displays a reminder to download a backup if a certain period of time has gone by since last download. -#### ```CORS Assistant``` +### ```CORS Assistant``` Displays an assistant to help resolve CORS problems when they are detected. -### System Settings +## System Settings -#### ```View System Report``` +### ```View System Report``` Displays current storage usage information and other system information. -#### ```Compression Utility``` +### ```Compression Utility``` Analyze and synchronize storage to match the current Storage Compression setting. -#### ```Reset Muledump Options``` +### ```Reset Muledump Options``` Erases current options and resets it to the default Muledump options. -#### ```Erase Account Data Cache``` +### ```Erase Account Data Cache``` Erases all cached account data for Muledump. Useful when account data appears to be bad. -#### ```Erase Secondary Cache``` +### ```Erase Secondary Cache``` Erases all secondary cache data generated by SetupTools (e.g. totals cache). -#### ```Erase SetupTools``` +### ```Erase SetupTools``` Erases all SetupTools-specific configuration and restores Muledump to its original state. -#### ```Erase All Data``` +### ```Erase All Data``` Erases all Muledump data including SetupTools, options, accounts, groups, backups, etc. -#### ```Reset to Default Settings``` +### ```Reset to Default Settings``` Restore all settings to the default SetupTools configuration. diff --git a/docs/setuptools/muledump-sample-config.json b/docs/setuptools/muledump-sample-config.json index 2b2b6a81..61e1f5f8 100644 --- a/docs/setuptools/muledump-sample-config.json +++ b/docs/setuptools/muledump-sample-config.json @@ -1,9 +1,9 @@ { "meta": { - "BackupDate": "2018-08-04T00:00:00.000Z", + "BackupDate": "2018-09-25T00:00:00.000Z", "protected": false, "auto": false, - "name": "muledump-sample-config-v9.4" + "name": "muledump-sample-config-v9.5" }, "config": { "accountAssistant": 1, @@ -15,11 +15,13 @@ "automaticBackups": true, "autoReloadDays": 1, "backupAssistant": 14, + "badaccounts": -1, "compression": false, "corsAssistant": 1, "debugging": true, "enabled": false, "encryption": false, + "equipSilhouettes": true, "exportDefault": 4, "errors": true, "ga": false, @@ -30,6 +32,7 @@ "giftChestWidth": 0, "groupsMergeMode": 2, "hideHeaderText": false, + "keyBindings": 0, "lazySave": 10000, "longpress": 1000, "lowStorageSpace": true, @@ -48,17 +51,18 @@ "timesync": false, "tooltip": 500, "totalsExportWidth": 0, - "totalswidth": 0 + "totalswidth": 0, + "wbTotals": true }, "version": { "major": 9, - "minor": 4, + "minor": 5, "patch": 0 }, "accounts": { "meta": { "created": 1510135507593, - "modified": 1528416000000, + "modified": 1537833600000, "format": 1, "version": 1, "encryption": false, @@ -198,6 +202,7 @@ "backpack": false, "gifts": false, "wawawa": false, + "shrink": false, "totals": true, "totalsGlobal": false, "famefilter": false, @@ -208,6 +213,7 @@ "nonsbfilter": false, "utfilter": false, "stfilter": false, + "wbfilter": false, "totalsFilter-empty": true, "totalsFilter-swords": true, "totalsFilter-daggers": true, @@ -411,6 +417,7 @@ "nonsbfilter": false, "utfilter": false, "stfilter": false, + "wbfilter": false, "totalsFilter-empty": true, "totalsFilter-swords": true, "totalsFilter-daggers": true, diff --git a/lib/constants.js b/lib/constants.js index 5550e110..29fa2bf0 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -3,7 +3,7 @@ * Game Version: X29.0.1 */ -rendersVersion = "renders-20180920-095931-X29.0.1"; +rendersVersion = "renders-20180925-210205-X29.0.1"; // type: ["id", SlotType, Tier, x, y, FameBonus, feedPower, BagType, Soulbound, UT/ST], items = { @@ -1048,9 +1048,9 @@ items = { 0xc7f: ["Ruby Gemstone", 10, -1, 600, 1520, 0, 600, 7, false, 0], 0xc80: ["Speed Sprout", 10, -1, 640, 1520, 0, 35, 2, false, 0], 0xc81: ["Old Firecracker", 10, -1, 40, 1400, 0, 400, 0, true, 0], - 0xc82: ["Cheater Light Armor", 6, -1, 680, 1520, 0, 300, 0, true, 1], - 0xc83: ["Cheater Robe", 14, -1, 720, 1520, 0, 300, 0, true, 1], - 0xc84: ["Cheater Heavy Armor", 7, -1, 760, 1520, 0, 300, 0, true, 1], + 0xc82: ["Cheater Light Armor", 6, -1, 680, 1520, 0, 300, 6, true, 1], + 0xc83: ["Cheater Robe", 14, -1, 720, 1520, 0, 300, 6, true, 1], + 0xc84: ["Cheater Heavy Armor", 7, -1, 760, 1520, 0, 300, 6, true, 1], 0xcc1: ["Draconis Potion", 10, -1, 800, 960, 0, 5, 0, false, 0], 0xcc2: ["Lucky Clover", 10, -1, 800, 1520, 0, 100, 8, true, 0], 0xcc3: ["Saint Paddy's Brew", 10, -1, 840, 1520, 0, 250, 2, false, 0], @@ -2273,6 +2273,65 @@ items = { 0x9ba: ["Mad God Token x 8", 10, -1, 40, 0, 0, 1600, 7, true, 0], 0x9bb: ["Mad God Token x 9", 10, -1, 40, 0, 0, 1800, 7, true, 0], 0x9bc: ["Mad God Token x 10", 10, -1, 40, 0, 0, 2000, 7, true, 0], + 0x6CF7: ["Primal Ice x 1", 10, -1, 40, 0, 0, 25, 7, true, 0], + 0x6CF8: ["Primal Ice x 2", 10, -1, 40, 0, 0, 50, 7, true, 0], + 0x6CF9: ["Primal Ice x 3", 10, -1, 40, 0, 0, 75, 7, true, 0], + 0x6CFA: ["Primal Ice x 4", 10, -1, 40, 0, 0, 100, 7, true, 0], + 0x6CFB: ["Primal Ice x 5", 10, -1, 40, 0, 0, 125, 7, true, 0], + 0x6CFC: ["Primal Ice x 6", 10, -1, 40, 0, 0, 150, 7, true, 0], + 0x6CFD: ["Primal Ice x 7", 10, -1, 40, 0, 0, 175, 7, true, 0], + 0x6CFE: ["Primal Ice x 8", 10, -1, 40, 0, 0, 200, 7, true, 0], + 0x6CFF: ["Primal Ice x 9", 10, -1, 40, 0, 0, 225, 7, true, 0], + 0x6D00: ["Primal Ice x 10", 10, -1, 40, 0, 0, 250, 7, true, 0], + 0x6D01: ["Primal Ice x 11", 10, -1, 40, 0, 0, 275, 7, true, 0], + 0x6D02: ["Primal Ice x 12", 10, -1, 40, 0, 0, 300, 7, true, 0], + 0x6D03: ["Primal Ice x 13", 10, -1, 40, 0, 0, 325, 7, true, 0], + 0x6D04: ["Primal Ice x 14", 10, -1, 40, 0, 0, 350, 7, true, 0], + 0x6D05: ["Primal Ice x 15", 10, -1, 40, 0, 0, 375, 7, true, 0], + 0x6D06: ["Primal Ice x 16", 10, -1, 40, 0, 0, 400, 7, true, 0], + 0x6D07: ["Primal Ice x 17", 10, -1, 40, 0, 0, 425, 7, true, 0], + 0x6D08: ["Primal Ice x 18", 10, -1, 40, 0, 0, 450, 7, true, 0], + 0x6D09: ["Primal Ice x 19", 10, -1, 40, 0, 0, 475, 7, true, 0], + 0x6D0A: ["Primal Ice x 20", 10, -1, 40, 0, 0, 500, 7, true, 0], + 0x6CF1: ["Ice Shard x 1", 10, -1, 40, 0, 0, 20, 7, true, 0], + 0x6CF2: ["Ice Shard x 2", 10, -1, 40, 0, 0, 40, 7, true, 0], + 0x6CF3: ["Ice Shard x 3", 10, -1, 40, 0, 0, 60, 7, true, 0], + 0x6CF4: ["Ice Shard x 4", 10, -1, 40, 0, 0, 80, 7, true, 0], + 0x6CF5: ["Ice Shard x 5", 10, -1, 40, 0, 0, 100, 7, true, 0], + 0x6CE6: ["Bell x 1", 10, -1, 40, 0, 0, 75, 7, true, 0], + 0x6CE7: ["Bell x 2", 10, -1, 40, 0, 0, 150, 7, true, 0], + 0x6CE8: ["Bell x 3", 10, -1, 40, 0, 0, 225, 7, true, 0], + 0x6CE9: ["Bell x 4", 10, -1, 40, 0, 0, 300, 7, true, 0], + 0x6CEA: ["Bell x 5", 10, -1, 40, 0, 0, 375, 7, true, 0], + 0x6CEB: ["Bell x 6", 10, -1, 40, 0, 0, 450, 7, true, 0], + 0x6CEC: ["Bell x 7", 10, -1, 40, 0, 0, 525, 7, true, 0], + 0x6CED: ["Bell x 8", 10, -1, 40, 0, 0, 600, 7, true, 0], + 0x6CEE: ["Bell x 9", 10, -1, 40, 0, 0, 675, 7, true, 0], + 0x6ccc: ["Ornament x 1", 10, -1, 40, 0, 0, 32, 7, true, 0], + 0x6ccd: ["Ornament x 2", 10, -1, 40, 0, 0, 64, 7, true, 0], + 0x6CCE: ["Ornament x 3", 10, -1, 40, 0, 0, 96, 7, true, 0], + 0x6CCF: ["Ornament x 4", 10, -1, 40, 0, 0, 128, 7, true, 0], + 0x6CD0: ["Ornament x 5", 10, -1, 40, 0, 0, 160, 7, true, 0], + 0x6CD1: ["Ornament x 6", 10, -1, 40, 0, 0, 192, 7, true, 0], + 0x6CD2: ["Ornament x 7", 10, -1, 40, 0, 0, 224, 7, true, 0], + 0x6CD3: ["Ornament x 8", 10, -1, 40, 0, 0, 256, 7, true, 0], + 0x6CD4: ["Ornament x 9", 10, -1, 40, 0, 0, 288, 7, true, 0], + 0x6CD5: ["Ornament x 10", 10, -1, 40, 0, 0, 320, 7, true, 0], + 0x6CD6: ["Ornament x 11", 10, -1, 40, 0, 0, 352, 7, true, 0], + 0x6CD7: ["Ornament x 12", 10, -1, 40, 0, 0, 384, 7, true, 0], + 0x6CD8: ["Ornament x 13", 10, -1, 40, 0, 0, 416, 7, true, 0], + 0x6CD9: ["Ornament x 14", 10, -1, 40, 0, 0, 448, 7, true, 0], + 0x6CDA: ["Ornament x 15", 10, -1, 40, 0, 0, 480, 7, true, 0], + 0x6CDB: ["Ornament x 16", 10, -1, 40, 0, 0, 512, 7, true, 0], + 0x6CDC: ["Ornament x 17", 10, -1, 40, 0, 0, 544, 7, true, 0], + 0x6CDD: ["Ornament x 18", 10, -1, 40, 0, 0, 576, 7, true, 0], + 0x6CDE: ["Ornament x 19", 10, -1, 40, 0, 0, 608, 7, true, 0], + 0x6CDF: ["Ornament x 20", 10, -1, 40, 0, 0, 640, 7, true, 0], + 0x6CE0: ["Ornament x 21", 10, -1, 40, 0, 0, 672, 7, true, 0], + 0x6CE1: ["Ornament x 22", 10, -1, 40, 0, 0, 704, 7, true, 0], + 0x6CE2: ["Ornament x 23", 10, -1, 40, 0, 0, 736, 7, true, 0], + 0x6CE3: ["Ornament x 24", 10, -1, 40, 0, 0, 768, 7, true, 0], + 0x6CE4: ["Ornament x 25", 10, -1, 40, 0, 0, 800, 7, true, 0], 0x702: ["Enemy Spawner", 10, -1, 720, 3080, 0, 0, 0, true, 0], 0x8da: ["Admin Prism", 22, -1, 320, 1320, 0, 100000, 6, true, 1], 0x705e: ["InvinceMe", 10, -1, 760, 3080, 0, 0, 6, true, 1], @@ -3030,98 +3089,56 @@ skins = { // texId: ["clothing id", clothing type, "accessory id", accessory type] textures = { -0xffffffff: ["Magical Clothing Dye Remover", 0x999, "Magical Accessory Dye Remover", 0x998], -0x01FFFAFA: ["Snow Clothing Dye", 0x107e, "Snow Accessory Dye", 0x117e], - 0xa000029: ["Large Purple Bones Cloth", 0x1240, "Small Purple Bones Cloth", 0x1340], -0x01FAFAD2: ["Light Golden Rod Yellow Clothing Dye", 0x1042, "Light Golden Rod Yellow Accessory Dye", 0x1142], -0x01FAEBD7: ["Antique White Clothing Dye", 0x1001, "Antique White Accessory Dye", 0x1101], - 0x9000000: ["Large Rainbow Cloth", 0x1204, "Small Rainbow Cloth", 0x1304], -0x01CD853F: ["Peru Clothing Dye", 0x106c, "Peru Accessory Dye", 0x116c], -0x01E9967A: ["Dark Salmon Clothing Dye", 0x1020, "Dark Salmon Accessory Dye", 0x1120], - 0x9000002: ["Large Blue Lace Cloth", 0x1217, "Small Blue Lace Cloth", 0x1317], -0x01FFE4E1: ["Misty Rose Clothing Dye", 0x105c, "Misty Rose Accessory Dye", 0x115c], -0x01000000: ["Black Clothing Dye", 0x1007, "Black Accessory Dye", 0x1107], -0x0187CEEB: ["Sky Blue Clothing Dye", 0x107b, "Sky Blue Accessory Dye", 0x117b], - 0xa000013: ["Large Viva Cloth", 0x1229, "Small Viva Cloth", 0x1329], - 0xa00002b: ["Large Clanranald Cloth", 0x1247, "Small Clanranald Cloth", 0x1347], -0x01CD5C5C: ["Indian Red Clothing Dye", 0x1037, "Indian Red Accessory Dye", 0x1137], -0x014169E1: ["Royal Blue Clothing Dye", 0x1073, "Royal Blue Accessory Dye", 0x1173], - 0xa00001b: ["Large Pink Dot Cloth", 0x1231, "Small Pink Dot Cloth", 0x1331], - 0xa00001f: ["Large USA Flag Cloth", 0x1236, "Small USA Flag Cloth", 0x1336], - 0xa000037: ["Large Sunburst Cloth", 0x1254, "Small Sunburst Cloth", 0x1354], -0x01FFF0F5: ["Lavender Blush Clothing Dye", 0x103c, "Lavender Blush Accessory Dye", 0x113c], - 0xa00000b: ["Large Crossbox Cloth", 0x1211, "Small Crossbox Cloth", 0x1311], - 0xa00003e: ["Large Stormy Cloth", 0x1261, "Small Stormy Cloth", 0x1361], -0x01778899: ["Light Slate Gray Clothing Dye", 0x1049, "Light Slate Gray Accessory Dye", 0x1149], -0x019ACD32: ["Yellow Green Clothing Dye", 0x108b, "Yellow Green Accessory Dye", 0x118b], -0x017B68EE: ["Medium Slate Blue Clothing Dye", 0x1056, "Medium Slate Blue Accessory Dye", 0x1156], - 0x4000005: ["Large Robber Cloth", 0x1224, "Small Robber Cloth", 0x1324], -0x01006400: ["Dark Green Clothing Dye", 0x1019, "Dark Green Accessory Dye", 0x1119], -0x01008000: ["Green Clothing Dye", 0x1033, "Green Accessory Dye", 0x1133], -0x017FFF00: ["Chartreuse Clothing Dye", 0x100e, "Chartreuse Accessory Dye", 0x110e], -0x01FFA500: ["Orange Clothing Dye", 0x1063, "Orange Accessory Dye", 0x1163], - 0xa000024: ["Large Teal Crystal Cloth", 0x123b, "Small Teal Crystal Cloth", 0x133b], - 0xa00002a: ["Large Plaid Cloth", 0x1241, "Small Plaid Cloth", 0x1341], - 0x5000002: ["Large Glowthread Cloth", 0x121f, "Small Glowthread Cloth", 0x131f], - 0x4000002: ["Large Yellow Dot Cloth", 0x121d, "Small Yellow Dot Cloth", 0x131d], - 0xa000031: ["Large Leopard Print Cloth", 0x124e, "Small Leopard Print Cloth", 0x134e], - 0xa000005: ["Large Futuristic Cloth", 0x120b, "Small Futuristic Cloth", 0x130b], -0x01FFFAF0: ["Floral White Clothing Dye", 0x102b, "Floral White Accessory Dye", 0x112b], -0x01D3D3D3: ["Light Grey Clothing Dye", 0x1043, "Light Grey Accessory Dye", 0x1143], - 0x9000003: ["Large Loud Spotted Cloth", 0x1218, "Small Loud Spotted Cloth", 0x1318], 0x01800000: ["Maroon Clothing Dye", 0x1050, "Maroon Accessory Dye", 0x1150], -0x01F5DEB3: ["Wheat Clothing Dye", 0x1087, "Wheat Accessory Dye", 0x1187], 0x0100FFFF: ["Cyan Clothing Dye", 0x1014, "Cyan Accessory Dye", 0x1114], + 0x4000002: ["Large Yellow Dot Cloth", 0x121d, "Small Yellow Dot Cloth", 0x131d], 0x01FFE4B5: ["Moccasin Clothing Dye", 0x105d, "Moccasin Accessory Dye", 0x115d], -0x01483D8B: ["Dark Slate Blue Clothing Dye", 0x1022, "Dark Slate Blue Accessory Dye", 0x1122], 0x01FFEBCD: ["Blanched Almond Clothing Dye", 0x1008, "Blanched Almond Accessory Dye", 0x1108], - 0xa000017: ["Large Big-Stripe Red Cloth", 0x122d, "Small Big-Stripe Red Cloth", 0x132d], - 0x4000007: ["Large Dark Blue Stripe Cloth", 0x1226, "Small Dark Blue Stripe Cloth", 0x1326], 0x01D8BFD8: ["Thistle Clothing Dye", 0x1083, "Thistle Accessory Dye", 0x1183], 0x0100008B: ["Dark Blue Clothing Dye", 0x1015, "Dark Blue Accessory Dye", 0x1115], -0x01F8F8FF: ["Ghost White Clothing Dye", 0x102f, "Ghost White Accessory Dye", 0x112f], -0x01FF0000: ["Red Clothing Dye", 0x1071, "Red Accessory Dye", 0x1171], - 0x5000007: ["Large Ivory Dragon Scale Cloth", 0x1255, "Small Ivory Dragon Scale Cloth", 0x1355], - 0xa00002c: ["Large American Flag Cloth", 0x1248, "Small American Flag Cloth", 0x1348], 0x01B0E0E6: ["Powder Blue Clothing Dye", 0x106f, "Powder Blue Accessory Dye", 0x116f], - 0xa00001c: ["Large Dark Eyes Cloth", 0x1232, "Small Dark Eyes Cloth", 0x1332], +0x01483D8B: ["Dark Slate Blue Clothing Dye", 0x1022, "Dark Slate Blue Accessory Dye", 0x1122], + 0x5000007: ["Large Ivory Dragon Scale Cloth", 0x1255, "Small Ivory Dragon Scale Cloth", 0x1355], + 0x5000002: ["Large Glowthread Cloth", 0x121f, "Small Glowthread Cloth", 0x131f], + 0x9000005: ["Large Pink Sparkly Cloth", 0x121a, "Small Pink Sparkly Cloth", 0x131a], +0x01556B2F: ["Dark Olive Green Clothing Dye", 0x101c, "Dark Olive Green Accessory Dye", 0x111c], 0x017CFC00: ["Lawn Green Clothing Dye", 0x103d, "Lawn Green Accessory Dye", 0x113d], + 0xa00002c: ["Large American Flag Cloth", 0x1248, "Small American Flag Cloth", 0x1348], 0x0100FF7F: ["Spring Green Clothing Dye", 0x107f, "Spring Green Accessory Dye", 0x117f], -0x01556B2F: ["Dark Olive Green Clothing Dye", 0x101c, "Dark Olive Green Accessory Dye", 0x111c], + 0x9000001: ["Large Starry Cloth", 0x1205, "Small Starry Cloth", 0x1305], 0x01B0C4DE: ["Light Steel Blue Clothing Dye", 0x104a, "Light Steel Blue Accessory Dye", 0x114a], 0x9000007: ["Large Pink Maze Cloth", 0x121c, "Small Pink Maze Cloth", 0x131c], + 0xa000039: ["Large Alchemist Cloth", 0x125b, "Small Alchemist Cloth", 0x135b], 0xa00000c: ["Large White Diamond Cloth", 0x1212, "Small White Diamond Cloth", 0x1312], 0x0100FA9A: ["Medium Spring Green Clothing Dye", 0x1057, "Medium Spring Green Accessory Dye", 0x1157], - 0x9000001: ["Large Starry Cloth", 0x1205, "Small Starry Cloth", 0x1305], - 0x9000005: ["Large Pink Sparkly Cloth", 0x121a, "Small Pink Sparkly Cloth", 0x131a], + 0xa00001c: ["Large Dark Eyes Cloth", 0x1232, "Small Dark Eyes Cloth", 0x1332], 0x01FF4500: ["Orange Red Clothing Dye", 0x1064, "Orange Red Accessory Dye", 0x1164], 0x01F4A460: ["Sandy Brown Clothing Dye", 0x1076, "Sandy Brown Accessory Dye", 0x1176], 0x01D2691E: ["Chocolate Clothing Dye", 0x100f, "Chocolate Accessory Dye", 0x110f], - 0x4000000: ["Large Purple Pinstripe Cloth", 0x1200, "Small Purple Pinstripe Cloth", 0x1300], 0xa00003f: ["Large Musical Cloth", 0x1262, "Small Musical Cloth", 0x1362], 0x01696969: ["Dim Gray Clothing Dye", 0x1028, "Dim Gray Accessory Dye", 0x1128], - 0x900000a: ["Large Red USA Star Cloth", 0x1242, "Small Red USA Star Cloth", 0x1342], + 0x4000000: ["Large Purple Pinstripe Cloth", 0x1200, "Small Purple Pinstripe Cloth", 0x1300], 0xa000020: ["Large Flannel Cloth", 0x1237, "Small Flannel Cloth", 0x1337], - 0xa000039: ["Large Alchemist Cloth", 0x125b, "Small Alchemist Cloth", 0x135b], 0x900000e: ["Large Spooky Cloth", 0x125c, "Small Spooky Cloth", 0x135c], 0x014B0082: ["Indigo Clothing Dye", 0x1038, "Indigo Accessory Dye", 0x1138], 0x018B0000: ["Dark Red Clothing Dye", 0x101f, "Dark Red Accessory Dye", 0x111f], + 0x900000a: ["Large Red USA Star Cloth", 0x1242, "Small Red USA Star Cloth", 0x1342], 0x0100cf00: ["St Patrick's Green Clothing Dye", 0x108c, "St Patrick's Green Accessory Dye", 0x118c], 0x0190EE90: ["Light Green Clothing Dye", 0x1044, "Light Green Accessory Dye", 0x1144], 0xa000032: ["Large Zebra Print Cloth", 0x124f, "Small Zebra Print Cloth", 0x134f], 0x9000004: ["Large Red Weft Cloth", 0x1219, "Small Red Weft Cloth", 0x1319], 0xa000006: ["Large Stony Cloth", 0x120c, "Small Stony Cloth", 0x130c], 0x0166CDAA: ["Medium Aqua Marine Clothing Dye", 0x1051, "Medium Aqua Marine Accessory Dye", 0x1151], - 0x5000003: ["Large Sweater Cloth", 0x1220, "Small Sweater Cloth", 0x1320], 0x01A0522D: ["Sienna Clothing Dye", 0x1079, "Sienna Accessory Dye", 0x1179], 0xa000025: ["Large Blue Fireworks Cloth", 0x123c, "Small Blue Fireworks Cloth", 0x133c], - 0xa000014: ["Large Nautical Cloth", 0x122a, "Small Nautical Cloth", 0x132a], 0x4000004: ["Large Blue Point Cloth", 0x1223, "Small Blue Point Cloth", 0x1323], +0x010000FF: ["Blue Clothing Dye", 0x1009, "Blue Accessory Dye", 0x1109], 0x01ADFF2F: ["Green Yellow Clothing Dye", 0x1034, "Green Yellow Accessory Dye", 0x1134], 0x01FFDEAD: ["Navajo White Clothing Dye", 0x105e, "Navajo White Accessory Dye", 0x115e], -0x01D87093: ["Pale Violet Red Clothing Dye", 0x1069, "Pale Violet Red Accessory Dye", 0x1169], -0x010000FF: ["Blue Clothing Dye", 0x1009, "Blue Accessory Dye", 0x1109], +0x019400D3: ["Dark Violet Clothing Dye", 0x1025, "Dark Violet Accessory Dye", 0x1125], + 0x5000003: ["Large Sweater Cloth", 0x1220, "Small Sweater Cloth", 0x1320], 0x017FFFD4: ["Aquamarine Clothing Dye", 0x1003, "Aquamarine Accessory Dye", 0x1103], + 0xa000014: ["Large Nautical Cloth", 0x122a, "Small Nautical Cloth", 0x132a], 0x5000008: ["Large Green Dragon Scale Cloth", 0x1256, "Small Green Dragon Scale Cloth", 0x1356], 0x01008B8B: ["Dark Cyan Clothing Dye", 0x1016, "Dark Cyan Accessory Dye", 0x1116], 0xa000018: ["Large Starry Night Cloth", 0x122e, "Small Starry Night Cloth", 0x132e], @@ -3132,8 +3149,7 @@ textures = { 0xa000040: ["Large Digital Navy Camo Cloth", 0x1263, "Small Digital Navy Camo Cloth", 0x1363], 0x01FFFFE0: ["Light Yellow Clothing Dye", 0x104b, "Light Yellow Accessory Dye", 0x114b], 0x018B008B: ["Dark Magenta Clothing Dye", 0x101b, "Dark Magenta Accessory Dye", 0x111b], - 0x4000003: ["Large Western Stripe Cloth", 0x1222, "Small Western Stripe Cloth", 0x1322], -0x019400D3: ["Dark Violet Clothing Dye", 0x1025, "Dark Violet Accessory Dye", 0x1125], +0x01D87093: ["Pale Violet Red Clothing Dye", 0x1069, "Pale Violet Red Accessory Dye", 0x1169], 0x01FF6347: ["Tomato Clothing Dye", 0x1084, "Tomato Accessory Dye", 0x1184], 0x01228B22: ["Forest Green Clothing Dye", 0x102c, "Forest Green Accessory Dye", 0x112c], 0x0148D1CC: ["Medium Turquoise Clothing Dye", 0x1058, "Medium Turquoise Accessory Dye", 0x1158], @@ -3142,89 +3158,91 @@ textures = { 0x01DA70D6: ["Orchid Clothing Dye", 0x1065, "Orchid Accessory Dye", 0x1165], 0xa00001d: ["Large Wind Cloth", 0x1233, "Small Wind Cloth", 0x1333], 0x01FFD700: ["Gold Clothing Dye", 0x1030, "Gold Accessory Dye", 0x1130], - 0xa000011: ["Large Vine Cloth", 0x1227, "Small Vine Cloth", 0x1327], + 0xa00003a: ["Large Mosaic Cloth", 0x125d, "Small Mosaic Cloth", 0x135d], 0xa000033: ["Large Colored Egg Cloth", 0x1250, "Small Colored Egg Cloth", 0x1350], 0x900000b: ["Large Blue USA Star Cloth", 0x1243, "Small Blue USA Star Cloth", 0x1343], +0x016A5ACD: ["Slate Blue Clothing Dye", 0x107c, "Slate Blue Accessory Dye", 0x117c], +0x01FFB6C1: ["Light Pink Clothing Dye", 0x1045, "Light Pink Accessory Dye", 0x1145], + 0x4000003: ["Large Western Stripe Cloth", 0x1222, "Small Western Stripe Cloth", 0x1322], 0xa000007: ["Large Heart Cloth", 0x120d, "Small Heart Cloth", 0x130d], - 0xa00003a: ["Large Mosaic Cloth", 0x125d, "Small Mosaic Cloth", 0x135d], +0x010000CD: ["Medium Blue Clothing Dye", 0x1052, "Medium Blue Accessory Dye", 0x1152], 0x014682B4: ["Steel Blue Clothing Dye", 0x1080, "Steel Blue Accessory Dye", 0x1180], - 0x4000001: ["Large Brown Lined Cloth", 0x1201, "Small Brown Lined Cloth", 0x1301], -0x018B4513: ["Saddle Brown Clothing Dye", 0x1074, "Saddle Brown Accessory Dye", 0x1174], -0x016A5ACD: ["Slate Blue Clothing Dye", 0x107c, "Slate Blue Accessory Dye", 0x117c], 0xa000021: ["Large Cow Print Cloth", 0x1238, "Small Cow Print Cloth", 0x1338], -0x01FFEFD5: ["Papaya Whip Clothing Dye", 0x106a, "Papaya Whip Accessory Dye", 0x116a], -0x010000CD: ["Medium Blue Clothing Dye", 0x1052, "Medium Blue Accessory Dye", 0x1152], -0x018A2BE2: ["Blue Violet Clothing Dye", 0x100a, "Blue Violet Accessory Dye", 0x110a], -0x01FFB6C1: ["Light Pink Clothing Dye", 0x1045, "Light Pink Accessory Dye", 0x1145], + 0x4000001: ["Large Brown Lined Cloth", 0x1201, "Small Brown Lined Cloth", 0x1301], 0x01000080: ["Navy Clothing Dye", 0x105f, "Navy Accessory Dye", 0x115f], -0x01B8860B: ["Dark Golden Rod Clothing Dye", 0x1017, "Dark Golden Rod Accessory Dye", 0x1117], + 0xa000011: ["Large Vine Cloth", 0x1227, "Small Vine Cloth", 0x1327], 0xa000026: ["Large Crisscross Cloth", 0x123d, "Small Crisscross Cloth", 0x133d], -0x01BDB76B: ["Dark Khaki Clothing Dye", 0x101a, "Dark Khaki Accessory Dye", 0x111a], +0x01B8860B: ["Dark Golden Rod Clothing Dye", 0x1017, "Dark Golden Rod Accessory Dye", 0x1117], +0x018A2BE2: ["Blue Violet Clothing Dye", 0x100a, "Blue Violet Accessory Dye", 0x110a], + 0x5000009: ["Large Midnight Dragon Scale Cloth", 0x1257, "Small Midnight Dragon Scale Cloth", 0x1357], 0xa00002d: ["Large Intense Clovers Cloth", 0x124a, "Small Intense Clovers Cloth", 0x134a], 0x01FFFFF0: ["Ivory Clothing Dye", 0x1039, "Ivory Accessory Dye", 0x1139], -0x01FF8C00: ["Dark Orange Clothing Dye", 0x101d, "Dark Orange Accessory Dye", 0x111d], - 0x5000009: ["Large Midnight Dragon Scale Cloth", 0x1257, "Small Midnight Dragon Scale Cloth", 0x1357], -0x01ADD8E6: ["Light Blue Clothing Dye", 0x103f, "Light Blue Accessory Dye", 0x113f], -0x01F0FFFF: ["Azure Clothing Dye", 0x1004, "Azure Accessory Dye", 0x1104], +0x01FFEFD5: ["Papaya Whip Clothing Dye", 0x106a, "Papaya Whip Accessory Dye", 0x116a], 0xa000001: ["Large Tan Diamond Cloth", 0x1207, "Small Tan Diamond Cloth", 0x1307], -0x0100FF00: ["Lime Clothing Dye", 0x104c, "Lime Accessory Dye", 0x114c], +0x01FF8C00: ["Dark Orange Clothing Dye", 0x101d, "Dark Orange Accessory Dye", 0x111d], 0x5000004: ["Large Bee Stripe Cloth", 0x1221, "Small Bee Stripe Cloth", 0x1321], + 0xa000041: ["Large Digital Fall Camo Cloth", 0x1264, "Small Digital Fall Camo Cloth", 0x1364], +0x01F0FFFF: ["Azure Clothing Dye", 0x1004, "Azure Accessory Dye", 0x1104], +0x018B4513: ["Saddle Brown Clothing Dye", 0x1074, "Saddle Brown Accessory Dye", 0x1174], 0x011E90FF: ["Dodger Blue Clothing Dye", 0x1029, "Dodger Blue Accessory Dye", 0x1129], 0x019932CC: ["Dark Orchid Clothing Dye", 0x101e, "Dark Orchid Accessory Dye", 0x111e], 0x01C71585: ["Medium Violet Red Clothing Dye", 0x1059, "Medium Violet Red Accessory Dye", 0x1159], - 0xa000041: ["Large Digital Fall Camo Cloth", 0x1264, "Small Digital Fall Camo Cloth", 0x1364], +0x0100FF00: ["Lime Clothing Dye", 0x104c, "Lime Accessory Dye", 0x114c], +0x01ADD8E6: ["Light Blue Clothing Dye", 0x103f, "Light Blue Accessory Dye", 0x113f], 0x01EEE8AA: ["Pale Golden Rod Clothing Dye", 0x1066, "Pale Golden Rod Accessory Dye", 0x1166], - 0xa00000e: ["Large Red Spotted Cloth", 0x1214, "Small Red Spotted Cloth", 0x1314], +0x01AFEEEE: ["Pale Turquoise Clothing Dye", 0x1068, "Pale Turquoise Accessory Dye", 0x1168], 0x016495ED: ["Cornflower Blue Clothing Dye", 0x1011, "Cornflower Blue Accessory Dye", 0x1111], 0x012F4F4F: ["Dark Slate Gray Clothing Dye", 0x1023, "Dark Slate Gray Accessory Dye", 0x1123], -0x01BC8F8F: ["Rosy Brown Clothing Dye", 0x1072, "Rosy Brown Accessory Dye", 0x1172], + 0xa000019: ["Large Lemon-Lime Cloth", 0x122f, "Small Lemon-Lime Cloth", 0x132f], 0x900000c: ["Large USA Star Cloth", 0x1244, "Small USA Star Cloth", 0x1344], 0x012E8B57: ["Sea Green Clothing Dye", 0x1077, "Sea Green Accessory Dye", 0x1177], 0x01F0FFF0: ["Honey Dew Clothing Dye", 0x1035, "Honey Dew Accessory Dye", 0x1135], 0xa00003b: ["Large Blue Bee Cloth", 0x125e, "Small Blue Bee Cloth", 0x135e], - 0xa000019: ["Large Lemon-Lime Cloth", 0x122f, "Small Lemon-Lime Cloth", 0x132f], +0x01BC8F8F: ["Rosy Brown Clothing Dye", 0x1072, "Rosy Brown Accessory Dye", 0x1172], 0x01DDA0DD: ["Plum Clothing Dye", 0x106e, "Plum Accessory Dye", 0x116e], 0xa000008: ["Large Skull Cloth", 0x120e, "Small Skull Cloth", 0x130e], -0x018FBC8F: ["Dark Sea Green Clothing Dye", 0x1021, "Dark Sea Green Accessory Dye", 0x1121], + 0xa00000e: ["Large Red Spotted Cloth", 0x1214, "Small Red Spotted Cloth", 0x1314], +0x01FFA07A: ["Light Salmon Clothing Dye", 0x1046, "Light Salmon Accessory Dye", 0x1146], 0x01F5F5F5: ["White Smoke Clothing Dye", 0x1089, "White Smoke Accessory Dye", 0x1189], - 0xa000015: ["Large Cactus Zag Cloth", 0x122b, "Small Cactus Zag Cloth", 0x132b], 0x01BA55D3: ["Medium Orchid Clothing Dye", 0x1053, "Medium Orchid Accessory Dye", 0x1153], -0x01FFA07A: ["Light Salmon Clothing Dye", 0x1046, "Light Salmon Accessory Dye", 0x1146], -0x01DAA520: ["Golden Rod Clothing Dye", 0x1031, "Golden Rod Accessory Dye", 0x1131], +0x018FBC8F: ["Dark Sea Green Clothing Dye", 0x1021, "Dark Sea Green Accessory Dye", 0x1121], + 0xa000015: ["Large Cactus Zag Cloth", 0x122b, "Small Cactus Zag Cloth", 0x132b], 0x01FDF5E6: ["Old Lace Clothing Dye", 0x1060, "Old Lace Accessory Dye", 0x1160], -0x01A52A2A: ["Brown Clothing Dye", 0x100b, "Brown Accessory Dye", 0x110b], + 0xa000027: ["Large Diamond Cloth", 0x123e, "Small Diamond Cloth", 0x133e], 0x9000009: ["Large Shamrock Cloth", 0x1234, "Small Shamrock Cloth", 0x1334], -0x01A9A9A9: ["Dark Gray Clothing Dye", 0x1018, "Dark Gray Accessory Dye", 0x1118], 0x5000000: ["Large Blue Striped Cloth", 0x1202, "Small Blue Striped Cloth", 0x1302], -0x01FF1493: ["Deep Pink Clothing Dye", 0x1026, "Deep Pink Accessory Dye", 0x1126], 0x0140E0D0: ["Turquoise Clothing Dye", 0x1085, "Turquoise Accessory Dye", 0x1185], +0x01A52A2A: ["Brown Clothing Dye", 0x100b, "Brown Accessory Dye", 0x110b], +0x01DAA520: ["Golden Rod Clothing Dye", 0x1031, "Golden Rod Accessory Dye", 0x1131], +0x01FF1493: ["Deep Pink Clothing Dye", 0x1026, "Deep Pink Accessory Dye", 0x1126], +0x01A9A9A9: ["Dark Gray Clothing Dye", 0x1018, "Dark Gray Accessory Dye", 0x1118], 0x01C0C0C0: ["Silver Clothing Dye", 0x107a, "Silver Accessory Dye", 0x117a], - 0xa000027: ["Large Diamond Cloth", 0x123e, "Small Diamond Cloth", 0x133e], 0xa000002: ["Large Green Weave Cloth", 0x1208, "Small Green Weave Cloth", 0x1308], 0xa000034: ["Large Spring Cloth", 0x1251, "Small Spring Cloth", 0x1351], 0x01F08080: ["Light Coral Clothing Dye", 0x1040, "Light Coral Accessory Dye", 0x1140], 0xa00002e: ["Large Celtic Knot Cloth", 0x124b, "Small Celtic Knot Cloth", 0x134b], -0x01FF00FF: ["Magenta Clothing Dye", 0x104f, "Magenta Accessory Dye", 0x114f], +0x01BDB76B: ["Dark Khaki Clothing Dye", 0x101a, "Dark Khaki Accessory Dye", 0x111a], 0xa000042: ["Large Digital Woods Camo Cloth", 0x1265, "Small Digital Woods Camo Cloth", 0x1365], 0x0132CD32: ["Lime Green Clothing Dye", 0x104d, "Lime Green Accessory Dye", 0x114d], 0x500000a: ["Large Blue Dragon Scale Cloth", 0x1258, "Small Blue Dragon Scale Cloth", 0x1358], 0x01D2B48C: ["Tan Clothing Dye", 0x1081, "Tan Accessory Dye", 0x1181], - 0xa00000f: ["Large Smiley Cloth", 0x1215, "Small Smiley Cloth", 0x1315], +0x01FF00FF: ["Magenta Clothing Dye", 0x104f, "Magenta Accessory Dye", 0x114f], 0x01191970: ["Midnight Blue Clothing Dye", 0x105a, "Midnight Blue Accessory Dye", 0x115a], 0xa000022: ["Large Lush Camo Cloth", 0x1239, "Small Lush Camo Cloth", 0x1339], 0x01F5F5DC: ["Beige Clothing Dye", 0x1005, "Beige Accessory Dye", 0x1105], 0x0198FB98: ["Pale Green Clothing Dye", 0x1067, "Pale Green Accessory Dye", 0x1167], - 0x4000006: ["Large Chainmail Cloth", 0x1225, "Small Chainmail Cloth", 0x1325], + 0xa00000f: ["Large Smiley Cloth", 0x1215, "Small Smiley Cloth", 0x1315], 0x01FFF8DC: ["Cornsilk Clothing Dye", 0x1012, "Cornsilk Accessory Dye", 0x1112], 0x01708090: ["Slate Gray Clothing Dye", 0x107d, "Slate Gray Accessory Dye", 0x117d], 0x01800080: ["Purple Clothing Dye", 0x1070, "Purple Accessory Dye", 0x1170], 0x01F0E68C: ["Khaki Clothing Dye", 0x103a, "Khaki Accessory Dye", 0x113a], 0xa000035: ["Large Hibiscus Beach Wrap Cloth", 0x1252, "Small Hibiscus Beach Wrap Cloth", 0x1352], - 0xa000012: ["Large Party Cloth", 0x1228, "Small Party Cloth", 0x1328], + 0x4000006: ["Large Chainmail Cloth", 0x1225, "Small Chainmail Cloth", 0x1325], 0x5000005: ["Large Purple Stripes Cloth", 0x1245, "Small Purple Stripes Cloth", 0x1345], 0xa000009: ["Large Red Diamond Cloth", 0x120f, "Small Red Diamond Cloth", 0x130f], 0xa00003c: ["Large Yellow Bee Cloth", 0x125f, "Small Yellow Bee Cloth", 0x135f], 0x0120B2AA: ["Light Sea Green Clothing Dye", 0x1047, "Light Sea Green Accessory Dye", 0x1147], + 0xa000012: ["Large Party Cloth", 0x1228, "Small Party Cloth", 0x1328], 0x019370D8: ["Medium Purple Clothing Dye", 0x1054, "Medium Purple Accessory Dye", 0x1154], 0x01F0F8FF: ["Alice Blue Clothing Dye", 0x1000, "Alice Blue Accessory Dye", 0x1100], 0xa00001a: ["Large Floral Cloth", 0x1230, "Small Floral Cloth", 0x1330], @@ -3234,43 +3252,84 @@ textures = { 0xa000028: ["Large Egyptian Cloth", 0x123f, "Small Egyptian Cloth", 0x133f], 0x9000006: ["Large Red Lace Cloth", 0x121b, "Small Red Lace Cloth", 0x131b], 0xa00002f: ["Large Flame Cloth", 0x124c, "Small Flame Cloth", 0x134c], - 0x5000001: ["Large Black Striped Cloth", 0x1203, "Small Black Striped Cloth", 0x1303], 0x01FFFF00: ["Yellow Clothing Dye", 0x108a, "Yellow Accessory Dye", 0x118a], 0x500000b: ["Large Red Dragon Scale Cloth", 0x1259, "Small Red Dragon Scale Cloth", 0x1359], 0x01E0FFFF: ["Light Cyan Clothing Dye", 0x1041, "Light Cyan Accessory Dye", 0x1141], 0xa000010: ["Large Bold Diamond Cloth", 0x1216, "Small Bold Diamond Cloth", 0x1316], - 0xa000003: ["Large Blue Wave Cloth", 0x1209, "Small Blue Wave Cloth", 0x1309], + 0x5000001: ["Large Black Striped Cloth", 0x1203, "Small Black Striped Cloth", 0x1303], 0x01FAF0E6: ["Linen Clothing Dye", 0x104e, "Linen Accessory Dye", 0x114e], 0x01B22222: ["Fire Brick Clothing Dye", 0x102a, "Fire Brick Accessory Dye", 0x112a], 0xa00001e: ["Large Bright Stripes Cloth", 0x1235, "Small Bright Stripes Cloth", 0x1335], 0x01F5FFFA: ["Mint Cream Clothing Dye", 0x105b, "Mint Cream Accessory Dye", 0x115b], - 0xa000043: ["Large Digital Arctic Camo Cloth", 0x1266, "Small Digital Arctic Camo Cloth", 0x1366], + 0xa000003: ["Large Blue Wave Cloth", 0x1209, "Small Blue Wave Cloth", 0x1309], 0x01FFE4C4: ["Bisque Clothing Dye", 0x1006, "Bisque Accessory Dye", 0x1106], -0x01AFEEEE: ["Pale Turquoise Clothing Dye", 0x1068, "Pale Turquoise Accessory Dye", 0x1168], 0x01FA8072: ["Salmon Clothing Dye", 0x1075, "Salmon Accessory Dye", 0x1175], 0x01DC143C: ["Crimson Clothing Dye", 0x1013, "Crimson Accessory Dye", 0x1113], 0x01808080: ["Gray Clothing Dye", 0x1032, "Gray Accessory Dye", 0x1132], 0x01EE82EE: ["Violet Clothing Dye", 0x1086, "Violet Accessory Dye", 0x1186], - 0xa000016: ["Large Big-Stripe Blue Cloth", 0x122c, "Small Big-Stripe Blue Cloth", 0x132c], 0xa000036: ["Large Blue Camo Cloth", 0x1253, "Small Blue Camo Cloth", 0x1353], - 0x5000006: ["Large Bright Floral Cloth", 0x1246, "Small Bright Floral Cloth", 0x1346], + 0xa000016: ["Large Big-Stripe Blue Cloth", 0x122c, "Small Big-Stripe Blue Cloth", 0x132c], 0x9000008: ["Large Cloud Cloth", 0x121e, "Small Cloud Cloth", 0x131e], 0xa00003d: ["Large Red Bee Cloth", 0x1260, "Small Red Bee Cloth", 0x1360], + 0xa000043: ["Large Digital Arctic Camo Cloth", 0x1266, "Small Digital Arctic Camo Cloth", 0x1366], 0x01E6E6FA: ["Lavender Clothing Dye", 0x103b, "Lavender Accessory Dye", 0x113b], + 0x5000006: ["Large Bright Floral Cloth", 0x1246, "Small Bright Floral Cloth", 0x1346], 0xa00000a: ["Large Jester Cloth", 0x1210, "Small Jester Cloth", 0x1310], 0x0187CEFA: ["Light Sky Blue Clothing Dye", 0x1048, "Light Sky Blue Accessory Dye", 0x1148], 0xa000023: ["Large Dark Camo Cloth", 0x123a, "Small Dark Camo Cloth", 0x133a], 0x01DCDCDC: ["Gainsboro Clothing Dye", 0x102e, "Gainsboro Accessory Dye", 0x112e], -0x01008080: ["Teal Clothing Dye", 0x1082, "Teal Accessory Dye", 0x1182], +0x013CB371: ["Medium Sea Green Clothing Dye", 0x1055, "Medium Sea Green Accessory Dye", 0x1155], 0x01FFC0CB: ["Pink Clothing Dye", 0x106d, "Pink Accessory Dye", 0x116d], 0x016B8E23: ["Olive Drab Clothing Dye", 0x1062, "Olive Drab Accessory Dye", 0x1162], -0x013CB371: ["Medium Sea Green Clothing Dye", 0x1055, "Medium Sea Green Accessory Dye", 0x1155], +0x01FFDAB9: ["Peach Puff Clothing Dye", 0x106b, "Peach Puff Accessory Dye", 0x116b], 0x0100CED1: ["Dark Turquoise Clothing Dye", 0x1024, "Dark Turquoise Accessory Dye", 0x1124], 0x01FFF5EE: ["Sea Shell Clothing Dye", 0x1078, "Sea Shell Accessory Dye", 0x1178], 0xa000030: ["Large Heavy Chainmail Cloth", 0x124d, "Small Heavy Chainmail Cloth", 0x134d], -0x01FFDAB9: ["Peach Puff Clothing Dye", 0x106b, "Peach Puff Accessory Dye", 0x116b], +0x015F9EA0: ["Cadet Blue Clothing Dye", 0x100d, "Cadet Blue Accessory Dye", 0x110d], 0xa000038: ["Large Jester Argyle Cloth", 0x125a, "Small Jester Argyle Cloth", 0x135a], +0xffffffff: ["Magical Clothing Dye Remover", 0x999, "Magical Accessory Dye Remover", 0x998], + 0xa000029: ["Large Purple Bones Cloth", 0x1240, "Small Purple Bones Cloth", 0x1340], +0x01FFFAFA: ["Snow Clothing Dye", 0x107e, "Snow Accessory Dye", 0x117e], +0x01FAFAD2: ["Light Golden Rod Yellow Clothing Dye", 0x1042, "Light Golden Rod Yellow Accessory Dye", 0x1142], 0x0100BFFF: ["Deep Sky Blue Clothing Dye", 0x1027, "Deep Sky Blue Accessory Dye", 0x1127], -0x015F9EA0: ["Cadet Blue Clothing Dye", 0x100d, "Cadet Blue Accessory Dye", 0x110d], +0x01FAEBD7: ["Antique White Clothing Dye", 0x1001, "Antique White Accessory Dye", 0x1101], 0xa000004: ["Large Yellow Wire Cloth", 0x120a, "Small Yellow Wire Cloth", 0x130a], +0x01CD853F: ["Peru Clothing Dye", 0x106c, "Peru Accessory Dye", 0x116c], +0x01E9967A: ["Dark Salmon Clothing Dye", 0x1020, "Dark Salmon Accessory Dye", 0x1120], + 0x9000002: ["Large Blue Lace Cloth", 0x1217, "Small Blue Lace Cloth", 0x1317], +0x01FFE4E1: ["Misty Rose Clothing Dye", 0x105c, "Misty Rose Accessory Dye", 0x115c], +0x01000000: ["Black Clothing Dye", 0x1007, "Black Accessory Dye", 0x1107], + 0x9000000: ["Large Rainbow Cloth", 0x1204, "Small Rainbow Cloth", 0x1304], +0x0187CEEB: ["Sky Blue Clothing Dye", 0x107b, "Sky Blue Accessory Dye", 0x117b], +0x01008080: ["Teal Clothing Dye", 0x1082, "Teal Accessory Dye", 0x1182], + 0xa00002b: ["Large Clanranald Cloth", 0x1247, "Small Clanranald Cloth", 0x1347], + 0xa000013: ["Large Viva Cloth", 0x1229, "Small Viva Cloth", 0x1329], +0x01CD5C5C: ["Indian Red Clothing Dye", 0x1037, "Indian Red Accessory Dye", 0x1137], +0x014169E1: ["Royal Blue Clothing Dye", 0x1073, "Royal Blue Accessory Dye", 0x1173], + 0xa00001b: ["Large Pink Dot Cloth", 0x1231, "Small Pink Dot Cloth", 0x1331], + 0xa00001f: ["Large USA Flag Cloth", 0x1236, "Small USA Flag Cloth", 0x1336], + 0xa000037: ["Large Sunburst Cloth", 0x1254, "Small Sunburst Cloth", 0x1354], +0x01FFF0F5: ["Lavender Blush Clothing Dye", 0x103c, "Lavender Blush Accessory Dye", 0x113c], + 0xa00000b: ["Large Crossbox Cloth", 0x1211, "Small Crossbox Cloth", 0x1311], + 0xa00003e: ["Large Stormy Cloth", 0x1261, "Small Stormy Cloth", 0x1361], +0x01778899: ["Light Slate Gray Clothing Dye", 0x1049, "Light Slate Gray Accessory Dye", 0x1149], +0x019ACD32: ["Yellow Green Clothing Dye", 0x108b, "Yellow Green Accessory Dye", 0x118b], + 0x4000005: ["Large Robber Cloth", 0x1224, "Small Robber Cloth", 0x1324], +0x017B68EE: ["Medium Slate Blue Clothing Dye", 0x1056, "Medium Slate Blue Accessory Dye", 0x1156], +0x01FFA500: ["Orange Clothing Dye", 0x1063, "Orange Accessory Dye", 0x1163], +0x017FFF00: ["Chartreuse Clothing Dye", 0x100e, "Chartreuse Accessory Dye", 0x110e], +0x01006400: ["Dark Green Clothing Dye", 0x1019, "Dark Green Accessory Dye", 0x1119], + 0xa000024: ["Large Teal Crystal Cloth", 0x123b, "Small Teal Crystal Cloth", 0x133b], + 0xa00002a: ["Large Plaid Cloth", 0x1241, "Small Plaid Cloth", 0x1341], +0x01FFFAF0: ["Floral White Clothing Dye", 0x102b, "Floral White Accessory Dye", 0x112b], +0x01008000: ["Green Clothing Dye", 0x1033, "Green Accessory Dye", 0x1133], + 0x4000007: ["Large Dark Blue Stripe Cloth", 0x1226, "Small Dark Blue Stripe Cloth", 0x1326], + 0xa000005: ["Large Futuristic Cloth", 0x120b, "Small Futuristic Cloth", 0x130b], +0x01F5DEB3: ["Wheat Clothing Dye", 0x1087, "Wheat Accessory Dye", 0x1187], + 0xa000017: ["Large Big-Stripe Red Cloth", 0x122d, "Small Big-Stripe Red Cloth", 0x132d], + 0xa000031: ["Large Leopard Print Cloth", 0x124e, "Small Leopard Print Cloth", 0x134e], + 0x9000003: ["Large Loud Spotted Cloth", 0x1218, "Small Loud Spotted Cloth", 0x1318], +0x01F8F8FF: ["Ghost White Clothing Dye", 0x102f, "Ghost White Accessory Dye", 0x112f], +0x01D3D3D3: ["Light Grey Clothing Dye", 0x1043, "Light Grey Accessory Dye", 0x1143], +0x01FF0000: ["Red Clothing Dye", 0x1071, "Red Accessory Dye", 0x1171], }; \ No newline at end of file diff --git a/lib/media/itemsilhouettes.png b/lib/media/itemsilhouettes.png index 7f1abf99..bcfa8b51 100644 Binary files a/lib/media/itemsilhouettes.png and b/lib/media/itemsilhouettes.png differ diff --git a/lib/media/itemsilhouettes_25p.png b/lib/media/itemsilhouettes_25p.png new file mode 100644 index 00000000..672a9e40 Binary files /dev/null and b/lib/media/itemsilhouettes_25p.png differ diff --git a/lib/muledump/dump.css b/lib/muledump/dump.css index 6b306f64..1c457a08 100644 --- a/lib/muledump/dump.css +++ b/lib/muledump/dump.css @@ -86,7 +86,7 @@ body { .menu:not(.setuptools) label:hover, .menu:not(.setuptools) input:hover ~ label, -#export div:hover, +div#export div:hover, #top > div:hover, #top > a:hover { background: #253c63 !important; color: #fff; @@ -95,12 +95,12 @@ body { .menu:not(.setuptools) div { overflow: hidden; } .menu:not(.setuptools) div>div>div { padding-left: 15px; } -#export { +div#export { width: auto; text-align: center; z-index: 2000; } -#export div { padding: 0 5px; } +div#export div { padding: 0 5px; } #totals, .mule, .guid, .reload, .item { display: inline-block; } @@ -241,12 +241,27 @@ hr { width: 40px; height: 40px; margin: 2px; - background: url(../renders.png) #545454; overflow: hidden; z-index: 100; cursor: pointer; } +.item:not(.silhouette) { + background: url(../renders.png) #545454; +} + +.item.transbackground { + background: url(../renders.png); +} + +.item.silhouette { + background: url(../media/itemsilhouettes.png) #545454; +} + +.item.silhouette25p { + background: url(../media/itemsilhouettes_25p.png) #545454; +} + .item.selected { background-color: #ffcd57; outline: 2px solid #fefe8e; @@ -608,55 +623,43 @@ div.noTotals { padding: 5px 0; } -div#whitebagTracker { +div.wbstage { display: flex; - width: 100%; - justify-content: center; - align-items: center; -} - -div#whitebagTracker:empty { - display: none; -} - -div#whitebagTracker > div.wbstage { - display: flex; - margin: 10px 0 10px 25px; background-color: #333; box-shadow: 2px 2px 8px #111; - width: 528px; + max-width: 494px; padding: 5px; flex-wrap: wrap; } -div#whitebagTracker > div.wbstage > div { +div.wbstage > div { width: 100%; } -div#whitebagTracker > div.wbstage > div:not(.items) { +div.wbstage > div:not(.items) { display: flex; align-items: center; justify-content: center; } -div#whitebagTracker > div.wbstage > div:not(:last-child) { +div.wbstage > div:not(:last-child) { margin-bottom: 5px; } -div#whitebagTracker > div.wbstage > div.header { +div.wbstage > div.header { font-size: 16px; font-weight: bold; } -div#whitebagTracker > div.wbstage > div.header:not(:first-child) { +div.wbstage > div.header:not(:first-child) { font-size: 14px; } -/*.item.wb.selected { - background-color: #bcfff1; +.item.wb.selected { + background-color: #88a09b; outline: 2px solid #dcf7fe; outline-offset: -1px; -}*/ +} .item.wb.have { background-color: #51fcff; diff --git a/lib/muledump/export.js b/lib/muledump/export.js index eca27542..7bcc7686 100644 --- a/lib/muledump/export.js +++ b/lib/muledump/export.js @@ -2,24 +2,28 @@ function render_totals(callback, override) { - var totals = window.totals; - var ids = window.ids; + if ( typeof override === 'object' ) override.adam = false; + if ( typeof override !== 'object' ) override = {adam: true}; + var totals = override.totals || window.totals; + var ids = override.sortorder || window.ids; var items = window.items; - var filter = window.filter; - var $totals = $('#totals'); + var filter = override.filter || window.filter; // set items value if provided - if ( typeof override !== 'object' && setuptools.data.config.totalsExportWidth > 0 ) override = { - items: setuptools.data.config.totalsExportWidth - }; + if ( !override.items && setuptools.data.config.totalsExportWidth > 0 ) override.items = setuptools.data.config.totalsExportWidth; // set items value to match totalswidth - if ( typeof override !== 'object' && setuptools.data.config.totalsExportWidth === -1 && setuptools.data.config.totalswidth > 0 ) override = { - items: setuptools.data.config.totalswidth - }; + if ( + !override.items && + setuptools.data.config.totalsExportWidth === -1 && + setuptools.data.config.totalswidth > 0 + ) override.items = setuptools.data.config.totalswidth; + + // determine items if set to whole screen + if ( !override.items ) override.items = Math.floor($(window).innerWidth()/setuptools.config.totalsItemWidth); - // create a default object - if ( typeof override !== 'object' ) override = {}; + // adjust the width down if smaller than standard width + override.items = ( Object.keys(totals).length < override.items ) ? Object.keys(totals).length : override.items; // automatically determine export width and height if items is set if ( $.isNumeric(override.items) ) { @@ -30,7 +34,7 @@ function render_totals(callback, override) { } // set the width and height - var w = override.w || $totals.innerWidth(), h = override.h || $totals.innerHeight(); + var w = override.w, h = override.h; // prepare our image var img = new Image(); @@ -41,28 +45,29 @@ function render_totals(callback, override) { // draw the image function render() { - c.width = w; c.height = h; - ct.font = 'bold 15px Arial,sans-serif'; - ct.textBaseline = 'bottom'; - ct.textAlign = 'right'; - ct.shadowColor = 'black'; - ct.fillStyle = '#363636'; - ct.fillRect(0, 0, c.width, c.height); - ct.fillStyle = '#545454'; - ct.strokeStyle = '#fefe8e'; - ct.lineWidth = 2; + c.width = w; c.height = h; + ct.font = 'bold 15px Arial,sans-serif'; + ct.textBaseline = 'bottom'; + ct.textAlign = 'right'; + ct.shadowColor = 'black'; + ct.fillStyle = override.bgColor || '#363636'; + ct.fillRect(0, 0, c.width, c.height); + ct.fillStyle = override.bgColorItem || '#545454'; + ct.strokeStyle = override.strokeStyle || '#fefe8e'; + ct.lineWidth = 2; var m = (h - Math.floor(h / 44) * 44 + 4) / 2; var x = m, y = m; for (var i = 0; i < ids.length; i++) { var id = ids[i], it = items[id]; - if (!totals[id]) continue; + if (!override.totals && !totals[id]) continue; + if ( override.totals && typeof override.totals[id] !== 'number' ) continue; ct.save(); ct.translate(x, y); - if (id in filter) ct.fillStyle = '#ffcd57'; + if (id in filter) ct.fillStyle = override.fillStyle || '#ffcd57'; ct.fillRect(0, 0, 40, 40); if (id in filter) ct.strokeRect(0, 0, 40, 40); ct.drawImage(img, it[3], it[4], 40, 40, 0, 0, 40, 40); - if (totals[id] > 1) { + if ( (override.fillNumbers !== false) && totals[id] > (override.minTotal || 1)) { ct.save(); ct.fillStyle = 'white'; ct.shadowBlur = 3; diff --git a/lib/muledump/mule.js b/lib/muledump/mule.js index a4277ae4..295e007a 100644 --- a/lib/muledump/mule.js +++ b/lib/muledump/mule.js @@ -6,8 +6,8 @@ var classes = window.classes; // max width of an account box in columns - var ROW = ( window.rowlength ) ? window.rowlength : 7; - var vaultlayout = ( window.vaultlayout ) ? window.vaultlayout : 0; + var ROW = ( setuptools.data.config.rowlength ) ? setuptools.data.config.rowlength : 7; + var vaultlayout = ( setuptools.data.config.vaultlayout ) ? setuptools.data.config.vaultlayout : 0; // we'll prepare this later VAULTORDER = []; @@ -19,7 +19,7 @@ return $('').addClass(type).text(text).appendTo(where); } - function item(id, type, num) { + function item(id, type, num, ext) { id = +id; if ( typeof window.items[id] === 'undefined' ) { setuptools.tmp.constantsRemovedItems.push(id); @@ -38,14 +38,27 @@ if (id !== -1 && it[1] === 0) { $r.append($('').text(ids)) } - $r.attr('data-itemId', id).css('background-position', '-' + it[3] + 'px -' + it[4] + 'px'); - setuptools.app.muledump.tooltip($r); + + $r.attr('data-itemId', id); + if ( setuptools.data.config.equipSilhouettes === false || !Array.isArray(ext) || (ext[0] !== 'equipment' || id > -1) ) { + $r.css('background-position', '-' + it[3] + 'px -' + it[4] + 'px'); + setuptools.app.muledump.tooltip($r); + } else { + // classid gets classes slot array + // slottype is found in slotMap and position taken from there + var slotmapPos = []; + Object.filter(itemsSlotTypeMap, function(key, value) { + if ( value.slotType === classes[ext[2]][4][ext[1]] ) slotmapPos = value.sheet; + }); + $r.addClass('silhouette25p'); + $r.css('background-position', '-' + slotmapPos[0] + 'px -' + slotmapPos[1] + 'px'); + } return $r; } window.item = item; - function item_listing(arr, classname) { + function item_listing(arr, classname, classid) { var $r = $('
'); for (var i = 0; i < arr.length; i++) { var itemid = arr[i]; @@ -54,7 +67,7 @@ setuptools.config.disqualifiedItemIds.push(Number(arr[i])); } if ( setuptools.tmp.constantsRemovedItems.indexOf(Number(arr[i])) > -1 ) itemid = -1; - item(itemid).appendTo($r); + item(itemid, undefined, undefined, [classname, i, classid]).appendTo($r); } if (classname) $r.addClass(classname); return $r; @@ -244,6 +257,7 @@ this.loaded = false; this.fresh = false; this.customSorting = false; + this.shrunk = false; this.dom = $('
'); if ( setuptools.app.muledump.totals.config.getKey('accountFilter').indexOf(this.guid) > -1 ) this.dom.addClass('filteringEnabled'); this.dom.appendTo($('#stage')).hide(); @@ -268,8 +282,8 @@ } // ctrl+click to disable/enable a mule - this.dom.on('click.muledump.disableMule', function(e) { - if (e.ctrlKey && !e.shiftKey) { + this.dom.on('click.muledump.disableMule', ':not(.item)', function(e) { + if (setuptools.app.muledump.keys('ctrl', e) === true && setuptools.app.muledump.keys('shift', e) === false) { self.disabled = !self.disabled; self.dom.toggleClass('disabled', self.disabled); if ( self.disabled === true && setuptools.app.muledump.totals.config.getKey('disabled').indexOf(self.guid) === -1 ) setuptools.app.muledump.totals.config.getKey('disabled').push(self.guid); @@ -287,7 +301,7 @@ // adjust account filter on shift+click of the mule this.dom.on('click.muledump.mule', function(e) { - if ( e.shiftKey === false || e.ctrlKey === true ) return; + if ( setuptools.app.muledump.keys('shift', e) === false || setuptools.app.muledump.keys('ctrl', e) === true ) return; // add account to account filter if ( setuptools.app.muledump.totals.config.getKey('accountFilter').indexOf(self.guid) === -1 ) { @@ -346,7 +360,9 @@ Mule.prototype.log = function(s, cl) { }; - Mule.prototype.error = function(s, callback) { + Mule.prototype.error = function(s, callback, options) { + + if ( typeof options !== 'object' ) options = {}; // don't show if errors are turned off if ( setuptools.data.config.errors === false ) return; @@ -382,7 +398,13 @@ // custom callback on click if ( typeof callback === 'function' ) callback(); - $(this).fadeOut(600, function () { + if ( options.action === 'removeall' ) { + + self.dom.fadeOut(600, function() { + self.dom.remove(); + }); + + } else $(this).fadeOut(600, function () { this.remove(); }); @@ -419,6 +441,8 @@ } + if ( this.deleteAccount === true ) setuptools.app.config.userDelete(guid); + }; Mule.prototype.createCounter = function(cache, callback) { @@ -612,7 +636,7 @@ eventCategory: 'detect', eventAction: 'nonJakcodexCORS' }); - if (['chrome', 'opera'].indexOf(setuptools.browser) > -1) setuptools.app.muledump.notices.add('New CORS Extension Available', setuptools.app.assistants.jakcodexcors); + if (['chrome', 'opera', 'firefox'].indexOf(setuptools.browser) > -1) setuptools.app.muledump.notices.add('New CORS Extension Available', setuptools.app.assistants.jakcodexcors); } else { @@ -634,7 +658,29 @@ // check for an error response if ( error = xml.match(/^(.*?)<\/?Error>$/) ) { - if ( error[1] === 'Internal error, please wait 5 minutes to try again!' ) { + var errOpts = {}; + if ( error[1] === 'Account credentials not valid' ) { + + // disabled invalid accounts + if ( [0,4].indexOf(setuptools.data.config.badaccounts) > -1 ) { + errOpts.action = 'removeall'; + setuptools.app.config.userToggle(self.guid); + } + + // delete invalid accounts + if ( [2,5].indexOf(setuptools.data.config.badaccounts) > -1 ) { + errOpts.action = 'removeall'; + self.deleteAccount = true; + } + + self.queueFinish(self.guid, 'error', false, error[1]); + self.error(error[1], undefined, errOpts); + setuptools.app.ga('send', 'event', { + eventCategory: 'detect', + eventAction: 'invalidCredentials' + }); + + } else if ( error[1] === 'Internal error, please wait 5 minutes to try again!' ) { self.log("Your IP is being rate limited by Deca. Waiting 5 minutes to retry."); self.queueFinish(self.guid, 'rateLimited', 'Request was rate limited by Appspot'); @@ -650,8 +696,15 @@ if ( setuptools.state.loaded === true && setuptools.data.accounts.accounts[self.guid].banned === false ) { setuptools.data.accounts.accounts[self.guid].banned = true; - setuptools.app.config.save('Banned, boo!'); + setuptools.app.config.save('Banned, boo!', true); } + + // disabled banned accounts + if ( [1,4].indexOf(setuptools.data.config.badaccounts) > -1 ) setuptools.app.config.userToggle(self.guid); + + // delete invalid accounts + if ( [3,5].indexOf(setuptools.data.config.badaccounts) > -1 ) self.deleteAccount = true; + self.queueFinish(self.guid, 'error', false, error[1]); self.error("This account is banned - RIP"); setuptools.app.ga('send', 'event', { @@ -694,6 +747,7 @@ // let's simulate a YQL response setuptools.app.uaTiming('mule', 'xmlToJson', 'start', self.guid, false, setuptools.app.uaTimingAggregate); var xmlParse = parser.parseFromString(xml, "text/xml"); + //console.log(xmlParse); var JSONData = xmlToJson(xmlParse); setuptools.app.uaTiming('mule', 'xmlToJson', 'stop', self.guid); JSONData.other = { @@ -1004,6 +1058,9 @@ } } + // add value + carr[i].muledump.CharValue = setuptools.app.muledump.value.char(this.guid, carr[i].id, true); + } } @@ -1077,7 +1134,7 @@ $name.on('click.muledump.muleAccountName', function (e) { if (e.target !== this) return; setuptools.lightbox.menu.context.close(); - if ( e.ctrlKey === true || e.shiftKey === true ) return; + if ( setuptools.app.muledump.keys('ctrl', e) === true || setuptools.app.muledump.keys('shift', e) === true ) return; var $ao = $('#accopts'); $ao.css({ left: e.pageX - 5 + 'px', @@ -1091,75 +1148,79 @@ }); $name.appendTo(this.dom); - // display account info - if (this.opt('accountinfo')) { - stats = calculateStatTotals(this.data.query.results.Chars, this.guid); - $('
\ -
Account Data Cache Age
' + stats.CacheAge + ' ' + ((stats.CacheAge === 1) ? 'day' : 'days') + '
\ -
Account Fame
' + this.data.query.results.Chars.Account.Stats.Fame + '
\ -
All Time Account Fame
' + this.data.query.results.Chars.Account.Stats.TotalFame + '
\ -
Account Gold
' + this.data.query.results.Chars.Account.Credits + '
\ -
Gift Items
' + stats.TotalGifts + '
\ -
Last Gold Purchase
' + stats.LastGoldPurchase + '
\ -
Total Char Exp
' + stats.TotalExp + '
\ -
Total Char Fame
' + stats.TotalFame + '
\ -
Total Death Fame
' + stats.TotalDeathFame + '
\ -
Total Characters
' + stats.TotalChars + '
\ -
Total Character Slots
' + ( (data.query.results.other) ? data.query.results.other.maxCharNum : 'N/A' ) + '
\ -
Total Lifetime Characters
' + ( (data.query.results.other) ? (data.query.results.other.nextCharId-1) : 'N/A' ) + '
\ -
Total Skins Unlocked
' + this.data.query.results.Chars.OwnedSkins.length + ' of ' + Object.keys(skins).length + '
\ -
Total Time Active
' + stats.TotalActive + '
\ - \ -
Total Unlocked Chests
' + stats.TotalChests + ' of ' + (vaultorders[0].vaultorder.filter(function (item) { + if ( !this.opt('shrink') ) { + + // display account info + if (this.opt('accountinfo')) { + stats = calculateStatTotals(this.data.query.results.Chars, this.guid); + $('
\ +
Account Data Cache Age
' + stats.CacheAge + ' ' + ((stats.CacheAge === 1) ? 'day' : 'days') + '
\ +
Account Fame
' + this.data.query.results.Chars.Account.Stats.Fame + '
\ +
All Time Account Fame
' + this.data.query.results.Chars.Account.Stats.TotalFame + '
\ +
Account Gold
' + this.data.query.results.Chars.Account.Credits + '
\ +
Gift Items
' + stats.TotalGifts + '
\ +
Last Gold Purchase
' + stats.LastGoldPurchase + '
\ +
Total Char Exp
' + stats.TotalExp + '
\ +
Total Char Fame
' + stats.TotalFame + '
\ +
Total Death Fame
' + stats.TotalDeathFame + '
\ +
Total Characters
' + stats.TotalChars + '
\ +
Total Character Slots
' + ((data.query.results.other) ? data.query.results.other.maxCharNum : 'N/A') + '
\ +
Total Lifetime Characters
' + ((data.query.results.other) ? (data.query.results.other.nextCharId - 1) : 'N/A') + '
\ +
Total Skins Unlocked
' + (this.data.query.results.Chars.OwnedSkins.length + Object.keys(classes).length) + ' of ' + Object.keys(skins).length + '
\ +
Total Time Active
' + stats.TotalActive + '
\ + \ +
Total Unlocked Chests
' + stats.TotalChests + ' of ' + (vaultorders[0].vaultorder.filter(function (item) { return (item !== 0) })).length + '
\ -
').appendTo(this.dom); - } +
').appendTo(this.dom); + } - // for future use - skins owned by percentage to append total skins unlocked - //' / ' + ( ((this.data.query.results.Chars.OwnedSkins.length/Object.keys(skins).length)*100).toFixed(0) ) + '%
\ + // for future use - skins owned by percentage to append total skins unlocked + //' / ' + ( ((this.data.query.results.Chars.OwnedSkins.length/Object.keys(skins).length)*100).toFixed(0) ) + '%
\ - // check for gift chests bug - var TotalGifts = 0; - if (typeof d.Account.Gifts === 'string') TotalGifts = d.Account.Gifts.split(',').length; - if (TotalGifts >= setuptools.config.giftsWarningThreshold) { + // check for gift chests bug + var TotalGifts = 0; + if (typeof d.Account.Gifts === 'string') TotalGifts = d.Account.Gifts.split(',').length; + if (TotalGifts >= setuptools.config.giftsWarningThreshold) { - // check if we should alert the user - if ( - setuptools.app.config.determineFormat(setuptools.data.accounts) === 0 || - setuptools.data.accounts.accounts[this.guid].giftsBugAck !== true - ) { + // check if we should alert the user + if ( + setuptools.app.config.determineFormat(setuptools.data.accounts) === 0 || + setuptools.data.accounts.accounts[this.guid].giftsBugAck !== true + ) { - this.error('Warning: Account is nearing the gift chests bug!', function() { + this.error('Warning: Account is nearing the gift chests bug!', function () { - if ( setuptools.app.config.determineFormat(setuptools.data.accounts) === 1 ) { + if (setuptools.app.config.determineFormat(setuptools.data.accounts) === 1) { - setuptools.data.accounts.accounts[self.guid].giftsBugAck = true; - setuptools.app.config.save('Gift Chests Bug Ack'); + setuptools.data.accounts.accounts[self.guid].giftsBugAck = true; + setuptools.app.config.save('Gift Chests Bug Ack'); - } + } - }); + }); + + } } + // reset the acknowledgement if the issue isn't detected + else if ( + setuptools.state.loaded === true && + setuptools.app.config.determineFormat(setuptools.data.accounts) === 1 && + setuptools.data.accounts.accounts[self.guid].giftsBugAck === true + ) setuptools.data.accounts.accounts[self.guid].giftsBugAck = false; } - // reset the acknowledgement if the issue isn't detected - else if ( - setuptools.state.loaded === true && - setuptools.app.config.determineFormat(setuptools.data.accounts) === 1 && - setuptools.data.accounts.accounts[self.guid].giftsBugAck === true - ) setuptools.data.accounts.accounts[self.guid].giftsBugAck = false; // sort the character list - if ( setuptools.data.config.debugging === true ) setuptools.app.uaTiming('mule', 'parseCharacterSorting', 'start', this.guid, false, setuptools.app.uaTimingAggregate); + if (setuptools.data.config.debugging === true) setuptools.app.uaTiming('mule', 'parseCharacterSorting', 'start', this.guid, false, setuptools.app.uaTimingAggregate); // if we had been customSorting we need to regenerate the totals - if ( this.customSorting === true && this.opt('chsort') !== '100' ) { + if (this.customSorting === true && this.opt('chsort') !== '100') { - this.createCounter(); - this.redoTotals = true; - this.customSorting = false; + this.createCounter(); + this.redoTotals = true; + this.customSorting = false; } @@ -1167,9 +1228,9 @@ if (this.opt('chsort') === '100') { // clean and read the active char sorting list - if ( skipCacheWrite !== true ) setuptools.app.muledump.charsort.clean(this.guid); + if (skipCacheWrite !== true) setuptools.app.muledump.charsort.clean(this.guid); var CharList = setuptools.app.muledump.charsort.read(this.guid, true); - if ( Array.isArray(CharList) && CharList.length > 0 ) { + if (Array.isArray(CharList) && CharList.length > 0) { CharList = setuptools.app.muledump.charsort.disabled(this.guid, setuptools.app.muledump.charsort.read(this.guid), CharList); this.createCounter(); @@ -1177,12 +1238,12 @@ this.customSorting = true; carr = CharList; - if ( setuptools.data.options.totalsGlobal === false ) CountingCharList = CharList; + if (setuptools.data.options.totalsGlobal === false) CountingCharList = CharList; } else { // reset the active list - if ( Array.isArray(CharList) && CharList.length === 0 ) setuptools.app.muledump.charsort.active(this.guid); + if (Array.isArray(CharList) && CharList.length === 0) setuptools.app.muledump.charsort.active(this.guid); // use default carr.sort(function (a, b) { @@ -1191,6 +1252,11 @@ } + // character value + } else if (this.opt('chsort') === '7') { + carr.sort(function (a, b) { + return b.muledump.CharValue - a.muledump.CharValue; + }); // active time } else if (this.opt('chsort') === '6') { carr.sort(function (a, b) { @@ -1246,7 +1312,8 @@ return a.id - b.id }); } - if ( setuptools.data.config.debugging === true ) setuptools.app.uaTiming('mule', 'parseCharacterSorting', 'stop', this.guid); + + if (setuptools.data.config.debugging === true) setuptools.app.uaTiming('mule', 'parseCharacterSorting', 'stop', this.guid); } @@ -1279,7 +1346,7 @@ if (!c) continue; var cl = classes[c.ObjectType]; if (!cl) continue; - if ( this.loginOnly === false && this.opt('chdesc') ) { + if ( this.loginOnly === false && !this.opt('shrink') && this.opt('chdesc') ) { f = true; @@ -1288,7 +1355,7 @@ } - if ( this.loginOnly === false && this.opt('stats') ) { + if ( this.loginOnly === false && !this.opt('shrink') && this.opt('stats') ) { f = true; var $stats = $(''); @@ -1337,25 +1404,25 @@ if (this.opt('equipment') || this.opt('inv') || dobp) { f = true; - if ( this.loginOnly === false ) var itc = $('
').addClass('items'); + if ( this.loginOnly === false && !this.opt('shrink') ) var itc = $('
').addClass('items'); if (this.opt('equipment')) { tcount = tcount.concat(eq.slice(0, 4)); - if ( this.loginOnly === false ) itc.append(item_listing(eq.slice(0, 4), 'equipment')); + if ( this.loginOnly === false && !this.opt('shrink') ) itc.append(item_listing(eq.slice(0, 4), 'equipment', c.ObjectType)); } if (this.opt('inv')) { tcount = tcount.concat(eq.slice(4, 12)); - if ( this.loginOnly === false ) itc.append(item_listing(eq.slice(4, 12), 'inv')); + if ( this.loginOnly === false && !this.opt('shrink') ) itc.append(item_listing(eq.slice(4, 12), 'inv')); } if (dobp) { tcount = tcount.concat(eq.slice(12, eq.length)); - if ( this.loginOnly === false ) itc.append(item_listing(eq.slice(12, eq.length), 'backpack')); + if ( this.loginOnly === false && !this.opt('shrink') ) itc.append(item_listing(eq.slice(12, eq.length), 'backpack')); } - if ( this.loginOnly === false ) itc.appendTo($c); + if ( this.loginOnly === false && !this.opt('shrink') ) itc.appendTo($c); } - if ( this.loginOnly === false && this.opt('hpmp')) { + if ( this.loginOnly === false && !this.opt('shrink') && this.opt('hpmp')) { var hpmp = $('
'); var hp = $('
'); var mp = $('
'); @@ -1366,7 +1433,7 @@ } // keeping this separate from the wawawa code - if ( this.loginOnly === false && this.opt('wawawa')) { + if ( this.loginOnly === false && !this.opt('shrink') && this.opt('wawawa')) { if (setuptools.tmp.gaSentWawawa !== true) { @@ -1388,7 +1455,7 @@ */ ///////////////////////// // WAWAWA PART - if (this.loginOnly === false && this.opt('wawawa')) { + if (this.loginOnly === false && !this.opt('shrink') && this.opt('wawawa')) { if ( setuptools.data.config.debugging === true ) setuptools.app.uaTiming('mule', 'parseWawawa', 'start', this.guid); function round(value, decimals) { @@ -1400,7 +1467,7 @@ var b = bonuses[k](st, c, d, value); if (!b) continue; var incr = 0; - if (typeof b === 'object') { + if (typeof b == 'object') { incr += b.add; b = b.mul; } incr += Math.floor(value * b); @@ -1418,7 +1485,7 @@ var b = bonuses[k](st, c, d, iTotalFame); if (!b) continue; var incr = 0; - if (typeof b === 'object') { + if (typeof b == 'object') { incr += b.add; b = b.mul; } incr += Math.floor(iTotalFame * b); @@ -1427,9 +1494,10 @@ } fbonus.push('\nTotal Fame : ' + iTotalFame.toLocaleString() + ' Fame' + '\n\nFirst Born : ' + d.Account.Stats.BestCharFame); + var boost = round((iTotalFame / fame), 2) var lower = 0; var upper = d.Account.Stats.BestCharFame; - if (upper - lower === 1) { + if (upper - lower == 1) { upper = +c.CurrentFame + 1; } while (upper - lower > 1) { @@ -1443,27 +1511,30 @@ } if (apply_bonus(+c.CurrentFame) < d.Account.Stats.BestCharFame) { var upperleft = upper - +c.CurrentFame; - fbonus.push('\nBase Fame Needed for First Born : ' + upper.toLocaleString() + ' (' + upperleft.toLocaleString() + ' Base Fame Left)'); + fbonus.push('\nBase Fame Needed for First Born : ' + lower.toLocaleString() + ' (' + upperleft.toLocaleString() + ' Base Fame Left)'); } - var $table = $('
'); - - function statOut(stat, value, tooltip, color){ - $('').append($(' \ - \ - ' - ).attr('title', tooltip)) - .appendTo($table); + if (iTotalFame > 0) { + if (iTotalFame > 400) { + if (iTotalFame > 2000) { + $('
').append($('
').text(' Total Fame = ' + iTotalFame.toLocaleString() + ' Fame ').attr('title', fbonus.join(''))) + .appendTo($c); + } + else { + $('
').append($('
').text(' Total Fame = ' + iTotalFame.toLocaleString() + ' Fame ').attr('title', fbonus.join(''))) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Total Fame = ' + iTotalFame.toLocaleString() + ' Fame ').attr('title', fbonus.join(''))) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Total Fame = ' + iTotalFame.toLocaleString() + ' Fame ').attr('title', fbonus.join(''))) + .appendTo($c); } - - // Total Fame - var fameColor = "bad"; - if(iTotalFame > 400){ fameColor = "great"; } - if(iTotalFame > 2000){ fameColor = "perfect"; } - statOut('Total Fame', iTotalFame.toLocaleString() + ' Fame ', fbonus.join(''), fameColor); - - // Time Active var v = st[20], ATime = []; //TIME var FPM = round(fame / v, 2) + ' Base Fame/Minute\n' + round(iTotalFame / v, 2) + ' Total Fame/Minute\nFame Boost : ' + round((iTotalFame / fame) * 100, 2) + ' %'; var divs = { 'y': 525600, 'm': 43200, 'd': 1440, 'h': 60, 'min': 1 }; @@ -1474,18 +1545,29 @@ v %= divs[s]; } - var timeColor = "bad"; - if(st[20] > 10) { timeColor = "good"; } - if(st[20] > 60){ timeColor = "great"; } - if(st[20] > 60){ timeColor = "perfect"; } - - if (ATime === "") { - statOut('Active Time', ' < 1 min', FPM, "bad") - } else { - statOut('Active Time', ATime.join(' '), FPM, timeColor) + if (st[20] > 60) { + $('
').append($('
').text(' Active Time = ' + ATime.join(' ')).attr('title', FPM)) + .appendTo($c); + } + else if (st[20] > 30) { + $('
').append($('
').text(' Active Time = ' + ATime.join(' ')).attr('title', FPM)) + .appendTo($c); + } + else if (st[20] > 10) { + $('
').append($('
').text(' Active Time = ' + ATime.join(' ')).attr('title', FPM)) + .appendTo($c); + } + else { + if (ATime == "") { + $('
').append($('
').text(' Active Time < 1 min ').attr('title', FPM)) + .appendTo($c); + } + else { + $('
').append($('
').text(' Active Time = ' + ATime.join(' ')).attr('title', FPM)) + .appendTo($c); + } } - // Tiles Uncovered var TilesDone = st[3].toLocaleString(); // TILES var TPM = round(st[3] / st[20], 0); var TilesData = []; @@ -1519,54 +1601,102 @@ TilesData.push(TPM.toLocaleString() + ' Tiles/Minute\n\n' + TilesLeft); } - var tilesColor = "bad"; - if(st[3] > 0) { tilesColor = "good"; } - if(st[3] > 1e6){ tilesColor = "great"; } - if(st[3] > 4e6){ tilesColor = "perfect"; } - - statOut('Tiles', TilesDone, TilesData, tilesColor) - + if (st[3] > 0) { + if (st[3] > 1e6) { + if (st[3] > 4e6) { + $('
').append($('
').text(' Tiles = ' + TilesDone).attr('title', TilesData)) + .appendTo($c); + } + else { + $('
').append($('
').text(' Tiles = ' + TilesDone).attr('title', TilesData)) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Tiles = ' + TilesDone).attr('title', TilesData)) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Tiles = ' + TilesDone).attr('title', TilesData)) + .appendTo($c); + } - //Tunnel Rat var QuestName = { // TUNNEL RAT - 13: 'Pirate Caves', - 14: 'Undead Lairs', - 15: 'Abysses Of Demons', - 16: 'Snake Pits', - 17: 'Spider Dens', - 18: 'Sprite Worlds', - 21: 'Tombs', - 22: 'Trenches', - 23: 'Jungles', - 24: 'Manors', - 25: 'Forest Mazes', + 13: 'Pirate Cave', + 14: 'Undead Lair', + 15: 'Abyss Of Demons', + 16: 'Snake Pit', + 17: 'Spider Den', + 18: 'Sprite World', + 21: 'Tomb', + 22: 'Trench', + 23: 'Jungle', + 24: 'Manor', + 25: 'Forest Maze', + 26: 'Lair Of Draconis', + 28: 'Haunted Cemetary', + 29: 'Cave Of A Thousand Treasures', + 30: 'Mad Lab', + 31: 'Davy Jones Locker', + 34: 'Ice Cave', + 35: 'Deadwater Docks', + 36: 'Crawling Depths', + 37: 'Woodland Labyrinth', + 38: 'Battle for Nexus', + 39: 'Shatters', + 40: 'Belladonnas Garden', + 41: 'Puppet Masters Theatre', + 42: 'Sewers', + 43: 'Hive', + 44: 'Mountain Temple', + 45: 'Nest', + 46: 'Lair Of Draconis (Hard)', + 47: 'Lost Halls', + 48: 'Cultist Hideout', + 49: 'Void', + 50: 'Puppet Master Encore', + 51: 'Lair Of Shaitan', + 52: 'Parasite Chambers', + 53: 'Magic Woods', + 54: 'Cnidarian Reefs' + }; + + var QuestName2 = { + 25: 'Forest Maze', 26: 'Lair Of Draconis', - 28: 'Haunted Cemetarys', - 29: 'Caves Of A Thousand Treasures', - 30: 'Mad Labs', - 31: 'Davy Jones Lockers', - 34: 'Ice Caves', + 28: 'Haunted Cemetary', + 29: 'Cave Of A Thousand Treasures', + 30: 'Mad Lab', + 31: 'Davy Jones Locker', + 34: 'Ice Cave', 35: 'Deadwater Docks', 36: 'Crawling Depths', - 37: 'Woodland Labyrinths', - 38: 'Battles for Nexus', + 37: 'Woodland Labyrinth', + 38: 'Battle for Nexus', 39: 'Shatters', - 40: 'Belladonnas Gardens', - 41: 'Puppet Masters Theatres', + 40: 'Belladonnas Garden', + 41: 'Puppet Masters Theatre', 42: 'Sewers', - 43: 'Hives', - 44: 'Temples', - 45: 'Nests', - 46: 'Lair Of Draconis(Hard)', + 43: 'Hive', + 44: 'Mountain Temple', + 45: 'Nest', + 46: 'Lair Of Draconis (Hard)', 47: 'Lost Halls', - 48: 'Cultist Hideouts', - 49: 'Voids', + 48: 'Cultist Hideout', + 49: 'Void', + 50: 'Puppet Master Encore', + 51: 'Lair Of Shaitan', + 52: 'Parasite Chambers', + 53: 'Magic Woods', + 54: 'Cnidarian Reefs' }; + var QuestList = []; var QuestMiss = []; for (m in QuestName) { - if (st[m] !== 0) { - if (QuestList === '') { + if (st[m] != 0) { + if (QuestList == '') { QuestList.push(st[m].toLocaleString() + ' ' + QuestName[m]); } else { @@ -1574,7 +1704,7 @@ } } else { - if (QuestMiss === '') { + if (QuestMiss == '') { QuestMiss.push(st[m] + ' ' + QuestName[m]); } else { @@ -1583,86 +1713,130 @@ } } var TratQuest = []; + var TratQuest2 = []; for (m in shortdungeonnames) { - if ( shortdungeonnames.hasOwnProperty(m) ) { - if (st[m] === 0) { - if (TratQuest === '') { - TratQuest.push(st[m] + ' ' + shortdungeonnames[m]); - } - else { - TratQuest.push('\n' + st[m] + ' ' + shortdungeonnames[m]); - } + if (st[m] == 0) { + if (TratQuest == '') { + TratQuest.push(st[m] + ' ' + shortdungeonnames[m]); + TratQuest2.push(st[m] + ' ' + shortdungeonnames[m]); + } + else { + TratQuest.push('\n' + st[m] + ' ' + shortdungeonnames[m]); + TratQuest2.push('\n' + st[m] + ' ' + shortdungeonnames[m]); } } } + for (m in QuestName2) { + if (m == 25) { + if (st[m] == 0) { + TratQuest2.push('\n\n' + st[m] + ' ' + QuestName2[m]); + } + else { + TratQuest2.push('\n'); + } + } + else { + TratQuest2.push('\n' + st[m] + ' ' + QuestName2[m]); + } + } - if (TratQuest.length === 0) { - if (QuestMiss.length === 0) { - statOut('Epic Tunnel Rat', "Complete", QuestMiss.join(' '), "perfect") + if (TratQuest.length == 0) { + if (QuestMiss.length == 0) { + $('
').append($('
').text(' Tunnel Rat = Complete').attr('title', QuestMiss.join(' '))) + .appendTo($c); } else { - statOut('Tunnel Rat', "Done", 'Remaining Uncompleted Dungeons\n' + QuestMiss.join(' ').replace(/(0 )/g, ''), "green") + $('
').append($('
').text(' Tunnel Rat = Done').attr('title', QuestMiss.join(' '))) + .appendTo($c); } } else { - var tunnelColor = "bad"; - var tunnelText = "Not Started" - - if(TratQuest.length < 10) { tunnelColor = "good"; tunnelText = "In Progress" } - if(TratQuest.length < 5){ tunnelColor = "great"; tunnelText = "In Progress" } - - statOut('Tunnel Rat', tunnelText, TratQuest.join(' '), tunnelColor) + if (TratQuest.length < 5) { + $('
').append($('
').text(' Tunnel Rat = In Progress').attr('title', TratQuest.join(' '))) + .appendTo($c); + } + else if (TratQuest.length < 10) { + $('
').append($('
').text(' Tunnel Rat = In Progress').attr('title', TratQuest.join(' '))) + .appendTo($c); + } + else if (TratQuest.length == 10) { + $('
').append($('
').text(' Tunnel Rat = Not Started').attr('title', TratQuest.join(' '))) + .appendTo($c); + } } - - //Oryx Kills var OKill = st[11]; // ORYX KILL if (OKill < 1) { - statOut('Oryx Kills', OKill, '', 'bad') + $('
').append($('
').text(' Oryx Kills = ' + OKill)) + .appendTo($c); } else { - statOut('Oryx Kills', OKill.toLocaleString(), '', 'perfect') + $('
').append($('
').text(' Oryx Kills = ' + OKill.toLocaleString())) + .appendTo($c); } - //Accuracy var ShotData = []; // ACCURACY var iAcc = round(100 * st[1] / st[0], 2); var l2Acc = (0.75 * st[0] - st[1]) / 0.25; - if (Math.ceil(l2Acc) === l2Acc) l2Acc += 1; + if (Math.ceil(l2Acc) == l2Acc) l2Acc += 1; var l2Acc2 = (0.5 * st[0] - st[1]) / 0.5; - if (Math.ceil(l2Acc2) === l2Acc2) l2Acc2 += 1; + if (Math.ceil(l2Acc2) == l2Acc2) l2Acc2 += 1; var l2Acc3 = (0.25 * st[0] - st[1]) / 0.75; - if (Math.ceil(l2Acc3) === l2Acc3) l2Acc3 += 1; + if (Math.ceil(l2Acc3) == l2Acc3) l2Acc3 += 1; l2Acc = 'Accurate : ' + Math.ceil(l2Acc3).toLocaleString() + ' Shots Left\nSharpshooter : ' + Math.ceil(l2Acc2).toLocaleString() + ' Shots Left\nSniper : ' + Math.ceil(l2Acc).toLocaleString() + ' Shots Left';; ShotData.push('Shots : ' + st[0].toLocaleString() + '\nHits : ' + st[1].toLocaleString() + '\nAbility : ' + st[2].toLocaleString() + '\n\n' + l2Acc); - var accColor = "bad"; - if(iAcc > 25) { accColor = "good"; } - if(iAcc > 50){ accColor = "great"; } - if(iAcc > 75){ accColor = "perfect"; } - - statOut('Accuracy', iAcc + ' % ', ShotData, accColor) - + if (iAcc < 75) { + if (iAcc < 50) { + if (iAcc < 25) { + $('
').append($('
').text(' Accuracy = ' + iAcc + ' % ').attr('title', ShotData)) + .appendTo($c); + } + else { + $('
').append($('
').text(' Accuracy = ' + iAcc + ' % ').attr('title', ShotData)) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Accuracy = ' + iAcc + ' % ').attr('title', ShotData)) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Accuracy = ' + iAcc + ' % ').attr('title', ShotData)) + .appendTo($c); + } - //Gods Killed var GodKillRatio = round(100 * st[8] / (st[6] + st[8]), 2); // GOD KILL var GodData =[]; var GodKillLeft = st[6] - st[8] + 1; var tenpercent = st[6] / 9 - st[8]; - GodData.push('Monster Kills : ' + st[6].toLocaleString() + '\nGod Kills : ' + st[8].toLocaleString() + '\n\nEnemy of the Gods : ' + Math.ceil(tenpercent).toLocaleString() + ' Kills Left\nSlayer of the Gods : ' + GodKillLeft.toLocaleString() + ' Kills Left'); - - var godsColor = "bad"; - if ( $.isNumeric(GodKillRatio) === false ) GodKillRatio = 0; - if(GodKillRatio > 0) { godsColor = "good"; } - if(GodKillRatio > 10){ godsColor = "great"; } - if(GodKillRatio > 50){ godsColor = "perfect"; } + GodData.push('Monster Kills : ' + st[6].toLocaleString() + '\nGod Kills : ' + st[8].toLocaleString() + '\n\nEnnemy of the Gods : ' + Math.ceil(tenpercent).toLocaleString() + ' Kills Left\nSlayer of the Gods : ' + GodKillLeft.toLocaleString() + ' Kills Left'); - statOut('God Kill Ratio', GodKillRatio + ' %', GodData, godsColor) + if (GodKillRatio > 0) { + if (GodKillRatio > 10) { + if (GodKillRatio > 50) { + $('
').append($('
').text(' God Kill Ratio = ' + GodKillRatio + ' %').attr('title', GodData)) + .appendTo($c); + } + else { + $('
').append($('
').text(' God Kill Ratio = ' + GodKillRatio + ' %').attr('title', GodData)) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' God Kill Ratio = ' + GodKillRatio + ' %').attr('title', GodData)) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' God Kill Ratio = 0 %').attr('title', GodData)) + .appendTo($c); + } - // Party Level Ups var LvlUp = st[19]; // LEVEL UP var LvlUpLeft = 1000 - st[19] + 1; if (LvlUpLeft > 0) { @@ -1676,15 +1850,27 @@ } if (LvlUpLeft <= 0) LvlUpLeft = ''; - var lvlColor = "bad"; - if(LvlUp > 0) { lvlColor = "good"; } - if(LvlUp > 100){ lvlColor = "great"; } - if(LvlUp > 1000){ lvlColor = "perfect"; } - - statOut('Level Up', LvlUp.toLocaleString(), LvlUpLeft, lvlColor) - + if (LvlUp > 0) { + if (LvlUp > 100) { + if (LvlUp > 1000) { + $('
').append($('
').text(' Level Up = ' + LvlUp.toLocaleString()).attr('title', LvlUpLeft)) + .appendTo($c); + } + else { + $('
').append($('
').text(' Level Up = ' + LvlUp.toLocaleString()).attr('title', LvlUpLeft)) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Level Up = ' + LvlUp.toLocaleString()).attr('title', LvlUpLeft)) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Level Up = ' + LvlUp.toLocaleString()).attr('title', LvlUpLeft)) + .appendTo($c); + } - // Quests Complete var QuestDone = st[12]; // QUESTS if (QuestDone < 1001) { QuestDone = QuestDone.toLocaleString() + ' / 1000'; @@ -1693,14 +1879,27 @@ QuestDone = QuestDone.toLocaleString(); } - var questsColor = "bad"; - if(st[12] > 1) { questsColor = "good"; } - if(st[12] > 500){ questsColor = "great"; } - if(st[12] > 1000){ questsColor = "perfect"; } - statOut('Quests Completed', QuestDone, QuestList.join(' '), questsColor) - - $table.appendTo($c); + if (st[12] < 1001) { + if (st[12] < 500) { + if (st[12] < 1) { + $('
').append($('
').text(' Quests Completed = ' + QuestDone).attr('title', QuestList.join(' '))) + .appendTo($c); + } + else { + $('
').append($('
').text(' Quests Completed = ' + QuestDone).attr('title', QuestList.join(' '))) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Quests Completed = ' + QuestDone).attr('title', QuestList.join(' '))) + .appendTo($c); + } + } + else { + $('
').append($('
').text(' Quests Completed = ' + QuestDone).attr('title', QuestList.join(' '))) + .appendTo($c); + } if ( setuptools.data.config.debugging === true ) setuptools.app.uaTiming('mule', 'parseWawawa', 'stop', this.guid); } @@ -1719,14 +1918,14 @@ } - if (f) { + if (!this.opt('shrink') && f) { this.dom.append($('
')); maketable('chars', arr).appendTo(this.dom); } arr = []; // record cummulative timing data - setuptools.app.ga('timing', { + if ( typeof timing.aggregate['mule-mainCharLoopTimer'] === 'object' ) setuptools.app.ga('timing', { category: 'mule', key: 'parseMainCharacterLoop', value: timing.aggregate['mule-mainCharLoopTimer'].mean @@ -1770,7 +1969,7 @@ if (this.opt('vaults')) { if ( setuptools.data.config.debugging === true ) setuptools.app.uaTiming('mule', 'parseVaults', 'start', this.guid, false, setuptools.app.uaTimingAggregate); - if ( this.loginOnly === false ) this.dom.append($('
')); + if ( this.loginOnly === false && !this.opt('shrink') ) this.dom.append($('
')); if ( !chests ) { @@ -1804,7 +2003,7 @@ arr.push(makechest(chest, 'vaults')); } - if ( this.loginOnly === false ) maketable('vaults', arr, w[0]).appendTo(this.dom); + if ( this.loginOnly === false && !this.opt('shrink') ) maketable('vaults', arr, w[0]).appendTo(this.dom); if ( setuptools.data.config.debugging === true ) setuptools.app.uaTiming('mule', 'parseVaults', 'stop', this.guid); } @@ -1821,7 +2020,7 @@ if (this.opt('gifts')) { if ( setuptools.data.config.debugging === true ) setuptools.app.uaTiming('mule', 'parseGifts', 'start', this.guid, false, setuptools.app.uaTimingAggregate); - if ( this.loginOnly === false ) this.dom.append($('
')); + if ( this.loginOnly === false && !this.opt('shrink') ) this.dom.append($('
')); if ( Array.isArray(items) === true ) { var garr = []; @@ -1830,7 +2029,7 @@ garr.push(makechest(items, 'gifts')); items = items.slice(8); } - if ( this.loginOnly === false ) maketable('gifts', garr, ( (setuptools.data.config.giftChestWidth === 0) ? setuptools.data.config.rowlength : setuptools.data.config.giftChestWidth )).appendTo(this.dom); + if ( this.loginOnly === false && !this.opt('shrink') ) maketable('gifts', garr, ( (setuptools.data.config.giftChestWidth === 0) ? setuptools.data.config.rowlength : setuptools.data.config.giftChestWidth )).appendTo(this.dom); } if ( setuptools.data.config.debugging === true ) setuptools.app.uaTiming('mule', 'parseGifts', 'stop', this.guid); @@ -1856,27 +2055,27 @@ this.dom.on('click.mule.screenshot', function(e) { var dom = $(this)[0]; // this does not work as intended; need to clone somehow instead: // $(dom).find('.button').remove(); - if ( e.shiftKey === true && e.ctrlKey === true ) setuptools.app.muledump.exporter.canvas(dom); + if ( setuptools.app.muledump.keys(['ctrl','shift'], e) === true ) setuptools.app.muledump.exporter.canvas(dom); }); // hotkey for creating image of all chars this.dom.find('table.chars').on('click.chars.screenshot', function(e) { - if ( e.shiftKey === true && e.ctrlKey === true ) setuptools.app.muledump.exporter.canvas($(this)[0]); + if ( setuptools.app.muledump.keys(['ctrl','shift'], e) === true ) setuptools.app.muledump.exporter.canvas($(this)[0]); }); // hotkey for creating image of a char this.dom.find('table.chars > tr > td.cont').on('click.char.screenshot', function(e) { - if ( e.shiftKey === true && e.ctrlKey === true ) setuptools.app.muledump.exporter.canvas($(this)[0]); + if ( setuptools.app.muledump.keys(['ctrl','shift'], e) === true ) setuptools.app.muledump.exporter.canvas($(this)[0]); }); // hotkey for creating image of specific vault this.dom.find('table.vaults > tr > td.cont').on('click.vault.screenshot', function(e) { - if ( e.shiftKey === true && e.ctrlKey === true ) setuptools.app.muledump.exporter.canvas($(this)[0]); + if ( setuptools.app.muledump.keys(['ctrl','shift'], e) === true ) setuptools.app.muledump.exporter.canvas($(this)[0]); }); // hotkey for creating image of gift chests this.dom.find('table.gifts').on('click.gifts.screenshot', function(e) { - if ( e.shiftKey === true && e.ctrlKey === true ) setuptools.app.muledump.exporter.canvas($(this)[0]); + if ( setuptools.app.muledump.keys(['ctrl','shift'], e) === true ) setuptools.app.muledump.exporter.canvas($(this)[0]); }); }; diff --git a/lib/muledump/muledump.js b/lib/muledump/muledump.js index 2d27660b..32700041 100644 --- a/lib/muledump/muledump.js +++ b/lib/muledump/muledump.js @@ -44,12 +44,14 @@ setuptools.app.mulecrypt.init(function() { // bind itemFilter interactions $('body').on('click.muledump.itemFilter', '.item:not(.noselect)', function(e) { - if ( e.shiftKey === true ) { + console.log('s', e, setuptools.app.muledump.keys('shift', e)); + if ( setuptools.app.muledump.keys('shift', e) === true ) { setuptools.app.muledump.totals.toggleHideItem($(this).attr('data-itemid')); return; } - if ( e.ctrlKey === false ) { + console.log('e', setuptools.app.muledump.keys('ctrl', e)); + if ( setuptools.app.muledump.keys('ctrl', e) === false ) { window.toggle_filter(this); } else { setuptools.app.muledump.realmeye.itemSelection(this); diff --git a/lib/muledump/options.js b/lib/muledump/options.js index 6e530e3a..220d59a9 100644 --- a/lib/muledump/options.js +++ b/lib/muledump/options.js @@ -19,6 +19,7 @@ backpack: true, gifts: false, wawawa: false, + shrink: false, // totals menu options totals: true, @@ -30,7 +31,8 @@ sbfilter: false, nonsbfilter: false, utfilter: false, - stfilter: false + stfilter: false, + wbfilter: false, // remaining keys are auto-generated on startup from window.itemsSlotTypeMap key names // see setuptools.app.muledump.totals.updateSecondaryFilter() for generation code }; @@ -50,7 +52,7 @@ 'chdesc': 'Char Description', 'chsortchoice': { 'label': 'Char Sort', - 'radio': ['chsort', {0: 'ID', 1: 'Base Fame', 2: 'Total Fame', 3: 'Base Exp', 4: 'Class', 5: 'Active Time', 6: 'Maxed Stats', 100: 'Custom'}] + 'radio': ['chsort', {0: 'ID', 1: 'Base Fame', 2: 'Total Fame', 3: 'Base Exp', 4: 'Class', 5: 'Active Time', 6: 'Maxed Stats', 100: 'Custom'}] //7: 'Character Value', }, 'equipment': 'Equipment', 'hpmp': 'HP/MP Pots', @@ -72,10 +74,11 @@ }, 'pcstats': 'Additional Stats', 'goals': 'Achievement Progress', - 'wawawa': 'Wawawa\'s Progress Tracker' + 'wawawa': 'Wawawa\'s Progress Tracker', + 'shrink': 'Shrink Mules', }; - var globalopts = { 'totals': 1, 'famefilter': 1, 'feedfilter': 1, 'sbfilter': 1, 'nonsbfilter': 1, 'utfilter': 1, 'stfilter': 1 }; + var globalopts = { 'totals': 1, 'famefilter': 1, 'feedfilter': 1, 'sbfilter': 1, 'nonsbfilter': 1, 'utfilter': 1, 'stfilter': 1, 'wbfilter': 1 }; var hiddenopts = { 'sttype': 1, 'fameamount': 1, 'feedpower': 1, 'vaultlayout': 1, 'chsort': 1, 'chsortchoice': 1, 'vaults': 1}; function gen_option(o, $targ, guid) { @@ -103,6 +106,10 @@ options[guid] = options[guid] || {}; options[guid][name] = $(this).is(':checked'); options_save(); + if ( ['totals', 'accountinfo', 'accountName', 'email', 'chdesc', 'pcstats', 'stats', 'wawawa', 'updatecheck'].indexOf(o) === -1 ) { + window.update_totals(); + window.update_filter(); + } window.mules[guid].query(false, true); } else { options[name] = $(this).is(':checked'); @@ -143,6 +150,10 @@ options[guid] = options[guid] || {}; options[guid][name] = $this.is(':checked') ? $this.val() : false; options_save(); + if ( ['totals', 'accountinfo', 'accountName', 'email', 'chdesc', 'pcstats', 'stats', 'wawawa', 'updatecheck'].indexOf(o) === -1 ) { + window.update_totals(); + window.update_filter(); + } mule.query(false, true); } else { options[name] = $this.is(':checked') ? $this.val() : false; diff --git a/lib/muledump/portrait.js b/lib/muledump/portrait.js index da960a4c..d112ca15 100644 --- a/lib/muledump/portrait.js +++ b/lib/muledump/portrait.js @@ -153,7 +153,7 @@ var queue = []; var st; - window.portrait = function (img, type, skin, tex1, tex2) { + window.portrait = function (img, type, skin, tex1, tex2, adjust) { if (!ready) return queue.push(Array.prototype.slice.apply(arguments)); // fallback to default skin, this happens when loading new skins on outdated renders @@ -168,12 +168,39 @@ var x16 = skinData[2]; // adjustments - if ( x16 && [11,13].indexOf(skinData[1]) > -1 ) img.css({ + if ( adjust !== false && x16 && [11,13].indexOf(skinData[1]) > -1 ) img.css({ "overflow": 'hidden', "margin-top": '-7px', "margin-right": "7px" }); + // apply texture tooltip + if ( setuptools.data.config.tooltip > 0 && (textures[tex1] || textures[tex2]) ) { + + var large; + var small; + if ( textures[tex1] ) large = items[textures[tex1][1]]; + if ( textures[tex2] ) small = items[textures[tex2][3]]; + + setuptools.app.muledump.tooltip(img, 'mb5 autoHeight', ' \ +
\ + ' + ( (textures[tex1] ) ? + '
\ +
 
\ +
' + (textures[tex1][0] || 'Default') + '
\ +
' : '' + ) + ' \ + ' + ( (textures[tex2] ) ? + '
\ +
 
\ +
' + (textures[tex2][2] || 'Default') + '
\ +
' : '' + ) + '\ +
\ + '); + + } + if (c) return img.attr('src', c); diff --git a/lib/muledump/realmapi.js b/lib/muledump/realmapi.js index eb04597f..7793f6d7 100644 --- a/lib/muledump/realmapi.js +++ b/lib/muledump/realmapi.js @@ -51,7 +51,8 @@ dataType: 'text', url: url, complete: callback, - error: setuptools.app.assistants.xhrError + error: setuptools.app.assistants.xhrError, + timeout: setuptools.config.realmApiTimeout }) } diff --git a/lib/muledump/totals.js b/lib/muledump/totals.js index 8ba1edbd..ae248477 100644 --- a/lib/muledump/totals.js +++ b/lib/muledump/totals.js @@ -117,15 +117,16 @@ function update_totals() { if ( setuptools.tmp.totalsSecondaryFilter.indexOf(id) > -1 ) return true; if ( setuptools.app.muledump.totals.config.getKey('itemFilter').indexOf(id) > -1 ) return true; - if (!options.famefilter && !options.feedfilter && !options.utfilter && !options.sbfilter && !options.stfilter && !options.nonsbfilter ) return false; + if (!options.famefilter && !options.feedfilter && !options.utfilter && !options.sbfilter && !options.stfilter && !options.nonsbfilter && !options.wbfilter ) return false; var i = items[id] || items[-1]; - if (options.famefilter && i[5] <= +options.fameamount) return true; - if (options.feedfilter && i[6] <= +options.feedpower) return true; - if (options.utfilter && [0,2].indexOf(i[9]) > -1 ) return true; - if (options.stfilter && [0,1].indexOf(i[9]) > -1 ) return true; - if (options.sbfilter && i[8] === false ) return true; - if (options.nonsbfilter && i[8] === true ) return true; + if ( options.famefilter && i[5] <= +options.fameamount ) return true; + if ( options.feedfilter && i[6] <= +options.feedpower ) return true; + if ( options.utfilter && [0,2].indexOf(i[9]) > -1 ) return true; + if ( options.stfilter && [0,1].indexOf(i[9]) > -1 ) return true; + if ( options.sbfilter && i[8] === false ) return true; + if ( options.nonsbfilter && i[8] === true ) return true; + if ( options.wbfilter && i[7] !== 6 ) return true; return false; } @@ -266,20 +267,20 @@ function toggle_filter(self) { function update_filter() { - $('.item.selected').filter(function() { + $('.item.selected:not(.noselect)').filter(function() { return !($(this).data('id') in filter); }).removeClass('selected'); - $('.item').filter(function() { + $('.item:not(.noselect)').filter(function() { return $(this).data('id') in filter; }).addClass('selected'); - if ($.isEmptyObject(filter) || $('.item.selected:visible').length === 0) { + if ($.isEmptyObject(filter) || $('.item.selected:not(.noselect):visible').length === 0) { var mules = window.mules; for (var i in mules) if (mules[i].loaded) mules[i].dom.css('display', 'inline-block'); return; } // if filtering - var selected = $('.item.selected'); + var selected = $('.item.selected:not(.noselect)'); var itemList = []; for ( var s = 0; s < selected.length; s++ ) { diff --git a/lib/setuptools/css/setuptools.css b/lib/setuptools/css/setuptools.css index 579bd699..1d0258a3 100644 --- a/lib/setuptools/css/setuptools.css +++ b/lib/setuptools/css/setuptools.css @@ -101,8 +101,18 @@ input.setuptools.app.wideinput { color: #ffffff; } +.featherlight-inner select:focus { + border: #22b7da solid 2px !important; +} + +.featherlight-inner select:hover { + border: #5f9eb1 solid 2px; + transition: 0.1s linear; +} + .featherlight-inner select, .featherlight-inner input { + transition: 0.1s linear; font-size: 12px; width: 200px; border: #707070 solid 2px; @@ -800,7 +810,7 @@ div.massSwitch > div.link { width: 200px; padding: 3px; color: #00ceff; - background-color: #12182b; + background-color: #132236; border: #000 solid 2px; margin-right: 5px; transition: 0.3s linear; @@ -837,7 +847,7 @@ div.AccountsList > div.controller.exportAccountsJS:hover, .menuStyle.negative { color: #f6a084; - background-color: #2b1215; + background-color: #321417; } .menuStyle.negative:hover { @@ -882,7 +892,7 @@ div.AccountsList > div.controller.exportAccountsJS:hover, .menuStyle.notice { color: #c78bff; - background-color: #231525; + background-color: #2c1d2e; } .menuStyle.notice:hover { @@ -1016,6 +1026,19 @@ div.AccountsList > div.controller.exportAccountsJS:hover, width: 600px; } +.fl-Wardrobe .featherlight-content { + max-width: 570px; +} + +.fl-Wardrobe.short .featherlight-content { + max-width: 75%; + max-height: 60%; +} + +.fl-Whitebags .featherlight-content { + width: 564px; +} + .fl-MuleCryptAnimated.featherlight { background: rgba(0, 0, 0, 0.8) url('../../media/mulecrypt-background.svg') !important; transition: background-color 2s ease; @@ -1028,20 +1051,24 @@ div.AccountsList > div.controller.exportAccountsJS:hover, /* other */ +.m0 { + margin: 0 !important; +} + .ml5 { - margin-left: 5px; + margin-left: 5px !important; } .mb5 { - margin-bottom: 5px; + margin-bottom: 5px !important; } .mb0 { - margin-bottom: 0; + margin-bottom: 0 !important; } .mr5 { - margin-right: 5px; + margin-right: 5px !important; } .mr0 { @@ -1049,15 +1076,19 @@ div.AccountsList > div.controller.exportAccountsJS:hover, } .mt10 { - margin-top: 10px; + margin-top: 10px !important; } .mt5 { - margin-top: 5px; + margin-top: 5px !important; } .mt15 { - margin-top: 15px; + margin-top: 15px !important; +} + +.ol1 { + margin-left: -1px !important; } .w100 { @@ -1117,11 +1148,16 @@ input[type="checkbox"] { margin-right: 0 !important; } -.dragbox div.selected, .selected:not(.item) { +.dragbox div.selected, +.selected:not(.item) { background-color: #040f51 !important; color: #22b7da !important; } +div.tooltip:not(.autoHeight) { + height: 36px; +} + div.tooltip { z-index: 500; position: absolute; @@ -1129,14 +1165,30 @@ div.tooltip { color: #ffffff; text-align: left; background-color: #2c2c2c; - height: 36px; } +.highz, +.whitebagTrackerTooltip, +.ownedSkinsTooltip, .hiddenItemsTooltip, .itemSubsortingTooltip { z-index: 9999999999 !important; } +.ownedSkinsTooltip { + display: flex; + justify-content: center; + align-items: center; + border: 2px solid #ffffff !important; + margin-top: -5px; + margin-left: -1px; +} + +div.ownedSkinsTooltip > div { + padding: 5px 10px; + color: #fff; +} + div.tooltip > div:not(.ignore) { padding: 4px; } @@ -1349,10 +1401,20 @@ a.rateLimited:hover { background-color: #2c2c2c !important; } -.exporterMenu { +div.exporterMenu { text-align: center; } +div.exporterMenu > div:nth-child(1), +div.exporterMenu > div:nth-child(2) { + padding: 0 15px 0 0; +} + +textarea.setuptools.text.exporter { + height: 400px; + margin: 15px 0 0 0; +} + .mulequeue-topMenu a, .mulequeue-topMenu a:hover, .exporterMenu a, @@ -1627,7 +1689,7 @@ strong.info { } .realmeyeBorder { - background-color: #00b0fc; + background-color: #00b0fc !important; } #itemSubsortingBox { @@ -1666,9 +1728,11 @@ strong.info { transition: 0.3s linear; } +.ownedSkins img.enabled, .mule.filteringEnabled, .itemSlotTypeSorting.enabled, -.charsort.enabled { +.charsort.enabled, +.enabled.item.cloth.selector { border: #00eaff solid 1px !important; } @@ -1725,8 +1789,9 @@ strong.info { } #drawhelpBox h3 { - color: #90ccff; + color: #74c8ff; background-color: #333; + padding: 2px 5px; } #drawhelpBox h4 { @@ -1765,3 +1830,80 @@ div#charField > div.cell { margin: 5px; padding: 4px 2px 2px 2px; } + +.ownedSkins:not(:last-child) { + margin-bottom: 20px; +} + +div.ownedSkins { + background-color: #222; + justify-content: flex-start; + flex-wrap: wrap; +} + +div.ownedSkins > div:nth-child(1) { + justify-content: space-between; + padding: 5px; + border: 2px solid #000000; + background-color: #333; +} + +div.ownedSkins > div:nth-child(1) > div { + font-size: 14px; +} + +div.ownedSkins > div:nth-child(1) > div:nth-child(2) { + font-weight: bold; +} + +div.item.cloth.selector:hover:not(.enabled), +div.item.wb:hover:not(.selected), +img.ownedSkins:hover { + outline: solid 2px #ffffff !important; + outline-offset: -1px; + transition: 0.1s linear; +} + +div.wbmenu { + justify-content: space-evenly; + flex-wrap: wrap; + margin-bottom: 10px; +} + +div.wbmenu:last-child { + margin-bottom: 16px; +} + +div.wbmenu > div:nth-child(1) { + width: 45%; + justify-content: flex-end; +} + +div.wbmenu > div:nth-child(2) { + width: 45%; + justify-content: flex-start; +} + +div.wbmenu > div:nth-child(1) > select, +div.wbmenu > div:nth-child(2) > div { + width: 50%; + height: 26px; +} + +div.wbimportoptions { + justify-content: space-between; + margin: 25px 0 0 0; + flex-flow: column; +} + +div.wbimportoptions > div { + justify-content: space-between; +} + +.bg222 { + background-color: #222; +} + +.bg333 { + background-color: #333; +} diff --git a/lib/setuptools/src/app.js b/lib/setuptools/src/app.js index f0cf9cd6..9a9c57dc 100644 --- a/lib/setuptools/src/app.js +++ b/lib/setuptools/src/app.js @@ -143,7 +143,10 @@ setuptools.app.index = function(config) { $('.setuptools.config.settings').on('click.setuptools.settings', setuptools.app.config.settings); $('.setuptools.config.import').on('click.setuptools.import', setuptools.app.accounts.AccountsJSImport); $('.setuptools.app.intro').on('click.setuptools.introduction', setuptools.app.introduction); - $('.setuptools.config.totals').on('click.setuptools.totals', setuptools.app.muledump.totals.menu.settings); + $('.setuptools.config.totals').on('click.setuptools.totals', function() { + setuptools.lightbox.insert('totalsmenu-settings', 'goback', ['totalsmenu-settings', setuptools.app.index]); + setuptools.app.muledump.totals.menu.settings(); + }); }; @@ -617,7 +620,7 @@ setuptools.app.techlog = function(msg, type) { // if ( window.verbosity ) verbosity = window.verbosity; // debug logging to console - if ( (window.debugging === true && type === 'string') || type === 'force' ) console.log(msg); + if ( (setuptools.data.config.debugging === true && type === 'string') || type === 'force' ) console.log(msg); // process tech report if enabled // this is no longer enabled for the time being diff --git a/lib/setuptools/src/assistants.js b/lib/setuptools/src/assistants.js index a5ad3d3a..af3aec12 100644 --- a/lib/setuptools/src/assistants.js +++ b/lib/setuptools/src/assistants.js @@ -82,13 +82,13 @@ setuptools.app.assistants.cors = function(force) {

If it fails to load then you are having connectivity issues with ROTMG. \ ' + // chrome/opera extension notice - ( (setuptools.state.extension !== true && ['chrome','opera'].indexOf(setuptools.browser) > -1) ? ' \ + ( (setuptools.state.extension !== true && ['chrome','opera','firefox'].indexOf(setuptools.browser) > -1) ? ' \

Upgrade Your CORS Extension \
It does not look like you are using the Jakcodex/Muledump CORS Adapter browser extension. Is it on? \

You can read about upgrading to the Muledump CORS Adapter in the wiki.\ ' : '' ) + // other browser notice - ( ( ['chrome','opera'].indexOf(setuptools.browser) === -1 ) ? ' \ + ( ( ['chrome','opera','firefox'].indexOf(setuptools.browser) === -1 ) ? ' \

Jakcodex/Muledump recommends Google Chrome \
If you like your browser and can get it working in a way you like, then great you can disregard this.\

If not then we recommend you install Google Chrome and run through the Installation and Setup Guide.\ @@ -226,19 +226,19 @@ setuptools.app.assistants.jakcodexcors = function() { var variant = ''; if ( setuptools.browser === 'chrome' ) variant = 'Chrome'; - if ( setuptools.browser === 'Opera' ) variant = 'Opera'; + if ( setuptools.browser === 'opera' ) variant = 'Opera'; + if ( setuptools.browser === 'firefox' ) variant = 'Firefox'; if ( variant === '' ) return; setuptools.lightbox.build('jakcodexcors-extension-notice', " \ - Jakcodex/Muledump is pleased to introduce a new CORS extension now available in the Chrome Web Store!\ + Jakcodex/Muledump provides a CORS extension for " + variant + " users.\

\ \ -
Since adding Usage Analytics we now know that 65% of daily users experience some form of CORS errors. Many users experience it multiple times per day. This is simply unacceptable.\ -

This new extension is always on and requires no configuration. Remove the old extension, install the new extension, and you're ready to go. \ +
This new extension is always on and requires no configuration. Remove the old extension, install the new extension, and you're ready to go. \

Header over to Muledump CORS Adapter in the wiki to read more.\ "); setuptools.lightbox.settitle('jakcodexcors-extension-notice', 'New ' + variant + ' Extension Available'); diff --git a/lib/setuptools/src/chsort.js b/lib/setuptools/src/chsort.js new file mode 100644 index 00000000..a15af956 --- /dev/null +++ b/lib/setuptools/src/chsort.js @@ -0,0 +1,939 @@ +/** + * @function + * @param {string} guid + * @param {number} charid + * Records the date a character id is first seen + */ +setuptools.app.muledump.charSeen = function(guid, charid) { + + charid = Number(charid); + if ( typeof setuptools.data.muledump.charsSeen[guid] !== 'object' ) setuptools.data.muledump.charsSeen[guid] = {}; + if ( typeof setuptools.data.muledump.charsSeen[guid][charid] === 'undefined' ) { + setuptools.data.muledump.charsSeen[guid][charid] = Date.now(); + setuptools.app.config.save('Recording character seen', true); + } + +}; + +/** + * @function + * @param {string} guid + * @param {string | boolean} [list] + * @returns {void | string} + * Returns active charlist for a guid if no list is provided, or sets new active charlist if valid + */ +setuptools.app.muledump.charsort.active = function(guid, list) { + + if ( !(mules[guid] instanceof Mule) ) return; + var CustomList = setuptools.data.muledump.chsortcustom.accounts[guid]; + if ( typeof CustomList !== 'object' ) return; + + // return the active list if none is provided + if ( list === false ) { + options_set('chsort', null, guid); + mules[guid].query(false, true); + return ''; + } else if ( list === true ) { + options_set('chsort', '100', guid); + mules[guid].query(false, true); + return CustomList.active; + } + + if ( typeof list !== 'string' ) return CustomList.active; + if ( list === '' ) { + CustomList.active = ''; + options_set('chsort', null, guid); + setuptools.app.config.save('Muledump/Charsort changed active', true); + mules[guid].query(false, true); + return ''; + } + + if ( + typeof CustomList === 'object' && + typeof CustomList.data === 'object' && + Array.isArray(CustomList.data[list]) + ) { + + CustomList.active = list; + options_set('chsort', '100', guid); + setuptools.app.config.save('Muledump/Charsort changed active', true); + mules[guid].query(false, true); + return list; + + } + + if ( typeof CustomList === 'object' && CustomList.active ) return CustomList.active; + +}; + +/** + * @function + * @param {string} guid + * @param {string | boolean} [list] + * @param {boolean} [clist] + * @returns {*} + * Reads a character sorting list (or active) for provided guid + */ +setuptools.app.muledump.charsort.read = function(guid, list, clist) { + + if ( typeof list === 'boolean' ) { + clist = list; + list = undefined; + } + + if ( !(mules[guid] instanceof Mule) || !Array.isArray(mules[guid].data.query.results.Chars.Char) ) return; + var d = mules[guid].data.query.results.Chars; + var CharList = []; + var CustomList = setuptools.data.muledump.chsortcustom.accounts[guid]; + if ( + typeof CustomList === 'object' && + typeof CustomList.data === 'object' && + Array.isArray(CustomList.data[(list || CustomList.active)]) + ) { + + if ( typeof list !== 'string' ) list = CustomList.active; + if ( typeof CustomList.data[list] === 'undefined' ) return; + for (var i in d.Char) { + + if (d.Char.hasOwnProperty(i)) { + + var index = CustomList.data[list].indexOf(d.Char[i].id); + if (index > -1) CharList[index] = ( clist === true ) ? d.Char[i] : d.Char[i].id; + + } + + } + + // make sure no missing entries were found (i.e. dead characters) + for (var i2 = 0; i2 < CharList.length; i2++) + if (typeof CharList[i2] === 'undefined') + CustomList.data[list].splice(i2, 1); + + } + + if ( CharList.length > 0 ) setuptools.app.ga('send', 'event', { + eventCategory: 'detect', + eventAction: 'charSortCustom' + }); + + return CharList; + +}; + +/** + * @function + * @param {string} guid + * @param {string} charlist + * @param {array} CharList + * @returns {boolean} + * Sets a charlist with new data + */ +setuptools.app.muledump.charsort.set = function(guid, charlist, CharList) { + + if ( !Array.isArray(CharList) ) return false; + setuptools.app.muledump.charsort.unsaved = true; + setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist] = CharList; + return true; + +}; + +/** + * @function + * @param {function} [callback] + * @returns {void | boolean} + * Saves the configuration if any list changes were made + */ +setuptools.app.muledump.charsort.save = function(callback) { + + if ( setuptools.app.muledump.charsort.unsaved !== true ) return; + delete setuptools.app.muledump.charsort.unsaved; + setuptools.app.config.save('Muledump/Charsort saving changes'); + if ( typeof callback === 'function' ) callback(); + return true; + +}; + +/** + * @function + * @param {string} guid + * @param {string} charlist + * @returns {boolean} + * Creates an empty charlist + */ +setuptools.app.muledump.charsort.create = function(guid, charlist) { + + if ( typeof setuptools.data.muledump.chsortcustom.accounts[guid] === 'undefined' ) setuptools.data.muledump.chsortcustom.accounts[guid] = $.extend(true, {}, setuptools.objects.charlist); + if ( typeof setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist] === 'undefined' ) { + setuptools.data.muledump.chsortcustom.accounts[guid].active = charlist; + setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist] = []; + } + return true; + +}; + +/** + * @function + * @param {string} guid + * @param {string} charlist + * @returns {boolean} + * Deletes the specified charlist + */ +setuptools.app.muledump.charsort.delete = function(guid, charlist) { + + if ( + typeof setuptools.data.muledump.chsortcustom.accounts[guid] === 'undefined' || + typeof setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist] === 'undefined' + ) return false; + delete setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist]; + if ( setuptools.data.muledump.chsortcustom.accounts[guid].active === charlist ) setuptools.app.muledump.charsort.active(guid, false); + return true; + +}; + +/** + * @function + * @param {string} guid + * @param {string} charlist + * @param {string} charid + * @param {number} [position] + * @returns {void | boolean} + * Adds a charid to a list + */ +setuptools.app.muledump.charsort.add = function(guid, charlist, charid, position) { + + var CharList = setuptools.app.muledump.charsort.read(guid, charlist); + if ( !Array.isArray(CharList) ) return; + if ( CharList.indexOf(charid) > -1 ) return false; + if ( !position || position >= CharList.length ) { + CharList.push(charid); + } else CharList.splice(position, 0, charid); + setuptools.app.muledump.charsort.set(guid, charlist, CharList); + return true; + +}; + +/** + * @function + * @param {string} guid + * @param {string} charlist + * @param {string} charid + * @returns {void | boolean} + * Removes a charid from a list + */ +setuptools.app.muledump.charsort.remove = function(guid, charlist, charid) { + + var CharList = setuptools.app.muledump.charsort.read(guid, charlist); + if ( !Array.isArray(CharList) ) return; + if ( CharList.indexOf(charid) === -1 ) return false; + CharList.splice(CharList.indexOf(charid), 1); + setuptools.app.muledump.charsort.set(guid, charlist, CharList); + return true; + +}; + +/** + * @function + * @param {*} [guids] + * Clean up character sorting lists for the provided guids + */ +setuptools.app.muledump.charsort.clean = function(guids) { + + if ( typeof guids === 'undefined' ) guids = Object.keys(setuptools.data.muledump.chsortcustom.accounts); + if ( typeof guids === 'string' ) guids = [guids]; + if ( !Array.isArray(guids) ) return; + + setuptools.app.techlog('Muledump/Charsort cleanup is running'); + + // loop thru each provided guid + for ( var id = 0; id < guids.length; id++ ) { + + // a bit of sanity here + var guid = guids[id]; + var CustomList = setuptools.data.muledump.chsortcustom.accounts[guid]; + if ( + typeof CustomList === 'object' && + typeof CustomList.data === 'object' + ) { + + var saveReq = []; + var d = mules[guid].data.query.results.Chars; + + // loop thru each list for this account + for ( var list in CustomList.data ) { + + if ( CustomList.data.hasOwnProperty(list) ) { + + // loop thru all characters for this account and check match their ids to list members + var length = CustomList.data[list].length; + CustomList.data[list] = CustomList.data[list].filter(function(charid) { + return (d.Char.filter(function(char) { + return ( char.id === charid ); + }).length > 0); + }); + + if ( CustomList.data[list].length < length ) saveReq.push([list, length-CustomList.data[list].length]); + + } + + } + + // if any lists were found with bad data we'll save the changes + if (saveReq.length > 0) setuptools.app.config.save('CharSort/Cleanup updated these lists: ' + saveReq); + + } + + } + +}; + +/** + * @function + * @param a + * @param b + * @returns {number} + * For use with CharList.sort() + */ +setuptools.app.muledump.charsort.sort = function(a, b) { + + // by id + if (setuptools.data.muledump.chsortcustom.sort === 0) return a.id - b.id; + + // by fame + if (setuptools.data.muledump.chsortcustom.sort === 1) return b.CurrentFame - a.CurrentFame; + + // by total fame + if (setuptools.data.muledump.chsortcustom.sort === 2) return b.muledump.TotalFame - a.muledump.TotalFame; + + // by class, then fame + if (setuptools.data.muledump.chsortcustom.sort === 3) { + + if (a.muledump.ClassName < b.muledump.ClassName) return -1; + if (a.muledump.ClassName > b.muledump.ClassName) return 1; + if (a.muledump.ClassName === b.muledump.ClassName) { + return b.CurrentFame - a.CurrentFame; + } + return 0; + + } + +}; + +/** + * @function + * @param {string} guid + * @param {array} CharList + * @param {object} chars + * @returns {object} + * Sort thru and add disabled chars to the CharList if enabled + */ +setuptools.app.muledump.charsort.disabled = function(guid, CharList, chars) { + + if ( !(mules[guid] instanceof Mule) || !Array.isArray(mules[guid].data.query.results.Chars.Char) ) return chars; + if ( setuptools.data.muledump.chsortcustom.disabledmode === true ) { + + var unusedChars = []; + mules[guid].data.query.results.Chars.Char.filter(function (element) { + if (CharList.indexOf(element.id) === -1) unusedChars.push(element); + }); + + // sort that list + unusedChars.sort(setuptools.app.muledump.charsort.sort); + + // join both lists + chars = chars.concat(unusedChars); + + } + return chars; + +}; + +/** + * @function + * @param {string} guid + * @param {string} charlist + * Display the Char Sorting menu + */ +setuptools.app.muledump.charsort.menu = function(guid, charlist) { + + setuptools.lightbox.close('muledump-charsort'); + var variant = 'fl-Chsort'; + var lists; + var title = 'Custom Character Sorting'; + var goback = false; + + // multi-character accounts have an array here + if ( + typeof mules[guid] === 'object' && + typeof mules[guid].data === 'object' && + Array.isArray(mules[guid].data.query.results.Chars.Char) + ) { + + // select/create/manage lists + if ( typeof charlist === 'undefined' ) { + + variant = ''; + function toggleButtonDraw() { + + var toggleButtonText = 'Turn on Custom Character Sorting'; + var toggleButtonClasses = ('muledump link toggleEnabled menuStyle textCenter mr0').split(' '); + if ( mules[guid].opt('chsort') === '100' ) { + toggleButtonClasses.push('negative'); + toggleButtonText = 'Turn off Custom Character Sorting'; + } else { + toggleButtonClasses.push('positive'); + } + + return '
' + toggleButtonText + '
'; + + } + + var content = $('
'); + setuptools.lightbox.build('muledump-charsort', ' \ + Welcome to the Character Sorting menu! \ +

From here you can create, select, edit, and delete custom character sorting lists. \ +
 \ +
\ + ' + toggleButtonDraw() + '\ +
\ +
\ + \ +
\ + \ +
\ + \ + \ +
\ + ' + ( + // determine button state + ( + mules[guid].opt('chsort') !== '100' || + ( + mules[guid].opt('chsort') === '100' && + setuptools.app.muledump.charsort.active(guid) === '' + ) + ) ? + '' : + '' + ) + '\ + \ + \ +
\ +
\ + '); + + } + // character sorting gui + else { + + goback = true; + var list = setuptools.app.muledump.charsort.read(guid, charlist); + var chars = []; + + // build our list of enabled characters + mules[guid].data.query.results.Chars.Char.filter(function(element) { + if ( list.indexOf(element.id) > -1 ) chars.push(element); + }); + + // sort that list + chars.sort(function(a, b) { + if ( list.indexOf(a.id) > -1 && list.indexOf(b.id) > -1 ) return list.indexOf(a.id) - list.indexOf(b.id); + return Number(b.id) - Number(a.id); + }); + + // build out list of disabled chars + var unusedChars = []; + mules[guid].data.query.results.Chars.Char.filter(function (element) { + if (list.indexOf(element.id) === -1) unusedChars.push(element); + }); + + // sort that list + unusedChars.sort(setuptools.app.muledump.charsort.sort); + + // join both lists + chars = chars.concat(unusedChars); + chars = setuptools.app.muledump.charsort.disabled(guid, list, chars); + + var portraits = {}; + var portraitHtml = ''; + for ( var cid in chars ) { + + if ( chars.hasOwnProperty(cid) ) { + + portraits[chars[cid].id] = setuptools.app.muledump.drawPortrait(chars[cid]); + portraitHtml += '
' + portraits[chars[cid].id].html() + '
'; + + } + + } + + setuptools.lightbox.build('muledump-charsort', ' \ +
' + portraitHtml + '
\ +
⚪⚪⚪
\ +
\ +
    \ +
  1. Shift+Click characters to enable or disable them
  2. \ +
  3. Click and drag enabled characters to sort them
  4. \ +
  5. Changes save automatically when you close the UI
  6. \ +
\ +
\ +
Disabled Characters Sort Mode
\ + \ +
 
Disabled Characters Display Mode
\ + \ +
\ +
\ + '); + + } + + } + // single-character accounts have an object here + else if ( + typeof mules[guid] === 'object' && + typeof mules[guid].data === 'object' && + !Array.isArray(mules[guid].data.query.results.Chars.Char) + ) { + + variant = ''; + setuptools.lightbox.build('muledump-charsort', ' \ + This feature can only be utilized by accounts with multiple characters.\ + '); + + } + // of course, if there's no guid they she be told that + else if ( typeof guid !== 'undefined' ) { + + setuptools.lightbox.build('muledump-charsort', 'Invalid GUID specified: ' + guid); + + } else { + + setuptools.lightbox.build('muledump-charsort', 'Invalid request arguments'); + + } + + setuptools.lightbox.settitle('muledump-charsort', title); + setuptools.lightbox.drawhelp('muledump-charsort', 'docs/setuptools/help/charsort.md', 'Character Sorting Help'); + if ( goback === true ) setuptools.lightbox.goback('muledump-charsort', function() { + setuptools.app.muledump.charsort.menu(guid); + }); + setuptools.lightbox.display('muledump-charsort', { + variant: variant, + afterClose: function() { + setuptools.app.muledump.charsort.save(function() { + mules[guid].query(false, true); + }); + } + }); + + // create new list and open it in the editor + $('div.muledump.link.createNew').on('click.charsort.createnew', function() { + + var name = $('input[name="charsortNewList"]').val(); + if ( typeof name !== 'string' || name.length < 1 ) return; + setuptools.app.muledump.charsort.create(guid, name); + setuptools.app.muledump.charsort.menu(guid, name); + + }); + + // create new list and open it in the editor + $('div.muledump.link.deleteList').on('click.charsort.deleteList', function() { + + var name = $('select[name="charsortList"]').val(); + if ( typeof name !== 'string' || name.length < 1 ) return; + setuptools.app.muledump.charsort.delete(guid, name); + setuptools.app.config.save('Muledump/Charsort deleted a list', true); + setuptools.app.muledump.charsort.menu(guid); + + }); + + // change character sorting mode for disabled chars + $('select[name="chsortmode"]').on('change.chsortmode', function() { + + var value = Number($(this).val()); + if ( value > -1 && value <= 3 ) setuptools.data.muledump.chsortcustom.sort = value; + setuptools.app.muledump.charsort.unsaved = true; + if ( setuptools.data.muledump.chsortcustom.disabledmode === true ) setuptools.app.muledump.charsort.menu(guid, charlist); + + }); + + // change character disabled display mode for disabled chars + $('select[name="chsortdisabledmode"]').on('change.chsortdisabledmode', function() { + + setuptools.data.muledump.chsortcustom.disabledmode = ( $(this).val() === "1" ); + setuptools.app.muledump.charsort.unsaved = true; + setuptools.app.muledump.charsort.menu(guid, charlist); + + }); + + // toggle character enable/disable state + // did it this way so I can offer alternative bindings later on + function charsortCellToggle(e, force) { + + if ( setuptools.app.muledump.keys('shift', e) === false && force !== true ) return; + var charid = $(this).attr('data-charid'); + if ( typeof charid !== 'string' ) return; + var state = !( $(this).hasClass('enabled') ); + if ( state === true ) { + + setuptools.app.muledump.charsort.add(guid, charlist, charid, $(this).index()); + $(this).addClass('enabled'); + + } else { + + setuptools.app.muledump.charsort.remove(guid, charlist, charid); + $(this).removeClass('enabled'); + + } + + } + + $('div.charsort.cell').on('click.charsort.toggleEnable', charsortCellToggle); + + // bind character click/drag sorting + setuptools.tmp.itemSortDragging = new Muledump_Dragging({ + target: ['charsort', 'cell'], + targetattr: 'data-charid', + approach: 0.4, + callbacks: { + before: function(parent, self) { + + // validate the source and target + if ( typeof self.attr('data-charid') !== 'string' ) return false; + if ( !parent.CharList ) parent.CharList = setuptools.app.muledump.charsort.read(guid, charlist); + parent.srcIndex = parent.CharList.indexOf(self.attr('data-charid')); + parent.destIndex = parent.CharList.indexOf(parent.target); + if ( parent.srcIndex === -1 || parent.destIndex === -1 || self.attr('data-charid') === parent.target ) return; + return true; + + }, + after: function(parent, self) { + + // transform list + parent.srcId = self.attr('data-charid'); + if ( parent.srcId === parent.target ) return; + parent.CharList.splice(parent.CharList.indexOf(parent.srcId), 1); + parent.CharList.splice((parent.CharList.indexOf(parent.target)+parent.indexModifier), 0, parent.srcId); + setuptools.app.muledump.charsort.set(guid, charlist, parent.CharList); + + } + } + }); + + // bind character sorting display expansion + setuptools.lightbox.expander('#charField', '.charField.expansion'); + + // bind edit list button + $('div.muledump.link.editList').on('click.edit.list', function() { + + var name = $('select[name="charsortList"]').val(); + if ( typeof name !== 'string' || name.length < 1 ) return; + setuptools.app.muledump.charsort.menu(guid, name); + + }); + + // toggle state of charsort option + $('div.muledump.link.toggleEnabled').on('click.toggle.state', function() { + + var state = ( $(this).hasClass('positive') ); + var list = $('select[name="charsortList"]').val(); + if ( typeof list !== 'string' || list.length < 1 ) return; + if ( state === true ) { + + $(this).removeClass('positive').addClass('negative').text('Turn off Custom Character Sorting'); + + if ( + setuptools.app.muledump.charsort.active(guid) === list + ) $('div.muledump.link.enableList').removeClass('positive').text('Disable'); + + setuptools.app.muledump.charsort.active(guid, true); + + } else { + + $(this).removeClass('negative').addClass('positive').text('Turn on Custom Character Sorting'); + $('div.muledump.link.enableList').addClass('positive').text('Enable'); + setuptools.app.muledump.charsort.active(guid, false); + + } + + }); + + // bind character sorting list selection menu + $('select[name="charsortList"]').on('change.charsortList', function() { + + var list = $(this).val(); + if ( typeof list !== 'string' || list.length < 1 ) return; + if ( + options_get('chsort', guid) === '100' && + setuptools.app.muledump.charsort.active(guid) === list + ) { + $('div.muledump.link.enableList').removeClass('positive').text('Disable'); + } else $('div.muledump.link.enableList').addClass('positive').text('Enable'); + + }); + + // toggle state of lists + $('div.muledump.link.enableList').on('click.toggle.list', function() { + + var list = $('select[name="charsortList"]').val(); + var state = ( $(this).hasClass('positive') ); + if ( typeof list !== 'string' || list.length < 1 ) return; + + if ( state === true ) { + $(this).removeClass('positive').text('Disable'); + $('div.muledump.link.enableList').removeClass('positive').text('Disable'); + setuptools.app.muledump.charsort.active(guid, list); + } else { + $(this).addClass('positive').text('Enable'); + setuptools.app.muledump.charsort.active(guid, ''); + } + + }); + +}; + +/** + * @function + * @param {array} CustomList + * @param {object} mule + * @returns {{FinalList: Array, RemovedList: Array}} + * Chsort v1 - Deduplicate and validate custom character id list + */ +setuptools.app.muledump.chsortcustomDedupAndValidate = function(CustomList, mule) { + + // get our list of char ids + var FinalList = []; + var CharIdList = []; + var DuplicateList = []; + var RemovedList = []; + CustomList = CustomList.replace('#', '').split(/, ?/); + + // generate the character id list + for ( var i = 0; i < mule.data.query.results.Chars.Char.length; i++ ) CharIdList.push(mule.data.query.results.Chars.Char[i].id); + + // validate and deduplicate + for ( var i in CustomList ) { + + if ( CustomList.hasOwnProperty(i) ) { + + // is it a valid id + if ( CharIdList.indexOf(CustomList[i]) === -1 ) { + if ( typeof CustomList[i] === 'string' ) RemovedList.push(JSON.parse(JSON.stringify(CustomList[i]))); + delete CustomList[i]; + } + + // is it already in the list + if ( DuplicateList.indexOf(CustomList[i]) > -1) { + if ( typeof CustomList[i] === 'string' ) RemovedList.push(JSON.parse(JSON.stringify(CustomList[i]))); + delete CustomList[i]; + } else { + if ( typeof CustomList[i] === 'string' ) DuplicateList.push(JSON.parse(JSON.stringify(CustomList[i]))); + } + + } + + } + + // clean up our final list + for ( var i in CustomList ) + if ( CustomList.hasOwnProperty(i) ) + if ( typeof CustomList[i] === 'string' ) + FinalList.push(CustomList[i]); + + return {FinalList: FinalList, RemovedList: RemovedList}; + +}; + +/** + * @function + * @param {object} mule + * Chsort v1 - Assist the user in creating a custom sort list + */ +setuptools.app.muledump.chsortcustom = function(mule) { + + if ( !mule ) setuptools.lightbox.error('No mule provided to custom sort utility.'); + + // prepare the object is none exists + if ( typeof setuptools.data.muledump.chsortcustom.accounts[mule.guid] === 'undefined' ) setuptools.data.muledump.chsortcustom.accounts[mule.guid] = {active: '', data: {}}; + + setuptools.lightbox.build('muledump-chsortcustom-index', ' \ + Saving a list will set that list as active and overwrite any stored data for that list or create a new list item. \ +

For account :: ' + mule.guid + ' \ + ' + ( ( + setuptools.state.loaded === true && + typeof setuptools.data.accounts.accounts[mule.guid].ign === 'string' && + setuptools.data.accounts.accounts[mule.guid].ign.length > 0 + ) ? '
IGN :: ' + setuptools.data.accounts.accounts[mule.guid].ign + '' : '' ) + '\ +

Choose Existing List \ +
\ +
\ + '); + + // build our select menu + if ( Object.keys(setuptools.data.muledump.chsortcustom.accounts[mule.guid].data).length > 0 ) { + + setuptools.lightbox.build('muledump-chsortcustom-index', ' \ +
\ + '); + + } else { + + setuptools.lightbox.build('muledump-chsortcustom-index', 'No saved lists found'); + + } + + setuptools.lightbox.build('muledump-chsortcustom-index', ' \ +

List Name to Edit \ +

\ +
\ +
Prepare List \ +

Enter a list of IDs separated by commas. \ +

\ +

\ +
\ + \ + \ +
\ + '); + + setuptools.lightbox.settitle('muledump-chsortcustom-index', 'Character Sorting Lists'); + setuptools.lightbox.drawhelp('muledump-chsortcustom-index', 'docs/features/character-sorting', 'Character Sorting Lists Help'); + setuptools.lightbox.display('muledump-chsortcustom-index'); + + // populate selected data + $('select[name="chsortExisting"]').change(function() { + + var chsortId = $(this).val(); + $('input[name="chsortListName"]').val(chsortId); + $('input[name="chsortcustom"]').val(setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[chsortId].join(', ')); + + }); + + $('.setuptools.link.muledump.save.delete').click(function() { + + var chsortId = $('input[name="chsortListName"]').val(); + if ( chsortId.length === 0 ) return; + if ( typeof setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[chsortId] === 'undefined' ) return; + + // delete the list + delete setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[chsortId]; + + // set default value to top key + var newChsortId = Object.keys(setuptools.data.muledump.chsortcustom.accounts[mule.guid].data)[0]; + if ( setuptools.data.muledump.chsortcustom.accounts[mule.guid].active === chsortId ) + setuptools.data.muledump.chsortcustom.accounts[mule.guid].active = (typeof newChsortId === 'undefined' ) ? '' : newChsortId; + + // save the changes + setuptools.app.config.save('CharacterSort/Delete'); + + // update the form + $('select[name="chsortExisting"] option[value="' + chsortId + '"]').remove(); + if ( typeof newChsortId === 'string' ) { + + $('select[name="chsortExisting"] option[value="' + newChsortId + '"]').prop('selected', 'selected'); + $('input[name="chsortListName"]').val(newChsortId); + $('input[name="chsortcustom"]').val(setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[newChsortId].join(', ')); + + } + + }); + + // save changes to a list or new list + $('.setuptools.link.muledump.save.list').click(function() { + + var UserListName = $('input[name="chsortListName"]').val(); + var UserInput = $('input[name="chsortcustom"]').val(); + var Lists = false; + if ( UserInput.length > 0 ) Lists = setuptools.app.muledump.chsortcustomDedupAndValidate(UserInput, mule); + var SaveState = false; + + // save the list if it's at least 1 long + if ( typeof Lists === 'object' && Lists.FinalList.length > 0 ) { + + setuptools.data.muledump.chsortcustom.accounts[mule.guid].active = UserListName; + setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[UserListName] = $.extend(true, [], Lists.FinalList); + SaveState = setuptools.app.config.save('CharacterSort/Save'); + if ( setuptools.config.devForcePoint !== 'chsortcustom-save' && SaveState === true ) { + + if ( Lists.RemovedList.length > 0 ) setuptools.lightbox.build('muledump-chsortcustom-save', 'The follow IDs were invalid or duplicates:

' + Lists.RemovedList.join(', ') + '

'); + setuptools.lightbox.build('muledump-chsortcustom-save', 'The changes have been saved.'); + mule.query(false, true); + + } + + } else { + + // if no list is provided then we're erasing this instead + if ( UserInput.length === 0 ) { + + setuptools.lightbox.build('muledump-chsortcustom-save', 'Choose \'Delete List\' to remove a list.'); + + } else { + + setuptools.lightbox.build('muledump-chsortcustom-save', 'Oops! No valid account IDs were detected.'); + + } + + setuptools.lightbox.build('muledump-chsortcustom-save', ' \ +

Valid formats include: \ +

1, 2, 3, 4, ... \ +

1,2,3,4,... \ +

#1,#2,#3,#4,... \ +

1, #2, 3,#4, ... \ +

You get the idea. \ + '); + + } + + if ( SaveState === false ) setuptools.lightbox.build('muledump-chsortcustom-save', 'Hmm, there was a problem saving. This setting will reset on page reload.'); + setuptools.lightbox.goback('muledump-chsortcustom-save', function() { + setuptools.app.muledump.chsortcustom(mule); + }); + setuptools.lightbox.settitle('muledump-chsortcustom-save', 'Character Sorting Lists'); + setuptools.lightbox.display('muledump-chsortcustom-save'); + + + }); + +}; diff --git a/lib/setuptools/src/config.js b/lib/setuptools/src/config.js index ce8e4d03..b44b10fa 100644 --- a/lib/setuptools/src/config.js +++ b/lib/setuptools/src/config.js @@ -4,8 +4,9 @@ setuptools.app.config.settings = function(highlight, section) { var disabled = ''; var sections = { - muledump: ['accountLoadDelay', 'rowlength', 'errors', 'exportDefault', 'mulelogin', 'giftChestWidth', 'muleMenu', 'pagesearch', 'totalsExportWidth', 'totalswidth', 'nomasonry'], - settings: ['enabled', 'accountsPerPage', 'animations', 'autocomplete', 'automaticBackups', 'autoReloadDays', 'alertNewVersion', 'compression', 'debugging', 'groupsMergeMode', 'hideHeaderText', 'lazySave', 'longpress', 'lowStorageSpace', 'maximumBackupCount', 'menuPosition', 'preventAutoDownload', 'timesync'], + muledump: ['accountLoadDelay', 'rowlength', 'errors', 'equipSilhouettes', 'exportDefault', 'mulelogin', 'giftChestWidth', 'pagesearch', 'totalsExportWidth', 'totalswidth'], + settings: ['enabled', 'accountsPerPage', 'autoReloadDays', 'badaccounts', 'groupsMergeMode', 'hideHeaderText', 'maximumBackupCount', 'menuPosition'], + advanced: ['alertNewVersion', 'animations', 'autocomplete', 'automaticBackups', 'compression', 'debugging', 'lazySave', 'longpress', 'lowStorageSpace', 'muleMenu', 'nomasonry', 'preventAutoDownload', 'timesync'], assistants: ['accountAssistant', 'backupAssistant', 'corsAssistant'], system: ['ga', 'gaPing', 'gaErrors', 'gaOptions', 'gaTotals'] }; @@ -19,9 +20,10 @@ setuptools.app.config.settings = function(highlight, section) { section = i; setuptools.lightbox.build('settings', ' \ -
\ +
\ \ \ + \ \ \
\ @@ -67,6 +69,13 @@ setuptools.app.config.settings = function(highlight, section) { No \ \
\ +
\ +
Equipment Silhouettes
\ + \ +
\
\
Export Default Mode
\ \
\ -
\ -
Mule Menu
\ - \ -
\
\ -
Page Search
\ +
Page Search
\ \
\ -
\ -
Use Smart Layout
\ - \ -
\ \
\ \ @@ -170,44 +165,7 @@ setuptools.app.config.settings = function(highlight, section) {
\ '); - if (setuptools.config.devForcePoint === 'online-versioncheck' || setuptools.state.hosted === true) { - - setuptools.lightbox.build('settings', ' \ -
\ -
Alert on New Version
\ - \ -
\ - '); - - } - setuptools.lightbox.build('settings', ' \ -
\ -
Animations
\ - \ -
\ -
\ -
Auto Complete for Password Managers
\ - \ -
\ -
\ -
Automatic Backups
\ - \ -
\
\
Automatically Reload Account Data
\ \
\
\ -
Debug Logging
\ - \ + Off \ + Disable Invalid Accounts \ + Disable Banned Accounts \ + Delete Invalid Accounts \ + Delete Banned Accounts \ + Disable Both \ + Delete Both \ \
\
\ @@ -243,31 +206,6 @@ setuptools.app.config.settings = function(highlight, section) { Off \ \
\ -
\ -
Lazily Save Minor Config Changes
\ - \ -
\ -
\ -
Longpress Length in Seconds
\ - \ -
\ -
\ -
Low Storage Space Check
\ - \ -
\
\
Maximum Backups in Local Storage
\ \
\ -
\ -
Prevent Auto Download
\ - \ -
\ -
\ -
Storage Compression
\ - \ -
\ -
\ -
Time Synchronize
\ - \ -
\ '); } @@ -317,6 +234,130 @@ setuptools.app.config.settings = function(highlight, section) { \
\ \ +
\ +

Advanced Settings


\ + '); + + if (setuptools.config.devForcePoint === 'online-versioncheck' || setuptools.state.hosted === true) { + + setuptools.lightbox.build('settings', ' \ +
\ +
Alert on New Version
\ + \ +
\ + '); + + } + + setuptools.lightbox.build('settings', ' \ +
\ +
Animations
\ + \ +
\ +
\ +
Automatic Backups
\ + \ +
\ +
\ +
Auto Complete for Password Managers
\ + \ +
\ +
\ +
Debug Logging
\ + \ +
\ +
\ +
Key Bindings
\ + \ +
\ +
\ +
Lazily Save Minor Config Changes
\ + \ +
\ +
\ +
Longpress Length in Seconds
\ + \ +
\ +
\ +
Low Storage Space Check
\ + \ +
\ +
\ +
Mule Menu
\ + \ +
\ +
\ +
Prevent Auto Download
\ + \ +
\ +
\ +
Storage Compression
\ + \ +
\ +
\ +
Time Synchronize
\ + \ +
\ +
\ +
Use Smart Layout
\ + \ +
\ + \ +
\ + \
\

Program Assistants


\
\ @@ -400,8 +441,8 @@ setuptools.app.config.settings = function(highlight, section) { } setuptools.lightbox.build('settings', ' \ -
\ -

System Data


\ +
\ +

System Data

\ \ \ \ @@ -506,6 +547,7 @@ setuptools.app.config.settings = function(highlight, section) { var switchTo = false; if ( $(this).hasClass('muledump') === true ) switchTo = 'muledump'; if ( $(this).hasClass('settings') === true ) switchTo = 'settings'; + if ( $(this).hasClass('advanced') === true ) switchTo = 'advanced'; if ( $(this).hasClass('assistants') === true ) switchTo = 'assistants'; if ( $(this).hasClass('system') === true ) switchTo = 'system'; if ( switchTo === false ) return; @@ -660,7 +702,7 @@ setuptools.app.config.settings = function(highlight, section) { if ( [ 'enabled', 'preventAutoDownload', 'automaticBackups', 'debugging', 'ga', 'gaPing', 'gaErrors', 'gaOptions', 'gaTotals', 'errors', 'autocomplete', 'mqDisplayIgn', 'muleMenu', 'hideHeaderText', 'lowStorageSpace', - 'compression', 'timesync' + 'compression', 'timesync', 'equipSilhouettes' ].indexOf(name) > -1 ) { newvalue = ( setuptools.copy.config[name] === true ) ? 1 : 0; @@ -672,8 +714,8 @@ setuptools.app.config.settings = function(highlight, section) { 'maximumBackupCount', 'rowlength', 'nomasonry', 'accountLoadDelay', 'totalswidth', 'mulelogin', 'alertNewVersion', 'menuPosition', 'corsAssistant', 'accountAssistant', 'longpress', 'accountsPerPage', 'backupAssistant', 'groupsMergeMode', 'autoReloadDays', 'pagesearch', 'animations', 'giftChestWidth', - 'lazySave', 'totalsExportWidth', 'exportDefault' - ].indexOf(name) > -1 ) { + 'lazySave', 'totalsExportWidth', 'exportDefault', 'keyBindings', 'badaccounts', + ].indexOf(name) > -1 ) { newvalue = setuptools.copy.config[name]; @@ -751,6 +793,7 @@ setuptools.app.config.settings = function(highlight, section) { settings.maximumBackupCount = Number($('.setuptools.app.config.settings select[name="maximumBackupCount"]').val()); settings.autocomplete = ( $('.setuptools.app.config.settings select[name="autocomplete"]').val() === '1' ); settings.automaticBackups = ( $('.setuptools.app.config.settings select[name="automaticBackups"]').val() === '1' ); + settings.badaccounts = Number($('.setuptools.app.config.settings select[name="badaccounts"]').val()); settings.rowlength = Number($('.setuptools.app.config.settings select[name="rowlength"]').val()); settings.accountLoadDelay = Number($('.setuptools.app.config.settings select[name="accountLoadDelay"]').val()); settings.totalswidth = Number($('.setuptools.app.config.settings select[name="totalswidth"]').val()); @@ -758,6 +801,7 @@ setuptools.app.config.settings = function(highlight, section) { settings.muleMenu = ( $('.setuptools.app.config.settings select[name="muleMenu"]').val() === '1' ); settings.nomasonry = ( $('.setuptools.app.config.settings select[name="nomasonry"]').val() === '0' ) ? 0 : 1; settings.errors = ( $('.setuptools.app.config.settings select[name="errors"]').val() === '1' ); + settings.equipSilhouettes = ( $('.setuptools.app.config.settings select[name="equipSilhouettes"]').val() === '1' ); settings.hideHeaderText = ( $('.setuptools.app.config.settings select[name="hideHeaderText"]').val() === '1' ); settings.debugging = ( $('.setuptools.app.config.settings select[name="debugging"]').val() === '1' ); settings.compression = ( $('.setuptools.app.config.settings select[name="compression"]').val() === '1' ); @@ -765,6 +809,7 @@ setuptools.app.config.settings = function(highlight, section) { settings.groupsMergeMode = Number($('.setuptools.app.config.settings select[name="groupsMergeMode"]').val()); settings.autoReloadDays = Number($('.setuptools.app.config.settings select[name="autoReloadDays"]').val()); settings.menuPosition = Number($('.setuptools.app.config.settings select[name="menuPosition"]').val()); + settings.keyBindings = Number($('.setuptools.app.config.settings select[name="keyBindings"]').val()); settings.lazySave = Number($('.setuptools.app.config.settings select[name="lazySave"]').val()); settings.longpress = Number($('.setuptools.app.config.settings select[name="longpress"]').val()); settings.lowStorageSpace = ( $('.setuptools.app.config.settings select[name="lowStorageSpace"]').val() === '1' ); @@ -1024,6 +1069,71 @@ setuptools.app.config.userExists = function(username) { }; +/** + * @function + * @param {string} username + * @returns {boolean} + * Toggle the enabled/disabled state of a user account + */ +setuptools.app.config.userToggle = function(username) { + + if ( setuptools.state.loaded === true && setuptools.data.accounts.accounts[username] ) { + + setuptools.data.accounts.accounts[username].enabled = !(setuptools.data.accounts.accounts[username].enabled); + setuptools.app.config.save('SetupTools/Config user toggle', true); + return true; + + } + + return false; + +}; + +/** + * @function + * @param {string} guid + * @returns {boolean} + * Delete the specified user account gracefully + */ +setuptools.app.config.userDelete = function(guid) { + + if ( setuptools.state.loaded === true && setuptools.data.accounts.accounts[guid] ) { + + // cancel any potential mulequeue inclusion + setuptools.app.mulequeue.task.cancel(guid); + + // cleanup account presence where necessary + delete window.accounts[guid]; + delete setuptools.data.accounts.accounts[guid]; + + // clean up pagesearch configs + setuptools.app.muledump.pagesearch.state.list = setuptools.app.muledump.pagesearch.state.list.filter(function(data) { + return !( data.username === guid ); + }); + + setuptools.app.muledump.pagesearch.paginate.PageList = setuptools.app.muledump.pagesearch.paginate.PageList.filter(function(data) { + return !( data.username === guid ); + }); + + // reinitialize pagesearch + setuptools.app.muledump.pagesearch.init(); + + // clean up mule dom and data + if ( mules[guid] ) { + mules[guid].dom.remove(); + delete mules[guid]; + } + + // save and go + setuptools.app.config.save('SetupTools/Config user deleted'); + return true; + + } + + return false; + +}; + // determine if a user is enabled setuptools.app.config.userEnabled = function(username) { diff --git a/lib/setuptools/src/groups.js b/lib/setuptools/src/groups.js index d7bc3673..9a707e8f 100644 --- a/lib/setuptools/src/groups.js +++ b/lib/setuptools/src/groups.js @@ -1305,7 +1305,7 @@ setuptools.app.groups.manager = function(group, open) { direction = $(this).hasClass('selected'); $(this).addClass('selected'); - if ( setuptools.state.ctrlKey === false ) $(this).siblings().removeClass('selected'); + if ( setuptools.app.muledump.keys('ctrl', e) === false ) $(this).siblings().removeClass('selected'); firstSelected = $(self).text(); lastSelected = false; triggered = false; @@ -1346,7 +1346,7 @@ setuptools.app.groups.manager = function(group, open) { var cells = $('.setuptools.groupMember.cell'); var firstIndex = setuptools.data.groups.groupOrder.indexOf(firstSelected); var lastIndex = setuptools.data.groups.groupOrder.indexOf(lastSelected); - if ( setuptools.state.ctrlKey === false ) $(this).siblings().removeClass('selected'); + if ( setuptools.app.muledump.keys('ctrl', e) === false ) $(this).siblings().removeClass('selected'); // ascending selection if ( firstIndex < lastIndex ) @@ -1366,7 +1366,7 @@ setuptools.app.groups.manager = function(group, open) { } $(this).addClass('selected'); - if ( setuptools.state.ctrlKey === false ) $(this).siblings().removeClass('selected'); + if ( setuptools.app.muledump.keys('ctrl', e) === false ) $(this).siblings().removeClass('selected'); } diff --git a/lib/setuptools/src/init.js b/lib/setuptools/src/init.js index 20ba5358..716099bc 100644 --- a/lib/setuptools/src/init.js +++ b/lib/setuptools/src/init.js @@ -111,16 +111,18 @@ setuptools.init.main = function(window) { // if user provides their own configuration let's load it if ( typeof userConfiguration === 'object' && - (new SeaSalt_Hashing(JSON.stringify(userConfiguration))).toString() !== '7df52aba88bafe6ffdcdd8cf2e0d358be3bcb08ae5a4f4991940938c45f8ce96' + userConfiguration.enabled === true ) { window.techlog('SetupTools/Init - Client config importing ' + Object.keys(userConfiguration).length + ' keys', 'force'); + + delete userConfiguration.enabled; $.extend(true, setuptools.data, userConfiguration); // load our configuration into the window - for ( var i in setuptools.data.config ) - if ( setuptools.data.config.hasOwnProperty(i) ) - window[i] = setuptools.data.config[i]; + Object.filter(setuptools.data.config, function(key, value) { + window[key] = value; + }); // check for potential performance issues setuptools.app.checkperf(); @@ -171,9 +173,9 @@ setuptools.init.main = function(window) { window.options_init(setuptools.state.hosted); // load our configuration into the window - for ( var i in setuptools.data.config ) - if ( setuptools.data.config.hasOwnProperty(i) ) - window[i] = setuptools.data.config[i]; + Object.filter(setuptools.data.config, function(key, value) { + window[key] = value; + }); // run any configuration upgrades setuptools.app.upgrade.seek(); diff --git a/lib/setuptools/src/lightbox.js b/lib/setuptools/src/lightbox.js index 6b62e557..e8009029 100644 --- a/lib/setuptools/src/lightbox.js +++ b/lib/setuptools/src/lightbox.js @@ -1228,7 +1228,9 @@ setuptools.lightbox.tooltip = function(parent, content, modifiers) { // adjust menu position if this is going to render right of the window var parentOuter = ( parent !== false ) ? parent.outerWidth() : 0; var width = tooltip.outerWidth(true); + var height = tooltip.outerHeight(true); if ( position.left+width >= window.innerWidth-20 ) css.left = css.left-width+parentOuter; + if ( css.top < window.pageYOffset ) css.top += (parent && parent.outerHeight(true) || 0)+height; if ( css.left+width >= window.innerWidth ) return; // set the css @@ -1347,6 +1349,15 @@ setuptools.lightbox.display = function(page, config) { if ( typeof config !== 'object' ) config = {}; + // apply any insertions + setuptools.lightbox.inserts = setuptools.lightbox.inserts.filter(function(data) { + if ( data[0] === page ) { + console.log(data); + setuptools.lightbox[data[1]].apply(null, data[2]); + } + return false; + }); + // search build data for drawhelp and goback data var gobackData; var drawhelpData; @@ -1507,7 +1518,8 @@ setuptools.lightbox.goback = function(page, callback, text1, text2) { text1 = 'Go back to the'; text2 = 'previous page'; } - if ( typeof callback != 'function' ) setuptools.lightbox.error('The callback value for goback is not valid.', 10); + + if ( typeof callback !== 'function' ) setuptools.lightbox.error('The callback value for goback is not valid.', 10); if ( !setuptools.lightbox.builds[page] ) setuptools.lightbox.builds[page] = []; setuptools.lightbox.builds[page].push({ @@ -1519,6 +1531,28 @@ setuptools.lightbox.goback = function(page, callback, text1, text2) { }; +/** + * @function + * @param {string} page + * @param {string} callback + * @param {array} [args] + * Insert a page piece for a future page display + */ +setuptools.lightbox.insert = function(page, callback, args) { + + // check for duplicates + if ( setuptools.lightbox.inserts.filter(function(data) { + return !( + data[0] !== page || + (data[0] === page && data[1] !== callback) || + (data[0] === page && data[1] === callback && JSON.stringify(data[2]) !== JSON.stringify(args)) + ); + }).length > 0 ) return false; + + return setuptools.lightbox.inserts.push([page, callback, args]); + +}; + // display an error message setuptools.lightbox.error = function(message, code) { diff --git a/lib/setuptools/src/muledump.js b/lib/setuptools/src/muledump.js index c2733f03..302e4cfb 100644 --- a/lib/setuptools/src/muledump.js +++ b/lib/setuptools/src/muledump.js @@ -58,291 +58,92 @@ setuptools.app.muledump.warnData = function(Mule, name, data) { /** * @function - * @param {array} CustomList - * @param {object} mule - * @returns {{FinalList: Array, RemovedList: Array}} - * Chsort v1 - Deduplicate and validate custom character id list - */ -setuptools.app.muledump.chsortcustomDedupAndValidate = function(CustomList, mule) { - - // get our list of char ids - var FinalList = []; - var CharIdList = []; - var DuplicateList = []; - var RemovedList = []; - CustomList = CustomList.replace('#', '').split(/, ?/); - - // generate the character id list - for ( var i = 0; i < mule.data.query.results.Chars.Char.length; i++ ) CharIdList.push(mule.data.query.results.Chars.Char[i].id); - - // validate and deduplicate - for ( var i in CustomList ) { - - if ( CustomList.hasOwnProperty(i) ) { - - // is it a valid id - if ( CharIdList.indexOf(CustomList[i]) === -1 ) { - if ( typeof CustomList[i] === 'string' ) RemovedList.push(JSON.parse(JSON.stringify(CustomList[i]))); - delete CustomList[i]; - } - - // is it already in the list - if ( DuplicateList.indexOf(CustomList[i]) > -1) { - if ( typeof CustomList[i] === 'string' ) RemovedList.push(JSON.parse(JSON.stringify(CustomList[i]))); - delete CustomList[i]; - } else { - if ( typeof CustomList[i] === 'string' ) DuplicateList.push(JSON.parse(JSON.stringify(CustomList[i]))); - } - - } - - } - - // clean up our final list - for ( var i in CustomList ) - if ( CustomList.hasOwnProperty(i) ) - if ( typeof CustomList[i] === 'string' ) - FinalList.push(CustomList[i]); - - return {FinalList: FinalList, RemovedList: RemovedList}; - -}; - -/** - * @function - * @param {object} mule - * Chsort v1 - Assist the user in creating a custom sort list + * @param {jQuery} $i + * @param {string | array} [classes] + * @param {string} [content] + * @param {number} [ttl] + * Binds the item tooltip to all item divs */ -setuptools.app.muledump.chsortcustom = function(mule) { - - if ( !mule ) setuptools.lightbox.error('No mule provided to custom sort utility.'); - - // prepare the object is none exists - if ( typeof setuptools.data.muledump.chsortcustom.accounts[mule.guid] === 'undefined' ) setuptools.data.muledump.chsortcustom.accounts[mule.guid] = {active: '', data: {}}; - - setuptools.lightbox.build('muledump-chsortcustom-index', ' \ - Saving a list will set that list as active and overwrite any stored data for that list or create a new list item. \ -

For account :: ' + mule.guid + ' \ - ' + ( ( - setuptools.state.loaded === true && - typeof setuptools.data.accounts.accounts[mule.guid].ign === 'string' && - setuptools.data.accounts.accounts[mule.guid].ign.length > 0 - ) ? '
IGN :: ' + setuptools.data.accounts.accounts[mule.guid].ign + '' : '' ) + '\ -

Choose Existing List \ -
\ -
\ - '); +setuptools.app.muledump.tooltip = function($i, classes, content, ttl) { - // build our select menu - if ( Object.keys(setuptools.data.muledump.chsortcustom.accounts[mule.guid].data).length > 0 ) { - - setuptools.lightbox.build('muledump-chsortcustom-index', ' \ -
\ - '); - - } else { + if ( typeof ttl !== 'number' ) ttl = setuptools.data.config.tooltip; + if ( typeof content === 'number' ) { - setuptools.lightbox.build('muledump-chsortcustom-index', 'No saved lists found'); + ttl = content; + content = undefined; } - setuptools.lightbox.build('muledump-chsortcustom-index', ' \ -

List Name to Edit \ -

\ -
\ -
Prepare List \ -

Enter a list of IDs separated by commas. \ -

\ -

\ -
\ - \ - \ -
\ - '); - - setuptools.lightbox.settitle('muledump-chsortcustom-index', 'Character Sorting Lists'); - setuptools.lightbox.drawhelp('muledump-chsortcustom-index', 'docs/features/character-sorting', 'Character Sorting Lists Help'); - setuptools.lightbox.display('muledump-chsortcustom-index'); - - // populate selected data - $('select[name="chsortExisting"]').change(function() { - - var chsortId = $(this).val(); - $('input[name="chsortListName"]').val(chsortId); - $('input[name="chsortcustom"]').val(setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[chsortId].join(', ')); - - }); - - $('.setuptools.link.muledump.save.delete').click(function() { - - var chsortId = $('input[name="chsortListName"]').val(); - if ( chsortId.length === 0 ) return; - if ( typeof setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[chsortId] === 'undefined' ) return; - - // delete the list - delete setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[chsortId]; - - // set default value to top key - var newChsortId = Object.keys(setuptools.data.muledump.chsortcustom.accounts[mule.guid].data)[0]; - if ( setuptools.data.muledump.chsortcustom.accounts[mule.guid].active === chsortId ) - setuptools.data.muledump.chsortcustom.accounts[mule.guid].active = (typeof newChsortId === 'undefined' ) ? '' : newChsortId; - - // save the changes - setuptools.app.config.save('CharacterSort/Delete'); - - // update the form - $('select[name="chsortExisting"] option[value="' + chsortId + '"]').remove(); - if ( typeof newChsortId === 'string' ) { - - $('select[name="chsortExisting"] option[value="' + newChsortId + '"]').prop('selected', 'selected'); - $('input[name="chsortListName"]').val(newChsortId); - $('input[name="chsortcustom"]').val(setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[newChsortId].join(', ')); - - } - - }); - - // save changes to a list or new list - $('.setuptools.link.muledump.save.list').click(function() { - - var UserListName = $('input[name="chsortListName"]').val(); - var UserInput = $('input[name="chsortcustom"]').val(); - var Lists = false; - if ( UserInput.length > 0 ) Lists = setuptools.app.muledump.chsortcustomDedupAndValidate(UserInput, mule); - var SaveState = false; - - // save the list if it's at least 1 long - if ( typeof Lists === 'object' && Lists.FinalList.length > 0 ) { - - setuptools.data.muledump.chsortcustom.accounts[mule.guid].active = UserListName; - setuptools.data.muledump.chsortcustom.accounts[mule.guid].data[UserListName] = $.extend(true, [], Lists.FinalList); - SaveState = setuptools.app.config.save('CharacterSort/Save'); - if ( setuptools.config.devForcePoint !== 'chsortcustom-save' && SaveState === true ) { - - if ( Lists.RemovedList.length > 0 ) setuptools.lightbox.build('muledump-chsortcustom-save', 'The follow IDs were invalid or duplicates:

' + Lists.RemovedList.join(', ') + '

'); - setuptools.lightbox.build('muledump-chsortcustom-save', 'The changes have been saved.'); - mule.query(false, true); - - } - - } else { - - // if no list is provided then we're erasing this instead - if ( UserInput.length === 0 ) { - - setuptools.lightbox.build('muledump-chsortcustom-save', 'Choose \'Delete List\' to remove a list.'); - - } else { - - setuptools.lightbox.build('muledump-chsortcustom-save', 'Oops! No valid account IDs were detected.'); - - } - - setuptools.lightbox.build('muledump-chsortcustom-save', ' \ -

Valid formats include: \ -

1, 2, 3, 4, ... \ -

1,2,3,4,... \ -

#1,#2,#3,#4,... \ -

1, #2, 3,#4, ... \ -

You get the idea. \ - '); - - } - - if ( SaveState === false ) setuptools.lightbox.build('muledump-chsortcustom-save', 'Hmm, there was a problem saving. This setting will reset on page reload.'); - setuptools.lightbox.goback('muledump-chsortcustom-save', function() { - setuptools.app.muledump.chsortcustom(mule); - }); - setuptools.lightbox.settitle('muledump-chsortcustom-save', 'Character Sorting Lists'); - setuptools.lightbox.display('muledump-chsortcustom-save'); - - - }); - -}; - -/** - * @function - * @param {jQuery} $i - * @param {string | array} classes - * Binds the item tooltip to all item divs - */ -setuptools.app.muledump.tooltip = function($i, classes) { - - // select all items - if ( !item ) $i = $('.item'); + var contentCallback = function(self) { + setuptools.lightbox.tooltip(self, content, {heightFrom: 'tooltip', classes: classes}); + }; - // item mouseenter events - $i.off('mouseenter.muledump.tooltip').on('mouseenter.muledump.tooltip', function(e) { + // the default tooltip is for items + var defaultCallback = function(self) { - if ( e.ctrlKey === true ) return; - var self = this; var id = +$(self).attr('data-itemId'); var ItemData = items[id]; if ( typeof ItemData !== 'object' || ItemData[0] === 'Empty Slot' ) return; - // tooltip popup - clearTimeout(setuptools.tmp.tstateOpen); - setuptools.tmp.tstateOpen = setTimeout(function() { - if ( typeof ItemData !== 'object' || ItemData[0] === 'Empty Slot' ) return; - - // build tooltip data - // three columns: [ bagTypeImage ] [ item name/feed power ] [ tier/fame bonus ] - var html = ''; - - // poorman's bagType constants - var bagPosition = '0px 0px'; - if ( ItemData[7] === 1 ) bagPosition = '-26px -0px'; - if ( ItemData[7] === 2 ) bagPosition = '-52px -0px'; - if ( ItemData[7] === 3 ) bagPosition = '-78px -0px'; - if ( ItemData[7] === 4 ) bagPosition = '-26px -26px'; - if ( ItemData[7] === 5 ) bagPosition = '-52px -26px'; - if ( ItemData[7] === 6 ) bagPosition = '-26px -52px'; - if ( ItemData[7] === 7 ) bagPosition = '-0px -26px'; - if ( ItemData[7] === 8 ) bagPosition = '-78px -26px'; - if ( ItemData[7] === 9 ) bagPosition = '-0px -52px'; - - // column one - html += ' \ + // build tooltip data + // three columns: [ bagTypeImage ] [ item name/feed power ] [ tier/fame bonus ] + var html = ''; + + // poorman's bagType constants + var bagPosition = '0px 0px'; + if ( ItemData[7] === 1 ) bagPosition = '-26px -0px'; + if ( ItemData[7] === 2 ) bagPosition = '-52px -0px'; + if ( ItemData[7] === 3 ) bagPosition = '-78px -0px'; + if ( ItemData[7] === 4 ) bagPosition = '-26px -26px'; + if ( ItemData[7] === 5 ) bagPosition = '-52px -26px'; + if ( ItemData[7] === 6 ) bagPosition = '-26px -52px'; + if ( ItemData[7] === 7 ) bagPosition = '-0px -26px'; + if ( ItemData[7] === 8 ) bagPosition = '-78px -26px'; + if ( ItemData[7] === 9 ) bagPosition = '-0px -52px'; + + // column one + html += ' \
\
 
\
\ '; - // column two - html += ' \ + // column two + html += ' \
\ ' + ItemData[0] + ( ( ItemData[8] === true ) ? ' (SB)' : '' ) + ' \ ' + ( (ItemData[6]) ? '
Feed Power: ' + ItemData[6] + '' : '' ) + '\
\ '; - // column three - var tier = ''; - if ( ItemData[2] > -1 && ItemData[1] !== 10 ) tier += 'T' + ItemData[2] + ''; - if ( ItemData[9] === 1 && ItemData[1] !== 10 ) tier += 'UT'; - if ( ItemData[9] === 2 ) tier += 'ST'; - var c2Margin = ( tier.length > 0 ) ? ' margin-left: 15px;' : ''; - html += ' \ + // column three + var tier = ''; + if ( ItemData[2] > -1 && ItemData[1] !== 10 ) tier += 'T' + ItemData[2] + ''; + if ( ItemData[9] === 1 && ItemData[1] !== 10 ) tier += 'UT'; + if ( ItemData[9] === 2 ) tier += 'ST'; + var c2Margin = ( tier.length > 0 ) ? ' margin-left: 15px;' : ''; + html += ' \
\ ' + tier + ' \ ' + ( ( ItemData[5] ) ? '
Fame Bonus: ' + ItemData[5] + '%' : '' ) + ' \
\ '; - setuptools.lightbox.tooltip(self, html, {classes: classes}); - }, setuptools.data.config.tooltip); + setuptools.lightbox.tooltip(self, html, {classes: classes}); + }; + + // select all items + if ( !item ) $i = $('.item'); + + // item mouseenter events + $i.off('mouseenter.muledump.tooltip').on('mouseenter.muledump.tooltip', function(e) { + + if ( setuptools.app.muledump.keys('ctrl', e) === true ) return; + var self = this; + + // tooltip popup + clearTimeout(setuptools.tmp.tstateOpen); + setuptools.tmp.tstateOpen = setTimeout(((typeof content === 'string') ? contentCallback : defaultCallback), ttl, self); // search context menu /*$(this).contextmenu(function(e) { @@ -716,1816 +517,84 @@ setuptools.app.muledump.pagesearch.execute = function(state, searchTerm) { }; -/* -// Totals -*/ - /** * @function - * @param {jQuery} [track] - * @param {string} [page] - * Display the advanced totals menu + * @param {string} guid + * @returns {string} + * Returns the display name for a provided guid */ -setuptools.app.muledump.totals.menu.advanced = function(track, page) { - - if ( !(track instanceof jQuery) ) track = $('#totalsMenu'); - setuptools.lightbox.menu.context.close('totalsmenuAdvanced'); - var options = [ - { - option: 'hover', - action: 'close' - }, - { - option: 'scrollLock', - hook: '#totalsMenu' - }, - { - option: 'skip', - value: 'reposition' - }, - { - option: 'afterClose', - callback: setuptools.app.muledump.totals.menu.advanced, - callbackArg: [track, page] - }, - { - option: 'css', - css: { - width: '177px' - } - }, - { - option: 'class', - value: 'smallMenuCells' - }, - { - option: 'pos', - h: 'left', - v: 'top', - vpx: 28 - }, - { - class: 'goBack', - name: 'Go back...', - callback: setuptools.app.muledump.totals.menu.main, - override: 'afterClose' - }, - /*{ - class: 'goBack', - name: 'Basic Filters...', - callback: setuptools.app.muledump.totals.menu.basic, - override: 'afterClose' - },*/ - { - option: 'header', - value: 'Weapons', - class: 'openTotalWeaponsMenu', - callback: function(args) { - setuptools.app.muledump.totals.menu.advanced(args.track, args.page); - }, - callbackArg: {track: track, page: 'weapons'}, - override: 'afterClose' - } - ]; - - // populate type - weapons - if ( page === 'weapons' ) setuptools.app.muledump.totals.menu.populateByType( - options, - ['bows', 'daggers', 'katanas', 'staves', 'swords', 'wands'] - ); - - options.push({ - option: 'header', - value: 'Abilities', - class: 'openTotalAbilitiesMenu', - callback: function(args) { - setuptools.app.muledump.totals.menu.advanced(args.track, args.page); - }, - callbackArg: {track: track, page: 'abilities'}, - override: 'afterClose' - }); - - // populate type - abilities - if ( page === 'abilities' ) setuptools.app.muledump.totals.menu.populateByType( - options, - ['cloaks', 'helms', 'orbs', 'poisons', 'prisms', 'quivers', 'scepters', 'seals', 'shields', 'skulls', 'spells', 'stars', 'tomes', 'traps'] - ); +setuptools.app.muledump.getName = function(guid) { - options.push({ - option: 'header', - value: 'Armor', - class: 'openTotalArmorMenu', - callback: function(args) { - setuptools.app.muledump.totals.menu.advanced(args.track, args.page); - }, - callbackArg: {track: track, page: 'armor'}, - override: 'afterClose' - }); + return ( ( + setuptools.state.loaded === true && + setuptools.data.config.mqDisplayIgn === true && + typeof setuptools.data.accounts.accounts[guid].ign === 'string' + ) ? setuptools.data.accounts.accounts[guid].ign : guid ); - // populate type - armor - if ( page === 'armor' ) setuptools.app.muledump.totals.menu.populateByType( - options, - ['heavyarmor', 'lightarmor', 'robes'] - ); +}; - setuptools.app.muledump.totals.menu.populateByType(options, ['rings']); +/** + * @function + * @param {string | array} keys + * @param {object} e + * @param {boolean} [raw] + * Return the state of the specified keys + */ +setuptools.app.muledump.keys = function(keys, e, raw) { - options.push( - { - class: 'disableAll', - name: 'Disable All Filters', - callback: setuptools.app.muledump.totals.config.toggleAllTypes, - callbackArg: false - }, - { - class: 'hideAll', - name: 'Enable All Filters', - callback: setuptools.app.muledump.totals.config.toggleAllTypes, - callbackArg: true - } - ); + if ( typeof keys === 'undefined' ) return; + if ( typeof keys === 'string' ) keys = [keys]; + if ( !Array.isArray(keys) ) return; - if ( setuptools.data.muledump.totals.configSets.active !== 'Default' ) options.push({ - class: 'saveTotalsSettings', - name: 'Save Settings', - callback: function() { - setuptools.app.muledump.totals.config.save('active', true); - setuptools.lightbox.status(this, 'Saved!'); - } + var keymap = $.extend(true, setuptools.data.muledump.keys[0], setuptools.data.muledump.keys[setuptools.data.config.keyBindings]); + var result = {}; + keys.filter(function(key) { + result[key] = e[keymap[key]] || false; }); - options.push({ - class: 'resetTotalsSettings', - name: 'Reset Settings', - callback: function() { - setuptools.app.muledump.cleanupSecondaryCache(); - setuptools.app.muledump.totals.config.activate('active', true); - } + if ( keys.length === 1 ) return result[keys[0]]; + if ( raw === true ) return result; + var falseCount = 0; + Object.filter(result, function(key, value) { + if ( value === false ) falseCount++; }); - - setuptools.lightbox.menu.context.create('totalsmenuAdvanced', false, track, options); + return ( falseCount === 0 ); }; /** * @function - * @param {jQuery} [track] - * @param {string} [page] - * Display the item types totals menu - * Presently not used (keeping the menu short) + * @param {string} option + * @param {boolean} [value] + * @param {boolean} [skip] + * Toggle the state of the specified options */ -setuptools.app.muledump.totals.menu.basic = function(track, page) { - - if ( !(track instanceof jQuery) ) track = $('#totalsMenu'); - setuptools.lightbox.menu.context.close('totalsmenuBasic'); - var options = [ - { - option: 'hover', - action: 'close' - }, - { - option: 'scrollLock', - hook: '#totalsMenu' - }, - { - option: 'skip', - value: 'reposition' - }, - { - option: 'afterClose', - callback: setuptools.app.muledump.totals.menu.basic, - callbackArg: [track, page] - }, - { - option: 'class', - value: 'smallMenuCells' - }, - { - option: 'css', - css: { - width: '177px' - } - }, - { - option: 'pos', - h: 'left', - v: 'top', - vpx: 28 - }, - { - class: 'goBack', - name: 'Go back...', - callback: setuptools.app.muledump.totals.menu.main, - override: 'afterClose' - }, - { - class: 'goBack', - name: 'Advanced Filters...', - callback: setuptools.app.muledump.totals.menu.advanced, - override: 'afterClose' - } - ]; - - /* waiting on this - options.push({ - option: 'header', - value: 'Equipment', - class: 'openTotalEquipmentMenu', - callback: function(args) { - setuptools.app.muledump.totals.menu.basic(args.track, args.page); - }, - callbackArg: {track: track, page: 'equipment'}, - override: 'afterClose' - }); +setuptools.app.muledump.toggleoption = function(option, value, skip) { - // populate type - equipment - if ( page === 'equipment' ) setuptools.app.muledump.totals.menu.populateByType( - options, - ['weapons', 'abilities', 'armor', 'rings'] - );*/ + if ( typeof option === 'undefined' ) return; + if ( typeof option === 'string' ) option = [option]; + if ( Array.isArray(option) === false ) return; - options.push({ - option: 'header', - value: 'Consumables', - class: 'openTotalConsumableMenu', - callback: function(args) { - setuptools.app.muledump.totals.menu.basic(args.track, args.page); - }, - callbackArg: {track: track, page: 'consumables'}, - override: 'afterClose' - }); + // switch the option + for ( var i = 0; i < option.length; i++) setuptools.data.options[option[i]] = ( typeof value === 'undefined' ) ? !setuptools.data.options[option[i]] : value; - // populate type - consumables - if ( page === 'consumables' ) setuptools.app.muledump.totals.menu.populateByType( - options, - ['candies', 'helpfulconsumables', 'assistants', 'otherconsumables', 'potions', 'potionssb'] - ); + // totals filter keys need to update the secondary item filter list + setuptools.app.muledump.totals.updateSecondaryFilter(); - options.push({ - option: 'header', - value: 'Single Use Items', - class: 'openTotalSingleUseMenu', - callback: function(args) { - setuptools.app.muledump.totals.menu.basic(args.track, args.page); - }, - callbackArg: {track: track, page: 'singleuse'}, - override: 'afterClose' - }); + if ( skip !== true ) { + update_totals(); + update_filter(); + options_save(); + } - // populate type - singleuser - if ( page === 'singleuse' ) setuptools.app.muledump.totals.menu.populateByType( - options, - ['finespirits', 'eggs', 'keys', 'petfood', 'petstones', 'portkeys', 'skins', 'textiles'] - ); +}; - options.push({ - option: 'header', - value: 'Other Items', - class: 'openTotalOtherItemsMenu', - callback: function(args) { - setuptools.app.muledump.totals.menu.basic(args.track, args.page); - }, - callbackArg: {track: track, page: 'otheritems'}, - override: 'afterClose' - }); - - // populate type - armor - if ( page === 'otheritems' ) setuptools.app.muledump.totals.menu.populateByType( - options, - ['empty', 'eventitems', 'misc', 'tarot', 'treasures', 'assistants', 'other', 'tarot', 'treasures'] - ); - - options.push( - { - class: 'disableAll', - name: 'Disable All Filters', - callback: setuptools.app.muledump.totals.config.toggleAllTypes, - callbackArg: false - }, - { - class: 'hideAll', - name: 'Enable All Filters', - callback: setuptools.app.muledump.totals.config.toggleAllTypes, - callbackArg: true - } - ); - - if ( setuptools.data.muledump.totals.configSets.active !== 'Default' ) options.push({ - class: 'saveTotalsSettings', - name: 'Save Settings', - callback: function() { - setuptools.app.muledump.totals.config.save('active', true); - setuptools.lightbox.status(this, 'Saved!'); - } - }); - - options.push({ - class: 'resetTotalsSettings', - name: 'Reset Settings', - callback: function() { - setuptools.app.muledump.cleanupSecondaryCache(); - setuptools.app.muledump.totals.config.activate('active', true); - } - }); - - setuptools.lightbox.menu.context.create('totalsmenuBasic', false, track, options); - -}; - -/** - * @function - * Display a menu for managing totals-related settings - */ -setuptools.app.muledump.totals.menu.settings = function() { - - /* Active Configuration Sets - /* Create New Configuration Set - /* Active Account Filter Members - /* Item Group Sort Order - /* Permanently Hidden Items - */ - - setuptools.lightbox.close(); - setuptools.lightbox.build('totalsmenu-settings', ' \ -
\ - '); - - if ( setuptools.state.loaded === false ) setuptools.lightbox.build('totalsmenu-settings', ' \ -
In order to permanently save these settings you must be using SetupTools. See Totals Management in the wiki.
\ -
 
\ - '); - - // display the account filter info - setuptools.lightbox.build('totalsmenu-settings', ' \ -
\ -
Active Configuration Set
\ -
\ - \ -
\ -
\ - \ - \ - \ - \ -
\ -
\ -
 
\ - \ -
\ -
Create New Configuration Set
\ -
\ - \ -
\ -
\ - \ -
\ -
\ -
 
\ - \ -
Item Group Sorting
\ - ' + ( (setuptools.app.muledump.totals.config.getKey('slotOrder').length === 0) ? '
Uh oh :D This configSet has invalid data!
 
' : '' ) + ' \ -
\ - '); - - // sort keys into their proper order - var types = setuptools.app.muledump.totals.config.getTypes().sort(function(a, b) { - var slotOrder = setuptools.app.muledump.totals.config.getKey('slotOrder'); - var vst = {}; - vst.a = setuptools.app.muledump.itemSlotTypeVst(a); - vst.b = setuptools.app.muledump.itemSlotTypeVst(b); - return ( slotOrder.indexOf(vst.a) - slotOrder.indexOf(vst.b) ); - }); - - // display a tile for each type - types.filter(function(type) { - var name = setuptools.app.muledump.itemSlotTypeName(type); - var vst = setuptools.app.muledump.itemSlotTypeVst(type); - var itemList = setuptools.app.muledump.itemsByVst(vst); - var item = window.items[itemList[Math.floor(Math.random()*Math.floor(itemList.length))]]; - var classes = ''; - - if ( setuptools.data.options['totalsFilter-' + type] === true ) classes += 'enabled'; - setuptools.lightbox.build('totalsmenu-settings', ' \ -
\ -
' + name + '
\ -
\ -
\ - '); - - }); - - setuptools.lightbox.build('totalsmenu-settings', ' \ -
\ -
⚪⚪⚪
\ -
\ -
 
\ - \ -
Active Account Filter Members
\ - ' + ( (setuptools.app.muledump.totals.config.getKey('accountFilter').length === 0) ? '
No accounts in filter
' : '' ) + ' \ -
\ - '); - - if ( - setuptools.state.loaded === true && - setuptools.app.muledump.totals.config.getKey('accountFilter').length > 0 - ) setuptools.lightbox.build('totalsmenu-settings', '\ - \ - '); - - setuptools.app.muledump.totals.config.getKey('accountFilter').sort(); - setuptools.app.muledump.totals.config.getKey('accountFilter').filter(function(guid) { - - setuptools.lightbox.build('totalsmenu-settings', ' \ -
' + setuptools.app.muledump.getName(guid) + '
\ - '); - - }); - - setuptools.lightbox.build('totalsmenu-settings', ' \ -
\ -
 
\ - '); - - // display the hidden items filter info - setuptools.lightbox.build('totalsmenu-settings', ' \ -
Permanently Hidden Items
\ - ' + ( ( setuptools.app.muledump.totals.config.getKey('itemFilter').length === 0 ) ? '
No items hidden
' : '' ) + '\ -
'); - - if ( setuptools.app.muledump.totals.config.getKey('itemFilter').length > 0 ) { - - setuptools.app.muledump.totals.config.getKey('itemFilter').filter(function(itemid) { - - var item = items[+itemid]; - if ( item === undefined ) { - - var data = setuptools.app.muledump.totals.config.getKey('itemFilter'); - data.splice(data.indexOf(+itemid), 1); - setuptools.app.muledump.totals.config.setKey('itemFilter', data); - setuptools.app.techlog('Totals/itemFilter removing: ' + itemid); - - } else setuptools.lightbox.build('totalsmenu-settings', '
'); - - }); - - } - - setuptools.lightbox.build('totalsmenu-settings', '
\ - '); - - if ( setuptools.app.muledump.totals.config.getKey('itemFilter').length > 0 ) setuptools.lightbox.build('totalsmenu-settings', ' \ -
⚪⚪⚪
\ -
\ - '); - - setuptools.lightbox.build('totalsmenu-settings', ' \ -
 \ -
Legend\ -
Shift+Click items to enable/disable them\ -
Click and drag items to sort them (item sorting)\ -
Double click items to access subsorting menu (item sorting)\ -
\ - '); - - var currentSet = setuptools.data.muledump.totals.configSets.active; - setuptools.lightbox.settitle('totalsmenu-settings', 'Totals Settings Manager'); - setuptools.lightbox.drawhelp('totalsmenu-settings', 'docs/muledump/totals-manager', 'Totals Help'); - setuptools.lightbox.display('totalsmenu-settings', {variant: 'fl-Totals', afterClose: function() { - setuptools.tmp.itemSortDragging.off(); - setuptools.app.muledump.totals.updateSecondaryFilter(); - window.update_totals(); - window.update_filter(); - option_updated('totals'); - }}); - - if ( setuptools.state.loaded === false ) { - $('.featherlight-content input').prop('disabled', true).attr('placeholder', 'This feature requires SetupTools'); - $('.featherlight-content select').prop('disabled', true); - $('.featherlight-content div.setuptools.menuStyle:not(.resetSlotOrder)').addClass('disabled truly').removeClass('selected negative').attr('title', 'This feature requires SetupTools'); - } - - // item subsorting allows for sorting items within a group - $('.itemSlotTypeSorting.cell') - .on('click.muledump.totals.itemGroupSorting', function(e) { - if ( e.shiftKey === false ) return; - setuptools.app.muledump.toggleoption('totalsFilter-' + $(this).attr('data-type'), undefined, true); - $(this).toggleClass('enabled'); - if ( setuptools.state.loaded === false ) { - window.update_totals(); - window.update_filter(); - option_updated('totals'); - } - }) - .on('dblclick.muledump.totals.itemGroupSorting', function(e) { - - var vst = setuptools.app.muledump.itemSlotTypeVst($(this).attr('data-type')); - var itemList = setuptools.app.muledump.itemsByVst(vst); - if ( typeof vst === 'undefined' ) return; - - setuptools.lightbox.build('totalsmenu-itemSorting', ' \ -
\ - Click and drag to sort items within their group. Don\'t forget to save on previous page.\ -
 \ -
\ -
\ - '); - - // determine item sorting - var slotSubOrder = setuptools.app.muledump.totals.config.getKey('slotSubOrder'); - if ( Array.isArray(slotSubOrder[vst]) === false ) { - - //itemList = itemList.sort(window.ids_sort); - slotSubOrder[vst] = itemList; - - } - - if ( slotSubOrder[vst].length > 0 ) slotSubOrder[vst].filter(function(itemid) { - - var item = items[+itemid]; - if ( setuptools.config.disqualifiedItemIds.indexOf(+itemid) > -1 ) return; - if ( item[3] === 40 && item[4] === 0 ) return; - setuptools.lightbox.build('totalsmenu-itemSorting', '
'); - - }); - - setuptools.lightbox.build('totalsmenu-itemSorting', ' \ -
\ - \ - '); - - setuptools.lightbox.settitle('totalsmenu-itemSorting', 'Item Sorting'); - setuptools.lightbox.display('totalsmenu-itemSorting', {variant: 'fl-Totals'}); - - // provide a hidden item filter integration - $('#itemSubsortingBox > div.item').on('click.muledump.itemFilter', function(e) { - - if ( e.target !== this || e.shiftKey === false || !$(this).attr('data-itemid') ) return; - setuptools.app.muledump.totals.toggleHideItem($(this).attr('data-itemid')); - $(this).toggleClass('selected'); - - }); - - // bind the tooltip - var itemsSelected = $('div#itemSubsortingBox div.item'); - setuptools.app.muledump.tooltip(itemsSelected, 'itemSubsortingTooltip'); - - // item dragging - setuptools.tmp.itemSubsortDragging = new Muledump_Dragging({ - target: ['item', 'subsorting', 'cell'], - targetattr: 'data-itemId', - approach: 0.1, - dragclass: 'dragging bright', - callbacks: { - before: function(parent, self) { - - if ( - typeof window.items[self.attr('data-itemId')] !== 'object' || - typeof window.items[parent.target] !== 'object' - ) return; - - // determine source and target virtualSlotTypes and exit if target doesn't have the attribute - var itemid = self.attr('data-itemId'); - var targetid = parent.target; - parent.itemid = itemid; - parent.targetid = targetid; - if ( itemid === targetid ) return; - return true; - - }, - after: function(parent, self) { - - var slotSubOrder = setuptools.app.muledump.totals.config.getKey('slotSubOrder'); - var vst = window.items[parent.itemid][setuptools.config.vstIndex]; - slotSubOrder[vst].splice(slotSubOrder[vst].indexOf(parent.itemid), 1); - slotSubOrder[vst].splice((slotSubOrder[vst].indexOf(parent.targetid)+parent.indexModifier), 0, parent.itemid); - - } - } - }); - - }); - - // bind the dragging class - setuptools.tmp.itemSortDragging = new Muledump_Dragging({ - target: ['itemSlotTypeSorting', 'cell'], - targetattr: 'data-type', - approach: 0.1, - callbacks: { - before: function(parent, self) { - - if ( - typeof window.itemsSlotTypeMap[self.attr('data-type')] !== 'object' || - typeof window.itemsSlotTypeMap[parent.target] !== 'object' - ) return; - - // determine source and target virtualSlotTypes and exit if target doesn't have the attribute - var vst = setuptools.app.muledump.itemSlotTypeVst(self.attr('data-type')); - var targetVst = setuptools.app.muledump.itemSlotTypeVst(parent.target); - parent.vst = vst; - parent.targetVst = targetVst; - if ( vst === targetVst ) return; - return true; - - }, - after: function(parent, self) { - - var slotOrder = setuptools.app.muledump.totals.config.getKey('slotOrder'); - slotOrder.splice(slotOrder.indexOf(parent.vst), 1); - slotOrder.splice((slotOrder.indexOf(parent.targetVst)+parent.indexModifier), 0, parent.vst); - - }, - finish: function(parent, self) { - - if ( parent.clickIndexDown === parent.clickIndexUp ) return; - if ( setuptools.state.loaded === false ) { - window.init_totals(); - window.update_totals(); - } - - } - } - }); - - // item sorting is an expandable box - setuptools.lightbox.expander('#itemSlotTypeSorting', '.itemSlotTypeSorting.expansion'); - setuptools.lightbox.expander('#hiddenItems', '.hiddenItems.expansion'); - - // toggle favorite status - $('.setuptools.link.favorite').on('click.muledump.totals.favorite', function() { - - if ( $(this).hasClass('disabled') === true ) return; - var name = $(this).parent().prev().find('select[name="totalsConfigSets"]').val(); - if ( name === 'Default' ) { - setuptools.lightbox.status(this, 'No!'); - return; - } - var index = setuptools.data.muledump.totals.configSets.favorites.indexOf(name); - if ( index === -1 ) { - setuptools.data.muledump.totals.configSets.favorites.push(name); - $(this).addClass('selected').attr('title', 'Click to Unfavorite'); - } else { - setuptools.data.muledump.totals.configSets.favorites.splice(index, 1); - $(this).removeClass('selected').attr('title', 'Click to Favorite'); - } - setuptools.app.config.save('Totals config set was favorite toggled', true); - - }); - - // automatically switch buttons on config selection - $('select[name="totalsConfigSets"]').on('change.muledump.totals.totalsConfigSets', function() { - - var name = $(this).val(); - - var favoriteButton = $('.setuptools.link.favorite'); - if ( setuptools.data.muledump.totals.configSets.favorites.indexOf(name) === -1 ) { - favoriteButton.removeClass('selected').attr('title', 'Click to Favorite'); - } else favoriteButton.addClass('selected').attr('title', 'Click to Unfavorite'); - - var activateButton = $('.setuptools.link.activateSet'); - if ( setuptools.data.muledump.totals.configSets.active === name ) { - activateButton.text('Save'); - } else activateButton.text('Switch To'); - - }); - - // resets configuration to original state - $('.setuptools.link.reset').on('click.muledump.totals.reset', function() { - if ( $(this).hasClass('disabled') === true ) return; - setuptools.app.muledump.totals.config.activate(undefined, true, true); - setuptools.lightbox.status(this, 'Active reset!'); - setuptools.app.muledump.totals.menu.settings(); - }); - - // switch active configuration - $('.setuptools.link.activateSet') - .off('click.muledump.totals.activateSet') - .on('click.muledump.totals.activateSet', function() { - - if ( $(this).hasClass('disabled') === true ) return; - var name = $('select[name="totalsConfigSets"]').val(); - if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; - if ( $(this).text() === 'Save' ) { - - setuptools.app.muledump.totals.config.save(name, true); - setuptools.lightbox.status($(this), 'Saved!'); - - window.init_totals(); - window.update_totals(); - - return; - - } - - if ( currentSet !== name ) setuptools.app.muledump.totals.config.reset(currentSet); - currentSet = name; - setuptools.app.muledump.totals.config.activate(name); - setuptools.app.muledump.totals.menu.settings(); - setuptools.lightbox.status($('.setuptools.link.activateSet'), "Enabled!"); - - }); - - // delete a configuration set - $('.setuptools.link.deleteSet').on('click.muledump.totals.deleteSet', function() { - - if ( $(this).hasClass('disabled') === true ) return; - var name = $('select[name="totalsConfigSets"]').val(); - if ( name === 'Default' ) { - setuptools.lightbox.status(this, 'No!'); - return; - } - if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; - delete setuptools.data.muledump.totals.configSets.settings[name]; - setuptools.app.config.save('Totals config set deleted', true); - if ( name === setuptools.data.muledump.totals.configSets.active ) setuptools.app.muledump.totals.config.activate('Default'); - setuptools.app.muledump.totals.menu.settings(); - - }); - - // save configurations - $('.setuptools.link.saveNewSet').on('click.muledump.totals.saveNewSet', function() { - - if ( $(this).hasClass('disabled') === true ) return; - if ( this.busy === true ) return; - var name = $('input[name="newConfigSetName"]').val(); - - // name cannot be empty - if ( name === '' ) { - - this.busy = true; - $(this).removeClass('positive').addClass('negative'); - setuptools.lightbox.status(this, 'Invalid set name', function(self) { - self.busy = false; - $(self).removeClass('negative'); - }); - return; - - } - - // name must be unique - if ( typeof setuptools.data.muledump.totals.configSets[name] === 'object' ) { - - $(this).removeClass('positive').addClass('negative'); - setuptools.lightbox.status(this, 'Name already exists', function(self) { - self.removeClass('negative').addClass('positive'); - }); - return; - - } - - var origName = setuptools.data.muledump.totals.configSets.active; - - // create the configuration - setuptools.app.muledump.totals.config.save(name); - setuptools.app.muledump.totals.menu.settings(); - setuptools.lightbox.status($('.setuptools.link.saveNewSet'), 'Created!'); - - // reset previous configSet if saving a new set - if ( origName !== name ) setuptools.app.muledump.totals.config.reset(origName); - - }); - - // reset the slotOrder to default - $('div.setuptools.link.resetSlotOrder').on('click.muledump.resetSlotOrder', function() { - setuptools.app.muledump.totals.config.setKey('slotOrder', $.extend(true, [], setuptools.copy.totals.defaultConfig.slotOrder)); - setuptools.app.muledump.totals.config.setKey('slotSubOrder', $.extend(true, {}, setuptools.config.totalsKeyObjects.slotSubOrder)); - setuptools.app.muledump.totals.menu.settings(); - }); - - // erase the hidden items list - $('div.setuptools.link.clearAllHidden').on('click.muledump.clearAllHidden', function() { - setuptools.app.muledump.totals.config.setKey('itemFilter', $.extend(true, [], setuptools.config.totalsKeyObjects.itemFilter)); - setuptools.tmp.globalTotalsCounter.import('clearExcluded'); - window.update_totals(); - window.update_filter(); - option_updated('totals'); - setuptools.app.muledump.totals.menu.settings(); - }); - - // handle hidden items list clicks - var itemsSelected = $('div#hiddenItems div.item'); - setuptools.app.muledump.tooltip(itemsSelected, 'hiddenItemsTooltip'); - itemsSelected.off('click.muledump.totals.hiddenItems').on('click.muledump.totals.hiddenItems', function(e) { - if ( e.shiftKey === true ) { - - var itemId = +$(this).attr('data-itemid'); - setuptools.app.muledump.totals.config.getKey('itemFilter').splice(setuptools.app.muledump.totals.config.getKey('itemFilter').indexOf(itemId), 1); - setuptools.app.muledump.totals.config.setKey('itemFilter', setuptools.app.muledump.totals.config.getKey('itemFilter')); - $(this).remove(); - $('.tooltip').remove(); - - } - }); - - // handle account filter list clicks - $('#accountFilterList div').off('click.muledump.totals.accountFilterList').on('click.muledump.totals.accountFilterList', function(e) { - - if ( e.shiftKey === true ) { - - var guid = $(this).attr('data-guid'); - if ( !guid ) return; - setuptools.app.muledump.totals.config.getKey('accountFilter').splice(setuptools.app.muledump.totals.config.getKey('accountFilter').indexOf(guid), 1); - $(this).remove(); - if ( setuptools.app.muledump.totals.config.getKey('accountFilter').length === 0 ) { - - $('#accountFilterList').text('No accounts in filter'); - - } - - } - - }); - - $('div.muledump.link.nameswap').on('click.muledump.link.nameswap', function() { - setuptools.data.config.mqDisplayIgn = !(setuptools.data.config.mqDisplayIgn); - setuptools.app.muledump.totals.menu.settings(); - }); - -}; - -/** - * @function - * @param {jQuery} [track] - * Display the totals menu - */ -setuptools.app.muledump.totals.menu.main = function(track) { - - if ( !(track instanceof jQuery) ) track = $('#totalsMenu'); - setuptools.lightbox.menu.context.close('totalsmenu'); - var options = [ - { - option: 'hover', - action: 'close' - }, - { - option: 'scrollLock', - hook: '#totalsMenu' - }, - { - option: 'skip', - value: 'reposition' - }, - { - option: 'afterClose', - callback: setuptools.app.muledump.totals.menu.main - }, - { - option: 'class', - value: 'smallMenuCells' - }, - { - option: 'css', - css: { - width: '177px' - } - }, - { - option: 'pos', - h: 'left', - v: 'top', - vpx: 28 - }, - { - class: 'toggleTotals', - name: ( (setuptools.data.options.totals === true) ? 'Disable' : 'Enable' ) + ' Totals', - callback: setuptools.app.muledump.toggleoption, - callbackArg: 'totals' - }, - { - class: 'openTotalsSettings', - name: 'Settings Manager', - callback: setuptools.app.muledump.totals.menu.settings, - override: 'afterClose' - } - ]; - - // totals needs to be enabled for these options - if ( setuptools.data.options.totals === true ) { - - if ( Array.isArray(setuptools.app.muledump.totals.config.getKey('accountFilter')) && setuptools.app.muledump.totals.config.getKey('accountFilter').length > 0 ) options.push({ - class: 'resetAccountFilter', - name: 'Reset Account Filter', - callback: function() { - setuptools.app.muledump.totals.config.setKey('accountFilter', $.extend(true, [], setuptools.config.totalsKeyObjects.accountFilter)); - setuptools.app.muledump.totals.updateSecondaryFilter(); - setuptools.tmp.globalTotalsCounter.import(); - window.update_totals(); - window.update_filter(); - option_updated('totals'); - } - }); - - options.push({ - class: 'displayGlobalTotals', - name: ( (setuptools.data.options.totalsGlobal === true) ? 'Disable' : 'Enable' ) + ' Global', - callback: function(arg) { - - // toggle the option - setuptools.app.muledump.toggleoption(arg, undefined, true); - - // mules with custom sorting need to be reset in certain circumstances - for (var guid in mules) - if (mules.hasOwnProperty(guid)) - if (mules[guid].customSorting === true) { - - mules[guid].createCounter(); - mules[guid].query(false, true); - - } - - window.update_totals(); - window.update_filter(); - window.options_save(); - - }, - callbackArg: 'totalsGlobal' - }); - - options.push( - /*{ - class: 'totalsBasicMenu', - name: 'Basic Filters...', - callback: setuptools.app.muledump.totals.menu.basic, - override: 'afterClose' - },*/ - { - option: 'select', - name: 'Sorting Mode', - class: 'sortingMode', - options: { - standard: 'Standard', - alphabetical: 'Alphabetical', - fb: 'Fame Bonus', - fp: 'Feed Power' - }, - selected: setuptools.app.muledump.totals.config.getKey('sortingMode'), - binding: function () { - - $('select.sortingMode').on('change.muledump.totals.sortingMode', function () { - - var mode = $(this).val(); - setuptools.app.muledump.totals.config.setKey('sortingMode', mode); - setuptools.app.muledump.totals.updateSecondaryFilter(); - window.init_totals(); - window.update_totals(); - setuptools.app.muledump.totals.menu.main(); - - }); - - } - }); - - var favoriteOptions = {}; - setuptools.data.muledump.totals.configSets.favorites.filter(function(item, index) { - if ( setuptools.app.muledump.totals.config.exists(item) === false ) { - - setuptools.data.muledump.totals.configSets.favorites.splice(index, 1); - return; - - } - - favoriteOptions[item] = item; - }); - if ( typeof favoriteOptions[setuptools.data.muledump.totals.configSets.active] !== 'string' ) favoriteOptions[setuptools.data.muledump.totals.configSets.active] = setuptools.data.muledump.totals.configSets.active; - - if ( Object.keys(favoriteOptions).length > 1 ) options.push({ - option: 'select', - name: 'Favorite Filters', - class: 'favoriteFilter', - options: favoriteOptions, - selected: setuptools.data.muledump.totals.configSets.active, - binding: function() { - - $('select.favoriteFilter').on('change.muledump.totals.favoriteFilter', function() { - - var name = $(this).val(); - if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; - setuptools.app.muledump.totals.config.reset(setuptools.data.muledump.totals.configSets.active); - setuptools.app.muledump.totals.config.activate(name); - setuptools.app.muledump.totals.menu.main(); - - }); - - } - }); - - if ( setuptools.data.muledump.totals.configSets.active !== 'Default' ) options.push({ - class: 'saveTotalsSettings', - name: 'Save Settings', - callback: function() { - setuptools.app.muledump.totals.config.save('active', true); - setuptools.lightbox.status(this, 'Saved!'); - } - }); - - options.push({ - class: 'resetTotalsSettings', - name: 'Reset Settings', - callback: function() { - setuptools.app.muledump.cleanupSecondaryCache(); - setuptools.app.muledump.totals.config.activate('active', true); - } - }, - { - option: 'header', - value: 'Advanced Filters...', - class: 'totalsAdvancedMenu', - callback: setuptools.app.muledump.totals.menu.advanced, - override: 'afterClose' - }, - { - option: 'header', - value: 'Standard Filters' - }, - { - option: 'select', - name: 'Fame Bonus', - class: 'fameBonusFilter', - options: { - '-1': 'Disabled', - '0': '> 0', - '1': '> 1%', - '2': '> 2%', - '3': '> 3%', - '4': '> 4%', - '5': '> 5%' - }, - selected: setuptools.data.options.fameamount, - binding: function() { - - $('select.fameBonusFilter').change(function() { - - setuptools.data.options.famefilter = !( $(this).val() === '-1' ); - setuptools.data.options.fameamount = $(this).val(); - option_updated('famefilter'); - - }); - - } - }, - { - option: 'select', - name: 'Feed Power', - class: 'feedPowerFilter', - options: { - '-1': 'Disabled', - '0': '> 0', - '100': '> 100', - '250': '> 250', - '500': '> 500', - '1000': '> 1000', - '2500': '> 2500' - }, - selected: setuptools.data.options.feedpower, - binding: function() { - - $('select.feedPowerFilter').change(function() { - - setuptools.data.options.feedfilter = !( $(this).val() === '-1' ); - setuptools.data.options.feedpower = $(this).val(); - option_updated('feedfilter'); - - }); - - } - }, - { - class: 'toggleSBFilter', - name: ( (setuptools.data.options.sbfilter === true) ? 'Disable' : 'Show Only' ) + ' Soulbound', - callback: setuptools.app.muledump.toggleoption, - callbackArg: 'sbfilter' - }, - { - class: 'toggleNonSBFilter', - name: ( (setuptools.data.options.nonsbfilter === true) ? 'Disable' : 'Show Only' ) + ' Tradeable', - callback: setuptools.app.muledump.toggleoption, - callbackArg: 'nonsbfilter' - }, - { - class: 'toggleUTFilter', - name: ( (setuptools.data.options.utfilter === true) ? 'Disable' : 'Show Only' ) + ' Untiered', - callback: setuptools.app.muledump.toggleoption, - callbackArg: 'utfilter' - }, - { - class: 'toggleSTFilter', - name: ( (setuptools.data.options.stfilter === true) ? 'Disable' : 'Show Only' ) + ' Set Items', - callback: setuptools.app.muledump.toggleoption, - callbackArg: 'stfilter' - }); - - } - - setuptools.lightbox.menu.context.create('totalsmenu', false, track, options); - -}; - -/** - * @function - * @param {object} options - * @param types - */ -setuptools.app.muledump.totals.menu.populateByType = function(options, types) { - - if ( typeof types === 'string' ) types = [types]; - if ( Array.isArray(types) === false ) return; - - for ( var a = 0; a < types.length; a++ ) { - - var type = types[a]; - var filterName = 'totalsFilter-' + type; - var displayName = setuptools.app.muledump.itemSlotTypeName(type); - if ( typeof displayName === 'undefined' ) continue; - options.push({ - class: 'toggle-' + filterName, - name: ( (setuptools.data.options[filterName] === true) ? 'Hide' : 'Show' ) + ' ' + displayName, - callback: setuptools.app.muledump.toggleoption, - callbackArg: filterName - }); - - } - -}; - -/** - * @function - * @param {string} key - * @param {string} [configSet] - * @param {*} [defaultValue] - * @returns {*} - * Returns the specified key from a configSet - */ -setuptools.app.muledump.totals.config.getKey = function(key, configSet, defaultValue) { - - if ( !configSet || configSet === false ) configSet = setuptools.data.muledump.totals.configSets.active; - if ( typeof setuptools.data.muledump.totals.configSets.settings[configSet] !== 'object' ) return; - if ( typeof setuptools.data.muledump.totals.configSets.settings[configSet][key] === 'undefined' ) { - if ( defaultValue === null ) return; - if ( !defaultValue ) defaultValue = ( Array.isArray(setuptools.config.totalsKeyObjects[key]) === true ) ? - $.extend(true, [], setuptools.config.totalsKeyObjects[key]) : - $.extend(true, {}, setuptools.config.totalsKeyObjects[key]); - this.setKey(key, defaultValue, configSet); - return defaultValue; - } - return setuptools.data.muledump.totals.configSets.settings[configSet][key]; - -}; - -/** - * @function - * @param {string} key - * @param {*} value - * @param {string} [configSet] - * Returns the specified key from a configSet - */ -setuptools.app.muledump.totals.config.setKey = function(key, value, configSet) { - - if ( typeof key !== 'string' || !value ) return; - if ( !configSet ) configSet = setuptools.data.muledump.totals.configSets.active; - if ( typeof setuptools.data.muledump.totals.configSets.settings[configSet] !== 'object' ) return; - setuptools.data.muledump.totals.configSets.settings[configSet][key] = value; - setuptools.data.options[key] = setuptools.data.muledump.totals.configSets.settings[configSet][key]; - -}; - -/** - * @function - * @param {string} configSet - * @returns {boolean} - * Returns whether or not the specified configSet exists - */ -setuptools.app.muledump.totals.config.exists = function(configSet) { - - if ( !configSet || configSet === 'active' ) configSet = setuptools.data.muledump.totals.configSets.active; - if ( typeof configSet !== 'string' ) return; - return ( typeof setuptools.data.muledump.totals.configSets.settings[configSet] === 'object' ); - -}; - -/** - * @function - * @param configSet - * Reinitializes a configSet (or multiple) for when the slotMap changes or items get added or removed - */ -setuptools.app.muledump.totals.config.reinit = function(configSet) { - - if ( configSet === 'all' ) configSet = Object.keys(setuptools.data.muledump.totals.configSets.settings); - if ( configSet === 'active' ) configSet = [setuptools.data.muledump.totals.configSets.active]; - if ( typeof configSet === 'string' ) configSet = [configSet]; - if ( Array.isArray(configSet) === false || configSet.length === 0 ) return; - - setuptools.app.techlog('Totals/ConfigSet reinit executing'); - - // configSet cleanup - configSet.filter(function(configSet) { - - var slotSubOrder = setuptools.app.muledump.totals.config.getKey('slotSubOrder', configSet); - Object.filter(slotSubOrder, function(vst, items) { - - // loop through slotOrder groups and make list of items that do not belong - var deleteItems = []; - items.filter(function(item) { - - var itemid = +item; - if ( - typeof window.items[itemid] === 'undefined' || - ( - window.items[itemid][setuptools.config.vstIndex] !== (+vst) && - window.items[itemid][1] !== (+vst) - ) - ) { - deleteItems.push(item); - } - - }); - - // delete the found items - for ( var i = 0; i < deleteItems.length; i++ ) { - slotSubOrder[vst].splice(slotSubOrder[vst].indexOf(deleteItems[i]), 1); - setuptools.app.techlog('Totals/ConfigSet reinit deleting: [set: ' + configSet + ', vst: ' + vst + ', itemid: ' + deleteItems[i] + ']'); - } - - // loop through window.items and insert items that do belong - Object.filter(window.items, function(itemid, item) { - itemid = itemid.toString(); - if ( (!(item[setuptools.config.vstIndex] !== (+vst) && item[1] !== (+vst))) && slotSubOrder[vst].indexOf(itemid) === -1 ) { - slotSubOrder[vst].push(itemid); - setuptools.app.techlog('Totals/ConfigSet reinit adding: [set: ' + configSet + ', vst: ' + vst + ', itemid: ' + itemid + ']'); - } - }); - - }); - - }); - -}; - -/** - * @function - * @param {string} configSet - * @returns {boolean} - * Delete a specific configSet - */ -setuptools.app.muledump.totals.config.delete = function(configSet) { - - if ( configSet === 'all' ) configSet = Object.keys(setuptools.data.muledump.totals.configSets.settings); - if ( configSet === 'active' ) configSet = [setuptools.data.muledump.totals.configSets.active]; - if ( typeof configSet === 'string' ) configSet = [configSet]; - if ( Array.isArray(configSet) === false || configSet.length === 0 ) return; - - // delete specified configSets - configSet.filter(function(configSet) { - if ( - setuptools.app.muledump.totals.config.exists(configSet) === false || - configSet === 'Default' - ) return; - - // delete configSet - delete setuptools.data.muledump.totals.configSets.settings[configSet]; - - // remove from favorites - if ( setuptools.data.muledump.totals.configSets.favorites.indexOf(configSet) > -1 ) setuptools.data.muledump.totals.configSets.favorites.splice( - setuptools.data.muledump.totals.configSets.favorites.indexOf(configSet), - 1 - ); - }); - - // reset default configuration - if ( configSet.length === 1 && configSet[0] === 'Default' ) setuptools.data.muledump.totals.configSets.settings[configSet[0]] = $.extend(true, {}, setuptools.copy.totals.defaultConfig); - if ( configSet.indexOf(setuptools.data.muledump.totals.configSets.active) > -1 ) setuptools.app.muledump.totals.config.activate('Default'); - - return true; - -}; - -/** - * @function - * @param {boolean} state - */ -setuptools.app.muledump.totals.config.toggleAllTypes = function(state) { - - if ( typeof state === 'undefined' ) return false; - setuptools.app.muledump.totals.config.getTypes().filter(function(type) { - setuptools.app.muledump.toggleoption('totalsFilter-' + type, state, true); - }); - window.update_totals(); - window.update_filter(); - option_updated('totals'); - return true; - -}; - -/** - * @function - * @param {string} name - * Store a temporary backup of all configSets - */ -setuptools.app.muledump.totals.config.backup = function(name) { - - if ( typeof setuptools.copy.totals.configSets === 'undefined' ) { - setuptools.copy.totals.configSets = $.extend(true, {}, setuptools.data.muledump.totals.configSets); - return; - } - - // only copy configSets not present - var configSets = []; - if ( typeof name === 'string' ) configSets = [name]; - if ( configSets.length === 0 ) configSets = setuptools.data.muledump.totals.configSets.settings; - for ( var configSet in configSets ) - if ( configSets.hasOwnProperty(configSet) ) - if ( typeof setuptools.copy.totals.configSets[configSet] === 'undefined' ) - setuptools.copy.totals.configSets[configSet] = $.extend(true, {}, configSets[configSet]); - -}; - -/** - * @function - * @param {string} name - * @param {boolean} [immediate] - * Create a totals configuration set - */ -setuptools.app.muledump.totals.config.save = function(name, immediate) { - - if ( typeof name === 'undefined' || name === 'active') name = setuptools.data.muledump.totals.configSets.active; - if ( typeof name !== 'string' ) return; - var accountFilter = $.extend(true, [], setuptools.app.muledump.totals.config.getKey('accountFilter')); - var slotOrder = $.extend(true, [], setuptools.app.muledump.totals.config.getKey('slotOrder')); - var itemFilter = $.extend(true, [], setuptools.app.muledump.totals.config.getKey('itemFilter')); - var slotSubOrder = $.extend(true, {}, setuptools.app.muledump.totals.config.getKey('slotSubOrder')); - var disabled = $.extend(true, [], setuptools.app.muledump.totals.config.getKey('disabled')); - var sortingMode = setuptools.app.muledump.totals.config.getKey('sortingMode'); - if ( setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) setuptools.data.muledump.totals.configSets.settings[name] = {}; - setuptools.config.totalsSaveKeys.filter(function(item) { - setuptools.data.muledump.totals.configSets.settings[name][item] = setuptools.data.options[item]; - }); - var origName = setuptools.data.muledump.totals.configSets.active; - setuptools.data.muledump.totals.configSets.active = name; - setuptools.app.muledump.totals.config.setKey('accountFilter', accountFilter); - setuptools.app.muledump.totals.config.setKey('slotOrder', slotOrder); - setuptools.app.muledump.totals.config.setKey('itemFilter', itemFilter); - setuptools.app.muledump.totals.config.setKey('slotSubOrder', slotSubOrder); - setuptools.app.muledump.totals.config.setKey('sortingMode', sortingMode); - setuptools.app.muledump.totals.config.setKey('disabled', disabled); - setuptools.app.config.save('Totals config set saved', (immediate !== true)); - setuptools.copy.totals.configSets.settings[name] = $.extend(true, {}, setuptools.data.muledump.totals.configSets.settings[name]); - if ( name !== origName ) setuptools.app.muledump.totals.config.reset(origName); - window.options_save(); - setuptools.app.muledump.totals.config.backup(name); - -}; - -/** - * @function - * @param {string} [name] - * Resets the specified configSet to its previous save state without changing the UI - */ -setuptools.app.muledump.totals.config.reset = function(name) { - - if ( typeof name === 'undefined' || name === 'active' ) name = setuptools.data.muledump.totals.configSets.active || 'Default'; - if ( typeof name !== 'string' ) return; - if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; - setuptools.data.muledump.totals.configSets.settings[name] = $.extend(true, {}, setuptools.copy.totals.configSets && setuptools.copy.totals.configSets.settings[name] || setuptools.copy.totals.defaultConfig); - -}; - -/** - * @function - * @param {string} [name] - * @param {boolean} [reset] - * @param {boolean} [skipSave] - * Activate a totals configSet and optionally reset its state - */ -setuptools.app.muledump.totals.config.activate = function(name, reset, skipSave) { - - if ( typeof name === 'boolean' ) { - reset = name; - name = undefined; - } - - if ( typeof name === 'undefined' || name === 'active' ) name = setuptools.data.muledump.totals.configSets.active || 'Default'; - if ( typeof name !== 'string' ) return; - if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; - - // reset from original configuration - if ( reset === true ) setuptools.app.muledump.totals.config.reset(name); - - // reset keys for default profile - if ( name === 'Default' ) { - setuptools.data.muledump.totals.configSets.settings[name] = $.extend(true, {}, setuptools.copy.totals.defaultConfig); - setuptools.data.muledump.totals.configSets.settings[name].sortingMode = setuptools.copy.totals.defaultConfig.sortingMode; - } - - // reset keys - Object.filter(setuptools.data.muledump.totals.configSets.settings[name], function(key) { - setuptools.data.options[key] = setuptools.data.muledump.totals.configSets.settings[name][key]; - }); - - setuptools.data.muledump.totals.configSets.active = name; - if ( skipSave !== true ) setuptools.app.config.save('Totals config set activated'); - if ( setuptools.tmp.globalTotalsCounter instanceof Muledump_TotalsCounter ) setuptools.tmp.globalTotalsCounter.import(); - setuptools.app.muledump.totals.updateSecondaryFilter(); - window.init_totals(); - window.update_totals(); - window.update_filter(); - -}; - -/** - * @function - * @returns {Array} - * Return a list of item types - */ -setuptools.app.muledump.totals.config.getTypes = function() { - - var types = []; - Object.filter(window.itemsSlotTypeMap, function(type) { - if ( types.indexOf(type) === -1 ) types.push(type); - }); - return types; - -}; - -/** - * @function - * @param {string} guid - * @returns {string} - * Returns the display name for a provided guid - */ -setuptools.app.muledump.getName = function(guid) { - - return ( ( - setuptools.state.loaded === true && - setuptools.data.config.mqDisplayIgn === true && - typeof setuptools.data.accounts.accounts[guid].ign === 'string' - ) ? setuptools.data.accounts.accounts[guid].ign : guid ); - -}; - -/** - * @function - * @param vst - * Returns a list of items by virtualSlotType - */ -setuptools.app.muledump.itemsByVst = function(vst) { - - if ( typeof vst === 'string' ) vst = setuptools.app.muledump.itemSlotTypeVst(vst); - if ( typeof vst !== 'number' ) return []; - var itemList = []; - Object.filter(window.items, function(itemid, item) { - if ( - item[setuptools.config.vstIndex] === vst && - !(item[3] === 40 && item[4] === 0) && - setuptools.config.disqualifiedItemIds.indexOf(+itemid) === -1 - ) itemList.push(itemid); - }); - return itemList; - -}; - -/** - * @function - * @param {string} name - * Return the virtualSlotType of a named item group - */ -setuptools.app.muledump.itemSlotTypeVst = function(name) { - - if ( typeof window.itemsSlotTypeMap[name] === 'undefined' ) return; - return window.itemsSlotTypeMap[name].virtualSlotType || window.itemsSlotTypeMap[name].slotType; - -}; - -/** - * @function - * @param {number} vst - * @returns {*} - * Determine the display name of a provided type name, slotType, or virtualSlotType - */ -setuptools.app.muledump.itemSlotTypeName = function(vst) { - - var type = Object.filter(window.itemsSlotTypeMap, undefined, function(type, data) { - if ( vst === type || data.virtualSlotType === vst || data.slotType === vst ) return data.displayName || type[0].toUpperCase()+type.substr(1); - }); - return type[Object.keys(type)[0]]; - -}; - -/** - * @function - * @param {number} type - * @returns {*} - * Map item SlotType to a virtual id format - */ -setuptools.app.muledump.itemsSlotTypeMapper = function(type) { - - if ( typeof Number(type) === 'number' ) var itemid = Number(type); - - // mapConfig identifier keys and their corresponding index in constants - var mapKeys = { - name: 0, - slotType: 1, - tier: 2, - fameBonus: 5, - feedPower: 6, - bagType: 7, - soulbound: 8, - utst: 9 - }; - - var mapConfig = window.itemsSlotTypeMap; - var itemList = items; - if ( typeof itemid === 'number' ) { - - itemList = {}; - itemList[itemid] = window.items[itemid]; - - } - - var filteredItems = Object.filter(itemList, undefined, function(itemid, item) { - - if ( typeof item === 'undefined' ) return; - - var slotType = item[1]; - var virtualSlotType; - var configKeys = Object.keys(Object.filter(mapConfig, function(type, data) { - if ( data.slotType === slotType ) { - if ( typeof data.sheet === 'undefined' ) data.sheet = setuptools.config.totalsDefaultIcon; - return true; - } - })); - - for ( var x = 0; x < configKeys.length; x++ ) { - - var configKey = configKeys[x]; - - if ( typeof mapConfig[configKey] === 'undefined' ) { - setuptools.app.techlog('SlotTypeMapper encountered unknown slotType - ' + JSON.stringify(configKey)); - continue; - } - - virtualSlotType = undefined; - var matches = 0; - var required = Object.keys(mapConfig[configKey]).length; - for (var key in mapConfig[configKey]) { - - if (mapConfig[configKey].hasOwnProperty(key)) { - - // reserved properties; not checked against - if ( ['displayName', 'sheet'].indexOf(key) > -1 ) { - matches++; - continue; - } - - if ( key === 'slotType' && typeof virtualSlotType !== 'string' ) virtualSlotType = mapConfig[configKey].virtualSlotType; - - if ( key === 'virtualSlotType' ) { - virtualSlotType = mapConfig[configKey].virtualSlotType; - matches++; - continue; - } - - // values must match - if ( - ['number', 'boolean'].indexOf(typeof mapConfig[configKey][key]) > -1 && - mapConfig[configKey][key] !== item[mapKeys[key]] - ) continue; - - // try and include items but not require them to match (like name key) - if ( key === 'include' ) { - - if ( - mapConfig[configKey][key] instanceof RegExp && - item[mapKeys.name].match(mapConfig[configKey][key]) - ) { - matches = required; - } else { - required--; - } - continue; - } - - // some groups have multiple values for one key (I'm looking at you potions) - if ( - Array.isArray(mapConfig[configKey][key]) === true && - mapConfig[configKey][key].indexOf(item[mapKeys[key]]) === -1 - ) continue; - - if ( - mapConfig[configKey][key] instanceof RegExp && - !item[mapKeys[key]].match(mapConfig[configKey][key]) - ) continue; - - // support multiple gt/gte/lt/lte operations - if ( - Array.isArray(mapConfig[configKey][key]) === false && - !(mapConfig[configKey][key] instanceof RegExp) && - typeof mapConfig[configKey][key] === 'object' - ) { - - var foundCommands = 0; - var matchedCommands = 0; - for ( var command in mapConfig[configKey][key] ) { - - if ( mapConfig[configKey][key].hasOwnProperty(command) ) { - - foundCommands++; - var value = mapConfig[configKey][key][command]; - if ( - (command === 'gte' && item[mapKeys[key]] >= value) || - (command === 'gt' && item[mapKeys[key]] > value) || - (command === 'lte' && item[mapKeys[key]] <= value) || - (command === 'lt' && item[mapKeys[key]] < value) - ) matchedCommands++; - - } - - } - - if ( foundCommands !== matchedCommands ) continue; - - } - - matches++; - - } - - } - - if ( matches >= required ) return virtualSlotType || slotType; - - } - - }); - - var filteredValues = Object.values(filteredItems); - if ( typeof itemid === 'number' && filteredValues.length === 0 ) return 50000; - if ( filteredValues.length === 1 ) return filteredValues[0]; - return filteredItems; - -}; - -/** - * @function - * Update all secondary filters for totals processing - */ -setuptools.app.muledump.totals.updateSecondaryFilter = function() { - - // reset accountFilter and disabled filter on mules - for ( var guid in mules ) { - if (mules.hasOwnProperty(guid)) { - - // accountFilter - if ( setuptools.app.muledump.totals.config.getKey('accountFilter').indexOf(guid) === -1 ) { - mules[guid].dom.removeClass('filteringEnabled'); - } else { - mules[guid].dom.addClass('filteringEnabled'); - } - - // disabled filter - mules[guid].disabled = ( setuptools.app.muledump.totals.config.getKey('disabled').indexOf(guid) > -1 ); - mules[guid].dom.toggleClass('disabled', mules[guid].disabled); - if ( mules[guid].disabled === true ) { - setuptools.tmp.globalTotalsCounter.import(mules[guid].totals, true); - } else { - - // we'll only run this if it'll pass mode 0 - if ( - typeof setuptools.tmp.globalTotalsCounter.sourceData[guid] !== 'object' || - new SeaSalt_Hashing(JSON.stringify(setuptools.tmp.globalTotalsCounter.sourceData[guid].meta), 'sha256', 'hex').toString() !== new SeaSalt_Hashing(JSON.stringify(mules[guid].totals.data.meta), 'sha256', 'hex').toString() - ) setuptools.tmp.globalTotalsCounter.import(mules[guid].totals); - - } - - } - } - - // insert generated totals save keys if they aren't already there - // note: doing this by key count is probably not as good a choice as doing it by key validation. - // this would be the place to add/remove key changes. - if ( setuptools.config.totalsSaveKeys.length <= setuptools.config.totalsFilterKeysIndex ) { - Object.keys(window.itemsSlotTypeMap).filter(function(element) { - setuptools.config.totalsSaveKeys.push('totalsFilter-' + element); - }); - setuptools.app.muledump.totals.config.activate(true); - } - - // populate any missing filter keys in options - for ( var h = 0; h < setuptools.config.totalsSaveKeys.length; h++ ) - if ( typeof setuptools.data.options[setuptools.config.totalsSaveKeys[h]] === 'undefined' ) - setuptools.data.options[setuptools.config.totalsSaveKeys[h]] = true; - - // generate the secondary item filter - setuptools.tmp.totalsSecondaryFilter = []; - for ( var i = setuptools.config.totalsFilterKeysIndex; i < setuptools.config.totalsSaveKeys.length; i++ ) { - - var key = setuptools.config.totalsSaveKeys[i]; - var type = (key.match(/^.*?-([a-z0-9]*)$/i))[1]; - var vstList = setuptools.app.muledump.itemSlotTypeVst(type); - if ( typeof vstList !== 'number' ) vstList = [50000]; - if ( typeof vstList === 'number' ) vstList = [vstList]; - - // rather than build this every call, let's cache the object given it is static anyway - if ( typeof setuptools.tmp.totalsRuntimeCache === 'undefined') setuptools.tmp.totalsRuntimeCache = {}; - if ( typeof setuptools.tmp.totalsRuntimeCache[type] === 'undefined' ) setuptools.tmp.totalsRuntimeCache[type] = []; - - Object.filter( - window.items, - function(itemid, item) { - for ( var i = 0; i < vstList.length; i++ ) - if ( item[setuptools.config.vstIndex] === vstList[i] ) setuptools.tmp.totalsRuntimeCache[type].push(Number(itemid)); - } - ); - - // process the item list - var itemList = setuptools.tmp.totalsRuntimeCache[type]; - var j; - if ( setuptools.data.options[key] === true ) { - - for ( j = 0; j < itemList.length; j++ ) - if ( setuptools.tmp.totalsSecondaryFilter.indexOf(itemList[j]) > -1 ) - setuptools.tmp.totalsSecondaryFilter.splice(setuptools.tmp.totalsSecondaryFilter.indexOf(itemList[j]), 1); - - } else { - - for ( j = 0; j < itemList.length; j++ ) - if ( setuptools.tmp.totalsSecondaryFilter.indexOf(itemList[j]) === -1 ) - setuptools.tmp.totalsSecondaryFilter.push(itemList[j]); - - } - - } - -}; - -/** - * @function - * @param {number} itemid - * Toggle the item in and out of the itemFilter - */ -setuptools.app.muledump.totals.toggleHideItem = function(itemid) { - - itemid = Number(itemid); - var index = setuptools.app.muledump.totals.config.getKey('itemFilter').indexOf(itemid); - if ( index === -1 ) { - setuptools.app.muledump.totals.config.getKey('itemFilter').push(itemid); - } else setuptools.app.muledump.totals.config.getKey('itemFilter').splice(index, 1); - setuptools.app.muledump.totals.config.setKey('itemFilter', setuptools.app.muledump.totals.config.getKey('itemFilter')); - window.update_totals(); - window.update_filter(); - option_updated('totals'); - -}; - -/** - * @function - * @param {string} option - * @param {boolean} [value] - * @param {boolean} [skip] - * Toggle the state of the specified options - */ -setuptools.app.muledump.toggleoption = function(option, value, skip) { - - if ( typeof option === 'undefined' ) return; - if ( typeof option === 'string' ) option = [option]; - if ( Array.isArray(option) === false ) return; - - // switch the option - for ( var i = 0; i < option.length; i++) setuptools.data.options[option[i]] = ( typeof value === 'undefined' ) ? !setuptools.data.options[option[i]] : value; - - // totals filter keys need to update the secondary item filter list - setuptools.app.muledump.totals.updateSecondaryFilter(); - - if ( skip !== true ) { - update_totals(); - update_filter(); - options_save(); - } - -}; - -/** - * @function - * @param {object} e - * Create a quick access menu for various UI endpoints and commands - */ -setuptools.app.muledump.bodymenu = function(e) { +/** + * @function + * @param {object} e + * Create a quick access menu for various UI endpoints and commands + */ +setuptools.app.muledump.bodymenu = function(e) { e.preventDefault(); var options = [{ @@ -2778,21 +847,6 @@ setuptools.app.muledump.mulemenu = function(e, guid, context, track, extraopts) } // add global options - if ( - setuptools.app.config.determineFormat(setuptools.data.accounts, 0) === true || - (setuptools.state.loaded === true && setuptools.data.accounts.accounts[guid].loginOnly === false ) - ) options.push( - { - class: 'chsort', - name: 'Edit Character Sorting Lists', - callback: function(guid) { - // v1 // setuptools.app.muledump.chsortcustom(mules[guid]); - setuptools.app.muledump.charsort.menu(guid); - }, - callbackArg: guid - } - ); - if ( setuptools.data.options.totals === true ) options.push({ class: 'toggleTotals', name: (( @@ -2816,9 +870,38 @@ setuptools.app.muledump.mulemenu = function(e, guid, context, track, extraopts) }, callbackArg: guid - }); - - options.push({ + }); + + if ( + setuptools.app.config.determineFormat(setuptools.data.accounts, 0) === true || + (setuptools.state.loaded === true && setuptools.data.accounts.accounts[guid].loginOnly === false ) + ) options.push( + { + class: 'chsort', + name: 'Character Sorting Lists', + callback: function(guid) { + // v1 // setuptools.app.muledump.chsortcustom(mules[guid]); + setuptools.app.muledump.charsort.menu(guid); + }, + callbackArg: guid + } + ); + + options.push({ + class: 'openWardrobe', + name: 'Skin Wardrobe', + callback: function(guid) { + setuptools.app.muledump.ownedSkins(guid); + }, + callbackArg: guid + },{ + class: 'openWhitebags', + name: 'Whitebag Tracker', + callback: function(guid) { + setuptools.app.muledump.whitebag.tracker(guid); + }, + callbackArg: guid + },{ class: 'copyMenuOpen', name: "Copy...", callback: setuptools.app.muledump.copymenu, @@ -3129,7 +1212,7 @@ setuptools.app.muledump.realmeye.link = function(itemNumber, link, extra) { // determine uri if ( link === 'wiki' ) { - itemName = itemName.toLowerCase().replace(/\s/g, '-'); + itemName = itemName.toLowerCase().replace(/(\s|')/g, '-'); } else if ( link === 'sell' ) { link = 'offers-to/buy'; itemName = itemNumber; @@ -3553,66 +1636,331 @@ setuptools.app.muledump.checkupdates = function(force) { // White Bag Tracker */ -setuptools.app.muledump.whitebag = {}; - -// returns a list of all white bag items +/** + * @function + * @param {boolean} [full] + * @returns {object} + * Gather a list of white bag items from constants + */ setuptools.app.muledump.whitebag.items = function(full) { // pull a list of whitebags from constants - var whitebags = Object.filter(items, function(key, value) { - if ( value[7] === 6 ) return true; - }); + setuptools.tmp.whitebagsFull = ( typeof setuptools.tmp.whitebagsFull === 'object' ) ? + setuptools.tmp.whitebags : + Object.filter(items, function(key, value) { + if ( value[7] === 6 ) return true; + }); // if full === true we will send the items and their data - if ( full === true ) return whitebags; + if ( full === true ) return setuptools.tmp.whitebagsFull; - // but typically we'll only need to send the item ids - return Object.keys(whitebags); + // but typically we'll only need to send the item ids after converting them from strings + if ( typeof setuptools.tmp.whitebagsCompact === 'object' ) return setuptools.tmp.whitebagsCompact; + setuptools.tmp.whitebagsCompact = Object.keys(setuptools.tmp.whitebagsFull); + setuptools.tmp.whitebagsCompact.filter(function(element, index) { + setuptools.tmp.whitebagsCompact[index] = Number(element); + }); + return setuptools.tmp.whitebagsCompact; }; -setuptools.app.muledump.whitebag.tracker = function(guid) { +/** + * @function + * @param {string} guid + * @param {boolean} [counters] + * @param {boolean} [owned] + * Initialize the base object for a new guid + */ +setuptools.app.muledump.whitebag.init = function(guid, counters, owned) { // it's so big! var config = setuptools.data.muledump.whitebagTracker; // generate the base configuration for new accounts if ( typeof config.accounts[guid] === 'undefined' ) config.accounts[guid] = $.extend(true, {}, setuptools.objects.whitebagTrackerAccount); + if ( typeof config.accounts[guid] === 'object' ) { + if ( counters === true ) config.accounts[guid].items = {}; + if ( owned === true ) config.accounts[guid].owned = []; + } - var displayName; - if ( - setuptools.state.loaded === true && - setuptools.data.config.mqDisplayIgn === true && - typeof setuptools.data.accounts.accounts[guid] === 'object' && - typeof setuptools.data.accounts.accounts[guid].ign === 'string' - ) displayName = setuptools.data.accounts.accounts[guid].ign; - if ( displayName === undefined ) displayName = guid; +}; + +/** + * @function + * @param {string} guid + * @param {object} config + * Saves the specified configuration permanently + */ +setuptools.app.muledump.whitebag.save = function(guid, config) { + + setuptools.data.muledump.whitebagTracker.accounts[guid] = config; + setuptools.app.config.save('Whitebags/Totals saving changes', true); + +}; + +/** + * @function + * @param guid + * Display Whitebag Tracker for Totals Count + */ +setuptools.app.muledump.whitebag.tracker = function(guid) { + + setuptools.lightbox.close(); + setuptools.tmp.wbSaveOnClose = false; + + // initialize the base object if this account is new here + setuptools.app.muledump.whitebag.init(guid); + + // it's so big! + var config = $.extend(true, {}, setuptools.data.muledump.whitebagTracker.accounts[guid]); // build our ui - var dom = $('#whitebagTracker'); - var html = ' \ -
\ -
White Bag Tracker
\ - ' + ( (mules[guid].opt('accountName') === true ) ? '
' + displayName + '
' : '' ) + ' \ -
\ -
\ - '; + setuptools.lightbox.build('whitebag-totals', ' \ +
\ +
\ + \ +
\ +
\ +
\ +
\ +
\ + \ +
\ +
\ +
\ +
\ +
\ + ' + ( (mules[guid].opt('accountName') === true ) ? '
' + setuptools.app.muledump.getName(guid) + '
' : '' ) + ' \ +
\ +
\ +
\ +
 \ +
Legend\ +
Shift+Click items to add/remove them from the owned list\ +
Click items to increase the quantity by 1\ +
Ctrl+Click items to decrease the quantity by 1\ +
Auto saves on close\ +
\ + '); // display our ui - dom.empty().append(html); + setuptools.lightbox.settitle('whitebag-totals', 'White Bag Tracker'); + setuptools.lightbox.drawhelp('whitebag-totals', 'docs/muledump/whitebags', 'White Bag Tracker Help'); + setuptools.lightbox.display('whitebag-totals', { + variant: 'fl-Whitebags', + afterClose: function() { + + if ( setuptools.tmp.wbSaveOnClose !== true ) return; + setuptools.app.muledump.whitebag.save(guid, config); + + } + }); - // populate the items - var itemsDom = dom.find('div.items'); + // obtain and sort the whitebags list var whitebags = {}; - (setuptools.app.muledump.whitebag.items()).filter(function(item) { + var wbitems = ((setuptools.app.muledump.whitebag.items()).filter(function(item) { whitebags[item] = 0; - }); - whitebags = $.extend(true, whitebags, config.accounts[guid].items); - Object.filter(whitebags, function(key) { - var itemDom = window.item(key, 'wb', (config.accounts[guid].items[key] || 0)); + return true; + })).sort(function(a,b) { + // sort alphabetically if same slotType + if ( items[a][1] === items[b][1] ) { + if ( items[a][0] < items[b][0] ) return -1; + if ( items[a][0] > items[b][0] ) return 1; + // identical names; sort by itemid instead + return a-b; + } + // sort by slotType + return (items[a][1]-items[b][1]); + }); + + // merge the whitebags list with the configuration data + config.items = $.extend(true, whitebags, config.items); + + // populate items + var itemsDom = $('div.wbstage > div.items > div'); + wbitems.filter(function(key) { + var selected = false; + if ( config.owned.indexOf(key) === -1 && config.items[key] > 0 ) config.owned.push(key); + if ( config.owned.indexOf(key) > -1 ) selected = true; + var itemDom = window.item(key, 'wb noselect' + ( (selected === true) ? ' selected' : '' ), ( (setuptools.data.config.wbTotals === true) ? (config.items[key] || 0) : undefined )); itemDom.appendTo(itemsDom); }); + // select the newly inserted items + var wbitemsdom = $('div.item.wb'); + + // bind tooltips + setuptools.app.muledump.tooltip(wbitemsdom, 'whitebagTrackerTooltip', 750); + + // bind increment/decrement + wbitemsdom.on('click.wb.increment', function(e) { + + var itemid = Number($(this).attr('data-itemid')); + + if ( setuptools.app.muledump.keys('shift', e) === true ) { + + if ( config.owned.indexOf(itemid) === -1 ) { + $(this).addClass('selected'); + config.owned.push(itemid); + } else { + if ( setuptools.data.config.wbTotals === true && config.items[itemid] > 0 ) return; + $(this).removeClass('selected'); + config.owned.splice( + config.owned.indexOf(itemid), + 1 + ); + config.items[itemid] = 0; + } + setuptools.tmp.wbSaveOnClose = true; + return; + + } + + if ( setuptools.data.config.wbTotals === false ) return; + var value = Number($(this).text()); + if ( typeof value !== 'number' ) value = 0; + if ( value === 0 && setuptools.app.muledump.keys('ctrl', e) === true ) return; + value = ( setuptools.app.muledump.keys('ctrl', e) === true ) ? + ( + (value > 0) ? + value-1 : + value + ) : + value+1; + + setuptools.tmp.wbSaveOnClose = true; + $(this).find('div').text(value); + if ( value > 0 ) { + $(this).addClass('selected'); + if ( config.owned.indexOf(itemid) === -1 ) config.owned.push(itemid); + } + if ( + value === 0 && + config.owned.indexOf(itemid) === -1 + ) $(this).removeClass('selected'); + config.items[itemid] = value; + + }); + + // handle the actions menu button + $('div.muledump.link.go').on('click.wbmenu.go', function() { + + var action = $('select[name="wbaction"]').val().toLowerCase(); + if ( action === 'reset' ) { + setuptools.tmp.wbSaveOnClose = false; + setuptools.app.muledump.whitebag.tracker(guid); + } else if ( action === 'cancel' ) { + setuptools.tmp.wbSaveOnClose = false; + setuptools.lightbox.close(); + } else if ( action === 'clear' ) { + setuptools.app.muledump.whitebag.init(guid, true, true); + setuptools.tmp.wbSaveOnClose = false; + setuptools.app.muledump.whitebag.tracker(guid); + } else if ( action === 'save' ) { + setuptools.tmp.wbSaveOnClose = false; + setuptools.app.muledump.whitebag.save(guid, config); + setuptools.lightbox.status($(this), 'Ok!'); + } else if ( action === 'totals' ) { + setuptools.data.config.wbTotals = !( setuptools.data.config.wbTotals ); + setuptools.app.config.save('WhiteBag/Tracker switching wbTotals option', true); + setuptools.app.muledump.whitebag.tracker(guid); + } else if ( action === 'import' ) { + + setuptools.lightbox.build('whitebags-import', ' \ + This replaces the current values by counting current inventory. \ +
 \ +
How do you wish to proceed?\ + \ +
\ + \ + \ + \ + \ +
\ + '); + + setuptools.lightbox.settitle('whitebags-import', 'Import from Inventory'); + setuptools.lightbox.drawhelp('whitebags-import', 'docs/features/whitebags', 'White Bag Tracker Help'); + setuptools.lightbox.display('whitebags-import', {variant: 'nobackground'}); + + // bind cancel button + $('div.muledump.link.import.cancel').on('click.import.cancel', function() { + setuptools.lightbox.close('whitebags-import'); + }); + + // bind confirm button + $('div.muledump.link.import:not(.cancel)').on('click.import.confirm', function(e) { + + var action; + if ( $(this).hasClass('clear') ) { + action = 'clear'; + } else if ( $(this).hasClass('reset') ) { + action = 'reset'; + } + + // ctrl+click overrides the zeroing of existing data + if ( action === 'clear' ) setuptools.app.muledump.whitebag.init(guid, true); + if ( action === 'reset' ) setuptools.app.muledump.whitebag.init(guid, true, true); + var config = $.extend(true, {}, setuptools.data.muledump.whitebagTracker.accounts[guid]); + + wbitems.filter(function(itemid) { + itemid = Number(itemid); + var newvalue = (config.items[itemid] || 0); + if ( mules[guid].totals instanceof Muledump_TotalsCounter ) newvalue += (mules[guid].totals.data.totals[itemid] || 0); + setuptools.data.muledump.whitebagTracker.accounts[guid].items[itemid] = (setuptools.data.muledump.whitebagTracker.accounts[guid].items[itemid] || 0)+newvalue; + }); + + setuptools.app.config.save('Whitebags/Totals saving after import'); + setuptools.app.muledump.whitebag.tracker(guid); + + }); + + } + + }); + + // handle the export button + $('div.muledump.link.export').on('click.wb.export', function(e) { + + // build our base object + var action = $('select[name="wbexport"]').val().toLowerCase(); + var owned = {}; + config.owned.filter(function(itemid) { + owned[itemid] = 1; + }); + + // insert goback button to exporter page + setuptools.lightbox.insert('exporter-main', 'goback', ['exporter-main', function() { + setuptools.app.muledump.whitebag.tracker(guid); + }]); + + // close lightbox and proceed to exporter + setuptools.lightbox.close(); + setuptools.app.muledump.exporter.ui.main(undefined, action, { + items: 11, + totals: config.items, + sortorder: wbitems, + filter: owned, + fillStyle: '#88a09b', + strokeStyle: '#dcf7fe', + minTotal: -1, + fillNumbers: ( setuptools.data.config.wbTotals === true ) + }); + + }); }; @@ -3730,13 +2078,15 @@ setuptools.app.muledump.exporter.imgur = function(canvas, callback) { /** * @function * @param {string} type + * @param {object} [override] * @returns {string} * Generate the Totals text export data */ -setuptools.app.muledump.exporter.text = function(type) { +setuptools.app.muledump.exporter.text = function(type, override) { - var ids = window.ids; - var totals = window.totals; + if ( typeof override !== 'object' ) override = {}; + var totals = override.totals || window.totals; + var ids = override.sortorder || window.ids; var items = window.items; var e = {txt: [], csv: [], json: {}}; if ( !e[type] ) return 'Invalid text export type requested'; @@ -3806,9 +2156,10 @@ setuptools.app.muledump.exporter.saveLink = function(string, type) { * @function * @param [canvas] * @param {string} [type] + * @param {object} [override] * Displays the Muledump Exporter UI */ -setuptools.app.muledump.exporter.ui.main = function(canvas, type) { +setuptools.app.muledump.exporter.ui.main = function(canvas, type, override) { if ( typeof type === 'undefined' && typeof canvas === 'undefined' ) { @@ -3846,7 +2197,12 @@ setuptools.app.muledump.exporter.ui.main = function(canvas, type) { if ( canvas.match(/^https?:\/\/.*$/) ) { $('div.canvas.exporter').html(''); - } else $('div.canvas.exporter').html(''); + } else if ( canvas.match(/^data:image\/.*$/) ) { + $('div.canvas.exporter').html(''); + } else { + $('div.exporter.status').html('
No totals information available'); + $('div.canvas.exporter').html(''); + } } @@ -3859,8 +2215,8 @@ setuptools.app.muledump.exporter.ui.main = function(canvas, type) { setuptools.lightbox.build('exporter-main', '\
\ -
Totals Export
\ -
\ +
Totals Export
\ +
\ \
\ \ - \ + \ \
\
\ @@ -3903,20 +2259,20 @@ setuptools.app.muledump.exporter.ui.main = function(canvas, type) { if ( type === 'image' ) { $('div.exporter.canvas').html(' 
Loading image...'); - render_totals(render); + render_totals(render, override); } else { // produce the text export - var text = setuptools.app.muledump.exporter.text(type); + var text = setuptools.app.muledump.exporter.text(type, override); //setuptools.app.ga('send', 'event', { // eventCategory: 'detect', // eventAction: 'export-' + type //}); $('div.exporter.status').html(''); - $('div.exporter.canvas').html(''); + $('div.exporter.canvas').html(''); } @@ -3950,12 +2306,18 @@ setuptools.app.muledump.exporter.ui.main = function(canvas, type) { var image = $('div.canvas.content img'); if ( image.length === 0 || (image.length === 1 && image.attr('src').match(/^https?:\/\/.*/) !== null) ) { - $('div.exporter.status').html('
Uploading to Imgur...
 
'); + if ( image.length === 0 ) $('div.exporter.status').html('
Uploading to Imgur...
 '); + if ( image.length > 0 ) $('div.exporter.status').html('
Uploading to Imgur...
 '); render_totals(function (canvas) { - setuptools.app.muledump.exporter.imgur(canvas, imgur); + if ( canvas.match(/^data:image\/.*$/) ) { + setuptools.app.muledump.exporter.imgur(canvas, imgur); + } else { + $('div.exporter.status').html('
No totals information available'); + $('div.canvas.exporter').html(''); + } - }); + }, override); } else if ( image.length === 1 ) { @@ -3969,7 +2331,7 @@ setuptools.app.muledump.exporter.ui.main = function(canvas, type) { else { $('div.exporter.status').html('
Uploading to Paste...
 '); - var text = setuptools.app.muledump.exporter.text(type); + var text = setuptools.app.muledump.exporter.text(type, override); setuptools.app.muledump.exporter.paste(type, text, function(data, err, errDesc) { if ( err !== 'success' || data.data.error === true ) { @@ -3999,7 +2361,7 @@ setuptools.app.muledump.exporter.ui.main = function(canvas, type) { }); - $('div.exporter.canvas').html(''); + $('div.exporter.canvas').html(''); } @@ -4113,833 +2475,640 @@ setuptools.app.muledump.exporter.ui.menu = function(track) { /** * @function - * @param {string} guid - * @param {number} charid - * Records the date a character id is first seen + * @param {object} c + * @param {jQuery} [$c] + * @returns {void | jQuery} + * Return or render the character portrait and description */ -setuptools.app.muledump.charSeen = function(guid, charid) { - - charid = Number(charid); - if ( typeof setuptools.data.muledump.charsSeen[guid] !== 'object' ) setuptools.data.muledump.charsSeen[guid] = {}; - if ( typeof setuptools.data.muledump.charsSeen[guid][charid] === 'undefined' ) { - setuptools.data.muledump.charsSeen[guid][charid] = Date.now(); - setuptools.app.config.save('Recording character seen', true); - } - -}; +setuptools.app.muledump.drawPortrait = function(c, $c) { -/** - * @function - * @param {string} guid - * @param {string | boolean} [list] - * @returns {void | string} - * Returns active charlist for a guid if no list is provided, or sets new active charlist if valid - */ -setuptools.app.muledump.charsort.active = function(guid, list) { + var cl = classes[c.ObjectType]; - if ( !(mules[guid] instanceof Mule) ) return; - var CustomList = setuptools.data.muledump.chsortcustom.accounts[guid]; - if ( typeof CustomList !== 'object' ) return; - - // return the active list if none is provided - if ( list === false ) { - options_set('chsort', null, guid); - mules[guid].query(false, true); - return ''; - } else if ( list === true ) { - options_set('chsort', '100', guid); - mules[guid].query(false, true); - return CustomList.active; - } + if ( $c instanceof jQuery ) { - if ( typeof list !== 'string' ) return CustomList.active; - if ( list === '' ) { - CustomList.active = ''; - options_set('chsort', null, guid); - setuptools.app.config.save('Muledump/Charsort changed active', true); - mules[guid].query(false, true); - return ''; - } + // look for ld/lt/xp boost + var boost = $(''); + var boosts = [c.XpBoosted, c.XpTimer, c.LDTimer, c.LTTimer]; + var boostHtml = ''; + for ( var x = 0; x < boosts.length; x++ ) { + if ( boosts[x] !== "0" ) { - if ( - typeof CustomList === 'object' && - typeof CustomList.data === 'object' && - Array.isArray(CustomList.data[list]) - ) { + boost.removeClass('hidden'); + var length = ''; - CustomList.active = list; - options_set('chsort', '100', guid); - setuptools.app.config.save('Muledump/Charsort changed active', true); - mules[guid].query(false, true); - return list; + if ( c.XpBoosted !== "0" ) { - } + length = Math.floor(Number(c.XpTimer)/60) + ' minutes'; + if ( c.XpTimer === "0" ) length = "Until Level 20"; + boostHtml += '
XpBooster
' + length + '
'; - if ( typeof CustomList === 'object' && CustomList.active ) return CustomList.active; + } -}; + if ( c.LDTimer !== "0" ) { -/** - * @function - * @param {string} guid - * @param {string | boolean} [list] - * @param {boolean} [clist] - * @returns {*} - * Reads a character sorting list (or active) for provided guid - */ -setuptools.app.muledump.charsort.read = function(guid, list, clist) { + length = Math.floor(Number(c.LDTimer)/60); + boostHtml += '
Loot Drop
' + length + ' minutes
'; - if ( typeof list === 'boolean' ) { - clist = list; - list = undefined; - } + } - if ( !(mules[guid] instanceof Mule) || !Array.isArray(mules[guid].data.query.results.Chars.Char) ) return; - var d = mules[guid].data.query.results.Chars; - var CharList = []; - var CustomList = setuptools.data.muledump.chsortcustom.accounts[guid]; - if ( - typeof CustomList === 'object' && - typeof CustomList.data === 'object' && - Array.isArray(CustomList.data[(list || CustomList.active)]) - ) { + if ( c.LTTimer !== "0" ) { - if ( typeof list !== 'string' ) list = CustomList.active; - if ( typeof CustomList.data[list] === 'undefined' ) return; - for (var i in d.Char) { + length = Math.floor(Number(c.LTTimer)/60); + boostHtml += '
Loot Tier
' + length + ' minutes
'; - if (d.Char.hasOwnProperty(i)) { + } - var index = CustomList.data[list].indexOf(d.Char[i].id); - if (index > -1) CharList[index] = ( clist === true ) ? d.Char[i] : d.Char[i].id; + break; } } - // make sure no missing entries were found (i.e. dead characters) - for (var i2 = 0; i2 < CharList.length; i2++) - if (typeof CharList[i2] === 'undefined') - CustomList.data[list].splice(i2, 1); - - } - - if ( CharList.length > 0 ) setuptools.app.ga('send', 'event', { - eventCategory: 'detect', - eventAction: 'charSortCustom' - }); - - return CharList; - -}; - -/** - * @function - * @param {string} guid - * @param {string} charlist - * @param {array} CharList - * @returns {boolean} - * Sets a charlist with new data - */ -setuptools.app.muledump.charsort.set = function(guid, charlist, CharList) { - - if ( !Array.isArray(CharList) ) return false; - setuptools.app.muledump.charsort.unsaved = true; - setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist] = CharList; - return true; - -}; - -/** - * @function - * @param {function} [callback] - * @returns {void | boolean} - * Saves the configuration if any list changes were made - */ -setuptools.app.muledump.charsort.save = function(callback) { - - if ( setuptools.app.muledump.charsort.unsaved !== true ) return; - delete setuptools.app.muledump.charsort.unsaved; - setuptools.app.config.save('Muledump/Charsort saving changes'); - if ( typeof callback === 'function' ) callback(); - return true; - -}; - -/** - * @function - * @param {string} guid - * @param {string} charlist - * @returns {boolean} - * Creates an empty charlist - */ -setuptools.app.muledump.charsort.create = function(guid, charlist) { - - if ( typeof setuptools.data.muledump.chsortcustom.accounts[guid] === 'undefined' ) setuptools.data.muledump.chsortcustom.accounts[guid] = $.extend(true, {}, setuptools.objects.charlist); - if ( typeof setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist] === 'undefined' ) { - setuptools.data.muledump.chsortcustom.accounts[guid].active = charlist; - setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist] = []; } - return true; - -}; - -/** - * @function - * @param {string} guid - * @param {string} charlist - * @returns {boolean} - * Deletes the specified charlist - */ -setuptools.app.muledump.charsort.delete = function(guid, charlist) { - - if ( - typeof setuptools.data.muledump.chsortcustom.accounts[guid] === 'undefined' || - typeof setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist] === 'undefined' - ) return false; - delete setuptools.data.muledump.chsortcustom.accounts[guid].data[charlist]; - if ( setuptools.data.muledump.chsortcustom.accounts[guid].active === charlist ) setuptools.app.muledump.charsort.active(guid, false); - return true; - -}; - -/** - * @function - * @param {string} guid - * @param {string} charlist - * @param {string} charid - * @param {number} [position] - * @returns {void | boolean} - * Adds a charid to a list - */ -setuptools.app.muledump.charsort.add = function(guid, charlist, charid, position) { - - var CharList = setuptools.app.muledump.charsort.read(guid, charlist); - if ( !Array.isArray(CharList) ) return; - if ( CharList.indexOf(charid) > -1 ) return false; - if ( !position || position >= CharList.length ) { - CharList.push(charid); - } else CharList.splice(position, 0, charid); - setuptools.app.muledump.charsort.set(guid, charlist, CharList); - return true; - -}; - -/** - * @function - * @param {string} guid - * @param {string} charlist - * @param {string} charid - * @returns {void | boolean} - * Removes a charid from a list - */ -setuptools.app.muledump.charsort.remove = function(guid, charlist, charid) { - - var CharList = setuptools.app.muledump.charsort.read(guid, charlist); - if ( !Array.isArray(CharList) ) return; - if ( CharList.indexOf(charid) === -1 ) return false; - CharList.splice(CharList.indexOf(charid), 1); - setuptools.app.muledump.charsort.set(guid, charlist, CharList); - return true; - -}; - -/** - * @function - * @param {*} [guids] - * Clean up character sorting lists for the provided guids - */ -setuptools.app.muledump.charsort.clean = function(guids) { - if ( typeof guids === 'undefined' ) guids = Object.keys(setuptools.data.muledump.chsortcustom.accounts); - if ( typeof guids === 'string' ) guids = [guids]; - if ( !Array.isArray(guids) ) return; - - setuptools.app.techlog('Muledump/Charsort cleanup is running'); - - // loop thru each provided guid - for ( var id = 0; id < guids.length; id++ ) { + var portimg = $(''); + window.portrait(portimg, c.ObjectType, c.Texture, c.Tex1, c.Tex2); + var chtext = $('
'); + if ( typeof boost !== 'undefined' ) chtext.append(boost); + chtext.append($('
').text(cl[0] + ' ' + c.Level + ", " + c.muledump.MaxedStats + "/8" + ', #' + c.id)) + .append($('
').text(c.CurrentFame + ' F ' + c.Exp + ' XP')); - // a bit of sanity here - var guid = guids[id]; - var CustomList = setuptools.data.muledump.chsortcustom.accounts[guid]; - if ( - typeof CustomList === 'object' && - typeof CustomList.data === 'object' - ) { + var chdesc = $('
') + .append(portimg) + .append(chtext); - var saveReq = []; - var d = mules[guid].data.query.results.Chars; + if ( typeof $c === 'undefined' ) return chdesc; - // loop thru each list for this account - for ( var list in CustomList.data ) { + // add it to the dom + chdesc.appendTo($c); - if ( CustomList.data.hasOwnProperty(list) ) { + // bind lt/ld/xp boost tooltip + if ( boost && boost.hasClass('hidden') === false ) { - // loop thru all characters for this account and check match their ids to list members - var length = CustomList.data[list].length; - CustomList.data[list] = CustomList.data[list].filter(function(charid) { - return (d.Char.filter(function(char) { - return ( char.id === charid ); - }).length > 0); - }); + boost.on('mouseenter.muledump.boostTooltip', [boost, boostHtml], function (e) { + setuptools.lightbox.tooltip( + e.data[0].parent().parent(), + e.data[1], + { + classes: 'tooltip-boost', + heightFrom: 'tooltip' + } + ); + }); - if ( CustomList.data[list].length < length ) saveReq.push([list, length-CustomList.data[list].length]); + boost.on('mouseleave.muledump.boostTooltip', function() { + $('.tooltip').remove(); + }); - } + } - } + // provide dye/texture data for portrait + /*portimg.on('mouseover.muledump.portrait.tooltip', function() { + $('.tooltip').remove(); - // if any lists were found with bad data we'll save the changes - if (saveReq.length > 0) setuptools.app.config.save('CharSort/Cleanup updated these lists: ' + saveReq); + var tex1 = $(this).attr('data-tex1'); + var tex1 = $(this).attr('data-tex2'); + setuptools.lightbox.tooltip($(this).parent(), ' \ + Textile One\ +
Textile Two\ + ', { + heightFrom: 'tooltip', + classes: 'tooltip-textiles' + }); + }).on('mouseleave.muledump.portrait.tooltip', function() { + $('.tooltip').remove(); + }); + */ - } +}; - } +/* +// Account Valuation +*/ +setuptools.app.muledump.value = { + items: {} }; /** * @function - * @param a - * @param b - * @returns {number} - * For use with CharList.sort() + * @param {number | string} itemid + * @param {boolean} [raw] + * @returns {number | object} + * Calculates the value of an item */ -setuptools.app.muledump.charsort.sort = function(a, b) { +setuptools.app.muledump.value.item = function(itemid, raw) { - // by id - if (setuptools.data.muledump.chsortcustom.sort === 0) return a.id - b.id; + itemid = +itemid; + if ( !items[itemid] || itemid === -1 ) return 0; + if ( raw !== true && setuptools.app.muledump.value.items[itemid] ) return setuptools.app.muledump.value.items[itemid]; - // by fame - if (setuptools.data.muledump.chsortcustom.sort === 1) return b.CurrentFame - a.CurrentFame; - - // by total fame - if (setuptools.data.muledump.chsortcustom.sort === 2) return b.muledump.TotalFame - a.muledump.TotalFame; - - // by class, then fame - if (setuptools.data.muledump.chsortcustom.sort === 3) { + var rel = setuptools.data.muledump.value.rel.item; + var whites = setuptools.app.muledump.whitebag.items(); + var vst = items[itemid][setuptools.config.vstIndex]; + var value = { + vst: ( (rel.vst[vst]) ? rel.vst[vst] : rel.vst.default ), + tier: ( (items[itemid][2] > -1 ) ? (items[itemid][2]*((typeof rel.tier === 'number') ? rel.tier : 1)) : 0 ), + fb: items[itemid][5]*((typeof rel.fb === 'number') ? rel.fb : 1), + fp: items[itemid][6]*((typeof rel.fp === 'number') ? rel.fp : 1), + white: ( ( whites.indexOf(itemid.toString()) > -1 ) ? (rel.white || 100) : 0 ), + total: 0 + }; - if (a.muledump.ClassName < b.muledump.ClassName) return -1; - if (a.muledump.ClassName > b.muledump.ClassName) return 1; - if (a.muledump.ClassName === b.muledump.ClassName) { - return b.CurrentFame - a.CurrentFame; - } - return 0; + Object.filter(value, function(key, element) { + if ( key === 'total' ) return; + value.total += element; + }); - } + setuptools.app.muledump.value.items[itemid] = value.total; + return ( raw === true ) ? value.total : value; }; /** * @function * @param {string} guid - * @param {array} CharList - * @param {object} chars - * @returns {object} - * Sort thru and add disabled chars to the CharList if enabled + * @param {string} charid + * @param {boolean} [raw] + * @returns {number | object | void} + * Calculates the value of a character */ -setuptools.app.muledump.charsort.disabled = function(guid, CharList, chars) { - - if ( !(mules[guid] instanceof Mule) || !Array.isArray(mules[guid].data.query.results.Chars.Char) ) return chars; - if ( setuptools.data.muledump.chsortcustom.disabledmode === true ) { +setuptools.app.muledump.value.char = function(guid, charid, raw) { - var unusedChars = []; - mules[guid].data.query.results.Chars.Char.filter(function (element) { - if (CharList.indexOf(element.id) === -1) unusedChars.push(element); - }); + if ( !mules[guid] ) return 0; + var d = mules[guid].data.query.results.Chars; + var chars; + if ( !Array.isArray(d.Char) ) { + chars = [d.Char]; + } else chars = $.extend(true, [], d.Char); + + var char = Object.filter(chars, function(key, element) { + if ( +element.id === +charid ) return true; + }); + + if ( typeof char !== 'object' || Object.keys(char).length !== 1 ) return 0; + + var rel = setuptools.data.muledump.value.rel.char; + char = char[Object.keys(char)[0]]; + var value = { + level: +char.Level*((typeof rel.level === 'number') ? rel.level : 1), + bp: ( ( +char.HasBackpack === 1 ) ? ((typeof rel.bp === 'number') ? rel.bp : 0) : 0 ), + totalfame: char.muledump.TotalFame*((typeof rel.totalFame === 'number') ? rel.totalFame : 1), + stats: char.muledump.MaxedStats*((typeof rel.stats === 'number') ? rel.stats : 1), + inv: 0, + equip: 0, + total: 0 + }; - // sort that list - unusedChars.sort(setuptools.app.muledump.charsort.sort); + /*var charitems = char.Equipment.split(',').filter(function(itemid, index) { + if ( index < 4 ) { + value.inv += setuptools.app.muledump.value.item(+itemid, true)*((typeof rel.inv === 'number') ? rel.inv : 1) + } else value.equip += (setuptools.app.muledump.value.item(+itemid, true)*((typeof rel.equip === 'number') ? rel.equip : 1)) + });*/ - // join both lists - chars = chars.concat(unusedChars); + Object.filter(value, function(key, element) { + if ( key === 'total' ) return; + value[key] = Number(element.toFixed(0)); + value.total += element; + }); - } - return chars; + value.total = Number(value.total.toFixed(0)); + return ( raw === true ) ? value.total : value; }; /** * @function * @param {string} guid - * @param {string} charlist - * Display the Char Sorting menu + * @param {boolean} [raw] + * Calculates the value of an account */ -setuptools.app.muledump.charsort.menu = function(guid, charlist) { - - setuptools.lightbox.close('muledump-charsort'); - var variant = 'fl-Chsort'; - var lists; - var title = 'Custom Character Sorting'; - var goback = false; +setuptools.app.muledump.value.mule = function(guid, raw) { - // multi-character accounts have an array here - if ( - typeof mules[guid] === 'object' && - typeof mules[guid].data === 'object' && - Array.isArray(mules[guid].data.query.results.Chars.Char) - ) { - - // select/create/manage lists - if ( typeof charlist === 'undefined' ) { - - variant = ''; - function toggleButtonDraw() { - - var toggleButtonText = 'Turn on Custom Character Sorting'; - var toggleButtonClasses = ('muledump link toggleEnabled menuStyle textCenter mr0').split(' '); - if ( mules[guid].opt('chsort') === '100' ) { - toggleButtonClasses.push('negative'); - toggleButtonText = 'Turn off Custom Character Sorting'; - } else { - toggleButtonClasses.push('positive'); - } - - return '
' + toggleButtonText + '
'; - - } - - var content = $('
'); - setuptools.lightbox.build('muledump-charsort', ' \ - Welcome to the Character Sorting menu! \ -

From here you can create, select, edit, and delete custom character sorting lists. \ -
 \ -
\ - ' + toggleButtonDraw() + '\ -
\ -
\ - \ -
\ - \ -
\ - \ - \ -
\ - ' + ( - // determine button state - ( - mules[guid].opt('chsort') !== '100' || - ( - mules[guid].opt('chsort') === '100' && - setuptools.app.muledump.charsort.active(guid) === '' - ) - ) ? - '' : - '' - ) + '\ - \ - \ -
\ -
\ - '); + value.total = Number(value.total.toFixed(0)); + return ( raw === true ) ? value.total : value; - } - // character sorting gui - else { +}; - goback = true; - var list = setuptools.app.muledump.charsort.read(guid, charlist); - var chars = []; +setuptools.app.muledump.value.generateCache = function(key, force) { - // build our list of enabled characters - mules[guid].data.query.results.Chars.Char.filter(function(element) { - if ( list.indexOf(element.id) > -1 ) chars.push(element); - }); + var cache = { + skins: {}, + skinitems: Object.filter(items, function(itemid, item) { + //if ( item[0].match(/^.* Skin$/) !== null ) cache.skinitems[itemid] = + }) + }; - // sort that list - chars.sort(function(a, b) { - if ( list.indexOf(a.id) > -1 && list.indexOf(b.id) > -1 ) return list.indexOf(a.id) - list.indexOf(b.id); - return Number(b.id) - Number(a.id); - }); + // build skins cache data + Object.filter(skins, function(skinid, skin) { - // build out list of disabled chars - var unusedChars = []; - mules[guid].data.query.results.Chars.Char.filter(function (element) { - if (list.indexOf(element.id) === -1) unusedChars.push(element); - }); + cache.skins[skinid] = { + name: skin[0], + item: Object.filter(items, function(itemid, item) { + var pattern = new RegExp('^' + skin[0] + ' Skin$'); + if ( !( item[0].match(pattern) === null ) ) return true; - // sort that list - unusedChars.sort(setuptools.app.muledump.charsort.sort); + pattern = new RegExp('^' + skin[0].replace(/\sStatue/, '') + ' Skin$'); + if ( !( item[0].match(pattern) === null ) ) return true; - // join both lists - chars = chars.concat(unusedChars); - chars = setuptools.app.muledump.charsort.disabled(guid, list, chars); + return false; - var portraits = {}; - var portraitHtml = ''; - for ( var cid in chars ) { + }) + }; - if ( chars.hasOwnProperty(cid) ) { + cache.skins[skinid].item = cache.skins[skinid].item[Object.keys(cache.skins[skinid].item)[0]]; - portraits[chars[cid].id] = setuptools.app.muledump.drawPortrait(chars[cid]); - portraitHtml += '
' + portraits[chars[cid].id].html() + '
'; + }); - } +}; - } +/** + * @function + * @param {string} guid + * @param {number | string} [tex1] + * @param {number | string} [tex2] + */ +// display owned skins +setuptools.app.muledump.ownedSkins = function(guid, tex1, tex2) { - setuptools.lightbox.build('muledump-charsort', ' \ -
' + portraitHtml + '
\ -
⚪⚪⚪
\ -
\ -
    \ -
  1. Shift+Click characters to enable or disable them
  2. \ -
  3. Click and drag enabled characters to sort them
  4. \ -
  5. Changes save automatically when you close the UI
  6. \ -
\ -
\ -
Disabled Characters Sort Mode
\ - \ -
 
Disabled Characters Display Mode
\ - \ -
\ -
\ - '); + if ( !(mules[guid] instanceof Mule) ) return; - } + setuptools.lightbox.close('wardrobe-index'); + + // sort out texture data + if ( tex1 ) tex1 = Number(tex1); + if ( tex2 ) tex2 = Number(tex2); + if ( typeof tex1 !== 'number' || !textures[tex1] ) tex1 = ( + typeof setuptools.data.muledump.wardrobe.accounts[guid] === 'object' && + typeof setuptools.data.muledump.wardrobe.accounts[guid].clothes.large === 'number' && + textures[setuptools.data.muledump.wardrobe.accounts[guid].clothes.large] + ) ? setuptools.data.muledump.wardrobe.accounts[guid].clothes.large : undefined; + if ( typeof tex2 !== 'number' || !textures[tex2] ) tex2 = ( + typeof setuptools.data.muledump.wardrobe.accounts[guid] === 'object' && + typeof setuptools.data.muledump.wardrobe.accounts[guid].clothes.small === 'number' && + textures[setuptools.data.muledump.wardrobe.accounts[guid].clothes.small] + ) ? setuptools.data.muledump.wardrobe.accounts[guid].clothes.small : undefined; + var large; + var small; + if ( tex1 ) large = items[textures[tex1][1]]; + if ( tex2 ) small = items[textures[tex2][3]]; + if ( !large ) large = items[5073]; + if ( !small ) small = items[5074]; + + // obtain the base list of owned skins + var ownedSkins = $.extend(true, [], mules[guid].data.query.results.Chars.OwnedSkins); + ownedSkins.filter(function(element, index) { + ownedSkins[index] = Number(element); + }); + + // add default skins to owned list + Object.keys(classes).filter(function(classid) { + ownedSkins.push(Number(classid)); + }); + + var count = { + total: 0, + owned: Object.keys(classes).length + }; + var cache = true; + + // build skinid map cache + if ( typeof setuptools.tmp.skins !== 'object' ) setuptools.tmp.skins = {}; + if ( typeof setuptools.tmp.skins[guid] !== 'object' ) { + + cache = false; + setuptools.tmp.skins[guid] = {}; + + // generate the base object + Object.filter(classes, function (classid, data) { + if ( !Array.isArray(setuptools.tmp.skins[guid][classid]) ) setuptools.tmp.skins[guid][classid] = { + total: 0, + owned: 0, + skins: [] + }; + }); - } - // single-character accounts have an object here - else if ( - typeof mules[guid] === 'object' && - typeof mules[guid].data === 'object' && - !Array.isArray(mules[guid].data.query.results.Chars.Char) - ) { + // populate skinids + Object.filter(skins, function(skinid, data) { - variant = ''; - setuptools.lightbox.build('muledump-charsort', ' \ - This feature can only be utilized by accounts with multiple characters.\ - '); + // build a classlist + var classlist = []; + Object.keys(classes).filter(function(classid) { + classlist.push(classes[classid][0]); + }); - } - // of course, if there's no guid they she be told that - else if ( typeof guid !== 'undefined' ) { + // check skin validity + if ( + [65535].indexOf(data[4]) > -1 || + data[0].match((new RegExp('^(?:.*? Set(?: Skin)?|Christmas (?:' + classlist.join('|') + '))$'))) !== null + ) return; - setuptools.lightbox.build('muledump-charsort', 'Invalid GUID specified: ' + guid); + // include skin + setuptools.tmp.skins[guid][data[4]].skins.push(Number(skinid)); - } else { + }); - setuptools.lightbox.build('muledump-charsort', 'Invalid request arguments'); + // sort each class + Object.filter(setuptools.tmp.skins[guid], function(classid, data) { + data.skins.sort(function(a,b) { + if ( classes[a] && !classes[b] ) return -1; + if ( skins[a][1] === skins[b][1] ) return a-b; + return skins[a][1] - skins[b][1]; + }) + }); } - setuptools.lightbox.settitle('muledump-charsort', title); - setuptools.lightbox.drawhelp('muledump-charsort', 'docs/setuptools/help/charsort.md', 'Character Sorting Help'); - if ( goback === true ) setuptools.lightbox.goback('muledump-charsort', function() { - setuptools.app.muledump.charsort.menu(guid); - }); - setuptools.lightbox.display('muledump-charsort', { - variant: variant, - afterClose: function() { - setuptools.app.muledump.charsort.save(function() { - mules[guid].query(false, true); - }); - } - }); - - // create new list and open it in the editor - $('div.muledump.link.createNew').on('click.charsort.createnew', function() { + // build html + var pieces = []; + Object.filter(setuptools.tmp.skins[guid], function(classid, data) { + + classid = Number(classid); + var classData = classes[classid]; + var html = ' \ +
\ +
\ +
' + classData[0] + '
\ +
[[' + classid + '_count]]
\ +
\ +
\ + '; - var name = $('input[name="charsortNewList"]').val(); - if ( typeof name !== 'string' || name.length < 1 ) return; - setuptools.app.muledump.charsort.create(guid, name); - setuptools.app.muledump.charsort.menu(guid, name); + var skinDom = $('
'); - }); + data.skins.filter(function(skinid) { - // create new list and open it in the editor - $('div.muledump.link.deleteList').on('click.charsort.deleteList', function() { + skinid = Number(skinid); + var $s = $(''); + window.portrait($s, classid, skinid, tex1, tex2, false); + if ( cache === false ) setuptools.tmp.skins[guid][classid].total++; + count.total++; + if ( ownedSkins.indexOf(skinid) > -1 ) { + if ( cache === false ) setuptools.tmp.skins[guid][classid].owned++; + count.owned++; + $s.addClass('enabled'); + } + skinDom.append($s); - var name = $('select[name="charsortList"]').val(); - if ( typeof name !== 'string' || name.length < 1 ) return; - setuptools.app.muledump.charsort.delete(guid, name); - setuptools.app.config.save('Muledump/Charsort deleted a list', true); - setuptools.app.muledump.charsort.menu(guid); + }); - }); + // insert skin count + html = html.replace('[[' + classid + '_count]]', setuptools.tmp.skins[guid][classid].owned + ' of ' + setuptools.tmp.skins[guid][classid].total + ' (' + ( ((setuptools.tmp.skins[guid][classid].owned/setuptools.tmp.skins[guid][classid].total)*100).toFixed(0) ) + '%)'); - // change character sorting mode for disabled chars - $('select[name="chsortmode"]').on('change.chsortmode', function() { + // insert skins html + html += ' \ + ' + skinDom.html() + '\ +
\ +
\ + '; - var value = Number($(this).val()); - if ( value > -1 && value <= 3 ) setuptools.data.muledump.chsortcustom.sort = value; - setuptools.app.muledump.charsort.unsaved = true; - if ( setuptools.data.muledump.chsortcustom.disabledmode === true ) setuptools.app.muledump.charsort.menu(guid, charlist); + pieces.push([classid, html]); }); - // change character disabled display mode for disabled chars - $('select[name="chsortdisabledmode"]').on('change.chsortdisabledmode', function() { - - setuptools.data.muledump.chsortcustom.disabledmode = ( $(this).val() === "1" ); - setuptools.app.muledump.charsort.unsaved = true; - setuptools.app.muledump.charsort.menu(guid, charlist); - + // sort pieces by class name + pieces.sort(function(a,b) { + if (classes[a[0]][0] < classes[b[0]][0]) return -1; + if (classes[a[0]][0] > classes[b[0]][0]) return 1; + return 0; }); - // toggle character enable/disable state - // did it this way so I can offer alternative bindings later on - function charsortCellToggle(e, force) { - - if ( !e.shiftKey && force !== true ) return; - var charid = $(this).attr('data-charid'); - if ( typeof charid !== 'string' ) return; - var state = !( $(this).hasClass('enabled') ); - if ( state === true ) { - - setuptools.app.muledump.charsort.add(guid, charlist, charid, $(this).index()); - $(this).addClass('enabled'); - - } else { - - setuptools.app.muledump.charsort.remove(guid, charlist, charid); - $(this).removeClass('enabled'); - - } - - } - - $('div.charsort.cell').on('click.charsort.toggleEnable', charsortCellToggle); + // build page header + setuptools.lightbox.build('wardrobe-index', ' \ +
\ +
    \ +
  • Wardrobe for ' + setuptools.app.muledump.getName(guid) + '
  • \ +
  • You possess ' + count.owned + ' of ' + count.total + ' skins (' + ( ((count.owned/count.total)*100).toFixed(0) ) + '%)
  • \ +
\ +
\ +
\ +
\ +
\ +
\ + \ +
\ + '); + // insert pieces html to page + pieces.filter(function(piece) { + setuptools.lightbox.build('wardrobe-index', ' \ + ' + piece[1] + '\ + '); }); - // toggle state of charsort option - $('div.muledump.link.toggleEnabled').on('click.toggle.state', function() { - - var state = ( $(this).hasClass('positive') ); - var list = $('select[name="charsortList"]').val(); - if ( typeof list !== 'string' || list.length < 1 ) return; - if ( state === true ) { - - $(this).removeClass('positive').addClass('negative').text('Turn off Custom Character Sorting'); - - if ( - setuptools.app.muledump.charsort.active(guid) === list - ) $('div.muledump.link.enableList').removeClass('positive').text('Disable'); - - setuptools.app.muledump.charsort.active(guid, true); + setuptools.lightbox.build('wardrobe-index', ' \ +
\ +
 \ +
Legend\ +
Ctrl+Shift+Click within class block to take screenshot of class skins\ +
Ctrl+Shift+Click between class block to take screenshot of all classes \ +
\ + '); - } else { + setuptools.lightbox.drawhelp('wardrobe-index', 'docs/muledump/wardrobe', 'Wardrobe Help'); + setuptools.lightbox.settitle('wardrobe-index', 'Skin Wardrobe'); + setuptools.lightbox.display('wardrobe-index', {variant: 'fl-Wardrobe'}); - $(this).removeClass('negative').addClass('positive').text('Turn on Custom Character Sorting'); - $('div.muledump.link.enableList').addClass('positive').text('Enable'); - setuptools.app.muledump.charsort.active(guid, false); + // insert images to class links + Object.keys(classes).filter(function(classid) { - } + var $s = $('img[data-classid="' + classid.toString() + '"]'); + window.portrait($s, classid, classid, tex1, tex2, false); + setuptools.app.muledump.tooltip($s, 'ownedSkinsTooltip skinmenu', '
' + classes[classid][0] + '
', 100); }); - // bind character sorting list selection menu - $('select[name="charsortList"]').on('change.charsortList', function() { + // bind tooltips to skins + $('img.ownedSkins:not(.skinmenu)').each(function() { - var list = $(this).val(); - if ( typeof list !== 'string' || list.length < 1 ) return; - if ( - options_get('chsort', guid) === '100' && - setuptools.app.muledump.charsort.active(guid) === list - ) { - $('div.muledump.link.enableList').removeClass('positive').text('Disable'); - } else $('div.muledump.link.enableList').addClass('positive').text('Enable'); + var skinid = Number($(this).attr('data-skinid')); + setuptools.app.muledump.tooltip($(this), 'ownedSkinsTooltip', '
' + skins[skinid][0] + '
'); }); - // toggle state of lists - $('div.muledump.link.enableList').on('click.toggle.list', function() { - - var list = $('select[name="charsortList"]').val(); - var state = ( $(this).hasClass('positive') ); - if ( typeof list !== 'string' || list.length < 1 ) return; + // bind cloth selection tool + $('div.cloth.item').on('click.wardrobe.clothes', function(e) { - if ( state === true ) { - $(this).removeClass('positive').text('Disable'); - $('div.muledump.link.enableList').removeClass('positive').text('Disable'); - setuptools.app.muledump.charsort.active(guid, list); - } else { - $(this).addClass('positive').text('Enable'); - setuptools.app.muledump.charsort.active(guid, ''); - } + setuptools.tmp.ownedSkinRefresh = false; - }); + // is the size large or small (true or false) + var clothindex = ( $(this).hasClass('large') ) ? 1 : 3; + var clothkey = ( clothindex === 1 ) ? 'large' : 'small'; -}; + // sort through the textures object + Object.keys(textures).filter(function(tex) { -/** - * @function - * @param {object} c - * @param {jQuery} [$c] - * @returns {void | jQuery} - * Return or render the character portrait and description - */ -setuptools.app.muledump.drawPortrait = function(c, $c) { + tex = Number(tex); + if ( tex === 0xffffffff ) return; + var texture = textures[tex]; + var cloth = items[texture[clothindex]]; + var enabled = ''; + if ( + typeof setuptools.data.muledump.wardrobe.accounts[guid] === 'object' && + setuptools.data.muledump.wardrobe.accounts[guid].clothes[clothkey] === tex + ) enabled = 'enabled'; - var cl = classes[c.ObjectType]; + setuptools.lightbox.build('wardrobe-clothes', ' \ +
\ + '); - if ( $c instanceof jQuery ) { + }); - // look for ld/lt/xp boost - var boost = $(''); - var boosts = [c.XpBoosted, c.XpTimer, c.LDTimer, c.LTTimer]; - var boostHtml = ''; - for ( var x = 0; x < boosts.length; x++ ) { - if ( boosts[x] !== "0" ) { + setuptools.lightbox.drawhelp('wardrobe-clothes', 'docs/muledump/wardrobe', 'Wardrobe Help'); + setuptools.lightbox.settitle('wardrobe-clothes', false); + setuptools.lightbox.display('wardrobe-clothes', { + variant: 'fl-Wardrobe short nobackground', + afterClose: function() { - boost.removeClass('hidden'); - var length = ''; + if ( setuptools.tmp.ownedSkinRefresh === true ) { + setuptools.app.config.save('SkinWardrobe/Clothes adjustment'); + setuptools.app.muledump.ownedSkins(guid); + } - if ( c.XpBoosted !== "0" ) { + } + }); - length = Math.floor(Number(c.XpTimer)/60) + ' minutes'; - if ( c.XpTimer === "0" ) length = "Until Level 20"; - boostHtml += '
XpBooster
' + length + '
'; + // bind selector + $('div.cloth.selector.item') + .each(function() { - } + var tex = $(this).attr('data-tex'); + tex = Number(tex); + if ( tex === 0xffffffff || typeof tex !== 'number' ) return; + var texture = textures[tex]; + setuptools.app.muledump.tooltip($(this), 'mb5 autoHeight highz ol1', '
' + texture[clothindex-1] + '
'); - if ( c.LDTimer !== "0" ) { + }) + .on('click.wardrobe.clothselector', function(e) { - length = Math.floor(Number(c.LDTimer)/60); - boostHtml += '
Loot Drop
' + length + ' minutes
'; + var tex = Number($(this).attr('data-tex')); + if ( typeof tex !== 'number' ) return; - } + // make the object for the first time + if ( typeof setuptools.data.muledump.wardrobe.accounts[guid] === 'undefined' ) setuptools.data.muledump.wardrobe.accounts[guid] = $.extend(true, {}, setuptools.objects.wardrobeConfig); - if ( c.LTTimer !== "0" ) { + // update object to new format + setuptools.data.muledump.wardrobe.accounts[guid] = $.extend(true, setuptools.objects.wardrobeConfig, setuptools.data.muledump.wardrobe.accounts[guid]); - length = Math.floor(Number(c.LTTimer)/60); - boostHtml += '
Loot Tier
' + length + ' minutes
'; + // trigger the refresh on close + setuptools.tmp.ownedSkinRefresh = true; - } + // deselect this + if ( $(this).hasClass('enabled') ) { - break; + // update the clothes array + delete setuptools.data.muledump.wardrobe.accounts[guid].clothes[clothkey]; + $(this).removeClass('enabled'); } + // select this + else { - } - - } - - var portimg = $(''); - window.portrait(portimg, c.ObjectType, c.Texture, c.Tex1, c.Tex2); - var chtext = $('
'); - if ( typeof boost !== 'undefined' ) chtext.append(boost); - chtext.append($('
').text(cl[0] + ' ' + c.Level + ", " + c.muledump.MaxedStats + "/8" + ', #' + c.id)) - .append($('
').text(c.CurrentFame + ' F ' + c.Exp + ' XP')); + // update the clothes array + setuptools.data.muledump.wardrobe.accounts[guid].clothes[clothkey] = tex; + $(this).siblings().removeClass('enabled'); + $(this).addClass('enabled'); - var chdesc = $('
') - .append(portimg) - .append(chtext); + } - if ( typeof $c === 'undefined' ) return chdesc; + }); - // add it to the dom - chdesc.appendTo($c); + }); - // bind lt/ld/xp boost tooltip - if ( boost && boost.hasClass('hidden') === false ) { + // bind screenshot hotkeys + $('div.ownedSkins:not(.skinmenu)').on('click.skins.block', function(e) { - boost.on('mouseenter.muledump.boostTooltip', [boost, boostHtml], function (e) { - setuptools.lightbox.tooltip( - e.data[0].parent().parent(), - e.data[1], - { - classes: 'tooltip-boost', - heightFrom: 'tooltip' - } - ); - }); + if ( setuptools.app.muledump.keys(['ctrl','shift'], e) === false ) return; + setuptools.app.muledump.exporter.canvas(this); - boost.on('mouseleave.muledump.boostTooltip', function() { - $('.tooltip').remove(); - }); + }); - } + $('div.skinstage').on('click.skins.stage', function(e) { - // provide dye/texture data for portrait - /*portimg.on('mouseover.muledump.portrait.tooltip', function() { - $('.tooltip').remove(); + if ( setuptools.app.muledump.keys(['ctrl','shift'], e) === false ) return; + setuptools.app.muledump.exporter.canvas(this); - var tex1 = $(this).attr('data-tex1'); - var tex1 = $(this).attr('data-tex2'); - setuptools.lightbox.tooltip($(this).parent(), ' \ - Textile One\ -
Textile Two\ - ', { - heightFrom: 'tooltip', - classes: 'tooltip-textiles' - }); - }).on('mouseleave.muledump.portrait.tooltip', function() { - $('.tooltip').remove(); }); - */ }; diff --git a/lib/setuptools/src/mulequeue.js b/lib/setuptools/src/mulequeue.js index 613129a1..d2c967df 100644 --- a/lib/setuptools/src/mulequeue.js +++ b/lib/setuptools/src/mulequeue.js @@ -600,7 +600,7 @@ setuptools.app.mulequeue.task.start = function(guid, callback) { ign: ( ( setuptools.state.loaded === true && setuptools.app.config.determineFormat(setuptools.data.accounts) === 1 - ) ? setuptools.data.accounts.accounts[response.guid].ign : undefined ), + ) ? (setuptools.data.accounts.accounts[response.guid] && setuptools.data.accounts.accounts[response.guid].ign) : undefined ), status: response.status, errorMessage: response.errorMessage || undefined, runtime: (task.runTime / 1000).toFixed(2), diff --git a/lib/setuptools/src/setuptools.js b/lib/setuptools/src/setuptools.js index 9e4e90d6..fac5dbe4 100644 --- a/lib/setuptools/src/setuptools.js +++ b/lib/setuptools/src/setuptools.js @@ -7,7 +7,7 @@ var setuptools = { version: { major: 9, - minor: 4, + minor: 5, patch: 0 }, state: { @@ -55,11 +55,15 @@ var setuptools = { }, whitebagTrackerAccount: { items: {}, - totals: [] + owned: [] }, charlist: { active: '', data: {} + }, + wardrobeConfig: { + format: 1, + clothes: {} } }, tmp: {}, @@ -81,6 +85,7 @@ var setuptools = { active: {}, builds: {}, overrides: {}, + inserts: [], menu: { paginate: { state: {} @@ -121,7 +126,8 @@ var setuptools = { totals: { menu: {}, config: {} - } + }, + whitebag: {} }, mulequeue: {} } @@ -135,7 +141,11 @@ setuptools.config.backupAssistantDelay = 30000; setuptools.config.compressionMinimum = 1000; setuptools.config.compressionFormat = 0; setuptools.config.compressionLibraries = {snappy: {}}; -setuptools.config.defaultSlotOrder = [42010, 42011, 42012, 1, 2, 3, 17, 8, 24, 5, 16, 12, 13, 18, 22, 15, 20, 11, 19, 21, 4, 23, 25, 7, 6, 14, 9, 42013, 42014, 42015, 42016, 42017, 42018, 42019, 42020, 42021, 42022, 42023, 42024, 42025, 42026, 42027, 42028, 42029, 50000, 10, 26, 0]; +setuptools.config.corsURL = { + default: 'https://chrome.google.com/webstore/detail/jakcodexmuledump-cors-ada/iimhkldbldnmapepklmeeinclchfkddd', + firefox: 'https://addons.mozilla.org/en-US/firefox/addon/muledump-cors-adapter-firefox/' +}; +setuptools.config.defaultSlotOrder = [42010, 42011, 42012, 1, 2, 3, 17, 8, 24, 5, 16, 12, 13, 18, 22, 15, 20, 11, 19, 21, 4, 23, 25, 27, 7, 6, 14, 9, 42013, 42014, 42015, 42016, 42017, 42018, 42019, 42020, 42021, 42022, 42023, 42024, 42025, 42026, 42027, 42028, 42029, 50000, 10, 26, 0]; setuptools.config.devForcePoint = ''; setuptools.config.disqualifiedItemIds = [587, 2505, 2503, 2509, 2320, 2496, 2501, 2499, 2512]; setuptools.config.encryption = false; @@ -177,7 +187,7 @@ setuptools.config.mqStaleCache = 86400000; setuptools.config.noEncryptKeys = ['mulecrypt:keychain']; setuptools.config.noticesMonitorMaxAge = 300; setuptools.config.oneclickHelp = 'https://github.com/jakcodex/muledump/wiki/One-Click-Login'; -setuptools.config.perfLoadTime = 3000; +setuptools.config.perfLoadTime = 5000; setuptools.config.perfMinCPUs = 4; setuptools.config.ratelimitHelp = 'https://github.com/jakcodex/muledump/wiki/Rate-Limiting'; setuptools.config.remotePasteUrl = 'https://paste.jakcodex.io/api/create'; @@ -185,6 +195,7 @@ setuptools.config.realmApiParams = { muleDump: true, __source: 'jakcodex-v' + setuptools.version.major + setuptools.version.minor + setuptools.version.patch }; +setuptools.config.realmApiTimeout = 10000; setuptools.config.realmeyeUrl = 'https://www.realmeye.com'; setuptools.config.realmeyeOfferIds = [1793, 1803, 1808, 1826, 1932, 25630, 25631, 25632, 25633, 25634, 25635, 25636, 25637, 25638, 25639, 2571, 2572, 2579, 2591, 2592, 2593, 2608, 2611, 2612, 2613, 2629, 2630, 2631, 2636, 2640, 2641, 2644, 2645, 2649, 2651, 2656, 2659, 2660, 2661, 2666, 2667, 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2720, 2721, 2722, 2727, 2728, 2734, 2735, 2736, 2741, 2742, 2744, 2749, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2771, 2774, 2785, 2793, 2794, 2799, 2800, 2801, 2806, 2809, 2812, 2815, 2818, 2821, 2824, 2827, 283, 2847, 2848, 2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2865, 2866, 2867, 2868, 29769, 29772, 2979, 2980, 29804, 2981, 29819, 2982, 29820, 29821, 29822, 29823, 29824, 29825, 29826, 29827, 29828, 29829, 2983, 29830, 29831, 29832, 29836, 2984, 2985, 2986, 2990, 2991, 303, 308, 3089, 3090, 3105, 3107, 3118, 3129, 3130, 3131, 3132, 3137, 3149, 3150, 3151, 3152, 3159, 3160, 3161, 3163, 3164, 3165, 3170, 3183, 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, 3200, 3205, 3206, 3209, 3210, 3213, 3214, 3217, 3218, 3221, 3222, 3225, 3226, 3229, 3230, 3233, 3234, 3237, 3238, 3241, 3242, 3245, 3246, 3249, 3250, 3253, 3254, 3257, 3258, 3261, 3262, 3267, 32695, 3278, 3279, 3284, 3290, 3293, 3311, 3312, 3313, 3320, 3856, 3857, 3858, 3859, 3860, 3861, 4252, 5407, 573, 8333, 8334, 8335, 8336, 8337, 8338, 8339, 8340, 8341, 8342, 8343, 8344, 8345, 8346, 8608, 8609, 8610, 8611, 8615, 8616, 8617, 8618, 8732, 8781, 8783, 8796, 8812, 8814, 8815, 8827, 8828, 8829, 8830, 8831, 8842, 8843, 8844, 8845, 8846, 8847, 8848, 8850, 8851, 8852, 8856, 8857, 8858, 8859, 8860, 8861, 8862, 8863, 8960, 8962, 8980, 8981, 8982, 8983, 8984, 8985, 8993, 8995, 8996, 8997, 8998, 8999, 9000, 9011, 9015, 9016, 9017, 9018, 9019, 9020, 9021, 9022, 9023, 9024, 9025, 9033, 9034, 9035, 9036, 9037, 9038, 9039, 9040, 9041, 9042, 9052, 9053, 9054, 9055, 9056, 9057, 9058, 9059, 9060, 9061, 9062, 9063, 9068, 9069, 9074, 9075, 9076, 9077, 9084, 9085, 9086, 9087, 9610, 9612, 9615, 1802, 3133, 284, 10245, 2787, 2782, 12290, 3109, 10243, 584, 2802, 3174, 10244, 3119, 2781, 3098, 3168, 4253, 2733, 2788, 3393]; setuptools.config.reloadDelay = 3; @@ -192,8 +203,8 @@ setuptools.config.timesyncTtl = 2500; setuptools.config.timesyncUrl = 'https://time.jakcodex.io/api/time'; setuptools.config.totalsDefaultIcon = [880, 40]; setuptools.config.totalsItemWidth = 44; -setuptools.config.totalsFilterKeysIndex = 10; -setuptools.config.totalsSaveKeys = ['totalsGlobal', 'famefilter', 'fameamount', 'feedfilter', 'feedpower', 'sbfilter', 'nonsbfilter', 'utfilter', 'stfilter', 'disabled']; +setuptools.config.totalsFilterKeysIndex = 11; +setuptools.config.totalsSaveKeys = ['totalsGlobal', 'famefilter', 'fameamount', 'feedfilter', 'feedpower', 'sbfilter', 'nonsbfilter', 'utfilter', 'stfilter', 'wbfilter', 'disabled']; setuptools.config.totalsKeyObjects = { accountFilter: [], itemFilter: [], @@ -221,6 +232,13 @@ if ( window.location && window.location.pathname.match(/^\/muledump-preview/) ) } +// easily adjust certain settings into preview state (namely to make docs work during dev on local) +if ( window.location && window.location.hash === '#preview' ) { + + setuptools.config.url += '-preview'; + +} + // regex patterns setuptools.config.regex = { email: new RegExp(/^.*?@.*?\..*$/), @@ -246,11 +264,13 @@ setuptools.data.config.autocomplete = true; setuptools.data.config.automaticBackups = true; setuptools.data.config.autoReloadDays = 1; setuptools.data.config.backupAssistant = 14; +setuptools.data.config.badaccounts = -1; setuptools.data.config.compression = false; setuptools.data.config.corsAssistant = 1; -setuptools.data.config.debugging = true; +setuptools.data.config.debugging = false; setuptools.data.config.enabled = false; setuptools.data.config.encryption = false; +setuptools.data.config.equipSilhouettes = true; setuptools.data.config.exportDefault = 4; setuptools.data.config.errors = true; setuptools.data.config.ga = false; @@ -261,6 +281,7 @@ setuptools.data.config.gaTotals = true; setuptools.data.config.giftChestWidth = 0; setuptools.data.config.groupsMergeMode = 2; setuptools.data.config.hideHeaderText = false; +setuptools.data.config.keyBindings = 0; setuptools.data.config.lazySave = 10000; setuptools.data.config.longpress = 1000; setuptools.data.config.lowStorageSpace = true; @@ -280,6 +301,7 @@ setuptools.data.config.timesync = false; setuptools.data.config.tooltip = 500; setuptools.data.config.totalsExportWidth = 0; setuptools.data.config.totalswidth = 0; +setuptools.data.config.wbTotals = true; setuptools.data.exporter = { remote: { paste: false, @@ -289,6 +311,7 @@ setuptools.data.exporter = { storedLinks: [] }; setuptools.data.muledump = { + charsSeen: {}, chsortcustom: { format: 1, sort: -1, @@ -306,10 +329,19 @@ setuptools.data.muledump = { // // // } }, - whitebagTracker: { - accounts: {}, - totals: [] - }, + keys: [ + // key 0 - default map + { + name: 'Standard', + ctrl: 'ctrlKey', + shift: 'shiftKey' + }, + // key 1 - mac os + { + name: 'Mac OS', + ctrl: 'metaKey' + } + ], totals: { configSets: { active: 'Default', @@ -317,7 +349,50 @@ setuptools.data.muledump = { settings: {} } }, - charsSeen: {} + value: { + rel: { + item: { + fp: 1, + fb: 1, + tier: 1, + white: 100, + vst: { + "default": 2, // default value + "0": 1, // empty slots + "42010": 10, // potions + "42013": 20, // keys + "42015": 5, // dyes, cloths + "42016": 50, // skins + "42019": 20, // unlockers + "42021": 10, // assistants + "42026": 10, // pet food + } + }, + char: { + level: 10, + bp: 100, + totalFame: 10, + stats: 100, + equip: 0.1, + inv: 1 + }, + mule: { + chars: 1, + vaults: 1, + gifts: 1, + charSlots: 1, + openVaults: 1, + star: 1 + } + } + }, + wardrobe: { + accounts: {} + }, + whitebagTracker: { + accounts: {}, + totals: [] + } }; // by default the userid is false as it will be generated after the first page load @@ -330,6 +405,7 @@ setuptools.data.acknowledge = { // prepare for userConfiguration to be provided in accounts.js files var userConfiguration = { + "enabled": false, "config": {}, "muledump": { "chsortcustom": {}, @@ -476,7 +552,7 @@ setuptools.app.accounts.state = { // shift+click mechanics select a lot of screen text at random; this will prevent that $('*:not(.setuptools)').on('mousedown.muledump.setuptools.shiftCleanup', function(e) { - if ( e.shiftKey === false ) return; + if ( setuptools.app.muledump.keys('shift', e) === false ) return; $(this).addClass('noselect'); }).on('mouseup.muledump.setuptools.shiftCleanup', function(e) { if ( $(this).hasClass('noselect') )$(this).removeClass('noselect'); @@ -527,14 +603,9 @@ setuptools.click = function() { setuptools.tmp.activeClick = e; }); - // control keydown tracking - $(document).on('keydown.muledump.keydownTrack', function(e) { - if ( e.keyCode === 17 ) setuptools.state.ctrlKey = true; - }); - + // realmeye menu ctrl $(document).on('keyup.muledump.keyupTrack', function(e) { - if ( e.keyCode === 17 ) { - setuptools.state.ctrlKey = false; + if ( setuptools.app.muledump.keys('ctrl', e) === true || e.keyCode === 17 ) { setuptools.app.muledump.realmeye.itemCtrlUp(e); } }); @@ -559,21 +630,21 @@ setuptools.click = function() { $('#stage').on('click.page.screenshot', function(e) { - if ( !e.ctrlKey || !e.shiftKey ) return; + if ( setuptools.app.muledump.keys(['ctrl', 'shift'], e) === false ) return; setuptools.app.muledump.exporter.canvas($('#stage')[0]); }); $('#totals').on('click.totals.screenshot', function(e) { - if ( !e.ctrlKey || !e.shiftKey ) return; + if ( setuptools.app.muledump.keys(['ctrl', 'shift'], e) === false ) return; setuptools.app.muledump.exporter.canvas($('#totals')[0]); }); $('#main').on('click.main.screenshot', function(e) { - if ( !e.ctrlKey || !e.shiftKey ) return; + if ( setuptools.app.muledump.keys(['ctrl', 'shift'], e) === false ) return; setuptools.app.muledump.exporter.canvas($('#main')[0]); }); diff --git a/lib/setuptools/src/totals.js b/lib/setuptools/src/totals.js new file mode 100644 index 00000000..55885b15 --- /dev/null +++ b/lib/setuptools/src/totals.js @@ -0,0 +1,1766 @@ +/* +// Totals +*/ + +/** + * @function + * @param {jQuery} [track] + * @param {string} [page] + * Display the advanced totals menu + */ +setuptools.app.muledump.totals.menu.advanced = function(track, page) { + + if ( !(track instanceof jQuery) ) track = $('#totalsMenu'); + setuptools.lightbox.menu.context.close('totalsmenuAdvanced'); + var options = [ + { + option: 'hover', + action: 'close' + }, + { + option: 'scrollLock', + hook: '#totalsMenu' + }, + { + option: 'skip', + value: 'reposition' + }, + { + option: 'afterClose', + callback: setuptools.app.muledump.totals.menu.advanced, + callbackArg: [track, page] + }, + { + option: 'css', + css: { + width: '177px' + } + }, + { + option: 'class', + value: 'smallMenuCells' + }, + { + option: 'pos', + h: 'left', + v: 'top', + vpx: 28 + }, + { + class: 'goBack', + name: 'Go back...', + callback: setuptools.app.muledump.totals.menu.main, + override: 'afterClose' + }, + /*{ + class: 'goBack', + name: 'Basic Filters...', + callback: setuptools.app.muledump.totals.menu.basic, + override: 'afterClose' + },*/ + { + option: 'header', + value: 'Weapons', + class: 'openTotalWeaponsMenu', + callback: function(args) { + setuptools.app.muledump.totals.menu.advanced(args.track, args.page); + }, + callbackArg: {track: track, page: 'weapons'}, + override: 'afterClose' + } + ]; + + // populate type - weapons + if ( page === 'weapons' ) setuptools.app.muledump.totals.menu.populateByType( + options, + ['bows', 'daggers', 'katanas', 'staves', 'swords', 'wands'] + ); + + options.push({ + option: 'header', + value: 'Abilities', + class: 'openTotalAbilitiesMenu', + callback: function(args) { + setuptools.app.muledump.totals.menu.advanced(args.track, args.page); + }, + callbackArg: {track: track, page: 'abilities'}, + override: 'afterClose' + }); + + // populate type - abilities + if ( page === 'abilities' ) setuptools.app.muledump.totals.menu.populateByType( + options, + ['cloaks', 'helms', 'orbs', 'poisons', 'prisms', 'quivers', 'scepters', 'seals', 'shields', 'skulls', 'spells', 'stars', 'tomes', 'traps'] + ); + + options.push({ + option: 'header', + value: 'Armor', + class: 'openTotalArmorMenu', + callback: function(args) { + setuptools.app.muledump.totals.menu.advanced(args.track, args.page); + }, + callbackArg: {track: track, page: 'armor'}, + override: 'afterClose' + }); + + // populate type - armor + if ( page === 'armor' ) setuptools.app.muledump.totals.menu.populateByType( + options, + ['heavyarmor', 'lightarmor', 'robes'] + ); + + setuptools.app.muledump.totals.menu.populateByType(options, ['rings']); + + options.push( + { + class: 'disableAll', + name: 'Disable All Filters', + callback: setuptools.app.muledump.totals.config.toggleAllTypes, + callbackArg: false + }, + { + class: 'hideAll', + name: 'Enable All Filters', + callback: setuptools.app.muledump.totals.config.toggleAllTypes, + callbackArg: true + } + ); + + if ( setuptools.data.muledump.totals.configSets.active !== 'Default' ) options.push({ + class: 'saveTotalsSettings', + name: 'Save Settings', + callback: function() { + setuptools.app.muledump.totals.config.save('active', true); + setuptools.lightbox.status(this, 'Saved!'); + } + }); + + options.push({ + class: 'resetTotalsSettings', + name: 'Reset Settings', + callback: function() { + setuptools.app.muledump.cleanupSecondaryCache(); + setuptools.app.muledump.totals.config.activate('active', true); + } + }); + + setuptools.lightbox.menu.context.create('totalsmenuAdvanced', false, track, options); + +}; + +/** + * @function + * @param {jQuery} [track] + * @param {string} [page] + * Display the item types totals menu + * Presently not used (keeping the menu short) + */ +setuptools.app.muledump.totals.menu.basic = function(track, page) { + + if ( !(track instanceof jQuery) ) track = $('#totalsMenu'); + setuptools.lightbox.menu.context.close('totalsmenuBasic'); + var options = [ + { + option: 'hover', + action: 'close' + }, + { + option: 'scrollLock', + hook: '#totalsMenu' + }, + { + option: 'skip', + value: 'reposition' + }, + { + option: 'afterClose', + callback: setuptools.app.muledump.totals.menu.basic, + callbackArg: [track, page] + }, + { + option: 'class', + value: 'smallMenuCells' + }, + { + option: 'css', + css: { + width: '177px' + } + }, + { + option: 'pos', + h: 'left', + v: 'top', + vpx: 28 + }, + { + class: 'goBack', + name: 'Go back...', + callback: setuptools.app.muledump.totals.menu.main, + override: 'afterClose' + }, + { + class: 'goBack', + name: 'Advanced Filters...', + callback: setuptools.app.muledump.totals.menu.advanced, + override: 'afterClose' + } + ]; + + /* waiting on this + options.push({ + option: 'header', + value: 'Equipment', + class: 'openTotalEquipmentMenu', + callback: function(args) { + setuptools.app.muledump.totals.menu.basic(args.track, args.page); + }, + callbackArg: {track: track, page: 'equipment'}, + override: 'afterClose' + }); + + // populate type - equipment + if ( page === 'equipment' ) setuptools.app.muledump.totals.menu.populateByType( + options, + ['weapons', 'abilities', 'armor', 'rings'] + );*/ + + options.push({ + option: 'header', + value: 'Consumables', + class: 'openTotalConsumableMenu', + callback: function(args) { + setuptools.app.muledump.totals.menu.basic(args.track, args.page); + }, + callbackArg: {track: track, page: 'consumables'}, + override: 'afterClose' + }); + + // populate type - consumables + if ( page === 'consumables' ) setuptools.app.muledump.totals.menu.populateByType( + options, + ['candies', 'helpfulconsumables', 'assistants', 'otherconsumables', 'potions', 'potionssb'] + ); + + options.push({ + option: 'header', + value: 'Single Use Items', + class: 'openTotalSingleUseMenu', + callback: function(args) { + setuptools.app.muledump.totals.menu.basic(args.track, args.page); + }, + callbackArg: {track: track, page: 'singleuse'}, + override: 'afterClose' + }); + + // populate type - singleuser + if ( page === 'singleuse' ) setuptools.app.muledump.totals.menu.populateByType( + options, + ['finespirits', 'eggs', 'keys', 'petfood', 'petstones', 'portkeys', 'skins', 'textiles'] + ); + + options.push({ + option: 'header', + value: 'Other Items', + class: 'openTotalOtherItemsMenu', + callback: function(args) { + setuptools.app.muledump.totals.menu.basic(args.track, args.page); + }, + callbackArg: {track: track, page: 'otheritems'}, + override: 'afterClose' + }); + + // populate type - armor + if ( page === 'otheritems' ) setuptools.app.muledump.totals.menu.populateByType( + options, + ['empty', 'eventitems', 'misc', 'tarot', 'treasures', 'assistants', 'other', 'tarot', 'treasures'] + ); + + options.push( + { + class: 'disableAll', + name: 'Disable All Filters', + callback: setuptools.app.muledump.totals.config.toggleAllTypes, + callbackArg: false + }, + { + class: 'hideAll', + name: 'Enable All Filters', + callback: setuptools.app.muledump.totals.config.toggleAllTypes, + callbackArg: true + } + ); + + if ( setuptools.data.muledump.totals.configSets.active !== 'Default' ) options.push({ + class: 'saveTotalsSettings', + name: 'Save Settings', + callback: function() { + setuptools.app.muledump.totals.config.save('active', true); + setuptools.lightbox.status(this, 'Saved!'); + } + }); + + options.push({ + class: 'resetTotalsSettings', + name: 'Reset Settings', + callback: function() { + setuptools.app.muledump.cleanupSecondaryCache(); + setuptools.app.muledump.totals.config.activate('active', true); + } + }); + + setuptools.lightbox.menu.context.create('totalsmenuBasic', false, track, options); + +}; + +/** + * @function + * Display a menu for managing totals-related settings + */ +setuptools.app.muledump.totals.menu.settings = function() { + + /* Active Configuration Sets + /* Create New Configuration Set + /* Active Account Filter Members + /* Item Group Sort Order + /* Permanently Hidden Items + */ + + setuptools.lightbox.close(); + setuptools.lightbox.build('totalsmenu-settings', ' \ +
\ + '); + + if ( setuptools.state.loaded === false ) setuptools.lightbox.build('totalsmenu-settings', ' \ +
In order to permanently save these settings you must be using SetupTools. See Totals Management in the wiki.
\ +
 
\ + '); + + // display the account filter info + setuptools.lightbox.build('totalsmenu-settings', ' \ +
\ +
Active Configuration Set
\ +
\ + \ +
\ +
\ + \ + \ + \ + \ +
\ +
\ +
 
\ + \ +
\ +
Create New Configuration Set
\ +
\ + \ +
\ +
\ + \ +
\ +
\ +
 
\ + \ +
Item Group Sorting
\ + ' + ( (setuptools.app.muledump.totals.config.getKey('slotOrder').length === 0) ? '
Uh oh :D This configSet has invalid data!
 
' : '' ) + ' \ +
\ + '); + + // sort keys into their proper order + var types = setuptools.app.muledump.totals.config.getTypes().sort(function(a, b) { + var slotOrder = setuptools.app.muledump.totals.config.getKey('slotOrder'); + var vst = {}; + vst.a = setuptools.app.muledump.itemSlotTypeVst(a); + vst.b = setuptools.app.muledump.itemSlotTypeVst(b); + return ( slotOrder.indexOf(vst.a) - slotOrder.indexOf(vst.b) ); + }); + + // display a tile for each type + types.filter(function(type) { + var name = setuptools.app.muledump.itemSlotTypeName(type); + var vst = setuptools.app.muledump.itemSlotTypeVst(type); + var itemList = setuptools.app.muledump.itemsByVst(vst); + var item = window.items[itemList[Math.floor(Math.random()*Math.floor(itemList.length))]]; + var classes = ''; + + if ( setuptools.data.options['totalsFilter-' + type] === true ) classes += 'enabled'; + setuptools.lightbox.build('totalsmenu-settings', ' \ +
\ +
' + name + '
\ +
\ +
\ + '); + + }); + + setuptools.lightbox.build('totalsmenu-settings', ' \ +
\ +
⚪⚪⚪
\ +
\ +
 
\ + \ +
Active Account Filter Members
\ + ' + ( (setuptools.app.muledump.totals.config.getKey('accountFilter').length === 0) ? '
No accounts in filter
' : '' ) + ' \ +
\ + '); + + if ( + setuptools.state.loaded === true && + setuptools.app.muledump.totals.config.getKey('accountFilter').length > 0 + ) setuptools.lightbox.build('totalsmenu-settings', '\ + \ + '); + + setuptools.app.muledump.totals.config.getKey('accountFilter').sort(); + setuptools.app.muledump.totals.config.getKey('accountFilter').filter(function(guid) { + + setuptools.lightbox.build('totalsmenu-settings', ' \ +
' + setuptools.app.muledump.getName(guid) + '
\ + '); + + }); + + setuptools.lightbox.build('totalsmenu-settings', ' \ +
\ +
 
\ + '); + + // display the hidden items filter info + setuptools.lightbox.build('totalsmenu-settings', ' \ +
Permanently Hidden Items
\ + ' + ( ( setuptools.app.muledump.totals.config.getKey('itemFilter').length === 0 ) ? '
No items hidden
' : '' ) + '\ +
'); + + if ( setuptools.app.muledump.totals.config.getKey('itemFilter').length > 0 ) { + + setuptools.app.muledump.totals.config.getKey('itemFilter').filter(function(itemid) { + + var item = items[+itemid]; + if ( item === undefined ) { + + var data = setuptools.app.muledump.totals.config.getKey('itemFilter'); + data.splice(data.indexOf(+itemid), 1); + setuptools.app.muledump.totals.config.setKey('itemFilter', data); + setuptools.app.techlog('Totals/itemFilter removing: ' + itemid); + + } else setuptools.lightbox.build('totalsmenu-settings', '
'); + + }); + + } + + setuptools.lightbox.build('totalsmenu-settings', '
\ + '); + + if ( setuptools.app.muledump.totals.config.getKey('itemFilter').length > 0 ) setuptools.lightbox.build('totalsmenu-settings', ' \ +
⚪⚪⚪
\ +
\ + '); + + setuptools.lightbox.build('totalsmenu-settings', ' \ +
 \ +
Legend\ +
Shift+Click items to enable/disable them\ +
Click and drag items to sort them (item sorting)\ +
Double click items to access subsorting menu (item sorting)\ +
\ + '); + + var currentSet = setuptools.data.muledump.totals.configSets.active; + setuptools.lightbox.settitle('totalsmenu-settings', 'Totals Settings Manager'); + setuptools.lightbox.drawhelp('totalsmenu-settings', 'docs/muledump/totals-manager', 'Totals Help'); + setuptools.lightbox.display('totalsmenu-settings', {variant: 'fl-Totals', afterClose: function() { + setuptools.tmp.itemSortDragging.off(); + setuptools.app.muledump.totals.updateSecondaryFilter(); + window.update_totals(); + window.update_filter(); + option_updated('totals'); + }}); + + if ( setuptools.state.loaded === false ) { + $('.featherlight-content input').prop('disabled', true).attr('placeholder', 'This feature requires SetupTools'); + $('.featherlight-content select').prop('disabled', true); + $('.featherlight-content div.setuptools.menuStyle:not(.resetSlotOrder)').addClass('disabled truly').removeClass('selected negative').attr('title', 'This feature requires SetupTools'); + } + + // item subsorting allows for sorting items within a group + $('.itemSlotTypeSorting.cell') + .on('click.muledump.totals.itemGroupSorting', function(e) { + if ( setuptools.app.muledump.keys('shift', e) === false ) return; + setuptools.app.muledump.toggleoption('totalsFilter-' + $(this).attr('data-type'), undefined, true); + $(this).toggleClass('enabled'); + if ( setuptools.state.loaded === false ) { + window.update_totals(); + window.update_filter(); + option_updated('totals'); + } + }) + .on('dblclick.muledump.totals.itemGroupSorting', function(e) { + + var vst = setuptools.app.muledump.itemSlotTypeVst($(this).attr('data-type')); + var itemList = setuptools.app.muledump.itemsByVst(vst); + if ( typeof vst === 'undefined' ) return; + + setuptools.lightbox.build('totalsmenu-itemSorting', ' \ +
\ + Click and drag to sort items within their group. Don\'t forget to save on previous page.\ +
 \ +
\ +
\ + '); + + // determine item sorting + var slotSubOrder = setuptools.app.muledump.totals.config.getKey('slotSubOrder'); + if ( Array.isArray(slotSubOrder[vst]) === false ) { + + //itemList = itemList.sort(window.ids_sort); + slotSubOrder[vst] = itemList; + + } + + if ( slotSubOrder[vst].length > 0 ) slotSubOrder[vst].filter(function(itemid) { + + var item = items[+itemid]; + if ( setuptools.config.disqualifiedItemIds.indexOf(+itemid) > -1 ) return; + if ( item[3] === 40 && item[4] === 0 ) return; + setuptools.lightbox.build('totalsmenu-itemSorting', '
'); + + }); + + setuptools.lightbox.build('totalsmenu-itemSorting', ' \ +
\ + \ + '); + + setuptools.lightbox.settitle('totalsmenu-itemSorting', 'Item Sorting'); + setuptools.lightbox.display('totalsmenu-itemSorting', {variant: 'fl-Totals nobackground'}); + + // provide a hidden item filter integration + $('#itemSubsortingBox > div.item').on('click.muledump.itemFilter', function(e) { + + if ( e.target !== this || setuptools.app.muledump.keys('shift', e) === false || !$(this).attr('data-itemid') ) return; + setuptools.app.muledump.totals.toggleHideItem($(this).attr('data-itemid')); + $(this).toggleClass('selected'); + + }); + + // bind the tooltip + var itemsSelected = $('div#itemSubsortingBox div.item'); + setuptools.app.muledump.tooltip(itemsSelected, 'itemSubsortingTooltip'); + + // item dragging + setuptools.tmp.itemSubsortDragging = new Muledump_Dragging({ + target: ['item', 'subsorting', 'cell'], + targetattr: 'data-itemId', + approach: 0.1, + dragclass: 'dragging bright', + callbacks: { + before: function(parent, self) { + + if ( + typeof window.items[self.attr('data-itemId')] !== 'object' || + typeof window.items[parent.target] !== 'object' + ) return; + + // determine source and target virtualSlotTypes and exit if target doesn't have the attribute + var itemid = self.attr('data-itemId'); + var targetid = parent.target; + parent.itemid = itemid; + parent.targetid = targetid; + if ( itemid === targetid ) return; + return true; + + }, + after: function(parent, self) { + + var slotSubOrder = setuptools.app.muledump.totals.config.getKey('slotSubOrder'); + var vst = window.items[parent.itemid][setuptools.config.vstIndex]; + slotSubOrder[vst].splice(slotSubOrder[vst].indexOf(parent.itemid), 1); + slotSubOrder[vst].splice((slotSubOrder[vst].indexOf(parent.targetid)+parent.indexModifier), 0, parent.itemid); + + } + } + }); + + }); + + // bind the dragging class + setuptools.tmp.itemSortDragging = new Muledump_Dragging({ + target: ['itemSlotTypeSorting', 'cell'], + targetattr: 'data-type', + approach: 0.1, + callbacks: { + before: function(parent, self) { + + if ( + typeof window.itemsSlotTypeMap[self.attr('data-type')] !== 'object' || + typeof window.itemsSlotTypeMap[parent.target] !== 'object' + ) return; + + // determine source and target virtualSlotTypes and exit if target doesn't have the attribute + var vst = setuptools.app.muledump.itemSlotTypeVst(self.attr('data-type')); + var targetVst = setuptools.app.muledump.itemSlotTypeVst(parent.target); + parent.vst = vst; + parent.targetVst = targetVst; + if ( vst === targetVst ) return; + return true; + + }, + after: function(parent, self) { + + var slotOrder = setuptools.app.muledump.totals.config.getKey('slotOrder'); + slotOrder.splice(slotOrder.indexOf(parent.vst), 1); + slotOrder.splice((slotOrder.indexOf(parent.targetVst)+parent.indexModifier), 0, parent.vst); + + }, + finish: function(parent, self) { + + if ( parent.clickIndexDown === parent.clickIndexUp ) return; + if ( setuptools.state.loaded === false ) { + window.init_totals(); + window.update_totals(); + } + + } + } + }); + + // item sorting is an expandable box + setuptools.lightbox.expander('#itemSlotTypeSorting', '.itemSlotTypeSorting.expansion'); + setuptools.lightbox.expander('#hiddenItems', '.hiddenItems.expansion'); + + // toggle favorite status + $('.setuptools.link.favorite').on('click.muledump.totals.favorite', function() { + + if ( $(this).hasClass('disabled') === true ) return; + var name = $(this).parent().prev().find('select[name="totalsConfigSets"]').val(); + if ( name === 'Default' ) { + setuptools.lightbox.status(this, 'No!'); + return; + } + var index = setuptools.data.muledump.totals.configSets.favorites.indexOf(name); + if ( index === -1 ) { + setuptools.data.muledump.totals.configSets.favorites.push(name); + $(this).addClass('selected').attr('title', 'Click to Unfavorite'); + } else { + setuptools.data.muledump.totals.configSets.favorites.splice(index, 1); + $(this).removeClass('selected').attr('title', 'Click to Favorite'); + } + setuptools.app.config.save('Totals config set was favorite toggled', true); + + }); + + // automatically switch buttons on config selection + $('select[name="totalsConfigSets"]').on('change.muledump.totals.totalsConfigSets', function() { + + var name = $(this).val(); + + var favoriteButton = $('.setuptools.link.favorite'); + if ( setuptools.data.muledump.totals.configSets.favorites.indexOf(name) === -1 ) { + favoriteButton.removeClass('selected').attr('title', 'Click to Favorite'); + } else favoriteButton.addClass('selected').attr('title', 'Click to Unfavorite'); + + var activateButton = $('.setuptools.link.activateSet'); + if ( setuptools.data.muledump.totals.configSets.active === name ) { + activateButton.text('Save'); + } else activateButton.text('Switch To'); + + }); + + // resets configuration to original state + $('.setuptools.link.reset').on('click.muledump.totals.reset', function() { + if ( $(this).hasClass('disabled') === true ) return; + setuptools.app.muledump.totals.config.activate(undefined, true, true); + setuptools.lightbox.status(this, 'Active reset!'); + setuptools.app.muledump.totals.menu.settings(); + }); + + // switch active configuration + $('.setuptools.link.activateSet') + .off('click.muledump.totals.activateSet') + .on('click.muledump.totals.activateSet', function() { + + if ( $(this).hasClass('disabled') === true ) return; + var name = $('select[name="totalsConfigSets"]').val(); + if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; + if ( $(this).text() === 'Save' ) { + + setuptools.app.muledump.totals.config.save(name, true); + setuptools.lightbox.status($(this), 'Saved!'); + + window.init_totals(); + window.update_totals(); + + return; + + } + + if ( currentSet !== name ) setuptools.app.muledump.totals.config.reset(currentSet); + currentSet = name; + setuptools.app.muledump.totals.config.activate(name); + setuptools.app.muledump.totals.menu.settings(); + setuptools.lightbox.status($('.setuptools.link.activateSet'), "Enabled!"); + + }); + + // delete a configuration set + $('.setuptools.link.deleteSet').on('click.muledump.totals.deleteSet', function() { + + if ( $(this).hasClass('disabled') === true ) return; + var name = $('select[name="totalsConfigSets"]').val(); + if ( name === 'Default' ) { + setuptools.lightbox.status(this, 'No!'); + return; + } + if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; + delete setuptools.data.muledump.totals.configSets.settings[name]; + setuptools.app.config.save('Totals config set deleted', true); + if ( name === setuptools.data.muledump.totals.configSets.active ) setuptools.app.muledump.totals.config.activate('Default'); + setuptools.app.muledump.totals.menu.settings(); + + }); + + // save configurations + $('.setuptools.link.saveNewSet').on('click.muledump.totals.saveNewSet', function() { + + if ( $(this).hasClass('disabled') === true ) return; + if ( this.busy === true ) return; + var name = $('input[name="newConfigSetName"]').val(); + + // name cannot be empty + if ( name === '' ) { + + this.busy = true; + $(this).removeClass('positive').addClass('negative'); + setuptools.lightbox.status(this, 'Invalid set name', function(self) { + self.busy = false; + $(self).removeClass('negative'); + }); + return; + + } + + // name must be unique + if ( typeof setuptools.data.muledump.totals.configSets[name] === 'object' ) { + + $(this).removeClass('positive').addClass('negative'); + setuptools.lightbox.status(this, 'Name already exists', function(self) { + self.removeClass('negative').addClass('positive'); + }); + return; + + } + + var origName = setuptools.data.muledump.totals.configSets.active; + + // create the configuration + setuptools.app.muledump.totals.config.save(name); + setuptools.app.muledump.totals.menu.settings(); + setuptools.lightbox.status($('.setuptools.link.saveNewSet'), 'Created!'); + + // reset previous configSet if saving a new set + if ( origName !== name ) setuptools.app.muledump.totals.config.reset(origName); + + }); + + // reset the slotOrder to default + $('div.setuptools.link.resetSlotOrder').on('click.muledump.resetSlotOrder', function() { + setuptools.app.muledump.totals.config.setKey('slotOrder', $.extend(true, [], setuptools.copy.totals.defaultConfig.slotOrder)); + setuptools.app.muledump.totals.config.setKey('slotSubOrder', $.extend(true, {}, setuptools.config.totalsKeyObjects.slotSubOrder)); + setuptools.app.muledump.totals.menu.settings(); + }); + + // erase the hidden items list + $('div.setuptools.link.clearAllHidden').on('click.muledump.clearAllHidden', function() { + setuptools.app.muledump.totals.config.setKey('itemFilter', $.extend(true, [], setuptools.config.totalsKeyObjects.itemFilter)); + setuptools.tmp.globalTotalsCounter.import('clearExcluded'); + window.update_totals(); + window.update_filter(); + option_updated('totals'); + setuptools.app.muledump.totals.menu.settings(); + }); + + // handle hidden items list clicks + var itemsSelected = $('div#hiddenItems div.item'); + setuptools.app.muledump.tooltip(itemsSelected, 'hiddenItemsTooltip'); + itemsSelected.off('click.muledump.totals.hiddenItems').on('click.muledump.totals.hiddenItems', function(e) { + if ( setuptools.app.muledump.keys('shift', e) === true ) { + + var itemId = +$(this).attr('data-itemid'); + setuptools.app.muledump.totals.config.getKey('itemFilter').splice(setuptools.app.muledump.totals.config.getKey('itemFilter').indexOf(itemId), 1); + setuptools.app.muledump.totals.config.setKey('itemFilter', setuptools.app.muledump.totals.config.getKey('itemFilter')); + $(this).remove(); + $('.tooltip').remove(); + + } + }); + + // handle account filter list clicks + $('#accountFilterList div').off('click.muledump.totals.accountFilterList').on('click.muledump.totals.accountFilterList', function(e) { + + if ( setuptools.app.muledump.keys('shift', e) === true ) { + + var guid = $(this).attr('data-guid'); + if ( !guid ) return; + setuptools.app.muledump.totals.config.getKey('accountFilter').splice(setuptools.app.muledump.totals.config.getKey('accountFilter').indexOf(guid), 1); + $(this).remove(); + if ( setuptools.app.muledump.totals.config.getKey('accountFilter').length === 0 ) { + + $('#accountFilterList').text('No accounts in filter'); + + } + + } + + }); + + $('div.muledump.link.nameswap').on('click.muledump.link.nameswap', function() { + setuptools.data.config.mqDisplayIgn = !(setuptools.data.config.mqDisplayIgn); + setuptools.app.muledump.totals.menu.settings(); + }); + +}; + +/** + * @function + * @param {jQuery} [track] + * Display the totals menu + */ +setuptools.app.muledump.totals.menu.main = function(track) { + + if ( !(track instanceof jQuery) ) track = $('#totalsMenu'); + setuptools.lightbox.menu.context.close('totalsmenu'); + var options = [ + { + option: 'hover', + action: 'close' + }, + { + option: 'scrollLock', + hook: '#totalsMenu' + }, + { + option: 'skip', + value: 'reposition' + }, + { + option: 'afterClose', + callback: setuptools.app.muledump.totals.menu.main + }, + { + option: 'class', + value: 'smallMenuCells' + }, + { + option: 'css', + css: { + width: '177px' + } + }, + { + option: 'pos', + h: 'left', + v: 'top', + vpx: 28 + }, + { + class: 'toggleTotals', + name: ( (setuptools.data.options.totals === true) ? 'Disable' : 'Enable' ) + ' Totals', + callback: setuptools.app.muledump.toggleoption, + callbackArg: 'totals' + }, + { + class: 'openTotalsSettings', + name: 'Settings Manager', + callback: setuptools.app.muledump.totals.menu.settings, + override: 'afterClose' + } + ]; + + // totals needs to be enabled for these options + if ( setuptools.data.options.totals === true ) { + + if ( Array.isArray(setuptools.app.muledump.totals.config.getKey('accountFilter')) && setuptools.app.muledump.totals.config.getKey('accountFilter').length > 0 ) options.push({ + class: 'resetAccountFilter', + name: 'Reset Account Filter', + callback: function() { + setuptools.app.muledump.totals.config.setKey('accountFilter', $.extend(true, [], setuptools.config.totalsKeyObjects.accountFilter)); + setuptools.app.muledump.totals.updateSecondaryFilter(); + setuptools.tmp.globalTotalsCounter.import(); + window.update_totals(); + window.update_filter(); + option_updated('totals'); + } + }); + + options.push({ + class: 'displayGlobalTotals', + name: ( (setuptools.data.options.totalsGlobal === true) ? 'Disable' : 'Enable' ) + ' Global', + callback: function(arg) { + + // toggle the option + setuptools.app.muledump.toggleoption(arg, undefined, true); + + // mules with custom sorting need to be reset in certain circumstances + for (var guid in mules) + if (mules.hasOwnProperty(guid)) + if (mules[guid].customSorting === true) { + + mules[guid].createCounter(); + mules[guid].query(false, true); + + } + + window.update_totals(); + window.update_filter(); + window.options_save(); + + }, + callbackArg: 'totalsGlobal' + }); + + options.push( + /*{ + class: 'totalsBasicMenu', + name: 'Basic Filters...', + callback: setuptools.app.muledump.totals.menu.basic, + override: 'afterClose' + },*/ + { + option: 'select', + name: 'Sorting Mode', + class: 'sortingMode', + options: { + standard: 'Standard', + alphabetical: 'Alphabetical', + fb: 'Fame Bonus', + fp: 'Feed Power' + }, + selected: setuptools.app.muledump.totals.config.getKey('sortingMode'), + binding: function () { + + $('select.sortingMode').on('change.muledump.totals.sortingMode', function () { + + var mode = $(this).val(); + setuptools.app.muledump.totals.config.setKey('sortingMode', mode); + setuptools.app.muledump.totals.updateSecondaryFilter(); + window.init_totals(); + window.update_totals(); + setuptools.app.muledump.totals.menu.main(); + + }); + + } + }); + + var favoriteOptions = {}; + setuptools.data.muledump.totals.configSets.favorites.filter(function(item, index) { + if ( setuptools.app.muledump.totals.config.exists(item) === false ) { + + setuptools.data.muledump.totals.configSets.favorites.splice(index, 1); + return; + + } + + favoriteOptions[item] = item; + }); + if ( typeof favoriteOptions[setuptools.data.muledump.totals.configSets.active] !== 'string' ) favoriteOptions[setuptools.data.muledump.totals.configSets.active] = setuptools.data.muledump.totals.configSets.active; + + if ( Object.keys(favoriteOptions).length > 1 ) options.push({ + option: 'select', + name: 'Favorite Filters', + class: 'favoriteFilter', + options: favoriteOptions, + selected: setuptools.data.muledump.totals.configSets.active, + binding: function() { + + $('select.favoriteFilter').on('change.muledump.totals.favoriteFilter', function() { + + var name = $(this).val(); + if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; + setuptools.app.muledump.totals.config.reset(setuptools.data.muledump.totals.configSets.active); + setuptools.app.muledump.totals.config.activate(name); + setuptools.app.muledump.totals.menu.main(); + + }); + + } + }); + + if ( setuptools.data.muledump.totals.configSets.active !== 'Default' ) options.push({ + class: 'saveTotalsSettings', + name: 'Save Settings', + callback: function() { + setuptools.app.muledump.totals.config.save('active', true); + setuptools.lightbox.status(this, 'Saved!'); + } + }); + + options.push({ + class: 'resetTotalsSettings', + name: 'Reset Settings', + callback: function() { + setuptools.app.muledump.cleanupSecondaryCache(); + setuptools.app.muledump.totals.config.activate('active', true); + } + }, + { + option: 'header', + value: 'Advanced Filters...', + class: 'totalsAdvancedMenu', + callback: setuptools.app.muledump.totals.menu.advanced, + override: 'afterClose' + }, + { + option: 'header', + value: 'Standard Filters' + }, + { + option: 'select', + name: 'Fame Bonus', + class: 'fameBonusFilter', + options: { + '-1': 'Disabled', + '0': '> 0', + '1': '> 1%', + '2': '> 2%', + '3': '> 3%', + '4': '> 4%', + '5': '> 5%' + }, + selected: setuptools.data.options.fameamount, + binding: function() { + + $('select.fameBonusFilter').change(function() { + + setuptools.data.options.famefilter = !( $(this).val() === '-1' ); + setuptools.data.options.fameamount = $(this).val(); + option_updated('famefilter'); + + }); + + } + }, + { + option: 'select', + name: 'Feed Power', + class: 'feedPowerFilter', + options: { + '-1': 'Disabled', + '0': '> 0', + '100': '> 100', + '250': '> 250', + '500': '> 500', + '1000': '> 1000', + '2500': '> 2500' + }, + selected: setuptools.data.options.feedpower, + binding: function() { + + $('select.feedPowerFilter').change(function() { + + setuptools.data.options.feedfilter = !( $(this).val() === '-1' ); + setuptools.data.options.feedpower = $(this).val(); + option_updated('feedfilter'); + + }); + + } + }, + { + class: 'toggleSBFilter', + name: ( (setuptools.data.options.sbfilter === true) ? 'Disable' : 'Show Only' ) + ' Soulbound', + callback: setuptools.app.muledump.toggleoption, + callbackArg: 'sbfilter' + }, + { + class: 'toggleNonSBFilter', + name: ( (setuptools.data.options.nonsbfilter === true) ? 'Disable' : 'Show Only' ) + ' Tradeable', + callback: setuptools.app.muledump.toggleoption, + callbackArg: 'nonsbfilter' + }, + { + class: 'toggleUTFilter', + name: ( (setuptools.data.options.utfilter === true) ? 'Disable' : 'Show Only' ) + ' Untiered', + callback: setuptools.app.muledump.toggleoption, + callbackArg: 'utfilter' + }, + { + class: 'toggleSTFilter', + name: ( (setuptools.data.options.stfilter === true) ? 'Disable' : 'Show Only' ) + ' Set Items', + callback: setuptools.app.muledump.toggleoption, + callbackArg: 'stfilter' + }, + { + class: 'toggleWBFilter', + name: ( (setuptools.data.options.wbfilter === true) ? 'Disable' : 'Show Only' ) + ' White Bags', + callback: setuptools.app.muledump.toggleoption, + callbackArg: 'wbfilter' + }); + + } + + setuptools.lightbox.menu.context.create('totalsmenu', false, track, options); + +}; + +/** + * @function + * @param {object} options + * @param types + */ +setuptools.app.muledump.totals.menu.populateByType = function(options, types) { + + if ( typeof types === 'string' ) types = [types]; + if ( Array.isArray(types) === false ) return; + + for ( var a = 0; a < types.length; a++ ) { + + var type = types[a]; + var filterName = 'totalsFilter-' + type; + var displayName = setuptools.app.muledump.itemSlotTypeName(type); + if ( typeof displayName === 'undefined' ) continue; + options.push({ + class: 'toggle-' + filterName, + name: ( (setuptools.data.options[filterName] === true) ? 'Hide' : 'Show' ) + ' ' + displayName, + callback: setuptools.app.muledump.toggleoption, + callbackArg: filterName + }); + + } + +}; + +/** + * @function + * @param {string} key + * @param {string} [configSet] + * @param {*} [defaultValue] + * @returns {*} + * Returns the specified key from a configSet + */ +setuptools.app.muledump.totals.config.getKey = function(key, configSet, defaultValue) { + + if ( !configSet || configSet === false ) configSet = setuptools.data.muledump.totals.configSets.active; + if ( typeof setuptools.data.muledump.totals.configSets.settings[configSet] !== 'object' ) return; + if ( typeof setuptools.data.muledump.totals.configSets.settings[configSet][key] === 'undefined' ) { + if ( defaultValue === null ) return; + if ( !defaultValue ) defaultValue = ( Array.isArray(setuptools.config.totalsKeyObjects[key]) === true ) ? + $.extend(true, [], setuptools.config.totalsKeyObjects[key]) : + $.extend(true, {}, setuptools.config.totalsKeyObjects[key]); + this.setKey(key, defaultValue, configSet); + return defaultValue; + } + return setuptools.data.muledump.totals.configSets.settings[configSet][key]; + +}; + +/** + * @function + * @param {string} key + * @param {*} value + * @param {string} [configSet] + * Returns the specified key from a configSet + */ +setuptools.app.muledump.totals.config.setKey = function(key, value, configSet) { + + if ( typeof key !== 'string' || !value ) return; + if ( !configSet ) configSet = setuptools.data.muledump.totals.configSets.active; + if ( typeof setuptools.data.muledump.totals.configSets.settings[configSet] !== 'object' ) return; + setuptools.data.muledump.totals.configSets.settings[configSet][key] = value; + setuptools.data.options[key] = setuptools.data.muledump.totals.configSets.settings[configSet][key]; + +}; + +/** + * @function + * @param {string} configSet + * @returns {boolean} + * Returns whether or not the specified configSet exists + */ +setuptools.app.muledump.totals.config.exists = function(configSet) { + + if ( !configSet || configSet === 'active' ) configSet = setuptools.data.muledump.totals.configSets.active; + if ( typeof configSet !== 'string' ) return; + return ( typeof setuptools.data.muledump.totals.configSets.settings[configSet] === 'object' ); + +}; + +/** + * @function + * @param configSet + * Reinitializes a configSet (or multiple) for when the slotMap changes or items get added or removed + */ +setuptools.app.muledump.totals.config.reinit = function(configSet) { + + if ( configSet === 'all' ) configSet = Object.keys(setuptools.data.muledump.totals.configSets.settings); + if ( configSet === 'active' ) configSet = [setuptools.data.muledump.totals.configSets.active]; + if ( typeof configSet === 'string' ) configSet = [configSet]; + if ( Array.isArray(configSet) === false || configSet.length === 0 ) return; + + setuptools.app.techlog('Totals/ConfigSet reinit executing'); + + // configSet cleanup + configSet.filter(function(configSet) { + + var slotSubOrder = setuptools.app.muledump.totals.config.getKey('slotSubOrder', configSet); + Object.filter(slotSubOrder, function(vst, items) { + + // loop through slotOrder groups and make list of items that do not belong + var deleteItems = []; + items.filter(function(item) { + + var itemid = +item; + if ( + typeof window.items[itemid] === 'undefined' || + ( + window.items[itemid][setuptools.config.vstIndex] !== (+vst) && + window.items[itemid][1] !== (+vst) + ) + ) { + deleteItems.push(item); + } + + }); + + // delete the found items + for ( var i = 0; i < deleteItems.length; i++ ) { + slotSubOrder[vst].splice(slotSubOrder[vst].indexOf(deleteItems[i]), 1); + setuptools.app.techlog('Totals/ConfigSet reinit deleting: [set: ' + configSet + ', vst: ' + vst + ', itemid: ' + deleteItems[i] + ']'); + } + + // loop through window.items and insert items that do belong + Object.filter(window.items, function(itemid, item) { + itemid = itemid.toString(); + if ( (!(item[setuptools.config.vstIndex] !== (+vst) && item[1] !== (+vst))) && slotSubOrder[vst].indexOf(itemid) === -1 ) { + slotSubOrder[vst].push(itemid); + setuptools.app.techlog('Totals/ConfigSet reinit adding: [set: ' + configSet + ', vst: ' + vst + ', itemid: ' + itemid + ']'); + } + }); + + }); + + }); + +}; + +/** + * @function + * @param {string} configSet + * @returns {boolean} + * Delete a specific configSet + */ +setuptools.app.muledump.totals.config.delete = function(configSet) { + + if ( configSet === 'all' ) configSet = Object.keys(setuptools.data.muledump.totals.configSets.settings); + if ( configSet === 'active' ) configSet = [setuptools.data.muledump.totals.configSets.active]; + if ( typeof configSet === 'string' ) configSet = [configSet]; + if ( Array.isArray(configSet) === false || configSet.length === 0 ) return; + + // delete specified configSets + configSet.filter(function(configSet) { + if ( + setuptools.app.muledump.totals.config.exists(configSet) === false || + configSet === 'Default' + ) return; + + // delete configSet + delete setuptools.data.muledump.totals.configSets.settings[configSet]; + + // remove from favorites + if ( setuptools.data.muledump.totals.configSets.favorites.indexOf(configSet) > -1 ) setuptools.data.muledump.totals.configSets.favorites.splice( + setuptools.data.muledump.totals.configSets.favorites.indexOf(configSet), + 1 + ); + }); + + // reset default configuration + if ( configSet.length === 1 && configSet[0] === 'Default' ) setuptools.data.muledump.totals.configSets.settings[configSet[0]] = $.extend(true, {}, setuptools.copy.totals.defaultConfig); + if ( configSet.indexOf(setuptools.data.muledump.totals.configSets.active) > -1 ) setuptools.app.muledump.totals.config.activate('Default'); + + return true; + +}; + +/** + * @function + * @param {boolean} state + */ +setuptools.app.muledump.totals.config.toggleAllTypes = function(state) { + + if ( typeof state === 'undefined' ) return false; + setuptools.app.muledump.totals.config.getTypes().filter(function(type) { + setuptools.app.muledump.toggleoption('totalsFilter-' + type, state, true); + }); + window.update_totals(); + window.update_filter(); + option_updated('totals'); + return true; + +}; + +/** + * @function + * @param {string} name + * Store a temporary backup of all configSets + */ +setuptools.app.muledump.totals.config.backup = function(name) { + + if ( typeof setuptools.copy.totals.configSets === 'undefined' ) { + setuptools.copy.totals.configSets = $.extend(true, {}, setuptools.data.muledump.totals.configSets); + return; + } + + // only copy configSets not present + var configSets = []; + if ( typeof name === 'string' ) configSets = [name]; + if ( configSets.length === 0 ) configSets = setuptools.data.muledump.totals.configSets.settings; + for ( var configSet in configSets ) + if ( configSets.hasOwnProperty(configSet) ) + if ( typeof setuptools.copy.totals.configSets[configSet] === 'undefined' ) + setuptools.copy.totals.configSets[configSet] = $.extend(true, {}, configSets[configSet]); + +}; + +/** + * @function + * @param {string} name + * @param {boolean} [immediate] + * Create a totals configuration set + */ +setuptools.app.muledump.totals.config.save = function(name, immediate) { + + if ( typeof name === 'undefined' || name === 'active') name = setuptools.data.muledump.totals.configSets.active; + if ( typeof name !== 'string' ) return; + var accountFilter = $.extend(true, [], setuptools.app.muledump.totals.config.getKey('accountFilter')); + var slotOrder = $.extend(true, [], setuptools.app.muledump.totals.config.getKey('slotOrder')); + var itemFilter = $.extend(true, [], setuptools.app.muledump.totals.config.getKey('itemFilter')); + var slotSubOrder = $.extend(true, {}, setuptools.app.muledump.totals.config.getKey('slotSubOrder')); + var disabled = $.extend(true, [], setuptools.app.muledump.totals.config.getKey('disabled')); + var sortingMode = setuptools.app.muledump.totals.config.getKey('sortingMode'); + if ( setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) setuptools.data.muledump.totals.configSets.settings[name] = {}; + setuptools.config.totalsSaveKeys.filter(function(item) { + setuptools.data.muledump.totals.configSets.settings[name][item] = setuptools.data.options[item]; + }); + var origName = setuptools.data.muledump.totals.configSets.active; + setuptools.data.muledump.totals.configSets.active = name; + setuptools.app.muledump.totals.config.setKey('accountFilter', accountFilter); + setuptools.app.muledump.totals.config.setKey('slotOrder', slotOrder); + setuptools.app.muledump.totals.config.setKey('itemFilter', itemFilter); + setuptools.app.muledump.totals.config.setKey('slotSubOrder', slotSubOrder); + setuptools.app.muledump.totals.config.setKey('sortingMode', sortingMode); + setuptools.app.muledump.totals.config.setKey('disabled', disabled); + setuptools.app.config.save('Totals config set saved', (immediate !== true)); + setuptools.copy.totals.configSets.settings[name] = $.extend(true, {}, setuptools.data.muledump.totals.configSets.settings[name]); + if ( name !== origName ) setuptools.app.muledump.totals.config.reset(origName); + window.options_save(); + setuptools.app.muledump.totals.config.backup(name); + +}; + +/** + * @function + * @param {string} [name] + * Resets the specified configSet to its previous save state without changing the UI + */ +setuptools.app.muledump.totals.config.reset = function(name) { + + if ( typeof name === 'undefined' || name === 'active' ) name = setuptools.data.muledump.totals.configSets.active || 'Default'; + if ( typeof name !== 'string' ) return; + if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; + setuptools.data.muledump.totals.configSets.settings[name] = $.extend(true, {}, setuptools.copy.totals.configSets && setuptools.copy.totals.configSets.settings[name] || setuptools.copy.totals.defaultConfig); + +}; + +/** + * @function + * @param {string} [name] + * @param {boolean} [reset] + * @param {boolean} [skipSave] + * Activate a totals configSet and optionally reset its state + */ +setuptools.app.muledump.totals.config.activate = function(name, reset, skipSave) { + + if ( typeof name === 'boolean' ) { + reset = name; + name = undefined; + } + + if ( typeof name === 'undefined' || name === 'active' ) name = setuptools.data.muledump.totals.configSets.active || 'Default'; + if ( typeof name !== 'string' ) return; + if ( typeof setuptools.data.muledump.totals.configSets.settings[name] !== 'object' ) return; + + // reset from original configuration + if ( reset === true ) setuptools.app.muledump.totals.config.reset(name); + + // reset keys for default profile + if ( name === 'Default' ) { + setuptools.data.muledump.totals.configSets.settings[name] = $.extend(true, {}, setuptools.copy.totals.defaultConfig); + setuptools.data.muledump.totals.configSets.settings[name].sortingMode = setuptools.copy.totals.defaultConfig.sortingMode; + } + + // reset keys + Object.filter(setuptools.data.muledump.totals.configSets.settings[name], function(key) { + setuptools.data.options[key] = setuptools.data.muledump.totals.configSets.settings[name][key]; + }); + + setuptools.data.muledump.totals.configSets.active = name; + if ( skipSave !== true ) setuptools.app.config.save('Totals config set activated'); + if ( setuptools.tmp.globalTotalsCounter instanceof Muledump_TotalsCounter ) setuptools.tmp.globalTotalsCounter.import(); + setuptools.app.muledump.totals.updateSecondaryFilter(); + window.init_totals(); + window.update_totals(); + window.update_filter(); + +}; + +/** + * @function + * @returns {Array} + * Return a list of item types + */ +setuptools.app.muledump.totals.config.getTypes = function() { + + var types = []; + Object.filter(window.itemsSlotTypeMap, function(type) { + if ( types.indexOf(type) === -1 ) types.push(type); + }); + return types; + +}; + +/** + * @function + * @param vst + * Returns a list of items by virtualSlotType + */ +setuptools.app.muledump.itemsByVst = function(vst) { + + if ( typeof vst === 'string' ) vst = setuptools.app.muledump.itemSlotTypeVst(vst); + if ( typeof vst !== 'number' ) return []; + var itemList = []; + Object.filter(window.items, function(itemid, item) { + if ( + item[setuptools.config.vstIndex] === vst && + !(item[3] === 40 && item[4] === 0) && + setuptools.config.disqualifiedItemIds.indexOf(+itemid) === -1 + ) itemList.push(itemid); + }); + return itemList; + +}; + +/** + * @function + * @param {string} name + * Return the virtualSlotType of a named item group + */ +setuptools.app.muledump.itemSlotTypeVst = function(name) { + + if ( typeof window.itemsSlotTypeMap[name] === 'undefined' ) return; + return window.itemsSlotTypeMap[name].virtualSlotType || window.itemsSlotTypeMap[name].slotType; + +}; + +/** + * @function + * @param {number} vst + * @returns {*} + * Determine the display name of a provided type name, slotType, or virtualSlotType + */ +setuptools.app.muledump.itemSlotTypeName = function(vst) { + + var type = Object.filter(window.itemsSlotTypeMap, undefined, function(type, data) { + if ( vst === type || data.virtualSlotType === vst || data.slotType === vst ) return data.displayName || type[0].toUpperCase()+type.substr(1); + }); + return type[Object.keys(type)[0]]; + +}; + +/** + * @function + * @param {number} type + * @returns {*} + * Map item SlotType to a virtual id format + */ +setuptools.app.muledump.itemsSlotTypeMapper = function(type) { + + if ( typeof Number(type) === 'number' ) var itemid = Number(type); + + // mapConfig identifier keys and their corresponding index in constants + var mapKeys = { + name: 0, + slotType: 1, + tier: 2, + fameBonus: 5, + feedPower: 6, + bagType: 7, + soulbound: 8, + utst: 9 + }; + + var mapConfig = window.itemsSlotTypeMap; + var itemList = items; + if ( typeof itemid === 'number' ) { + + itemList = {}; + itemList[itemid] = window.items[itemid]; + + } + + var filteredItems = Object.filter(itemList, undefined, function(itemid, item) { + + if ( typeof item === 'undefined' ) return; + + var slotType = item[1]; + var virtualSlotType; + var configKeys = Object.keys(Object.filter(mapConfig, function(type, data) { + if ( data.slotType === slotType ) { + if ( typeof data.sheet === 'undefined' ) data.sheet = setuptools.config.totalsDefaultIcon; + return true; + } + })); + + for ( var x = 0; x < configKeys.length; x++ ) { + + var configKey = configKeys[x]; + + if ( typeof mapConfig[configKey] === 'undefined' ) { + setuptools.app.techlog('SlotTypeMapper encountered unknown slotType - ' + JSON.stringify(configKey)); + continue; + } + + virtualSlotType = undefined; + var matches = 0; + var required = Object.keys(mapConfig[configKey]).length; + for (var key in mapConfig[configKey]) { + + if (mapConfig[configKey].hasOwnProperty(key)) { + + // reserved properties; not checked against + if ( ['displayName', 'sheet'].indexOf(key) > -1 ) { + matches++; + continue; + } + + if ( key === 'slotType' && typeof virtualSlotType !== 'string' ) virtualSlotType = mapConfig[configKey].virtualSlotType; + + if ( key === 'virtualSlotType' ) { + virtualSlotType = mapConfig[configKey].virtualSlotType; + matches++; + continue; + } + + // values must match + if ( + ['number', 'boolean'].indexOf(typeof mapConfig[configKey][key]) > -1 && + mapConfig[configKey][key] !== item[mapKeys[key]] + ) continue; + + // try and include items but not require them to match (like name key) + if ( key === 'include' ) { + + if ( + mapConfig[configKey][key] instanceof RegExp && + item[mapKeys.name].match(mapConfig[configKey][key]) + ) { + matches = required; + } else { + required--; + } + continue; + } + + // some groups have multiple values for one key (I'm looking at you potions) + if ( + Array.isArray(mapConfig[configKey][key]) === true && + mapConfig[configKey][key].indexOf(item[mapKeys[key]]) === -1 + ) continue; + + if ( + mapConfig[configKey][key] instanceof RegExp && + !item[mapKeys[key]].match(mapConfig[configKey][key]) + ) continue; + + // support multiple gt/gte/lt/lte operations + if ( + Array.isArray(mapConfig[configKey][key]) === false && + !(mapConfig[configKey][key] instanceof RegExp) && + typeof mapConfig[configKey][key] === 'object' + ) { + + var foundCommands = 0; + var matchedCommands = 0; + for ( var command in mapConfig[configKey][key] ) { + + if ( mapConfig[configKey][key].hasOwnProperty(command) ) { + + foundCommands++; + var value = mapConfig[configKey][key][command]; + if ( + (command === 'gte' && item[mapKeys[key]] >= value) || + (command === 'gt' && item[mapKeys[key]] > value) || + (command === 'lte' && item[mapKeys[key]] <= value) || + (command === 'lt' && item[mapKeys[key]] < value) + ) matchedCommands++; + + } + + } + + if ( foundCommands !== matchedCommands ) continue; + + } + + matches++; + + } + + } + + if ( matches >= required ) return virtualSlotType || slotType; + + } + + }); + + var filteredValues = Object.values(filteredItems); + if ( typeof itemid === 'number' && filteredValues.length === 0 ) return 50000; + if ( filteredValues.length === 1 ) return filteredValues[0]; + return filteredItems; + +}; + +/** + * @function + * Update all secondary filters for totals processing + */ +setuptools.app.muledump.totals.updateSecondaryFilter = function() { + + // reset accountFilter and disabled filter on mules + for ( var guid in mules ) { + if (mules.hasOwnProperty(guid)) { + + // accountFilter + if ( setuptools.app.muledump.totals.config.getKey('accountFilter').indexOf(guid) === -1 ) { + mules[guid].dom.removeClass('filteringEnabled'); + } else { + mules[guid].dom.addClass('filteringEnabled'); + } + + // disabled filter + mules[guid].disabled = ( setuptools.app.muledump.totals.config.getKey('disabled').indexOf(guid) > -1 ); + mules[guid].dom.toggleClass('disabled', mules[guid].disabled); + if ( mules[guid].disabled === true ) { + setuptools.tmp.globalTotalsCounter.import(mules[guid].totals, true); + } else { + + // we'll only run this if it'll pass mode 0 + if ( + typeof setuptools.tmp.globalTotalsCounter.sourceData[guid] !== 'object' || + new SeaSalt_Hashing(JSON.stringify(setuptools.tmp.globalTotalsCounter.sourceData[guid].meta), 'sha256', 'hex').toString() !== new SeaSalt_Hashing(JSON.stringify(mules[guid].totals.data.meta), 'sha256', 'hex').toString() + ) setuptools.tmp.globalTotalsCounter.import(mules[guid].totals); + + } + + } + } + + // insert generated totals save keys if they aren't already there + // note: doing this by key count is probably not as good a choice as doing it by key validation. + // this would be the place to add/remove key changes. + if ( setuptools.config.totalsSaveKeys.length <= setuptools.config.totalsFilterKeysIndex ) { + Object.keys(window.itemsSlotTypeMap).filter(function(element) { + setuptools.config.totalsSaveKeys.push('totalsFilter-' + element); + }); + setuptools.app.muledump.totals.config.activate(true); + } + + // populate any missing filter keys in options + for ( var h = 0; h < setuptools.config.totalsSaveKeys.length; h++ ) + if ( typeof setuptools.data.options[setuptools.config.totalsSaveKeys[h]] === 'undefined' ) + setuptools.data.options[setuptools.config.totalsSaveKeys[h]] = true; + + // generate the secondary item filter + setuptools.tmp.totalsSecondaryFilter = []; + for ( var i = setuptools.config.totalsFilterKeysIndex; i < setuptools.config.totalsSaveKeys.length; i++ ) { + + var key = setuptools.config.totalsSaveKeys[i]; + var type = (key.match(/^.*?-([a-z0-9]*)$/i))[1]; + var vstList = setuptools.app.muledump.itemSlotTypeVst(type); + if ( typeof vstList !== 'number' ) vstList = [50000]; + if ( typeof vstList === 'number' ) vstList = [vstList]; + + // rather than build this every call, let's cache the object given it is static anyway + if ( typeof setuptools.tmp.totalsRuntimeCache === 'undefined') setuptools.tmp.totalsRuntimeCache = {}; + if ( typeof setuptools.tmp.totalsRuntimeCache[type] === 'undefined' ) setuptools.tmp.totalsRuntimeCache[type] = []; + + Object.filter( + window.items, + function(itemid, item) { + for ( var i = 0; i < vstList.length; i++ ) + if ( item[setuptools.config.vstIndex] === vstList[i] ) setuptools.tmp.totalsRuntimeCache[type].push(Number(itemid)); + } + ); + + // process the item list + var itemList = setuptools.tmp.totalsRuntimeCache[type]; + var j; + if ( setuptools.data.options[key] === true ) { + + for ( j = 0; j < itemList.length; j++ ) + if ( setuptools.tmp.totalsSecondaryFilter.indexOf(itemList[j]) > -1 ) + setuptools.tmp.totalsSecondaryFilter.splice(setuptools.tmp.totalsSecondaryFilter.indexOf(itemList[j]), 1); + + } else { + + for ( j = 0; j < itemList.length; j++ ) + if ( setuptools.tmp.totalsSecondaryFilter.indexOf(itemList[j]) === -1 ) + setuptools.tmp.totalsSecondaryFilter.push(itemList[j]); + + } + + } + +}; + +/** + * @function + * @param {number} itemid + * Toggle the item in and out of the itemFilter + */ +setuptools.app.muledump.totals.toggleHideItem = function(itemid) { + + itemid = Number(itemid); + var index = setuptools.app.muledump.totals.config.getKey('itemFilter').indexOf(itemid); + if ( index === -1 ) { + setuptools.app.muledump.totals.config.getKey('itemFilter').push(itemid); + } else setuptools.app.muledump.totals.config.getKey('itemFilter').splice(index, 1); + setuptools.app.muledump.totals.config.setKey('itemFilter', setuptools.app.muledump.totals.config.getKey('itemFilter')); + window.update_totals(); + window.update_filter(); + option_updated('totals'); + +}; diff --git a/lib/setuptools/src/upgrade.js b/lib/setuptools/src/upgrade.js index 453e4b24..815b1d9a 100644 --- a/lib/setuptools/src/upgrade.js +++ b/lib/setuptools/src/upgrade.js @@ -124,7 +124,6 @@ setuptools.app.upgrade.seek = function() { if ( accountsUpgrade === true ) { - autoBackup = setuptools.app.config.backup(true, true); for ( var i in setuptools.data.accounts.accounts ) { if (setuptools.data.accounts.accounts.hasOwnProperty(i)) { @@ -147,15 +146,53 @@ setuptools.app.upgrade.seek = function() { } /* - // upgrade animations key for preview users (deprecated; will remove soon) + // upgrade whitebag tracker object format (v9.5 preview dev change) */ - if ( typeof setuptools.data.config.animations === 'boolean' ) { - setuptools.data.config.animations = ( setuptools.data.config.animations === true ) ? 1 : 0; - window.techlog('SetupTools/ClientConfig upgraded animations to new key format', 'force'); + if ( + typeof setuptools.data.muledump.whitebagTracker === 'object' && + typeof setuptools.data.muledump.whitebagTracker.format === 'undefined' + ) { + + setuptools.data.muledump.whitebagTracker.format = 1; + Object.filter(setuptools.data.muledump.whitebagTracker.accounts, function(guid, data) { + + delete setuptools.data.muledump.whitebagTracker.accounts[guid].totals; + setuptools.data.muledump.whitebagTracker.accounts[guid].owned = []; + + }); + + window.techlog('SetupTools/ClientConfig upgraded whitebags to format 1', 'force'); + saveCount++; } + /* + // upgrade wardrobe config silently + */ + Object.keys(setuptools.data.accounts.accounts).filter(function(guid) { + + // make the object for the first time + if ( typeof setuptools.data.muledump.wardrobe.accounts[guid] === 'undefined' ) { + + setuptools.data.muledump.wardrobe.accounts[guid] = $.extend(true, {}, setuptools.objects.wardrobeConfig); + + } else { + + // upgrade the object if there is a new format + if ( + !setuptools.data.muledump.wardrobe.accounts[guid].format || + setuptools.data.muledump.wardrobe.accounts[guid].format < setuptools.objects.wardrobeConfig.format + ) { + setuptools.data.muledump.wardrobe.accounts[guid] = $.extend(true, setuptools.objects.wardrobeConfig, setuptools.data.muledump.wardrobe.accounts[guid]); + window.techlog('SetupTools/ClientConfig upgraded wardrobe to format ' + setuptools.objects.wardrobeConfig.format, 'force'); + saveCount++; + } + + } + + }); + /* // upgrade accounts meta data for encryption */ @@ -163,11 +200,14 @@ setuptools.app.upgrade.seek = function() { if ( typeof setuptools.data.accounts.meta.encryptionTestKey === 'undefined' ) setuptools.data.accounts.meta.encryptionTestKey = ''; // save if any upgrades request a save - if ( saveCount > 0 ) - if ( autoBackup.status === true ) { + if ( saveCount > 0 ) { + + autoBackup = setuptools.app.config.backup(true, true); + if (autoBackup.status === true) { setuptools.app.config.save('SetupTools/ClientConfig updated ' + saveCount + ' keys'); - } else - window.techlog('SetupTools/ClientConfig not saving accounts upgrade due to auto backup error', 'force'); + } else window.techlog('SetupTools/ClientConfig not saving accounts upgrade due to auto backup error', 'force'); + + } // check for new muledump version and upgrade ClientConfig to new version number // On Muledump Online - display version update notice conditionally diff --git a/lib/slotmap.js b/lib/slotmap.js index 09e63a68..7de8d1c9 100644 --- a/lib/slotmap.js +++ b/lib/slotmap.js @@ -265,6 +265,7 @@ var itemsSlotTypeMap = { scepters: {slotType: 23, sheet: [880, 0]}, katanas: {slotType: 24, sheet: [360, 0]}, stars: {slotType: 25, sheet: [920, 0]}, - eggs: {slotType: 26, sheet: [840, 40]} + eggs: {slotType: 26, sheet: [840, 40]}, + wakis: {slotType: 27, sheet: [920, 40]} }; window.itemsSlotTypeMap = itemsSlotTypeMap; diff --git a/muledump.html b/muledump.html index a298644a..9e5a213e 100644 --- a/muledump.html +++ b/muledump.html @@ -11,7 +11,7 @@ - + @@ -39,6 +39,8 @@ + + diff --git a/package.json b/package.json index 74b5183c..8ee8354a 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "Muledump", - "version": "9.4.0", + "version": "9.5.0", "description": "A utility for managing all of your ROTMG mules.", "homepage": "https://jakcodex.github.io/muledump/", "dependencies": { "jquery": "git://github.com/jquery/jquery.git^3.3.1", - "clipboard": "git://github.com/zenorocha/clipboard.js.git^1.7.1", - "masonry-layout": "git://github.com/desandro/masonry.git^4.2.0", + "clipboard": "git://github.com/zenorocha/clipboard.js.git^2.0.0", + "masonry-layout": "git://github.com/desandro/masonry.git^4.2.2", "featherlight": "git://github.com/noelboss/featherlight.git^1.7.8", "html2canvas": "git://github.com/niklasvh/html2canvas.git^1.0.0", "libsodium.js": "git://github.com/jedisct1/libsodium.js.git^0.7.3", diff --git a/privacy-policy.md b/privacy-policy.md index 4705052a..581a17ba 100644 --- a/privacy-policy.md +++ b/privacy-policy.md @@ -1,4 +1,5 @@ ### Effective Date: December 20, 2017 +##### Modified: September 26, 2018 Thank you for choosing and trusting Jakcodex/Muledump. Traditionally no information at all has been collected and with the introduction of Usage Analytics we want to be absolutely clear about what it means for you. @@ -16,7 +17,7 @@ This version is eligible to participate in Usage Analytics which can be disabled #### Muledump CORS Adapter -The Chrome web store extension does not collect any usage analytics or any other sort of data. +The Chrome web store extension and Firefox addon do not collect any usage analytics or any other sort of data. ## About Usage Analytics in Jakcodex/Muledump diff --git a/user-config.js b/user-config.js index 29056a0c..a22e3519 100644 --- a/user-config.js +++ b/user-config.js @@ -13,6 +13,11 @@ // */ +/* +// Required to enable feature +*/ +userConfiguration.enabled = true; + /* // SetupTools Client Configuration */ diff --git a/vendor/html2canvas.min.js b/vendor/html2canvas.min.js index 57c8518c..be7d72af 100644 --- a/vendor/html2canvas.min.js +++ b/vendor/html2canvas.min.js @@ -1,6 +1,6 @@ /*! - * html2canvas 1.0.0-alpha.5 - * Copyright (c) 2017 Niklas von Hertzen + * html2canvas 1.0.0-alpha.11 + * Copyright (c) 2018 Niklas von Hertzen * Released under MIT License */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.html2canvas=t():e.html2canvas=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,t),a.l=!0,a.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=24)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,a=!1,o=void 0;try{for(var i,u=e[Symbol.iterator]();!(r=(i=u.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){a=!0,o=e}finally{try{!r&&u.return&&u.return()}finally{if(a)throw o}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),a=function(){function e(e,t){for(var n=0;n4)&&[Number(t[1]),Number(t[2]),Number(t[3]),Number(t[4])]},h=function(e){return[Math.min(e[0],255),Math.min(e[1],255),Math.min(e[2],255),e.length>3?e[3]:null]},p=function(e){var t=E[e.toLowerCase()];return t||!1},g=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e);var n=Array.isArray(t)?h(t):i(t)||c(t)||f(t)||p(t)||l(t)||[0,0,0,null],a=r(n,4),o=a[0],u=a[1],s=a[2],d=a[3];this.r=o,this.g=u,this.b=s,this.a=d}return a(e,[{key:"isTransparent",value:function(){return 0===this.a}},{key:"toString",value:function(){return null!==this.a&&1!==this.a?"rgba("+this.r+","+this.g+","+this.b+","+this.a+")":"rgb("+this.r+","+this.g+","+this.b+")"}}]),e}();t.default=g;var E={transparent:[0,0,0,0],aliceblue:[240,248,255,null],antiquewhite:[250,235,215,null],aqua:[0,255,255,null],aquamarine:[127,255,212,null],azure:[240,255,255,null],beige:[245,245,220,null],bisque:[255,228,196,null],black:[0,0,0,null],blanchedalmond:[255,235,205,null],blue:[0,0,255,null],blueviolet:[138,43,226,null],brown:[165,42,42,null],burlywood:[222,184,135,null],cadetblue:[95,158,160,null],chartreuse:[127,255,0,null],chocolate:[210,105,30,null],coral:[255,127,80,null],cornflowerblue:[100,149,237,null],cornsilk:[255,248,220,null],crimson:[220,20,60,null],cyan:[0,255,255,null],darkblue:[0,0,139,null],darkcyan:[0,139,139,null],darkgoldenrod:[184,134,11,null],darkgray:[169,169,169,null],darkgreen:[0,100,0,null],darkgrey:[169,169,169,null],darkkhaki:[189,183,107,null],darkmagenta:[139,0,139,null],darkolivegreen:[85,107,47,null],darkorange:[255,140,0,null],darkorchid:[153,50,204,null],darkred:[139,0,0,null],darksalmon:[233,150,122,null],darkseagreen:[143,188,143,null],darkslateblue:[72,61,139,null],darkslategray:[47,79,79,null],darkslategrey:[47,79,79,null],darkturquoise:[0,206,209,null],darkviolet:[148,0,211,null],deeppink:[255,20,147,null],deepskyblue:[0,191,255,null],dimgray:[105,105,105,null],dimgrey:[105,105,105,null],dodgerblue:[30,144,255,null],firebrick:[178,34,34,null],floralwhite:[255,250,240,null],forestgreen:[34,139,34,null],fuchsia:[255,0,255,null],gainsboro:[220,220,220,null],ghostwhite:[248,248,255,null],gold:[255,215,0,null],goldenrod:[218,165,32,null],gray:[128,128,128,null],green:[0,128,0,null],greenyellow:[173,255,47,null],grey:[128,128,128,null],honeydew:[240,255,240,null],hotpink:[255,105,180,null],indianred:[205,92,92,null],indigo:[75,0,130,null],ivory:[255,255,240,null],khaki:[240,230,140,null],lavender:[230,230,250,null],lavenderblush:[255,240,245,null],lawngreen:[124,252,0,null],lemonchiffon:[255,250,205,null],lightblue:[173,216,230,null],lightcoral:[240,128,128,null],lightcyan:[224,255,255,null],lightgoldenrodyellow:[250,250,210,null],lightgray:[211,211,211,null],lightgreen:[144,238,144,null],lightgrey:[211,211,211,null],lightpink:[255,182,193,null],lightsalmon:[255,160,122,null],lightseagreen:[32,178,170,null],lightskyblue:[135,206,250,null],lightslategray:[119,136,153,null],lightslategrey:[119,136,153,null],lightsteelblue:[176,196,222,null],lightyellow:[255,255,224,null],lime:[0,255,0,null],limegreen:[50,205,50,null],linen:[250,240,230,null],magenta:[255,0,255,null],maroon:[128,0,0,null],mediumaquamarine:[102,205,170,null],mediumblue:[0,0,205,null],mediumorchid:[186,85,211,null],mediumpurple:[147,112,219,null],mediumseagreen:[60,179,113,null],mediumslateblue:[123,104,238,null],mediumspringgreen:[0,250,154,null],mediumturquoise:[72,209,204,null],mediumvioletred:[199,21,133,null],midnightblue:[25,25,112,null],mintcream:[245,255,250,null],mistyrose:[255,228,225,null],moccasin:[255,228,181,null],navajowhite:[255,222,173,null],navy:[0,0,128,null],oldlace:[253,245,230,null],olive:[128,128,0,null],olivedrab:[107,142,35,null],orange:[255,165,0,null],orangered:[255,69,0,null],orchid:[218,112,214,null],palegoldenrod:[238,232,170,null],palegreen:[152,251,152,null],paleturquoise:[175,238,238,null],palevioletred:[219,112,147,null],papayawhip:[255,239,213,null],peachpuff:[255,218,185,null],peru:[205,133,63,null],pink:[255,192,203,null],plum:[221,160,221,null],powderblue:[176,224,230,null],purple:[128,0,128,null],rebeccapurple:[102,51,153,null],red:[255,0,0,null],rosybrown:[188,143,143,null],royalblue:[65,105,225,null],saddlebrown:[139,69,19,null],salmon:[250,128,114,null],sandybrown:[244,164,96,null],seagreen:[46,139,87,null],seashell:[255,245,238,null],sienna:[160,82,45,null],silver:[192,192,192,null],skyblue:[135,206,235,null],slateblue:[106,90,205,null],slategray:[112,128,144,null],slategrey:[112,128,144,null],snow:[255,250,250,null],springgreen:[0,255,127,null],steelblue:[70,130,180,null],tan:[210,180,140,null],teal:[0,128,128,null],thistle:[216,191,216,null],tomato:[255,99,71,null],turquoise:[64,224,208,null],violet:[238,130,238,null],wheat:[245,222,179,null],white:[255,255,255,null],whitesmoke:[245,245,245,null],yellow:[255,255,0,null],yellowgreen:[154,205,50,null]};t.TRANSPARENT=new g([0,0,0,0])},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.parseBoundCurves=t.calculatePaddingBoxPath=t.calculateBorderBoxPath=t.parsePathForBorder=t.parseDocumentSize=t.calculateContentBox=t.calculatePaddingBox=t.parseBounds=t.Bounds=void 0;var a=function(){function e(e,t){for(var n=0;n0||u>0?c(e.left,e.top,i,u,s.TOP_LEFT):new o.default(e.left,e.top),topLeftInner:i>0||u>0?c(e.left+t[3].borderWidth,e.top+t[0].borderWidth,Math.max(0,i-t[3].borderWidth),Math.max(0,u-t[0].borderWidth),s.TOP_LEFT):new o.default(e.left+t[3].borderWidth,e.top+t[0].borderWidth),topRightOuter:l>0||d>0?c(e.left+E,e.top,l,d,s.TOP_RIGHT):new o.default(e.left+e.width,e.top),topRightInner:l>0||d>0?c(e.left+Math.min(E,e.width+t[3].borderWidth),e.top+t[0].borderWidth,E>e.width+t[3].borderWidth?0:l-t[3].borderWidth,d-t[0].borderWidth,s.TOP_RIGHT):new o.default(e.left+e.width-t[1].borderWidth,e.top+t[0].borderWidth),bottomRightOuter:f>0||h>0?c(e.left+T,e.top+m,f,h,s.BOTTOM_RIGHT):new o.default(e.left+e.width,e.top+e.height),bottomRightInner:f>0||h>0?c(e.left+Math.min(T,e.width-t[3].borderWidth),e.top+Math.min(m,e.height+t[0].borderWidth),Math.max(0,f-t[1].borderWidth),h-t[2].borderWidth,s.BOTTOM_RIGHT):new o.default(e.left+e.width-t[1].borderWidth,e.top+e.height-t[2].borderWidth),bottomLeftOuter:p>0||g>0?c(e.left,e.top+y,p,g,s.BOTTOM_LEFT):new o.default(e.left,e.top+e.height),bottomLeftInner:p>0||g>0?c(e.left+t[3].borderWidth,e.top+y,Math.max(0,p-t[3].borderWidth),g-t[2].borderWidth,s.BOTTOM_LEFT):new o.default(e.left+t[3].borderWidth,e.top+e.height-t[2].borderWidth)}},{TOP_LEFT:0,TOP_RIGHT:1,BOTTOM_RIGHT:2,BOTTOM_LEFT:3}),c=function(e,t,n,r,a){var u=(Math.sqrt(2)-1)/3*4,l=n*u,c=r*u,d=e+n,f=t+r;switch(a){case s.TOP_LEFT:return new i.default(new o.default(e,f),new o.default(e,f-c),new o.default(d-l,t),new o.default(d,t));case s.TOP_RIGHT:return new i.default(new o.default(e,t),new o.default(e+l,t),new o.default(d,f-c),new o.default(d,f));case s.BOTTOM_RIGHT:return new i.default(new o.default(d,t),new o.default(d,t+c),new o.default(e+l,f),new o.default(e,f));case s.BOTTOM_LEFT:default:return new i.default(new o.default(d,f),new o.default(d-l,f),new o.default(e,t+c),new o.default(e,t))}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.calculateLengthFromValueWithUnit=t.LENGTH_TYPE=void 0;var r=function(){function e(e,t){for(var n=0;n=0;n--){var r=e.item(n);"content"!==r&&t.style.setProperty(r,e.getPropertyValue(r))}return t},t.SMALL_IMAGE="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n0&&this.style.visibility===I.VISIBILITY.VISIBLE}},{key:"isAbsolutelyPositioned",value:function(){return this.style.position!==m.POSITION.STATIC&&this.style.position!==m.POSITION.RELATIVE}},{key:"isPositioned",value:function(){return this.style.position!==m.POSITION.STATIC}},{key:"isFloating",value:function(){return this.style.float!==c.FLOAT.NONE}},{key:"isRootElement",value:function(){return null===this.parent}},{key:"isTransformed",value:function(){return null!==this.style.transform}},{key:"isPositionedWithZIndex",value:function(){return this.isPositioned()&&!this.style.zIndex.auto}},{key:"isInlineLevel",value:function(){return(0,o.contains)(this.style.display,s.DISPLAY.INLINE)||(0,o.contains)(this.style.display,s.DISPLAY.INLINE_BLOCK)||(0,o.contains)(this.style.display,s.DISPLAY.INLINE_FLEX)||(0,o.contains)(this.style.display,s.DISPLAY.INLINE_GRID)||(0,o.contains)(this.style.display,s.DISPLAY.INLINE_LIST_ITEM)||(0,o.contains)(this.style.display,s.DISPLAY.INLINE_TABLE)}},{key:"isInlineBlockOrInlineTable",value:function(){return(0,o.contains)(this.style.display,s.DISPLAY.INLINE_BLOCK)||(0,o.contains)(this.style.display,s.DISPLAY.INLINE_TABLE)}}]),e}();t.default=L;var R=function(e,t){if(e instanceof e.ownerDocument.defaultView.SVGSVGElement||e instanceof SVGSVGElement){var n=new XMLSerializer;return t.loadImage("data:image/svg+xml,"+encodeURIComponent(n.serializeToString(e)))}switch(e.tagName){case"IMG":var r=e;return t.loadImage(r.currentSrc||r.src);case"CANVAS":var a=e;return t.loadCanvas(a);case"IFRAME":var o=e.getAttribute("data-html2canvas-internal-iframe-key");if(o)return o}return null}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.parseBackgroundImage=t.parseBackground=t.calculateBackgroundRepeatPath=t.calculateBackgroundPosition=t.calculateBackgroungPositioningArea=t.calculateBackgroungPaintingArea=t.calculateGradientBackgroundSize=t.calculateBackgroundSize=t.BACKGROUND_ORIGIN=t.BACKGROUND_CLIP=t.BACKGROUND_SIZE=t.BACKGROUND_REPEAT=void 0;var a=r(n(0)),o=r(n(2)),i=r(n(28)),u=r(n(7)),l=n(1),s=n(14),c=t.BACKGROUND_REPEAT={REPEAT:0,NO_REPEAT:1,REPEAT_X:2,REPEAT_Y:3},d=t.BACKGROUND_SIZE={AUTO:0,CONTAIN:1,COVER:2,LENGTH:3},f=t.BACKGROUND_CLIP={BORDER_BOX:0,PADDING_BOX:1,CONTENT_BOX:2},h=t.BACKGROUND_ORIGIN=f,p=function e(t){switch(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),t){case"contain":this.size=d.CONTAIN;break;case"cover":this.size=d.COVER;break;case"auto":this.size=d.AUTO;break;default:this.value=new o.default(t)}},g=(t.calculateBackgroundSize=function(e,t,n){var r=0,a=0,o=e.size;if(o[0].size===d.CONTAIN||o[0].size===d.COVER){var u=n.width/n.height,l=t.width/t.height;return u0&&(e=a.substr(0,t).toLowerCase(),a=a.substr(t)),"none"!==(a=a.toLowerCase())&&n.push({prefix:e,method:a,args:r})}r=[],a=i=""};return e.split("").forEach(function(e){if(0!==u||!t.test(e)){switch(e){case'"':o?o===e&&(o=null):o=e;break;case"(":if(o)break;if(0===u)return void(u=1);l++;break;case")":if(o)break;if(1===u){if(0===l)return u=0,void s();l--}break;case",":if(o)break;if(0===u)return void s();if(1===u&&0===l&&!a.match(/^url$/i))return r.push(i.trim()),void(i="")}0===u?a+=e:i+=e}}),s(),n}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PATH={VECTOR:0,BEZIER_CURVE:1,CIRCLE:2}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(6);t.default=function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.type=r.PATH.VECTOR,this.x=t,this.y=n}},function(e,t,n){"use strict";function r(e,t,n){return e.length>0?t+n.toUpperCase():e}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n";try{r.drawImage(t,0,0),n.toDataURL()}catch(e){return!1}return!0}(document);return Object.defineProperty(o,"SUPPORT_SVG_DRAWING",{value:e}),e},get SUPPORT_BASE64_DRAWING(){return function(e){var t=function(e,t){var n=new Image,r=e.createElement("canvas"),a=r.getContext("2d");return new Promise(function(e){n.src=t;var o=function(){try{a.drawImage(n,0,0),r.toDataURL()}catch(t){return e(!1)}return e(!0)};n.onload=o,n.onerror=function(){return e(!1)},!0===n.complete&&setTimeout(function(){o()},500)})}(document,e);return Object.defineProperty(o,"SUPPORT_BASE64_DRAWING",{value:function(){return t}}),t}},get SUPPORT_FOREIGNOBJECT_DRAWING(){var e="function"==typeof Array.from&&"function"==typeof window.fetch?function(e){var t=e.createElement("canvas");t.width=100,t.height=100;var n=t.getContext("2d");n.fillStyle="rgb(0, 255, 0)",n.fillRect(0,0,100,100);var o=new Image,i=t.toDataURL();o.src=i;var u=(0,r.createForeignObjectSVG)(100,100,0,0,o);return n.fillStyle="red",n.fillRect(0,0,100,100),(0,r.loadSerializedSVG)(u).then(function(t){n.drawImage(t,0,0);var o=n.getImageData(0,0,100,100).data;n.fillStyle="red",n.fillRect(0,0,100,100);var u=e.createElement("div");return u.style.backgroundImage="url("+i+")",u.style.height="100px",a(o)?(0,r.loadSerializedSVG)((0,r.createForeignObjectSVG)(100,100,0,0,u)):Promise.reject(!1)}).then(function(e){return n.drawImage(e,0,0),a(n.getImageData(0,0,100,100).data)}).catch(function(e){return!1})}(document):Promise.resolve(!1);return Object.defineProperty(o,"SUPPORT_FOREIGNOBJECT_DRAWING",{value:e}),e},get SUPPORT_CORS_IMAGES(){var e=void 0!==(new Image).crossOrigin;return Object.defineProperty(o,"SUPPORT_CORS_IMAGES",{value:e}),e},get SUPPORT_RESPONSE_TYPE(){var e="string"==typeof(new XMLHttpRequest).responseType;return Object.defineProperty(o,"SUPPORT_RESPONSE_TYPE",{value:e}),e},get SUPPORT_CORS_XHR(){var e="withCredentials"in new XMLHttpRequest;return Object.defineProperty(o,"SUPPORT_CORS_XHR",{value:e}),e}};t.default=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.parseTextDecoration=t.TEXT_DECORATION_LINE=t.TEXT_DECORATION=t.TEXT_DECORATION_STYLE=void 0;var r=function(e){return e&&e.__esModule?e:{default:e}}(n(0)),a=t.TEXT_DECORATION_STYLE={SOLID:0,DOUBLE:1,DOTTED:2,DASHED:3,WAVY:4},o=t.TEXT_DECORATION={NONE:null},i=t.TEXT_DECORATION_LINE={UNDERLINE:1,OVERLINE:2,LINE_THROUGH:3,BLINK:4},u=function(e){switch(e){case"underline":return i.UNDERLINE;case"overline":return i.OVERLINE;case"line-through":return i.LINE_THROUGH}return i.BLINK};t.parseTextDecoration=function(e){var t=function(e){return"none"===e?null:e.split(" ").map(u)}(e.textDecorationLine?e.textDecorationLine:e.textDecoration);if(null===t)return o.NONE;return{textDecorationLine:t,textDecorationColor:e.textDecorationColor?new r.default(e.textDecorationColor):null,textDecorationStyle:function(e){switch(e){case"double":return a.DOUBLE;case"dotted":return a.DOTTED;case"dashed":return a.DASHED;case"wavy":return a.WAVY}return a.SOLID}(e.textDecorationStyle)}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.parseBorder=t.BORDER_SIDES=t.BORDER_STYLE=void 0;var r=function(e){return e&&e.__esModule?e:{default:e}}(n(0)),a=t.BORDER_STYLE={NONE:0,SOLID:1},o=t.BORDER_SIDES={TOP:0,RIGHT:1,BOTTOM:2,LEFT:3},i=Object.keys(o).map(function(e){return e.toLowerCase()});t.parseBorder=function(e){return i.map(function(t){var n=new r.default(e.getPropertyValue("border-"+t+"-color")),o=function(e){switch(e){case"none":return a.NONE}return a.SOLID}(e.getPropertyValue("border-"+t+"-style")),i=parseFloat(e.getPropertyValue("border-"+t+"-width"));return{borderColor:n,borderStyle:o,borderWidth:isNaN(i)?0:i}})}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;ne.height?(e.left+=(e.width-e.height)/2,e.width=e.height):e.width0&&o){var i=t.ownerDocument.createElement("html2canvaswrapper");(0,d.copyCSSStyles)(t.ownerDocument.defaultView.getComputedStyle(t,null),i),i.style.position="fixed",i.style.left=n.bounds.left+"px",i.style.top=n.bounds.top+"px",r||(i.style.whiteSpace="nowrap");var u=t.ownerDocument.createTextNode(e);i.appendChild(u),o.appendChild(i),n.childNodes.push(a.default.fromTextNode(u,n)),o.removeChild(i)}}),I=function(e){var t="password"===e.type?new Array(e.value.length+1).join("•"):e.value;return 0===t.length?e.placeholder||"":t}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.parseTextBounds=t.TextBounds=void 0;var r=n(41),a=n(1),o=n(10),i=function(e){return e&&e.__esModule?e:{default:e}}(n(9)),u=/[^\u0000-\u00ff]/,l=function(e){return r.ucs2.encode([e])},s=t.TextBounds=function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.text=t,this.bounds=n},c=(t.parseTextBounds=function(e,t,n){for(var a=r.ucs2.decode(e),h=0!==t.style.letterSpacing||function(e){return u.test(e)}(e)?a.map(l):f(a),p=h.length,g=n.parentNode?n.parentNode.ownerDocument.defaultView:null,E=g?g.pageXOffset:0,m=g?g.pageYOffset:0,T=[],y=0,v=0;v0)if(i.default.SUPPORT_RANGE_BOUNDS)T.push(new s(b,d(n,y,b.length,E,m)));else{var I=n.splitText(b.length);T.push(new s(b,c(n,E,m))),n=I}else i.default.SUPPORT_RANGE_BOUNDS||(n=n.splitText(b.length));y+=b.length}return T},function(e,t,n){var r=e.ownerDocument.createElement("html2canvaswrapper");r.appendChild(e.cloneNode(!0));var o=e.parentNode;if(o){o.replaceChild(r,e);var i=(0,a.parseBounds)(r,t,n);return r.firstChild&&o.replaceChild(r.firstChild,r),i}return new a.Bounds(0,0,0,0)}),d=function(e,t,n,r,o){var i=e.ownerDocument.createRange();return i.setStart(e,t),i.setEnd(e,t+n),a.Bounds.fromClientRect(i.getBoundingClientRect(),r,o)},f=function(e){for(var t=[],n=0,a=!1,o=void 0;e.length;)h(e[n])===a?((o=e.splice(0,n)).length&&t.push(r.ucs2.encode(o)),a=!a,n=0):n++,n>=e.length&&(o=e.splice(0,n)).length&&t.push(r.ucs2.encode(o));return t},h=function(e){return-1!==[32,13,10,9,45].indexOf(e)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n5&&void 0!==arguments[5]?arguments[5]:". ";return en?y(e,a):r.integers.reduce(function(t,n,a){for(;e>=n;)e-=n,t+=r.values[a];return t},"")+o},g=function(e,t,n,r){var a="";do{n||e--,a=r(e)+a,e/=t}while(e*t>=t);return a},E=function(e,t,n,r){var a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:". ",o=n-t+1;return(e<0?"-":"")+(g(Math.abs(e),o,r,function(e){return(0,l.fromCodePoint)(Math.floor(e%o)+t)})+a)},m=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:". ",r=t.length;return g(Math.abs(e),r,!1,function(e){return t[Math.floor(e%r)]})+n},T=function(e,t,n,r,o,i){if(e<-9999||e>9999)return y(e,u.LIST_STYLE_TYPE.CJK_DECIMAL);var l=Math.abs(e),s=o;if(0===l)return t[0]+s;for(var c=0;l>0&&c<=4;c++){var d=l%10;0===d&&(0,a.contains)(i,1)&&""!==s?s=t[d]+s:d>1||1===d&&0===c||1===d&&1===c&&(0,a.contains)(i,2)||1===d&&1===c&&(0,a.contains)(i,4)&&e>100||1===d&&c>1&&(0,a.contains)(i,8)?s=t[d]+(c>0?n[c-1]:"")+s:1===d&&c>0&&(s=n[c-1]+s),l=Math.floor(l/10)}return(e<0?r:"")+s},y=function(e,t){switch(t){case u.LIST_STYLE_TYPE.DISC:return"•";case u.LIST_STYLE_TYPE.CIRCLE:return"◦";case u.LIST_STYLE_TYPE.SQUARE:return"◾";case u.LIST_STYLE_TYPE.DECIMAL_LEADING_ZERO:var n=E(e,48,57,!0);return n.length<4?"0"+n:n;case u.LIST_STYLE_TYPE.CJK_DECIMAL:return m(e,"〇一二三四五六七八九","、");case u.LIST_STYLE_TYPE.LOWER_ROMAN:return p(e,1,3999,c,u.LIST_STYLE_TYPE.DECIMAL).toLowerCase();case u.LIST_STYLE_TYPE.UPPER_ROMAN:return p(e,1,3999,c,u.LIST_STYLE_TYPE.DECIMAL);case u.LIST_STYLE_TYPE.LOWER_GREEK:return E(e,945,969,!1);case u.LIST_STYLE_TYPE.LOWER_ALPHA:return E(e,97,122,!1);case u.LIST_STYLE_TYPE.UPPER_ALPHA:return E(e,65,90,!1);case u.LIST_STYLE_TYPE.ARABIC_INDIC:return E(e,1632,1641,!0);case u.LIST_STYLE_TYPE.ARMENIAN:case u.LIST_STYLE_TYPE.UPPER_ARMENIAN:return p(e,1,9999,d,u.LIST_STYLE_TYPE.DECIMAL);case u.LIST_STYLE_TYPE.LOWER_ARMENIAN:return p(e,1,9999,d,u.LIST_STYLE_TYPE.DECIMAL).toLowerCase();case u.LIST_STYLE_TYPE.BENGALI:return E(e,2534,2543,!0);case u.LIST_STYLE_TYPE.CAMBODIAN:case u.LIST_STYLE_TYPE.KHMER:return E(e,6112,6121,!0);case u.LIST_STYLE_TYPE.CJK_EARTHLY_BRANCH:return m(e,"子丑寅卯辰巳午未申酉戌亥","、");case u.LIST_STYLE_TYPE.CJK_HEAVENLY_STEM:return m(e,"甲乙丙丁戊己庚辛壬癸","、");case u.LIST_STYLE_TYPE.CJK_IDEOGRAPHIC:case u.LIST_STYLE_TYPE.TRAD_CHINESE_INFORMAL:return T(e,"零一二三四五六七八九","十百千萬","負","、",14);case u.LIST_STYLE_TYPE.TRAD_CHINESE_FORMAL:return T(e,"零壹貳參肆伍陸柒捌玖","拾佰仟萬","負","、",15);case u.LIST_STYLE_TYPE.SIMP_CHINESE_INFORMAL:return T(e,"零一二三四五六七八九","十百千萬","负","、",14);case u.LIST_STYLE_TYPE.SIMP_CHINESE_FORMAL:return T(e,"零壹贰叁肆伍陆柒捌玖","拾佰仟萬","负","、",15);case u.LIST_STYLE_TYPE.JAPANESE_INFORMAL:return T(e,"〇一二三四五六七八九","十百千万","マイナス","、",0);case u.LIST_STYLE_TYPE.JAPANESE_FORMAL:return T(e,"零壱弐参四伍六七八九","拾百千万","マイナス","、",7);case u.LIST_STYLE_TYPE.KOREAN_HANGUL_FORMAL:return T(e,"영일이삼사오육칠팔구","십백천만","마이너스 ",", ",7);case u.LIST_STYLE_TYPE.KOREAN_HANJA_INFORMAL:return T(e,"零一二三四五六七八九","十百千萬","마이너스 ",", ",0);case u.LIST_STYLE_TYPE.KOREAN_HANJA_FORMAL:return T(e,"零壹貳參四五六七八九","拾百千","마이너스 ",", ",7);case u.LIST_STYLE_TYPE.DEVANAGARI:return E(e,2406,2415,!0);case u.LIST_STYLE_TYPE.GEORGIAN:return p(e,1,19999,h,u.LIST_STYLE_TYPE.DECIMAL);case u.LIST_STYLE_TYPE.GUJARATI:return E(e,2790,2799,!0);case u.LIST_STYLE_TYPE.GURMUKHI:return E(e,2662,2671,!0);case u.LIST_STYLE_TYPE.HEBREW:return p(e,1,10999,f,u.LIST_STYLE_TYPE.DECIMAL);case u.LIST_STYLE_TYPE.HIRAGANA:return m(e,"あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをん");case u.LIST_STYLE_TYPE.HIRAGANA_IROHA:return m(e,"いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす");case u.LIST_STYLE_TYPE.KANNADA:return E(e,3302,3311,!0);case u.LIST_STYLE_TYPE.KATAKANA:return m(e,"アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン","、");case u.LIST_STYLE_TYPE.KATAKANA_IROHA:return m(e,"イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス","、");case u.LIST_STYLE_TYPE.LAO:return E(e,3792,3801,!0);case u.LIST_STYLE_TYPE.MONGOLIAN:return E(e,6160,6169,!0);case u.LIST_STYLE_TYPE.MYANMAR:return E(e,4160,4169,!0);case u.LIST_STYLE_TYPE.ORIYA:return E(e,2918,2927,!0);case u.LIST_STYLE_TYPE.PERSIAN:return E(e,1776,1785,!0);case u.LIST_STYLE_TYPE.TAMIL:return E(e,3046,3055,!0);case u.LIST_STYLE_TYPE.TELUGU:return E(e,3174,3183,!0);case u.LIST_STYLE_TYPE.THAI:return E(e,3664,3673,!0);case u.LIST_STYLE_TYPE.TIBETAN:return E(e,3872,3881,!0);case u.LIST_STYLE_TYPE.DECIMAL:default:return E(e,48,57,!0)}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.FontMetrics=void 0;var r=function(){function e(e,t){for(var n=0;n0&&n.childNodes.push(i.default.fromTextNode(g,n));else if(g instanceof E.HTMLElement||g instanceof HTMLElement||E.parent&&g instanceof E.parent.HTMLElement){if(-1===s.indexOf(g.nodeName)){var m=new o.default(g,n,c,h++);if(m.isVisible()){"INPUT"===g.tagName?(0,u.inlineInputElement)(g,m):"TEXTAREA"===g.tagName?(0,u.inlineTextAreaElement)(g,m):"SELECT"===g.tagName?(0,u.inlineSelectElement)(g,m):m.style.listStyle&&"none"!==m.style.listStyle.listStyleType&&(0,l.inlineListItemElement)(g,m,c);var T="TEXTAREA"!==g.tagName,y=d(m,g);if(y||f(m)){var v=y||m.isPositioned()?r.getRealParentStackingContext():r,b=new a.default(m,v,y);v.contexts.push(b),T&&e(g,m,b,c,h)}else r.children.push(m),T&&e(g,m,r,c,h)}}}else if(g instanceof E.SVGSVGElement||g instanceof SVGSVGElement||E.parent&&g instanceof E.parent.SVGSVGElement){var I=new o.default(g,n,c,h++),_=d(I,g);if(_||f(I)){var w=_||I.isPositioned()?r.getRealParentStackingContext():r,A=new a.default(I,w,_);w.contexts.push(A)}else r.children.push(I)}}},d=function(e,t){return e.isRootElement()||e.isPositionedWithZIndex()||e.style.opacity<1||e.isTransformed()||h(e,t)},f=function(e){return e.isPositioned()||e.isFloating()},h=function(e,t){return"BODY"===t.nodeName&&e.parent instanceof o.default&&e.parent.style.background.backgroundColor.isTransparent()}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n1&&(r=n[0]+"@",e=n[1]);return r+u((e=e.replace(R,".")).split("."),t).join(".")}function s(e){for(var t,n,r=[],a=0,o=e.length;a=55296&&t<=56319&&a65535&&(t+=M((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+=M(e)}).join("")}function d(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:y}function f(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function h(e,t,n){var r=0;for(e=n?C(e/_):e>>1,e+=C(e/t);e>N*b>>1;r+=y)e=C(e/N);return C(r+(N+1)*e/(e+I))}function p(e){var t,n,r,a,o,u,l,s,f,p,g=[],E=e.length,m=0,I=A,_=w;for((n=e.lastIndexOf(O))<0&&(n=0),r=0;r=128&&i("not-basic"),g.push(e.charCodeAt(r));for(a=n>0?n+1:0;a=E&&i("invalid-input"),((s=d(e.charCodeAt(a++)))>=y||s>C((T-m)/u))&&i("overflow"),m+=s*u,f=l<=_?v:l>=_+b?b:l-_,!(sC(T/(p=y-f))&&i("overflow"),u*=p;_=h(m-o,t=g.length+1,0==o),C(m/t)>T-I&&i("overflow"),I+=C(m/t),m%=t,g.splice(m++,0,I)}return c(g)}function g(e){var t,n,r,a,o,u,l,c,d,p,g,E,m,I,_,S=[];for(E=(e=s(e)).length,t=A,n=0,o=w,u=0;u=t&&gC((T-n)/(m=r+1))&&i("overflow"),n+=(l-t)*m,t=l,u=0;uT&&i("overflow"),g==t){for(c=n,d=y;p=d<=o?v:d>=o+b?b:d-o,!(c= 0x80 (not a basic code point)","invalid-input":"Invalid input"},N=y-v,C=Math.floor,M=String.fromCharCode;m={version:"1.4.1",ucs2:{decode:s,encode:c},decode:p,encode:g,toASCII:function(e){return l(e,function(e){return L.test(e)?"xn--"+g(e):e})},toUnicode:function(e){return l(e,function(e){return S.test(e)?p(e.slice(4).toLowerCase()):e})}},void 0===(a=function(){return m}.call(t,n,t,e))||(e.exports=a)}()}).call(t,n(42)(e),n(43))},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(6);t.default=function e(t,n,a){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.type=r.PATH.CIRCLE,this.x=t,this.y=n,this.radius=a}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.fromCodePoint=function(){if(String.fromCodePoint)return String.fromCodePoint.apply(String,arguments);var e=arguments.length;if(!e)return"";for(var t=[],n=-1,r="";++n>10),a%1024+56320)),(n+1===e||t.length>16384)&&(r+=String.fromCharCode.apply(String,t),t.length=0)}return r}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,a=!1,o=void 0;try{for(var i,u=e[Symbol.iterator]();!(r=(i=u.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){a=!0,o=e}finally{try{!r&&u.return&&u.return()}finally{if(a)throw o}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),a=function(){function e(e,t){for(var n=0;n0?n.width:r.width,i="number"==typeof n.height&&n.height>0?n.height:r.height;a>0&&i>0&&t.target.clip([(0,o.calculatePaddingBoxPath)(e.curvedBounds)],function(){t.target.drawImage(n,new o.Bounds(0,0,a,i),r)})}}},r=e.getClipPaths();r.length?this.target.clip(r,n):n()}},{key:"renderNodeBackgroundAndBorders",value:function(e){var t=this,n=!e.style.background.backgroundColor.isTransparent()||e.style.background.backgroundImage.length,r=e.style.border.filter(function(e){return e.borderStyle!==s.BORDER_STYLE.NONE&&!e.borderColor.isTransparent()}),a=function(){var a=(0,l.calculateBackgroungPaintingArea)(e.curvedBounds,e.style.background.backgroundClip);n&&t.target.clip([a],function(){e.style.background.backgroundColor.isTransparent()||t.target.fill(e.style.background.backgroundColor),t.renderBackgroundImage(e)}),r.forEach(function(n,r){t.renderBorder(n,r,e.curvedBounds)})};if(n||r.length){var o=e.parent?e.parent.getClipPaths():[];o.length?this.target.clip(o,a):a()}}},{key:"renderBackgroundImage",value:function(e){var t=this;e.style.background.backgroundImage.slice(0).reverse().forEach(function(n){"url"===n.source.method&&n.source.args.length?t.renderBackgroundRepeat(e,n):/gradient/i.test(n.source.method)&&t.renderBackgroundGradient(e,n)})}},{key:"renderBackgroundRepeat",value:function(e,t){var n=this.options.imageStore.get(t.source.args[0]);if(n){var r=(0,l.calculateBackgroungPositioningArea)(e.style.background.backgroundOrigin,e.bounds,e.style.padding,e.style.border),a=(0,l.calculateBackgroundSize)(t,n,r),o=(0,l.calculateBackgroundPosition)(t.position,a,r),i=(0,l.calculateBackgroundRepeatPath)(t,o,a,r,e.bounds),u=Math.round(r.left+o.x),s=Math.round(r.top+o.y);this.target.renderRepeat(i,n,a,u,s)}}},{key:"renderBackgroundGradient",value:function(e,t){var n=(0,l.calculateBackgroungPositioningArea)(e.style.background.backgroundOrigin,e.bounds,e.style.padding,e.style.border),r=(0,l.calculateGradientBackgroundSize)(t,n),a=(0,l.calculateBackgroundPosition)(t.position,r,n),u=new o.Bounds(Math.round(n.left+a.x),Math.round(n.top+a.y),r.width,r.height),s=(0,i.parseGradient)(e,t.source,u);if(s)switch(s.type){case i.GRADIENT_TYPE.LINEAR_GRADIENT:this.target.renderLinearGradient(u,s);break;case i.GRADIENT_TYPE.RADIAL_GRADIENT:this.target.renderRadialGradient(u,s)}}},{key:"renderBorder",value:function(e,t,n){this.target.drawShape((0,o.parsePathForBorder)(n,t),e.borderColor)}},{key:"renderStack",value:function(e){var t=this;if(e.container.isVisible()){var n=e.getOpacity();n!==this._opacity&&(this.target.setOpacity(e.getOpacity()),this._opacity=n);var r=e.container.style.transform;null!==r?this.target.transform(e.container.bounds.left+r.transformOrigin[0].value,e.container.bounds.top+r.transformOrigin[1].value,r.transform,function(){return t.renderStackContent(e)}):this.renderStackContent(e)}}},{key:"renderStackContent",value:function(e){var t=f(e),n=r(t,5),a=n[0],o=n[1],i=n[2],u=n[3],l=n[4],s=d(e),c=r(s,2),p=c[0],g=c[1];this.renderNodeBackgroundAndBorders(e.container),a.sort(h).forEach(this.renderStack,this),this.renderNodeContent(e.container),g.forEach(this.renderNode,this),u.forEach(this.renderStack,this),l.forEach(this.renderStack,this),p.forEach(this.renderNode,this),o.forEach(this.renderStack,this),i.sort(h).forEach(this.renderStack,this)}},{key:"render",value:function(e){this.options.backgroundColor&&this.target.rectangle(this.options.x,this.options.y,this.options.width,this.options.height,this.options.backgroundColor),this.renderStack(e);var t=this.target.getTarget();return t}}]),e}();t.default=c;var d=function(e){for(var t=[],n=[],r=e.children.length,a=0;a0?r.push(l):n.push(l):l.container.isFloating()?a.push(l):o.push(l)}return[t,n,r,a,o]},h=function(e,t){return e.container.style.zIndex.order>t.container.style.zIndex.order?1:e.container.style.zIndex.ordert.container.index?1:-1}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.transformWebkitRadialGradientArgs=t.parseGradient=t.RadialGradient=t.LinearGradient=t.RADIAL_GRADIENT_SHAPE=t.GRADIENT_TYPE=void 0;var o=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,a=!1,o=void 0;try{for(var i,u=e[Symbol.iterator]();!(r=(i=u.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){a=!0,o=e}finally{try{!r&&u.return&&u.return()}finally{if(a)throw o}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),i=(r(n(4)),n(48)),u=r(n(0)),l=n(2),s=r(l),c=n(3),d=/^(to )?(left|top|right|bottom)( (left|top|right|bottom))?$/i,f=/^([+-]?\d*\.?\d+)% ([+-]?\d*\.?\d+)%$/i,h=/(px)|%|( 0)$/i,p=/^(from|to|color-stop)\((?:([\d.]+)(%)?,\s*)?(.+?)\)$/i,g=/^\s*(circle|ellipse)?\s*((?:([\d.]+)(px|r?em|%)\s*(?:([\d.]+)(px|r?em|%))?)|closest-side|closest-corner|farthest-side|farthest-corner)?\s*(?:at\s*(?:(left|center|right)|([\d.]+)(px|r?em|%))\s+(?:(top|center|bottom)|([\d.]+)(px|r?em|%)))?(?:\s|$)/i,E=t.GRADIENT_TYPE={LINEAR_GRADIENT:0,RADIAL_GRADIENT:1},m=t.RADIAL_GRADIENT_SHAPE={CIRCLE:0,ELLIPSE:1},T={left:new s.default("0%"),top:new s.default("0%"),center:new s.default("50%"),right:new s.default("100%"),bottom:new s.default("100%")},y=t.LinearGradient=function e(t,n){a(this,e),this.type=E.LINEAR_GRADIENT,this.colorStops=t,this.direction=n},v=t.RadialGradient=function e(t,n,r,o){a(this,e),this.type=E.RADIAL_GRADIENT,this.colorStops=t,this.shape=n,this.center=r,this.radius=o},b=(t.parseGradient=function(e,t,n){var r=t.args,a=t.method,o=t.prefix;return"linear-gradient"===a?I(r,n,!!o):"gradient"===a&&"linear"===r[0]?I(["to bottom"].concat(N(r.slice(3))),n,!!o):"radial-gradient"===a?_(e,"-webkit-"===o?P(r):r,n):"gradient"===a&&"radial"===r[0]?_(e,N(P(r.slice(1))),n):void 0},function(e,t,n){for(var r=[],a=t;ae.optimumDistance)?{optimumCorner:a,optimumDistance:o}:e},{optimumDistance:r?1/0:-1/0,optimumCorner:null}).optimumCorner},R=function(e,t,n,r,a){var o=n.x,i=n.y,u=0,l=0;switch(e){case"closest-side":t===m.CIRCLE?u=l=Math.min(Math.abs(o),Math.abs(o-a.width),Math.abs(i),Math.abs(i-a.height)):t===m.ELLIPSE&&(u=Math.min(Math.abs(o),Math.abs(o-a.width)),l=Math.min(Math.abs(i),Math.abs(i-a.height)));break;case"closest-corner":if(t===m.CIRCLE)u=l=Math.min((0,c.distance)(o,i),(0,c.distance)(o,i-a.height),(0,c.distance)(o-a.width,i),(0,c.distance)(o-a.width,i-a.height));else if(t===m.ELLIPSE){var s=Math.min(Math.abs(i),Math.abs(i-a.height))/Math.min(Math.abs(o),Math.abs(o-a.width)),d=L(a,o,i,!0);l=s*(u=(0,c.distance)(d.x-o,(d.y-i)/s))}break;case"farthest-side":t===m.CIRCLE?u=l=Math.max(Math.abs(o),Math.abs(o-a.width),Math.abs(i),Math.abs(i-a.height)):t===m.ELLIPSE&&(u=Math.max(Math.abs(o),Math.abs(o-a.width)),l=Math.max(Math.abs(i),Math.abs(i-a.height)));break;case"farthest-corner":if(t===m.CIRCLE)u=l=Math.max((0,c.distance)(o,i),(0,c.distance)(o,i-a.height),(0,c.distance)(o-a.width,i),(0,c.distance)(o-a.width,i-a.height));else if(t===m.ELLIPSE){var f=Math.max(Math.abs(i),Math.abs(i-a.height))/Math.max(Math.abs(o),Math.abs(o-a.width)),h=L(a,o,i,!1);l=f*(u=(0,c.distance)(h.x-o,(h.y-i)/f))}break;default:u=r.x||0,l=void 0!==r.y?r.y:u}return{x:u,y:l}},P=t.transformWebkitRadialGradientArgs=function(e){var t="",n="",r="",a="",o=0,i=/^(left|center|right|\d+(?:px|r?em|%)?)(?:\s+(top|center|bottom|\d+(?:px|r?em|%)?))?$/i,u=/^\d+(px|r?em|%)?(?:\s+\d+(px|r?em|%)?)?$/i,l=e[o].match(i);l&&o++;var s=e[o].match(/^(circle|ellipse)?\s*(closest-side|closest-corner|farthest-side|farthest-corner|contain|cover)?$/i);s&&(t=s[1]||"","contain"===(r=s[2]||"")?r="closest-side":"cover"===r&&(r="farthest-corner"),o++);var c=e[o].match(u);c&&o++;var d=e[o].match(i);d&&o++;var f=e[o].match(u);f&&o++;var h=d||l;h&&h[1]&&(a=h[1]+(/^\d+$/.test(h[1])?"px":""),h[2]&&(a+=" "+h[2]+(/^\d+$/.test(h[2])?"px":"")));var p=f||c;return p&&(n=p[0],p[1]||(n+="px")),!a||t||n||r||(n=a,a=""),a&&(a="at "+a),[[t,r,n,a].filter(function(e){return!!e}).join(" ")].concat(e.slice(o))},N=function(e){return e.map(function(e){return e.match(p)}).map(function(t,n){if(!t)return e[n];switch(t[1]){case"from":return t[4]+" 0%";case"to":return t[4]+" 100%";case"color-stop":return"%"===t[3]?t[4]+" "+t[2]:t[4]+" "+100*parseFloat(t[2])+"%"}})}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=/([+-]?\d*\.?\d+)(deg|grad|rad|turn)/i;t.parseAngle=function(e){var t=e.match(r);if(t){var n=parseFloat(t[1]);switch(t[2].toLowerCase()){case"deg":return Math.PI*n/180;case"grad":return Math.PI/200*n;case"rad":return n;case"turn":return 2*Math.PI*n}}return null}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.cloneWindow=t.DocumentCloner=void 0;var a=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,a=!1,o=void 0;try{for(var i,u=e[Symbol.iterator]();!(r=(i=u.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){a=!0,o=e}finally{try{!r&&u.return&&u.return()}finally{if(a)throw o}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),o=function(){function e(e,t){for(var n=0;n1&&(n.backgroundColor=""),n.backgroundImage=e.join(",")}),e instanceof HTMLImageElement&&this.resourceLoader.inlineImage(e.src).then(function(t){if(t&&e instanceof HTMLImageElement&&e.parentNode){var n=e.parentNode,r=(0,s.copyCSSStyles)(e.style,t.cloneNode(!1));n.replaceChild(r,e)}}).catch(function(e){0})}}},{key:"inlineFonts",value:function(e){var t=this;return Promise.all(Array.from(e.styleSheets).map(function(t){return t.href?fetch(t.href).then(function(e){return e.text()}).then(function(e){return g(e,t.href)}).catch(function(e){return[]}):p(t,e)})).then(function(e){return e.reduce(function(e,t){return e.concat(t)},[])}).then(function(e){return Promise.all(e.map(function(e){return fetch(e.formats[0].src).then(function(e){return e.blob()}).then(function(e){return new Promise(function(t,n){var r=new FileReader;r.onerror=n,r.onload=function(){var e=r.result;t(e)},r.readAsDataURL(e)})}).then(function(t){return e.fontFace.setProperty("src",'url("'+t+'")'),"@font-face {"+e.fontFace.cssText+" "})}))}).then(function(n){var r=e.createElement("style");r.textContent=n.join("\n"),t.documentElement.appendChild(r)})}},{key:"createElementClone",value:function(e){var t=this;if(this.copyStyles&&e instanceof HTMLCanvasElement){var n=e.ownerDocument.createElement("img");try{return n.src=e.toDataURL(),n}catch(e){0}}if(e instanceof HTMLIFrameElement){var r=e.cloneNode(!1),a=L();r.setAttribute("data-html2canvas-internal-iframe-key",a);var o=(0,i.parseBounds)(e,0,0),u=o.width,l=o.height;return this.resourceLoader.cache[a]=P(e,this.options).then(function(e){return t.renderer(e,{async:t.options.async,allowTaint:t.options.allowTaint,backgroundColor:"#ffffff",canvas:null,imageTimeout:t.options.imageTimeout,logging:t.options.logging,proxy:t.options.proxy,removeContainer:t.options.removeContainer,scale:t.options.scale,foreignObjectRendering:t.options.foreignObjectRendering,useCORS:t.options.useCORS,target:new d.default,width:u,height:l,x:0,y:0,windowWidth:e.ownerDocument.defaultView.innerWidth,windowHeight:e.ownerDocument.defaultView.innerHeight,scrollX:e.ownerDocument.defaultView.pageXOffset,scrollY:e.ownerDocument.defaultView.pageYOffset},t.logger.child(a))}).then(function(t){return new Promise(function(n,a){var o=document.createElement("img");o.onload=function(){return n(t)},o.onerror=a,o.src=t.toDataURL(),r.parentNode&&r.parentNode.replaceChild((0,s.copyCSSStyles)(e.ownerDocument.defaultView.getComputedStyle(e),o),r)})}),r}return e.cloneNode(!1)}},{key:"cloneNode",value:function(e){var t=e.nodeType===Node.TEXT_NODE?document.createTextNode(e.nodeValue):this.createElementClone(e),n=e.ownerDocument.defaultView;this.referenceElement===e&&t instanceof n.HTMLElement&&(this.clonedReferenceElement=t),t instanceof n.HTMLBodyElement&&A(t);for(var r=e.firstChild;r;r=r.nextSibling)(r.nodeType!==Node.ELEMENT_NODE||"SCRIPT"!==r.nodeName&&!r.hasAttribute(f))&&(this.copyStyles&&"STYLE"===r.nodeName||t.appendChild(this.cloneNode(r)));if(e instanceof n.HTMLElement&&t instanceof n.HTMLElement)switch(this.inlineAllImages(m(e,t,v)),this.inlineAllImages(m(e,t,b)),!this.copyStyles||e instanceof HTMLIFrameElement||(0,s.copyCSSStyles)(e.ownerDocument.defaultView.getComputedStyle(e),t),this.inlineAllImages(t),0===e.scrollTop&&0===e.scrollLeft||this.scrolledElements.push([t,e.scrollLeft,e.scrollTop]),e.nodeName){case"CANVAS":this.copyStyles||E(e,t);break;case"TEXTAREA":case"SELECT":t.value=e.value}return t}}]),e}(),p=function(e,t){return(e.cssRules?Array.from(e.cssRules):[]).filter(function(e){return e.type===CSSRule.FONT_FACE_RULE}).map(function(e){for(var n=(0,c.parseBackgroundImage)(e.style.getPropertyValue("src")),r=[],a=0;a0&&"complete"===n.readyState&&(clearInterval(t),r(e))},50)}})};t.cloneWindow=function(e,t,n,r,a,o){var i=new h(n,r,a,!1,o),u=e.defaultView.pageXOffset,l=e.defaultView.pageYOffset;return N(e,t).then(function(r){var a=r.contentWindow,o=a.document,s=C(r).then(function(){return i.scrolledElements.forEach(S),a.scrollTo(t.left,t.top),!/(iPad|iPhone|iPod)/g.test(navigator.userAgent)||a.scrollY===t.top&&a.scrollX===t.left||(o.documentElement.style.top=-t.top+"px",o.documentElement.style.left=-t.left+"px",o.documentElement.style.position="absolute"),i.clonedReferenceElement instanceof a.HTMLElement||i.clonedReferenceElement instanceof e.defaultView.HTMLElement||i.clonedReferenceElement instanceof HTMLElement?Promise.resolve([r,i.clonedReferenceElement,i.resourceLoader]):Promise.reject("")});return o.open(),o.write(""),function(e,t,n){!e.defaultView||t===e.defaultView.pageXOffset&&n===e.defaultView.pageYOffset||e.defaultView.scrollTo(t,n)}(n.ownerDocument,u,l),o.replaceChild(o.adoptNode(i.documentElement),o.documentElement),o.close(),s})}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.ResourceStore=void 0;var a=function(){function e(e,t){for(var n=0;n4)&&[Number(e[1]),Number(e[2]),Number(e[3]),Number(e[4])]},Q=function(A){return[Math.min(A[0],255),Math.min(A[1],255),Math.min(A[2],255),A.length>3?A[3]:null]},w=function(A){var e=g[A.toLowerCase()];return e||!1},U=function(){function A(e){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A);var t=Array.isArray(e)?Q(e):a(e)||c(e)||u(e)||w(e)||o(e)||[0,0,0,null],n=r(t,4),B=n[0],s=n[1],i=n[2],l=n[3];this.r=B,this.g=s,this.b=i,this.a=l}return n(A,[{key:"isTransparent",value:function(){return 0===this.a}},{key:"toString",value:function(){return null!==this.a&&1!==this.a?"rgba("+this.r+","+this.g+","+this.b+","+this.a+")":"rgb("+this.r+","+this.g+","+this.b+")"}}]),A}();e.default=U;var g={transparent:[0,0,0,0],aliceblue:[240,248,255,null],antiquewhite:[250,235,215,null],aqua:[0,255,255,null],aquamarine:[127,255,212,null],azure:[240,255,255,null],beige:[245,245,220,null],bisque:[255,228,196,null],black:[0,0,0,null],blanchedalmond:[255,235,205,null],blue:[0,0,255,null],blueviolet:[138,43,226,null],brown:[165,42,42,null],burlywood:[222,184,135,null],cadetblue:[95,158,160,null],chartreuse:[127,255,0,null],chocolate:[210,105,30,null],coral:[255,127,80,null],cornflowerblue:[100,149,237,null],cornsilk:[255,248,220,null],crimson:[220,20,60,null],cyan:[0,255,255,null],darkblue:[0,0,139,null],darkcyan:[0,139,139,null],darkgoldenrod:[184,134,11,null],darkgray:[169,169,169,null],darkgreen:[0,100,0,null],darkgrey:[169,169,169,null],darkkhaki:[189,183,107,null],darkmagenta:[139,0,139,null],darkolivegreen:[85,107,47,null],darkorange:[255,140,0,null],darkorchid:[153,50,204,null],darkred:[139,0,0,null],darksalmon:[233,150,122,null],darkseagreen:[143,188,143,null],darkslateblue:[72,61,139,null],darkslategray:[47,79,79,null],darkslategrey:[47,79,79,null],darkturquoise:[0,206,209,null],darkviolet:[148,0,211,null],deeppink:[255,20,147,null],deepskyblue:[0,191,255,null],dimgray:[105,105,105,null],dimgrey:[105,105,105,null],dodgerblue:[30,144,255,null],firebrick:[178,34,34,null],floralwhite:[255,250,240,null],forestgreen:[34,139,34,null],fuchsia:[255,0,255,null],gainsboro:[220,220,220,null],ghostwhite:[248,248,255,null],gold:[255,215,0,null],goldenrod:[218,165,32,null],gray:[128,128,128,null],green:[0,128,0,null],greenyellow:[173,255,47,null],grey:[128,128,128,null],honeydew:[240,255,240,null],hotpink:[255,105,180,null],indianred:[205,92,92,null],indigo:[75,0,130,null],ivory:[255,255,240,null],khaki:[240,230,140,null],lavender:[230,230,250,null],lavenderblush:[255,240,245,null],lawngreen:[124,252,0,null],lemonchiffon:[255,250,205,null],lightblue:[173,216,230,null],lightcoral:[240,128,128,null],lightcyan:[224,255,255,null],lightgoldenrodyellow:[250,250,210,null],lightgray:[211,211,211,null],lightgreen:[144,238,144,null],lightgrey:[211,211,211,null],lightpink:[255,182,193,null],lightsalmon:[255,160,122,null],lightseagreen:[32,178,170,null],lightskyblue:[135,206,250,null],lightslategray:[119,136,153,null],lightslategrey:[119,136,153,null],lightsteelblue:[176,196,222,null],lightyellow:[255,255,224,null],lime:[0,255,0,null],limegreen:[50,205,50,null],linen:[250,240,230,null],magenta:[255,0,255,null],maroon:[128,0,0,null],mediumaquamarine:[102,205,170,null],mediumblue:[0,0,205,null],mediumorchid:[186,85,211,null],mediumpurple:[147,112,219,null],mediumseagreen:[60,179,113,null],mediumslateblue:[123,104,238,null],mediumspringgreen:[0,250,154,null],mediumturquoise:[72,209,204,null],mediumvioletred:[199,21,133,null],midnightblue:[25,25,112,null],mintcream:[245,255,250,null],mistyrose:[255,228,225,null],moccasin:[255,228,181,null],navajowhite:[255,222,173,null],navy:[0,0,128,null],oldlace:[253,245,230,null],olive:[128,128,0,null],olivedrab:[107,142,35,null],orange:[255,165,0,null],orangered:[255,69,0,null],orchid:[218,112,214,null],palegoldenrod:[238,232,170,null],palegreen:[152,251,152,null],paleturquoise:[175,238,238,null],palevioletred:[219,112,147,null],papayawhip:[255,239,213,null],peachpuff:[255,218,185,null],peru:[205,133,63,null],pink:[255,192,203,null],plum:[221,160,221,null],powderblue:[176,224,230,null],purple:[128,0,128,null],rebeccapurple:[102,51,153,null],red:[255,0,0,null],rosybrown:[188,143,143,null],royalblue:[65,105,225,null],saddlebrown:[139,69,19,null],salmon:[250,128,114,null],sandybrown:[244,164,96,null],seagreen:[46,139,87,null],seashell:[255,245,238,null],sienna:[160,82,45,null],silver:[192,192,192,null],skyblue:[135,206,235,null],slateblue:[106,90,205,null],slategray:[112,128,144,null],slategrey:[112,128,144,null],snow:[255,250,250,null],springgreen:[0,255,127,null],steelblue:[70,130,180,null],tan:[210,180,140,null],teal:[0,128,128,null],thistle:[216,191,216,null],tomato:[255,99,71,null],turquoise:[64,224,208,null],violet:[238,130,238,null],wheat:[245,222,179,null],white:[255,255,255,null],whitesmoke:[245,245,245,null],yellow:[255,255,0,null],yellowgreen:[154,205,50,null]};e.TRANSPARENT=new U([0,0,0,0])},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.calculateLengthFromValueWithUnit=e.LENGTH_TYPE=void 0;var r,n=function(){function A(A,e){for(var t=0;t1&&(r/=U,B/=U,a/=U,s/=U,o/=U,l/=U,u/=U,Q/=U);var g=A.width-a,C=A.height-l,d=A.width-o,F=A.height-Q;return{topLeftOuter:r>0||B>0?c(A.left,A.top,r,B,i.TOP_LEFT):new n.default(A.left,A.top),topLeftInner:r>0||B>0?c(A.left+e[3].borderWidth,A.top+e[0].borderWidth,Math.max(0,r-e[3].borderWidth),Math.max(0,B-e[0].borderWidth),i.TOP_LEFT):new n.default(A.left+e[3].borderWidth,A.top+e[0].borderWidth),topRightOuter:a>0||s>0?c(A.left+g,A.top,a,s,i.TOP_RIGHT):new n.default(A.left+A.width,A.top),topRightInner:a>0||s>0?c(A.left+Math.min(g,A.width+e[3].borderWidth),A.top+e[0].borderWidth,g>A.width+e[3].borderWidth?0:a-e[3].borderWidth,s-e[0].borderWidth,i.TOP_RIGHT):new n.default(A.left+A.width-e[1].borderWidth,A.top+e[0].borderWidth),bottomRightOuter:o>0||l>0?c(A.left+d,A.top+C,o,l,i.BOTTOM_RIGHT):new n.default(A.left+A.width,A.top+A.height),bottomRightInner:o>0||l>0?c(A.left+Math.min(d,A.width-e[3].borderWidth),A.top+Math.min(C,A.height+e[0].borderWidth),Math.max(0,o-e[1].borderWidth),l-e[2].borderWidth,i.BOTTOM_RIGHT):new n.default(A.left+A.width-e[1].borderWidth,A.top+A.height-e[2].borderWidth),bottomLeftOuter:u>0||Q>0?c(A.left,A.top+F,u,Q,i.BOTTOM_LEFT):new n.default(A.left,A.top+A.height),bottomLeftInner:u>0||Q>0?c(A.left+e[3].borderWidth,A.top+F,Math.max(0,u-e[3].borderWidth),Q-e[2].borderWidth,i.BOTTOM_LEFT):new n.default(A.left+e[3].borderWidth,A.top+A.height-e[2].borderWidth)}},{TOP_LEFT:0,TOP_RIGHT:1,BOTTOM_RIGHT:2,BOTTOM_LEFT:3}),c=function(A,e,t,r,a){var s=(Math.sqrt(2)-1)/3*4,o=t*s,c=r*s,l=A+t,u=e+r;switch(a){case i.TOP_LEFT:return new B.default(new n.default(A,u),new n.default(A,u-c),new n.default(l-o,e),new n.default(l,e));case i.TOP_RIGHT:return new B.default(new n.default(A,e),new n.default(A+o,e),new n.default(l,u-c),new n.default(l,u));case i.BOTTOM_RIGHT:return new B.default(new n.default(l,e),new n.default(l,e+c),new n.default(A+o,u),new n.default(A,u));case i.BOTTOM_LEFT:default:return new B.default(new n.default(l,u),new n.default(l-o,u),new n.default(A,e+c),new n.default(A,e))}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r,n=function(){function A(A,e){for(var t=0;t0&&this.style.visibility===I.VISIBILITY.VISIBLE}},{key:"isAbsolutelyPositioned",value:function(){return this.style.position!==f.POSITION.STATIC&&this.style.position!==f.POSITION.RELATIVE}},{key:"isPositioned",value:function(){return this.style.position!==f.POSITION.STATIC}},{key:"isFloating",value:function(){return this.style.float!==u.FLOAT.NONE}},{key:"isRootElement",value:function(){return null===this.parent}},{key:"isTransformed",value:function(){return null!==this.style.transform}},{key:"isPositionedWithZIndex",value:function(){return this.isPositioned()&&!this.style.zIndex.auto}},{key:"isInlineLevel",value:function(){return(0,s.contains)(this.style.display,l.DISPLAY.INLINE)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_BLOCK)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_FLEX)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_GRID)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_LIST_ITEM)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_TABLE)}},{key:"isInlineBlockOrInlineTable",value:function(){return(0,s.contains)(this.style.display,l.DISPLAY.INLINE_BLOCK)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_TABLE)}}]),A}();e.default=S;var L=function(A,e){if(A instanceof A.ownerDocument.defaultView.SVGSVGElement||A instanceof SVGSVGElement){var t=new XMLSerializer;return e.loadImage("data:image/svg+xml,"+encodeURIComponent(t.serializeToString(A)))}switch(A.tagName){case"IMG":var r=A;return e.loadImage(r.currentSrc||r.src);case"CANVAS":var n=A;return e.loadCanvas(n);case"IFRAME":var B=A.getAttribute("data-html2canvas-internal-iframe-key");if(B)return B}return null}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.contains=function(A,e){return 0!=(A&e)},e.distance=function(A,e){return Math.sqrt(A*A+e*e)},e.copyCSSStyles=function(A,e){for(var t=A.length-1;t>=0;t--){var r=A.item(t);"content"!==r&&e.style.setProperty(r,A.getPropertyValue(r))}return e},e.SMALL_IMAGE="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseBackgroundImage=e.parseBackground=e.calculateBackgroundRepeatPath=e.calculateBackgroundPosition=e.calculateBackgroungPositioningArea=e.calculateBackgroungPaintingArea=e.calculateGradientBackgroundSize=e.calculateBackgroundSize=e.BACKGROUND_ORIGIN=e.BACKGROUND_CLIP=e.BACKGROUND_SIZE=e.BACKGROUND_REPEAT=void 0;var r=i(t(0)),n=i(t(1)),B=i(t(31)),a=i(t(7)),s=t(2),o=t(17);function i(A){return A&&A.__esModule?A:{default:A}}var c=e.BACKGROUND_REPEAT={REPEAT:0,NO_REPEAT:1,REPEAT_X:2,REPEAT_Y:3},l=e.BACKGROUND_SIZE={AUTO:0,CONTAIN:1,COVER:2,LENGTH:3},u=e.BACKGROUND_CLIP={BORDER_BOX:0,PADDING_BOX:1,CONTENT_BOX:2},Q=e.BACKGROUND_ORIGIN=u,w=function A(e){switch(function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),e){case"contain":this.size=l.CONTAIN;break;case"cover":this.size=l.COVER;break;case"auto":this.size=l.AUTO;break;default:this.value=new n.default(e)}},U=(e.calculateBackgroundSize=function(A,e,t){var r=0,n=0,a=A.size;if(a[0].size===l.CONTAIN||a[0].size===l.COVER){var s=t.width/t.height,o=e.width/e.height;return s0&&(A=n.substr(0,e).toLowerCase(),n=n.substr(e)),"none"!==(n=n.toLowerCase())&&t.push({prefix:A,method:n,args:r})}r=[],n=a=""};return A.split("").forEach(function(A){if(0!==s||!e.test(A)){switch(A){case'"':B?B===A&&(B=null):B=A;break;case"(":if(B)break;if(0===s)return void(s=1);o++;break;case")":if(B)break;if(1===s){if(0===o)return s=0,void i();o--}break;case",":if(B)break;if(0===s)return void i();if(1===s&&0===o&&!n.match(/^url$/i))return r.push(a.trim()),void(a="")}0===s?n+=A:a+=A}}),i(),t}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.PATH={VECTOR:0,BEZIER_CURVE:1,CIRCLE:2}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=t(6);e.default=function A(e,t){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.type=r.PATH.VECTOR,this.x=e,this.y=t}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseListStyle=e.parseListStyleType=e.LIST_STYLE_TYPE=e.LIST_STYLE_POSITION=void 0;var r=t(5),n=e.LIST_STYLE_POSITION={INSIDE:0,OUTSIDE:1},B=e.LIST_STYLE_TYPE={NONE:-1,DISC:0,CIRCLE:1,SQUARE:2,DECIMAL:3,CJK_DECIMAL:4,DECIMAL_LEADING_ZERO:5,LOWER_ROMAN:6,UPPER_ROMAN:7,LOWER_GREEK:8,LOWER_ALPHA:9,UPPER_ALPHA:10,ARABIC_INDIC:11,ARMENIAN:12,BENGALI:13,CAMBODIAN:14,CJK_EARTHLY_BRANCH:15,CJK_HEAVENLY_STEM:16,CJK_IDEOGRAPHIC:17,DEVANAGARI:18,ETHIOPIC_NUMERIC:19,GEORGIAN:20,GUJARATI:21,GURMUKHI:22,HEBREW:22,HIRAGANA:23,HIRAGANA_IROHA:24,JAPANESE_FORMAL:25,JAPANESE_INFORMAL:26,KANNADA:27,KATAKANA:28,KATAKANA_IROHA:29,KHMER:30,KOREAN_HANGUL_FORMAL:31,KOREAN_HANJA_FORMAL:32,KOREAN_HANJA_INFORMAL:33,LAO:34,LOWER_ARMENIAN:35,MALAYALAM:36,MONGOLIAN:37,MYANMAR:38,ORIYA:39,PERSIAN:40,SIMP_CHINESE_FORMAL:41,SIMP_CHINESE_INFORMAL:42,TAMIL:43,TELUGU:44,THAI:45,TIBETAN:46,TRAD_CHINESE_FORMAL:47,TRAD_CHINESE_INFORMAL:48,UPPER_ARMENIAN:49,DISCLOSURE_OPEN:50,DISCLOSURE_CLOSED:51},a=e.parseListStyleType=function(A){switch(A){case"disc":return B.DISC;case"circle":return B.CIRCLE;case"square":return B.SQUARE;case"decimal":return B.DECIMAL;case"cjk-decimal":return B.CJK_DECIMAL;case"decimal-leading-zero":return B.DECIMAL_LEADING_ZERO;case"lower-roman":return B.LOWER_ROMAN;case"upper-roman":return B.UPPER_ROMAN;case"lower-greek":return B.LOWER_GREEK;case"lower-alpha":return B.LOWER_ALPHA;case"upper-alpha":return B.UPPER_ALPHA;case"arabic-indic":return B.ARABIC_INDIC;case"armenian":return B.ARMENIAN;case"bengali":return B.BENGALI;case"cambodian":return B.CAMBODIAN;case"cjk-earthly-branch":return B.CJK_EARTHLY_BRANCH;case"cjk-heavenly-stem":return B.CJK_HEAVENLY_STEM;case"cjk-ideographic":return B.CJK_IDEOGRAPHIC;case"devanagari":return B.DEVANAGARI;case"ethiopic-numeric":return B.ETHIOPIC_NUMERIC;case"georgian":return B.GEORGIAN;case"gujarati":return B.GUJARATI;case"gurmukhi":return B.GURMUKHI;case"hebrew":return B.HEBREW;case"hiragana":return B.HIRAGANA;case"hiragana-iroha":return B.HIRAGANA_IROHA;case"japanese-formal":return B.JAPANESE_FORMAL;case"japanese-informal":return B.JAPANESE_INFORMAL;case"kannada":return B.KANNADA;case"katakana":return B.KATAKANA;case"katakana-iroha":return B.KATAKANA_IROHA;case"khmer":return B.KHMER;case"korean-hangul-formal":return B.KOREAN_HANGUL_FORMAL;case"korean-hanja-formal":return B.KOREAN_HANJA_FORMAL;case"korean-hanja-informal":return B.KOREAN_HANJA_INFORMAL;case"lao":return B.LAO;case"lower-armenian":return B.LOWER_ARMENIAN;case"malayalam":return B.MALAYALAM;case"mongolian":return B.MONGOLIAN;case"myanmar":return B.MYANMAR;case"oriya":return B.ORIYA;case"persian":return B.PERSIAN;case"simp-chinese-formal":return B.SIMP_CHINESE_FORMAL;case"simp-chinese-informal":return B.SIMP_CHINESE_INFORMAL;case"tamil":return B.TAMIL;case"telugu":return B.TELUGU;case"thai":return B.THAI;case"tibetan":return B.TIBETAN;case"trad-chinese-formal":return B.TRAD_CHINESE_FORMAL;case"trad-chinese-informal":return B.TRAD_CHINESE_INFORMAL;case"upper-armenian":return B.UPPER_ARMENIAN;case"disclosure-open":return B.DISCLOSURE_OPEN;case"disclosure-closed":return B.DISCLOSURE_CLOSED;case"none":default:return B.NONE}},s=(e.parseListStyle=function(A){var e=(0,r.parseBackgroundImage)(A.getPropertyValue("list-style-image"));return{listStyleType:a(A.getPropertyValue("list-style-type")),listStyleImage:e.length?e[0]:null,listStylePosition:s(A.getPropertyValue("list-style-position"))}},function(A){switch(A){case"inside":return n.INSIDE;case"outside":default:return n.OUTSIDE}})},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function A(A,e){for(var t=0;t0?e+t.toUpperCase():A}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=t(23),n=function(A){return 0===A[0]&&255===A[1]&&0===A[2]&&255===A[3]},B={get SUPPORT_RANGE_BOUNDS(){var A=function(A){if(A.createRange){var e=A.createRange();if(e.getBoundingClientRect){var t=A.createElement("boundtest");t.style.height="123px",t.style.display="block",A.body.appendChild(t),e.selectNode(t);var r=e.getBoundingClientRect(),n=Math.round(r.height);if(A.body.removeChild(t),123===n)return!0}}return!1}(document);return Object.defineProperty(B,"SUPPORT_RANGE_BOUNDS",{value:A}),A},get SUPPORT_SVG_DRAWING(){var A=function(A){var e=new Image,t=A.createElement("canvas"),r=t.getContext("2d");e.src="data:image/svg+xml,";try{r.drawImage(e,0,0),t.toDataURL()}catch(A){return!1}return!0}(document);return Object.defineProperty(B,"SUPPORT_SVG_DRAWING",{value:A}),A},get SUPPORT_BASE64_DRAWING(){return function(A){var e=function(A,e){var t=new Image,r=A.createElement("canvas"),n=r.getContext("2d");return new Promise(function(A){t.src=e;var B=function(){try{n.drawImage(t,0,0),r.toDataURL()}catch(e){return A(!1)}return A(!0)};t.onload=B,t.onerror=function(){return A(!1)},!0===t.complete&&setTimeout(function(){B()},500)})}(document,A);return Object.defineProperty(B,"SUPPORT_BASE64_DRAWING",{value:function(){return e}}),e}},get SUPPORT_FOREIGNOBJECT_DRAWING(){var A="function"==typeof Array.from&&"function"==typeof window.fetch?function(A){var e=A.createElement("canvas");e.width=100,e.height=100;var t=e.getContext("2d");t.fillStyle="rgb(0, 255, 0)",t.fillRect(0,0,100,100);var B=new Image,a=e.toDataURL();B.src=a;var s=(0,r.createForeignObjectSVG)(100,100,0,0,B);return t.fillStyle="red",t.fillRect(0,0,100,100),(0,r.loadSerializedSVG)(s).then(function(e){t.drawImage(e,0,0);var B=t.getImageData(0,0,100,100).data;t.fillStyle="red",t.fillRect(0,0,100,100);var s=A.createElement("div");return s.style.backgroundImage="url("+a+")",s.style.height="100px",n(B)?(0,r.loadSerializedSVG)((0,r.createForeignObjectSVG)(100,100,0,0,s)):Promise.reject(!1)}).then(function(A){return t.drawImage(A,0,0),n(t.getImageData(0,0,100,100).data)}).catch(function(A){return!1})}(document):Promise.resolve(!1);return Object.defineProperty(B,"SUPPORT_FOREIGNOBJECT_DRAWING",{value:A}),A},get SUPPORT_CORS_IMAGES(){var A=void 0!==(new Image).crossOrigin;return Object.defineProperty(B,"SUPPORT_CORS_IMAGES",{value:A}),A},get SUPPORT_RESPONSE_TYPE(){var A="string"==typeof(new XMLHttpRequest).responseType;return Object.defineProperty(B,"SUPPORT_RESPONSE_TYPE",{value:A}),A},get SUPPORT_CORS_XHR(){var A="withCredentials"in new XMLHttpRequest;return Object.defineProperty(B,"SUPPORT_CORS_XHR",{value:A}),A}};e.default=B},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseTextDecoration=e.TEXT_DECORATION_LINE=e.TEXT_DECORATION=e.TEXT_DECORATION_STYLE=void 0;var r,n=t(0),B=(r=n)&&r.__esModule?r:{default:r};var a=e.TEXT_DECORATION_STYLE={SOLID:0,DOUBLE:1,DOTTED:2,DASHED:3,WAVY:4},s=e.TEXT_DECORATION={NONE:null},o=e.TEXT_DECORATION_LINE={UNDERLINE:1,OVERLINE:2,LINE_THROUGH:3,BLINK:4},i=function(A){switch(A){case"underline":return o.UNDERLINE;case"overline":return o.OVERLINE;case"line-through":return o.LINE_THROUGH}return o.BLINK};e.parseTextDecoration=function(A){var e,t="none"===(e=A.textDecorationLine?A.textDecorationLine:A.textDecoration)?null:e.split(" ").map(i);return null===t?s.NONE:{textDecorationLine:t,textDecorationColor:A.textDecorationColor?new B.default(A.textDecorationColor):null,textDecorationStyle:function(A){switch(A){case"double":return a.DOUBLE;case"dotted":return a.DOTTED;case"dashed":return a.DASHED;case"wavy":return a.WAVY}return a.SOLID}(A.textDecorationStyle)}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseBorder=e.BORDER_SIDES=e.BORDER_STYLE=void 0;var r,n=t(0),B=(r=n)&&r.__esModule?r:{default:r};var a=e.BORDER_STYLE={NONE:0,SOLID:1},s=e.BORDER_SIDES={TOP:0,RIGHT:1,BOTTOM:2,LEFT:3},o=Object.keys(s).map(function(A){return A.toLowerCase()});e.parseBorder=function(A){return o.map(function(e){var t=new B.default(A.getPropertyValue("border-"+e+"-color")),r=function(A){switch(A){case"none":return a.NONE}return a.SOLID}(A.getPropertyValue("border-"+e+"-style")),n=parseFloat(A.getPropertyValue("border-"+e+"-width"));return{borderColor:t,borderStyle:r,borderWidth:isNaN(n)?0:n}})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.toCodePoints=function(A){for(var e=[],t=0,r=A.length;t=55296&&n<=56319&&t>10),n%1024+56320)),(t+1===A||e.length>16384)&&(r+=String.fromCharCode.apply(String,e),e.length=0)}return r};for(var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n="undefined"==typeof Uint8Array?[]:new Uint8Array(256),B=0;B>4,l[B++]=(15&s)<<4|o>>2,l[B++]=(3&o)<<6|63&i;return c},e.polyUint16Array=function(A){for(var e=A.length,t=[],r=0;rt?F(A,n,B.length>0):r.integers.reduce(function(e,t,n){for(;A>=t;)A-=t,e+=r.values[n];return e},"")+B},U=function(A,e,t,r){var n="";do{t||A--,n=r(A)+n,A/=e}while(A*e>=e);return n},g=function(A,e,t,r,n){var B=t-e+1;return(A<0?"-":"")+(U(Math.abs(A),B,r,function(A){return(0,s.fromCodePoint)(Math.floor(A%B)+e)})+n)},C=function(A,e){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:". ",r=e.length;return U(Math.abs(A),r,!1,function(A){return e[Math.floor(A%r)]})+t},d=function(A,e,t,n,B,s){if(A<-9999||A>9999)return F(A,a.LIST_STYLE_TYPE.CJK_DECIMAL,B.length>0);var o=Math.abs(A),i=B;if(0===o)return e[0]+i;for(var c=0;o>0&&c<=4;c++){var l=o%10;0===l&&(0,r.contains)(s,1)&&""!==i?i=e[l]+i:l>1||1===l&&0===c||1===l&&1===c&&(0,r.contains)(s,2)||1===l&&1===c&&(0,r.contains)(s,4)&&A>100||1===l&&c>1&&(0,r.contains)(s,8)?i=e[l]+(c>0?t[c-1]:"")+i:1===l&&c>0&&(i=t[c-1]+i),o=Math.floor(o/10)}return(A<0?n:"")+i},F=e.createCounterText=function(A,e,t){var r=t?". ":"",n=t?"、":"",B=t?", ":"";switch(e){case a.LIST_STYLE_TYPE.DISC:return"•";case a.LIST_STYLE_TYPE.CIRCLE:return"◦";case a.LIST_STYLE_TYPE.SQUARE:return"◾";case a.LIST_STYLE_TYPE.DECIMAL_LEADING_ZERO:var s=g(A,48,57,!0,r);return s.length<4?"0"+s:s;case a.LIST_STYLE_TYPE.CJK_DECIMAL:return C(A,"〇一二三四五六七八九",n);case a.LIST_STYLE_TYPE.LOWER_ROMAN:return w(A,1,3999,c,a.LIST_STYLE_TYPE.DECIMAL,r).toLowerCase();case a.LIST_STYLE_TYPE.UPPER_ROMAN:return w(A,1,3999,c,a.LIST_STYLE_TYPE.DECIMAL,r);case a.LIST_STYLE_TYPE.LOWER_GREEK:return g(A,945,969,!1,r);case a.LIST_STYLE_TYPE.LOWER_ALPHA:return g(A,97,122,!1,r);case a.LIST_STYLE_TYPE.UPPER_ALPHA:return g(A,65,90,!1,r);case a.LIST_STYLE_TYPE.ARABIC_INDIC:return g(A,1632,1641,!0,r);case a.LIST_STYLE_TYPE.ARMENIAN:case a.LIST_STYLE_TYPE.UPPER_ARMENIAN:return w(A,1,9999,l,a.LIST_STYLE_TYPE.DECIMAL,r);case a.LIST_STYLE_TYPE.LOWER_ARMENIAN:return w(A,1,9999,l,a.LIST_STYLE_TYPE.DECIMAL,r).toLowerCase();case a.LIST_STYLE_TYPE.BENGALI:return g(A,2534,2543,!0,r);case a.LIST_STYLE_TYPE.CAMBODIAN:case a.LIST_STYLE_TYPE.KHMER:return g(A,6112,6121,!0,r);case a.LIST_STYLE_TYPE.CJK_EARTHLY_BRANCH:return C(A,"子丑寅卯辰巳午未申酉戌亥",n);case a.LIST_STYLE_TYPE.CJK_HEAVENLY_STEM:return C(A,"甲乙丙丁戊己庚辛壬癸",n);case a.LIST_STYLE_TYPE.CJK_IDEOGRAPHIC:case a.LIST_STYLE_TYPE.TRAD_CHINESE_INFORMAL:return d(A,"零一二三四五六七八九","十百千萬","負",n,14);case a.LIST_STYLE_TYPE.TRAD_CHINESE_FORMAL:return d(A,"零壹貳參肆伍陸柒捌玖","拾佰仟萬","負",n,15);case a.LIST_STYLE_TYPE.SIMP_CHINESE_INFORMAL:return d(A,"零一二三四五六七八九","十百千萬","负",n,14);case a.LIST_STYLE_TYPE.SIMP_CHINESE_FORMAL:return d(A,"零壹贰叁肆伍陆柒捌玖","拾佰仟萬","负",n,15);case a.LIST_STYLE_TYPE.JAPANESE_INFORMAL:return d(A,"〇一二三四五六七八九","十百千万","マイナス",n,0);case a.LIST_STYLE_TYPE.JAPANESE_FORMAL:return d(A,"零壱弐参四伍六七八九","拾百千万","マイナス",n,7);case a.LIST_STYLE_TYPE.KOREAN_HANGUL_FORMAL:return d(A,"영일이삼사오육칠팔구","십백천만","마이너스 ",B,7);case a.LIST_STYLE_TYPE.KOREAN_HANJA_INFORMAL:return d(A,"零一二三四五六七八九","十百千萬","마이너스 ",B,0);case a.LIST_STYLE_TYPE.KOREAN_HANJA_FORMAL:return d(A,"零壹貳參四五六七八九","拾百千","마이너스 ",B,7);case a.LIST_STYLE_TYPE.DEVANAGARI:return g(A,2406,2415,!0,r);case a.LIST_STYLE_TYPE.GEORGIAN:return w(A,1,19999,Q,a.LIST_STYLE_TYPE.DECIMAL,r);case a.LIST_STYLE_TYPE.GUJARATI:return g(A,2790,2799,!0,r);case a.LIST_STYLE_TYPE.GURMUKHI:return g(A,2662,2671,!0,r);case a.LIST_STYLE_TYPE.HEBREW:return w(A,1,10999,u,a.LIST_STYLE_TYPE.DECIMAL,r);case a.LIST_STYLE_TYPE.HIRAGANA:return C(A,"あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをん");case a.LIST_STYLE_TYPE.HIRAGANA_IROHA:return C(A,"いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす");case a.LIST_STYLE_TYPE.KANNADA:return g(A,3302,3311,!0,r);case a.LIST_STYLE_TYPE.KATAKANA:return C(A,"アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン",n);case a.LIST_STYLE_TYPE.KATAKANA_IROHA:return C(A,"イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス",n);case a.LIST_STYLE_TYPE.LAO:return g(A,3792,3801,!0,r);case a.LIST_STYLE_TYPE.MONGOLIAN:return g(A,6160,6169,!0,r);case a.LIST_STYLE_TYPE.MYANMAR:return g(A,4160,4169,!0,r);case a.LIST_STYLE_TYPE.ORIYA:return g(A,2918,2927,!0,r);case a.LIST_STYLE_TYPE.PERSIAN:return g(A,1776,1785,!0,r);case a.LIST_STYLE_TYPE.TAMIL:return g(A,3046,3055,!0,r);case a.LIST_STYLE_TYPE.TELUGU:return g(A,3174,3183,!0,r);case a.LIST_STYLE_TYPE.THAI:return g(A,3664,3673,!0,r);case a.LIST_STYLE_TYPE.TIBETAN:return g(A,3872,3881,!0,r);case a.LIST_STYLE_TYPE.DECIMAL:default:return g(A,48,57,!0,r)}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function A(A,e){for(var t=0;tA.height?(A.left+=(A.width-A.height)/2,A.width=A.height):A.width0&&B){var a=e.ownerDocument.createElement("html2canvaswrapper");(0,c.copyCSSStyles)(e.ownerDocument.defaultView.getComputedStyle(e,null),a),a.style.position="absolute",a.style.left=t.bounds.left+"px",a.style.top=t.bounds.top+"px",n||(a.style.whiteSpace="nowrap");var s=e.ownerDocument.createTextNode(A);a.appendChild(s),B.appendChild(a),t.childNodes.push(r.default.fromTextNode(s,t)),B.removeChild(a)}}),h=function(A){var e="password"===A.type?new Array(A.value.length+1).join("•"):A.value;return 0===e.length?A.placeholder||"":e}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseTextBounds=e.TextBounds=void 0;var r,n=t(2),B=t(11),a=t(10),s=(r=a)&&r.__esModule?r:{default:r},o=t(24);var i=e.TextBounds=function A(e,t){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.text=e,this.bounds=t},c=(e.parseTextBounds=function(A,e,t){for(var r=0!==e.style.letterSpacing?(0,o.toCodePoints)(A).map(function(A){return(0,o.fromCodePoint)(A)}):(0,o.breakWords)(A,e),n=r.length,a=t.parentNode?t.parentNode.ownerDocument.defaultView:null,u=a?a.pageXOffset:0,Q=a?a.pageYOffset:0,w=[],U=0,g=0;g0)if(s.default.SUPPORT_RANGE_BOUNDS)w.push(new i(C,l(t,U,C.length,u,Q)));else{var d=t.splitText(C.length);w.push(new i(C,c(t,u,Q))),t=d}else s.default.SUPPORT_RANGE_BOUNDS||(t=t.splitText(C.length));U+=C.length}return w},function(A,e,t){var r=A.ownerDocument.createElement("html2canvaswrapper");r.appendChild(A.cloneNode(!0));var B=A.parentNode;if(B){B.replaceChild(r,A);var a=(0,n.parseBounds)(r,e,t);return r.firstChild&&B.replaceChild(r.firstChild,r),a}return new n.Bounds(0,0,0,0)}),l=function(A,e,t,r,B){var a=A.ownerDocument.createRange();return a.setStart(A,e),a.setEnd(A,e+t),n.Bounds.fromClientRect(a.getBoundingClientRect(),r,B)}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function A(A,e){for(var t=0;t0&&t.childNodes.push(B.default.fromTextNode(g,t));else if(g instanceof C.HTMLElement||g instanceof HTMLElement||C.parent&&g instanceof C.parent.HTMLElement){if(-1===c.indexOf(g.nodeName)){var d=new n.default(g,t,l,w++);if(d.isVisible()){"INPUT"===g.tagName?(0,a.inlineInputElement)(g,d):"TEXTAREA"===g.tagName?(0,a.inlineTextAreaElement)(g,d):"SELECT"===g.tagName?(0,a.inlineSelectElement)(g,d):d.style.listStyle&&d.style.listStyle.listStyleType!==o.LIST_STYLE_TYPE.NONE&&(0,s.inlineListItemElement)(g,d,l);var F="TEXTAREA"!==g.tagName,E=u(d,g);if(E||Q(d)){var f=E||d.isPositioned()?i.getRealParentStackingContext():i,h=new r.default(d,f,E);f.contexts.push(h),F&&A(g,d,h,l,w)}else i.children.push(d),F&&A(g,d,i,l,w)}}}else if(g instanceof C.SVGSVGElement||g instanceof SVGSVGElement||C.parent&&g instanceof C.parent.SVGSVGElement){var H=new n.default(g,t,l,w++),p=u(H,g);if(p||Q(H)){var N=p||H.isPositioned()?i.getRealParentStackingContext():i,I=new r.default(H,N,p);N.contexts.push(I)}else i.children.push(H)}}},u=function(A,e){return A.isRootElement()||A.isPositionedWithZIndex()||A.style.opacity<1||A.isTransformed()||w(A,e)},Q=function(A){return A.isPositioned()||A.isFloating()},w=function(A,e){return"BODY"===e.nodeName&&A.parent instanceof n.default&&A.parent.style.background.backgroundColor.isTransparent()}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r,n=function(){function A(A,e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"strict",t=[],r=[],n=[];return A.forEach(function(A,B){var a=O.get(A);if(a>c?(n.push(!0),a-=c):n.push(!1),-1!==["normal","auto","loose"].indexOf(e)&&-1!==[8208,8211,12316,12448].indexOf(A))return r.push(B),t.push(16);if(4===a||11===a){if(0===B)return r.push(B),t.push(N);var s=t[B-1];return-1===x.indexOf(s)?(r.push(r[B-1]),t.push(s)):(r.push(B),t.push(N))}return r.push(B),31===a?t.push("strict"===e?d:v):a===L?t.push(N):29===a?t.push(N):43===a?A>=131072&&A<=196605||A>=196608&&A<=262141?t.push(v):t.push(N):void t.push(a)}),[r,t,n]},G=function(A,e,t,r){var n=r[t];if(Array.isArray(A)?-1!==A.indexOf(n):A===n)for(var B=t;B<=r.length;){var a=r[++B];if(a===e)return!0;if(a!==l)break}if(n===l)for(var s=t;s>0;){var o=r[--s];if(Array.isArray(A)?-1!==A.indexOf(o):A===o)for(var i=t;i<=r.length;){var c=r[++i];if(c===e)return!0;if(c!==l)break}if(o!==l)break}return!1},Y=function(A,e){for(var t=A;t>=0;){var r=e[t];if(r!==l)return r;t--}return 0},W=function(A,e,t,r,n){if(0===t[r])return D;var B=r-1;if(Array.isArray(n)&&!0===n[B])return D;var a=B-1,s=B+1,o=e[B],i=a>=0?e[a]:0,c=e[s];if(2===o&&3===c)return D;if(-1!==P.indexOf(o))return _;if(-1!==P.indexOf(c))return D;if(-1!==X.indexOf(c))return D;if(8===Y(B,e))return M;if(11===O.get(A[B])&&(c===v||c===I||c===K))return D;if(7===o||7===c)return D;if(9===o)return D;if(-1===[l,u,Q].indexOf(o)&&9===c)return D;if(-1!==[w,U,g,E,p].indexOf(c))return D;if(Y(B,e)===F)return D;if(G(23,F,B,e))return D;if(G([w,U],d,B,e))return D;if(G(12,12,B,e))return D;if(o===l)return M;if(23===o||23===c)return D;if(16===c||16===o)return M;if(-1!==[u,Q,d].indexOf(c)||14===o)return D;if(36===i&&-1!==k.indexOf(o))return D;if(o===p&&36===c)return D;if(c===C&&-1!==R.concat(C,g,f,v,I,K).indexOf(o))return D;if(-1!==R.indexOf(c)&&o===f||-1!==R.indexOf(o)&&c===f)return D;if(o===H&&-1!==[v,I,K].indexOf(c)||-1!==[v,I,K].indexOf(o)&&c===h)return D;if(-1!==R.indexOf(o)&&-1!==z.indexOf(c)||-1!==z.indexOf(o)&&-1!==R.indexOf(c))return D;if(-1!==[H,h].indexOf(o)&&(c===f||-1!==[F,Q].indexOf(c)&&e[s+1]===f)||-1!==[F,Q].indexOf(o)&&c===f||o===f&&-1!==[f,p,E].indexOf(c))return D;if(-1!==[f,p,E,w,U].indexOf(c))for(var N=B;N>=0;){var L=e[N];if(L===f)return D;if(-1===[p,E].indexOf(L))break;N--}if(-1!==[H,h].indexOf(c))for(var x=-1!==[w,U].indexOf(o)?a:B;x>=0;){var J=e[x];if(J===f)return D;if(-1===[p,E].indexOf(J))break;x--}if(y===o&&-1!==[y,b,T,m].indexOf(c)||-1!==[b,T].indexOf(o)&&-1!==[b,S].indexOf(c)||-1!==[S,m].indexOf(o)&&c===S)return D;if(-1!==V.indexOf(o)&&-1!==[C,h].indexOf(c)||-1!==V.indexOf(c)&&o===H)return D;if(-1!==R.indexOf(o)&&-1!==R.indexOf(c))return D;if(o===E&&-1!==R.indexOf(c))return D;if(-1!==R.concat(f).indexOf(o)&&c===F||-1!==R.concat(f).indexOf(c)&&o===U)return D;if(41===o&&41===c){for(var W=t[B],j=1;W>0&&41===e[--W];)j++;if(j%2!=0)return D}return o===I&&c===K?D:M},j=(e.lineBreakAtIndex=function(A,e){if(0===e)return D;if(e>=A.length)return _;var t=J(A),r=B(t,2),n=r[0],a=r[1];return W(A,a,n,e)},function(A,e){e||(e={lineBreak:"normal",wordBreak:"normal"});var t=J(A,e.lineBreak),r=B(t,3),n=r[0],a=r[1],s=r[2];return"break-all"!==e.wordBreak&&"break-word"!==e.wordBreak||(a=a.map(function(A){return-1!==[f,N,L].indexOf(A)?v:A})),[n,a,"keep-all"===e.wordBreak?s.map(function(e,t){return e&&A[t]>=19968&&A[t]<=40959}):null]}),q=(e.inlineBreakOpportunities=function(A,e){var t=(0,i.toCodePoints)(A),r=D,n=j(t,e),a=B(n,3),s=a[0],o=a[1],c=a[2];return t.forEach(function(A,e){r+=(0,i.fromCodePoint)(A)+(e>=t.length-1?_:W(t,o,s,e+1,c))}),r},function(){function A(e,t,r,n){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this._codePoints=e,this.required=t===_,this.start=r,this.end=n}return n(A,[{key:"slice",value:function(){return i.fromCodePoint.apply(void 0,function(A){if(Array.isArray(A)){for(var e=0,t=Array(A.length);e=c)return{done:!0};for(var A=D;u>B,c=e.UTRIE2_DATA_BLOCK_LENGTH=1<>B,Q=e.UTRIE2_INDEX_2_BMP_LENGTH=i+u,w=e.UTRIE2_UTF8_2B_INDEX_2_OFFSET=Q,U=e.UTRIE2_UTF8_2B_INDEX_2_LENGTH=32,g=e.UTRIE2_INDEX_1_OFFSET=w+U,C=e.UTRIE2_OMITTED_BMP_INDEX_1_LENGTH=65536>>a,d=e.UTRIE2_INDEX_2_BLOCK_LENGTH=1<=0){if(A<55296||A>56319&&A<=65535)return e=((e=this.index[A>>B])<>B)])<>a),e=this.index[e],e+=A>>B&F,e=((e=this.index[e])<0?t.width:r.width,B="number"==typeof t.height&&t.height>0?t.height:r.height;n>0&&B>0&&e.target.clip([(0,a.calculatePaddingBoxPath)(A.curvedBounds)],function(){e.target.drawImage(t,new a.Bounds(0,0,n,B),r)})}}},r=A.getClipPaths();r.length?this.target.clip(r,t):t()}},{key:"renderNodeBackgroundAndBorders",value:function(A){var e=this,t=!A.style.background.backgroundColor.isTransparent()||A.style.background.backgroundImage.length,r=A.style.border.some(function(A){return A.borderStyle!==l.BORDER_STYLE.NONE&&!A.borderColor.isTransparent()}),n=function(){var r=(0,c.calculateBackgroungPaintingArea)(A.curvedBounds,A.style.background.backgroundClip);t&&e.target.clip([r],function(){A.style.background.backgroundColor.isTransparent()||e.target.fill(A.style.background.backgroundColor),e.renderBackgroundImage(A)}),A.style.border.forEach(function(t,r){t.borderStyle===l.BORDER_STYLE.NONE||t.borderColor.isTransparent()||e.renderBorder(t,r,A.curvedBounds)})};if(t||r){var B=A.parent?A.parent.getClipPaths():[];B.length?this.target.clip(B,n):n()}}},{key:"renderBackgroundImage",value:function(A){var e=this;A.style.background.backgroundImage.slice(0).reverse().forEach(function(t){"url"===t.source.method&&t.source.args.length?e.renderBackgroundRepeat(A,t):/gradient/i.test(t.source.method)&&e.renderBackgroundGradient(A,t)})}},{key:"renderBackgroundRepeat",value:function(A,e){var t=this.options.imageStore.get(e.source.args[0]);if(t){var r=(0,c.calculateBackgroungPositioningArea)(A.style.background.backgroundOrigin,A.bounds,A.style.padding,A.style.border),n=(0,c.calculateBackgroundSize)(e,t,r),B=(0,c.calculateBackgroundPosition)(e.position,n,r),a=(0,c.calculateBackgroundRepeatPath)(e,B,n,r,A.bounds),s=Math.round(r.left+B.x),o=Math.round(r.top+B.y);this.target.renderRepeat(a,t,n,s,o)}}},{key:"renderBackgroundGradient",value:function(A,e){var t=(0,c.calculateBackgroungPositioningArea)(A.style.background.backgroundOrigin,A.bounds,A.style.padding,A.style.border),r=(0,c.calculateGradientBackgroundSize)(e,t),n=(0,c.calculateBackgroundPosition)(e.position,r,t),B=new a.Bounds(Math.round(t.left+n.x),Math.round(t.top+n.y),r.width,r.height),o=(0,s.parseGradient)(A,e.source,B);if(o)switch(o.type){case s.GRADIENT_TYPE.LINEAR_GRADIENT:this.target.renderLinearGradient(B,o);break;case s.GRADIENT_TYPE.RADIAL_GRADIENT:this.target.renderRadialGradient(B,o)}}},{key:"renderBorder",value:function(A,e,t){this.target.drawShape((0,a.parsePathForBorder)(t,e),A.borderColor)}},{key:"renderStack",value:function(A){var e=this;if(A.container.isVisible()){var t=A.getOpacity();t!==this._opacity&&(this.target.setOpacity(A.getOpacity()),this._opacity=t);var r=A.container.style.transform;null!==r?this.target.transform(A.container.bounds.left+r.transformOrigin[0].value,A.container.bounds.top+r.transformOrigin[1].value,r.transform,function(){return e.renderStackContent(A)}):this.renderStackContent(A)}}},{key:"renderStackContent",value:function(A){var e=w(A),t=n(e,5),r=t[0],B=t[1],a=t[2],s=t[3],o=t[4],i=Q(A),c=n(i,2),l=c[0],u=c[1];this.renderNodeBackgroundAndBorders(A.container),r.sort(U).forEach(this.renderStack,this),this.renderNodeContent(A.container),u.forEach(this.renderNode,this),s.forEach(this.renderStack,this),o.forEach(this.renderStack,this),l.forEach(this.renderNode,this),B.forEach(this.renderStack,this),a.sort(U).forEach(this.renderStack,this)}},{key:"render",value:function(A){this.options.backgroundColor&&this.target.rectangle(this.options.x,this.options.y,this.options.width,this.options.height,this.options.backgroundColor),this.renderStack(A);var e=this.target.getTarget();return e}}]),A}();e.default=u;var Q=function(A){for(var e=[],t=[],r=A.children.length,n=0;n0?r.push(o):t.push(o):o.container.isFloating()?n.push(o):B.push(o)}return[e,t,r,n,B]},U=function(A,e){return A.container.style.zIndex.order>e.container.style.zIndex.order?1:A.container.style.zIndex.ordere.container.index?1:-1}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.transformWebkitRadialGradientArgs=e.parseGradient=e.RadialGradient=e.LinearGradient=e.RADIAL_GRADIENT_SHAPE=e.GRADIENT_TYPE=void 0;var r=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),n=(i(t(3)),t(53)),B=i(t(0)),a=t(1),s=i(a),o=t(4);function i(A){return A&&A.__esModule?A:{default:A}}function c(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}var l=/^(to )?(left|top|right|bottom)( (left|top|right|bottom))?$/i,u=/^([+-]?\d*\.?\d+)% ([+-]?\d*\.?\d+)%$/i,Q=/(px)|%|( 0)$/i,w=/^(from|to|color-stop)\((?:([\d.]+)(%)?,\s*)?(.+?)\)$/i,U=/^\s*(circle|ellipse)?\s*((?:([\d.]+)(px|r?em|%)\s*(?:([\d.]+)(px|r?em|%))?)|closest-side|closest-corner|farthest-side|farthest-corner)?\s*(?:at\s*(?:(left|center|right)|([\d.]+)(px|r?em|%))\s+(?:(top|center|bottom)|([\d.]+)(px|r?em|%)))?(?:\s|$)/i,g=e.GRADIENT_TYPE={LINEAR_GRADIENT:0,RADIAL_GRADIENT:1},C=e.RADIAL_GRADIENT_SHAPE={CIRCLE:0,ELLIPSE:1},d={left:new s.default("0%"),top:new s.default("0%"),center:new s.default("50%"),right:new s.default("100%"),bottom:new s.default("100%")},F=e.LinearGradient=function A(e,t){c(this,A),this.type=g.LINEAR_GRADIENT,this.colorStops=e,this.direction=t},E=e.RadialGradient=function A(e,t,r,n){c(this,A),this.type=g.RADIAL_GRADIENT,this.colorStops=e,this.shape=t,this.center=r,this.radius=n},f=(e.parseGradient=function(A,e,t){var r=e.args,n=e.method,B=e.prefix;return"linear-gradient"===n?h(r,t,!!B):"gradient"===n&&"linear"===r[0]?h(["to bottom"].concat(y(r.slice(3))),t,!!B):"radial-gradient"===n?H(A,"-webkit-"===B?v(r):r,t):"gradient"===n&&"radial"===r[0]?H(A,y(v(r.slice(1))),t):void 0},function(A,e,t){for(var r=[],n=e;nA.optimumDistance)?{optimumCorner:n,optimumDistance:B}:A},{optimumDistance:r?1/0:-1/0,optimumCorner:null}).optimumCorner},m=function(A,e,t,r,n){var B=t.x,a=t.y,s=0,i=0;switch(A){case"closest-side":e===C.CIRCLE?s=i=Math.min(Math.abs(B),Math.abs(B-n.width),Math.abs(a),Math.abs(a-n.height)):e===C.ELLIPSE&&(s=Math.min(Math.abs(B),Math.abs(B-n.width)),i=Math.min(Math.abs(a),Math.abs(a-n.height)));break;case"closest-corner":if(e===C.CIRCLE)s=i=Math.min((0,o.distance)(B,a),(0,o.distance)(B,a-n.height),(0,o.distance)(B-n.width,a),(0,o.distance)(B-n.width,a-n.height));else if(e===C.ELLIPSE){var c=Math.min(Math.abs(a),Math.abs(a-n.height))/Math.min(Math.abs(B),Math.abs(B-n.width)),l=T(n,B,a,!0);i=c*(s=(0,o.distance)(l.x-B,(l.y-a)/c))}break;case"farthest-side":e===C.CIRCLE?s=i=Math.max(Math.abs(B),Math.abs(B-n.width),Math.abs(a),Math.abs(a-n.height)):e===C.ELLIPSE&&(s=Math.max(Math.abs(B),Math.abs(B-n.width)),i=Math.max(Math.abs(a),Math.abs(a-n.height)));break;case"farthest-corner":if(e===C.CIRCLE)s=i=Math.max((0,o.distance)(B,a),(0,o.distance)(B,a-n.height),(0,o.distance)(B-n.width,a),(0,o.distance)(B-n.width,a-n.height));else if(e===C.ELLIPSE){var u=Math.max(Math.abs(a),Math.abs(a-n.height))/Math.max(Math.abs(B),Math.abs(B-n.width)),Q=T(n,B,a,!1);i=u*(s=(0,o.distance)(Q.x-B,(Q.y-a)/u))}break;default:s=r.x||0,i=void 0!==r.y?r.y:s}return{x:s,y:i}},v=e.transformWebkitRadialGradientArgs=function(A){var e="",t="",r="",n="",B=0,a=/^(left|center|right|\d+(?:px|r?em|%)?)(?:\s+(top|center|bottom|\d+(?:px|r?em|%)?))?$/i,s=/^\d+(px|r?em|%)?(?:\s+\d+(px|r?em|%)?)?$/i,o=A[B].match(a);o&&B++;var i=A[B].match(/^(circle|ellipse)?\s*(closest-side|closest-corner|farthest-side|farthest-corner|contain|cover)?$/i);i&&(e=i[1]||"","contain"===(r=i[2]||"")?r="closest-side":"cover"===r&&(r="farthest-corner"),B++);var c=A[B].match(s);c&&B++;var l=A[B].match(a);l&&B++;var u=A[B].match(s);u&&B++;var Q=l||o;Q&&Q[1]&&(n=Q[1]+(/^\d+$/.test(Q[1])?"px":""),Q[2]&&(n+=" "+Q[2]+(/^\d+$/.test(Q[2])?"px":"")));var w=u||c;return w&&(t=w[0],w[1]||(t+="px")),!n||e||t||r||(t=n,n=""),n&&(n="at "+n),[[e,r,t,n].filter(function(A){return!!A}).join(" ")].concat(A.slice(B))},y=function(A){return A.map(function(A){return A.match(w)}).map(function(e,t){if(!e)return A[t];switch(e[1]){case"from":return e[4]+" 0%";case"to":return e[4]+" 100%";case"color-stop":return"%"===e[3]?e[4]+" "+e[2]:e[4]+" "+100*parseFloat(e[2])+"%"}})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=/([+-]?\d*\.?\d+)(deg|grad|rad|turn)/i;e.parseAngle=function(A){var e=A.match(r);if(e){var t=parseFloat(e[1]);switch(e[2].toLowerCase()){case"deg":return Math.PI*t/180;case"grad":return Math.PI/200*t;case"rad":return t;case"turn":return 2*Math.PI*t}}return null}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.cloneWindow=e.DocumentCloner=void 0;var r=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),n=function(){function A(A,e){for(var t=0;t1&&(t.backgroundColor=""),t.backgroundImage=A.join(",")}),A instanceof HTMLImageElement&&this.resourceLoader.inlineImage(A.src).then(function(e){if(e&&A instanceof HTMLImageElement&&A.parentNode){var t=A.parentNode,r=(0,o.copyCSSStyles)(A.style,e.cloneNode(!1));t.replaceChild(r,A)}}).catch(function(A){0})}}},{key:"inlineFonts",value:function(A){var e=this;return Promise.all(Array.from(A.styleSheets).map(function(e){return e.href?fetch(e.href).then(function(A){return A.text()}).then(function(A){return U(A,e.href)}).catch(function(A){return[]}):w(e,A)})).then(function(A){return A.reduce(function(A,e){return A.concat(e)},[])}).then(function(A){return Promise.all(A.map(function(A){return fetch(A.formats[0].src).then(function(A){return A.blob()}).then(function(A){return new Promise(function(e,t){var r=new FileReader;r.onerror=t,r.onload=function(){var A=r.result;e(A)},r.readAsDataURL(A)})}).then(function(e){return A.fontFace.setProperty("src",'url("'+e+'")'),"@font-face {"+A.fontFace.cssText+" "})}))}).then(function(t){var r=A.createElement("style");r.textContent=t.join("\n"),e.documentElement.appendChild(r)})}},{key:"createElementClone",value:function(A){var e=this;if(this.copyStyles&&A instanceof HTMLCanvasElement){var t=A.ownerDocument.createElement("img");try{return t.src=A.toDataURL(),t}catch(A){0}}if(A instanceof HTMLIFrameElement){var r=A.cloneNode(!1),n=N();r.setAttribute("data-html2canvas-internal-iframe-key",n);var a=(0,B.parseBounds)(A,0,0),s=a.width,i=a.height;return this.resourceLoader.cache[n]=K(A,this.options).then(function(A){return e.renderer(A,{async:e.options.async,allowTaint:e.options.allowTaint,backgroundColor:"#ffffff",canvas:null,imageTimeout:e.options.imageTimeout,logging:e.options.logging,proxy:e.options.proxy,removeContainer:e.options.removeContainer,scale:e.options.scale,foreignObjectRendering:e.options.foreignObjectRendering,useCORS:e.options.useCORS,target:new c.default,width:s,height:i,x:0,y:0,windowWidth:A.ownerDocument.defaultView.innerWidth,windowHeight:A.ownerDocument.defaultView.innerHeight,scrollX:A.ownerDocument.defaultView.pageXOffset,scrollY:A.ownerDocument.defaultView.pageYOffset},e.logger.child(n))}).then(function(e){return new Promise(function(t,n){var B=document.createElement("img");B.onload=function(){return t(e)},B.onerror=n,B.src=e.toDataURL(),r.parentNode&&r.parentNode.replaceChild((0,o.copyCSSStyles)(A.ownerDocument.defaultView.getComputedStyle(A),B),r)})}),r}if(A instanceof HTMLStyleElement&&A.sheet&&A.sheet.cssRules){var l=[].slice.call(A.sheet.cssRules,0).reduce(function(A,t){try{return t&&t.cssText?A+t.cssText:A}catch(r){return e.logger.log("Unable to access cssText property",t.name),A}},""),u=A.cloneNode(!1);return u.textContent=l,u}return A.cloneNode(!1)}},{key:"cloneNode",value:function(A){var e=A.nodeType===Node.TEXT_NODE?document.createTextNode(A.nodeValue):this.createElementClone(A),t=A.ownerDocument.defaultView,r=A instanceof t.HTMLElement?t.getComputedStyle(A):null,n=A instanceof t.HTMLElement?t.getComputedStyle(A,":before"):null,B=A instanceof t.HTMLElement?t.getComputedStyle(A,":after"):null;this.referenceElement===A&&e instanceof t.HTMLElement&&(this.clonedReferenceElement=e),e instanceof t.HTMLBodyElement&&h(e);for(var a=(0,l.parseCounterReset)(r,this.pseudoContentData),s=(0,l.resolvePseudoContent)(A,n,this.pseudoContentData),i=A.firstChild;i;i=i.nextSibling)i.nodeType===Node.ELEMENT_NODE&&("SCRIPT"===i.nodeName||i.hasAttribute("data-html2canvas-ignore")||"function"==typeof this.options.ignoreElements&&this.options.ignoreElements(i))||this.copyStyles&&"STYLE"===i.nodeName||e.appendChild(this.cloneNode(i));var c=(0,l.resolvePseudoContent)(A,B,this.pseudoContentData);if((0,l.popCounters)(a,this.pseudoContentData),A instanceof t.HTMLElement&&e instanceof t.HTMLElement)switch(n&&this.inlineAllImages(C(A,e,n,s,d)),B&&this.inlineAllImages(C(A,e,B,c,F)),!r||!this.copyStyles||A instanceof HTMLIFrameElement||(0,o.copyCSSStyles)(r,e),this.inlineAllImages(e),0===A.scrollTop&&0===A.scrollLeft||this.scrolledElements.push([e,A.scrollLeft,A.scrollTop]),A.nodeName){case"CANVAS":this.copyStyles||g(A,e);break;case"TEXTAREA":case"SELECT":e.value=A.value}return e}}]),A}(),w=function(A,e){return(A.cssRules?Array.from(A.cssRules):[]).filter(function(A){return A.type===CSSRule.FONT_FACE_RULE}).map(function(A){for(var t=(0,i.parseBackgroundImage)(A.style.getPropertyValue("src")),r=[],n=0;n0&&"complete"===t.readyState&&(clearInterval(e),r(A))},50)}})},v=(e.cloneWindow=function(A,e,t,r,n,B){var a=new Q(t,r,n,!1,B),s=A.defaultView.pageXOffset,o=A.defaultView.pageYOffset;return T(A,e).then(function(n){var B=n.contentWindow,i=B.document,c=m(n).then(function(){a.scrolledElements.forEach(p),B.scrollTo(e.left,e.top),!/(iPad|iPhone|iPod)/g.test(navigator.userAgent)||B.scrollY===e.top&&B.scrollX===e.left||(i.documentElement.style.top=-e.top+"px",i.documentElement.style.left=-e.left+"px",i.documentElement.style.position="absolute");var t=Promise.resolve([n,a.clonedReferenceElement,a.resourceLoader]),s=r.onclone;return a.clonedReferenceElement instanceof B.HTMLElement||a.clonedReferenceElement instanceof A.defaultView.HTMLElement||a.clonedReferenceElement instanceof HTMLElement?"function"==typeof s?Promise.resolve().then(function(){return s(i)}).then(function(){return t}):t:Promise.reject("")});return i.open(),i.write(v(document.doctype)+""),function(A,e,t){!A.defaultView||e===A.defaultView.pageXOffset&&t===A.defaultView.pageYOffset||A.defaultView.scrollTo(e,t)}(t.ownerDocument,s,o),i.replaceChild(i.adoptNode(a.documentElement),i.documentElement),i.close(),c})},function(A){var e="";return A&&(e+=""),e})},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ResourceStore=void 0;var r,n=function(){function A(A,e){for(var t=0;t0&&t.push({type:s.ATTRIBUTE,value:l[0]});break;case"counter":if(l.length>0){var w={type:s.COUNTER,name:l[0]};l.length>1&&(w.format=l[1]),t.push(w)}break;case"counters":if(l.length>0){var U={type:s.COUNTERS,name:l[0]};l.length>1&&(U.glue=l[1]),l.length>2&&(U.format=l[2]),t.push(U)}break;case"url":l.length>0&&t.push({type:s.URL,value:l[0]})}a=!1,o=""}break;case",":n?o+=Q:a&&(l.push(o),o="");break;case" ":case"\t":n?o+=Q:o&&(i(t,o),o="");break;default:o+=Q}"\\"!==Q&&(B=!1)}return o&&i(t,o),e&&(e[A]=t),t}),i=function(A,e){switch(e){case"open-quote":A.push({type:s.OPENQUOTE});break;case"close-quote":A.push({type:s.CLOSEQUOTE})}},c=function(A,e,t){var r=A.quotes?A.quotes.split(/\s+/):["'\"'","'\"'"],n=2*t;return n>=r.length&&(n=r.length-2),e||++n,r[n].replace(/^["']|["']$/g,"")},l=function(A,e,t){for(var r=A.length,a="",s=0;s0&&(a+=e||""),a+=(0,n.createCounterText)(A[s],(0,B.parseListStyleType)(t||"decimal"),!1);return a}}])}); \ No newline at end of file diff --git a/vendor/masonry-4.2.0.pkgd.min.js b/vendor/masonry-4.2.0.pkgd.min.js deleted file mode 100644 index a61c0ded..00000000 --- a/vendor/masonry-4.2.0.pkgd.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Masonry PACKAGED v4.2.0 - * Cascading grid layout library - * http://masonry.desandro.com - * MIT License - * by David DeSandro - */ - -!function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,r,a){function h(t,e,n){var o,r="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void s(i+" not initialized. Cannot call methods, i.e. "+r);var d=u[e];if(!d||"_"==e.charAt(0))return void s(r+" is not a valid method");var l=d.apply(u,n);o=void 0===o?l:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new r(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(r.prototype.option||(r.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,r=t.console,s="undefined"==typeof r?function(){}:function(t){r.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("get-size/get-size",[],function(){return e()}):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;u>e;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);r.isBoxSizeOuter=s=200==t(o.width),i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==r.boxSizing,l=0;u>l;l++){var c=h[l],f=r[c],m=parseFloat(f);a[c]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,g=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,z=a.borderTopWidth+a.borderBottomWidth,E=d&&s,b=t(r.width);b!==!1&&(a.width=b+(E?0:p+_));var x=t(r.height);return x!==!1&&(a.height=x+(E?0:g+z)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(g+z),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var s,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,d=!1;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=window.Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;is?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},n.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},n._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this.options.horizontalOrder?"_getHorizontalColPosition":"_getTopColPosition",r=this[o](n,t),s={x:this.columnWidth*r.col,y:r.y},a=r.y+t.size.outerHeight,h=n+r.col,u=r.col;h>u;u++)this.colYs[u]=a;return s},n._getTopColPosition=function(t){var e=this._getTopColGroup(t),i=Math.min.apply(Math,e);return{col:e.indexOf(i),y:i}},n._getTopColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++)e[n]=this._getColGroupY(n,t);return e},n._getColGroupY=function(t,e){if(2>e)return this.colYs[t];var i=this.colYs.slice(t,t+e);return Math.max.apply(Math,i)},n._getHorizontalColPosition=function(t,e){var i=this.horizontalColIndex%this.cols,n=t>1&&i+t>this.cols;i=n?0:i;var o=e.size.outerWidth&&e.size.outerHeight;return this.horizontalColIndex=o?i+t:this.horizontalColIndex,{col:i,y:this._getColGroupY(i,t)}},n._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var h=Math.floor(s/this.columnWidth);h-=s%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var u=this._getOption("originTop"),d=(u?n.top:n.bottom)+i.outerHeight,l=a;h>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},n._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},n._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},n.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i}); \ No newline at end of file diff --git a/vendor/masonry.pkgd.min.js b/vendor/masonry.pkgd.min.js new file mode 100644 index 00000000..53386ae6 --- /dev/null +++ b/vendor/masonry.pkgd.min.js @@ -0,0 +1,9 @@ +/*! + * Masonry PACKAGED v4.2.2 + * Cascading grid layout library + * https://masonry.desandro.com + * MIT License + * by David DeSandro + */ + +!function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,r,a){function h(t,e,n){var o,r="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void s(i+" not initialized. Cannot call methods, i.e. "+r);var d=u[e];if(!d||"_"==e.charAt(0))return void s(r+" is not a valid method");var l=d.apply(u,n);o=void 0===o?l:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new r(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(r.prototype.option||(r.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,r=t.console,s="undefined"==typeof r?function(){}:function(t){r.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){i=i.slice(0),e=e||[];for(var n=this._onceEvents&&this._onceEvents[t],o=0;oe;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See https://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);s=200==Math.round(t(o.width)),r.isBoxSizeOuter=s,i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==r.boxSizing,l=0;u>l;l++){var c=h[l],f=r[c],m=parseFloat(f);a[c]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,g=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,z=a.borderTopWidth+a.borderBottomWidth,E=d&&s,b=t(r.width);b!==!1&&(a.width=b+(E?0:p+_));var x=t(r.height);return x!==!1&&(a.height=x+(E?0:g+z)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(g+z),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var s,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,d=!1;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=window.Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;is?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},n.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},n._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this.options.horizontalOrder?"_getHorizontalColPosition":"_getTopColPosition",r=this[o](n,t),s={x:this.columnWidth*r.col,y:r.y},a=r.y+t.size.outerHeight,h=n+r.col,u=r.col;h>u;u++)this.colYs[u]=a;return s},n._getTopColPosition=function(t){var e=this._getTopColGroup(t),i=Math.min.apply(Math,e);return{col:e.indexOf(i),y:i}},n._getTopColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++)e[n]=this._getColGroupY(n,t);return e},n._getColGroupY=function(t,e){if(2>e)return this.colYs[t];var i=this.colYs.slice(t,t+e);return Math.max.apply(Math,i)},n._getHorizontalColPosition=function(t,e){var i=this.horizontalColIndex%this.cols,n=t>1&&i+t>this.cols;i=n?0:i;var o=e.size.outerWidth&&e.size.outerHeight;return this.horizontalColIndex=o?i+t:this.horizontalColIndex,{col:i,y:this._getColGroupY(i,t)}},n._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var h=Math.floor(s/this.columnWidth);h-=s%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var u=this._getOption("originTop"),d=(u?n.top:n.bottom)+i.outerHeight,l=a;h>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},n._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},n._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},n.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i}); \ No newline at end of file
' + stat + ' ' + value + '