├── .editorconfig
├── .gitattributes
├── .gitignore
├── .gitmodules
├── .yarnclean
├── Fallout3.Hardcoded.dat
├── Fallout4.Hardcoded.dat
├── FalloutNV.Hardcoded.dat
├── LICENSE
├── Oblivion.Hardcoded.dat
├── README.md
├── Skyrim.Hardcoded.dat
├── XEditLib.dll
├── app
├── app.html
├── bethesdaFiles.json
├── directives
│ ├── apiItems.html
│ ├── autocompleteInput.html
│ ├── cellEditor.html
│ ├── childrenTopics.html
│ ├── colorInput.html
│ ├── colorSelector.html
│ ├── contextMenu.html
│ ├── contextMenuDivider.html
│ ├── contextMenuItem.html
│ ├── dropdown.html
│ ├── dropover.html
│ ├── elementView.html
│ ├── enumSelect.html
│ ├── enumerationMembers.html
│ ├── errorGroup.html
│ ├── errorResolutions.html
│ ├── errorTypes.html
│ ├── expandableSection.html
│ ├── fileSelect.html
│ ├── filterItems.html
│ ├── functionOptions.html
│ ├── hexEditor.html
│ ├── hexInput.html
│ ├── listView.html
│ ├── loader.html
│ ├── mergeItem.html
│ ├── modalViewsList.html
│ ├── objectSchema.html
│ ├── pane.html
│ ├── pluginLoader.html
│ ├── profile.html
│ ├── progressModal.html
│ ├── recordAddressBar.html
│ ├── referenceSelect.html
│ ├── searchBar.html
│ ├── statusBar.html
│ ├── tabs.html
│ ├── textureSelector.html
│ ├── titleBar.html
│ ├── tree.html
│ └── viewLinker.html
├── docs
│ ├── applicationModes.html
│ ├── arguments.html
│ ├── development.html
│ ├── development
│ │ ├── apis.html
│ │ ├── apis
│ │ │ ├── angularServices.html
│ │ │ ├── angularServices
│ │ │ │ ├── buttonFactory.html
│ │ │ │ ├── buttonFactory.json
│ │ │ │ ├── buttonSchema.json
│ │ │ │ ├── helpService.html
│ │ │ │ ├── helpService.json
│ │ │ │ ├── helpTopicSchema.json
│ │ │ │ ├── progressObjectSchema.json
│ │ │ │ ├── progressService.html
│ │ │ │ ├── progressService.json
│ │ │ │ ├── settingsSchema.json
│ │ │ │ ├── settingsService.html
│ │ │ │ ├── settingsService.json
│ │ │ │ ├── timerService.html
│ │ │ │ └── timerService.json
│ │ │ ├── extensions.html
│ │ │ ├── extensions.json
│ │ │ ├── fileHelpers.html
│ │ │ ├── fileHelpers.json
│ │ │ ├── logger.html
│ │ │ ├── logger.json
│ │ │ ├── modalApi.html
│ │ │ ├── modalApi.json
│ │ │ ├── modalApi
│ │ │ │ ├── basicModal.html
│ │ │ │ ├── basicModal.js
│ │ │ │ ├── tabsModal.html
│ │ │ │ └── tabsModal.js
│ │ │ ├── moduleService.html
│ │ │ ├── moduleService.json
│ │ │ ├── nodeObjectSchema.json
│ │ │ ├── scriptingApi.html
│ │ │ ├── scriptingApi.json
│ │ │ ├── xelib.html
│ │ │ └── xelib
│ │ │ │ ├── common.json
│ │ │ │ ├── elementValues.html
│ │ │ │ ├── elementValues.json
│ │ │ │ ├── elements.html
│ │ │ │ ├── elements.json
│ │ │ │ ├── fileValues.html
│ │ │ │ ├── fileValues.json
│ │ │ │ ├── files.html
│ │ │ │ ├── files.json
│ │ │ │ ├── groups.html
│ │ │ │ ├── groups.json
│ │ │ │ ├── masters.html
│ │ │ │ ├── masters.json
│ │ │ │ ├── messages.html
│ │ │ │ ├── messages.json
│ │ │ │ ├── meta.html
│ │ │ │ ├── meta.json
│ │ │ │ ├── paths.html
│ │ │ │ ├── pluginErrors.html
│ │ │ │ ├── pluginErrors.json
│ │ │ │ ├── recordValues.html
│ │ │ │ ├── recordValues.json
│ │ │ │ ├── records.html
│ │ │ │ ├── records.json
│ │ │ │ ├── resources.html
│ │ │ │ ├── resources.json
│ │ │ │ ├── serialization.html
│ │ │ │ ├── serialization.json
│ │ │ │ ├── setup.html
│ │ │ │ ├── setup.json
│ │ │ │ ├── utils.html
│ │ │ │ └── utils.json
│ │ ├── guides.html
│ │ └── guides
│ │ │ ├── commonMistakes.html
│ │ │ ├── creatingModules.html
│ │ │ ├── debuggingModules.html
│ │ │ ├── javascript.html
│ │ │ └── writingScripts.html
│ ├── gameModes.html
│ ├── modalViews.html
│ ├── modalViews
│ │ ├── automateModal.html
│ │ ├── editColumnsModal.html
│ │ ├── editMergeModal.html
│ │ ├── editValueModal.html
│ │ ├── helpModal.html
│ │ ├── loadOrderModal.html
│ │ ├── manageExtensionsModal.html
│ │ ├── profilesModal.html
│ │ ├── resolveModal.html
│ │ ├── saveModal.html
│ │ ├── settingsModal.html
│ │ └── settingsModal
│ │ │ ├── archiveCreationSettings.html
│ │ │ ├── coreSettings.html
│ │ │ ├── errorCachingSettings.html
│ │ │ ├── integrationSettings.html
│ │ │ ├── integrationSettings
│ │ │ └── modManagerIntegration.html
│ │ │ ├── mergeSettings.html
│ │ │ ├── recordViewSettings.html
│ │ │ └── treeViewSettings.html
│ ├── moduleSchema.json
│ ├── modules.html
│ ├── modules
│ │ ├── coreModules.html
│ │ ├── documentation.html
│ │ ├── standardModules.html
│ │ ├── standardVariables.json
│ │ └── topicsSchema.json
│ ├── overview.html
│ ├── overview
│ │ ├── about.html
│ │ ├── community.html
│ │ ├── gettingStarted.html
│ │ ├── mergePluginsComparison.html
│ │ ├── mergingWorkflows.html
│ │ └── xeditComparison.html
│ ├── profiles.html
│ ├── views.html
│ └── views
│ │ ├── cleanView.html
│ │ ├── editView.html
│ │ ├── editView
│ │ ├── logView.html
│ │ ├── recordView.html
│ │ ├── referencedByView.html
│ │ └── treeView.html
│ │ ├── mergeView.html
│ │ ├── progressView.html
│ │ └── startView.html
├── helpers
│ ├── context_menu.js
│ └── external_links.js
├── images
│ └── games
│ │ ├── 0.png
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ ├── 5.png
│ │ └── undefined.png
├── locales.json
├── partials
│ ├── addMastersModal.html
│ ├── advancedSearchModal.html
│ ├── automateModal.html
│ ├── base.html
│ ├── clean.html
│ ├── copyIntoModal.html
│ ├── edit.html
│ ├── editColumnsModal.html
│ ├── editMerge
│ │ ├── data.html
│ │ ├── details.html
│ │ ├── loadOrder.html
│ │ └── plugins.html
│ ├── editMergeModal.html
│ ├── editModal.html
│ ├── editValueModal.html
│ ├── filterView.html
│ ├── filters
│ │ ├── arrayItem.html
│ │ ├── baseRecord.html
│ │ ├── conflictStatus.html
│ │ ├── flag.html
│ │ ├── group.html
│ │ ├── number.html
│ │ ├── recordType.html
│ │ ├── reference.html
│ │ ├── referencedBy.html
│ │ └── string.html
│ ├── helpModal.html
│ ├── integrations
│ │ └── modManager.html
│ ├── loadOrderModal.html
│ ├── logView.html
│ ├── manageExtensions
│ │ ├── browseModules.html
│ │ ├── browseThemes.html
│ │ ├── installedModules.html
│ │ └── installedThemes.html
│ ├── manageExtensionsModal.html
│ ├── merge.html
│ ├── newTabView.html
│ ├── profilesModal.html
│ ├── promptModal.html
│ ├── recordView.html
│ ├── refactorFileModal.html
│ ├── refactorRecordsModal.html
│ ├── referencedByView.html
│ ├── relinkScriptsModal.html
│ ├── resolveModal.html
│ ├── saveModal.html
│ ├── settings
│ │ ├── archiveCreation.html
│ │ ├── core.html
│ │ ├── errorCaching.html
│ │ ├── integrations.html
│ │ ├── merge.html
│ │ ├── recordView.html
│ │ └── treeView.html
│ ├── settingsModal.html
│ ├── start.html
│ └── treeView.html
├── progress.html
└── topics.json
├── borlndmm.dll
├── build
├── icon.ico
└── icons
│ └── 512x512.png
├── cache
├── Anchorage.esm-bf1e8db35d04d9ad4b70fe9e1f6e1fd0.json
├── BrokenSteel.esm-4d64b97155aaf8101c78f399100a6969.json
├── CaravanPack.esm-91c0d7a834954057e7998921e154b4ff.json
├── ClassicPack.esm-44cb6ac23018c4394dbd6b747d6db402.json
├── DLCBattlehornCastle.esp-fee130f1cfd8b535928eca72dca4a0c4.json
├── DLCFrostcrag.esp-cf020d66d0c5b90e52dd03dfe7adfef4.json
├── DLCHorseArmor.esp-12733ad9718557860ae8c14bc7eb11ca.json
├── DLCMehrunesRazor.esp-b4ef46c23349a878ea05afd1eda25ab3.json
├── DLCOrrery.esp-d4e363c4cbf3b39320ed0590322a72a2.json
├── DLCRobot.esm-030b64e3770aaf37989d6a60e1011961.json
├── DLCShiveringIsles.esp-0dee99680d432152c8e41e901965090a.json
├── DLCSpellTomes.esp-c5c79fd6fbd6f887fdfb4a0a85dc25b8.json
├── DLCThievesDen.esp-a938166d6318e2606dc4cbdb9ccc6960.json
├── DLCVileLair.esp-2c51ff6c5196a334377f41a5ec7159e5.json
├── DLCworkshop01.esm-4a8c3d8482dd21e0a3ae1fc8889e0269.json
├── DLCworkshop02.esm-63aebbc3ce8269fa90d74a49cf675bee.json
├── DLCworkshop03.esm-aa1c1044e0105206db1742232763d2c2.json
├── Dawnguard.esm-5bd2f339925a5fb96f9f0da7f96fd8ce.json
├── Dawnguard.esm-fe650ebff4e9071c5bed74bf373a172e.json
├── DeadMoney.esm-2afca0a0df2ad1024c6fcbe66711a54d.json
├── Dragonborn.esm-37d8cbffcb460011ce2bf3aabd007a2d.json
├── Dragonborn.esm-68c00eb72f0733fbf3a934d05a371231.json
├── GunRunnersArsenal.esm-524904da7d585c31f02db34e6dd1a010.json
├── HearthFires.esm-57583e9a2c6251d12686718bc1eca839.json
├── HearthFires.esm-71c3d20ea9f8510e29c36f2a426247c2.json
├── HonestHearts.esm-791d410ea87b33cf4b89a1c4efe4970e.json
├── Knights.esp-4187dc56a5620815f4ea6bf8576dbf4e.json
├── LonesomeRoad.esm-c268a9e7d8bff8747c1210735e44d272.json
├── MercenaryPack.esm-4dff17254e80871ec094c9fb8d51916f.json
├── OldWorldBlues.esm-54b58db1a14b2a4bda83f860299f233c.json
├── PointLookout.esm-8f5cef0cd937a8f8937d05f76c6f6830.json
├── ThePitt.esm-4490f2f839d93ad0715600262af8e23f.json
├── TribalPack.esm-bbe875b0ecf08f337f55200c0f171cd5.json
├── Update.esm-57d3e58622ac36f441b2d5a44936014f.json
├── Update.esm-d35b2f436e7a0961e3bbedc41af012aa.json
└── Zeta.esm-3a6df6cf19c6f7f786824d0db96ce19e.json
├── config
├── env_development.json
├── env_production.json
└── env_test.json
├── e2e
├── hello_world.e2e.js
└── utils.js
├── filters
├── Conflict Losers.json
└── Permanently Disabled Master records.json
├── gulpfile.js
├── layouts
└── default.json
├── modules
└── .gitkeep
├── package-lock.json
├── package.json
├── scripts
├── Export Spells.js
└── Test Progress Modal.js
├── src
├── javascripts
│ ├── Directives
│ │ ├── apiItems.js
│ │ ├── autocompleteInput.js
│ │ ├── autofocus.js
│ │ ├── cellEditor.js
│ │ ├── childrenTopics.js
│ │ ├── codeBlock.js
│ │ ├── codeMirror.js
│ │ ├── colorInput.js
│ │ ├── colorSelector.js
│ │ ├── colorSwatch.js
│ │ ├── contextMenu.js
│ │ ├── dds.js
│ │ ├── dropdown.js
│ │ ├── dropover.js
│ │ ├── dynController.js
│ │ ├── editModal.js
│ │ ├── elementView.js
│ │ ├── enumSelect.js
│ │ ├── enumerationMembers.js
│ │ ├── errorGroup.js
│ │ ├── errorResolutions.js
│ │ ├── errorTypes.js
│ │ ├── expandableSection.js
│ │ ├── fileSelect.js
│ │ ├── filterItems.js
│ │ ├── focusOn.js
│ │ ├── functionOptions.js
│ │ ├── hexEditor.js
│ │ ├── hexInput.js
│ │ ├── listView.js
│ │ ├── listViewParent.js
│ │ ├── loader.js
│ │ ├── mergeItem.js
│ │ ├── modalViewsList.js
│ │ ├── ngDrag.js
│ │ ├── ngDrop.js
│ │ ├── ngScroll.js
│ │ ├── ngWheel.js
│ │ ├── numberInput.js
│ │ ├── objectSchema.js
│ │ ├── pane.js
│ │ ├── pluginLoader.js
│ │ ├── profile.js
│ │ ├── progressBar.js
│ │ ├── progressModal.js
│ │ ├── recordAddressBar.js
│ │ ├── recordCell.js
│ │ ├── recordSearch.js
│ │ ├── referenceSelect.js
│ │ ├── searchBar.js
│ │ ├── selectText.js
│ │ ├── splitBar.js
│ │ ├── statusBar.js
│ │ ├── tabs.js
│ │ ├── textureSelector.js
│ │ ├── themeScrollbarFix.js
│ │ ├── titleBar.js
│ │ ├── tree.js
│ │ ├── treeNode.js
│ │ ├── treeSearch.js
│ │ ├── unfocusModal.js
│ │ └── viewLinker.js
│ ├── Factories
│ │ ├── buttonFactory.js
│ │ ├── codeMirrorFactory.js
│ │ ├── columnsFactory.js
│ │ ├── contextMenuFactory.js
│ │ ├── editModalFactory.js
│ │ ├── errorResolutionFactory.js
│ │ ├── errorTypeFactory.js
│ │ ├── filterViewFactory.js
│ │ ├── hotkeyFactory.js
│ │ ├── logViewFactory.js
│ │ ├── newTabViewFactory.js
│ │ ├── recordViewFactory.js
│ │ ├── referencedByViewFactory.js
│ │ ├── spinnerFactory.js
│ │ ├── tabsFactory.js
│ │ ├── treeViewFactory.js
│ │ └── viewFactory.js
│ ├── Filters
│ │ ├── bytesFilter.js
│ │ ├── classifyFilter.js
│ │ ├── customDateFilter.js
│ │ ├── hexFilter.js
│ │ ├── profileValidFilter.js
│ │ └── wordwrapFilter.js
│ ├── Runners
│ │ ├── assetHandlers
│ │ │ ├── billboardHandler.js
│ │ │ ├── bsaHandler.js
│ │ │ ├── dialogViewHandler.js
│ │ │ ├── faceDataHandler.js
│ │ │ ├── generalAssetHandler.js
│ │ │ ├── iniFileHandler.js
│ │ │ ├── mcmTranslationHandler.js
│ │ │ ├── stringFileHandler.js
│ │ │ └── voiceDataHandler.js
│ │ ├── integrations
│ │ │ └── modManagerIntegration.js
│ │ └── recordFilters
│ │ │ ├── arrayItemFilter.js
│ │ │ ├── baseRecordFilter.js
│ │ │ ├── conflictStatusFilter.js
│ │ │ ├── flagFilter.js
│ │ │ ├── groupFilter.js
│ │ │ ├── numberFilter.js
│ │ │ ├── recordTypeFilter.js
│ │ │ ├── referenceFilter.js
│ │ │ ├── referencedByFilter.js
│ │ │ └── stringFilter.js
│ ├── Services
│ │ ├── clean
│ │ │ ├── errorCacheService.js
│ │ │ ├── errorMessageService.js
│ │ │ ├── navmeshHelpers.js
│ │ │ ├── pluginErrorHelpers.js
│ │ │ └── pluginErrorService.js
│ │ ├── edit
│ │ │ ├── automationService.js
│ │ │ ├── clipboardService.js
│ │ │ ├── columnsService.js
│ │ │ ├── gridService.js
│ │ │ ├── layoutService.js
│ │ │ ├── nodeColumnService.js
│ │ │ ├── nodeHelpers.js
│ │ │ ├── nodeSelectionService.js
│ │ │ ├── recordFilterService.js
│ │ │ ├── recordViewDragDropService.js
│ │ │ ├── recordViewElementService.js
│ │ │ ├── recordViewService.js
│ │ │ ├── referenceService.js
│ │ │ ├── referencedByViewService.js
│ │ │ ├── searchService.js
│ │ │ ├── treeService.js
│ │ │ ├── treeViewElementService.js
│ │ │ ├── treeViewService.js
│ │ │ └── typeToSearchService.js
│ │ ├── merge
│ │ │ ├── assetHelpers.js
│ │ │ ├── bsaHelpers.js
│ │ │ ├── mergeAssetService.js
│ │ │ ├── mergeBuilder.js
│ │ │ ├── mergeDataService.js
│ │ │ ├── mergeIntegrationService.js
│ │ │ ├── mergeLoadService.js
│ │ │ ├── mergeMasterService.js
│ │ │ ├── mergeService.js
│ │ │ ├── mergeStatusService.js
│ │ │ ├── pexService.js
│ │ │ ├── progressLogger.js
│ │ │ ├── recordMergingService.js
│ │ │ ├── relinker.js
│ │ │ ├── scriptsCache.js
│ │ │ └── seqService.js
│ │ └── shared
│ │ │ ├── appModeService.js
│ │ │ ├── argService.js
│ │ │ ├── bsaBuilder.js
│ │ │ ├── contextMenuService.js
│ │ │ ├── errorService.js
│ │ │ ├── eventService.js
│ │ │ ├── extensionService.js
│ │ │ ├── fileSearchService.js
│ │ │ ├── gameService.js
│ │ │ ├── helpService.js
│ │ │ ├── hotkeyService.js
│ │ │ ├── htmlHelpers.js
│ │ │ ├── integrationService.js
│ │ │ ├── interApiService.js
│ │ │ ├── loadOrderService.js
│ │ │ ├── modManagerService.js
│ │ │ ├── modOrganizerService.js
│ │ │ ├── modalService.js
│ │ │ ├── nexusModManagerService.js
│ │ │ ├── objectUtils.js
│ │ │ ├── profileService.js
│ │ │ ├── progressService.js
│ │ │ ├── protocolService.js
│ │ │ ├── randomService.js
│ │ │ ├── recentService.js
│ │ │ ├── resourceService.js
│ │ │ ├── saveModalService.js
│ │ │ ├── settingsService.js
│ │ │ ├── stylesheetService.js
│ │ │ ├── tabService.js
│ │ │ ├── themeService.js
│ │ │ ├── timerService.js
│ │ │ ├── viewLinkingService.js
│ │ │ ├── vortexService.js
│ │ │ └── xelibService.js
│ ├── Views
│ │ ├── clean
│ │ │ ├── clean.js
│ │ │ ├── cleanSaveModal.js
│ │ │ ├── errorCaching.js
│ │ │ └── resolveModal.js
│ │ ├── edit
│ │ │ ├── addMastersModal.js
│ │ │ ├── advancedSearchModal.js
│ │ │ ├── automateModal.js
│ │ │ ├── copyIntoModal.js
│ │ │ ├── edit.js
│ │ │ ├── editColumnsModal.js
│ │ │ ├── editSaveModal.js
│ │ │ ├── editValueModal.js
│ │ │ ├── filterView.js
│ │ │ ├── logView.js
│ │ │ ├── newTabView.js
│ │ │ ├── recordView.js
│ │ │ ├── refactorFileModal.js
│ │ │ ├── refactorRecordsModal.js
│ │ │ ├── referencedByView.js
│ │ │ └── treeView.js
│ │ ├── merge
│ │ │ ├── editMergeData.js
│ │ │ ├── editMergeLoadOrder.js
│ │ │ ├── editMergeModal.js
│ │ │ ├── editMergePlugins.js
│ │ │ ├── integrationSettings.js
│ │ │ ├── merge.js
│ │ │ ├── mergeSaveModal.js
│ │ │ └── mergeSettings.js
│ │ └── shared
│ │ │ ├── archiveCreationSettings.js
│ │ │ ├── base.js
│ │ │ ├── coreSettings.js
│ │ │ ├── helpModal.js
│ │ │ ├── installedModules.js
│ │ │ ├── installedThemes.js
│ │ │ ├── loadOrderModal.js
│ │ │ ├── manageExtensionsModal.js
│ │ │ ├── profilesModal.js
│ │ │ ├── promptModal.js
│ │ │ ├── settingsModal.js
│ │ │ └── start.js
│ ├── app.js
│ ├── color.js
│ ├── env.js
│ ├── extensions.js
│ ├── helpers
│ │ ├── fileHelpers.js
│ │ ├── logger.js
│ │ ├── moduleService.js
│ │ └── window.js
│ ├── main.js
│ └── progress.js
└── stylesheets
│ ├── _roboto.scss
│ ├── app.scss
│ ├── components
│ ├── apiItems.scss
│ ├── autocompleteInput.scss
│ ├── cellEditor.scss
│ ├── codeBlock.scss
│ ├── colorInput.scss
│ ├── colorSelector.scss
│ ├── colorSwatch.scss
│ ├── contextMenu.scss
│ ├── dds.scss
│ ├── dropdown.scss
│ ├── elementView.scss
│ ├── errorGroup.scss
│ ├── errorResolutions.scss
│ ├── expandableSection.scss
│ ├── hexEditor.scss
│ ├── hexInput.scss
│ ├── listEdit.scss
│ ├── listView.scss
│ ├── loader.scss
│ ├── nodeColumns.scss
│ ├── nodes.scss
│ ├── progressBar.scss
│ ├── recordAddressBar.scss
│ ├── searchBar.scss
│ ├── spinner.scss
│ ├── statusBar.scss
│ ├── tabs.scss
│ ├── textureSelector.scss
│ ├── titleBar.scss
│ ├── tree.scss
│ └── viewLinker.scss
│ ├── general
│ ├── buttons.scss
│ ├── conflicts.scss
│ ├── content.scss
│ ├── forms.scss
│ ├── mixins.scss
│ ├── modals.scss
│ └── utility.scss
│ ├── themes
│ ├── day.scss
│ └── night.scss
│ └── views
│ ├── advancedSearchModal.scss
│ ├── automateModal.scss
│ ├── clean.scss
│ ├── edit.scss
│ ├── editColumnsModal.scss
│ ├── editMergeModal.scss
│ ├── editModal.scss
│ ├── editValueModal.scss
│ ├── errorCaching.scss
│ ├── filterView.scss
│ ├── helpModal.scss
│ ├── loadOrderModal.scss
│ ├── logView.scss
│ ├── manageExtensionsModal.scss
│ ├── merge.scss
│ ├── newTabView.scss
│ ├── profilesModal.scss
│ ├── progressModal.scss
│ ├── promptModal.scss
│ ├── recordView.scss
│ ├── refactorModal.scss
│ ├── referencedByView.scss
│ ├── resolveModal.scss
│ ├── settingsModal.scss
│ ├── start.scss
│ └── treeView.scss
├── tasks
├── build_app.js
├── build_tests.js
├── bundle.js
├── generateCommonDocs.js
├── start.js
└── utils.js
├── tests
├── istanbul-reporter.js
└── travis-build.sh
├── update_xelib.bat
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 4
7 | end_of_line = crlf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.{scss,json}]
13 | indent_size = 2
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 | *.png binary
3 | *.jpg binary
4 | *.ico binary
5 | *.icns binary
6 | *.dll binary
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea
3 | .DS_Store
4 | Thumbs.db
5 | *.log
6 | *_log.txt
7 | *.autogenerated
8 | work.cmd
9 | # ignore everything in 'app' folder what had been generated from 'src' folder
10 | /app/stylesheets
11 | /app/app.js
12 | /app/main.js
13 | /app/env.json
14 | /app/**/*.map
15 | /dist
16 | /coverage
17 | /.idea/
18 | /profiles.json
19 | /app/themes/
20 | /profiles/
21 | /modules/
22 | /columns.json
23 | /app/background.js
24 | /app/progress.js
25 | /app/syntaxThemes/
26 | themes/
27 | syntaxThemes/
28 | scripts/history.json
29 | *.zip
30 | *.rar
31 | logs/
32 | merges/
33 | temp/
34 | /cache/scripts/*.json
35 | build/config\.gypi
36 | cache/pluginDiffs/
37 | patches/New Patch/
38 | AllRecords.esp/
39 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "modules/unifiedPatchingFramework"]
2 | path = modules/unifiedPatchingFramework
3 | url = https://github.com/matortheeternal/zedit-unified-patching-framework.git
4 | branch = dist
5 |
--------------------------------------------------------------------------------
/.yarnclean:
--------------------------------------------------------------------------------
1 | # test directories
2 | __tests__
3 | test
4 | tests
5 | powered-test
6 |
7 | # asset directories
8 | docs
9 | doc
10 | website
11 | images
12 | assets
13 |
14 | # examples
15 | example
16 | examples
17 |
18 | # code coverage directories
19 | coverage
20 | .nyc_output
21 |
22 | # build scripts
23 | Makefile
24 | Gulpfile.js
25 | Gruntfile.js
26 |
27 | # configs
28 | .tern-project
29 | .gitattributes
30 | .editorconfig
31 | .*ignore
32 | .eslintrc
33 | .jshintrc
34 | .flowconfig
35 | .documentup.json
36 | .yarn-metadata.json
37 | .*.yml
38 |
39 | # misc
40 | *.gz
41 | *.md
42 |
43 | # xelib
44 | *.Hardcoded.dat
45 | XEditLib.dll
46 |
--------------------------------------------------------------------------------
/Fallout3.Hardcoded.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/Fallout3.Hardcoded.dat
--------------------------------------------------------------------------------
/Fallout4.Hardcoded.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/Fallout4.Hardcoded.dat
--------------------------------------------------------------------------------
/FalloutNV.Hardcoded.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/FalloutNV.Hardcoded.dat
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Colin Allen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/Oblivion.Hardcoded.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/Oblivion.Hardcoded.dat
--------------------------------------------------------------------------------
/Skyrim.Hardcoded.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/Skyrim.Hardcoded.dat
--------------------------------------------------------------------------------
/XEditLib.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/XEditLib.dll
--------------------------------------------------------------------------------
/app/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | zEdit
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/directives/autocompleteInput.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Searching...
4 |
No results found
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/directives/cellEditor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/directives/childrenTopics.html:
--------------------------------------------------------------------------------
1 |
6 |
7 | No children topics found.
8 |
9 |
--------------------------------------------------------------------------------
/app/directives/colorInput.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/app/directives/colorSelector.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/directives/contextMenu.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/directives/contextMenuDivider.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/directives/contextMenuItem.html:
--------------------------------------------------------------------------------
1 |
2 | {{::item.label}}
3 | {{::item.hotkey}}
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/directives/dropdown.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
--------------------------------------------------------------------------------
/app/directives/dropover.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/app/directives/elementView.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{::field.key}}:
5 |
6 |
7 |
8 | {{::field.key}}:
9 |
10 |
{{::field.value}}
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/directives/enumSelect.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/directives/enumerationMembers.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Ordinal
5 | Key
6 | Description
7 |
8 |
9 |
10 |
11 | {{::$index}}
12 | {{::member.key}}
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/directives/errorGroup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ group.errors.length }} {{ ::group.name }}
5 |
6 |
7 | Automatic
8 | Ignore
9 | Manual
10 |
11 |
12 |
13 |
14 |
15 | {{ ::error.message.join('\n\r - ') }}
16 |
17 |
18 | {{ error.resolution.label }}
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/directives/errorResolutions.html:
--------------------------------------------------------------------------------
1 |
3 | {{ $index + 1 }}. {{:: resolution.label }}
4 |
5 |
--------------------------------------------------------------------------------
/app/directives/errorTypes.html:
--------------------------------------------------------------------------------
1 | {{::errorType.name}}
2 |
3 |
4 |
5 | Resolution
6 | Availability
7 | Description
8 |
9 |
10 |
11 |
12 | {{::resolution.label}}
13 | {{::resolution.availability}}
14 | {{::resolution.description}}
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/directives/expandableSection.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/directives/fileSelect.html:
--------------------------------------------------------------------------------
1 |
2 | {{::$parent.result}}
3 |
--------------------------------------------------------------------------------
/app/directives/filterItems.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Type
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/directives/functionOptions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Key
5 | Description
6 |
7 |
8 |
9 |
10 | {{::option.key}}
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/directives/hexEditor.html:
--------------------------------------------------------------------------------
1 | {{byte}}
--------------------------------------------------------------------------------
/app/directives/hexInput.html:
--------------------------------------------------------------------------------
1 | {{nibble}}
--------------------------------------------------------------------------------
/app/directives/listView.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | {{::item.label}}
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/directives/loader.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{message}}
6 | Cancel
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/directives/modalViewsList.html:
--------------------------------------------------------------------------------
1 |
6 |
7 | No modal views found.
8 |
9 |
--------------------------------------------------------------------------------
/app/directives/objectSchema.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Key
5 | Type
6 | Description
7 |
8 |
9 |
10 |
11 | {{::property.key}}
12 | (optional)
13 |
14 |
15 | {{::property.type}}
16 |
17 |
18 |
19 | {{::type}}
20 | /
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/directives/pane.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{tab.label}}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/directives/pluginLoader.html:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/app/directives/profile.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Name
6 |
7 |
8 |
9 | Game
10 |
11 |
12 |
13 | Path
14 |
15 |
16 |
17 |
18 | Language
19 |
20 | {{::language}}
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/directives/progressModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{progress.title}}
6 |
7 |
{{progress.message}}
8 |
9 |
10 |
11 |
12 | {{expanded ? 'Hide' : 'Show'}} Log
13 |
14 |
15 |
{{::message.text}}
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/directives/recordAddressBar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/directives/referenceSelect.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{::$parent.result}}
4 |
--------------------------------------------------------------------------------
/app/directives/searchBar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Search by
7 |
8 |
9 |
10 |
11 | Exact Match
12 |
13 |
14 | No match found.
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/directives/statusBar.html:
--------------------------------------------------------------------------------
1 | {{previewMessage}}
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/directives/tabs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{tab.label}}
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/directives/textureSelector.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{::$parent.item}}
7 |
8 | Other...
9 |
10 |
11 | {{::$parent.result}}
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/directives/titleBar.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/directives/tree.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/directives/viewLinker.html:
--------------------------------------------------------------------------------
1 | {{linkMessage}}
--------------------------------------------------------------------------------
/app/docs/development.html:
--------------------------------------------------------------------------------
1 | Technologies
2 | zEdit uses the following technologies:
3 |
4 |
5 |
6 | ES6 JavaScript - Programming Language
7 |
8 |
9 | NodeJS - JavaScript Runtime
10 |
11 |
12 | Electron - Platform
13 |
14 |
15 | AngularJS 1.5 - JavaScript Framework
16 |
17 |
18 | SASS - CSS Extension Language
19 |
20 |
21 | CSS3 - Stylesheet Language
22 |
23 |
24 | HTML5 - Markup Language
25 |
26 |
27 |
28 | APIs
29 | zEdit offers a number of APIs for developers to use.
30 |
31 | Guides
32 | This documentation includes several guides for contributing to zEdit.
33 |
--------------------------------------------------------------------------------
/app/docs/development/apis.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices.html:
--------------------------------------------------------------------------------
1 | zEdit is comprised of a number of angular services which provide APIs which are relevant to the development of zEdit modules and core functionality.
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/buttonFactory.html:
--------------------------------------------------------------------------------
1 | The buttonFactory
is used to register buttons to be displayed in the application's title bar.
2 |
3 |
4 |
5 | Button Schema
6 |
7 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/buttonFactory.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "buttons",
4 | "type": "array of object",
5 | "description": "Array of buttons which get displayed in the title bar."
6 | }
7 | ]
8 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/buttonSchema.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key": "class",
4 | "type": "string",
5 | "description": "The CSS class to apply to the button."
6 | },
7 | {
8 | "key": "title",
9 | "type": "string",
10 | "description": "The tooltip to display when the user hovers over the button."
11 | },
12 | {
13 | "key": "hidden",
14 | "type": "boolean",
15 | "icons": ["optional"],
16 | "description": "If true, the button will not be displayed. Keep a reference to the button object in your code to change this as needed when the button should be shown or hidden."
17 | },
18 | {
19 | "key": "onClick",
20 | "type": "function",
21 | "description": "The function to call when the user clicks the button. The first argument is the application's base scope, and the second argument is the click event."
22 | }
23 | ]
24 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/helpService.html:
--------------------------------------------------------------------------------
1 | The helpService
is used to register help topics which can be viewed in the Help Modal .
2 |
3 |
4 |
5 | Help Topic Schema
6 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/helpService.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "addTopic",
4 | "type": "function",
5 | "args": [{
6 | "name": "topic",
7 | "type": "object"
8 | }, {
9 | "name": "path",
10 | "type": "string"
11 | }],
12 | "description": "Registers the input `topic` at `path` in the help modal if it does not already exist."
13 | }
14 | ]
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/helpTopicSchema.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key": "label",
4 | "type": "string",
5 | "description": "Label for the help topic. Is displayed in the Help Modal navigation and as the topic's title."
6 | },
7 | {
8 | "key": "templateUrl",
9 | "type": "string",
10 | "description": "The URL of the HTML template to use with the topic."
11 | },
12 | {
13 | "key": "controller",
14 | "type": "string",
15 | "icons": ["optional"],
16 | "description": "Name of the AngularJS controller to use on the help topic page. It's highly recommended to use directives instead of controllers on documentation pages."
17 | },
18 | {
19 | "key": "children",
20 | "type": "array of object",
21 | "icons": ["optional"],
22 | "description": "Array of children topics. Not supported in module `topics.json` files."
23 | }
24 | ]
25 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/progressObjectSchema.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key": "determinate",
4 | "type": "boolean",
5 | "description": "When true the determinate progress modal is displayed. \nWhen false the indeterminate progress loader is displayed."
6 | },
7 | {
8 | "key": "title",
9 | "type": "string",
10 | "description": "The title displayed at the top of the determinate progress modal."
11 | },
12 | {
13 | "key": "message",
14 | "type": "string",
15 | "description": "The message displayed above the determinate progress modal's progress bar or below the indeterminate progress loader."
16 | },
17 | {
18 | "key": "canClose",
19 | "type": "boolean",
20 | "description": "Allows the user to close the determinate progress modal if true."
21 | },
22 | {
23 | "key": "current",
24 | "type": "integer",
25 | "description": "An integer representing the current progress. Used for displaying the progress bar on the determinate progress modal."
26 | },
27 | {
28 | "key": "max",
29 | "type": "integer",
30 | "description": "An integer representing the maximum progress. Used for displaying the progress bar on the determinate progress modal."
31 | }
32 | ]
33 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/progressService.html:
--------------------------------------------------------------------------------
1 | The progressService
provides an API for creating and communicating with the progress window .
2 |
3 |
4 |
5 | Progress Object Schema
6 |
7 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/settingsService.html:
--------------------------------------------------------------------------------
1 | The settingsService
is used to register settings tabs to be displayed in the Settings Modal .
2 |
3 |
4 |
5 | Settings Schema
6 |
7 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/settingsService.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "loadProfileSettings",
4 | "type": "function",
5 | "args": [{
6 | "name": "profileName",
7 | "type": "string"
8 | }],
9 | "description": "Loads the profile settings associated with `profileName`."
10 | },
11 | {
12 | "name": "loadGlobalSettings",
13 | "type": "function",
14 | "args": [],
15 | "description": "Loads global settings."
16 | },
17 | {
18 | "name": "saveProfileSettings",
19 | "type": "function",
20 | "args": [],
21 | "description": "Saves the currently loaded profile settings to disk."
22 | },
23 | {
24 | "name": "saveGlobalSettings",
25 | "type": "function",
26 | "args": [],
27 | "description": "Saves the currently loaded global settings to disk."
28 | },
29 | {
30 | "name": "registerSettings",
31 | "type": "function",
32 | "args": [{
33 | "name": "settingsTab",
34 | "type": "object"
35 | }],
36 | "description": "Registers `settingsTab` on the settings modal. See the settings schema below for more information."
37 | }
38 | ]
39 |
--------------------------------------------------------------------------------
/app/docs/development/apis/angularServices/timerService.html:
--------------------------------------------------------------------------------
1 | The timerService
provides an API for tracking time.
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/docs/development/apis/extensions.html:
--------------------------------------------------------------------------------
1 | This API provides a number of valuable extension methods for performing common operations on JavaScript types.
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/docs/development/apis/fileHelpers.html:
--------------------------------------------------------------------------------
1 | The File Helpers API is made accessible through the fh
variable. The API provides functions for interfacing with the user's file system through fs-jetpack , extract-zip , and shell .
2 |
3 | Unless otherwise specified, all paths passed to functions can be a path relative to the application root folder or an absolute path.
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/docs/development/apis/logger.html:
--------------------------------------------------------------------------------
1 | zEdit has a global logger which can be used to write log messages which will be appended to a log file on disk as the application is running. The Log View displays the contents of the application log.
2 |
3 | It's best not to pollute the log with verbose messages that are unlikely to help when debugging an issue.
4 |
5 | WARNING: Several of the functions here should never be called from zEdit scripts or modules. These functions have been marked with .
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/docs/development/apis/modalApi/basicModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Basic Modal
6 |
7 |
17 |
18 |
19 | OK
20 | Cancel
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/docs/development/apis/modalApi/basicModal.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('basicModalController', function($scope) {
2 | $scope.apply = function() {
3 | console.log('Enabled: ', $scope.modalOptions.enabled);
4 | console.log('Text: ', $scope.modalOptions.text);
5 | $scope.$emit('closeModal');
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/app/docs/development/apis/modalApi/tabsModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 | {{::tab.label}}
9 |
10 |
11 |
12 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/docs/development/apis/modalApi/tabsModal.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('tabsModalController', function($scope, tabService) {
2 | $scope.tabs = [{
3 | label: 'First Tab',
4 | templateUrl: 'partials/tabsModal/firstTab.html',
5 | controller: 'firstTabController'
6 | }, {
7 | label: 'Second Tab',
8 | templateUrl: 'partials/tabsModal/secondTab.html',
9 | controller: 'secondTabController'
10 | }];
11 |
12 | tabService.buildFunctions($scope);
13 | });
14 |
--------------------------------------------------------------------------------
/app/docs/development/apis/moduleService.html:
--------------------------------------------------------------------------------
1 | The module service allows you to get information about installed modules and register module loaders.
2 |
3 | Note: this service is not an angular service.
4 |
5 |
6 |
7 | Module Info Objects
8 | Module info objects are just deserialized module.json
files. See the Modules page for more information.
9 |
--------------------------------------------------------------------------------
/app/docs/development/apis/nodeObjectSchema.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key": "handle",
4 | "type": "handle",
5 | "description": "Handle of the element the node represents."
6 | },
7 | {
8 | "key": "element_type",
9 | "type": "integer",
10 | "description": "[Element Type](docs://Development/APIs/xelib/Elements) of the element the node represents."
11 | },
12 | {
13 | "key": "column_values",
14 | "type": "array of string",
15 | "description": "Array of the string values displayed in the [Tree View](docs://Views/Edit View/Tree View) columns."
16 | },
17 | {
18 | "key": "class",
19 | "type": "string",
20 | "description": "The node's class, which includes the element's [conflict all and conflict this](docs://Development/APIs/xelib/Elements) values."
21 | }
22 | ]
23 |
--------------------------------------------------------------------------------
/app/docs/development/apis/scriptingApi.html:
--------------------------------------------------------------------------------
1 | zEdit allows for the execution of user scripts through the Automate Modal . User scripts are executed as JavaScript functions.
2 |
3 | You can exit a script by throwing an exception or by calling return
. All scripts are given access to the following variables:
4 |
5 |
6 |
7 | Node Object Schema
8 |
9 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/elementValues.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/elements.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/fileValues.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/files.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/groups.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/groups.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "HasGroup",
4 | "args": [{
5 | "name": "id",
6 | "type": "handle"
7 | }, {
8 | "name": "signature",
9 | "type": "string"
10 | }],
11 | "returns": {
12 | "type": "boolean"
13 | },
14 | "description": "Returns true if group `signature` is present in file `id`."
15 | },
16 | {
17 | "name": "AddGroup",
18 | "args": [{
19 | "name": "id",
20 | "type": "handle"
21 | }, {
22 | "name": "signature",
23 | "type": "string"
24 | }],
25 | "returns": {
26 | "type": "handle"
27 | },
28 | "description": "Adds the group `signature` to file `id` if missing and returns a handle to it."
29 | },
30 | {
31 | "name": "GetChildGroup",
32 | "args": [{
33 | "name": "id",
34 | "type": "handle"
35 | }],
36 | "returns": {
37 | "type": "handle"
38 | },
39 | "description": "Returns a handle to the child group of `id`. Returns `0` if `id` does not have a child group."
40 | }
41 | ]
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/masters.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/messages.html:
--------------------------------------------------------------------------------
1 | WARNING: Several of the functions here should never be called from zEdit scripts or modules. These functions have been marked with .
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/messages.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "GetMessages",
4 | "args": [],
5 | "returns": {
6 | "type": "string",
7 | "description": "The messages separated by `\\r\\n`."
8 | },
9 | "description": "Gets any messages that have been added to XEditLib's internal log since the last time this function was called."
10 | },
11 | {
12 | "name": "ClearMessages",
13 | "icons": ["warn"],
14 | "args": [],
15 | "description": "Clears all messages from the XEditLib's internal log."
16 | },
17 | {
18 | "name": "GetExceptionMessage",
19 | "icons": ["warn"],
20 | "args": [],
21 | "returns": {
22 | "type": "string",
23 | "description": "The exception message."
24 | },
25 | "description": "Returns a message corresponding to the last exception that occurred. Returns an empty string if no exception has occurred since the last time this function was called."
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/meta.html:
--------------------------------------------------------------------------------
1 | WARNING: Several of the functions here should never be called from zEdit scripts or modules. These functions have been marked with .
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/pluginErrors.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/recordValues.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/records.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/resources.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/serialization.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/setup.html:
--------------------------------------------------------------------------------
1 | WARNING: Several of the functions here should never be called from zEdit scripts or modules. These functions have been marked with .
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/docs/development/apis/xelib/utils.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/guides.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/docs/development/guides/javascript.html:
--------------------------------------------------------------------------------
1 | The following resources cover learning JavaScript and ES6:
2 |
3 |
14 |
--------------------------------------------------------------------------------
/app/docs/development/guides/writingScripts.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/app/docs/development/guides/writingScripts.html
--------------------------------------------------------------------------------
/app/docs/gameModes.html:
--------------------------------------------------------------------------------
1 | zEdit supports the following game modes:
2 |
3 |
6 |
--------------------------------------------------------------------------------
/app/docs/modalViews.html:
--------------------------------------------------------------------------------
1 | zEdit uses a lot of modal views - child views which display above the currrent view and disable any controls below them.
2 |
3 | Modal views can be closed by:
4 |
5 |
6 | Clicking the X in the upper right corner of the modal
7 | Clicking in the space outside of the modal.
8 |
9 |
10 | Note: Some modal views cannot be closed.
11 |
12 | Modals
13 |
14 |
--------------------------------------------------------------------------------
/app/docs/modalViews/editColumnsModal.html:
--------------------------------------------------------------------------------
1 | The edit columns modal allows you to toggle the display of columns and create custom columns.
2 |
3 | The edit columns modal is available on the tree view and on the referenced by view .
4 |
5 | Disabling columns
6 | You can disable a column by unchecking the checkbox by it.
7 |
8 | Custom columns
9 | You can create a new custom column by clicking the Add Column button.
10 |
11 | To edit a custom column, click on it to select it. Once selected you can change the column's label and data retrieval code. The label must be unique among all columns, including disabled ones. The data retrieval code should return
a string value by calling one or more functions on the input node
. You should use the xelib API to get a value to display. If the code does not return a value for a given node no value will be displayed in the column.
12 |
13 | You can delete a custom column by clicking the Delete button.
14 |
--------------------------------------------------------------------------------
/app/docs/modalViews/helpModal.html:
--------------------------------------------------------------------------------
1 | The help modal allows you to view help topics and documentation for zEdit. You can open the modal:
2 |
3 |
4 |
5 | Pressing Ctrl + Shift + H .
6 |
7 |
8 | By clicking the ? icon in the title bar.
9 |
10 |
11 |
12 | Navigation
13 | The left section of the Help Modal displays a tree of help topics. Every node in the tree corresponds to a help page which can be viewed, though some pages may only display lists of child topics.
14 |
15 | You can navigate back/forward relative to a topic through the arrow buttons at the header of each page.
16 |
--------------------------------------------------------------------------------
/app/docs/modalViews/settingsModal.html:
--------------------------------------------------------------------------------
1 | The settings modal allows you to edit the settings associated with the currently active profile. You can open the settings modal by:
2 |
3 |
4 |
5 | Pressing Ctrl + Shift + S while on the Edit View .
6 |
7 |
8 | Clicking the button in the title bar while on the Edit View.
9 |
10 |
11 |
12 | Saving changes
13 | Any changes made in the settings modal will be saved automatically when the modal is closed.
14 |
15 | Settings tabs
16 |
17 |
--------------------------------------------------------------------------------
/app/docs/modalViews/settingsModal/coreSettings.html:
--------------------------------------------------------------------------------
1 | The core settings tab allows you to view the currently active profile and change the application's appearance.
2 |
3 |
4 |
5 |
6 | Setting
7 | Description
8 |
9 |
10 |
11 |
12 | Application theme
13 |
14 | The application theme is a global setting which corresponds to the appearance of the application. You can install new themes from the the Manage Extensions Modal .
15 |
16 |
17 |
18 | Syntax theme
19 |
20 | The syntax theme is a global setting which corresponds to the theme used for code blocks and editors. You can install syntax themes by putting their CSS files in the application's syntaxThemes
folder. You can install and use any valid CodeMirror theme with zEdit.
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/docs/modalViews/settingsModal/errorCachingSettings.html:
--------------------------------------------------------------------------------
1 | zClean caches errors based on plugin filenames and MD5 hashes. Error cache files are saved in minified JSON in the cache folder. The error caching settings tab allows you to view and manage error cache files.
2 |
3 | Disabling error caching
4 | You can disable error caching by unchecking the Cache errors checkbox. Error caching is enabled by default, and is recommended.
5 |
6 | Clearing the cache
7 | You can clear the entire error cache by clicking the Clear button.
8 |
9 | You can delete all cache files for a particular plugin by clicking the Delete button by it.
10 |
11 | You can delete an individual cache file by expanding the cache files section and clicking the X button by a cache file entry.
12 |
13 |
--------------------------------------------------------------------------------
/app/docs/modalViews/settingsModal/integrationSettings.html:
--------------------------------------------------------------------------------
1 | The integration settings tab allows you to configure integrations with other programs. You can have zEdit attempt to automatically detect integrations by clicking the Detect button or set them up manually.
2 |
3 | Integrations
4 |
5 |
--------------------------------------------------------------------------------
/app/docs/modalViews/settingsModal/mergeSettings.html:
--------------------------------------------------------------------------------
1 | The merge settings tab allows you to configure the merge output path and merge integrations.
2 |
3 |
4 |
5 |
6 | Setting
7 | Description
8 |
9 |
10 |
11 |
12 | Merge output path
13 |
14 | The path to the folder where you want zMerge to output merges and relinked scripts. Separate folders will be created at the merge output path for each merge built.
15 |
16 |
17 |
18 | Disable plugins
19 |
20 | If checked, merged plugins will be automatically disabled in plugins.txt once a merge is successfully built.
21 |
22 |
23 |
24 | Disable mods
25 |
26 | If checked, mods will be disabled in your mod manager once a merge with copy general assets enabled is successfully built. This integration is only available when using Mod Organizer or Mod Organizer 2 currently.
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/docs/modalViews/settingsModal/treeViewSettings.html:
--------------------------------------------------------------------------------
1 | The tree view settings tab allows you to adjust the behavior and appearance of the Tree View .
2 |
3 |
4 |
5 |
6 | Setting
7 | Description
8 |
9 |
10 |
11 |
12 | Show group signatures
13 |
14 | Enables the display of signatures on record groups. E.g. with this enabled, the Armor group will be displayed as ARMO - Armor
.
15 |
16 |
17 |
18 | Prompt on deletion
19 |
20 | If enabled a prompt will be shown to confirm the deletion of any records or groups on the tree view.
21 |
22 |
23 |
24 | Show separate file headers
25 |
26 | If disabled file headers will not be displayed in the tree view.
27 | If enabled file headers will be displayed as a separate node in the tree.
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/docs/modules.html:
--------------------------------------------------------------------------------
1 | zEdit includes a module system which allows developers to extend or add functionality to zEdit through zEdit's APIs .
2 |
3 | module.json
4 | All zEdit modules must provide a module.json
JSON file following the schema below:
5 |
6 |
7 |
8 | Types of modules
9 |
10 |
--------------------------------------------------------------------------------
/app/docs/modules/coreModules.html:
--------------------------------------------------------------------------------
1 | Modules which are packaged with zEdit releases are referred to as Core Modules.
2 |
3 | Installed core modules
4 |
5 |
--------------------------------------------------------------------------------
/app/docs/modules/documentation.html:
--------------------------------------------------------------------------------
1 | Modules can provide documentation accessible from the Help Modal. Documentation topics can be registered through a docs\topics.json
file or via the helpService . Registering documentation topics through a topics.json file is recommended because it allows your module documentation to be loaded onto the zEdit Website easily.
2 |
3 | Topics Schema
4 |
--------------------------------------------------------------------------------
/app/docs/modules/standardModules.html:
--------------------------------------------------------------------------------
1 | Standard modules use the default
module loader and are given access to the following variables:
2 |
3 |
4 |
5 | Installed standard modules
6 |
7 |
--------------------------------------------------------------------------------
/app/docs/modules/topicsSchema.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key": "path",
4 | "type": "string",
5 | "description": "Path of the parent topic the topic should be added to."
6 | },
7 | {
8 | "key": "topic",
9 | "type": "object",
10 | "description": "The topic object to register. See the [help topic schema](docs://Development/APIs/Angular Services/Help Service)."
11 | }
12 | ]
--------------------------------------------------------------------------------
/app/docs/overview.html:
--------------------------------------------------------------------------------
1 | You have found zEdit's documentation. Here you can find information about every part of the program.
2 |
3 | Getting Started
4 |
5 | Check out the documentation for the Help Modal to learn how to navigate this documentation effectively.
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/docs/overview/about.html:
--------------------------------------------------------------------------------
1 | zEdit is a Windows desktop application which provides a development environment for editing Bethesda Plugin Files.
2 |
3 | zEdit is built off of xEdit's codebase through XEditLib . zEdit is built with Electron, which allows it to take advantage of web technologies such as HTML, CSS, and ES6 JavaScript.
4 |
5 | The initial development goal for zEdit is to provide equivalent functionality to the xEdit GUI, but a number of popular extensions and improvements are also being developed. Check out xEdit Comparison for a comparison of xEdit and zEdit features.
6 |
--------------------------------------------------------------------------------
/app/docs/overview/community.html:
--------------------------------------------------------------------------------
1 | zEdit has an active community of developers and users.
2 |
3 |
8 |
--------------------------------------------------------------------------------
/app/docs/profiles.html:
--------------------------------------------------------------------------------
1 | zEdit offers a profile system which allow you to use different settings for different game modes/use cases. Profiles can be managed from the Profiles Modal .
2 |
3 |
--------------------------------------------------------------------------------
/app/docs/views.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Global modal views
4 | Modal views which are available from any part of the application.
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/docs/views/editView.html:
--------------------------------------------------------------------------------
1 | The edit view is the main view of the Edit application mode . This view offers a flexible interface to view and edit plugin files.
2 |
3 | Panes and tabs
4 | The edit view currently offers two panes, which each allow you to have any number of tabs. In the future you will be able to split panes arbitrarily, and move tabs between panes.
5 |
6 | You can create a tab by clicking the + button. You can close a tab by clicking the X button.
7 |
8 | Tab views
9 | Tabs can display one of the following views:
10 |
11 |
12 |
13 | Modal views
14 |
15 |
--------------------------------------------------------------------------------
/app/docs/views/editView/logView.html:
--------------------------------------------------------------------------------
1 | The log view allows you to view the application log.
2 |
3 | Message types
4 | There are three major types of messages in the log view:
5 |
6 |
7 | [INFO] - These are informational messages.
8 | [WARN] - These are warnings that something may not be operating as expected.
9 | [ERROR] - These are error messages, informing you when something went wrong.
10 |
--------------------------------------------------------------------------------
/app/docs/views/progressView.html:
--------------------------------------------------------------------------------
1 | The progress view is displayed over the application when it is performing a large task such as executing a script. The progress view either displays an indeterminate spinner and message or a modal with a progress bar and embedded log.
2 |
3 | Transparency
4 | The progress view uses transparency. If you are running Windows 7/8/10 with Aero disabled (e.g. using a Windows Basic theme) the window will not display, making the application unusable. You can fix this by starting the application with the --disable-transparency
target line parameter.
5 |
--------------------------------------------------------------------------------
/app/docs/views/startView.html:
--------------------------------------------------------------------------------
1 | The start view is the view displayed when you start zEdit.
2 |
3 | Starting a session
4 | To start a session, select the application mode you want to use from the application mode dropdown and the profile you want to use from the profile dropdown, then click the Start Session button.
5 |
6 | Modal views
7 |
8 |
--------------------------------------------------------------------------------
/app/images/games/0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/app/images/games/0.png
--------------------------------------------------------------------------------
/app/images/games/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/app/images/games/1.png
--------------------------------------------------------------------------------
/app/images/games/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/app/images/games/2.png
--------------------------------------------------------------------------------
/app/images/games/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/app/images/games/3.png
--------------------------------------------------------------------------------
/app/images/games/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/app/images/games/4.png
--------------------------------------------------------------------------------
/app/images/games/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/app/images/games/5.png
--------------------------------------------------------------------------------
/app/images/games/undefined.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/app/images/games/undefined.png
--------------------------------------------------------------------------------
/app/partials/addMastersModal.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/app/partials/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/partials/edit.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/partials/editMerge/details.html:
--------------------------------------------------------------------------------
1 |
20 |
--------------------------------------------------------------------------------
/app/partials/editMerge/loadOrder.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 | [{{$parent.item.index | hex:2 }}] {{::$parent.item.filename}}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/partials/editMerge/plugins.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{::$parent.item.filename}}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/partials/editMergeModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{editing ? 'Edit' : 'Create'}} Merge
6 |
7 |
8 |
9 |
10 | OK
11 | Cancel
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/partials/editModal.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/app/partials/filterView.html:
--------------------------------------------------------------------------------
1 |
2 | Search in
3 | {{scopeLabel}} -
4 | {{view.results.length}} results found.
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/partials/filters/arrayItem.html:
--------------------------------------------------------------------------------
1 |
2 | Path
3 |
4 |
5 |
6 | Subpath
7 |
8 |
9 |
10 | Value
11 |
12 |
13 |
14 |
15 |
16 | Not present
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/partials/filters/baseRecord.html:
--------------------------------------------------------------------------------
1 |
2 | Value
3 |
4 | Signature
5 | Editor ID
6 | Name
7 |
8 |
9 |
10 |
11 |
12 |
13 | Ignore case
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/partials/filters/conflictStatus.html:
--------------------------------------------------------------------------------
1 |
2 | Path
3 |
4 |
5 |
21 |
--------------------------------------------------------------------------------
/app/partials/filters/flag.html:
--------------------------------------------------------------------------------
1 |
2 | Path
3 |
4 |
5 |
6 | Flag Name
7 |
8 |
9 |
10 |
11 |
12 | Not present
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/partials/filters/group.html:
--------------------------------------------------------------------------------
1 |
2 | Mode
3 |
4 | and
5 | or
6 |
7 |
8 | Filters
9 |
10 | Add Filter
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/partials/filters/number.html:
--------------------------------------------------------------------------------
1 |
2 | Path
3 |
4 |
5 |
6 | Value
7 |
8 | Equal to
9 | Not equal to
10 | Greater than
11 | Less than
12 | Range
13 |
14 |
15 | to
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/partials/filters/recordType.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Master
5 |
6 |
7 |
8 | Override
9 |
10 |
11 |
12 | Injected
13 |
14 |
15 |
16 | Not Injected
17 |
18 |
--------------------------------------------------------------------------------
/app/partials/filters/reference.html:
--------------------------------------------------------------------------------
1 |
2 | Path
3 |
4 |
5 |
6 | Reference
7 |
8 |
9 |
10 |
11 |
12 | References file
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/partials/filters/referencedBy.html:
--------------------------------------------------------------------------------
1 |
2 | Value
3 |
4 | Record Type
5 | File
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/partials/filters/string.html:
--------------------------------------------------------------------------------
1 |
2 | Path
3 |
4 |
5 |
6 | Value
7 |
8 | Contains
9 | Exact match
10 | Regex
11 |
12 |
13 |
14 |
15 |
16 |
17 | Ignore case
18 |
19 |
20 |
21 | Search all paths
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/partials/helpModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{::$parent.item.label}}
8 |
9 |
10 |
11 |
12 | {{topic.label}}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/partials/loadOrderModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 | [{{$parent.item.index | hex:2 }}]
10 | {{::$parent.item.filename}}
11 |
12 |
13 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/partials/logView.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{::message.text}}
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/partials/manageExtensions/browseModules.html:
--------------------------------------------------------------------------------
1 | Browse Modules
2 |
3 | Modules are published via the zedit-registry repo and are installed to {{::modulesFolderPath}}.
4 |
5 |
6 |
11 |
12 | {{::module.description}}
13 |
14 |
19 |
20 |
--------------------------------------------------------------------------------
/app/partials/manageExtensions/browseThemes.html:
--------------------------------------------------------------------------------
1 | Browse Themes
2 |
3 | Themes are published via the zedit-registry repo and are installed to {{::themesFolderPath}}.
4 |
5 |
6 |
11 |
12 | {{::theme.description}}
13 |
14 |
19 |
20 |
--------------------------------------------------------------------------------
/app/partials/manageExtensions/installedThemes.html:
--------------------------------------------------------------------------------
1 | Installed Themes ({{themes.length}})
2 |
3 |
4 |
9 |
10 | {{::theme.description}}
11 |
12 |
20 |
21 |
22 |
23 | Install Theme
24 |
25 |
--------------------------------------------------------------------------------
/app/partials/manageExtensionsModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{::tab.label}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/partials/merge.html:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 | Build Merges
12 | Relink Scripts
13 | Create Merge
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/partials/newTabView.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{::viewName}}
5 |
6 |
--------------------------------------------------------------------------------
/app/partials/profilesModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Game Profiles
7 |
10 |
11 |
12 |
13 | Default Profile
14 |
15 | None
16 |
17 |
18 |
19 |
20 |
21 | Add Profile
22 | Close
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/partials/promptModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{::modalOptions.title}}
5 | {{::modalOptions.prompt}}
6 |
7 |
8 | Yes
9 | No
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/partials/refactorFileModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Refactor File
7 |
21 |
22 |
23 | OK
24 | Cancel
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/partials/relinkScriptsModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Relink Scripts
7 |
8 |
16 |
17 |
18 | OK
19 | Cancel
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/partials/saveModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{message}}
5 | {{detailedMessage}}...
6 |
7 |
8 | Select Plugins to Save
9 |
15 |
16 |
17 | Save
18 | Discard
19 | Cancel
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/partials/settings/integrations.html:
--------------------------------------------------------------------------------
1 |
2 |
Integration Settings
3 |
4 |
5 |
6 |
7 |
8 | Detect
9 | OK
10 |
11 |
--------------------------------------------------------------------------------
/app/partials/settings/merge.html:
--------------------------------------------------------------------------------
1 | Merge Settings
2 |
3 |
10 |
11 | Integrations
12 |
22 |
--------------------------------------------------------------------------------
/app/partials/settings/recordView.html:
--------------------------------------------------------------------------------
1 | Record View Settings
2 |
3 |
17 |
18 | Default Column Widths
19 |
20 |
21 | Element Names Column
22 |
23 |
24 |
25 | Record Columns
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/partials/settings/treeView.html:
--------------------------------------------------------------------------------
1 | Tree View Settings
2 |
3 |
--------------------------------------------------------------------------------
/app/partials/settingsModal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{::tab.label}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | OK
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/partials/start.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | z{{::appMode.capitalize()}}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | None
14 |
15 |
16 |
17 |
18 | Start Session
19 |
20 |
21 |
22 |
23 |
24 | zEdit v{{appVersion}}
25 |
26 |
--------------------------------------------------------------------------------
/app/progress.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | zEdit - Progress
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/borlndmm.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/borlndmm.dll
--------------------------------------------------------------------------------
/build/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/build/icon.ico
--------------------------------------------------------------------------------
/build/icons/512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/build/icons/512x512.png
--------------------------------------------------------------------------------
/cache/CaravanPack.esm-91c0d7a834954057e7998921e154b4ff.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/cache/ClassicPack.esm-44cb6ac23018c4394dbd6b747d6db402.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/cache/DLCOrrery.esp-d4e363c4cbf3b39320ed0590322a72a2.json:
--------------------------------------------------------------------------------
1 | [{"g":6,"f":17938939,"d":"","p":"Targets\\[6]\\Conditions\\[1]\\Parameter #2"},{"g":6,"f":17938939,"d":"","p":"Targets\\[5]\\Conditions\\[1]\\Parameter #2"},{"g":6,"f":17938939,"d":"","p":"Targets\\[4]\\Conditions\\[1]\\Parameter #2"},{"g":6,"f":17938939,"d":"","p":"Targets\\[3]\\Conditions\\[1]\\Parameter #2"},{"g":6,"f":17938939,"d":"","p":"Targets\\[2]\\Conditions\\[1]\\Parameter #2"},{"g":6,"f":17949016,"d":"","p":"Conditions\\[1]\\Parameter #2"},{"g":0,"f":31822},{"g":0,"f":32019},{"g":0,"f":204117},{"g":0,"f":43074},{"g":0,"f":42912},{"g":2,"f":550367},{"g":2,"f":180690}]
--------------------------------------------------------------------------------
/cache/DLCShiveringIsles.esp-0dee99680d432152c8e41e901965090a.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/cache/DLCSpellTomes.esp-c5c79fd6fbd6f887fdfb4a0a85dc25b8.json:
--------------------------------------------------------------------------------
1 | [{"g":0,"f":24668},{"g":0,"f":252832},{"g":0,"f":180736},{"g":0,"f":254616},{"g":0,"f":216630},{"g":0,"f":252831},{"g":0,"f":98516},{"g":0,"f":98489},{"g":0,"f":113650},{"g":0,"f":545951},{"g":0,"f":254615},{"g":0,"f":254614},{"g":0,"f":174110},{"g":0,"f":216610},{"g":0,"f":113663},{"g":0,"f":67004},{"g":0,"f":228415},{"g":0,"f":293920},{"g":0,"f":98485},{"g":0,"f":151704},{"g":0,"f":67003},{"g":0,"f":216634},{"g":0,"f":211136},{"g":0,"f":218567},{"g":0,"f":245787},{"g":0,"f":218554},{"g":0,"f":94763},{"g":0,"f":25795},{"g":0,"f":126280},{"g":0,"f":228417},{"g":0,"f":141412},{"g":0,"f":25787},{"g":0,"f":112832},{"g":0,"f":324618},{"g":0,"f":245823},{"g":0,"f":261499},{"g":0,"f":98488}]
--------------------------------------------------------------------------------
/cache/DLCVileLair.esp-2c51ff6c5196a334377f41a5ec7159e5.json:
--------------------------------------------------------------------------------
1 | [{"g":6,"f":16808310,"d":"","p":"Conditions\\[0]\\Parameter #2"},{"g":6,"f":16780861,"d":"","p":"Conditions\\[0]\\Parameter #2"},{"g":6,"f":16780856,"d":"","p":"Conditions\\[0]\\Parameter #2"},{"g":6,"f":16809570,"d":"","p":"Conditions\\[0]\\Parameter #2"},{"g":0,"f":38065},{"g":0,"f":31685},{"g":0,"f":29171},{"g":0,"f":29172},{"g":2,"f":1601040},{"g":0,"f":29205},{"g":0,"f":25213},{"g":0,"f":29236},{"g":0,"f":31684},{"g":0,"f":603264},{"g":0,"f":95473},{"g":0,"f":375994}]
--------------------------------------------------------------------------------
/cache/DLCworkshop02.esm-63aebbc3ce8269fa90d74a49cf675bee.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/cache/MercenaryPack.esm-4dff17254e80871ec094c9fb8d51916f.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/cache/TribalPack.esm-bbe875b0ecf08f337f55200c0f171cd5.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/config/env_development.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "development",
3 | "allow_relinking": true,
4 | "show_hidden_appmodes": true,
5 | "allow_experimental_merge_methods": true
6 | }
7 |
--------------------------------------------------------------------------------
/config/env_production.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "production",
3 | "allow_relinking": false
4 | }
5 |
--------------------------------------------------------------------------------
/config/env_test.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test",
3 | "description": "Add here any environment specific stuff you like."
4 | }
5 |
--------------------------------------------------------------------------------
/e2e/hello_world.e2e.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 | import testUtils from './utils';
3 |
4 | describe('application launch', () => {
5 | beforeEach(testUtils.beforeEach);
6 | afterEach(testUtils.afterEach);
7 |
8 | it('shows hello world text on screen after launch', function () {
9 | return this.app.client.getText('#greet').then((text) => {
10 | expect(text).to.equal('Hello World!');
11 | });
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/e2e/utils.js:
--------------------------------------------------------------------------------
1 | import electron from 'electron';
2 | import { Application } from 'spectron';
3 |
4 | var beforeEach = function () {
5 | this.timeout(10000);
6 | this.app = new Application({
7 | path: electron,
8 | args: ['.'],
9 | startTimeout: 10000,
10 | waitTimeout: 10000,
11 | });
12 | return this.app.start();
13 | };
14 |
15 | var afterEach = function () {
16 | this.timeout(10000);
17 | if (this.app && this.app.isRunning()) {
18 | return this.app.stop();
19 | }
20 | };
21 |
22 | export default {
23 | beforeEach: beforeEach,
24 | afterEach: afterEach,
25 | };
26 |
--------------------------------------------------------------------------------
/filters/Conflict Losers.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "Record Type",
4 | "master": false,
5 | "override": true,
6 | "injected": true,
7 | "notInjected": true
8 | },
9 | {
10 | "type": "Conflict Status",
11 | "path": "",
12 | "caUnknown": true,
13 | "caOnlyOne": true,
14 | "caNoConflict": true,
15 | "caConflictBenign": true,
16 | "caOverride": true,
17 | "caConflict": true,
18 | "caConflictCritical": true,
19 | "ctUnknown": false,
20 | "ctIgnored": false,
21 | "ctNotDefined": false,
22 | "ctIdenticalToMaster": false,
23 | "ctOnlyOne": false,
24 | "ctHiddenByModGroup": false,
25 | "ctMaster": false,
26 | "ctConflictBenign": false,
27 | "ctOverride": false,
28 | "ctIdenticalToMasterWinsConflict": false,
29 | "ctConflictWins": false,
30 | "ctConflictLoses": true
31 | }
32 | ]
--------------------------------------------------------------------------------
/filters/Permanently Disabled Master records.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "String",
4 | "path": "XESP\\Reference",
5 | "compareType": "Exact match",
6 | "value": "Player [00000014]",
7 | "allPaths": false,
8 | "ignoreCase": false
9 | },
10 | {
11 | "type": "Flag",
12 | "path": "XESP\\Flags",
13 | "value": "Set Enable State to Opposite of Parent",
14 | "notPresent": false
15 | }
16 | ]
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | require('./tasks/build_app');
2 | require('./tasks/build_tests');
3 | require('./tasks/start');
4 | require('./tasks/generateCommonDocs');
5 |
--------------------------------------------------------------------------------
/layouts/default.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "horizontal",
3 | "panes": [
4 | {
5 | "width": "45%",
6 | "tabs": ["treeView"]
7 | },
8 | {
9 | "tabs": ["recordView"]
10 | }
11 | ]
12 | }
--------------------------------------------------------------------------------
/modules/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z-edit/zedit/678bd7971849db5a01a052210332d0ea5c791132/modules/.gitkeep
--------------------------------------------------------------------------------
/scripts/Export Spells.js:
--------------------------------------------------------------------------------
1 | let allSpells = xelib.GetRecords(0, 'SPEL'),
2 | sortedSpells = {},
3 | perkSuffixes = ['Novice00', 'Apprentice25', 'Adept50', 'Expert75', 'Master100'],
4 | perkExpr = new RegExp(`^([a-zA-Z]+)(${perkSuffixes.join('|')})$`),
5 | output = '';
6 |
7 | let getSpellSchool = function(spell) {
8 | const halfCostPerkPath = 'SPIT\\Half-cost perk';
9 | if (!xelib.HasElement(spell, halfCostPerkPath)) return;
10 | if (xelib.GetUIntValue(spell, halfCostPerkPath) === 0) return;
11 | let halfCostPerk = xelib.GetLinksTo(spell, halfCostPerkPath),
12 | match = perkExpr.exec(xelib.EditorID(halfCostPerk));
13 | return match && match[1];
14 | };
15 |
16 | allSpells.forEach(spell => {
17 | let school = getSpellSchool(spell);
18 | if (!school) return;
19 | if (!sortedSpells.hasOwnProperty(school)) sortedSpells[school] = [];
20 | sortedSpells[school].push(xelib.LongName(spell));
21 | });
22 |
23 | Object.keys(sortedSpells).forEach(school => {
24 | output += `== ${school} ==\r\n`;
25 | sortedSpells[school].forEach(spell => output += `- ${spell}\r\n`);
26 | });
27 |
28 | console.log(output);
--------------------------------------------------------------------------------
/scripts/Test Progress Modal.js:
--------------------------------------------------------------------------------
1 | let {showProgress, logMessage, progressTitle,
2 | addProgress, progressMessage} = zedit.progressService;
3 |
4 | let targetDuration = 5, // duration in seconds
5 | numOperations = targetDuration * 10;
6 |
7 | showProgress({
8 | determinate: true,
9 | title: '?_?',
10 | message: '...',
11 | current: 0,
12 | max: numOperations,
13 | log: [],
14 | keepOpen: true
15 | });
16 |
17 | // ~0.1 seconds
18 | let doLongOperation = function() {
19 | for (let i = 0; i < 800; i++) {
20 | let j = 0;
21 | while (++j < i * i) {}
22 | }
23 | };
24 |
25 | logMessage('Let\'s do some stuff!');
26 | progressTitle('Doing Stuff');
27 |
28 | // ~10s
29 | for (let i = 0; i < numOperations; i++) {
30 | logMessage(`Stuff #${i}`);
31 | doLongOperation();
32 | addProgress(1);
33 | if (i === 5) progressMessage('Herp');
34 | if (i === 10) progressMessage('Derp');
35 | }
36 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/autofocus.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('autofocus', function($timeout) {
2 | return {
3 | restrict: 'A',
4 | link: function(scope, element) {
5 | $timeout(() => element[0].focus());
6 | }
7 | }
8 | });
9 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/childrenTopics.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('childrenTopics', function() {
2 | return {
3 | restrict: 'E',
4 | scope: false,
5 | templateUrl: 'directives/childrenTopics.html'
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/codeBlock.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('codeBlock', function(themeService, codeMirrorFactory) {
2 | return {
3 | restrict: 'E',
4 | scope: {
5 | basePath: '@',
6 | path: '@'
7 | },
8 | template: ' ',
9 | link: function(scope, element) {
10 | // load code
11 | let basePath = scope.basePath || 'app/docs/development/apis',
12 | path = `${basePath}/${scope.path}`,
13 | code = fh.loadResource(path, 'utf8') || fh.loadTextFile(path);
14 |
15 | // attach code mirror
16 | let language = fh.getFileExt(scope.path),
17 | options = codeMirrorFactory.getOptions(language, true),
18 | textArea = element[0].firstElementChild,
19 | cm = CodeMirror.fromTextArea(textArea, options);
20 | cm.setValue(code.trimRight());
21 |
22 | // event handling
23 | scope.$on('syntaxThemeChanged', function(e, theme) {
24 | let themeName = themeService.extractThemeName(theme, 'default');
25 | cm.setOption('theme', themeName);
26 | cm.refresh();
27 | });
28 | }
29 | }
30 | });
31 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/codeMirror.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('codeMirror', function($timeout, themeService, codeMirrorFactory) {
2 | return {
3 | restrict: 'A',
4 | require: '?ngModel',
5 | compile: function() {
6 | return function (scope, element, attrs, ngModel) {
7 | let options = codeMirrorFactory.getOptions(attrs.codeMirror || 'js'),
8 | cm = CodeMirror.fromTextArea(element[0], options);
9 |
10 | // ng model data binding
11 | ngModel.$render = () => cm.setValue(ngModel.$viewValue || '');
12 | cm.on('change', function() {
13 | let newValue = cm.getValue();
14 | scope.$evalAsync(() => ngModel.$setViewValue(newValue));
15 | });
16 |
17 | // event handling
18 | scope.$on('refresh', () => $timeout(cm.refresh));
19 | scope.$on('syntaxThemeChanged', function(e, theme) {
20 | let themeName = themeService.extractThemeName(theme, 'default');
21 | cm.setOption('theme', themeName);
22 | cm.refresh();
23 | });
24 | };
25 | }
26 | }
27 | });
28 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/colorSelector.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('colorSelector', function() {
2 | return {
3 | restrict: 'E',
4 | scope: {
5 | color: '='
6 | },
7 | templateUrl: 'directives/colorSelector.html',
8 | controller: 'colorSelectorController'
9 | }
10 | });
11 |
12 | ngapp.controller('colorSelectorController', function($scope) {
13 | $scope.selectColor = function(color) {
14 | $scope.$applyAsync(() => {
15 | color = new Color(color);
16 | $scope.color.copyRGB(color);
17 | });
18 | };
19 |
20 | $scope.$watch('color', () => {
21 | if (!$scope.color) return;
22 | $scope.customColorText = $scope.color.toRGB();
23 | }, true);
24 | });
25 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/dynController.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('dynController', function($controller, $parse) {
2 | let getController = function(ctrlName, scope, element, attrs) {
3 | return $controller(ctrlName, {
4 | $scope: scope,
5 | $element: element,
6 | $attrs: attrs
7 | });
8 | };
9 |
10 | let resolveController = function(ctrlExpr, scope, element, attrs) {
11 | let ctrl = $parse(ctrlExpr)(scope);
12 | return ctrl && getController(ctrl, scope, element, attrs);
13 | };
14 |
15 | return {
16 | restrict: 'A',
17 | scope: true,
18 | link: function(scope, element, attrs) {
19 | attrs.$observe('dynController', function(ctrlExpr) {
20 | let controller = resolveController(ctrlExpr, scope, element, attrs);
21 | if (!controller) return;
22 | element.data('$Controller', controller);
23 | });
24 | }
25 | }
26 | });
27 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/editModal.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('editModalController', function($scope) {
2 | // scope functions
3 | $scope.applyValue = function() {
4 | if ($scope.invalid) return;
5 | $scope.modalOptions.callback($scope.value);
6 | $scope.$emit('closeModal');
7 | };
8 |
9 | $scope.validate = function() {
10 | $scope.valid = angular.isDefined($scope.value) &&
11 | $scope.modalOptions.isValid($scope.value);
12 | };
13 |
14 | // initialization
15 | $scope.value = $scope.modalOptions.initialValue;
16 | });
17 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/enumSelect.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('enumSelect', function() {
2 | return {
3 | restrict: 'E',
4 | scope: {
5 | model: '=',
6 | handle: '=?'
7 | },
8 | templateUrl: 'directives/enumSelect.html',
9 | controller: 'enumSelectController'
10 | }
11 | });
12 |
13 | ngapp.controller('enumSelectController', function($scope) {
14 | $scope.enumOptions = xelib.GetEnumOptions($scope.handle);
15 | });
16 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/enumerationMembers.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('enumerationMembers', function() {
2 | return {
3 | restrict: 'E',
4 | templateUrl: 'directives/enumerationMembers.html',
5 | scope: {
6 | members: '='
7 | },
8 | replace: true
9 | }
10 | });
11 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/errorGroup.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('errorGroup', function() {
2 | return {
3 | restrict: 'E',
4 | scope: false,
5 | templateUrl: 'directives/errorGroup.html'
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/errorResolutions.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('errorResolutions', function () {
2 | return {
3 | restrict: 'E',
4 | templateUrl: 'directives/errorResolutions.html',
5 | scope: false
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/errorTypes.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('errorTypes', function() {
2 | return {
3 | restrict: 'E',
4 | scope: true,
5 | templateUrl: '/partials/errorTypes.html',
6 | link: function(scope, errorTypeFactory, errorResolutionFactory) {
7 | scope.errorTypes = errorTypeFactory.errorTypes();
8 | scope.errorResolutions = errorResolutionFactory.errorResolutions;
9 | }
10 | }
11 | });
--------------------------------------------------------------------------------
/src/javascripts/Directives/expandableSection.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('expandableSection', function($timeout) {
2 | return {
3 | restrict: 'E',
4 | transclude: {
5 | title: 'title',
6 | content: 'content'
7 | },
8 | templateUrl: 'directives/expandableSection.html',
9 | link: function(scope, element) {
10 | let titleElement = element[0].children[0],
11 | iconElement = titleElement.children[0],
12 | contentElement = element[0].children[1];
13 |
14 | titleElement.addEventListener('click', function() {
15 | contentElement.classList.toggle('ng-hide');
16 | iconElement.classList.toggle('collapsed');
17 | iconElement.classList.toggle('expanded');
18 | $timeout(() => scope.$broadcast('vsRepeatTrigger'));
19 | });
20 | }
21 | }
22 | });
23 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/fileSelect.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('fileSelect', function() {
2 | return {
3 | restrict: 'E',
4 | scope: {
5 | model: '='
6 | },
7 | templateUrl: 'directives/fileSelect.html',
8 | controller: 'fileSelectController'
9 | }
10 | });
11 |
12 | ngapp.controller('fileSelectController', function($scope) {
13 | let fileNames = xelib.GetLoadedFileNames();
14 |
15 | $scope.fileSearch = function(str) {
16 | return fileNames.filter((fileName) => {
17 | return fileName.startsWith(str);
18 | });
19 | };
20 | });
21 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/focusOn.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('focusOn', function() {
2 | return {
3 | restrict: 'A',
4 | scope: false,
5 | link: function(scope, element, attrs) {
6 | scope.$on(attrs.focusOn, () => element[0].focus());
7 | }
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/functionOptions.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('functionOptions', function() {
2 | return {
3 | restrict: 'E',
4 | templateUrl: 'directives/functionOptions.html',
5 | scope: {
6 | options: '='
7 | },
8 | replace: true
9 | }
10 | });
11 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/listViewParent.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('listViewParent', function($timeout) {
2 | return {
3 | restrict: 'A',
4 | link: function(scope, element) {
5 | let el = element[0];
6 | el.tabIndex = 0;
7 | $timeout(() => el.focus());
8 | }
9 | }
10 | });
11 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/loader.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('loader', function () {
2 | return {
3 | restrict: 'E',
4 | templateUrl: 'directives/loader.html',
5 | controller: 'loaderController',
6 | scope: {
7 | message: '=',
8 | spinnerOpts: '=',
9 | canCancel: '=?'
10 | }
11 | }
12 | });
13 |
14 | ngapp.controller('loaderController', function ($scope, $rootScope) {
15 | $scope.cancel = function() {
16 | $scope.message = "Cancelling...";
17 | $rootScope.$broadcast('cancel');
18 | };
19 | });
20 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/mergeItem.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('mergeItem', function() {
2 | return {
3 | restrict: 'E',
4 | templateUrl: 'directives/mergeItem.html',
5 | }
6 | });
--------------------------------------------------------------------------------
/src/javascripts/Directives/modalViewsList.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('modalViewsList', function() {
2 | return {
3 | restrict: 'E',
4 | scope: false,
5 | templateUrl: 'directives/modalViewsList.html'
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/ngDrag.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('ngDrag', function($parse, $rootScope) {
2 | return function(scope, element, attrs) {
3 | let el = element[0],
4 | callback = $parse(attrs.ngDrag),
5 | executeCallback = (e, callback) => {
6 | if (!callback) return;
7 | let result = false;
8 | scope.$apply(() => result = callback(scope, {$event: e}));
9 | return result;
10 | };
11 | el.draggable = true;
12 |
13 | // event listeners
14 | el.addEventListener('dragstart', function(e) {
15 | if (!executeCallback(e, callback)) {
16 | e.preventDefault();
17 | return;
18 | }
19 | e.dataTransfer.effectAllowed = 'move';
20 | el.classList.add('dragging');
21 | });
22 |
23 | el.addEventListener('dragend', () => {
24 | $rootScope.$broadcast('stopDrag');
25 | el.classList.remove('dragging');
26 | });
27 | }
28 | });
29 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/ngScroll.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('ngScroll', function($parse) {
2 | return {
3 | restrict: 'A',
4 | compile : function($element, attr) {
5 | let fn = $parse(attr.ngScroll);
6 | return function ngEventHandler(scope, element) {
7 | element.on('scroll', function(event) {
8 | scope.$apply(() => fn(scope, {$event: event}));
9 | });
10 | }
11 | }
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/ngWheel.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('ngWheel', function($parse) {
2 | return {
3 | restrict: 'A',
4 | compile : function($element, attr) {
5 | let fn = $parse(attr['ngWheel']);
6 | return function ngEventHandler(scope, element) {
7 | element.on('wheel', function(event) {
8 | scope.$apply(() => fn(scope, {$event: event}));
9 | });
10 | }
11 | }
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/objectSchema.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('objectSchema', function() {
2 | return {
3 | restrict: 'E',
4 | templateUrl: 'directives/objectSchema.html',
5 | controller: 'objectSchemaController',
6 | scope: {
7 | basePath: '@',
8 | path: '@',
9 | schema: '=?'
10 | },
11 | replace: true
12 | }
13 | });
14 |
15 | ngapp.controller('objectSchemaController', function($scope) {
16 | let loadSchema = function() {
17 | let basePath = $scope.basePath || 'app/docs/development/apis',
18 | path = `${basePath}/${$scope.path}`;
19 | return fh.loadResource(path) || fh.loadJsonFile(path);
20 | };
21 |
22 | if ($scope.path) {
23 | $scope.schema = loadSchema();
24 | }
25 | });
26 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/profile.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('profile', function() {
2 | return {
3 | restrict: 'E',
4 | scope: false,
5 | templateUrl: 'directives/profile.html'
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/progressBar.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('progressBar', function() {
2 | return {
3 | restrict: 'E',
4 | scope: {
5 | progress: '='
6 | },
7 | template:
8 | '
' +
9 | '{{percentProgress}}
',
10 | controller: 'progressBarController'
11 | }
12 | });
13 |
14 | ngapp.controller('progressBarController', function($scope) {
15 | let p = $scope.progress;
16 | $scope.$watch('progress.current', function() {
17 | $scope.percentProgress = (p.current / p.max).toPercentage();
18 | $scope.progressStyle = { width: $scope.percentProgress };
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/progressModal.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('progressModal', function() {
2 | return {
3 | restrict: 'E',
4 | scope: false,
5 | templateUrl: 'directives/progressModal.html',
6 | controller: 'progressModalController'
7 | }
8 | });
9 |
10 | ngapp.controller('progressModalController', function($scope) {
11 | $scope.toggleExpanded = () => $scope.expanded = !$scope.expanded;
12 | });
13 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/referenceSelect.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('referenceSelect', function() {
2 | return {
3 | restrict: 'E',
4 | scope: {
5 | model: '=',
6 | signature: '=?',
7 | signatures: '=?',
8 | handle: '=?'
9 | },
10 | templateUrl: 'directives/referenceSelect.html',
11 | controller: 'referenceSelectController'
12 | }
13 | });
14 |
15 | ngapp.controller('referenceSelectController', function($scope) {
16 | // default values
17 | if (angular.isUndefined($scope.signatures))
18 | $scope.signatures = Object.keys(xelib.GetSignatureNameMap()).sort();
19 | if (angular.isUndefined($scope.signature))
20 | $scope.signature = $scope.signatures[0];
21 |
22 | // scope functions
23 | $scope.referenceSearch = function(str) {
24 | if ($scope.signature === 'Any') return [];
25 | return xelib.FindValidReferences($scope.handle || 0,
26 | $scope.signature, str, 10);
27 | };
28 |
29 | $scope.setCustomResult = (str) => $scope.model = str;
30 | });
31 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/searchBar.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('searchBar', function () {
2 | return {
3 | restrict: 'E',
4 | templateUrl: 'directives/searchBar.html'
5 | }
6 | });
7 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/selectText.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('selectText', function($timeout) {
2 | return {
3 | restrict: 'A',
4 | link: function(scope, element) {
5 | $timeout(() => {
6 | element[0].focus();
7 | element[0].select();
8 | });
9 | }
10 | }
11 | });
12 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/statusBar.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('statusBar', function(spinnerFactory) {
2 | return {
3 | restrict: 'E',
4 | scope: false,
5 | templateUrl: 'directives/statusBar.html',
6 | link: function(scope) {
7 | scope.spinnerOpts = spinnerFactory.tinyOptions;
8 |
9 | scope.$on('statusMessage', function(e, message) {
10 | scope.$applyAsync(() => scope.statusMessage = message);
11 | logger.info(message);
12 | });
13 |
14 | scope.$on('toggleStatusBar', function(e, show) {
15 | scope.$applyAsync(() => {
16 | scope.showStatusBar = show;
17 | if (show) return;
18 | scope.statusMessage = '';
19 | scope.previewMessage = '';
20 | });
21 | });
22 |
23 | scope.$on('previewMessage', function(e, message) {
24 | scope.$applyAsync(() => scope.previewMessage = message);
25 | })
26 | }
27 | }
28 | });
29 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/tabs.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('tabs', function() {
2 | return {
3 | restrict: 'E',
4 | scope: false,
5 | templateUrl: 'directives/tabs.html',
6 | controller: 'tabsController'
7 | }
8 | });
9 |
10 | ngapp.controller('tabsController', function($scope, $attrs, tabService, tabsFactory) {
11 | $scope.tabs = tabsFactory[$attrs.source];
12 | tabService.buildFunctions($scope);
13 | });
14 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/textureSelector.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('textureSelector', function() {
2 | return {
3 | restrict: 'E',
4 | scope: {
5 | texture: '=',
6 | key: '@'
7 | },
8 | templateUrl: 'directives/textureSelector.html',
9 | controller: 'textureSelectorController'
10 | }
11 | });
12 |
13 | ngapp.controller('textureSelectorController', function($scope, $timeout, recentService, resourceService) {
14 | recentService.store($scope.key, 10);
15 | $scope.recentTextures = recentService.get($scope.key);
16 |
17 | // scope functions
18 | $scope.textureSearch = function(text) {
19 | const texturesLength = 9;
20 | return resourceService.getFiles('textures')
21 | .filter(path => path.contains(text, true))
22 | .slice(0, 100)
23 | .map(path => path.slice(texturesLength));
24 | };
25 |
26 | $scope.setTexture = function(texture) {
27 | $scope.$applyAsync(() => {
28 | $scope.texture = texture;
29 | recentService.add($scope.key, $scope.texture);
30 | });
31 | };
32 | });
33 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/themeScrollbarFix.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('themeScrollbarFix', function($timeout) {
2 | return {
3 | restrict: 'A',
4 | link: function(scope, element) {
5 | let el = element[0], oldOverflowY;
6 | scope.$on('themeChanged', function() {
7 | oldOverflowY = el.style['overflow-y'];
8 | el.style['overflow-y'] = 'hidden';
9 | $timeout(() => el.style['overflow-y'] = oldOverflowY);
10 | });
11 | }
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/titleBar.js:
--------------------------------------------------------------------------------
1 | ngapp.directive('titleBar', function() {
2 | return {
3 | restrict: 'E',
4 | scope: false,
5 | templateUrl: 'directives/titleBar.html'
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/src/javascripts/Directives/treeNode.js:
--------------------------------------------------------------------------------
1 | let initNodeFn = function(scope, element) {
2 | let el = element[0];
3 |
4 | // event listeners
5 | el.addEventListener('mousedown', function(e) {
6 | scope.$applyAsync(() => scope.onNodeMouseDown(e, scope.node));
7 | });
8 |
9 | el.addEventListener('dblclick', function(e) {
10 | scope.$applyAsync(() => scope.onNodeDoubleClick(e, scope.node));
11 | });
12 |
13 | scope.$watch('node.selected', function(newVal) {
14 | el.classList[newVal ? 'add' : 'remove']('selected');
15 | });
16 |
17 | // initialize node data
18 | if (scope.node.hasData) return;
19 | scope.getNodeData(scope.node);
20 | el.className = `${el.className} ${scope.node.class}`;
21 | };
22 |
23 | ngapp.directive('treeNode', function() {
24 | return {
25 | restrict: 'A',
26 | priority: 450,
27 | link: initNodeFn
28 | }
29 | });
30 |
--------------------------------------------------------------------------------
/src/javascripts/Factories/buttonFactory.js:
--------------------------------------------------------------------------------
1 | ngapp.service('buttonFactory', function() {
2 | this.buttons = [];
3 | });
4 |
--------------------------------------------------------------------------------
/src/javascripts/Factories/codeMirrorFactory.js:
--------------------------------------------------------------------------------
1 | ngapp.service('codeMirrorFactory', function(themeService) {
2 | let options = {
3 | js: { mode: 'javascript' },
4 | html: { mode: 'htmlmixed' }
5 | };
6 |
7 | this.getOptions = function(label, readOnly = false) {
8 | let filename = themeService.getCurrentSyntaxTheme();
9 | return Object.assign({}, options[label], {
10 | theme: themeService.extractThemeName(filename, 'default'),
11 | lineNumbers: !readOnly,
12 | readOnly: readOnly,
13 | scrollbarStyle: readOnly ? null : 'native',
14 | lineWrapping: true
15 | });
16 | };
17 | });
18 |
--------------------------------------------------------------------------------
/src/javascripts/Factories/editModalFactory.js:
--------------------------------------------------------------------------------
1 | ngapp.service('editModalFactory', function(gameService) {
2 | this.saveFileAs = function(node, scope) {
3 | let name = xelib.Name(node.handle);
4 | scope.$emit('openModal', 'edit', {
5 | title: 'Save File As',
6 | class: 'edit-modal save-file-as-modal',
7 | editType: 'string',
8 | maxLength: 64,
9 | initialValue: fh.path(gameService.dataPath, name),
10 | isValid: (value) => { return value.length > 0 },
11 | callback: (filePath) => {
12 | xelib.SaveFile(node.handle, filePath);
13 | }
14 | });
15 | };
16 |
17 | this.addFile = function(scope, callback) {
18 | scope.$emit('openModal', 'edit', {
19 | title: 'Add File',
20 | editType: 'string',
21 | maxLength: 64,
22 | initialValue: 'New File.esp',
23 | isValid: (value) => { return !xelib.HasElement(0, value) },
24 | callback: callback || ((fileName) => {
25 | xelib.Release(xelib.AddFile(fileName));
26 | scope.$root.$broadcast('reloadGUI');
27 | })
28 | });
29 | };
30 | });
31 |
--------------------------------------------------------------------------------
/src/javascripts/Factories/filterViewFactory.js:
--------------------------------------------------------------------------------
1 | ngapp.service('filterViewFactory', function(viewFactory, viewLinkingService) {
2 | this.new = function() {
3 | let view = viewFactory.new('filterView');
4 |
5 | view.destroy = function() {
6 | view.scope.treeView.destroy();
7 | view.searchOptions.nodes.forEach(node => {
8 | xelib.Release(node.handle);
9 | });
10 | view.results.forEach(xelib.Release);
11 | };
12 |
13 | viewLinkingService.buildFunctions(view, 'linkedFilterView', [
14 | 'record-view'
15 | ]);
16 |
17 | return view;
18 | };
19 | });
20 |
21 | ngapp.run(function(viewFactory, filterViewFactory) {
22 | viewFactory.registerView('filterView', filterViewFactory.new);
23 | });
24 |
--------------------------------------------------------------------------------
/src/javascripts/Factories/logViewFactory.js:
--------------------------------------------------------------------------------
1 | ngapp.service('logViewFactory', function(viewFactory) {
2 | this.new = function() {
3 | return viewFactory.new('logView');
4 | };
5 | });
6 |
7 | ngapp.run(function(viewFactory, logViewFactory) {
8 | viewFactory.registerView('logView', logViewFactory.new, 'Log View');
9 | });
10 |
--------------------------------------------------------------------------------
/src/javascripts/Factories/newTabViewFactory.js:
--------------------------------------------------------------------------------
1 | ngapp.service('newTabViewFactory', function() {
2 | this.new = function() {
3 | return {
4 | templateUrl: 'partials/newTabView.html',
5 | controller: 'newTabViewController',
6 | class: 'new-tab-view',
7 | label: 'New Tab',
8 | destroy: () => {}
9 | }
10 | };
11 | });
12 |
13 | ngapp.run(function(viewFactory, newTabViewFactory) {
14 | viewFactory.registerView('newTabView', newTabViewFactory.new);
15 | });
16 |
--------------------------------------------------------------------------------
/src/javascripts/Factories/referencedByViewFactory.js:
--------------------------------------------------------------------------------
1 | ngapp.service('referencedByViewFactory', function(viewFactory, viewLinkingService) {
2 | this.new = function() {
3 | let view = viewFactory.new('referencedByView');
4 |
5 | view.releaseGrid = function(grid) {
6 | grid.forEach((node) => xelib.Release(node.handle));
7 | };
8 |
9 | view.destroy = function() {
10 | view.scope.grid && view.releaseGrid(view.scope.grid);
11 | };
12 |
13 | viewLinkingService.buildFunctions(view, 'linkedReferencedByView', [
14 | 'record-view'
15 | ]);
16 |
17 | return view;
18 | };
19 | });
20 |
21 | ngapp.run(function(viewFactory, referencedByViewFactory) {
22 | viewFactory.registerView('referencedByView', referencedByViewFactory.new,
23 | 'Referenced By View');
24 | });
25 |
--------------------------------------------------------------------------------
/src/javascripts/Factories/tabsFactory.js:
--------------------------------------------------------------------------------
1 | ngapp.service('tabsFactory', function() {
2 | this.editMergeModalTabs = [{
3 | label: 'Details',
4 | class: 'details-tab',
5 | templateUrl: 'partials/editMerge/details.html'
6 | }, {
7 | label: 'Plugins',
8 | class: 'plugins-tab',
9 | templateUrl: 'partials/editMerge/plugins.html',
10 | controller: 'editMergePluginsController'
11 | }, {
12 | label: 'Load Order',
13 | class: 'load-order-tab',
14 | templateUrl: 'partials/editMerge/loadOrder.html',
15 | controller: 'editMergeLoadOrderController'
16 | }, {
17 | label: 'Data',
18 | class: 'data-tab',
19 | templateUrl: 'partials/editMerge/data.html',
20 | controller: 'editMergeDataController'
21 | }];
22 | });
23 |
--------------------------------------------------------------------------------
/src/javascripts/Filters/bytesFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.filter('bytes', function() {
2 | return function(number, precision) {
3 | if (typeof number === "string") number = parseInt(number);
4 | if (isNaN(parseFloat(number)) || !isFinite(number)) return '-';
5 | if (number === 0) return '0 bytes';
6 | return number.toBytes(precision);
7 | }
8 | });
9 |
--------------------------------------------------------------------------------
/src/javascripts/Filters/classifyFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.filter('classify', function() {
2 | return function(str) {
3 | if (typeof str !== 'string') return '';
4 | return str.underscore('-');
5 | }
6 | });
7 |
--------------------------------------------------------------------------------
/src/javascripts/Filters/customDateFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.filter('customDate', function($filter) {
2 | return function(date) {
3 | // return Never if date is undefined
4 | if (!angular.isDefined(date)) return 'Never';
5 | return $filter('date')(date, 'medium');
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/src/javascripts/Filters/hexFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.filter('hex', function() {
2 | return function(number, padding) {
3 | // return undefined if number is undefined
4 | if (!angular.isDefined(number)) return;
5 | // set up default padding
6 | if (typeof padding === 'undefined') padding = 2;
7 |
8 | // convert number to hex
9 | let hex = Number(number).toString(16).toUpperCase();
10 | // add 0 padding as necessary
11 | while (hex.length < padding) {
12 | hex = "0" + hex;
13 | }
14 |
15 | return hex;
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/src/javascripts/Filters/profileValidFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.filter('profileValid', function() {
2 | return function(profiles) {
3 | if (!profiles) return;
4 | return profiles.filter(profile => {
5 | return profile.valid && profile.name.length > 0;
6 | });
7 | }
8 | });
9 |
--------------------------------------------------------------------------------
/src/javascripts/Filters/wordwrapFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.filter('wordwrap', function() {
2 | return function(str, width) {
3 | if (typeof str !== 'string') return '';
4 | return str.wordwrap(width || 60);
5 | };
6 | });
--------------------------------------------------------------------------------
/src/javascripts/Runners/recordFilters/arrayItemFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.run(function(recordFilterService) {
2 | recordFilterService.addFilter('Array Item', (path = '') => ({
3 | type: 'Array Item',
4 | path: path,
5 | subpath: '',
6 | value: '',
7 | notPresent: false,
8 | templateUrl: 'partials/filters/arrayItem.html',
9 | exportKeys: ['path', 'subpath', 'value', 'notPresent'],
10 | test: function(record) {
11 | let args = [record, this.path, this.subpath, this.value];
12 | return xelib.HasArrayItem(...args) !== this.notPresent;
13 | }
14 | }));
15 | });
--------------------------------------------------------------------------------
/src/javascripts/Runners/recordFilters/conflictStatusFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.run(function(recordFilterService) {
2 | let conflictKeys = Array.prototype.concat(
3 | xelib.conflictAll, xelib.conflictThis
4 | ),
5 | conflictProperties = conflictKeys.reduce((obj, key) => {
6 | obj[key] = true;
7 | return obj;
8 | }, {});
9 |
10 | recordFilterService.addFilter('Conflict Status', (path = '') => Object.assign({
11 | type: 'Conflict Status',
12 | path: path,
13 | conflictAllOptions: xelib.conflictAll,
14 | conflictThisOptions: xelib.conflictThis,
15 | templateUrl: 'partials/filters/conflictStatus.html',
16 | exportKeys: ['path'].concat(conflictKeys),
17 | test: function(record) {
18 | let element;
19 | try {
20 | element = xelib.GetElement(record, path);
21 | let [ca, ct] = xelib.GetConflictData(0, element);
22 | return this[xelib.conflictAll[ca]] &&
23 | this[xelib.conflictThis[ct]];
24 | } finally {
25 | if (element) xelib.Release(element);
26 | }
27 | }
28 | }, conflictProperties));
29 | });
30 |
--------------------------------------------------------------------------------
/src/javascripts/Runners/recordFilters/flagFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.run(function(recordFilterService) {
2 | recordFilterService.addFilter('Flag', (path = '') => ({
3 | type: 'Flag',
4 | path: path,
5 | value: '',
6 | notPresent: false,
7 | templateUrl: 'partials/filters/flag.html',
8 | exportKeys: ['path', 'value', 'notPresent'],
9 | test: function(record) {
10 | let state = xelib.GetFlag(record, this.path, this.value);
11 | return state === !this.notPresent;
12 | }
13 | }));
14 | });
--------------------------------------------------------------------------------
/src/javascripts/Runners/recordFilters/groupFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.run(function(recordFilterService, searchService) {
2 | recordFilterService.addFilter('Group', () => ({
3 | type: 'Group',
4 | mode: 'and',
5 | children: [],
6 | templateUrl: 'partials/filters/group.html',
7 | test: function(record) {
8 | let args = [record, this.children, this.mode];
9 | return searchService.filter(...args);
10 | }
11 | }));
12 | });
--------------------------------------------------------------------------------
/src/javascripts/Runners/recordFilters/numberFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.run(function(recordFilterService) {
2 | let numberCompare = {
3 | 'Equal to': (n, filter) => { return n === filter.value },
4 | 'Not equal to': (n, filter) => { return n !== filter.value },
5 | 'Greater than': (n, filter) => { return n > filter.value },
6 | 'Less than': (n, filter) => { return n < filter.value },
7 | 'Range': (n, filter) => {
8 | return n >= filter.value && n <= filter.secondValue;
9 | }
10 | };
11 |
12 | recordFilterService.addFilter('Number', (path = '') => ({
13 | type: 'Number',
14 | path: path,
15 | compareType: 'Equal to',
16 | value: 0,
17 | secondValue: 0,
18 | templateUrl: 'partials/filters/number.html',
19 | exportKeys: ['path', 'compareType', 'value', 'secondValue'],
20 | test: function(record) {
21 | let value = xelib.GetValue(record, this.path),
22 | num = parseFloat(value);
23 | return numberCompare[this.compareType](num, this);
24 | }
25 | }));
26 | });
--------------------------------------------------------------------------------
/src/javascripts/Runners/recordFilters/recordTypeFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.run(function(recordFilterService) {
2 | recordFilterService.addFilter('Record Type', () => ({
3 | type: 'Record Type',
4 | master: true,
5 | override: true,
6 | injected: true,
7 | notInjected: true,
8 | templateUrl: 'partials/filters/recordType.html',
9 | exportKeys: ['master', 'override', 'injected', 'notInjected'],
10 | test: function(record) {
11 | let injected = xelib.IsInjected(record),
12 | master = xelib.IsMaster(record);
13 | return (injected && this.injected ||
14 | !injected && this.notInjected) &&
15 | (master && this.master ||
16 | !master && this.override);
17 | }
18 | }));
19 | });
--------------------------------------------------------------------------------
/src/javascripts/Runners/recordFilters/referenceFilter.js:
--------------------------------------------------------------------------------
1 | ngapp.run(function(recordFilterService) {
2 | recordFilterService.addFilter('Reference', (path = '') => ({
3 | type: 'Reference',
4 | path: path,
5 | value: '',
6 | templateUrl: 'partials/filters/reference.html',
7 | exportKeys: ['path', 'value'],
8 | test: function(record) {
9 | let value = xelib.GetValue(record, this.path);
10 | return value === this.value;
11 | }
12 | }));
13 | });
--------------------------------------------------------------------------------
/src/javascripts/Services/clean/pluginErrorHelpers.js:
--------------------------------------------------------------------------------
1 | ngapp.service('pluginErrorHelpers', function() {
2 | let referenceSignatures = ['REFR', 'PGRE', 'PMIS', 'ACHR', 'PARW',
3 | 'PBAR', 'PBEA', 'PCON', 'PFLA', 'PHZD'];
4 |
5 | this.errorAcronyms = ['ITM', 'ITPO', 'DR', 'UES', 'URR', 'UER', 'OE'];
6 |
7 | this.isUDR = function(error) {
8 | return referenceSignatures.indexOf(error.signature) > -1;
9 | };
10 |
11 | this.isNavmeshError = function(error) {
12 | return error.signature === 'NAVM';
13 | };
14 |
15 | this.withErrorElement = function(error, callback, onException = console.log) {
16 | if (error.handle === 0) return;
17 | let element = xelib.GetElement(error.handle, error.path);
18 | try {
19 | try {
20 | return callback(element);
21 | } catch(exception) {
22 | onException(error, exception);
23 | }
24 | } finally {
25 | xelib.Release(element);
26 | }
27 | };
28 | });
29 |
--------------------------------------------------------------------------------
/src/javascripts/Services/edit/clipboardService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('clipboardService', function() {
2 | let _clipboard;
3 |
4 | this.copyNodes = function(source, nodes) {
5 | if (nodes.length === 0) return;
6 | if (_clipboard)
7 | _clipboard.nodes.mapOnKey('handle').forEach(xelib.Release);
8 | _clipboard = {
9 | source: source,
10 | nodes: nodes.slice()
11 | };
12 | };
13 |
14 | this.copyText = function(text) {
15 | clipboard.writeText(text);
16 | };
17 |
18 | this.hasClipboard = () => !!_clipboard;
19 | this.getCopySource = () => _clipboard.source;
20 | this.getNodes = () => _clipboard.nodes;
21 | });
22 |
--------------------------------------------------------------------------------
/src/javascripts/Services/edit/recordFilterService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('recordFilterService', function() {
2 | let filters = {};
3 |
4 | this.addFilter = function(name, filter) {
5 | filters[name] = filter;
6 | };
7 |
8 | this.getFilters = () => filters;
9 | });
10 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/argService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('argService', function() {
2 | let unwrap = function(str) {
3 | if (str[0] === '"' && str[str.length - 1] === '"')
4 | return str.slice(1, -1);
5 | return str;
6 | };
7 |
8 | this.getArgValue = function(key) {
9 | let arg = argv.find(arg => arg.startsWith(key));
10 | return arg && unwrap(arg.slice(key.length + 1));
11 | };
12 | });
13 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/errorService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('errorService', function($exceptionHandler) {
2 | let service = this;
3 |
4 | this.handleException = $exceptionHandler;
5 |
6 | this.try = function(callback) {
7 | try {
8 | callback();
9 | return true;
10 | } catch(x) {
11 | service.handleException(x)
12 | }
13 | };
14 |
15 | this.tryEach = function(items, callback) {
16 | items.forEach(item => service.try(() => callback(item)));
17 | };
18 | });
19 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/eventService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('eventService', function() {
2 | this.onRegainFocus = function(callback, delay) {
3 | let focusTimeout, lostFocus = false;
4 |
5 | window.onblur = () => {
6 | focusTimeout = setTimeout(() => lostFocus = true, delay);
7 | };
8 |
9 | window.onfocus = () => {
10 | if (focusTimeout) clearTimeout(focusTimeout);
11 | if (lostFocus) callback();
12 | lostFocus = false;
13 | };
14 | };
15 |
16 | this.beforeClose = function(callback) {
17 | window.onbeforeunload = function(e) {
18 | if (remote.app.forceClose) return;
19 | e.returnValue = false;
20 | callback();
21 | };
22 | };
23 | });
24 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/integrationService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('integrationService', function() {
2 | let service = this;
3 |
4 | this.defaultSettings = {};
5 | this.integrations = [];
6 |
7 | this.addIntegration = function(integration) {
8 | service.integrations.push(integration);
9 | service.integrations.sortOnKey('priority');
10 | Object.assign(service.defaultSettings, integration.defaultSettings);
11 | };
12 | });
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/interApiService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('interApiService', function() {
2 | let registry = [];
3 |
4 | // PRIVATE
5 | let excludeApi = function(api, entry) {
6 | return entry.hasOwnProperty('except') && entry.except.includes(api) ||
7 | entry.hasOwnProperty('only') && !entry.only.includes(api);
8 | };
9 |
10 | // PUBLIC API
11 | this.getApi = function(apiKey) {
12 | let api = {};
13 | registry.forEach(entry => {
14 | if (excludeApi(apiKey, entry)) return;
15 | Object.assign(api, entry.api);
16 | });
17 | return api;
18 | };
19 |
20 | this.register = opts => registry.push(opts);
21 | });
22 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/objectUtils.js:
--------------------------------------------------------------------------------
1 | ngapp.service('objectUtils', function() {
2 | this.rebuildObject = function(obj, keys) {
3 | return Object.keys(obj).reduce((newObj, key) => {
4 | if (keys.includes(key)) newObj[key] = obj[key];
5 | return newObj;
6 | }, {})
7 | };
8 | });
9 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/protocolService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('protocolService', function($document) {
2 | this.init = function(scope) {
3 | let handleHttpLink = (href) => fh.openUrl(href);
4 |
5 | let handleDocsLink = function(href) {
6 | scope.activateModal('help');
7 | scope.$broadcast('helpNavigateTo', href.substr(7));
8 | };
9 |
10 | let protocolHandlers = {
11 | http: handleHttpLink,
12 | https: handleHttpLink,
13 | docs: handleDocsLink
14 | };
15 |
16 | let handleLink = function(href) {
17 | let protocol = href.match(/([^:]+)/)[1];
18 | let handler = protocolHandlers[protocol];
19 | handler && handler(href);
20 | return !!handler;
21 | };
22 |
23 | // handle link protocols properly
24 | $document.bind('click', function(event) {
25 | if (event.target.tagName !== 'A') return;
26 | if (!event.target.href) return;
27 | if (handleLink(event.target.href)) event.preventDefault();
28 | });
29 | };
30 | });
31 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/randomService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('randomService', function() {
2 | let service = this,
3 | alphanumeric = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
4 |
5 | this.generateRandomString = function(length, chars) {
6 | let id = '', numChars = chars.length;
7 | for (let i = 0; i < length; i++) {
8 | id += chars[Math.floor(Math.random() * numChars)];
9 | }
10 | return id;
11 | };
12 |
13 | this.generateUniqueId = function() {
14 | return service.generateRandomString(32, alphanumeric);
15 | };
16 |
17 | this.randomCheck = function(chance) {
18 | return Math.random() < chance;
19 | };
20 |
21 | this.randomInt = function(min, max) {
22 | return min + Math.floor(Math.random() * (max - min + 1));
23 | };
24 |
25 | this.weightedInt = function(min, max, weight = 1) {
26 | let n = Math.random();
27 | for (let i = weight; i > 1; i--) n *= Math.random();
28 | let half = (max - min) / 2.0,
29 | offset = n * half;
30 | if (Math.random() > 0.5) offset = 0 - offset;
31 | return min + Math.floor(half + offset);
32 | };
33 | });
34 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/recentService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('recentService', function() {
2 | let dictionary = {};
3 |
4 | this.store = function(key, max) {
5 | if (dictionary.hasOwnProperty(key)) return;
6 | dictionary[key] = { max, items: [] };
7 | };
8 |
9 | this.get = function(key) {
10 | return dictionary[key].items;
11 | };
12 |
13 | this.add = function(key, value) {
14 | let {items, max} = dictionary[key];
15 | let n = items.indexOf(value);
16 | (n === -1) ? items.length >= max && items.pop() : items.splice(n, 1);
17 | items.unshift(value);
18 | };
19 | });
20 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/resourceService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('resourceService', function() {
2 | let files = {};
3 |
4 | this.getFiles = function(folder) {
5 | if (!files.hasOwnProperty(folder))
6 | files[folder] = xelib.GetContainerFiles('', folder);
7 | return files[folder];
8 | };
9 | });
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/stylesheetService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('stylesheetService', function() {
2 | let service = this,
3 | lastIndex = document.styleSheets.length - 1,
4 | customStylesheet = document.styleSheets[lastIndex];
5 |
6 | this.getRule = function(selector) {
7 | let rules = customStylesheet.cssRules;
8 | for (let j = 0; j < rules.length; j++) {
9 | let rule = rules[j];
10 | if (rule.selectorText === selector) return rule;
11 | }
12 | };
13 |
14 | this.makeRule = function(selector, style) {
15 | customStylesheet.addRule(selector, style, 1);
16 | };
17 |
18 | this.setProperty = function(selector, property, value) {
19 | let rule = service.getRule(selector);
20 | if (!rule) {
21 | service.makeRule(selector, `${property}: ${value}`);
22 | } else {
23 | rule.style[property] = value;
24 | }
25 | };
26 | });
27 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/tabService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('tabService', function() {
2 | this.buildFunctions = function(scope) {
3 | // helper functions
4 | let selectTab = function(tab) {
5 | scope.tabs.forEach((tab) => tab.selected = false);
6 | scope.currentTab = tab;
7 | scope.currentTab.selected = true;
8 | };
9 |
10 | // scope functions
11 | scope.onTabClick = function(e, tab) {
12 | e.stopPropagation();
13 | if (tab === scope.currentTab) return;
14 | selectTab(tab);
15 | };
16 |
17 | // initialization
18 | selectTab(scope.tabs[0]);
19 | };
20 | });
21 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/timerService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('timerService', function() {
2 | let service = this,
3 | timers = {};
4 |
5 | let millisecondsAgo = function(ms) {
6 | return new Date((new Date()).getTime() - ms);
7 | };
8 |
9 | this.start = function(timerName) {
10 | timers[timerName] = new Date();
11 | };
12 |
13 | this.pause = function(timerName) {
14 | timers[timerName] = {
15 | started: timers[timerName],
16 | paused: new Date()
17 | };
18 | };
19 |
20 | this.resume = function(timerName) {
21 | timers[timerName] = millisecondsAgo(timers[timerName].pausedAt);
22 | };
23 |
24 | this.getSeconds = function(timerName) {
25 | let timer = timers[timerName];
26 | return (timer.pausedAt || new Date() - timer) / 1000.0;
27 | };
28 |
29 | this.getSecondsStr = function(timerName) {
30 | return `${service.getSeconds(timerName).toFixed(3)}s`;
31 | }
32 | });
33 |
34 | ngapp.run(function(interApiService, timerService) {
35 | interApiService.register({
36 | api: { timerService }
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/src/javascripts/Services/shared/viewLinkingService.js:
--------------------------------------------------------------------------------
1 | ngapp.service('viewLinkingService', function() {
2 | this.buildFunctions = function(view, linkKey, allowLinkTo) {
3 | let getLinkKey = function(className) {
4 | return `linked${className.toPascalCase()}`;
5 | };
6 |
7 | view.isLinkedTo = function(otherView) {
8 | return otherView[linkKey] === view;
9 | };
10 |
11 | view.canLinkTo = function(otherView) {
12 | return allowLinkTo.includes(otherView.class) && !view[linkKey];
13 | };
14 |
15 | view.linkTo = function(otherView) {
16 | if (!allowLinkTo.includes(otherView.class)) return;
17 | otherView[linkKey] = view;
18 | view[getLinkKey(otherView.class)] = otherView;
19 | };
20 |
21 | view.unlinkAll = function() {
22 | allowLinkTo.forEach(viewClass => {
23 | let otherLinkKey = getLinkKey(viewClass),
24 | linkedView = view[otherLinkKey];
25 | if (!linkedView) return;
26 | delete linkedView[linkKey];
27 | delete view[otherLinkKey];
28 | });
29 | };
30 | };
31 | });
--------------------------------------------------------------------------------
/src/javascripts/Views/edit/addMastersModal.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('addMastersModalController', function($scope, $timeout, errorService) {
2 | // initialization
3 | let selectedFile = $scope.modalOptions.handle,
4 | availableMasters = xelib.GetAvailableMasters(selectedFile);
5 | $scope.filename = xelib.Name(selectedFile);
6 | $scope.availableMasters = availableMasters.map(master => ({
7 | name: master,
8 | active: false
9 | }));
10 |
11 | // scope functions
12 | $scope.applyValue = function() {
13 | errorService.try(() => {
14 | $scope.availableMasters.forEach(master => {
15 | if (!master.active) return;
16 | xelib.AddMaster(selectedFile, master.name);
17 | });
18 | });
19 | $scope.afterApplyValue();
20 | };
21 |
22 | $scope.afterApplyValue = function() {
23 | $scope.$root.$broadcast('recordUpdated', selectedFile);
24 | $scope.$emit('closeModal');
25 | };
26 | });
27 |
--------------------------------------------------------------------------------
/src/javascripts/Views/edit/editSaveModal.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('editSaveModalController', function($scope, $timeout, saveModalService) {
2 | // inherited functions
3 | saveModalService.buildFunctions($scope);
4 |
5 | // helper functions
6 | let saveData = function() {
7 | $scope.total = $scope.pluginsToSave.length;
8 | if ($scope.total > 0) $scope.savePlugins();
9 | shouldFinalize ? $scope.finalize() : $scope.$emit('closeModal');
10 | };
11 |
12 | // scope functions
13 | $scope.save = function() {
14 | $scope.saving = true;
15 | $scope.pluginsToSave = $scope.getActivePlugins();
16 | $timeout(saveData, 50);
17 | };
18 |
19 | $scope.discard = function() {
20 | $scope.saving = true;
21 | $scope.pluginsToSave = [];
22 | $timeout(saveData, 50);
23 | };
24 |
25 | // initialization
26 | let shouldFinalize = $scope.modalOptions.shouldFinalize;
27 | $scope.pluginsToProcess = $scope.modalOptions.plugins;
28 | $scope.saving = false;
29 | $scope.message = 'Closing';
30 |
31 | // skip user interaction if there are no plugins to save
32 | if ($scope.pluginsToProcess.length === 0) $scope.discard();
33 | });
34 |
--------------------------------------------------------------------------------
/src/javascripts/Views/edit/logView.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('logViewController', function($scope, contextMenuService) {
2 | // link view to scope
3 | $scope.view = $scope.$parent.tab;
4 | $scope.view.scope = $scope;
5 |
6 | // helper functions
7 | let buildMessageObj = msg => ({
8 | text: msg.trimRight(),
9 | class: getMessageClass(msg)
10 | });
11 |
12 | let onLogMessage = msg => {
13 | $scope.messages.push(buildMessageObj(msg));
14 | };
15 |
16 | let getMessageClass = msg => {
17 | let n = msg[0] === '[' && msg.indexOf(']');
18 | if (n <= 0) return 'log';
19 | return `${msg.slice(1, n).toLowerCase()}`;
20 | };
21 |
22 | // scope functions
23 | $scope.loadMessages = function() {
24 | $scope.messages = logger.getMessages().map(buildMessageObj);
25 | };
26 |
27 | $scope.showContextMenu = function(e) {
28 | contextMenuService.showContextMenu($scope, e);
29 | };
30 |
31 | // initialization
32 | $scope.loadMessages();
33 |
34 | // event handlers
35 | logger.addCallback('log', onLogMessage);
36 |
37 | $scope.$on('destroy', function() {
38 | logger.removeCallback('log', onLogMessage);
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/src/javascripts/Views/edit/newTabView.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('newTabViewController', function($scope, viewFactory) {
2 | let views = viewFactory.getAccessibleViews();
3 | $scope.viewNames = Object.keys(views);
4 | $scope.selectView = (viewName) => $scope.$emit('changeView', views[viewName]);
5 | });
6 |
--------------------------------------------------------------------------------
/src/javascripts/Views/edit/refactorFileModal.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('refactorFileModalController', function($scope) {
2 | let node = $scope.modalOptions.nodes.last(),
3 | file = node.handle;
4 |
5 | $scope.filename = xelib.GetFileName(file);
6 | $scope.author = xelib.GetFileAuthor(file);
7 | $scope.description = xelib.GetFileDescription(file);
8 |
9 | $scope.doRefactor = function() {
10 | let originalFileName = xelib.GetFileName(file),
11 | originalAuthor = xelib.GetFileAuthor(file),
12 | originalDescription = xelib.GetFileDescription(file);
13 | if ($scope.filename !== originalFileName)
14 | xelib.RenameFile(file, $scope.filename);
15 | if ($scope.author !== originalAuthor)
16 | xelib.SetFileAuthor($scope.author);
17 | if ($scope.description !== originalDescription)
18 | xelib.SetFileDescription($scope.description);
19 |
20 | $scope.$root.$broadcast('reloadGUI');
21 | $scope.$emit('closeModal');
22 | };
23 | });
--------------------------------------------------------------------------------
/src/javascripts/Views/merge/mergeSaveModal.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('mergeSaveModalController', function($scope, $timeout, saveModalService, mergeService) {
2 | // inherited functions
3 | saveModalService.buildFunctions($scope);
4 |
5 | // helper functions
6 | let saveData = function() {
7 | let shouldFinalize = $scope.modalOptions.shouldFinalize;
8 | mergeService.saveMerges();
9 | shouldFinalize ? $scope.finalize() : $scope.$emit('closeModal');
10 | };
11 |
12 | // initialization
13 | $scope.saving = true;
14 | $scope.setMessage('Saving merge data');
15 | $timeout(saveData, 50);
16 | });
17 |
--------------------------------------------------------------------------------
/src/javascripts/Views/merge/mergeSettings.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('mergeSettingsController', function($scope, modManagerService) {
2 | let {getModManager} = modManagerService,
3 | integrationKeys = ['disableMods'];
4 |
5 | $scope.availableIntegrations = {};
6 | let modManager = getModManager($scope.settings.modManager);
7 | if (!modManager) return;
8 | integrationKeys.forEach(integrationKey => {
9 | if (!modManager.hasOwnProperty(integrationKey)) return;
10 | $scope.availableIntegrations[integrationKey] = true;
11 | });
12 | });
13 |
14 | ngapp.run(function(settingsService) {
15 | settingsService.registerSettings({
16 | label: 'Merge Settings',
17 | controller: 'mergeSettingsController',
18 | appModes: ['merge'],
19 | templateUrl: 'partials/settings/merge.html',
20 | defaultSettings: {
21 | mergePath: fh.jetpack.path('merges'),
22 | mergeIntegrations: {
23 | disablePlugins: true,
24 | disableMods: false
25 | }
26 | }
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/src/javascripts/Views/shared/installedModules.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('installedModulesController', function($scope, extensionService) {
2 | $scope.modules = extensionService.getInstalledModules();
3 |
4 | // scope functions
5 | $scope.uninstallModule = function(module) {
6 | fh.jetpack.remove(module.modulePath);
7 | $scope.showRestart = true;
8 | };
9 |
10 | $scope.toggleModule = function(module) {
11 | // TODO
12 | };
13 |
14 | $scope.openRepo = function(module) {
15 | module.repo && fh.openUrl(module.repo);
16 | };
17 |
18 | $scope.restart = function() {
19 | $scope.$emit('restart');
20 | };
21 |
22 | $scope.installModule = function() {
23 | let moduleFile = fh.selectFile('Select a module to install.', '', [
24 | { name: 'Archive', extensions: ['zip'] },
25 | { name: 'module.json', extensions: ['json'] }
26 | ]);
27 | if (!moduleFile) return;
28 | try {
29 | extensionService.installModule(moduleFile);
30 | $scope.showRestart = true;
31 | } catch (x) {
32 | alert(`Error extracting module archive:\r\n${x.stack}`);
33 | }
34 | };
35 | });
36 |
--------------------------------------------------------------------------------
/src/javascripts/Views/shared/manageExtensionsModal.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('manageExtensionsModalController', function($scope, extensionService, tabService) {
2 | $scope.tabs = extensionService.getTabs();
3 | tabService.buildFunctions($scope);
4 | });
5 |
--------------------------------------------------------------------------------
/src/javascripts/Views/shared/promptModal.js:
--------------------------------------------------------------------------------
1 | ngapp.controller('promptModalController', function($scope) {
2 | $scope.yes = function() {
3 | $scope.promptPromise.resolve(true);
4 | $scope.$emit('closeModal');
5 | };
6 |
7 | $scope.no = function() {
8 | $scope.promptPromise.resolve(false);
9 | $scope.$emit('closeModal');
10 | };
11 | });
12 |
--------------------------------------------------------------------------------
/src/javascripts/env.js:
--------------------------------------------------------------------------------
1 | // Simple wrapper exposing environment variables to rest of the code.
2 |
3 | import jetpack from 'fs-jetpack';
4 |
5 | // The variables have been written to `env.json` by the build process.
6 | let env = jetpack.cwd(__dirname).read('env.json', 'json');
7 |
8 | export default env;
9 |
--------------------------------------------------------------------------------
/src/stylesheets/components/autocompleteInput.scss:
--------------------------------------------------------------------------------
1 | autocomplete-input {
2 | position: relative;
3 |
4 | .dropdown {
5 | position: absolute;
6 | z-index: 5;
7 | left: 0;
8 | padding: 2px 0;
9 | background-color: $background;
10 | border: 1px solid $medium_border;
11 |
12 | > span {
13 | display: block;
14 | padding: 2px 6px;
15 | }
16 |
17 | .dropdown-item {
18 | padding: 2px 12px;
19 |
20 | &.selected {
21 | background-color: $selected;
22 | }
23 | }
24 | }
25 |
26 | &.inline .dropdown {
27 | position: initial;
28 | border: none;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/stylesheets/components/cellEditor.scss:
--------------------------------------------------------------------------------
1 | cell-editor {
2 | input[type="text"] {
3 | border: none;
4 | width: 100%;
5 | max-height: 100%;
6 |
7 | &:focus {
8 | outline: none;
9 | }
10 | }
11 |
12 | reference-select {
13 | display: flex;
14 | max-height: 100%;
15 |
16 | select {
17 | border: none;
18 | border-right: 1px solid $hard_border;
19 | }
20 | }
21 |
22 | enum-select {
23 | display: block;
24 |
25 | select {
26 | width: 100%;
27 | border: none;
28 | border-bottom: 1px solid $hard_border;
29 | padding-bottom: 0;
30 | }
31 | }
32 |
33 | autocomplete-input {
34 | flex: 1;
35 | color: $font_color !important;
36 | font-weight: normal !important;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/stylesheets/components/codeBlock.scss:
--------------------------------------------------------------------------------
1 | code-block {
2 | .CodeMirror {
3 | height: initial;
4 | border: 1px solid $medium_border;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/stylesheets/components/colorInput.scss:
--------------------------------------------------------------------------------
1 | .angular-color-picker {
2 | background: inherit !important;
3 | border: none !important;
4 |
5 | &:focus {
6 | outline: none;
7 | }
8 | }
9 |
10 | color-input {
11 | div.color-sample {
12 | height: 21px;
13 | width: 30px;
14 | display: inline-block;
15 | border: 1px solid $hard_border;
16 | border-right: none;
17 | }
18 |
19 | input[type="text"] {
20 | width: 150px;
21 | }
22 |
23 | .color-input-container {
24 | display: flex;
25 | align-items: center;
26 | justify-content: center;
27 | margin: 10px 0;
28 |
29 | button {
30 | margin-left: 8px;
31 | padding: 2px 8px;
32 | font-size: 16px;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/stylesheets/components/colorSelector.scss:
--------------------------------------------------------------------------------
1 | color-selector {
2 | dropdown .dropdown-items {
3 | display: flex;
4 | top: -3px;
5 | align-items: stretch;
6 | flex-wrap: wrap;
7 |
8 | color-swatch {
9 | width: 48px;
10 | height: 48px;
11 | }
12 |
13 | > .dropdown-item {
14 | width: 72px;
15 | flex-basis: 72px;
16 | }
17 | }
18 |
19 | dropdown .custom-select {
20 | padding: 3px;
21 | }
22 |
23 | custom-item {
24 | display: inline-block;
25 | margin: 19px 0;
26 | }
27 |
28 | .angular-color-picker {
29 | margin: 10px 18px 0;
30 | padding: 0;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/stylesheets/components/colorSwatch.scss:
--------------------------------------------------------------------------------
1 | color-swatch {
2 | width: 64px;
3 | height: 64px;
4 | display: block;
5 | margin: 4px 0;
6 |
7 | > div {
8 | height: 100%;
9 | position: relative;
10 | cursor: inherit;
11 |
12 | &::after {
13 | content: '';
14 | position: absolute;
15 | top: 0;
16 | right: 0;
17 | border: 1.0em solid transparent;
18 | border-right-color: inherit;
19 | border-top-color: inherit;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/stylesheets/components/dds.scss:
--------------------------------------------------------------------------------
1 | dds {
2 | display: flex;
3 |
4 | canvas {
5 | width: 96px;
6 | height: 96px;
7 | border: 1px solid $hard_border;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/stylesheets/components/elementView.scss:
--------------------------------------------------------------------------------
1 | element-view {
2 | display: block;
3 | text-align: left;
4 | margin-left: 2em;
5 |
6 | span.fa, span.no-button {
7 | min-width: 1em;
8 | text-align: center;
9 | }
10 |
11 | .key {
12 | font-weight: 500;
13 | margin-bottom: 2px;
14 | margin-right: 4px;
15 | display: inline-block;
16 | }
17 |
18 | .error {
19 | background-color: rgba(255, 0, 0, 0.65);
20 | padding: 2px 4px 0;
21 | display: inline-block;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/stylesheets/components/errorGroup.scss:
--------------------------------------------------------------------------------
1 | error-group {
2 | h2 {
3 | user-select: none;
4 | text-align: left;
5 | font-size: 20px;
6 | margin-bottom: 0.5em;
7 |
8 | .title {
9 | cursor: pointer;
10 | }
11 |
12 | .fa {
13 | text-align: center;
14 | min-width: 1em;
15 | font-size: 18px;
16 | }
17 |
18 | select {
19 | margin-left: 10px;
20 | border: none;
21 | padding: 3px;
22 | margin-top: 1px;
23 | vertical-align: top;
24 | }
25 | }
26 |
27 | table {
28 | table-layout: fixed;
29 | width: 100%;
30 | border-collapse: collapse;
31 |
32 | tr:nth-child(even) {
33 | background-color: $background_tint;
34 | }
35 |
36 | td {
37 | text-align: left;
38 |
39 | &.error-cell {
40 | padding: 0 4px;
41 | white-space: pre-line;
42 | font-size: 15px;
43 | width: 85%;
44 | }
45 |
46 | &.resolution-cell {
47 | text-align: center;
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/stylesheets/components/errorResolutions.scss:
--------------------------------------------------------------------------------
1 | error-resolutions {
2 | max-width: 490px;
3 | text-align: left;
4 |
5 | .action-btn {
6 | min-width: 240px;
7 | text-align: left;
8 | color: $font_color !important;
9 | background: none !important;
10 |
11 | &.selected, &:hover {
12 | color: $inverse_font_color !important;
13 |
14 | &.positive {
15 | background: $positive !important;
16 | }
17 |
18 | &.neutral {
19 | background: $neutral !important;
20 | }
21 |
22 | &.negative {
23 | background: $negative !important;
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/stylesheets/components/expandableSection.scss:
--------------------------------------------------------------------------------
1 | expandable-section title {
2 | display: inline;
3 | }
--------------------------------------------------------------------------------
/src/stylesheets/components/hexEditor.scss:
--------------------------------------------------------------------------------
1 | hex-editor {
2 | > span {
3 | padding: 1px 4px;
4 | white-space: pre;
5 |
6 | &:hover {
7 | background: $secondary_background;
8 | }
9 |
10 | &:focus {
11 | background: $action;
12 | color: $inverse_font_color;
13 | outline: none;
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/stylesheets/components/hexInput.scss:
--------------------------------------------------------------------------------
1 | hex-input {
2 | border: 1px solid $hard_border;
3 | padding: 0 3px;
4 |
5 | > span {
6 | @include monospace();
7 |
8 | &:focus {
9 | outline: none;
10 | background: $action;
11 | color: $inverse_font_color;
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/stylesheets/components/listEdit.scss:
--------------------------------------------------------------------------------
1 | .list-edit {
2 | > div {
3 | margin: 6px 0;
4 | }
5 |
6 | input[type="text"] {
7 | min-width: 300px;
8 | margin-right: 2px;
9 | }
10 | }
--------------------------------------------------------------------------------
/src/stylesheets/components/listView.scss:
--------------------------------------------------------------------------------
1 | list-view {
2 | text-align: left;
3 | display: block;
4 |
5 | &.scrollable {
6 | .list-items {
7 | padding: 15px;
8 | overflow-y: auto;
9 | }
10 | }
11 |
12 | .list-item {
13 | white-space: nowrap;
14 | text-overflow: ellipsis;
15 | overflow: hidden;
16 |
17 | &.dragging {
18 | opacity: 0.5;
19 | }
20 |
21 | &.insert-after {
22 | padding-bottom: 20px;
23 | }
24 |
25 | &.insert-before {
26 | padding-top: 20px;
27 | }
28 |
29 | &.selected {
30 | background-color: $selected;
31 | }
32 | }
33 |
34 | .list-items.dragging .list-item * {
35 | pointer-events: none;
36 | }
37 |
38 | .placeholder {
39 | min-height: 20px;
40 | color: $soft_font_color;
41 | }
42 |
43 | .filter-container {
44 | padding: 8px 10px;
45 | border-top: 1px solid $medium_border;
46 |
47 | input[type="text"] {
48 | margin-left: 4px;
49 | min-width: 250px;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/stylesheets/components/loader.scss:
--------------------------------------------------------------------------------
1 | loader {
2 | color: $inverse_font_color;
3 |
4 | .modal-container {
5 | background-color: rgba($modal_shadow, 0.65);
6 |
7 | .modal {
8 | background: none;
9 | box-shadow: none;
10 | max-width: 900px;
11 | }
12 | }
13 |
14 | .loading-content {
15 | margin-top: 16px;
16 | font-size: 24px;
17 | text-align: center;
18 | }
19 |
20 | .action-btn {
21 | margin-left: 10px;
22 | }
23 |
24 | .spinner.inverse > div > div {
25 | background: $font_color !important;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/stylesheets/components/nodeColumns.scss:
--------------------------------------------------------------------------------
1 | .node-columns {
2 | display: flex;
3 | border-bottom: 1px solid $medium_border;
4 | margin-top: -24px;
5 | position: relative;
6 |
7 | &:first-child {
8 | border-top: 1px solid $medium_border;
9 | }
10 |
11 | > split-bar {
12 | width: 5px;
13 | margin: 0 -2px 0 -3px;
14 | cursor: col-resize;
15 |
16 | .bar {
17 | border-left: 1px solid $hard_border;
18 | height: 100%;
19 | position: absolute;
20 | left: 2px;
21 | top: 0;
22 | }
23 | }
24 |
25 | .column {
26 | padding: 5px 26px 4px 8px;
27 | position: relative;
28 | text-overflow: ellipsis;
29 | overflow: hidden;
30 |
31 | &:last-of-type {
32 | flex: 1;
33 | border-right: 1px solid $medium_border;
34 | }
35 |
36 | &.sortable:hover {
37 | background-color: $selected;
38 | }
39 |
40 | .sort-arrow {
41 | margin-left: 6px;
42 | }
43 | }
44 |
45 | .column-action {
46 | font: 16px FontAwesome;
47 | cursor: pointer;
48 | position: absolute;
49 | right: 0;
50 | top: 0;
51 | padding: 4px 6px 5px;
52 |
53 | &:hover {
54 | color: $secondary_action;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/stylesheets/components/progressBar.scss:
--------------------------------------------------------------------------------
1 | progress-bar {
2 | display: block;
3 | position: relative;
4 | width: 100%;
5 | height: 20px;
6 | margin-bottom: 20px;
7 | overflow: hidden;
8 | background-color: $soft_border;
9 | box-shadow: inset 0 1px 2px $medium_border;
10 | border-radius: 4px;
11 |
12 | .progress {
13 | float: left;
14 | height: 100%;
15 | background-color: $secondary_action;
16 | transition: width .6s ease;
17 |
18 | &.complete {
19 | background-color: $positive;
20 | }
21 |
22 | &.error {
23 | background-color: $negative;
24 | }
25 | }
26 |
27 | .progress-label {
28 | position: absolute;
29 | left: 50%;
30 | width: 100px;
31 | margin-left: -50px;
32 | font-size: 15px;
33 | line-height: 20px;
34 | text-align: center;
35 | color: $inverse_font_color;
36 | text-shadow: 1px 1px 2px $font_color, 0 0 4px $font_color;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/stylesheets/components/recordAddressBar.scss:
--------------------------------------------------------------------------------
1 | record-address-bar {
2 | display: flex;
3 | margin-top: -24px;
4 | margin-bottom: 24px;
5 | border-bottom: 1px solid $medium_border;
6 | padding: 3px 2px;
7 | align-items: center;
8 |
9 | .back-record {
10 | margin-left: 2px;
11 | }
12 |
13 | input[type="text"] {
14 | flex: 1;
15 | margin-left: 2px;
16 | padding: 1px 3px;
17 | border-radius: 3px;
18 | border: 1px solid $medium_border;
19 | -webkit-transition: background 2.0s ease-in-out;
20 |
21 | &:focus {
22 | outline: none;
23 | box-shadow: 0 0 2px $secondary_action;
24 | border-color: $secondary_action;
25 | }
26 |
27 | &.error {
28 | background-color: rgba($negative, 0.15);
29 | -webkit-transition: none;
30 | }
31 | }
32 |
33 | .link-view, .unlink-view, .close-bar {
34 | padding-left: 12px;
35 |
36 | > span {
37 | cursor: pointer;
38 | }
39 | }
40 |
41 | .close-bar {
42 | text-align: right;
43 | padding-right: 4px;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/stylesheets/components/spinner.scss:
--------------------------------------------------------------------------------
1 | .big-spinner {
2 | height: 250px;
3 | }
4 |
5 | .spinner.default {
6 | > div > div {
7 | background: $font_color !important;
8 | }
9 | }
10 |
11 | .spinner.inverse {
12 | > div > div {
13 | background: $inverse_font_color !important;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/stylesheets/components/statusBar.scss:
--------------------------------------------------------------------------------
1 | status-bar {
2 | display: flex;
3 | flex-shrink: 0;
4 | justify-content: space-between;
5 | align-items: center;
6 | text-align: right;
7 | height: 24px;
8 | padding: 2px 8px;
9 | border-top: 1px solid $hard_border;
10 | background-color: $background;
11 | font-size: 13px;
12 | position: relative;
13 |
14 | .tiny-spinner {
15 | display: inline-block;
16 | height: 16px;
17 | width: 16px;
18 | margin-right: 4px;
19 | }
20 |
21 | .status-message {
22 | > span {
23 | vertical-align: middle;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/stylesheets/components/tabs.scss:
--------------------------------------------------------------------------------
1 | tabs {
2 | display: flex;
3 | flex-direction: column;
4 | border: 1px solid $hard_border;
5 |
6 | .tabs-bar {
7 | display: flex;
8 | font-size: 14px;
9 | line-height: 22px;
10 | height: 25px;
11 | overflow-x: auto;
12 |
13 | &::-webkit-scrollbar {
14 | display: none;
15 | }
16 |
17 | .tab {
18 | display: flex;
19 | justify-content: space-between;
20 | min-width: 100px;
21 | padding: 2px 8px;
22 | border-bottom: 1px solid $hard_border;
23 | border-right: 1px solid $hard_border;
24 | background-color: $medium_soft_border;
25 |
26 | &.active {
27 | border-bottom: 1px solid $background;
28 | margin-bottom: -1px;
29 | background-color: $background;
30 | }
31 | }
32 |
33 | .space {
34 | flex: 1;
35 | border-bottom: 1px solid $hard_border;
36 | }
37 | }
38 |
39 | .tab-view {
40 | display: flex;
41 | flex-direction: column;
42 | position: relative;
43 | }
44 | }
--------------------------------------------------------------------------------
/src/stylesheets/components/textureSelector.scss:
--------------------------------------------------------------------------------
1 | texture-selector {
2 | autocomplete-input {
3 | input[type="text"] {
4 | width: 250px;
5 | }
6 |
7 | .dropdown {
8 | max-height: 400px;
9 | overflow-y: auto;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/stylesheets/components/tree.scss:
--------------------------------------------------------------------------------
1 | tree {
2 | font-size: 14px;
3 | display: block;
4 |
5 | > div {
6 | margin: 2px 0;
7 | }
8 |
9 | .expander {
10 | font-size: 12px;
11 | min-width: 12px;
12 | display: inline-block;
13 | }
14 |
15 | .placeholder {
16 | padding-right: 1.2em;
17 | }
18 |
19 | .selected > span:last-of-type {
20 | color: $secondary_action;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/stylesheets/components/viewLinker.scss:
--------------------------------------------------------------------------------
1 | view-linker {
2 | position: absolute;
3 | display: flex;
4 | align-items: center;
5 | top: 0;
6 | left: 0;
7 | z-index: 5;
8 | height: 100%;
9 | width: 100%;
10 | cursor: pointer;
11 |
12 | &.neutral {
13 | background: rgba($neutral, 0.3);
14 | }
15 |
16 | &.positive {
17 | background: rgba($positive, 0.3);
18 | }
19 |
20 | &.action {
21 | background: rgba($action, 0.3);
22 | }
23 |
24 | &.negative {
25 | background: rgba($negative, 0.3);
26 | }
27 |
28 | .link-message {
29 | margin: auto;
30 | font-size: 28px;
31 | font-weight: bold;
32 | padding: 0 40px 40px;
33 | text-shadow: 1px 1px 2px $inverse_font_color;
34 | cursor: inherit;
35 | }
36 | }
--------------------------------------------------------------------------------
/src/stylesheets/general/conflicts.scss:
--------------------------------------------------------------------------------
1 | // mixin for adding two colors together
2 | @mixin conflict-bg($color) {
3 | $bg: rgba($color, $transparency);
4 | background: linear-gradient(to right, $bg, $bg);
5 | }
6 |
7 | // classes
8 | .ct-not-defined {
9 | color: $soft;
10 | }
11 |
12 | .ct-identical-to-master {
13 | color: $medium;
14 | }
15 |
16 | .ct-only-one {
17 | color: $base;
18 | }
19 |
20 | .ct-hidden-by-mod-group {
21 | color: $very_soft;
22 | }
23 |
24 | .ct-master {
25 | color: $purple;
26 | }
27 |
28 | .ct-conflict-benign {
29 | color: $base;
30 | }
31 |
32 | .ct-override {
33 | color: $green;
34 | }
35 |
36 | .ct-identical-to-master-wins-conflict {
37 | color: $olive;
38 | }
39 |
40 | .ct-conflict-wins {
41 | color: $orange;
42 | }
43 |
44 | .ct-conflict-loses {
45 | color: $red;
46 | }
47 |
48 | .ca-no-conflict {
49 | @include conflict-bg($lime);
50 | }
51 |
52 | .ca-conflict-benign {
53 | @include conflict-bg($yellow);
54 | }
55 |
56 | .ca-override {
57 | @include conflict-bg($yellow);
58 | }
59 |
60 | .ca-conflict {
61 | @include conflict-bg($red);
62 | }
63 |
64 | .ca-conflict-critical {
65 | @include conflict-bg($fuschia);
66 | }
--------------------------------------------------------------------------------
/src/stylesheets/views/automateModal.scss:
--------------------------------------------------------------------------------
1 | .automate-modal {
2 | .modal-container {
3 | .modal {
4 | max-width: 800px;
5 | padding: 20px;
6 | }
7 | }
8 |
9 | .select-script-container {
10 | display: flex;
11 | align-items: center;
12 |
13 | > span {
14 | text-align: left;
15 | margin-right: 10px;
16 | }
17 |
18 | > button {
19 | font-size: 16px;
20 | padding: 4px 6px;
21 | }
22 |
23 | .sort-dropdown {
24 | margin: 0 6px;
25 |
26 | dropdown-contents {
27 | left: -2px;
28 | }
29 |
30 | .dropdown-item {
31 | width: 130px;
32 | }
33 | }
34 |
35 | .scripts-dropdown {
36 | flex: 1;
37 |
38 | dropdown-contents {
39 | left: -2px;
40 | }
41 | }
42 |
43 | .fa {
44 | font-size: 20px;
45 | }
46 | }
47 |
48 | .CodeMirror {
49 | text-align: left;
50 | border: 1px solid $medium_border;
51 | margin-top: 10px;
52 | height: 350px;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/stylesheets/views/editColumnsModal.scss:
--------------------------------------------------------------------------------
1 | .edit-columns-modal {
2 | .columns-container {
3 | overflow-x: auto;
4 | border: 1px solid $medium_border;
5 | display: flex;
6 | }
7 |
8 | .column-item {
9 | display: inline-block;
10 | padding: 2px 8px;
11 | border-right: 1px solid $medium_border;
12 | white-space: nowrap;
13 | flex: 1;
14 |
15 | input {
16 | vertical-align: middle;
17 | }
18 |
19 | &:last-of-type {
20 | border-right: none;
21 | }
22 |
23 | &.selected {
24 | background: $selected;
25 | }
26 | }
27 |
28 | .edit-custom-column{
29 | font-size: 14px;
30 |
31 | .CodeMirror {
32 | border: 1px solid $medium_border;
33 | margin-top: 4px;
34 | height: 150px;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/src/stylesheets/views/editModal.scss:
--------------------------------------------------------------------------------
1 | .edit-modal {
2 | input {
3 | width: 100%;
4 | padding: 2px;
5 | }
6 |
7 | textarea {
8 | width: 100%;
9 | min-height: 150px;
10 | }
11 | }
12 |
13 | .save-file-as-modal {
14 | .modal {
15 | max-width: 600px;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/stylesheets/views/errorCaching.scss:
--------------------------------------------------------------------------------
1 | .cache-container {
2 | border: 1px solid #aaa;
3 | padding: 6px;
4 |
5 | .cache-item {
6 | border-top: 1px solid #aaa;
7 | position: relative;
8 | padding: 10px 4px;
9 |
10 | &:first-of-type {
11 | border-top: none;
12 | }
13 |
14 | .delete-item {
15 | position: absolute;
16 | top: 10px;
17 | right: 4px;
18 |
19 | .action-box {
20 | font-size: 12px;
21 | }
22 | }
23 |
24 | .filename {
25 | font-size: 20px;
26 | padding-bottom: 6px;
27 | }
28 | }
29 |
30 | .cache-files-table {
31 | td, th {
32 | padding-right: 10px;
33 | font-size: 14px;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/stylesheets/views/filterView.scss:
--------------------------------------------------------------------------------
1 | .filter-view {
2 | .results-bar {
3 | margin-bottom: 6px;
4 |
5 | .re-run {
6 | font: 16px FontAwesome;
7 | margin-left: 2px;
8 |
9 | &:hover {
10 | color: $secondary_action;
11 | }
12 |
13 | &:before {
14 | content: '\f002'
15 | }
16 | }
17 | }
18 |
19 | .tree-view {
20 | display: flex;
21 | flex-direction: column;
22 | flex: 1;
23 | }
24 | }
25 |
26 | .filter-view-icon {
27 | &:before {
28 | content: '\f0b0'
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/stylesheets/views/loadOrderModal.scss:
--------------------------------------------------------------------------------
1 | .load-order-modal {
2 | .disabled {
3 | color: $negative;
4 | }
5 |
6 | .required {
7 | color: $positive;
8 | }
9 |
10 | section.scrollable-section {
11 | min-height: 57vh;
12 | max-height: 57vh;
13 | }
14 |
15 | list-view {
16 | .list-items {
17 | max-height: 56vh;
18 | min-height: 56vh;
19 | }
20 |
21 | .list-item {
22 | padding-right: 30px;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/stylesheets/views/logView.scss:
--------------------------------------------------------------------------------
1 | .log-view {
2 | overflow: hidden;
3 |
4 | .messages {
5 | overflow-y: scroll;
6 | display: block;
7 | flex: 1;
8 | padding-bottom: 20px;
9 | user-select: initial;
10 | text-align: left;
11 | font-size: 13px;
12 |
13 | > div {
14 | padding: 1px 6px;
15 | border-bottom: 1px solid $soft_border;
16 | white-space: pre-wrap;
17 | }
18 | }
19 |
20 | .warn-message {
21 | color: $neutral;
22 | }
23 |
24 | .error-message {
25 | color: $negative;
26 | }
27 | }
28 |
29 | .label .log-view-icon {
30 | margin-top: -2px;
31 |
32 | &::before {
33 | font-size: 16px;
34 | }
35 | }
36 |
37 | .log-view-icon::before {
38 | content: "\f0f6";
39 | }
40 |
--------------------------------------------------------------------------------
/src/stylesheets/views/manageExtensionsModal.scss:
--------------------------------------------------------------------------------
1 | .module-item, .theme-item {
2 | border: 1px solid $hard_border;
3 | margin: 20px 0;
4 | padding: 12px;
5 | background-color: $secondary_background;
6 |
7 | .header {
8 | display: flex;
9 | align-items: center;
10 |
11 | .title {
12 | font-size: 20px;
13 |
14 | &:not(.no-link) {
15 | cursor: pointer;
16 | }
17 |
18 | &:hover:not(.no-link) {
19 | text-decoration: underline;
20 | }
21 | }
22 |
23 | .version {
24 | margin-left: 6px;
25 | color: $medium_font_color;
26 | }
27 |
28 | .author {
29 | flex: 1;
30 | text-align: right;
31 | }
32 | }
33 |
34 | .description {
35 | margin: 4px 0;
36 | }
37 |
38 | .footer {
39 | margin-top: 8px;
40 | text-align: right;
41 |
42 | .action-btn {
43 | font-size: 14px;
44 | padding: 4px 6px 3px;
45 | }
46 | }
47 | }
48 |
49 | .extensions-modal {
50 | .restart-message {
51 | color: $negative;
52 | text-align: center;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/stylesheets/views/newTabView.scss:
--------------------------------------------------------------------------------
1 | .new-tab-view {
2 | .view-items {
3 | display: flex;
4 | align-items: center;
5 | height: 100%;
6 | justify-content: center;
7 | padding: 20px 40px 80px;
8 | }
9 |
10 | .view-item {
11 | display: inline-block;
12 | width: 128px;
13 | height: 128px;
14 | padding: 10px 2px;
15 | margin: 12px;
16 | border: 3px solid $medium_border;
17 | border-radius: 8px;
18 |
19 | &:hover {
20 | border-color: $secondary_action;
21 | }
22 |
23 | .icon {
24 | font: 80px FontAwesome;
25 | }
26 |
27 | .record-view-icon {
28 | font-size: 88px;
29 | margin-bottom: -8px;
30 | }
31 |
32 | .referenced-by-view-icon {
33 | font-size: 82px;
34 | margin-bottom: -6px;
35 | margin-top: -8px;
36 | }
37 |
38 | .log-view-icon {
39 | font-size: 72px;
40 | margin-bottom: 4px;
41 | margin-top: -3px;
42 | }
43 |
44 | .label {
45 | text-align: center;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/stylesheets/views/profilesModal.scss:
--------------------------------------------------------------------------------
1 | .profiles-modal .modal {
2 | width: 850px;
3 | max-width: 85% !important;
4 | }
5 |
6 | profile {
7 | display: flex;
8 | align-items: center;
9 | position: relative;
10 | border: 1px solid $medium_border;
11 | border-radius: 3px;
12 | margin: 8px 0;
13 | padding: 8px 0;
14 |
15 | .remove-item {
16 | position: absolute;
17 | right: 0;
18 | top: 0;
19 | padding-right: 3px;
20 | font: 20px FontAwesome;
21 | }
22 |
23 | img {
24 | width: 105px;
25 | margin: 6px 8px;
26 | }
27 |
28 | select {
29 | min-width: 100px;
30 | }
31 |
32 | .fa-folder-open-o {
33 | cursor: pointer;
34 | margin-left: 6px;
35 | }
36 |
37 | .right-column {
38 | flex: 1;
39 | text-align: left;
40 | padding-right: 12px;
41 |
42 | label {
43 | display: flex;
44 | align-items: center;
45 | }
46 |
47 | .input-label {
48 | min-width: 100px;
49 | }
50 |
51 | .path-input {
52 | flex: 1;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/stylesheets/views/progressModal.scss:
--------------------------------------------------------------------------------
1 | progress-modal {
2 | .modal-container .modal {
3 | max-width: 800px;
4 | }
5 |
6 | .progress-title {
7 | font-size: 18px;
8 | margin-bottom: 16px;
9 | }
10 |
11 | .progress-message {
12 | margin-bottom: 4px;
13 | }
14 |
15 | .log {
16 | user-select: initial;
17 | height: 300px;
18 | border: 1px solid $hard_border;
19 | background-color: $background_tint;
20 | padding: 4px 0 20px;
21 | margin-top: 4px;
22 | font-size: 13px;
23 | overflow-y: auto;
24 |
25 | > div {
26 | padding: 1px 6px;
27 | white-space: pre-wrap;
28 | }
29 | }
30 |
31 | .warn-message {
32 | color: $neutral;
33 | }
34 |
35 | .error-message {
36 | color: $negative;
37 | }
38 | }
--------------------------------------------------------------------------------
/src/stylesheets/views/promptModal.scss:
--------------------------------------------------------------------------------
1 | .prompt-modal {
2 | .modal-container .modal {
3 | padding: 30px;
4 | }
5 |
6 | .prompt {
7 | white-space: pre-wrap;
8 | }
9 | }
--------------------------------------------------------------------------------
/src/stylesheets/views/refactorModal.scss:
--------------------------------------------------------------------------------
1 | .refactor-file-modal, .refactor-records-modal {
2 | form .input-label {
3 | min-width: 115px;
4 | }
5 |
6 | textarea {
7 | width: 100%;
8 | max-width: 100%;
9 | height: 60px;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/stylesheets/views/referencedByView.scss:
--------------------------------------------------------------------------------
1 | .referenced-by-view {
2 | text-align: left;
3 | font-size: 13px;
4 | overflow: hidden;
5 | padding-top: 24px;
6 |
7 | .node-columns {
8 | padding-right: 1.2em;
9 |
10 | .column:last-of-type {
11 | border-right: 1px solid $medium_border;
12 | }
13 | }
14 |
15 | .nodes {
16 | min-width: 400px;
17 | overflow-y: scroll;
18 |
19 | .column {
20 | min-width: 72px;
21 |
22 | &:last-of-type {
23 | flex: 1;
24 | border-right: none;
25 | }
26 | }
27 | }
28 |
29 | .edit-columns {
30 | right: 17px;
31 |
32 | &::before {
33 | content: "\f0db";
34 | }
35 | }
36 | }
37 |
38 | .referenced-by-view-icon {
39 | &::before {
40 | content: "\f079";
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/stylesheets/views/resolveModal.scss:
--------------------------------------------------------------------------------
1 | .resolve-modal {
2 | h2, h3 {
3 | margin-top: 0;
4 | }
5 |
6 | h3 {
7 | margin-bottom: 0;
8 |
9 | &.limit-text {
10 | padding: 0 50px;
11 | }
12 | }
13 |
14 | .modal-body {
15 | margin: 18px 40px 100px;
16 | overflow: auto;
17 | }
18 |
19 | .modal-footer {
20 | position: absolute;
21 | bottom: 0;
22 | left: 0;
23 | display: flex;
24 | align-items: center;
25 | justify-content: space-between;
26 | width: 100%;
27 | padding: 30px 45px;
28 |
29 | > div {
30 | min-width: 110px;
31 | }
32 |
33 | .action-box {
34 | min-width: 105px;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/stylesheets/views/settingsModal.scss:
--------------------------------------------------------------------------------
1 | .settings-modal {
2 | .modal-container .modal {
3 | margin: 100px auto;
4 | }
5 |
6 | ng-include.flex {
7 | display: flex;
8 | flex-direction: column;
9 | }
10 |
11 | .theme-metadata {
12 | padding-left: 20px;
13 | font-size: 15px;
14 |
15 | .theme-description {
16 | margin-top: 4px;
17 | max-width: 400px;
18 | }
19 | }
20 |
21 | .syntax-theme-preview {
22 | .CodeMirror {
23 | height: 200px;
24 | }
25 | }
26 | }
27 |
28 | .setting {
29 | display: flex;
30 | margin: 5px 0;
31 |
32 | .input-label {
33 | min-width: 225px;
34 | margin: 0;
35 | }
36 |
37 | input[type="text"] {
38 | flex-grow: 1;
39 | margin-right: 6px;
40 | }
41 |
42 | select {
43 | min-width: 150px;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/stylesheets/views/start.scss:
--------------------------------------------------------------------------------
1 | .game-logo-container {
2 | padding: 8px;
3 | }
4 |
5 | .appmode-select {
6 | margin: 0.67em 0;
7 | padding: 2px 40px 2px 8px;
8 | border-color: $soft_font_color;
9 | font-size: 2em;
10 | font-weight: bold;
11 |
12 | @include dropdown-triangle(10px);
13 | }
14 |
15 | .profile-controls {
16 | select, span {
17 | display: inline-block;
18 | vertical-align: middle;
19 | }
20 |
21 | span.fa {
22 | margin-left: 4px;
23 | font-size: 30px;
24 | cursor: pointer;
25 | }
26 |
27 | select {
28 | min-width: 140px;
29 | padding: 4px;
30 | padding-right: 35px;
31 | border-color: $soft_font_color;
32 | font-size: 20px;
33 |
34 | @include dropdown-triangle(10px);
35 | }
36 | }
37 |
38 | .app-version {
39 | position: absolute;
40 | bottom: 0;
41 | right: 0;
42 | padding: 4px 6px;
43 | font-size: 12px;
44 | }
45 |
--------------------------------------------------------------------------------
/src/stylesheets/views/treeView.scss:
--------------------------------------------------------------------------------
1 | .tree-view {
2 | text-align: left;
3 | font-size: 13px;
4 | overflow: hidden;
5 | padding-top: 24px;
6 |
7 | .node-columns {
8 | padding-right: 1.2em;
9 |
10 | .column:last-of-type {
11 | border-right: 1px solid $medium_border;
12 | }
13 | }
14 |
15 | .nodes {
16 | min-width: 400px;
17 | overflow-y: scroll;
18 |
19 | .column {
20 | min-width: 100px;
21 |
22 | &:last-of-type {
23 | flex: 1;
24 | border-right: none;
25 | }
26 | }
27 |
28 | .modified {
29 | font-weight: 600;
30 | }
31 | }
32 |
33 | .edit-columns {
34 | right: 17px;
35 |
36 | &::before {
37 | content: "\f0db";
38 | }
39 | }
40 | }
41 |
42 | .tree-view-icon {
43 | &::before {
44 | content: "\f0e8";
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/tasks/start.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const childProcess = require('child_process');
4 | const electron = require('electron');
5 | const gulp = require('gulp');
6 |
7 | function getApp(inputArgs) {
8 | let args = ['.'];
9 | if (Array.isArray(inputArgs))
10 | inputArgs.forEach(arg => args.push(arg));
11 |
12 | return function app(done) {
13 | childProcess.spawn(electron, args, {
14 | stdio: 'inherit'
15 | }).on('close', function () {
16 | process.exit();
17 | done();
18 | });
19 | };
20 | }
21 |
22 | gulp.task('start', gulp.series(
23 | 'build',
24 | gulp.parallel(
25 | 'watch',
26 | getApp()
27 | )
28 | ));
29 |
30 | gulp.task('start-debug', gulp.series(
31 | 'build',
32 | gulp.parallel(
33 | 'watch',
34 | getApp(["-dev", "--external-debugger", "--debug-progress"])
35 | )
36 | ));
37 |
38 |
--------------------------------------------------------------------------------
/tasks/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const argv = require('minimist')(process.argv);
4 |
5 | exports.getEnvName = function () {
6 | return argv.env || 'development';
7 | };
8 |
9 | exports.beepSound = function () {
10 | process.stdout.write('\u0007');
11 | };
12 |
--------------------------------------------------------------------------------
/tests/istanbul-reporter.js:
--------------------------------------------------------------------------------
1 | var istanbul = require('istanbul');
2 |
3 | module.exports = function (runner, options) {
4 | mocha.reporters.Base.call(this, runner);
5 |
6 | var reporterOpts = { dir: 'coverage' },
7 | reporters = ['text-summary', 'html'];
8 |
9 | options = options || {};
10 | if (options.reporters) reporters = options.reporters.split(',');
11 | if (process.env.ISTANBUL_REPORTERS) reporters = process.env.ISTANBUL_REPORTERS.split(',');
12 | if (options.reportDir) reporterOpts.dir = options.reportDir;
13 | if (process.env.ISTANBUL_REPORT_DIR) reporterOpts.dir = process.env.ISTANBUL_REPORT_DIR;
14 |
15 | runner.on('end', function(){
16 | var cov = global.__coverage__ || {},
17 | collector = new istanbul.Collector();
18 |
19 | collector.add(cov);
20 |
21 | reporters.forEach(function(reporter) {
22 | istanbul.Report.create(reporter, reporterOpts).writeReport(collector, true);
23 | });
24 |
25 | });
26 | };
27 |
--------------------------------------------------------------------------------
/tests/travis-build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | git clone https://github.com/creationix/nvm.git /tmp/.nvm
4 | source /tmp/.nvm/nvm.sh
5 | nvm install "$NODE_VERSION"
6 | nvm use --delete-prefix "$NODE_VERSION"
7 |
8 | if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
9 | export DISPLAY=:99.0
10 | sh -e /etc/init.d/xvfb start
11 | sleep 3
12 | fi
13 |
14 | node --version
15 | npm --version
16 |
17 | npm install
18 | npm test & npm run e2e
19 |
--------------------------------------------------------------------------------
/update_xelib.bat:
--------------------------------------------------------------------------------
1 | call npm i z-edit/xelib --save
2 | copy /Y .\node_modules\xelib\XEditLib.dll .\XEditLib.dll
3 | del ".\node_modules\xelib\XEditLib.dll"
4 | del ".\node_modules\xelib\*.dat"
5 | call npm run rebuild
--------------------------------------------------------------------------------