Compare commits

..

No commits in common. "v0.0.1-test14" and "main" have entirely different histories.

18 changed files with 45 additions and 457 deletions

View File

@ -131,35 +131,35 @@ jobs:
echo Definitions and docs packaged
- name: Update Package Versions
shell: powershell
shell: cmd
run: |
$VERSION = $env:CLEAN_VERSION
$CHANNEL = $env:CHANNEL
$TODAY = Get-Date -Format "yyyy-MM-dd"
setlocal enabledelayedexpansion
Write-Host "Updating to version $VERSION for channel $CHANNEL on $TODAY"
set "VERSION=%CLEAN_VERSION%"
set "CHANNEL=%CHANNEL%"
# Update package.xml files
Get-ChildItem -Path "installer\packages" -Filter "package.xml" -Recurse | ForEach-Object {
$content = Get-Content $_.FullName -Raw
$content = $content -replace '<Version>.*?</Version>', "<Version>$VERSION</Version>"
$content = $content -replace '<ReleaseDate>.*?</ReleaseDate>', "<ReleaseDate>$TODAY</ReleaseDate>"
Set-Content -Path $_.FullName -Value $content -NoNewline
}
REM Get today's date in YYYY-MM-DD format
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /value') do set "DT=%%I"
set "TODAY=!DT:~0,4!-!DT:~4,2!-!DT:~6,2!"
# Update config.xml
$configPath = "installer\config\config.xml"
$content = Get-Content $configPath -Raw
$content = $content -replace '<Version>.*?</Version>', "<Version>$VERSION</Version>"
$content = $content -replace 'repository/[^<"]*', "repository/$CHANNEL"
Set-Content -Path $configPath -Value $content -NoNewline
echo Updating to version !VERSION! for channel !CHANNEL! on !TODAY!
Write-Host "Updated versions to $VERSION for channel $CHANNEL"
REM Update package.xml files using PowerShell for regex
for /r installer\packages %%f in (package.xml) do (
if exist "%%f" (
powershell -Command "(Get-Content '%%f') -replace '<Version>.*</Version>', '<Version>%VERSION%</Version>' -replace '<ReleaseDate>.*</ReleaseDate>', '<ReleaseDate>%TODAY%</ReleaseDate>' | Set-Content '%%f'"
)
)
REM Update config.xml
powershell -Command "(Get-Content 'installer\config\config.xml') -replace '<Version>.*</Version>', '<Version>%VERSION%</Version>' -replace 'repository/[^<\"]*', 'repository/%CHANNEL%' | Set-Content 'installer\config\config.xml'"
echo Updated versions to !VERSION! for channel !CHANNEL!
- name: Generate Repository
shell: cmd
run: |
set PATH=C:\Qt\Tools\QtInstallerFramework\4.10\bin;%PATH%
set PATH=C:\Qt\Tools\QtInstallerFramework\4.8\bin;%PATH%
if exist repository rmdir /s /q repository
mkdir repository
@ -172,7 +172,7 @@ jobs:
- name: Create Offline Installer
shell: cmd
run: |
set PATH=C:\Qt\Tools\QtInstallerFramework\4.10\bin;%PATH%
set PATH=C:\Qt\Tools\QtInstallerFramework\4.8\bin;%PATH%
binarycreator.exe --offline-only -c installer\config\config.xml -p installer\packages "XPlor-%VERSION%-Windows-Setup.exe"
if errorlevel 1 exit /b 1
@ -182,7 +182,7 @@ jobs:
- name: Create Online Installer
shell: cmd
run: |
set PATH=C:\Qt\Tools\QtInstallerFramework\4.10\bin;%PATH%
set PATH=C:\Qt\Tools\QtInstallerFramework\4.8\bin;%PATH%
binarycreator.exe --online-only -c installer\config\config.xml -p installer\packages "XPlor-%VERSION%-Windows-Online.exe"
if errorlevel 1 exit /b 1
@ -191,18 +191,11 @@ jobs:
- name: Deploy to Repository
shell: cmd
continue-on-error: true
run: |
set REPO_PATH=P:\repository\%CHANNEL%
echo Deploying to %REPO_PATH%
REM Check if drive exists
if not exist "P:\" (
echo WARNING: P: drive not available, skipping local repository deployment
exit /b 0
)
if not exist "%REPO_PATH%" mkdir "%REPO_PATH%"
REM Copy repository contents
@ -211,7 +204,7 @@ jobs:
echo Repository updated at %REPO_PATH%
- name: Upload Installers
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: windows-installers
path: |
@ -356,30 +349,22 @@ jobs:
CHANNEL="${{ env.CHANNEL }}"
TODAY=$(date +%Y-%m-%d)
echo "Updating to version $VERSION for channel $CHANNEL on $TODAY"
# Update package.xml files
find installer/packages -name "package.xml" -exec sed -i '' \
-e "s|<Version>.*</Version>|<Version>$VERSION</Version>|" \
-e "s|<ReleaseDate>.*</ReleaseDate>|<ReleaseDate>$TODAY</ReleaseDate>|" {} \;
# Update config.xml
if [ -f "installer/config/config.xml" ]; then
sed -i '' \
-e "s|<Version>.*</Version>|<Version>$VERSION</Version>|" \
-e "s|repository/[^<\"]*|repository/$CHANNEL|" \
installer/config/config.xml
else
echo "WARNING: installer/config/config.xml not found"
fi
echo "Updated versions to $VERSION for channel $CHANNEL"
sed -i '' \
-e "s|<Version>.*</Version>|<Version>$VERSION</Version>|" \
-e "s|repository/[^<\"]*|repository/$CHANNEL|" \
installer/config/config.xml
- name: Generate Repository and Installers
shell: bash
run: |
# Find Qt IFW (macOS uses 4.10 at ~/Qt/Tools/QtInstallerFramework/bin)
for IFW_PATH in ~/Qt/Tools/QtInstallerFramework/bin ~/Qt/Tools/QtInstallerFramework/4.10/bin /opt/homebrew/opt/qt-installer-framework/bin; do
# Find Qt IFW
for IFW_PATH in ~/Qt/Tools/QtInstallerFramework/4.8/bin ~/Qt/Tools/QtInstallerFramework/4.7/bin /opt/homebrew/opt/qt-installer-framework/bin; do
if [ -f "$IFW_PATH/repogen" ]; then
echo "Found Qt IFW at: $IFW_PATH"
export PATH="$IFW_PATH:$PATH"
@ -412,7 +397,7 @@ jobs:
ls -la XPlor-*
- name: Upload Installers
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: macos-installers
path: |
@ -423,7 +408,7 @@ jobs:
retention-days: 90
- name: Upload Repository
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: macos-repository
path: repository/
@ -568,24 +553,16 @@ jobs:
CHANNEL="${{ env.CHANNEL }}"
TODAY=$(date +%Y-%m-%d)
echo "Updating to version $VERSION for channel $CHANNEL on $TODAY"
# Update package.xml files
find installer/packages -name "package.xml" -exec sed -i \
-e "s|<Version>.*</Version>|<Version>$VERSION</Version>|" \
-e "s|<ReleaseDate>.*</ReleaseDate>|<ReleaseDate>$TODAY</ReleaseDate>|" {} \;
# Update config.xml
if [ -f "installer/config/config.xml" ]; then
sed -i \
-e "s|<Version>.*</Version>|<Version>$VERSION</Version>|" \
-e "s|repository/[^<\"]*|repository/$CHANNEL|" \
installer/config/config.xml
else
echo "WARNING: installer/config/config.xml not found"
fi
echo "Updated versions to $VERSION for channel $CHANNEL"
sed -i \
-e "s|<Version>.*</Version>|<Version>$VERSION</Version>|" \
-e "s|repository/[^<\"]*|repository/$CHANNEL|" \
installer/config/config.xml
- name: Generate Repository and Installers
shell: bash
@ -616,7 +593,7 @@ jobs:
ls -la XPlor-*
- name: Upload Installers
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: linux-installers
path: |
@ -625,7 +602,7 @@ jobs:
retention-days: 90
- name: Upload Repository
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: linux-repository
path: repository/
@ -655,25 +632,24 @@ jobs:
echo CHANNEL=!CHANNEL!>> %GITHUB_ENV%
- name: Download all installers
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Download macOS repository
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: macos-repository
path: repo-macos
- name: Download Linux repository
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: linux-repository
path: repo-linux
- name: Merge repositories
shell: cmd
continue-on-error: true
run: |
setlocal enabledelayedexpansion
@ -682,12 +658,6 @@ jobs:
echo Deploying to: !REPO_PATH!
REM Check if P: drive exists
if not exist "P:\" (
echo WARNING: P: drive not available, skipping repository deployment
exit /b 0
)
REM Ensure directory exists
if not exist "!REPO_PATH!" mkdir "!REPO_PATH!"
@ -725,16 +695,10 @@ jobs:
dir release\
- name: Create Gitea Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
files: release/*
generate_release_notes: true
prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'test') }}
body: |
Release ${{ github.ref_name }}
## Downloads
- **Windows**: XPlor-*-Windows-Setup.exe (offline), XPlor-*-Windows-Online.exe
- **macOS**: XPlor-*-macOS-Setup.dmg (offline), XPlor-*-macOS-Online.dmg
- **Linux**: XPlor-*-Linux-Setup.run (offline), XPlor-*-Linux-Online.run
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

6
.gitignore vendored
View File

@ -11,8 +11,7 @@ tmpcl*
.vscode/*
.qmake.stash
# Installer: ignore data directories but track config and package metadata
installer/packages/*/data/
installer/*
# Ignore Qt Creator user files
*.pro.user
@ -74,6 +73,7 @@ third_party/dx9_sdk/
third_party/xna/
third_party/lzxdhelper/
# Qt Installer Framework build outputs
# Qt Installer Framework
repository/
installer/packages/*/data/
.deploy-temp/

