From 6b0fa4ff0de0de85dcde0f0bcab8410124c521bb Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 17 Aug 2026 02:04:19 +0200 Subject: [PATCH] =?UTF-8?q?feat(ui):=20Map/House=20panel=20=E2=80=94=20sli?= =?UTF-8?q?ces=202+3,=20panel=20shell=20+=20Map=20tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mounts host 0x2100006E slot 0x1000018C (RetailPanelCatalog.MapHouse = 16) as a two-tab UiTabPanel (Map default, House second) through the OP3/FA3 recipe (LayoutImporter.Build -> Bind -> ActivateTabBehavior). Toolbar button 0x1000019A un-ghosts (added to both RetailPanelCatalog.Mounted and .Toolbar). Combined into one commit because MapHousePanelController.Bind depends on both MapPageController and HousePageController existing — splitting them would mean landing dead code first. Map tab (gmMapUI, MapPageController): - Calendar formatter matching gmMapUI::Update's "Date: %s\nTime: %s" shape, reusing WorldTimeService.CurrentCalendar (new Func dependency threaded through InteractionRetainedUiDependencies/GameWindow — a stable long-lived service, not routed through the deferred-binding machinery Radar's per-session state needs). MonthName enum values already match retail display text; HourName's "AndHalf" suffix is rewritten to "-and-Half". - Coordinate math + marker placement reuse RadarCoordinates/ LandDefs.GidToLcoord verbatim (both already byte-exact ports of CPlayerSystem::InqPlayerCoords/LandDefs::gid_to_lcoord) — no re-port. PlaceMarkerOnMap's centering math (m_x0 + x - w/2) ported from gmMapUI::PlaceMarkerOnMap @0x004a18b0. Indoor gating clears the coordinate text and hides the player marker, matching gmMapUI::Update's else branch. - 53-town s_rgLocations table ported verbatim into MapLocations.cs. Markers built once at bind time via the panel's own RowTemplateResolver against m_pMap's authored hotspot-template attrs (0x47/0x48), with literal-string tooltips through AuthoredTooltipText/Enabled (RetailTooltipPresenter) — closes divergence-register row TS-85's last item, gmMapUI::AddMapNote @0x004A1C51. - Structural finding: m_pMap (0x100001EC) is itself authored as a Type-1 BUTTON (the GM click-to-teleport hook at gmMapUI::ListenToElementMessage), and the player/house icons (0x100001ED/EE) are its own NESTED children, not siblings — UiButton.ConsumesDatChildren swallows them from the normally-built tree. Both are re-resolved standalone through the same template resolver the town hotspots use and reattached under m_pMap. House tab (gmHouseUI, HousePageController): mounts the ListBox (0x100001E6) with its authored row template, wired to an empty Lines() source by default — genuinely empty until Slice 4's wire lands, matching retail's own PostInit (no Update call, no static content). 21 new tests (7 MapHousePanelControllerTests, 14 MapPageControllerTests): tab table pairing, close button, town-hotspot count/tooltips, calendar formatter golden values (Frostfell 27/119 P.Y., every HourName incl. AndHalf), player/house marker placement and indoor-gating reproduced against the real fixture via already-tested RadarCoordinates (no re-derivation). Fixture map_house_2100006E_1000018C.json captured via the shared RetailLayoutFixtureGenerator (other 34 fixtures deliberately NOT regenerated — out of scope for this batch, would touch unrelated panels' schema drift). Full solution builds clean; App suite 5391/0 failed/71 skipped (non-live; one earlier flaky streaming failure unrelated to this change, confirmed pre-existing on the branch before these commits). Co-Authored-By: Claude Fable 5 --- .../InteractionRetainedUiComposition.cs | 18 +- src/AcDream.App/Rendering/GameWindow.cs | 3 +- .../UI/Layout/HousePageController.cs | 102 + .../UI/Layout/MapHousePanelController.cs | 180 + src/AcDream.App/UI/Layout/MapLocations.cs | 79 + .../UI/Layout/MapPageController.cs | 355 ++ src/AcDream.App/UI/RetailPanelCatalog.cs | 17 + src/AcDream.App/UI/RetailUiRuntime.cs | 129 + src/AcDream.App/UI/WindowNames.cs | 4 + .../InteractionRetainedUiCompositionTests.cs | 3 +- .../UI/Layout/FixtureLoader.cs | 9 + .../UI/Layout/MapHousePanelControllerTests.cs | 171 + .../UI/Layout/MapPageControllerTests.cs | 191 + .../UI/Layout/RetailLayoutFixtureGenerator.cs | 5 + .../fixtures/map_house_2100006E_1000018C.json | 4602 +++++++++++++++++ 15 files changed, 5865 insertions(+), 3 deletions(-) create mode 100644 src/AcDream.App/UI/Layout/HousePageController.cs create mode 100644 src/AcDream.App/UI/Layout/MapHousePanelController.cs create mode 100644 src/AcDream.App/UI/Layout/MapLocations.cs create mode 100644 src/AcDream.App/UI/Layout/MapPageController.cs create mode 100644 tests/AcDream.App.Tests/UI/Layout/MapHousePanelControllerTests.cs create mode 100644 tests/AcDream.App.Tests/UI/Layout/MapPageControllerTests.cs create mode 100644 tests/AcDream.App.Tests/UI/Layout/fixtures/map_house_2100006E_1000018C.json diff --git a/src/AcDream.App/Composition/InteractionRetainedUiComposition.cs b/src/AcDream.App/Composition/InteractionRetainedUiComposition.cs index 90bbc822..5eb7b80a 100644 --- a/src/AcDream.App/Composition/InteractionRetainedUiComposition.cs +++ b/src/AcDream.App/Composition/InteractionRetainedUiComposition.cs @@ -79,7 +79,15 @@ internal sealed record InteractionRetainedUiDependencies( Func ClientTime, Action Log, AcDream.App.Rendering.Gpu.IGpuDevice GpuDevice, - ICurrentGpuFrameSource GpuFrameSource) + ICurrentGpuFrameSource GpuFrameSource, + // Batch C (Map/House toolbar panel): the same shape as ClientTime above — + // GameWindow's WorldTimeService is a stable for-the-window-lifetime + // service (unlike the per-session entity/world state Radar's deferred + // slots exist for), so a direct closure is enough; no DeferredXSource + // needed. gmMapUI::Update @0x004a1eb0 reads GameTime::current_game_time + // every 5s — MapPageController owns that cadence, this just supplies the + // current reading. + Func CurrentCalendar) { public RuntimeActionState Actions => Runtime.ActionOwner; @@ -970,6 +978,14 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory AllegianceSetUpdateSubscription: on => late.GameRuntime.AllegianceSetUpdateSubscription(on), Trade: d.Runtime.Trade), + // Batch C (overnight hover/UI round): HousePosition/ + // HouseLines/HouseShown are left unwired (their bindings + // default to "no house"/empty/no-op) — the House wire + // groundwork (RuntimeHouseState) lands separately; the + // panel mounts and the Map tab works standalone either way. + MapHouse: new MapHouseRuntimeBindings( + CurrentCalendar: d.CurrentCalendar, + PlayerCellId: () => d.PlayerController.Controller?.CellId ?? 0u), StackSplitQuantity: d.StackSplitQuantity, Plugins: d.UiRegistry, Persistence: persistence, diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 50cc1d79..1be03727 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -1419,7 +1419,8 @@ public sealed class GameWindow : ClientTimerNow, Console.WriteLine, hostInputCamera.GpuDevice, - hostInputCamera.GpuFrameLifetime), + hostInputCamera.GpuFrameLifetime, + () => WorldTime.CurrentCalendar), _retailUiLease, this).Compose( platformResult, diff --git a/src/AcDream.App/UI/Layout/HousePageController.cs b/src/AcDream.App/UI/Layout/HousePageController.cs new file mode 100644 index 00000000..577bcd52 --- /dev/null +++ b/src/AcDream.App/UI/Layout/HousePageController.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; + +namespace AcDream.App.UI.Layout; + +/// +/// Binds the House tab of the retail Map/House panel (gmHouseUI, +/// class id 0x10000025) — 's +/// second page. +/// +/// +/// Retail references: gmHouseUI::PostInit @0x004a2710 resolves ONE +/// UIElement_ListBox (m_pTextBox = 0x100001e6) and registers +/// four notice handlers for wire opcodes 0x0225-0x0228. +/// gmHouseUI::AddHousePanelText @0x004a2810 is +/// UIElement_ListBox::AddItemFromTemplateList(this, 0, nullptr) — +/// live-DAT-confirmed (MapHousePanelSlotProbeTests) as a single +/// UIElement_Text (Type 12) row template at LayoutDesc +/// 0x21000025 element 0x100001e7, no scrollbar authored. The +/// ListBox itself authors ZERO static child rows — the box starts genuinely +/// empty until the first server notice populates it (retail's own +/// PostInit never calls Update/DisplayHouseData). +/// +/// +/// +/// Scope (Batch C, 2026-08-17 recon doc). Of the seven +/// Display* line builders DisplayHouseData calls, only +/// DisplayPurchaseTimeText @0x004a3110's two simple, fully-recovered +/// literal strings ("You may buy another house immediately." / "...after +/// you abandon this one.") are wired end-to-end this session — see +/// RuntimeHouseState.PurchaseAvailabilityText. The other six +/// (BuyPayment/RentPayment/BuyTime/RentTimes/Location/WarningText) only +/// matter once a house is actually owned and are filed as an ISSUES entry +/// rather than guessed at from FPU-mangled decomp. +/// +/// +public sealed class HousePageController +{ + public const uint TextBoxId = 0x100001E6u; + + public sealed record Bindings( + Func> Lines, + // Fires once when the page transitions to visible — the seam that + // sends the outbound HouseQuery (0x021E) so the server has a + // reason to answer with fresh HouseData/HouseStatus. NOT a ported + // retail call site (PostInit never triggers a query) — an acdream + // convention, documented as such (recon doc open item). + Action? OnShown = null); + + private readonly UiTemplateListBox _listBox; + private readonly Bindings _bindings; + private IReadOnlyList _lastLines = Array.Empty(); + + private HousePageController(UiTemplateListBox listBox, Bindings bindings) + { + _listBox = listBox; + _bindings = bindings; + } + + public static HousePageController? Bind(UiElement page, Bindings bindings) + { + ArgumentNullException.ThrowIfNull(page); + ArgumentNullException.ThrowIfNull(bindings); + + if (UiElement.FindDescendant(page, TextBoxId) is not UiTemplateListBox listBox) + { + Console.WriteLine( + $"[D.2b] House tab: ListBox 0x{TextBoxId:X8} not found or not a template list box."); + return null; + } + + var controller = new HousePageController(listBox, bindings); + controller.Refresh(bindings.Lines()); + return controller; + } + + /// Per-frame poll — cheap no-op when the line set hasn't + /// changed (reference-content compare via SequenceEqual, mirroring the + /// other social-panel pages' revision-gated rebuild discipline). + public void Tick() + { + IReadOnlyList lines = _bindings.Lines(); + if (lines.SequenceEqual(_lastLines)) return; + Refresh(lines); + } + + public void OnShown() => _bindings.OnShown?.Invoke(); + + private void Refresh(IReadOnlyList lines) + { + _lastLines = lines; + _listBox.Flush(); + foreach (string line in lines) + { + UiElement? row = _listBox.AddItemFromTemplateList(0); + if (row is UiText text) + text.LinesProvider = () => [new UiText.Line(line, Vector4.One)]; + } + } +} diff --git a/src/AcDream.App/UI/Layout/MapHousePanelController.cs b/src/AcDream.App/UI/Layout/MapHousePanelController.cs new file mode 100644 index 00000000..c55527e7 --- /dev/null +++ b/src/AcDream.App/UI/Layout/MapHousePanelController.cs @@ -0,0 +1,180 @@ +using System; + +namespace AcDream.App.UI.Layout; + +/// +/// Mounts retail's two-tab Map/House panel — LayoutDesc 0x2100006E +/// slot 0x1000018C, +/// id 16. Batch C (overnight hover/UI round, 2026-08-17), built on +/// the / +/// recipe (Type-8 tab host, , +/// per-page scoped controllers). +/// +/// +/// Slot/panelId/button — resolved, not guessed. The FA campaign's own +/// full 16-slot gmPanelUI::SetupChildren dump +/// (docs/research/2026-08-11-fa-panel-structure.md:927-933) already +/// named slot 0x1000018C as "gmMapUI+gmHouseUI pages", panel id 16 — +/// this session's MapHousePanelSlotProbeTests re-confirmed it live. +/// The toolbar button is 0x1000019A (own authored +/// P0x10000029 = 16), one of three currently-ghosted panel buttons +/// (see docs/research/2026-08-17-map-house-recon.md). +/// +/// +/// +/// Tab table — live-DAT-confirmed. +/// button 0x100001F3 -> page 0x100001F6 (Map, DEFAULT), +/// button 0x100001F4 -> page 0x100001F7 (House). The page roots are +/// themselves typed 0x10000026 (gmMapUI) / 0x10000025 +/// (gmHouseUI) in the DAT — has no special +/// case for either id, so they build as generic containers (same as every +/// other unmodeled retail UI class); and +/// find their own signature children by +/// id underneath. +/// +/// +/// +/// Close button: 0x100001F5 (Type 1, top-right at +/// (276,0) 24x25) — same authored position/size as the Social +/// panel's own close button, the established gmPanelUI sibling +/// convention. +/// +/// +public sealed class MapHousePanelController : IRetainedPanelController +{ + public const uint HostLayoutId = 0x2100006Eu; + public const uint SlotElementId = 0x1000018Cu; + + private const uint MapButtonId = 0x100001F3u; + private const uint MapPageId = 0x100001F6u; + private const uint HouseButtonId = 0x100001F4u; + private const uint HousePageId = 0x100001F7u; + private const uint CloseButtonId = 0x100001F5u; + + public sealed record Callbacks( + Action Toggle, + MapPageController.Bindings Map, + HousePageController.Bindings House); + + private readonly UiTabPanel _tabPanel; + private readonly MapPageController? _map; + private readonly HousePageController? _house; + private readonly Action _onActivePageChanged; + private bool _visible; + private bool _disposed; + + public UiElement Root => _tabPanel; + public UiTabPanel TabPanel => _tabPanel; + + private MapHousePanelController( + UiTabPanel tabPanel, MapPageController? map, HousePageController? house) + { + _tabPanel = tabPanel; + _map = map; + _house = house; + + // House's outbound query is a fire-when-shown convenience (see + // HousePageController.Bindings.OnShown's own doc — not a ported + // retail trigger, an acdream one), gated the same "window shown AND + // my tab active" conjunction the social panel's Fellowship/ + // Allegiance pages use for their own declarations. + _onActivePageChanged = (_, _) => FireHouseShownIfActive(); + _tabPanel.ActivePageChanged += _onActivePageChanged; + } + + /// The pre-Build tree + /// was built from — + /// needs it to read m_pMap's own authored int/enum attrs, which + /// only exist on , not the built + /// tree. + public static MapHousePanelController? Bind( + ElementInfo rootInfo, ImportedLayout layout, Callbacks callbacks) + { + ArgumentNullException.ThrowIfNull(rootInfo); + ArgumentNullException.ThrowIfNull(layout); + ArgumentNullException.ThrowIfNull(callbacks); + + if (layout.Root is not UiTabPanel tabPanel) + { + Console.WriteLine( + "[D.2b] MapHousePanelController.Bind: root did not build as UiTabPanel " + + $"(actual type {layout.Root.GetType().Name}) — Map/House panel will not open."); + return null; + } + + if (layout.FindElement(CloseButtonId) is UiButton close) + close.OnClick = callbacks.Toggle; + else + Console.WriteLine( + $"[D.2b] MapHousePanelController: close button 0x{CloseButtonId:X8} not found."); + + UiElement? mapPage = UiElement.FindDescendant(tabPanel, MapPageId); + UiElement? housePage = UiElement.FindDescendant(tabPanel, HousePageId); + + MapPageController? map = null; + if (mapPage is not null) + { + ElementInfo? mapPageInfo = FindInfo(rootInfo, MapPageId); + map = mapPageInfo is null + ? null + : MapPageController.Bind(mapPage, mapPageInfo, callbacks.Map); + } + HousePageController? house = housePage is null + ? null + : HousePageController.Bind(housePage, callbacks.House); + + if (mapPage is null) + Console.WriteLine($"[D.2b] MapHousePanelController: Map page 0x{MapPageId:X8} not found."); + if (housePage is null) + Console.WriteLine($"[D.2b] MapHousePanelController: House page 0x{HousePageId:X8} not found."); + + return new MapHousePanelController(tabPanel, map, house); + } + + public void ActivateTabs() => _tabPanel.ActivateTabBehavior(); + + public bool IsShowingHouse => _tabPanel.ActivePageElementId == HousePageId; + + public void OnShown() + { + _visible = true; + FireHouseShownIfActive(); + } + + public void OnHidden() => _visible = false; + + private void FireHouseShownIfActive() + { + if (_visible && IsShowingHouse) + _house?.OnShown(); + } + + /// Per-frame poll: Map's 5 s-gated refresh (cheap when not due) + /// and House's revision-gated row rebuild. Both stay unconditional + /// (unlike Friends/Squelch's DAT-locked rebuild) — Map's own cadence + /// gate and House's list compare are both cheap even while hidden. + public void Tick(double deltaSeconds) + { + if (_disposed) return; + _map?.Tick(deltaSeconds); + _house?.Tick(); + } + + public void Dispose() + { + if (_disposed) return; + _disposed = true; + _tabPanel.ActivePageChanged -= _onActivePageChanged; + } + + private static ElementInfo? FindInfo(ElementInfo info, uint id) + { + if (info.Id == id) return info; + foreach (ElementInfo child in info.Children) + { + ElementInfo? found = FindInfo(child, id); + if (found is not null) return found; + } + return null; + } +} diff --git a/src/AcDream.App/UI/Layout/MapLocations.cs b/src/AcDream.App/UI/Layout/MapLocations.cs new file mode 100644 index 00000000..47198cf0 --- /dev/null +++ b/src/AcDream.App/UI/Layout/MapLocations.cs @@ -0,0 +1,79 @@ +namespace AcDream.App.UI.Layout; + +/// +/// One retail map hotspot rect + rollover name. Mirrors +/// gmMapUI::LocationRolloverInfo (acclient.h:55686): X/Y/Width/ +/// Height are direct pixel offsets within m_pMap (no coordinate +/// transform — gmMapUI::AddMapNote @0x004a1bb0 passes them straight to +/// MoveTo/ResizeTo), and Name is the literal tooltip text +/// (StringInfo::SetLiteralValue, not a DAT string-table lookup). +/// +public readonly record struct MapLocation(int X, int Y, int Width, int Height, string Name); + +/// +/// Verbatim port of retail's static s_rgLocations[0x35] table +/// (docs/research/named-retail/acclient_2013_pseudo_c.txt:977225-977651), +/// consumed by gmMapUI::PostInit @0x004a1c70 to place the 53 town +/// hotspots on the Map tab. Ported verbatim, in original index order — +/// do not resort or "clean up"; the order is not semantically meaningful +/// but the values must match byte-for-byte. +/// +public static class MapLocations +{ + public static readonly MapLocation[] All = + { + new(0xb2, 0x14, 0xb, 0xc, "Aerlinthe Island"), + new(0x12, 0x4a, 0x5, 0x5, "Ahurenga"), + new(0x8d, 0xa6, 0x7, 0x6, "Al-Arqas"), + new(0x81, 0x79, 0x7, 0x6, "Al-Jalima"), + new(0xbe, 0x58, 0x9, 0x8, "Arwic"), + new(0x13, 0xc9, 0x7, 0x6, "Ayan Baqur"), + new(0xc8, 0xbe, 0x7, 0x6, "Baishi"), + new(0xb8, 0x35, 0x5, 0x5, "Bandit Castle"), + new(0x22, 0x54, 0x5, 0x5, "Bluespire"), + new(0x2c, 0xeb, 0x5, 0x5, "Candeth Keep"), + new(0xb4, 0x61, 0x9, 0x8, "Cragstone"), + new(0x5b, 0x66, 0x5, 0x5, "Danby's Outpost"), + new(0xd3, 0x8a, 0x9, 0x8, "Dryreach"), + new(0xc7, 0x6a, 0x9, 0x8, "Eastham"), + new(0x38, 0xd, 0x5, 0x5, "Fiun Outpost"), + new(0x25, 0x7f, 0x9, 0x8, "Fort Tethana"), + new(0x9c, 0x5e, 0x9, 0x8, "Glenden Wood"), + new(0x2b, 0x4f, 0x5, 0x5, "Greenspire"), + new(0xe0, 0xb1, 0x7, 0x6, "Hebian-to"), + new(0xa4, 0x4d, 0x9, 0x8, "Holtburg"), + new(0xb6, 0xe6, 0x7, 0x6, "Kara"), + new(0x9b, 0xb9, 0x7, 0x6, "Khayyaban"), + new(0xe0, 0xda, 0x7, 0x6, "Kryst"), + new(0xd4, 0xc3, 0x7, 0x6, "Lin"), + new(0x9f, 0xe0, 0x5, 0x5, "Linvak Tukal"), + new(0xb9, 0x7e, 0x9, 0x8, "Lytelthorpe"), + new(0xeb, 0xdc, 0x7, 0x6, "MacNiall's Freehold"), + new(0xdf, 0xcb, 0x7, 0x6, "Mayoi"), + new(0x8d, 0x35, 0x5, 0x5, "Mt Esper-Crater Village"), + new(0xe0, 0xbf, 0x7, 0x6, "Nanto"), + new(0x8e, 0x2e, 0x5, 0x5, "Neydisa"), + new(0xf0, 0x80, 0x5, 0x5, "Oolutanga's Refuge"), + new(0x4a, 0x4f, 0x5, 0x5, "Plateau Village"), + new(0x94, 0xda, 0x7, 0x6, "Qalaba'r"), + new(0x1a, 0x53, 0x5, 0x5, "Redspire"), + new(0xc1, 0x72, 0x9, 0x8, "Rithwic"), + new(0x92, 0x85, 0x7, 0x6, "Samsur"), + new(0x32, 0x2a, 0x5, 0x5, "Sanamar"), + new(0xc3, 0xa3, 0x7, 0x6, "Sawato"), + new(0xd5, 0xab, 0x7, 0x6, "Shoushi"), + new(0x29, 0x19, 0x5, 0x5, "Silyun"), + new(0x6, 0xef, 0xf, 0x10, "Singularity Caul Island"), + new(0x64, 0x30, 0x5, 0x5, "Stonehold"), + new(0x20, 0x4c, 0x5, 0x5, "Timaru"), + new(0xef, 0xa3, 0x7, 0x6, "Tou-Tou"), + new(0x83, 0x94, 0x7, 0x6, "Tufa"), + new(0x70, 0xf4, 0x5, 0x5, "Ulgrim's Island"), + new(0x9f, 0xa0, 0x7, 0x6, "Uziz"), + new(0x3f, 0xcb, 0x7, 0x6, "Wai Jhou"), + new(0x90, 0xb5, 0x7, 0x6, "Xarabydun"), + new(0xaf, 0x91, 0x7, 0x6, "Yanshi"), + new(0x79, 0x9c, 0x7, 0x6, "Yaraq"), + new(0x7b, 0x70, 0x7, 0x6, "Zaikhal"), + }; +} diff --git a/src/AcDream.App/UI/Layout/MapPageController.cs b/src/AcDream.App/UI/Layout/MapPageController.cs new file mode 100644 index 00000000..d52f0cf1 --- /dev/null +++ b/src/AcDream.App/UI/Layout/MapPageController.cs @@ -0,0 +1,355 @@ +using System; +using System.Collections.Generic; +using AcDream.Core.Net.Messages; +using AcDream.Core.Ui; +using AcDream.Core.World; + +namespace AcDream.App.UI.Layout; + +/// +/// Binds the Map tab of the retail Map/House panel (gmMapUI, class id +/// 0x10000026) — 's default page. +/// +/// +/// Retail references: gmMapUI::PostInit @0x004a1c70 (child +/// resolution + hotspot template setup), gmMapUI::Update @0x004a1eb0 +/// (5 s refresh cadence — date/time text, coordinate readout, both +/// markers), gmMapUI::PlaceMarkerOnMap @0x004a18b0 (marker centering +/// math), gmMapUI::AddMapNote @0x004a1bb0 (town hotspot +/// instantiation + literal-string tooltip). Live-DAT byte values confirmed +/// by MapHousePanelSlotProbeTests: marker area +/// (6,8)-(247,258), hotspot template element 0x100001F0 in +/// LayoutDesc 0x21000026. +/// +/// +/// +/// Coordinate math reuses (already a byte- +/// exact port of the same CPlayerSystem::InqPlayerCoords @0x00560090 +/// formula the radar's own coordinate strip uses) rather than re-deriving +/// it — see the recon doc's "no re-port needed" note. +/// +/// +public sealed class MapPageController +{ + // gmMapUI PostInit signature children (pc:171993). + public const uint DateTimeTextId = 0x100001EBu; + public const uint MapWidgetId = 0x100001ECu; + public const uint PlayerIconId = 0x100001EDu; + public const uint HouseIconId = 0x100001EEu; + public const uint CoordinateTextId = 0x100001EFu; + + // m_pMap's own authored attrs (gmMapUI::PostInit @0x004a1c70). + private const uint MarkerAreaX0Attr = 0x1000004Eu; + private const uint MarkerAreaX1Attr = 0x1000004Fu; + private const uint MarkerAreaY0Attr = 0x10000050u; + private const uint MarkerAreaY1Attr = 0x10000051u; + private const uint HotspotTemplateElementAttr = 0x47u; + private const uint HotspotTemplateLayoutAttr = 0x48u; + + /// Retail's own 5 s tick cadence (gmMapUI::Update's + /// m_nextUpdate = Timer::cur_time + 5.0). + public const double RefreshIntervalSeconds = 5.0; + + public sealed record Bindings( + Func CurrentCalendar, + Func PlayerCellId, + // Slice 4 wires the real RuntimeHouseState-backed callback; defaults + // to "no house" (matching retail's Position::IsValid == false + // branch — the house icon starts/stays hidden) so this page works + // standalone before that lands. + Func HousePosition, + Func TemplateResolver); + + private readonly UiElement? _dateTimeText; + private readonly UiElement? _map; + private readonly UiElement? _playerIcon; + private readonly UiElement? _houseIcon; + private readonly UiElement? _coordinateText; + private readonly Bindings _bindings; + private readonly int _markerX0, _markerX1, _markerY0, _markerY1; + + private double _nextUpdateSeconds; + private string? _lastDateTimeText; + private string? _lastCoordinateText; + + private MapPageController( + UiElement? dateTimeText, + UiElement map, + UiElement? playerIcon, + UiElement? houseIcon, + UiElement? coordinateText, + (int X0, int X1, int Y0, int Y1) markerArea, + Bindings bindings) + { + _dateTimeText = dateTimeText; + _map = map; + _playerIcon = playerIcon; + _houseIcon = houseIcon; + _coordinateText = coordinateText; + _bindings = bindings; + (_markerX0, _markerX1, _markerY0, _markerY1) = markerArea; + } + + /// + /// Binds an already-built page root ( + /// resolves the page via the panel's tab table). Reads m_pMap's + /// own marker-area rect straight from the ORIGINAL + /// (post-Build widgets don't carry authored int attrs), instantiates the + /// 53 town hotspots once, and returns a controller ready for + /// per-frame polling. + /// + /// + /// Live-DAT structural finding (MapHousePanelSlotProbeTests' follow-up + /// dump): m_pMap (0x100001EC) is itself authored as a + /// Type-1 BUTTON (the GM click-to-teleport feature at + /// gmMapUI::ListenToElementMessage @0x004a2350 idMessage + /// 0x1c), and the player/house icons (0x100001ED/ + /// 0x100001EE) are authored as ITS OWN nested children, not + /// siblings. swallows a + /// button's dat children as skin/label parts, so they never appear in + /// the normally-built tree — + /// against the page root always returns null for them. They're + /// resolved the SAME way the town hotspot template is: re-imported + /// standalone via 's + /// against the panel's own host + /// LayoutDesc, then attached under m_pMap directly — their + /// authored local position is irrelevant since + /// overwrites it every refresh. + /// + /// + public static MapPageController? Bind(UiElement page, ElementInfo pageInfo, Bindings bindings) + { + ArgumentNullException.ThrowIfNull(page); + ArgumentNullException.ThrowIfNull(pageInfo); + ArgumentNullException.ThrowIfNull(bindings); + + UiElement? map = UiElement.FindDescendant(page, MapWidgetId); + if (map is null) + { + Console.WriteLine($"[D.2b] Map tab: m_pMap 0x{MapWidgetId:X8} not found — Map tab will not populate."); + return null; + } + + ElementInfo? mapInfo = FindInfo(pageInfo, MapWidgetId); + var markerArea = (X0: 0, X1: 0, Y0: 0, Y1: 0); + if (mapInfo is not null) + { + int x0 = mapInfo.TryGetEffectiveProperty(MarkerAreaX0Attr, out var vx0) ? vx0.IntegerValue : 0; + int x1 = mapInfo.TryGetEffectiveProperty(MarkerAreaX1Attr, out var vx1) ? vx1.IntegerValue : 0; + int y0 = mapInfo.TryGetEffectiveProperty(MarkerAreaY0Attr, out var vy0) ? vy0.IntegerValue : 0; + int y1 = mapInfo.TryGetEffectiveProperty(MarkerAreaY1Attr, out var vy1) ? vy1.IntegerValue : 0; + markerArea = (x0, x1, y0, y1); + } + + UiElement? playerIcon = ResolveSwallowedIcon(map, bindings.TemplateResolver, PlayerIconId); + UiElement? houseIcon = ResolveSwallowedIcon(map, bindings.TemplateResolver, HouseIconId); + + var controller = new MapPageController( + UiElement.FindDescendant(page, DateTimeTextId), + map, + playerIcon, + houseIcon, + UiElement.FindDescendant(page, CoordinateTextId), + markerArea, + bindings); + + controller.BuildTownMarkers(mapInfo, bindings.TemplateResolver); + + // UiText is a pull-based scrollback widget (LinesProvider), not an + // imperative SetText target — wire the provider ONCE here to read + // the mutable backing field Refresh() updates, matching the + // established pattern (e.g. CharacterStatController's xpValue). + if (controller._dateTimeText is UiText dateTimeText) + dateTimeText.LinesProvider = () => ToLines(controller._lastDateTimeText, dateTimeText.DefaultColor); + if (controller._coordinateText is UiText coordinateText) + coordinateText.LinesProvider = () => ToLines(controller._lastCoordinateText, coordinateText.DefaultColor); + + // Immediate first refresh rather than waiting out the first 5 s tick. + controller.Refresh(); + controller._nextUpdateSeconds = RefreshIntervalSeconds; + return controller; + } + + /// Re-resolves one of m_pMap's button-swallowed nested + /// icon children standalone (see 's own doc) and + /// attaches it under . Starts hidden — the first + /// call (from ) decides real + /// visibility. + private static UiElement? ResolveSwallowedIcon( + UiElement map, Func templateResolver, uint iconElementId) + { + UiElement? icon = templateResolver(MapHousePanelController.HostLayoutId, iconElementId); + if (icon is null) + { + Console.WriteLine( + $"[D.2b] Map tab: icon 0x{iconElementId:X8} did not resolve — it will not be shown."); + return null; + } + icon.Visible = false; + map.AddChild(icon); + return icon; + } + + private static IReadOnlyList ToLines(string? text, System.Numerics.Vector4 color) + { + if (string.IsNullOrEmpty(text)) return Array.Empty(); + string[] parts = text.Split('\n'); + var lines = new UiText.Line[parts.Length]; + for (int i = 0; i < parts.Length; i++) + lines[i] = new UiText.Line(parts[i], color); + return lines; + } + + /// + /// Instantiates the 53 static town hotspots (gmMapUI::AddMapNote) + /// from m_pMap's own 0x47/0x48 template attrs. A + /// missing template (either attr absent, or the DAT install lacks the + /// referenced LayoutDesc/element) leaves the map usable without + /// hotspots rather than failing the whole page — matches retail's own + /// null-guarded if (eax_10 != 0) before the loop. + /// + private void BuildTownMarkers(ElementInfo? mapInfo, Func templateResolver) + { + if (mapInfo is null) return; + if (!mapInfo.TryGetEffectiveProperty(HotspotTemplateElementAttr, out var templateElement)) return; + if (!mapInfo.TryGetEffectiveProperty(HotspotTemplateLayoutAttr, out var templateLayout)) return; + if (templateLayout.UnsignedValue == 0) return; + + foreach (MapLocation loc in MapLocations.All) + { + UiElement? marker = templateResolver( + (uint)templateLayout.UnsignedValue, (uint)templateElement.UnsignedValue); + if (marker is null) continue; + + marker.Left = loc.X; + marker.Top = loc.Y; + marker.Width = loc.Width; + marker.Height = loc.Height; + // gmMapUI::AddMapNote's UIElement::SetTooltip call — a LITERAL + // string (StringInfo::SetLiteralValue), not a DAT table lookup. + // AuthoredTooltipText/Enabled is the exact seam + // RetailTooltipPresenter already serves (closes register row + // TS-85's last item, gmMapUI::AddMapNote @0x004A1C51). + marker.AuthoredTooltipText = loc.Name; + marker.AuthoredTooltipEnabled = true; + _map!.AddChild(marker); + } + } + + /// Per-frame poll, accumulating wall-clock deltas + /// ('s own shape) into retail's 5 s + /// cadence — same net effect as Timer::cur_time comparison + /// without needing a separate absolute clock dependency. + public void Tick(double deltaSeconds) + { + _nextUpdateSeconds -= deltaSeconds; + if (_nextUpdateSeconds > 0) return; + _nextUpdateSeconds = RefreshIntervalSeconds; + Refresh(); + } + + private void Refresh() + { + RefreshDateTime(); + RefreshCoordinatesAndPlayerMarker(); + RefreshHouseMarker(); + } + + private void RefreshDateTime() + { + if (_dateTimeText is null) return; + DerethDateTime.Calendar calendar = _bindings.CurrentCalendar(); + string text = FormatDateTime(calendar); + // gmMapUI::Update only calls SetText when the string actually + // differs (wcscmp change-detect), not a re-stamp every 5s. The + // LinesProvider wired in Bind() re-reads this field lazily, so + // updating it IS the display update. + _lastDateTimeText = text; + } + + /// + /// "Date: %s\nTime: %s" (gmMapUI::Update's sprintf shape, + /// fed by GameTime::GetDateTimeString @0x005a6530). Month names + /// already match retail display text 1:1 + /// (); hour names need the + /// "AndHalf" suffix rewritten to "-and-Half". + /// + internal static string FormatDateTime(DerethDateTime.Calendar calendar) => + $"Date: {calendar.Month} {calendar.Day}, {calendar.Year} P.Y.\nTime: {FormatHourName(calendar.Hour)}"; + + private static string FormatHourName(DerethDateTime.HourName hour) + { + string name = hour.ToString(); + const string suffix = "AndHalf"; + return name.EndsWith(suffix, StringComparison.Ordinal) + ? string.Concat(name.AsSpan(0, name.Length - suffix.Length), "-and-Half") + : name; + } + + private void RefreshCoordinatesAndPlayerMarker() + { + if (_coordinateText is null && _playerIcon is null) return; + + bool outside = RadarCoordinates.TryFromCell(_bindings.PlayerCellId(), out RadarCoordinates coords); + if (outside) + { + _lastCoordinateText = coords.CombinedText; + PlaceMarker(_playerIcon, coords.X, coords.Y); + } + else + { + // Indoors: retail clears the coordinate text and hides the + // player marker (gmMapUI::Update's else branch, + // m_pPlayerLocationIcon->SetVisible(0)). + _lastCoordinateText = string.Empty; + if (_playerIcon is not null) + _playerIcon.Visible = false; + } + } + + private void RefreshHouseMarker() + { + if (_houseIcon is null) return; + + CreateObject.ServerPosition? housePosition = _bindings.HousePosition(); + if (housePosition is null) + { + _houseIcon.Visible = false; + return; + } + + // Position::get_outside_cell_id(&m_HousePosition) -> gid_to_lcoord + // -> the SAME (v-0x400)*0.1+0.5 transform PlaceMarkerOnMap's player + // branch uses (gmMapUI::Update @0x004a22a6-f6). + if (!RadarCoordinates.TryFromCell(housePosition.Value.LandblockId, out RadarCoordinates coords)) + { + _houseIcon.Visible = false; + return; + } + + PlaceMarker(_houseIcon, coords.X, coords.Y); + } + + /// + /// gmMapUI::PlaceMarkerOnMap @0x004a18b0: center the icon at + /// (markerAreaX0 + x, markerAreaY0 + y), then show it. + /// + private void PlaceMarker(UiElement? icon, double x, double y) + { + if (icon is null) return; + icon.Left = _markerX0 + (float)x - icon.Width / 2f; + icon.Top = _markerY0 + (float)y - icon.Height / 2f; + icon.Visible = true; + } + + private static ElementInfo? FindInfo(ElementInfo info, uint id) + { + if (info.Id == id) return info; + foreach (ElementInfo child in info.Children) + { + ElementInfo? found = FindInfo(child, id); + if (found is not null) return found; + } + return null; + } +} diff --git a/src/AcDream.App/UI/RetailPanelCatalog.cs b/src/AcDream.App/UI/RetailPanelCatalog.cs index 4b8eee25..6b9d6e0b 100644 --- a/src/AcDream.App/UI/RetailPanelCatalog.cs +++ b/src/AcDream.App/UI/RetailPanelCatalog.cs @@ -42,6 +42,21 @@ public static class RetailPanelCatalog /// public const uint SocialPanel = 12u; + /// + /// Batch C (overnight hover/UI round, 2026-08-17): the two-tab Map/House + /// panel's gmPanelUI slot key — byte-verified from the live + /// installed DATs (host 0x2100006E slot 0x1000018C's own + /// authored 0x10000029 = 16, and the toolbar Map/House button + /// 0x1000019A's own authored 0x10000029 = 16, + /// MapHousePanelSlotProbeTests). Already independently named by + /// the FA campaign's full 16-slot dump + /// (docs/research/2026-08-11-fa-panel-structure.md:927-933, + /// "gmMapUI+gmHouseUI pages"). Unlike , a real + /// toolbar button opens this one — it is in BOTH + /// and . + /// + public const uint MapHouse = 16u; + private static readonly (uint PanelId, string WindowName)[] Mounted = { (CharacterInformation, WindowNames.CharacterInformation), @@ -55,6 +70,7 @@ public static class RetailPanelCatalog (Vitae, WindowNames.Vitae), (Options, WindowNames.Options), (SocialPanel, WindowNames.SocialPanel), + (MapHouse, WindowNames.MapHouse), }; private static readonly (uint PanelId, string WindowName)[] Toolbar = @@ -63,6 +79,7 @@ public static class RetailPanelCatalog (Character, WindowNames.Character), (Magic, WindowNames.Spellbook), (Options, WindowNames.Options), + (MapHouse, WindowNames.MapHouse), }; public static IReadOnlyList<(uint PanelId, string WindowName)> MountedPanels => Mounted; diff --git a/src/AcDream.App/UI/RetailUiRuntime.cs b/src/AcDream.App/UI/RetailUiRuntime.cs index 64304dfd..a42d1441 100644 --- a/src/AcDream.App/UI/RetailUiRuntime.cs +++ b/src/AcDream.App/UI/RetailUiRuntime.cs @@ -289,6 +289,20 @@ public sealed record SocialRuntimeBindings( // Trailing/optional per the established compatibility convention. AcDream.Runtime.Gameplay.IRuntimeTradeView? Trade = null); +/// +/// Batch C (overnight hover/UI round, 2026-08-17): bindings for the +/// two-tab Map/House panel. defaults to +/// "no house" and to empty when the caller doesn't +/// wire the House wire groundwork — the panel still mounts and the Map tab +/// still works standalone. +/// +public sealed record MapHouseRuntimeBindings( + Func CurrentCalendar, + Func PlayerCellId, + Func? HousePosition = null, + Func>? HouseLines = null, + Action? HouseShown = null); + public sealed record InventoryRuntimeBindings( ClientObjectTable Objects, Func PlayerGuid, @@ -451,6 +465,7 @@ public sealed record RetailUiRuntimeBindings( AppraisalRuntimeBindings Appraisal, OptionsRuntimeBindings Options, SocialRuntimeBindings Social, + MapHouseRuntimeBindings MapHouse, StackSplitQuantityState StackSplitQuantity, BufferedUiRegistry? Plugins, RetailUiPersistenceBindings? Persistence, @@ -542,6 +557,7 @@ public sealed class RetailUiRuntime : IDisposable MountDialogFactory(); MountTooltipPresenter(); MountSocialPanel(); + MountMapHousePanel(); MountCharacter(); MountPlugins(); MountInventory(); @@ -650,6 +666,7 @@ public sealed class RetailUiRuntime : IDisposable public VendorUiController? VendorController { get; private set; } public OptionsPanelController? OptionsPanelController { get; private set; } public SocialPanelController? SocialPanelController { get; private set; } + public MapHousePanelController? MapHousePanelController { get; private set; } internal CharacterManagementUiController? CharacterManagementController => _characterManagementMount?.Controller; internal CharacterCreationUiController? CharacterCreationController => @@ -822,6 +839,7 @@ public sealed class RetailUiRuntime : IDisposable SelectedObjectController?.Tick(deltaSeconds); ExternalContainerController?.Tick(); SocialPanelController?.Tick(); + MapHousePanelController?.Tick(deltaSeconds); _itemCooldownController?.Tick(); _characterManagementMount?.Tick(); CharacterManagementController?.Tick(); @@ -3256,6 +3274,117 @@ public sealed class RetailUiRuntime : IDisposable Console.WriteLine("[UI] retail social panel from LayoutDesc importer (0x2100006E slot 0x1000018F)."); } + /// + /// Batch C (overnight hover/UI round, 2026-08-17): the two-tab Map/House + /// panel — host 0x2100006E slot 0x1000018C, + /// id 16. Same import/Build/Bind + /// recipe as . The House tab's ListBox rows + /// resolve through its own authored template directly via + /// (a FIXED + /// single template, unlike Friends/Squelch/Fellowship's live-roster + /// row families) — the below + /// serves only the Map tab's per-town hotspot template. + /// + private void MountMapHousePanel() + { + ElementInfo? rootInfo; + ImportedLayout? layout; + var strings = new DatStringResolver(_bindings.Assets.Dats); + lock (_bindings.Assets.DatLock) + { + rootInfo = LayoutImporter.ImportInfos( + _bindings.Assets.Dats, + Layout.MapHousePanelController.HostLayoutId, + Layout.MapHousePanelController.SlotElementId); + layout = rootInfo is null + ? null + : LayoutImporter.Build( + rootInfo, + _bindings.Assets.ResolveSprite, + _bindings.Assets.DefaultFont, + _bindings.Assets.ResolveFont, + strings.Resolve); + } + if (rootInfo is null || layout is null) + { + Console.WriteLine("[UI] Map/House panel: LayoutDesc 0x2100006E slot 0x1000018C not found."); + return; + } + + // The town-hotspot template (m_pMap's own 0x47/0x48 attrs) is + // resolved once and cached — same "resolve the ElementInfo once, + // Build a fresh UiElement per call" shape RowTemplateResolver uses + // for the social panel's row families. + var hotspotTemplate = new Layout.RowTemplateResolver( + (templateLayoutId, templateElementId) => LayoutImporter.ImportInfos( + _bindings.Assets.Dats, templateLayoutId, templateElementId), + info => LayoutImporter.Build( + info, + _bindings.Assets.ResolveSprite, + _bindings.Assets.DefaultFont, + _bindings.Assets.ResolveFont).Root); + UiElement? ResolveHotspotTemplate(uint templateLayoutId, uint templateElementId) + { + lock (_bindings.Assets.DatLock) + return hotspotTemplate.Resolve(templateLayoutId, templateElementId); + } + + MapHouseRuntimeBindings mh = _bindings.MapHouse; + var callbacks = new Layout.MapHousePanelController.Callbacks( + Toggle: () => ToggleWindow(WindowNames.MapHouse), + Map: new Layout.MapPageController.Bindings( + CurrentCalendar: mh.CurrentCalendar, + PlayerCellId: mh.PlayerCellId, + HousePosition: mh.HousePosition ?? (static () => null), + TemplateResolver: ResolveHotspotTemplate), + House: new Layout.HousePageController.Bindings( + Lines: mh.HouseLines ?? (static () => Array.Empty()), + OnShown: mh.HouseShown)); + + Layout.MapHousePanelController? controller; + lock (_bindings.Assets.DatLock) + controller = Layout.MapHousePanelController.Bind(rootInfo, layout, callbacks); + if (controller is null) + { + Console.WriteLine("[UI] Map/House panel: required root did not build as UiTabPanel."); + return; + } + + controller.ActivateTabs(); + MapHousePanelController = controller; + + RetailWindowHandle handle = RetailWindowFrame.Mount( + Host.Root, + controller.Root, + _bindings.Assets.ResolveSprite, + new RetailWindowFrame.Options + { + WindowName = WindowNames.MapHouse, + Chrome = RetailWindowChrome.NineSlice, + Left = 240f, + Top = 160f, + Visible = false, + ResizeX = false, + ResizeY = false, + ConstrainDragToParent = true, + ConstrainResizeToParent = true, + ContentAnchors = AnchorEdges.Left | AnchorEdges.Top + | AnchorEdges.Right | AnchorEdges.Bottom, + ContentClickThrough = false, + DrawChromeCenter = !AuthorsFullPanelCenter(rootInfo), + Controller = controller, + }); + _panelUi.RegisterMainPanel( + RetailPanelCatalog.MapHouse, + WindowNames.MapHouse, + handle, + rootInfo.TryGetEffectiveBool( + RetailPanelUiController.RestorePreviousPropertyId, + out bool restorePrevious) + && restorePrevious); + Console.WriteLine("[UI] retail Map/House panel from LayoutDesc importer (0x2100006E slot 0x1000018C)."); + } + private void MountDialogFactory() { if (DialogFactory is not null) diff --git a/src/AcDream.App/UI/WindowNames.cs b/src/AcDream.App/UI/WindowNames.cs index 42da88bf..0f741703 100644 --- a/src/AcDream.App/UI/WindowNames.cs +++ b/src/AcDream.App/UI/WindowNames.cs @@ -34,4 +34,8 @@ public static class WindowNames /// Campaign FA slice FA3: the four-tab Friends/Allegiance/ /// Fellowship/Squelch panel (). public const string SocialPanel = "social-panel"; + + /// Batch C (overnight hover/UI round): the two-tab Map/House + /// panel (). + public const string MapHouse = "map-house"; } diff --git a/tests/AcDream.App.Tests/Composition/InteractionRetainedUiCompositionTests.cs b/tests/AcDream.App.Tests/Composition/InteractionRetainedUiCompositionTests.cs index e8648e14..119b997a 100644 --- a/tests/AcDream.App.Tests/Composition/InteractionRetainedUiCompositionTests.cs +++ b/tests/AcDream.App.Tests/Composition/InteractionRetainedUiCompositionTests.cs @@ -257,7 +257,8 @@ public sealed class InteractionRetainedUiCompositionTests ClientTime: static () => 0d, Log: static _ => { }, GpuDevice: null!, - GpuFrameSource: null!); + GpuFrameSource: null!, + CurrentCalendar: static () => default); } public InteractionRetainedUiDependencies Dependencies { get; } diff --git a/tests/AcDream.App.Tests/UI/Layout/FixtureLoader.cs b/tests/AcDream.App.Tests/UI/Layout/FixtureLoader.cs index 29cd5e61..c6863bad 100644 --- a/tests/AcDream.App.Tests/UI/Layout/FixtureLoader.cs +++ b/tests/AcDream.App.Tests/UI/Layout/FixtureLoader.cs @@ -272,6 +272,15 @@ public static class FixtureLoader public static ElementInfo LoadSocialPanelHostInfos() => LoadInfos("social_panel_2100006E_1000018F.json"); + /// The two-tab Map/House panel host slot 0x1000018C — + /// Batch C (overnight hover/UI round). This is what + /// actually mounts. + public static ImportedLayout LoadMapHouseHost() + => LayoutImporter.Build(LoadMapHouseHostInfos(), _ => (0u, 0, 0), null); + + public static ElementInfo LoadMapHouseHostInfos() + => LoadInfos("map_house_2100006E_1000018C.json"); + /// Configure Keyboard screen LayoutDesc 0x21000009 (standalone /// import — its own separate full-screen window, NOT nested under the Options /// panel's 0x2100006E host — Campaign OP slice OP8). diff --git a/tests/AcDream.App.Tests/UI/Layout/MapHousePanelControllerTests.cs b/tests/AcDream.App.Tests/UI/Layout/MapHousePanelControllerTests.cs new file mode 100644 index 00000000..2c91ef6f --- /dev/null +++ b/tests/AcDream.App.Tests/UI/Layout/MapHousePanelControllerTests.cs @@ -0,0 +1,171 @@ +using System.Linq; +using AcDream.App.UI; +using AcDream.App.UI.Layout; +using AcDream.Core.Net.Messages; +using AcDream.Core.World; + +namespace AcDream.App.Tests.UI.Layout; + +/// +/// Controller-level tests for against +/// the committed map_house_2100006E_1000018C.json fixture (Batch C, +/// overnight hover/UI round) — the SAME LayoutImporter.ImportInfos(dats, +/// 0x2100006Eu, 0x1000018Cu) catalog import +/// performs against real +/// DATs. No DAT access, no live runtime — dat-free per the established +/// pattern. +/// +public sealed class MapHousePanelControllerTests +{ + /// Serves BOTH the town-hotspot template (any (layoutId, + /// elementId) pair not the player/house icon ids) and the two icons + /// re-resolves standalone + /// (m_pMap's own button-swallowed children) — a real + /// would set DatElementId the + /// same way does, so tests that need + /// to find these icons back by id after the fact need it too. + private static UiElement? FakeHotspotTemplate(uint layoutId, uint elementId) + => new UiText { Width = 10f, Height = 10f, DatElementId = elementId }; + + private static MapHousePanelController.Callbacks MakeCallbacks( + List? calls = null, + Func? currentCalendar = null, + Func? playerCellId = null, + Func? housePosition = null, + Func>? houseLines = null) + { + calls ??= new List(); + return new MapHousePanelController.Callbacks( + Toggle: () => calls.Add("toggle"), + Map: new MapPageController.Bindings( + CurrentCalendar: currentCalendar ?? (static () => default), + PlayerCellId: playerCellId ?? (static () => 0u), + HousePosition: housePosition ?? (static () => null), + TemplateResolver: FakeHotspotTemplate), + House: new HousePageController.Bindings( + Lines: houseLines ?? (static () => Array.Empty()), + OnShown: () => calls.Add("house-shown"))); + } + + [Fact] + public void Bind_RootBuildsAsUiTabPanel() + { + ElementInfo rootInfo = FixtureLoader.LoadMapHouseHostInfos(); + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + + MapHousePanelController? controller = + MapHousePanelController.Bind(rootInfo, layout, MakeCallbacks()); + + Assert.NotNull(controller); + Assert.IsType(controller!.Root); + } + + /// Pins the authored tab table exactly as read from the live + /// DATs (MapHousePanelSlotProbeTests): two entries, Map is the + /// sole default. + [Fact] + public void TabTable_MatchesLiveDatPairing_MapIsDefault() + { + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + var tabs = Assert.IsType(layout.Root); + + Assert.Equal(2, tabs.Tabs.Count); + Assert.Contains(tabs.Tabs, e => + e.ButtonElementId == 0x100001F3u && e.PageElementId == 0x100001F6u && e.IsDefault); + Assert.Contains(tabs.Tabs, e => + e.ButtonElementId == 0x100001F4u && e.PageElementId == 0x100001F7u && !e.IsDefault); + Assert.Single(tabs.Tabs, e => e.IsDefault); + } + + [Fact] + public void Bind_Succeeds_AndActivateTabs_SelectsMapByDefault() + { + ElementInfo rootInfo = FixtureLoader.LoadMapHouseHostInfos(); + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + MapHousePanelController? controller = + MapHousePanelController.Bind(rootInfo, layout, MakeCallbacks()); + + Assert.NotNull(controller); + controller!.ActivateTabs(); + + Assert.Empty(controller.TabPanel.UnresolvedEntries); + Assert.False(controller.IsShowingHouse); + } + + [Fact] + public void SwitchToHouse_FiresOnShown_OnlyWhenPanelIsVisible() + { + ElementInfo rootInfo = FixtureLoader.LoadMapHouseHostInfos(); + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + var calls = new List(); + MapHousePanelController? controller = + MapHousePanelController.Bind(rootInfo, layout, MakeCallbacks(calls)); + Assert.NotNull(controller); + controller!.ActivateTabs(); + + // Not visible yet: switching tabs must not fire OnShown. + controller.TabPanel.SwitchTo(0x100001F7u); + Assert.DoesNotContain("house-shown", calls); + + controller.OnShown(); + Assert.Contains("house-shown", calls); + } + + [Fact] + public void CloseButton_InvokesToggle() + { + ElementInfo rootInfo = FixtureLoader.LoadMapHouseHostInfos(); + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + var calls = new List(); + MapHousePanelController? controller = + MapHousePanelController.Bind(rootInfo, layout, MakeCallbacks(calls)); + Assert.NotNull(controller); + + UiElement? close = layout.FindElement(0x100001F5u); + Assert.IsType(close); + ((UiButton)close!).OnClick?.Invoke(); + + Assert.Contains("toggle", calls); + } + + [Fact] + public void Bind_BuildsAll53TownHotspots_UnderTheMapWidget() + { + ElementInfo rootInfo = FixtureLoader.LoadMapHouseHostInfos(); + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + MapHousePanelController? controller = + MapHousePanelController.Bind(rootInfo, layout, MakeCallbacks()); + Assert.NotNull(controller); + + UiElement? map = UiElement.FindDescendant(controller!.Root, MapPageController.MapWidgetId); + Assert.NotNull(map); + // m_pMap's own children are the player/house icons (re-resolved + // standalone — see MapPageController.Bind's doc on why m_pMap being + // a Button swallows its authored nested children) PLUS the 53 town + // hotspots. + var townMarkers = map!.Children + .Where(c => c.DatElementId != MapPageController.PlayerIconId + && c.DatElementId != MapPageController.HouseIconId) + .ToList(); + Assert.Equal(55, map.Children.Count); + Assert.Equal(53, townMarkers.Count); + Assert.All(townMarkers, c => Assert.Contains( + MapLocations.All, loc => loc.Width == c.Width && loc.Height == c.Height)); + Assert.All(townMarkers, c => Assert.True(c.AuthoredTooltipEnabled)); + Assert.Contains(townMarkers, c => c.AuthoredTooltipText == "Holtburg"); + } + + [Fact] + public void Bind_HouseListBoxStartsEmpty_MatchingRetailPostInit() + { + ElementInfo rootInfo = FixtureLoader.LoadMapHouseHostInfos(); + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + MapHousePanelController? controller = + MapHousePanelController.Bind(rootInfo, layout, MakeCallbacks()); + Assert.NotNull(controller); + + UiElement? box = UiElement.FindDescendant(controller!.Root, HousePageController.TextBoxId); + var listBox = Assert.IsType(box); + Assert.Equal(0, listBox.ContentHeight); + } +} diff --git a/tests/AcDream.App.Tests/UI/Layout/MapPageControllerTests.cs b/tests/AcDream.App.Tests/UI/Layout/MapPageControllerTests.cs new file mode 100644 index 00000000..9d48ef78 --- /dev/null +++ b/tests/AcDream.App.Tests/UI/Layout/MapPageControllerTests.cs @@ -0,0 +1,191 @@ +using AcDream.App.UI; +using AcDream.App.UI.Layout; +using AcDream.Core.Net.Messages; +using AcDream.Core.Physics; +using AcDream.Core.Ui; +using AcDream.Core.World; + +namespace AcDream.App.Tests.UI.Layout; + +/// +/// Unit coverage for 's pure math: the +/// calendar formatter ("Date: %s\nTime: %s", +/// gmMapUI::Update @0x004a1eb0) and the 53-town static table +/// (verbatim port of s_rgLocations). Marker-placement math itself is +/// / — both +/// already unit-tested elsewhere; this file only proves the wiring +/// reproduces their output through the real fixture (no re-derivation). +/// +public sealed class MapPageControllerTests +{ + // ── Calendar formatter ─────────────────────────────────────────────── + + [Fact] + public void FormatDateTime_OrdinaryHour_NoAndHalfSuffix() + { + var calendar = new DerethDateTime.Calendar( + 119, DerethDateTime.MonthName.Frostfell, 27, DerethDateTime.HourName.Dawnsong); + + string text = MapPageController.FormatDateTime(calendar); + + Assert.Equal("Date: Frostfell 27, 119 P.Y.\nTime: Dawnsong", text); + } + + [Fact] + public void FormatDateTime_AndHalfHour_RewritesSuffixWithHyphens() + { + var calendar = new DerethDateTime.Calendar( + 10, DerethDateTime.MonthName.Morningthaw, 1, DerethDateTime.HourName.MorntideAndHalf); + + string text = MapPageController.FormatDateTime(calendar); + + Assert.Equal("Date: Morningthaw 1, 10 P.Y.\nTime: Morntide-and-Half", text); + } + + [Theory] + [InlineData(DerethDateTime.HourName.Darktide, "Darktide")] + [InlineData(DerethDateTime.HourName.DarktideAndHalf, "Darktide-and-Half")] + [InlineData(DerethDateTime.HourName.Gloaming, "Gloaming")] + [InlineData(DerethDateTime.HourName.GloamingAndHalf, "Gloaming-and-Half")] + [InlineData(DerethDateTime.HourName.WarmtideAndHalf, "Warmtide-and-Half")] + public void FormatDateTime_EveryHourName_MatchesExpectedDisplayText( + DerethDateTime.HourName hour, string expectedHourText) + { + var calendar = new DerethDateTime.Calendar( + 10, DerethDateTime.MonthName.Morningthaw, 1, hour); + + string text = MapPageController.FormatDateTime(calendar); + + Assert.EndsWith($"Time: {expectedHourText}", text); + } + + // ── Town table ──────────────────────────────────────────────────────── + + [Fact] + public void MapLocations_Has53Entries() + { + Assert.Equal(53, MapLocations.All.Length); + } + + [Fact] + public void MapLocations_AllNamesAreUnique() + { + var names = new HashSet(StringComparer.Ordinal); + foreach (MapLocation loc in MapLocations.All) + Assert.True(names.Add(loc.Name), $"duplicate town name: {loc.Name}"); + } + + [Fact] + public void MapLocations_Holtburg_MatchesDecompiledByteValues() + { + // s_rgLocations[0x13] (pc:977379): X=0xa4 Y=0x4d W=9 H=8. + MapLocation holtburg = Assert.Single(MapLocations.All, l => l.Name == "Holtburg"); + Assert.Equal(0xa4, holtburg.X); + Assert.Equal(0x4d, holtburg.Y); + Assert.Equal(9, holtburg.Width); + Assert.Equal(8, holtburg.Height); + } + + [Fact] + public void MapLocations_EveryRectIsWithinTheMapWidgetsAuthoredExtent() + { + // m_pMap's own authored size (MapHousePanelSlotProbeTests: markerArea + // (6,8)-(247,258) — the widest observed extent). Town rects are + // independent of the marker-area rect but should still land inside + // a sane 0..300 canvas — a coarse sanity check that the verbatim + // port didn't transpose a digit. + foreach (MapLocation loc in MapLocations.All) + { + Assert.InRange(loc.X, 0, 260); + Assert.InRange(loc.Y, 0, 260); + Assert.InRange(loc.Width, 1, 20); + Assert.InRange(loc.Height, 1, 20); + } + } + + // ── Marker placement wiring (real fixture, no re-derivation) ──────────── + + [Fact] + public void Bind_PlayerMarker_OutdoorCell_ReproducesRadarCoordinatesPlacement() + { + // Arwic's landblock cell id (0x11CE0001 — an arbitrary real outdoor + // cell, picked only because RadarCoordinates.TryFromCell already + // proves gid-to-lcoord conformance elsewhere; this test proves the + // WIRING, not the formula). + const uint cellId = 0x11CE0001u; + Assert.True(RadarCoordinates.TryFromCell(cellId, out RadarCoordinates expected)); + + ElementInfo rootInfo = FixtureLoader.LoadMapHouseHostInfos(); + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + var callbacks = new MapHousePanelController.Callbacks( + Toggle: () => { }, + Map: new MapPageController.Bindings( + CurrentCalendar: static () => default, + PlayerCellId: () => cellId, + HousePosition: static () => (CreateObject.ServerPosition?)null, + TemplateResolver: (_, e) => new UiText { Width = 10f, Height = 10f, DatElementId = e }), + House: new HousePageController.Bindings(Lines: static () => Array.Empty())); + + MapHousePanelController? controller = MapHousePanelController.Bind(rootInfo, layout, callbacks); + Assert.NotNull(controller); + + UiElement? playerIcon = UiElement.FindDescendant(controller!.Root, MapPageController.PlayerIconId); + Assert.NotNull(playerIcon); + Assert.True(playerIcon!.Visible); + + // markerArea from the live fixture (MapHousePanelSlotProbeTests): + // (6,8)-(247,258) -> m_x0=6, m_y0=8. + const int markerX0 = 6, markerY0 = 8; + Assert.Equal(markerX0 + (float)expected.X - playerIcon.Width / 2f, playerIcon.Left, precision: 3); + Assert.Equal(markerY0 + (float)expected.Y - playerIcon.Height / 2f, playerIcon.Top, precision: 3); + } + + [Fact] + public void Bind_PlayerMarker_IndoorCell_HidesIconAndClearsCoordinateText() + { + // Envcell low word (>= 0x100) fails RadarCoordinates.TryFromCell — + // the indoor branch (gmMapUI::Update's else: SetVisible(0)). + const uint indoorCellId = 0x0012_0100u; + Assert.False(RadarCoordinates.TryFromCell(indoorCellId, out _)); + + ElementInfo rootInfo = FixtureLoader.LoadMapHouseHostInfos(); + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + var callbacks = new MapHousePanelController.Callbacks( + Toggle: () => { }, + Map: new MapPageController.Bindings( + CurrentCalendar: static () => default, + PlayerCellId: () => indoorCellId, + HousePosition: static () => (CreateObject.ServerPosition?)null, + TemplateResolver: (_, e) => new UiText { Width = 10f, Height = 10f, DatElementId = e }), + House: new HousePageController.Bindings(Lines: static () => Array.Empty())); + + MapHousePanelController? controller = MapHousePanelController.Bind(rootInfo, layout, callbacks); + Assert.NotNull(controller); + + UiElement? playerIcon = UiElement.FindDescendant(controller!.Root, MapPageController.PlayerIconId); + Assert.NotNull(playerIcon); + Assert.False(playerIcon!.Visible); + } + + [Fact] + public void Bind_HouseMarker_NullPosition_StaysHidden() + { + ElementInfo rootInfo = FixtureLoader.LoadMapHouseHostInfos(); + ImportedLayout layout = FixtureLoader.LoadMapHouseHost(); + var callbacks = new MapHousePanelController.Callbacks( + Toggle: () => { }, + Map: new MapPageController.Bindings( + CurrentCalendar: static () => default, + PlayerCellId: static () => 0u, + HousePosition: static () => (CreateObject.ServerPosition?)null, + TemplateResolver: (_, e) => new UiText { Width = 10f, Height = 10f, DatElementId = e }), + House: new HousePageController.Bindings(Lines: static () => Array.Empty())); + + MapHousePanelController? controller = MapHousePanelController.Bind(rootInfo, layout, callbacks); + Assert.NotNull(controller); + + UiElement? houseIcon = UiElement.FindDescendant(controller!.Root, MapPageController.HouseIconId); + Assert.NotNull(houseIcon); + Assert.False(houseIcon!.Visible); + } +} diff --git a/tests/AcDream.App.Tests/UI/Layout/RetailLayoutFixtureGenerator.cs b/tests/AcDream.App.Tests/UI/Layout/RetailLayoutFixtureGenerator.cs index e540eafe..a5b810a8 100644 --- a/tests/AcDream.App.Tests/UI/Layout/RetailLayoutFixtureGenerator.cs +++ b/tests/AcDream.App.Tests/UI/Layout/RetailLayoutFixtureGenerator.cs @@ -153,6 +153,11 @@ public sealed class RetailLayoutFixtureGenerator // lane-A unknowns U3/U4/U6/U7/U10. (SocialPanelController.HostLayoutId, SocialPanelController.SlotElementId, "social_panel_2100006E_1000018F.json"), + // Batch C (overnight hover/UI round, 2026-08-17): the two-tab + // Map/House panel — recon doc + // docs/research/2026-08-17-map-house-recon.md. + (MapHousePanelController.HostLayoutId, MapHousePanelController.SlotElementId, + "map_house_2100006E_1000018C.json"), }) { ElementInfo? panelPart = LayoutImporter.ImportInfos(dats, layoutId, rootId); diff --git a/tests/AcDream.App.Tests/UI/Layout/fixtures/map_house_2100006E_1000018C.json b/tests/AcDream.App.Tests/UI/Layout/fixtures/map_house_2100006E_1000018C.json new file mode 100644 index 00000000..a7f6053a --- /dev/null +++ b/tests/AcDream.App.Tests/UI/Layout/fixtures/map_house_2100006E_1000018C.json @@ -0,0 +1,4602 @@ +{ + "Id": 268435852, + "Type": 8, + "X": 0, + "Y": 0, + "Width": 300, + "Height": 362, + "OriginalParentWidth": 0, + "OriginalParentHeight": 0, + "HasOriginalParentSize": false, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 1, + "ReadOrder": 11, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "88": { + "Kind": 0, + "MasterPropertyId": 88, + "UnsignedValue": 1, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "46": { + "Kind": 7, + "MasterPropertyId": 46, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 8, + "MasterPropertyId": 47, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": { + "48": { + "Kind": 0, + "MasterPropertyId": 48, + "UnsignedValue": 268435955, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "49": { + "Kind": 0, + "MasterPropertyId": 49, + "UnsignedValue": 268435958, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "50": { + "Kind": 1, + "MasterPropertyId": 50, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + }, + { + "Kind": 8, + "MasterPropertyId": 47, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": { + "48": { + "Kind": 0, + "MasterPropertyId": 48, + "UnsignedValue": 268435956, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "49": { + "Kind": 0, + "MasterPropertyId": 49, + "UnsignedValue": 268435959, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "50": { + "Kind": 1, + "MasterPropertyId": 50, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + ], + "StructValue": {} + }, + "87": { + "Kind": 0, + "MasterPropertyId": 87, + "UnsignedValue": 268435478, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "268435497": { + "Kind": 0, + "MasterPropertyId": 268435497, + "UnsignedValue": 16, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [ + { + "Id": 268435955, + "Type": 12, + "X": 0, + "Y": 0, + "Width": 138, + "Height": 25, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "35": { + "Kind": 4, + "MasterPropertyId": 35, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "26": { + "Kind": 7, + "MasterPropertyId": 26, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 2, + "MasterPropertyId": 24, + "UnsignedValue": 1073741824, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + }, + "37": { + "Kind": 4, + "MasterPropertyId": 37, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "27": { + "Kind": 7, + "MasterPropertyId": 27, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 6, + "MasterPropertyId": 25, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 255, + "Green": 255, + "Red": 255, + "Alpha": 255 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + }, + "20": { + "Kind": 0, + "MasterPropertyId": 20, + "UnsignedValue": 1, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "21": { + "Kind": 0, + "MasterPropertyId": 21, + "UnsignedValue": 1, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "83": { + "Kind": 1, + "MasterPropertyId": 83, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "23": { + "Kind": 5, + "MasterPropertyId": 23, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 148800818, + "TableId": 587202561, + "Override": 0, + "English": 1, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + }, + "11": { + "Id": 11, + "Name": "Closed", + "PassToChildren": true, + "IncorporationFlags": 1, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "27": { + "Kind": 7, + "MasterPropertyId": 27, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 6, + "MasterPropertyId": 25, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 127, + "Green": 127, + "Red": 127, + "Alpha": 255 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + } + } + } + }, + "12": { + "Id": 12, + "Name": "Open", + "PassToChildren": true, + "IncorporationFlags": 1, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "27": { + "Kind": 7, + "MasterPropertyId": 27, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 6, + "MasterPropertyId": 25, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 204, + "Green": 204, + "Red": 204, + "Alpha": 255 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 11, + "FontDid": 1073741824, + "HJustify": 1, + "VJustify": 1, + "FontColor": { + "X": 0.49803922, + "Y": 0.49803922, + "Z": 0.49803922, + "W": 1 + }, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "Closed", + "Children": [ + { + "Id": 268436537, + "Type": 3, + "X": 0, + "Y": 0, + "Width": 17, + "Height": 25, + "OriginalParentWidth": 100, + "OriginalParentHeight": 25, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 2, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "11": { + "Id": 11, + "Name": "Closed", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687251, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "12": { + "Id": 12, + "Name": "Open", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687250, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "Closed": { + "Item1": 100687251, + "Item2": 3 + }, + "Open": { + "Item1": 100687250, + "Item2": 3 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435689, + "Type": 3, + "X": 17, + "Y": 0, + "Width": 66, + "Height": 25, + "OriginalParentWidth": 100, + "OriginalParentHeight": 25, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 2, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "11": { + "Id": 11, + "Name": "Closed", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687253, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "12": { + "Id": 12, + "Name": "Open", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687252, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "Closed": { + "Item1": 100687253, + "Item2": 3 + }, + "Open": { + "Item1": 100687252, + "Item2": 3 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435989, + "Type": 3, + "X": 83, + "Y": 0, + "Width": 17, + "Height": 25, + "OriginalParentWidth": 100, + "OriginalParentHeight": 25, + "HasOriginalParentSize": true, + "Left": 2, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 3, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "11": { + "Id": 11, + "Name": "Closed", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687255, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "12": { + "Id": 12, + "Name": "Open", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687254, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "Closed": { + "Item1": 100687255, + "Item2": 3 + }, + "Open": { + "Item1": 100687254, + "Item2": 3 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435956, + "Type": 12, + "X": 138, + "Y": 0, + "Width": 138, + "Height": 25, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 2, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "35": { + "Kind": 4, + "MasterPropertyId": 35, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "26": { + "Kind": 7, + "MasterPropertyId": 26, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 2, + "MasterPropertyId": 24, + "UnsignedValue": 1073741824, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + }, + "37": { + "Kind": 4, + "MasterPropertyId": 37, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "27": { + "Kind": 7, + "MasterPropertyId": 27, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 6, + "MasterPropertyId": 25, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 255, + "Green": 255, + "Red": 255, + "Alpha": 255 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + }, + "20": { + "Kind": 0, + "MasterPropertyId": 20, + "UnsignedValue": 1, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "21": { + "Kind": 0, + "MasterPropertyId": 21, + "UnsignedValue": 1, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "83": { + "Kind": 1, + "MasterPropertyId": 83, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "23": { + "Kind": 5, + "MasterPropertyId": 23, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 1502562, + "TableId": 587202561, + "Override": 0, + "English": 1, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + }, + "11": { + "Id": 11, + "Name": "Closed", + "PassToChildren": true, + "IncorporationFlags": 1, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "27": { + "Kind": 7, + "MasterPropertyId": 27, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 6, + "MasterPropertyId": 25, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 127, + "Green": 127, + "Red": 127, + "Alpha": 255 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + } + } + } + }, + "12": { + "Id": 12, + "Name": "Open", + "PassToChildren": true, + "IncorporationFlags": 1, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "27": { + "Kind": 7, + "MasterPropertyId": 27, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 6, + "MasterPropertyId": 25, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 204, + "Green": 204, + "Red": 204, + "Alpha": 255 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 11, + "FontDid": 1073741824, + "HJustify": 1, + "VJustify": 1, + "FontColor": { + "X": 0.49803922, + "Y": 0.49803922, + "Z": 0.49803922, + "W": 1 + }, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "Closed", + "Children": [ + { + "Id": 268436537, + "Type": 3, + "X": 0, + "Y": 0, + "Width": 17, + "Height": 25, + "OriginalParentWidth": 100, + "OriginalParentHeight": 25, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 2, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "11": { + "Id": 11, + "Name": "Closed", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687251, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "12": { + "Id": 12, + "Name": "Open", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687250, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "Closed": { + "Item1": 100687251, + "Item2": 3 + }, + "Open": { + "Item1": 100687250, + "Item2": 3 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435689, + "Type": 3, + "X": 17, + "Y": 0, + "Width": 66, + "Height": 25, + "OriginalParentWidth": 100, + "OriginalParentHeight": 25, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 2, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "11": { + "Id": 11, + "Name": "Closed", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687253, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "12": { + "Id": 12, + "Name": "Open", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687252, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "Closed": { + "Item1": 100687253, + "Item2": 3 + }, + "Open": { + "Item1": 100687252, + "Item2": 3 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435989, + "Type": 3, + "X": 83, + "Y": 0, + "Width": 17, + "Height": 25, + "OriginalParentWidth": 100, + "OriginalParentHeight": 25, + "HasOriginalParentSize": true, + "Left": 2, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 3, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "11": { + "Id": 11, + "Name": "Closed", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687255, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "12": { + "Id": 12, + "Name": "Open", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100687254, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "Closed": { + "Item1": 100687255, + "Item2": 3 + }, + "Open": { + "Item1": 100687254, + "Item2": 3 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435957, + "Type": 1, + "X": 276, + "Y": 0, + "Width": 24, + "Height": 25, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 3, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "18": { + "Kind": 0, + "MasterPropertyId": 18, + "UnsignedValue": 268435478, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + }, + "3": { + "Id": 3, + "Name": "Normal_pressed", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100668308, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "1": { + "Id": 1, + "Name": "Normal", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": { + "File": 100668307, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 1, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "Normal": { + "Item1": 100668307, + "Item2": 1 + }, + "Normal_pressed": { + "Item1": 100668308, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "Normal", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435958, + "Type": 268435494, + "X": 0, + "Y": 25, + "Width": 300, + "Height": 575, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 1, + "ReadOrder": 4, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "88": { + "Kind": 0, + "MasterPropertyId": 88, + "UnsignedValue": 1, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "87": { + "Kind": 0, + "MasterPropertyId": 87, + "UnsignedValue": 268435479, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [ + { + "Id": 268435945, + "Type": 3, + "X": 0, + "Y": 0, + "Width": 300, + "Height": 600, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 1, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [ + { + "Id": 268435737, + "Type": 3, + "X": 279, + "Y": 33, + "Width": 21, + "Height": 535, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 2, + "Top": 1, + "Right": 1, + "Bottom": 1, + "ReadOrder": 4, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100668018, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100668018, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435738, + "Type": 3, + "X": 0, + "Y": 568, + "Width": 300, + "Height": 32, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 2, + "Right": 1, + "Bottom": 1, + "ReadOrder": 5, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100668016, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100668016, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435728, + "Type": 3, + "X": 22, + "Y": 33, + "Width": 257, + "Height": 535, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 1, + "ReadOrder": 3, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100668015, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100668015, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435735, + "Type": 3, + "X": 0, + "Y": 0, + "Width": 300, + "Height": 33, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100668019, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100668019, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435736, + "Type": 3, + "X": 0, + "Y": 33, + "Width": 22, + "Height": 535, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 1, + "ReadOrder": 2, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100668017, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100668017, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435946, + "Type": 3, + "X": 0, + "Y": 135, + "Width": 300, + "Height": 330, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 3, + "Right": 1, + "Bottom": 3, + "ReadOrder": 6, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [ + { + "Id": 268435947, + "Type": 12, + "X": 21, + "Y": 4, + "Width": 227, + "Height": 30, + "OriginalParentWidth": 300, + "OriginalParentHeight": 330, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 2, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "26": { + "Kind": 7, + "MasterPropertyId": 26, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 2, + "MasterPropertyId": 24, + "UnsignedValue": 1073741826, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + }, + "27": { + "Kind": 7, + "MasterPropertyId": 27, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 6, + "MasterPropertyId": 25, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 255 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + }, + "39": { + "Kind": 1, + "MasterPropertyId": 39, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "20": { + "Kind": 0, + "MasterPropertyId": 20, + "UnsignedValue": 1, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "21": { + "Kind": 0, + "MasterPropertyId": 21, + "UnsignedValue": 1, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 0, + "FontDid": 1073741826, + "HJustify": 1, + "VJustify": 1, + "FontColor": { + "X": 0, + "Y": 0, + "Z": 0, + "W": 1 + }, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435948, + "Type": 1, + "X": 21, + "Y": 36, + "Width": 257, + "Height": 267, + "OriginalParentWidth": 300, + "OriginalParentHeight": 330, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 2, + "ReadOrder": 2, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100668029, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": { + "268435534": { + "Kind": 4, + "MasterPropertyId": 268435534, + "UnsignedValue": 0, + "IntegerValue": 6, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "268435535": { + "Kind": 4, + "MasterPropertyId": 268435535, + "UnsignedValue": 0, + "IntegerValue": 247, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "71": { + "Kind": 0, + "MasterPropertyId": 71, + "UnsignedValue": 268435952, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "268435536": { + "Kind": 4, + "MasterPropertyId": 268435536, + "UnsignedValue": 0, + "IntegerValue": 8, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "72": { + "Kind": 2, + "MasterPropertyId": 72, + "UnsignedValue": 553648166, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "268435537": { + "Kind": 4, + "MasterPropertyId": 268435537, + "UnsignedValue": 0, + "IntegerValue": 258, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100668029, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [ + { + "Id": 268435949, + "Type": 3, + "X": 0, + "Y": 0, + "Width": 17, + "Height": 16, + "OriginalParentWidth": 257, + "OriginalParentHeight": 267, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 2, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100683024, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": { + "59": { + "Kind": 1, + "MasterPropertyId": 59, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100683024, + "Item2": 3 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": true, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435950, + "Type": 1, + "X": 0, + "Y": 0, + "Width": 8, + "Height": 8, + "OriginalParentWidth": 257, + "OriginalParentHeight": 267, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 2, + "ReadOrder": 2, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100683025, + "DrawMode": 3 + }, + "Cursor": null, + "Properties": { + "Values": { + "80": { + "Kind": 3, + "MasterPropertyId": 80, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "59": { + "Kind": 1, + "MasterPropertyId": 59, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "71": { + "Kind": 0, + "MasterPropertyId": 71, + "UnsignedValue": 268436376, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "72": { + "Kind": 2, + "MasterPropertyId": 72, + "UnsignedValue": 553648193, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "73": { + "Kind": 5, + "MasterPropertyId": 73, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 258601413, + "TableId": 587202561, + "Override": 0, + "English": 1, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "19": { + "Kind": 1, + "MasterPropertyId": 19, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "75": { + "Kind": 1, + "MasterPropertyId": 75, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + }, + "1": { + "Id": 1, + "Name": "Normal", + "PassToChildren": true, + "IncorporationFlags": 1, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "2": { + "Id": 2, + "Name": "Normal_rollover", + "PassToChildren": true, + "IncorporationFlags": 1, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100683025, + "Item2": 3 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [ + { + "Id": 268435953, + "Type": 3, + "X": 0, + "Y": 0, + "Width": 8, + "Height": 8, + "OriginalParentWidth": 8, + "OriginalParentHeight": 8, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 1, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": {} + } + }, + "1": { + "Id": 1, + "Name": "Normal", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "59": { + "Kind": 1, + "MasterPropertyId": 59, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + }, + "2": { + "Id": 2, + "Name": "Normal_rollover", + "PassToChildren": false, + "IncorporationFlags": 0, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "59": { + "Kind": 1, + "MasterPropertyId": 59, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [ + { + "Id": 268435977, + "Type": 3, + "X": 0, + "Y": 0, + "Width": 1, + "Height": 100, + "OriginalParentWidth": 100, + "OriginalParentHeight": 100, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 1, + "ReadOrder": 2, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100682953, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100682953, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435978, + "Type": 3, + "X": 99, + "Y": 0, + "Width": 1, + "Height": 100, + "OriginalParentWidth": 100, + "OriginalParentHeight": 100, + "HasOriginalParentSize": true, + "Left": 2, + "Top": 1, + "Right": 1, + "Bottom": 1, + "ReadOrder": 3, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100682953, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100682953, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435979, + "Type": 3, + "X": 0, + "Y": 99, + "Width": 100, + "Height": 1, + "OriginalParentWidth": 100, + "OriginalParentHeight": 100, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 2, + "Right": 1, + "Bottom": 1, + "ReadOrder": 4, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100682953, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100682953, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268436149, + "Type": 3, + "X": 0, + "Y": 0, + "Width": 100, + "Height": 1, + "OriginalParentWidth": 100, + "OriginalParentHeight": 100, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100682953, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": {} + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100682953, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": true, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": true, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": true, + "TooltipText": { + "Token": 0, + "StringId": 258601413, + "TableId": 587202561, + "Override": 0, + "English": 1, + "Comment": 0 + }, + "TooltipRootElementId": 268436376, + "TooltipLayoutDid": 553648193, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": 0, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 268435952, + "TooltipLayoutDid": 553648166, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435951, + "Type": 12, + "X": 21, + "Y": 303, + "Width": 257, + "Height": 20, + "OriginalParentWidth": 300, + "OriginalParentHeight": 330, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 2, + "Bottom": 2, + "ReadOrder": 3, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "26": { + "Kind": 7, + "MasterPropertyId": 26, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 2, + "MasterPropertyId": 24, + "UnsignedValue": 1073741828, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + }, + "27": { + "Kind": 7, + "MasterPropertyId": 27, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 6, + "MasterPropertyId": 25, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 255 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + ], + "StructValue": {} + }, + "39": { + "Kind": 1, + "MasterPropertyId": 39, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": true, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 0, + "FontDid": 1073741828, + "HJustify": 1, + "VJustify": 1, + "FontColor": { + "X": 0, + "Y": 0, + "Z": 0, + "W": 1 + }, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + }, + { + "Id": 268435959, + "Type": 268435493, + "X": 0, + "Y": 25, + "Width": 300, + "Height": 575, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 1, + "ReadOrder": 5, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": { + "File": 100682946, + "DrawMode": 1 + }, + "Cursor": null, + "Properties": { + "Values": { + "88": { + "Kind": 0, + "MasterPropertyId": 88, + "UnsignedValue": 1, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "87": { + "Kind": 0, + "MasterPropertyId": 87, + "UnsignedValue": 268435480, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": { + "": { + "Item1": 100682946, + "Item2": 1 + } + }, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [ + { + "Id": 268435942, + "Type": 5, + "X": 5, + "Y": 5, + "Width": 290, + "Height": 590, + "OriginalParentWidth": 300, + "OriginalParentHeight": 600, + "HasOriginalParentSize": true, + "Left": 1, + "Top": 1, + "Right": 1, + "Bottom": 2, + "ReadOrder": 1, + "ZLevel": 0, + "States": { + "4294967295": { + "Id": 4294967295, + "Name": "", + "PassToChildren": false, + "IncorporationFlags": 30, + "Image": null, + "Cursor": null, + "Properties": { + "Values": { + "100": { + "Kind": 7, + "MasterPropertyId": 100, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [ + { + "Kind": 8, + "MasterPropertyId": 101, + "UnsignedValue": 0, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": { + "99": { + "Kind": 2, + "MasterPropertyId": 99, + "UnsignedValue": 553648165, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + }, + "98": { + "Kind": 0, + "MasterPropertyId": 98, + "UnsignedValue": 268435943, + "IntegerValue": 0, + "FloatValue": 0, + "BoolValue": false, + "StringInfoValue": { + "Token": 0, + "StringId": 0, + "TableId": 0, + "Override": 0, + "English": 0, + "Comment": 0 + }, + "ColorValue": { + "Blue": 0, + "Green": 0, + "Red": 0, + "Alpha": 0 + }, + "VectorValue": { + "X": 0, + "Y": 0, + "Z": 0 + }, + "ArrayValue": [], + "StructValue": {} + } + } + } + ], + "StructValue": {} + } + } + } + } + }, + "DefaultStateId": 0, + "FontDid": 0, + "HJustify": 1, + "VJustify": 1, + "FontColor": null, + "Outline": false, + "OutlineColor": null, + "StateMedia": {}, + "StateCursors": {}, + "DefaultStateName": "", + "Children": [], + "TabTable": [], + "TemplateList": [ + { + "TemplateLayoutId": 553648165, + "TemplateElementId": 268435943 + } + ], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null + } + ], + "TabTable": [ + { + "ButtonElementId": 268435955, + "PageElementId": 268435958, + "IsDefault": true + }, + { + "ButtonElementId": 268435956, + "PageElementId": 268435959, + "IsDefault": false + } + ], + "TemplateList": [], + "LedCheckedSprite": 0, + "LedUncheckedSprite": 0, + "ScrollbarElementId": 0, + "Invisible": false, + "MarginLeft": 0, + "MarginRight": 0, + "MarginTop": 0, + "MarginBottom": 0, + "TooltipEnabled": false, + "TooltipText": null, + "TooltipRootElementId": 0, + "TooltipLayoutDid": 0, + "TooltipTextChildElementId": 0, + "TooltipDelaySeconds": null, + "MaxWidth": null, + "MinWidth": null, + "MaxHeight": null, + "MinHeight": null +} \ No newline at end of file