View File

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Installer>
<Name>XPlor</Name>
<Version>1.11.0</Version>
<Title>XPlor Binary Format Explorer</Title>
<Publisher>RedLine Solutions LLC</Publisher>
<StartMenuDir>XPlor</StartMenuDir>
<TargetDir>@HomeDir@/XPlor</TargetDir>
<!-- Allow users to change install directory -->
<AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>
<AllowSpaceInPath>true</AllowSpaceInPath>
<!-- Remote repository URL - updated by deploy.cmd based on git branch -->
<RemoteRepositories>
<Repository>
<Url>https://xplor.redline.llc/repository/main</Url>
<Enabled>1</Enabled>
<DisplayName>XPlor Updates</DisplayName>
</Repository>
</RemoteRepositories>
<!-- Maintenance tool settings -->
<MaintenanceToolName>XPlorMaintenanceTool</MaintenanceToolName>
<MaintenanceToolIniFile>XPlorMaintenanceTool.ini</MaintenanceToolIniFile>
<!-- Update check settings -->
<InstallActionColumnVisible>true</InstallActionColumnVisible>
<!-- Styling -->
<WizardStyle>Modern</WizardStyle>
<WizardDefaultWidth>800</WizardDefaultWidth>
<WizardDefaultHeight>600</WizardDefaultHeight>
<!-- Installer resources (optional - will use defaults if missing) -->
<!-- <Logo>logo.png</Logo> -->
<!-- <Banner>banner.png</Banner> -->
<!-- <Watermark>watermark.png</Watermark> -->
<!-- Control script for channel selection -->
<ControlScript>controlscript.qs</ControlScript>
</Installer>

View File

@ -1,117 +0,0 @@
// XPlor Installer Control Script
// Provides channel selection (stable/beta) and post-install options
function Controller()
{
installer.setDefaultPageVisible(QInstaller.Introduction, true);
installer.setDefaultPageVisible(QInstaller.TargetDirectory, true);
installer.setDefaultPageVisible(QInstaller.ComponentSelection, true);
installer.setDefaultPageVisible(QInstaller.StartMenuSelection, true);
installer.setDefaultPageVisible(QInstaller.ReadyForInstallation, true);
installer.setDefaultPageVisible(QInstaller.PerformInstallation, true);
installer.setDefaultPageVisible(QInstaller.InstallationFinished, true);
}
Controller.prototype.IntroductionPageCallback = function()
{
var widget = gui.currentPageWidget();
if (widget != null) {
// Add channel selection radio buttons (only for fresh install, not updates)
if (!installer.isUpdater()) {
var channelWidget = widget.findChild("ChannelGroupBox");
if (channelWidget == null) {
var layout = widget.layout();
var groupBox = new QGroupBox("Update Channel");
groupBox.objectName = "ChannelGroupBox";
var vbox = new QVBoxLayout(groupBox);
var stableRadio = new QRadioButton("Stable - Recommended for most users");
stableRadio.checked = true;
stableRadio.objectName = "stableChannel";
vbox.addWidget(stableRadio);
var betaRadio = new QRadioButton("Beta - Early access to new features");
betaRadio.objectName = "betaChannel";
vbox.addWidget(betaRadio);
layout.addWidget(groupBox);
// Connect signal to update repository URL
stableRadio.toggled.connect(this, this.channelChanged);
}
}
}
}
Controller.prototype.channelChanged = function(checked)
{
if (!checked) return;
var widget = gui.currentPageWidget();
var stableRadio = widget.findChild("stableChannel");
// Update repository URL based on selection
var repos = installer.defaultRepositories();
for (var i = 0; i < repos.length; i++) {
var repo = repos[i];
var url = repo.url().toString();
if (stableRadio.checked) {
url = url.replace("/beta", "/stable");
} else {
url = url.replace("/stable", "/beta");
}
repo.setUrl(new QUrl(url));
}
}
Controller.prototype.TargetDirectoryPageCallback = function()
{
// Set default target directory
var widget = gui.currentPageWidget();
if (widget != null) {
widget.targetDirectoryLineEdit.setText(installer.value("TargetDir"));
}
}
Controller.prototype.ComponentSelectionPageCallback = function()
{
var widget = gui.currentPageWidget();
if (widget != null) {
// Optionally customize component tree
}
}
Controller.prototype.InstallationFinishedPageCallback = function()
{
// Offer to run the application after installation
if (installer.isInstaller() && installer.status == QInstaller.Success) {
var widget = gui.currentPageWidget();
if (widget != null) {
var runCheckbox = widget.findChild("RunAppCheckbox");
if (runCheckbox == null) {
var checkbox = new QCheckBox("Run XPlor after installation");
checkbox.checked = true;
checkbox.objectName = "RunAppCheckbox";
widget.layout().addWidget(checkbox);
}
}
}
}
Controller.prototype.FinishedPageCallback = function()
{
// Launch application if checkbox was checked
if (installer.isInstaller() && installer.status == QInstaller.Success) {
var widget = gui.currentPageWidget();
if (widget != null) {
var runCheckbox = widget.findChild("RunAppCheckbox");
if (runCheckbox != null && runCheckbox.checked) {
var installDir = installer.value("TargetDir");
QDesktopServices.openUrl("file:///" + installDir + "/XPlor.exe");
}
}
}
}

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>XPlor CLI Tool</DisplayName>
<Description>Command-line interface for scripted file analysis and batch processing.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.cli</Name>
<Default>false</Default>
<SortingPriority>90</SortingPriority>
</Package>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Asura Engine Formats</DisplayName>
<Description>Support for Sniper Elite V2 and related Asura engine game files.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.definitions.asura</Name>
<Dependencies>com.xplor.gui</Dependencies>
<Default>true</Default>
<SortingPriority>76</SortingPriority>
</Package>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Call of Duty Formats</DisplayName>
<Description>Support for Call of Duty game files including Fast Files (.ff), IWD archives, and related formats.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.definitions.cod</Name>
<Dependencies>com.xplor.gui</Dependencies>
<Default>true</Default>
<SortingPriority>79</SortingPriority>
</Package>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Dead Rising Formats</DisplayName>
<Description>Support for Dead Rising game files including BIG archives, textures, and animations.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.definitions.deadrising</Name>
<Dependencies>com.xplor.gui</Dependencies>
<Default>true</Default>
<SortingPriority>77</SortingPriority>
</Package>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>FMOD Audio Formats</DisplayName>
<Description>Support for FMOD sound bank files and audio containers.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.definitions.fmod</Name>
<Dependencies>com.xplor.gui</Dependencies>
<Default>true</Default>
<SortingPriority>75</SortingPriority>
</Package>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>THQA Formats</DisplayName>
<Description>Support for Tony Hawk series and related game files.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.definitions.thqa</Name>
<Dependencies>com.xplor.gui</Dependencies>
<Default>true</Default>
<SortingPriority>74</SortingPriority>
</Package>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Volition Engine Formats</DisplayName>
<Description>Support for Saints Row and Red Faction VPP archives, PEG textures, and related formats.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.definitions.volition</Name>
<Dependencies>com.xplor.gui</Dependencies>
<Default>true</Default>
<SortingPriority>78</SortingPriority>
</Package>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Nintendo Wii Formats</DisplayName>
<Description>Support for Wii-specific file formats and archives.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.definitions.wii</Name>
<Dependencies>com.xplor.gui</Dependencies>
<Default>true</Default>
<SortingPriority>73</SortingPriority>
</Package>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Format Definitions</DisplayName>
<Description>XScript format definition packs for various game engines. Select individual packs below.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.definitions</Name>
<Virtual>true</Virtual>
<SortingPriority>80</SortingPriority>
</Package>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Documentation</DisplayName>
<Description>XScript language guide and API reference documentation.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.docs</Name>
<Default>true</Default>
<SortingPriority>70</SortingPriority>
</Package>

View File

@ -1,67 +0,0 @@
// XPlor GUI Installation Script
// Creates shortcuts and registers file associations
function Component()
{
// Default constructor
}
Component.prototype.createOperations = function()
{
// Call default implementation
component.createOperations();
if (systemInfo.productType === "windows") {
// Create Start Menu shortcut
component.addOperation("CreateShortcut",
"@TargetDir@/XPlor.exe",
"@StartMenuDir@/XPlor.lnk",
"workingDirectory=@TargetDir@",
"iconPath=@TargetDir@/XPlor.exe",
"iconId=0",
"description=Binary File Format Explorer");
// Create Desktop shortcut
component.addOperation("CreateShortcut",
"@TargetDir@/XPlor.exe",
"@DesktopDir@/XPlor.lnk",
"workingDirectory=@TargetDir@",
"iconPath=@TargetDir@/XPlor.exe");
// Register file associations for common formats
component.addOperation("RegisterFileType",
"vpp_xbox2",
"@TargetDir@/XPlor.exe \"%1\"",
"Volition Package (Xbox 360)",
"application/octet-stream",
"@TargetDir@/XPlor.exe,0");
component.addOperation("RegisterFileType",
"vpp_pc",
"@TargetDir@/XPlor.exe \"%1\"",
"Volition Package (PC)",
"application/octet-stream",
"@TargetDir@/XPlor.exe,0");
component.addOperation("RegisterFileType",
"str2_pc",
"@TargetDir@/XPlor.exe \"%1\"",
"Saints Row Stream Container",
"application/octet-stream",
"@TargetDir@/XPlor.exe,0");
component.addOperation("RegisterFileType",
"ff",
"@TargetDir@/XPlor.exe \"%1\"",
"Call of Duty Fast File",
"application/octet-stream",
"@TargetDir@/XPlor.exe,0");
component.addOperation("RegisterFileType",
"big",
"@TargetDir@/XPlor.exe \"%1\"",
"Dead Rising Archive",
"application/octet-stream",
"@TargetDir@/XPlor.exe,0");
}
}

View File

@ -1,17 +0,0 @@
XPlor Binary Format Explorer
Copyright (c) 2025 RedLine Solutions LLC
This software is provided for personal and educational use.
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.
Third-Party Components:
- Qt Framework: LGPL v3 / Commercial License
- zlib: zlib License
- DevIL: LGPL License

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>XPlor GUI Application</DisplayName>
<Description>Binary file format explorer with graphical interface. Includes Qt runtime libraries.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.gui</Name>
<Default>true</Default>
<Essential>false</Essential>
<ForcedInstallation>false</ForcedInstallation>
<SortingPriority>100</SortingPriority>
<Script>installscript.qs</Script>
<Licenses>
<License name="License Agreement" file="license.txt"/>
</Licenses>
</Package>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Analysis Scripts</DisplayName>
<Description>Python scripts for advanced file analysis and data extraction. Requires Python 3.x.</Description>
<Version>1.11.0</Version>
<ReleaseDate>2026-01-12</ReleaseDate>
<Name>com.xplor.scripts</Name>
<Default>false</Default>
<SortingPriority>60</SortingPriority>
</Package>