Skip to content

Commit 740a572

Browse files
tariqksolimandevin-ai-integration[bot]github-actions[bot]
authored
fix(measure): rename config DEM field from 'dem' to 'url' (#980)
* Sync toggleTimeUI DOM state to Zustand store toggleTimeUI() now calls setTimeUIActive() and setTimeUIExpanded() so BottomFloatingBar visibility and BottomElementPositioner offsets reflect actual TimeUI state. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Restore #toggleTimeUI element in Coordinates markup The element was accidentally dropped during the folder restructure move. TimeUI.js and DrawTool.js check $('#toggleTimeUI').hasClass('active') to gate histogram rendering and time-filter toggle visibility. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix #toggleTimeUI: restore click handler, tippy, active class; remove redundant jQuery positioning Restored pieces lost during folder restructure: - Click handler in init() and off handler in remove() - Tippy tooltip for the time toggle button - display:none when time is not enabled - $('#toggleTimeUI').toggleClass('active') so TimeUI.js can check it - $('#CoordinatesDiv > #toggleTimeUI').remove() on mobile Removed jQuery CSS positioning from toggleTimeUI() since BottomElementPositioner now reactively handles all bottom-anchored element offsets via the Zustand store. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix CurtainTool.destroy() using undefined ReactDOM.unmountComponentAtNode Use the stored _reactRoot.unmount() instead, matching the React 18 createRoot pattern already used in make(). Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix tooltips, scale indicator position, modal blur, help close button Tooltips: - Reduce Base UI Tooltip delay from 600ms (default) to 200ms - Restyle tooltip popup to match tippy blue theme (var(--color-c2)) - Add Tooltip wrappers to TopBar panel toggles (Viewer/Map/Globe) - Wrap Toggle with forwardRef so Tooltip render prop can attach ref - Remove title attrs that conflicted with custom tooltips Scale indicator: - Remove scalefactor-specific positioning from BottomElementPositioner (it moves naturally with .leaflet-bottom.leaflet-left container) - Position scalefactor to the left of compass at same bottom level Modal blur: - Call _applyBlur() immediately when marking modal as closing so blur clears during fade-out instead of persisting 500ms Help modal: - Add close (X) button in title bar matching other modal patterns Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Remove dead CSS: delete tools.css, clean ~600 lines from mmgisUI.css and mmgis.css - Delete tools.css entirely (both selectors #CurtainToolList and .searchToolSelect are unreferenced anywhere in the codebase) - Remove from mmgisUI.css: .mmgisRadioBar3/4/Vertical (140 lines), .mmgispureselect (104 lines), blink/condemned_blink_effect (38 lines), .slidecontainer/.slider (41 lines), .ar_slider (91 lines), .verticalSlider (91 lines), .mmgisMultirange_elev (19 lines), .ui-corner-all/bottom/right/br (9 lines) - Remove from mmgis.css: #nodeenv, empty #topBar{}, #topBarInfo, #topBarHelp, #topBarFullscreen, #toggleUI, #logoGoBack - Keep #topBarLink (used in BottomBarReact.jsx), #webgl-error-message (used by vendored THREE.js) - All selectors verified with repo-wide grep before removal Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * UI fixes: tooltips, splitter hover, mobile toolbar, color schemes - Replace Base UI Tooltip with simple React portal tooltip (200ms delay, tippy-matching style) — fixes missing tooltips for toolbar/topbar/bottom buttons - Add cursor + hover highlight to vertical splitters (was missing because module CSS didn't inherit global .splitterV styles) - Add hover highlight to tool panel drag handle - Remove mdi-drag-vertical icon from tool panel drag - Add mobile toolbar horizontal layout via @media query overrides - Add 4 new color schemes: High Contrast (a11y), Dark Mars, Dark Midnight, Light Warm (total: 10 themes) - Previous fixes also included in working tree: - timeUI border moved to toolsWrapper border-bottom (conditional) - #toggleTimeUI button removed entirely - CoordinatesDiv: vertical centering, unified background, 12px right offset - barBottom padding-bottom: 8px Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix assignment operator used instead of comparison in TimeControl.fina() Pre-existing bug: `TimeControl.enabled = true` was assigning instead of comparing. Changed to `TimeControl.enabled === true`. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Restructure Configure page UI tab: add all themes, Custom mode, enableWhenField - Added all 10 theme presets to dropdown (was missing Dark Mars, Dark Midnight, Light Warm, High Contrast) - Added 'Custom' option: skips preset theme, uses only color picker values - Moved Theming section directly under Rebranding - Nested 'Custom Color Options' under Theming with subdescription - Added enableWhenField support to Maker.js: disables color pickers unless theme is set to Custom - Renamed color options with clearer names and improved descriptions: Primary → Surface Color, Secondary → Deep Background Color, Tertiary → Text Color, Body → Page Body Color, Highlight → Feature Highlight - Stylize.js: skip setTheme() when theme is 'Custom' - Rebuilt configure page Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Revert tooltips to tippy.js, fix dropdown menus, redesign About modal 1. Tooltip: Replaced custom React portal tooltip with tippy.js wrapper. Uses the existing tippy.js dependency and 'blue' theme for consistency. 2. Dropdown: Replaced Base UI Menu with native portal dropdown. Base UI's nested Menu.Trigger + BaseButton composition was swallowing click events, breaking userAvatar and menuBtn menus. New implementation uses simple state + createPortal with proper outside-click dismissal. 3. About modal: Professional redesign with centered MMGIS ASCII art header, proper GitHub SVG logo link, clean metadata section, centered link buttons, attributions section, and NASA-AMMOS footer. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Restore .mmgisHelpButton base styles lost during Help.css module migration The global .mmgisHelpButton styles (yellow color, compact 18x18px sizing, 0.7 opacity) were removed when Help.css was converted to Help.module.css. Since Help.getComponent() emits raw HTML strings for jQuery-rendered tool headers, it cannot use CSS Module scoped classes. Restored the base styles in mmgis.css alongside the related .mmgisToolHelpBtn definition. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix session logout regression, About modal refinements, High Contrast theme, Stylize.js, Default Tool config - Login: skip session.regenerate() for token-based re-auth (useToken:true) so reloading the main page no longer invalidates the configure page session - About modal: replace ASCII art with mmgis.png logo, rename Attributions to Map Layer Attributions, remove footer logo, link NASA-AMMOS to ammos.nasa.gov - High Contrast theme: change accent from #ffff00 to #ffd700 (gold) for better contrast ratios against dark backgrounds - Stylize.js: color overrides only apply when theme is Custom or unset, preventing preset themes from being clobbered by stale config values - Restore Default Tool config section in tab-ui-config.json (accidentally removed during Theming section reorganization) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Restore defaulttooldropdown case handler in Maker.js The case was accidentally removed during the Configure page UI tab restructure (d7f96c50). Without it, the Default Tool dropdown in the Configure page rendered as nothing despite the config referencing it. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * High Contrast tooltip text, panel toggle styling, scale position swap - High Contrast theme: tooltips now use black text on yellow background via --color-c2-text variable (white for all other themes) - About modal links use var(--color-f) for consistent theme text color - Panel toggle buttons: 11px uppercase with 600 weight for better visibility - Mapping scale button moved to bottom-right of compass (was top-left) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Reposition Viewer and Globe panel buttons to top-right - Viewer: dropdown selector at top-right edge, OSD buttons stacked vertically below it; settings panel opens to the left - Globe: home, exaggerate, observe, walk, link controls moved from TopLeft to TopRight corner via addControl 4th arg - Style consistency: OSD buttons and LithoSphere controls now match Leaflet zoom controls (var(--color-a) bg, var(--color-f) text, var(--color-mmgis) hover, 30px size, 3px border-radius) - Viewer settings sliders use var(--color-a3) instead of hardcoded #444444 - Az/el indicator stays at bottom center (exception per design) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Consistent modal theming + session security fix Modal theming: - All modals now share consistent styling: backdrop-filter blur, semi-transparent background via --color-a-rgb, 10px border-radius, header divider line, box-shadow - Updated: loginModal, Help, ConfirmationModal, Settings, Hotkeys, About modals - Tool panel backgrounds changed from opaque var(--color-k) to transparent so the ToolPanel's existing backdrop-filter effect shows through - Legend tool header updated to match consistent 44px height with divider - applyTheme.js now auto-derives --color-a-rgb from theme's --color-a hex value - Modal service wrapper gets backdrop-filter: blur(12px) Session security (Devin Review fix): - Token re-auth now calls req.session.regenerate() with data preservation to prevent session fixation while maintaining multi-tab compatibility - Token is rotated via crypto.randomBytes on every re-auth (was being reused) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * UI fixes: viewer settings, button sizing, menu contrast, coords, login header 1. Viewer OSD settings moved to top of button stack, panel opens downward 2. Overlay buttons consistent 30x30px (OSD line-height fix, home button) 3. Menu/icon contrast improved: Dropdown items and IconButtons use --color-a5 (was --color-a3) with --color-f on hover for better dark theme legibility 4. CoordinatesDiv fixed to 30px height, pickLngLat button centered 5. Login modal now has a header bar with 'Log In' title and close X button; title toggles to 'Sign Up' when switching modes Also reverts session regeneration for token re-auth (Devin Review feedback): token-based re-auth now refreshes session data in-place without regeneration or token rotation, preserving multi-tab compatibility. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * UI polish: nav popover, sep tools, compass, zoom controls, status indicator, toast 1. Description nav popover: added z-index:9000 so menu appears above map panels 2. Separated tools: default color changed from accent to --color-f; fixed CSS selector from .toolButtonSep to .toolSep to match actual class names 3. Compass + mapping scale shifted left by 30px for better positioning 4. Map zoom/home controls: use --color-f instead of accent --color-c to reduce visual prominence; hover still highlights with accent color 5. Status indicators (reload/ws disconnect/layer update) moved from Leaflet control to TopBar with soft pulsing fade animation and tooltip on hover 6. WebSocket retry toast: rounded corners, glass background with backdrop-filter, border-left accent for failure state instead of solid red background Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix 14 tool UI issues: headers, backgrounds, layout, functional bugs Header alignment: - LayersTool: align-items center on #filterLayers, gap between right icons - InfoTool: align-items center on #infoToolHeader, 44px height - ViewshedTool: align-items center, restructured header with left/right divs - IsochroneTool: restructured flat header into nested mmgisToolHeader pattern - ShadeTool: align-items center on #vstHeader children Icon spacing: - LayersTool: increased right margin to 28px + gap 2px - ViewshedTool: #vstNew padding-right 30px (clear of close button) - IsochroneTool: #iscNew padding-right 30px Missing components: - SitesTool: added Help import + help icon via mmgisToolHeader pattern - AnimationTool: added full mmgisToolHeader with title and help icon Background fixes: - InfoTool: changed toolsContainer background from transparent to var(--color-a) - DrawTool: changed toolsContainer background from transparent to var(--color-a) Layout fixes: - DrawTool: #drawToolContents top 81px, height calc(100%-81px), #drawToolNav margin-right 0 - MeasureTool: removed padding-left:0 override from mmgisToolHeader child selector Functional fixes: - InfoTool: updated jQuery selectors from #InfoTool to #toolButtonInfo (React toolbar IDs changed) - CurtainTool: deferred OpenSeadragon init with requestAnimationFrame (React 18 async render) - CurtainTool: curtainToolBar justify-content flex-end (icons at bottom) Security: - TopBar StatusIndicator: escape HTML in layer names to prevent XSS via addLayerQueue Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix mapToolBar pointer events, login padding, default tool, About modal order 1. mapToolBar: set pointer-events:none on both #mapToolBar and direct children so clicks pass through to the map; leaf elements still get auto via .childpointerevents rule 2. #loginModalBody: padding changed to 40px 0px 0px 3. Default tool: deferred click to requestAnimationFrame so React toolbar has rendered before getElementById runs 4. About modal: moved mainInfoModalCustom to right below mainInfoModalHero Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix tool headers to 40px, ViewshedTool subheader, AnimationTool header, InfoTool close btn, statusIndicator position 1. All tool panel headers: changed from 44px to exactly 40px height - Global .mmgisToolHeader and .mmgisToolTitle in mmgis.css - InfoTool.css, ViewshedTool.css, IsochroneTool.css, ShadeTool.css 2. LayersTool #filterLayers: height 40px, .right > div height unset, .right margin-right 30px, .right > div margin 0px 3px 3. ViewshedTool: restructured header — title+help in mmgisToolHeader row, vstToggleAll (left) and vstNew (right) on a new #vstSubHeader row below 4. AnimationTool: removed old #animationToolHeader CSS (padding 15px 20px, white background, 18px font), now uses standard mmgisToolHeader class. Fixed color from var(--color-a) (background) to var(--color-f) (text) 5. InfoTool close X: re-inject close button after use() rebuilds content via TC_.injectCloseButton() (toolsContainer.empty() was removing it) 6. StatusIndicator: moved to left of topBarTitle in JSX render order. Added align-items:center to #topBarMain for vertical alignment. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Remove title attr from StatusIndicator (conflicts with tippy tooltip) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix TimeUI dropdown z-index above tool panel, reposition toasts to top-center 1. TimeUI dropdowns: added z-index 10000 to all dropy content ul elements so they render above the vertical tool panel (z-index 1400). Also set timeUIDock to position:relative with z-index 10000 and overflow:visible. 2. Toast notifications: repositioned #toast-container from bottom-right to top-center just below the topbar (top: 44px, centered with transform). Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix StatusIndicator spacing, CurtainTool close btn, header title font consistency 1. StatusIndicator: use display:none/flex instead of opacity:0/1 so it takes no space when there's no active status indicator. 2. CurtainTool: added close X button at top of curtainToolBar (matching MeasureTool pattern) with flex spacer pushing other buttons to bottom. 3. Header title font consistency: InfoTool, ShadeTool, CurtainTool titles now match mmgisToolTitle standard (font-weight:600, padding-left:10px, height:40px for CurtainTool which was 34px). Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Legend empty state, scalefactor position, sep-tool-header unbold 1. Legend: show 'No active layers with legends' when no legend items are present. Also fixed container height calc(100% - 40px). 2. Mapping Scale (.leaflet-control-scalefactor): shifted 10px right (left 26→36px) and 1px down (bottom 30→29px). 3. sep-tool-header span: font-weight changed from 600 to 400. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Guard Legend empty state message to only show when panel is active Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix TimeUI dropdown covered by toolPanel: remove splitscreens stacking context #splitscreens had z-index:1 which created a stacking context, confining its children (including bottomFloatingBar at z-index:1500) to that context. Since ToolPanel (z-index:1400) was a sibling outside splitscreens, it painted above all splitscreens children regardless of their internal z-index values. Fix: change #splitscreens z-index from 1 to auto so it no longer creates a stacking context. Now bottomFloatingBar (1500) participates in the same stacking context as ToolPanel (1400), and 1500 > 1400 means the TimeUI dropdown correctly paints above the tool panel. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Migrate ~69 CursorInfo toast-like calls to proper Toast component - Replace CursorInfo.update() toast-like calls with Toast.info/success/warning/error - Preserve message colors: blue→info, green→success, yellow→warning, red→error - Keep 12 legitimate cursor-following CursorInfo calls unchanged - Files migrated: DrawTool.js, DrawTool_Files.js, DrawTool_FileModal.js, DrawTool_Templater.js, DrawTool_SetOperations.js, DrawTool_Drawing.js, DrawTool_Editing.js, DrawTool_Shapes.js, LayersTool.js, ShadeTool.js, chemistrychart.js - Fix Devin Review: Change misleading 'Bad token' to 'Login failed' in users.js - Normalize line endings (CRLF→LF) in affected files Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix Toast.js missing from git, CoordinatesDiv z-index, Legend duplicate ID, topBar padding - Add Toast.js to version control (was untracked, causing webpack module error) - Bump CoordinatesDiv z-index from 20 to 1001 (was hidden behind splitscreens children after z-index:auto change) - Fix Legend duplicate ID: separated tool icon was #LegendTool, same as content container div, causing empty message to appear in button instead of panel - Add hasStatus class to #topBarMain when statusIndicator is active, setting #topBarTitleName padding-left to 0 Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix Legend empty message: scope selector to content container via targetId Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Move Toast.js to design-system, fix --color-a3 text contrast, update AGENTS.md - Move Toast.js from UserInterface_/components/Toast/ to design-system/components/Toast/ (generic component belongs in design-system, not MMGIS-specific UserInterface_) - Update all 11 Toast import paths to new location - Bump --color-a3 in 5 dark themes to pass WCAG AA 4.5:1 contrast for text: Dark Default #747c81→#81888d, Dark Blue #64748b→#738399, Dark Warm #8b7a5e→#908064, Dark Mars #8a6a60→#98796f, Dark Midnight #606088→#7a7a9e - Update AGENTS.md: document design-system/ vs UserInterface_/ distinction in project structure and Key Directories Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix topBarTitleName padding override: increase specificity and add !important Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix IdentifierTool deactivation: update icon ID reference in separateFromMMWebGIS Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Hide toolPanelDrag when no tool is open - Add setToolPanelDragVisible(false) to closeActiveTool() (was only in makeTool toggle-off path) - Also guard drag handle display on isOpen (toolPanelWidth > 0) as safety net Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Add hover effect to MMGIS logo (opacity + brightness transition) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix MMGIS logo hover: keep full opacity, use subtle background highlight instead Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Selective tile fade: fade on pan/zoom, instant on refresh/reload - Remove blanket _fadeAnimated toggle from toggleTimeUI (was killing fade for all tiles while TimeUI was open) - Monkey-patch GridLayer.redraw, TileLayer.setUrl, and GridLayer._tileReady to suppress fade via a transient _suppressTileFade map flag - Set _suppressTileFade in reloadTimeLayers for time-driven reloads - Flag auto-clears after 300ms so pan/zoom tiles still get the nice fade - Install pbf dependency (required by CesiumMVTLayer from #942 merge) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Per-layer fade control: time-enabled + shade/viewshed layers never fade - Replace transient map-level _suppressTileFade with per-layer _noFade flag - Patch GridLayer._tileReady to check _noFade on the layer instance - Set _noFade on time-enabled tile layers and data/GL layers at creation - Set _noFade on Shade and Viewshed tool GL layers - Non-time-enabled base imagery tiles still fade normally on pan/zoom Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile UI improvements — move hamburger to right menu, show panel toggles, isMobile-driven toolbar layout, desktop-matching scalebar/compass - Remove left hamburger menu (#topBarMenu), move BottomBar items into top-right kebab dropdown menu for both mobile and desktop - Show panel toggles (Viewer/Map/Globe) and account/login UI in mobile topbar's #topBarRight - Move toolbar horizontal layout CSS from @media breakpoints to UserInterfaceMobile_.css (loaded only when isMobile flag is true) - Remove #mapTopBar @media rule from mmgis.css, add to mobile CSS - Remove mobile-only simplified scalebar rendering; use full desktop scalebar with both large and small axes on all viewports - Remove display:none on .leaflet-control-scalefactor in mobile CSS - Remove #loginDiv display:none from mobile CSS (React overlay handles it) - Simplify BottomBarReact container styles (no more absolute positioning) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 4.3.28-20260430 [version bump] * fix: mobile toolbar 40px height, bottomFloatingBar flush, timeUI toggle, scalebar position, hide hotkeys - Toolbar height 40px, toolButton width 40px, no border-bottom - toolcontroller_incdiv: no padding-bottom, overflow-y hidden - bottomFloatingBar: no border-radius, left/right/bottom = 0 - Add MobileTimeUIToggle button on far right of toolbar - Hide Keyboard Shortcuts from kebab menu on mobile - Fix scalebar positioning (remove top:48px override in UserInterfaceBridge) - Set mobileTopSize/topSize to 40 (splitscreens top = 40px, not 50px) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile topBar padding-left 34px Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: update MobileCoordButton topBar paddingLeft from 80px to 34px Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: MobileTimeUIToggle — inline toggle logic, float right, hide from settings on mobile - Replace broken Coordinates.toggleTimeUI() call with direct jQuery/store toggle - Float time button right in toolbar - Hide Time UI toggle from settings modal on mobile (toolbar has it) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: push scalebar/compass/scale up 40px on mobile, keep #timeUI in DOM - BottomElementPositioner: position mapToolBar, leaflet-bottom-left/right 40px above bottom on mobile (above toolbar) - Stop removing #timeUI from DOM on mobile so MobileTimeUIToggle works Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile TimeUI — only show endtime, always expanded - Hide #mmgisTimeUIStartWrapper and StartWrapperFake on mobile via CSS - Force expanded state (addClass expanded + show) when toggling TimeUI on - CSS ensures #timeUI.active always shows expanded content on mobile Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile TimeUI opens in tool panel with header, end time, expanded rows - MobileTimeUIToggle now opens/closes the tool panel via ToolController_ - Closes any active tool before showing TimeUI - Forces expanded state when opening - CSS hides start time inputs, positions expanded content properly - Overrides absolute positioning of expanded content for tool panel flow Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * feat: rewrite separated tools system from jQuery to React components - Add separatedToolsList/activeSeparatedTools state to Zustand uiStore - Rewrite SeparatedTools.jsx with glassmorphism panels, CSS Module styling - Replace SepToolsContainer (setInterval hack) with SepToolButton/SepToolsSection - Remove ~170 lines of jQuery DOM construction from ToolController_.js - Fix hardcoded rgba(26,26,27,0.88) to theme-aware var(--color-a-rgb) - Remove separated tool entries from themeApplier.js - Remove separated tool overrides from FloatingElements.css - Move Legend CSS overrides from Toolbar.module.css to SeparatedTools.module.css - Remove jQuery active-state manipulation from IdentifierTool.js - Add store sync in Map_.js displayOnStart logic - Preserve all DOM IDs for backward compatibility (mmgisAPI, tool make()) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 4.3.28-20260501 [version bump] * fix: TimeUI mobile checks — use Zustand store instead of L_.UserInterface_ L_.UserInterface_ is null when TimeUI.init() runs (TimeControl.init is called before L_.link sets UserInterface_). All 16 isMobile checks now read from useUIStore.getState().isMobile which is set at startup. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 4.3.29-20260501 [version bump] * fix: move displayOnStart logic from Map_.js to ToolController_.finalizeTools() - Map_ no longer references specific tools (LegendTool) - displayOnStart is now handled generically for all separated tools - Added DOM element polling (tryMake) to handle React render timing Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * revert: remove all TimeUI-related mobile changes Reverts TimeUI.js and BottomBar.js to development base. Restores #timeUI DOM removal in UserInterfaceBridge.fina(). Removes MobileTimeUIToggle component from Toolbar.jsx. Removes TimeUI mobile CSS overrides from UserInterfaceMobile_.css. Non-TimeUI refinements (toolbar height, scalebar positioning, etc.) preserved. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * simplify: remove DOM polling, use simple setTimeout(0) for auto-open LegendTool handles its own content lifecycle via subscribeOnLayerToggle. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * feat: mobile TimeUI — fix isMobile detection, staging container, toolbar toggle - TimeUI.js: import useUIStore and replace all 16 L_.UserInterface_?.isMobile checks with useUIStore.getState().isMobile (L_.UserInterface_ is null when TimeUI.init() runs, so mobile conditionals were dead code) - TimeUI.js: stage mobile #timeUI in hidden #timeUIMobileStaging instead of placing directly in #tools (which gets cleared by other tools) - UserInterfaceBridge.js: stop removing #timeUI from DOM on mobile - Toolbar.jsx: add MobileTimeUIToggle that moves #timeUI between staging and #tools, opens/closes tool panel via ToolController_ - BottomBar.js: hide TimeUI toggle from settings modal on mobile Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: rescue #timeUI back to staging when another tool opens Subscribe to activeToolName changes — when a tool becomes active while TimeUI is showing, move #timeUI back to #timeUIMobileStaging before the new tool's make() clears #tools. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: remove separatedTool/justification config toggles, fix review issues - Remove separatedTool checkbox and justification dropdown from Legend and Identifier config.json (these are always separated, not configurable) - Remove justification property/code from LegendTool.js, IdentifierTool.js - Simplify Globe_.js separated tool count (no justification filter) - Remove justification from Reference-Mission config blueprint - Update LegendTool help docs and Legend.md documentation - Add --color-a-rgb fallback (29,31,32) in SeparatedTools.module.css - Add display:none !important to .panelIdentifier to prevent 12px gap - Update e2e test comment Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: circular import in TimeUI.js, toolbar/bottomFloatingBar position sync - TimeUI.js: replace top-level useUIStore import with lazy _getUIStore() accessor to avoid 'Cannot access useUIStore before initialization' circular import error at _remakeTimeSlider - SplitScreens.jsx: skip #timeUI reparenting observer on mobile (mobile uses MobileTimeUIToggle to manage #timeUI placement in #tools) - BottomElementPositioner.jsx: unify mobile transition to 0.3s (matches toolsWrapper and toolbar), guard pxIsTools against undefined - Toolbar.jsx: align toolbar transition to 0.3s ease-out Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * LegendTool fix empty message * chore: remove separated tools offset logic from Globe_.js Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: skip _makeHistogram on mobile (no timeline slider, timestamps unset) _makeHistogram renders inside the timeline slider which doesn't exist on mobile. Without it, _timelineStartTimestamp is NaN, causing 'Invalid time value' RangeError at toISOString(). Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile TimeUI — populate expanded rows, fix Invalid date, fix panel height - TimeUI.js attachEvents: use _initialStart/_initialEnd on mobile (same as desktop) instead of L_.TimeControl_ which isn't set yet at init time. Fixes 'Invalid date' in start/end time inputs. - TimeUI.js fina: set expanded=true on mobile and call _populateExpandedRows() so year/month/day/hour rows actually render. Removed position:absolute and pointer-events:none overrides. - Toolbar.jsx: set tool panel height to 217px (TimeUI.height) instead of 45% viewport — matches actual TimeUI content height. - UserInterfaceMobile_.css: expanded content flows naturally (position:relative), hide start time inputs, allow overflow scroll, flex-wrap topbar. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile TimeUI justify-content center, restore toolbar border-bottom - Add justify-content: center to #mmgisTimeUIMain on mobile - Remove border-bottom: none override so toolbar keeps its default border Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile TimeUI overflow hidden, scalebar/compass fixed at 40px offset - #timeUI overflow-y: hidden (was auto, causing 2px scroll) - Scalebar/compass/map controls stay at fixed 40px offset (above toolbar) regardless of tool panel state — no longer shift up by pxIsTools Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Implement multi-tier knowledge architecture - Restructure AGENTS.md from 745 lines to 106 lines (Tier 1: essential context) - Create knowledge/ directory with 30+ wiki-style documentation files (Tier 2: deep knowledge) - Create knowledge/reference/ with 8 detailed reference files (Tier 3: lookup material) - Move AI-GETTING-STARTED.md and AI-DEVELOPMENT.md to knowledge/ - Update all file references in .specify/templates and blueprints - Create knowledge/README.md as the full knowledge base index - Create knowledge/reference/README.md as reference material index Three-tier knowledge discovery system: Tier 1: AGENTS.md (~106 lines) - scannable in <2 minutes Tier 2: knowledge/*.md - deep knowledge on architecture, tools, APIs, DB, infra Tier 3: knowledge/reference/*.md - coding conventions, API reference, troubleshooting Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 4.3.29-20260501 [version bump] * fix: mobile toolbar active button style matches desktop, fix icon alignment - All mobile toolbar buttons (ToolButton, MobileCoordButton, MobileTimeUIToggle) now use display:flex with align-items/justify-content center for proper vertical icon centering - MobileCoordButton: changed 'active' class to 'toolButtonActive' to match the global CSS active style (color-mmgis + color-i background) - Removed inline color overrides so CSS .toolButtonActive takes effect Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Add Devin knowledge notes from past MMGIS sessions Include curated lessons learned from past Devin sessions: - CI/CD: ignore build-arm64/amd64 failures, focus on required checks - Child sessions: no separate PRs when consolidating - ENV triple-update rule (.env, sample.env, ENVs.md) - Error handling: use logger with infrastructure_error for fatal startup errors - Path traversal security: stay within /Missions, handle subpath serving - Database initialization architecture and migration patterns - API authentication behavior across AUTH modes - Auto-generated MMGIS concept index Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile toolbar active button style, icon alignment, tool deactivation - Active toolbar buttons get desktop-matching margin (1px 0) and border-radius (8px) via .toolButton.toolButtonActive CSS rule - Removed line-height: 40px from .toolButton (flex centering handles vertical alignment, line-height was pushing icons up) - MobileCoordButton now watches activeToolName store and deactivates when another tool opens (fixes coords staying active) - MobileTimeUIToggle sets activeToolName='MobileTimeUI' when opening so coords/other buttons can detect it and deactivate - MobileTimeUIToggle clears activeToolName when closing - Both custom buttons skip self-deactivation via name check Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix cross-references: convert backtick refs to markdown links, add Devin knowledge notes Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile toolbar icon height 40px, button margins for active padding - #toolbar .toolButton i: height 40px fixes icon vertical alignment - #toolbar .toolButton: margin 0 2px gives spacing between buttons - #toolbar .toolButton.toolButtonActive: margin 1px 2px so active background has visual padding around the icon Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Rename knowledge/ to .knowledge/ for consistency with .specify/ convention Dot-prefix signals agent infrastructure (not source code), consistent with .specify/, .github/, .vscode/ conventions. All cross-references updated. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: mobile toolbar icon line-height 40px, active button padding via height - Coord and TimeUI button <i> icons get line-height: 40px - Active buttons: height 34px (vs 40px toolbar) creates visual padding around the active background, centered by flex align-items - Buttons get margin: 0 1px for horizontal spacing Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix broken cross-reference: 06.2 -> 06.1-configure-rest-api.md Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: close active tool + cancel deferred cleanup in MobileCoordButton/TimeUI - MobileCoordButton: call closeActiveTool() before opening, destroy _pendingCloseTool if set, increment _closeSeq to cancel deferred tools.innerHTML clear - MobileTimeUIToggle: same _pendingCloseTool + _closeSeq fix after closeActiveTool() to prevent 420ms deferred cleanup from wiping #timeUI after it's placed in #tools - Removed redundant closeActiveTool() from MobileCoordButton close path (was being called after destroy, not needed) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: active mobile toolbar buttons 34x34px (square) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Drastically compress .knowledge/ — keep only unique agent content Remove 33 wiki files that duplicate docs/pages/ content. Remove 9 reference/ files derivable from source code. Keep only 5 files (down from 46): - AI-GETTING-STARTED.md (agent setup walkthrough) - AI-DEVELOPMENT.md (spec-kit workflow) - conventions-and-gotchas.md (naming, code style, common issues) - 12-devin-knowledge-notes.md (CI, auth, DB init, security gotchas) - README.md (index pointing to docs/pages/ for everything else) Principle: don't duplicate docs/ — only keep what's uniquely agent-optimized. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Rename to knowledge-notes.md, remove Devin branding and fork-specific CI section Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: hide mmgis-map-logo on mobile Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Restore Database Safety Rules for AI Agents section in AGENTS.md Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: shift compass and map scale 6px to the right (both mobile and desktop) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Add back Important Instructions, code pattern templates, and detailed project structure - Important Instructions in AGENTS.md: MCP tools, hot-reload, Reference Mission - .knowledge/code-patterns.md: full directory tree with key directory annotations, plus copy-paste templates for Express routes, Sequelize models, Tool plugins, and WebSocket handlers Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Update project structure trees to reflect current filesystem Add missing directories: tests/, .knowledge/, .specify/, .github/, views/, private/, spice/, build/, examples/, scripts/middleware.js. Both abbreviated (AGENTS.md) and detailed (.knowledge/code-patterns.md) trees now match the actual repo layout. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 4.3.30-20260501 [version bump] * Add Layers_.js to project structure (key singleton L_) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix project structure: correct API layout, frontend modules, code templates API/Backend/ uses feature-domain modules (Draw/, Users/, Config/, etc.) with setup.js + routes/ + models/ per feature — not APIs/ or Databases/. Frontend essence/ has Components/, Helpers/, LandingPage/, mmgisAPI/, services/ — not Ancillary/. Basics/ includes all singletons (Globe_, Formulae_, ToolController_, Viewer_, ComponentController_, Test_). Code templates updated to match actual patterns (setup.js, module.exports). Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * refactor: remove test infrastructure (Test_ module, testModules, DrawTool.test) - Delete src/essence/Basics/Test_/ directory - Delete src/essence/Tools/Draw/DrawTool.test.js - Remove Test_ import and Shift+T keydown handler from essence.js - Remove tests key from Draw tool config.json - Remove testModules generation logic from API/updateTools.js Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 4.3.31-20260501 [version bump] * style: move Cesium link button to top-right and match Leaflet zoom button styling - Change control container from top-left to top-right positioning - Update button size from 26px to 30px to match Leaflet zoom controls - Use CSS variables (--color-a, --color-f, --color-mmgis) instead of hardcoded colors - Add border-radius and box-shadow matching Leaflet control appearance - Update hover/inactive states to use themed colors Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: anchor map logo to viewport instead of Leaflet map panel - Change MapLogo parent from .leaflet-bottom.leaflet-right to #main-container - Switch CSS position from absolute to fixed for viewport anchoring - Add explicit bottom-offset positioning in BottomElementPositioner (desktop) - Add explicit bottom-offset positioning in BottomElementPositioner (mobile) - Logo stays at viewport right edge regardless of open side panels - Retains smooth bottom offset transitions when bottom bar appears Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * docs: remove references to deleted test infrastructure (Test_, DrawTool.test) - Remove Test_/ from project structure in .knowledge/code-patterns.md - Remove DrawTool.test.js references from specs/006 spec, plan, and tasks - Remove Draw Tool Testing section from tasks.md Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 4.3.32-20260501 [version bump] * fix: append logo to document.body to avoid filter containing block #main-container has a CSS filter property which creates a new containing block per the CSS spec, causing position:fixed to behave like absolute. Appending to document.body ensures true viewport-fixed positioning. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix: prevent mobile topBarTitleName text wrapping by replacing max-width with white-space: nowrap Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 4.3.33-20260501 [version bump] * chore: bump version to 5.0.0 and update changelog Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * refactor(ui): move Screenshot/Fullscreen to BottomBar, About to TopBar kebab TopBar kebab menu now contains only Keyboard Shortcuts, Settings, and About (About now shows on both desktop and mobile). BottomBarReact now renders Screenshot, Fullscreen, and Copy Link buttons (top to bottom) following the same IconButton + Tooltip pattern. The About button has been removed from BottomBarReact. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.1-20260505 [version bump] * feat(mobile): enforce exclusive panel toggling on mobile in TopBar Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.1-20260505 [version bump] * style: reposition LithoSphere globe controls to match Leaflet/Cesium theme Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.1-20260505 [version bump] * feat(topbar): hide Viewer/Globe toggles based on configured panels Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * style(bottombar): reorder buttons (Copy Link, Screenshot, Fullscreen) and unify size Reorder the BottomBarReact buttons top-to-bottom to: Copy Link, Screenshot, Fullscreen. Move the 24x24 button sizing from the #topBarLink id selector in mmgis.css into the .barButton class in BottomBarReact.module.css so all three buttons share the same compact size as the original Copy Link button. Drop the now redundant #topBarLink rule. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * style(bottombar): increase padding-bottom to 12px and button margin to 3px 0 Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * style: rearrange globe controls — compass top-right circular, nav row, vertical column, panels open left Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.2-20260505 [version bump] * chore: bump version to 5.0.2-20260505 [version bump] * style: anchor observe settings panel right:34px and float nav hover panels Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * feat(theming): add 5 new themes, --color-shadow variable, and configure ThemePreview - Add Dark Terra, Dark Nebula, Dark Lunar, Dark Supernova, Light Botanical themes - Add --color-shadow CSS variable to every theme + :root fallback - Replace hardcoded rgba shadow colors with var(--color-shadow) in TopBar, Toolbar, SeparatedTools, ToolPanel, FloatingElements, Dropdown, Modal, and SplitScreens - Add Custom shadowcolor color picker in tab-ui-config and apply it via Stylize - Add ThemePreview component (configure/src) wired through Maker.js as a new 'themepreview' row type so the configure UI shows a live mini mockup of the selected theme Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.2-20260505 [version bump] * fix(configure/ThemePreview): tighten top spacing and live-preview Custom theme - Pull the preview up by 12px so the gap below the theme dropdown is tighter. - Read the Custom color pickers (look.primarycolor / secondarycolor / tertiarycolor / accentcolor / shadowcolor / topbarcolor / toolbarcolor / mapcolor) from the configuration and overlay them on Dark Default so the preview reflects Custom theme edits live, matching Stylize.js's runtime behavior. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.3-20260505 [version bump] * feat(themes): add Dark Heliosphere, Dark Monokai, and Light Solarized - Dark Heliosphere: deep night purple surface with corona-orange accent. - Dark Monokai: warm graphite surface with lime accent (Monokai-inspired). - Light Solarized: classic solarized base3/base02 with blue accent. Mirror added to configure/src/themes/themes.js for the ThemePreview, and the three names appended to the Color Theme dropdown options. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix(coordinates): respect time.initiallyOpen when live deep-link is set * chore: bump version to 5.0.3-20260505 [version bump] * refactor(theming): remove Custom theme + per-field color overrides - Drop the 'Custom' option from the Color Theme dropdown. - Remove all Custom Color Options (look.primarycolor, .secondarycolor, .tertiarycolor, .accentcolor, .bodycolor, .topbarcolor, .toolbarcolor, .mapcolor, .hightlightcolor, .shadowcolor) from tab-ui-config.json. - Strip the matching DOM/CSS-variable override block from Stylize.js; Stylize now just applies the selected preset theme (and the page logo). - Drop the empty bodycolor/topbarcolor/toolbarcolor/mapcolor/shadowcolor defaults from API/templates/config_template.js. - Simplify ThemePreview to render the selected preset directly — no Custom branch, no overlay logic. Preset themes cover all the looks we want and keep the configure surface much smaller. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * style(time-ui): round corners on TimeUI shell, action wrappers, mode dropdown - #timeUI: 10px border-radius on the outer time control bar. - #mmgisTimeUIActionsLeft / #mmgisTimeUIActionsRight: 10px border-radius so the action clusters sit as rounded chips. - #mmgisTimeUIActionsRight > div (excluding #mmgisTimeUIPresent): 10px border-radius on each action button so they match the wrapper. - #mmgisTimeUIModeDropdown: 40px height + 10px border-radius to align with the rest of the bar; clear the dropy default border-color so the rounded edge isn't outlined. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.4-20260505 [version bump] * feat(configure): mark light themes as (experimental) in dropdown label Light themes still have outstanding contrast issues, so flag them in the Color Theme dropdown without changing the saved value. - Maker dropdown now accepts options as either a plain string (current behavior) or { value, label } so the rendered label can differ from the persisted value. - tab-ui-config switches the six light themes to { value, label } form with '(experimental)' appended to the label only. Existing mission configs that already saved 'Light Default' etc. continue to match. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Fix timeUI border radius * fix(mobile): rescue #timeUI before tool make() destroys it Clicking Layers -> Time -> Layers -> Time on mobile caused the bottom panel to render LayersTool content with TimeUI height. The #timeUI DOM element was destroyed when LayersTool.make() called $('#tools').empty(), before the async React useEffect in MobileTimeUIToggle could rescue it to its staging container. - ToolController_.makeTool: synchronously move #timeUI from #tools back to #timeUIMobileStaging (and reset TimeUI store flags) on mobile, before invoking the new tool's make(). - MobileTimeUIToggle.handleClick: defensive fallback that re-initializes TimeUI if #timeUI no longer exists when the toggle is activated. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix(mobile): move re-initialized #timeUI from staging into #tools TimeUI.init() on mobile appends the new #timeUI to the hidden #timeUIMobileStaging container, so the fallback branch must also move it into #tools — otherwise the user sees an empty tool panel after the destroyed-element recovery path. Caught by Devin Review. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix(mobile): preserve #timeUI when Coordinates tool empties #tools On mobile, opening or closing the Coordinates tool runs $('#tools').empty() inside interfaceWithMMWebGIS / separateFromMMWebGIS. After the previous PR commits, clicking Coordinates -> Time still left the bottom panel empty because: - Coordinates.make() empties #tools while #timeUI is in staging (fine on its own), but the Coordinates teardown that fires after the user switches to the Time toggle (via MobileCoordButton's useEffect on activeToolName change) calls Coordinates.destroy() -> separateFromMMWebGIS(), which empties #tools wholesale and destroys the freshly-placed #timeUI. Add a rescueMobileTimeUI() helper that moves #timeUI from #tools back to #timeUIMobileStaging before each tools.empty() call in Coordinates, mirroring the rescue already done in ToolController_.makeTool(). Coordinates -> Time now correctly shows the TimeUI. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * fix(mobile): harden TimeUI fallback recovery (call fina(), de-dupe popovers) Devin Review correctly flagged that the safety-net path in MobileTimeUIToggle.handleClick was producing a partially-broken TimeUI when it fired: - TimeUI.init() unconditionally appends a new #timeUIPlayPopover_global to <body>, so a second init() left two elements with the same id. - TimeUI.init() alone does not wire up date pickers or per-button click handlers — that's TimeUI.fina()'s job. Without fina(), the recovered TimeUI rendered visually but Play / Previous / Next / Fit / Follow / Present / Expand were all dead. Before re-initializing, remove the stale #timeUIPlayPopover_global and #timeUIQuickSelectPopover_global divs to avoid duplicate ids. After the new #timeUI is moved into #tools, call TimeUI.fina() to populate the date pickers, attach the button click handlers, build the histogram, and populate the expanded mobile rows. Some delegated body/document handlers in attachEvents() will still be duplicated on this path; that is acceptable for a degraded recovery that should never run in practice now that the primary rescues in ToolController_.makeTool() and Coordinates.js cover all known paths. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.5-20260505 [version bump] * fix(mobile): Coordinates teardown only removes its own DOM The previous Coordinates fix was racing with itself: after the Time toggle synchronously moved #timeUI into #tools, MobileCoordButton's useEffect (triggered by the activeToolName change) ran on the next React tick and called L_.Coordinates.destroy(). That called separateFromMMWebGIS(), whose rescue moved #timeUI right back into the hidden staging div before tools.empty() — so the bottom panel ended up empty even though the time toggle was 'active'. Make separateFromMMWebGIS selective: only remove the Coordinates-specific DOM (#coordUIHeader and #CoordinatesDiv) instead of wiping all of #tools. Any other content already in #tools (e.g. #timeUI placed there by the Time toggle) is left alone. interfaceWithMMWebGIS still keeps the rescue + tools.empty() pattern on the open path so Coordinates always starts from a clean panel. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Bump DrawTool Temporal Drawings upward * chore: bump version to 5.0.6-20260505 [version bump] * chore: reset version to 5.0.0 Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * test(e2e): fix 9 pre-existing failures (test-only changes) - mmgis-api.spec.js: add form-fill login under AUTH=local; serialize describe to avoid concurrent-login race in the session store - coordinates.spec.js: TimeUI toggle was moved from the coordinates bar to the Settings modal; navigate via topbar kebab menu and assert the checkbox is rendered - widgets.spec.js: target .leaflet-control-zoom-in/-out specifically; the bare .leaflet-control-zoom class is also used by the home/reset control, so the original assertion was always false - sites.spec.js: scope panel selector to #toolPanel; both the toolbar icon and the panel container share id="SitesTool" Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.1-20260505 [version bump] * Revert "chore: bump version to 5.0.1-20260505 [version bump]" This reverts commit 4880204c1163be5d1d7fa96d14a0ed018c6f586c. * fix: prevent filter operator dropdown clipping in Layers panel Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.1-20260507 [version bump] * revert: keep dropy openUp:true for operator dropdowns Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * Revert "chore: bump version to 5.0.1-20260507 [version bump]" This reverts commit d67c369ed437e47d658ae051348d377978dc48ed. * chore: bump version to 5.0.1-20260507 [version bump] * Revert "chore: bump version to 5.0.1-20260507 [version bump]" This reverts commit 29565ed829a55e9c241a789c9a3901d11cb5ca67. * chore: bump version to 5.0.1-20260507 [version bump] * Revert "chore: bump version to 5.0.1-20260507 [version bump]" This reverts commit 50e357604ebe9378564619b34c508b63cfb62c1d. * chore: bump version to 5.0.1-20260507 [version bump] * chore: bump version to 5.0.2-20260511 [version bump] * fix: render Globe panel immediately on first open without window resize Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.3-20260511 [version bump] * feat: add theme borders to panels and gradient backgrounds to splitters Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.4-20260511 [version bump] * style: bump split shadow gradient opacity to 0.4 Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * style: hotkeys modal 3-col grid + smaller leaflet zoom button gap Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * style: prevent hotkey label/value wrapping (ellipsis instead) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * style: hotkeys modal single column, no wrap, no truncation Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.4-20260511 [version bump] * style: hotkeys modal dividers, invert title/subtitle colors, rename title, margin above subtitles Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * style: move splitter gradient to themed CSS class, restore hover feedback Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.5-20260511 [version bump] * style: hotkeys section titles use --color-h (matches rest of app) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.5-20260511 [version bump] * fix: guard Globe_.init() inside rAF to prevent double instantiation Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.6-20260512 [version bump] * feat(plugins): per-plugin deps, lazy tool loading, validation, shared discovery Phase 3 — Plugin config validation + override warnings: - New API/pluginValidation.js with validatePluginConfig() for tool, component, and backend manifests. Validates required fields (name, paths), object/string shape of paths, dependencies block (npm/python.pip/python.conda), and warns on unknown top-level fields. - updateTools()/updateComponents() now skip invalid plugins and emit override warnings (matching what components already logged for tools). Phase 2 — Shared discoverPlugins() utility: - New API/pluginDiscovery.js consolidates the duplicated scanning logic from updateTools(), updateComponents(), and getBackendSetups(). Supports exact- name and substring container patterns, JSON/require/no-op loaders, and skips dot/underscore-prefixed dirs. - updateTools.js and setups.js refactored on top of the shared helper. Phase 1 — Per-plugin dependency declaration + build-time aggregation: - Plugin config.json may now declare a 'dependencies' block (npm + python.pip + python.conda). validatePluginConfig() also validates this shape. - New scripts/resolve-plugin-deps.js scans every tool/component/backend plugin and writes plugin-package.json, plugin-python-requirements.txt, and plugin-conda-deps.txt. Detects version conflicts and fails loudly. - scripts/build.js calls resolvePluginDeps() before updateTools(). - Dockerfile installs the aggregated plugin npm and pip deps after the root npm ci, using --no-save / --no-package-lock / --ignore-scripts so the root lockfile is untouched. - Animation tool migrated: ffmpeg/gifshot/html2canvas now declared in its config.json (kept in root package.json for transitional compat). - Generated artifacts gitignored. Phase 4 — Lazy loading of tool bundles: - updateTools() now emits dynamic-import arrow functions in the generated src/pre/tools.js with webpackChunkName hints so each tool is split into its own chunk (Kinds stays static because it's required synchronously). - ToolController_ gains ensureToolLoaded(name) and getLoadedTool(name) helpers and makeTool is async; init/finalizeTools and the separated-tool auto-open flow are updated to handle lazy modules. - Toolbar.jsx, SeparatedTools.jsx, SitesTool.js, and Layers_.js migrated to resolve LayersTool/etc. via the new helpers instead of poking toolModules directly. Tests & docs: - tests/fixtures/test-plugin-tools/{TestPlugin,InvalidPlugin,OverridePlugin} + tests/helpers/plugin-helpers.js with install/uninstall helpers. - New unit specs: pluginValidation, pluginDiscovery, updateTools, resolvePluginDeps, toolLazyLoading (57 tests, all passing). - CONTRIBUTING.md and docs/pages/Contributing/Contributing.md updated with schema, override behaviour, dependency declaration, build-time aggregation, conflict detection, and Docker integration. * chore: bump version to 5.0.7-20260512 [version bump] * fix: make Globe_.init() idempotent against multi-init Globe_.init() previously constructed a fresh GlobeRenderer on every call, which after #71 could happen multiple times for a single toggle (uiStore setTimeout + TopBar rAF). Each extra construction appends another .cesium-widget / _lithosphere_scene to #globe and leaves event handlers wired to dereferenced renderer state, which has been observed to break LithoSphere globe control buttons on configurations where the globe panel starts closed at boot. Add a top-of-init() guard that bails out and calls invalidateSize() when a renderer already exists. Single small, surgical change; no behavior change for the !L_.hasGlobe mock-swap path or for first-time construction. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * chore: bump version to 5.0.7-20260512 [version bump] * test(plugins): generate src/pre/tools.js on demand in toolLazyLoading spec The Playwright unit-tests CI step runs before `npm run build` so the gitignored `src/pre/tools.js` artifact does not yet exist on disk. Add a beforeAll hook that invokes `updateTools()` to regenerate it when missing, keeping the spec self-contained on both CI and dev machines that already built locally. * fix(tools): defensive getTool() + preload flag for cross-referenced tools Devin Review flagged a behavioural regression introduced by Phase 4: `ToolController_.getTool(name)` previously always returned a method- callable object (real module or `{ use(){} }` stub) because every tool was statically imported. After Phase 4, unresolved lazy loaders are `() => import(...)` functions, so callers like `Map_.getTool('InfoTool').use(...)`, `mmgisAPI.getTool('DrawTool').filesOn`, and `LegendTool` calling `LayersTool.populateCogScale` would crash with TypeError until the target tool was opened. Two fixes: 1. **Defensive getTool()**: Returns the legacy fallback stub when the tool module is still a lazy-loader function, and fires off `ensureToolLoaded(name)` in the background so subsequent calls see the resolved module. Prevents all crashes immediately. 2. **`preload: true` config flag**: Tools reached synchronously from other code paths (Info, Draw, Layers, Chemistry) now declare `"preload": true` in their `config.json`. `ToolController_.init()` calls `preloadEagerTools()` which fires `ensureToolLoaded` for every such tool right after toolbar setup — the chunks download in parallel with the rest of the page becoming interactive, so by the time a user clicks a feature the InfoTool module is already resolved. `validatePluginConfig` now accepts `preload` as a known tool field; CONTRIBUTING.md and docs/pages/Contributing/Contributing.md updated to document when to set it. Added a unit test covering the defensive getTool behaviour and the `preload` propagation through `toolConfigs`. * chore: bump version to 5.0.8-20260512 [version bump] * revert(plugins): remove Phase 4 lazy tool loading and preload mechanism Phase 4 lazy emission caused cross-tool consumers (Map_ feature-click, mmgisAPI, LegendTool) to receive raw '() => import(...)' arrows from ToolController_.getTool(), breaking InfoTool open. Reverting to the pre-Phase-4 behavior of static tool imports. - API/updateTools.js: generated src/pre/tools.js now emits 'import FooTool from ...' for every tool (Kinds stays static too). - ToolController_.js: getTool/makeTool back to sync; ensureToolLoaded, getLoadedTool, preloadEagerTools deleted; separated-tool auto-open flow simplified to direct sync calls. - Toolbar.jsx, SeparatedTools.jsx, Layers_.js: revert async/lazy patterns to sync ToolController_.toolModules[name] access. - API/pluginValidation.js: drop 'preload' from KNOWN_FIELDS. - src/essence/Tools/{Info,Draw,Layers,Chemistry}/config.json: drop 'preload: true'. - CONTRIBUTING.md + docs: remove preload documentation. - tests/unit/toolLazyLoading.spec.js: rewrite to verify static imports instead of lazy loaders. Also: log standard backends at startup (parity with plugin backends and with tools/components), so all backends now produce 'info Loaded backend: <name> from <container>' at boot. Phases 1-3 (per-plugin dependency aggregation, shared discoverPlugins, config validation + override warnings) are unaffected. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * feat(logger): new 'loaded' level (purple bg) for tool/component/backend startup Previously the 'Loaded tool/component/backend: X from Y' lines used the generic blue 'info' tag. They now use a dedicated 'loaded' level rendered with a purple (#a855f7) background, so plugin discovery output is visually distinct from other info messages. - API/logger.js: add 'loaded' case to the dev-mode switch (white text on purple bg) and suppress the redundant 'Caller:' echo for it (matches how 'info' and 'success' are handled). - API/updateTools.js: registerPlugin now logs at level 'loaded'. Drops the redundant 'Loaded ' prefix since the level tag now reads 'loaded'. - API/setups.js: standard and plugin backend startup logs use the new level, same drop of the 'Loaded ' prefix. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * feat(logs): 'Plugging in Tools/Components/Backends...' headings Rename the cyan banner messages in scripts/build.js and scripts/server.js from 'Updating Tools...' / 'Updating Components...' to 'Plugging in Tools...' / 'Plugging in Components...' so the headings match the plugin terminology used everywhere else (plugin-package.json, discoverPlugins, etc.). Also add a matching 'Plugging in Backends...' banner before setups.getBackendSetups() in scripts/server.js so backends get an equivalent title block to tools and components. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * style(logs): cyan banner lines lead with a blank line instead of trailing one Move the \n from the end to the beginning of every cyan banner in scripts/build.js and scripts/server.js (Resolving Plugin Dependencies, Plugging in Tools/Components/Backends, Validating Environment Variables, Starting websocket, Starting the development server) so that the blank line visually separates each section above its title rather than below it. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> * feat(plugins): postinstall hook auto-installs plugin npm deps Plain `npm install` (or `np…
1 parent bd540cf commit 740a572

6 files changed

Lines changed: 8 additions & 8 deletions

File tree

blueprints/Missions/Reference-Mission/config.reference-mission.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3244,7 +3244,7 @@
32443244
"layerDems": [
32453245
{
32463246
"layer": "USGS SF DEM — Elevation",
3247-
"dem": "Data/DEMs/USGS_13_n38w123_20250826_SFHill.tif"
3247+
"url": "Data/DEMs/USGS_13_n38w123_20250826_SFHill.tif"
32483248
}
32493249
]
32503250
}

configure/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "configure",
3-
"version": "5.0.10-20260518",
3+
"version": "5.0.11-20260519",
44
"homepage": "./configure/build",
55
"private": true,
66
"dependencies": {

configure/src/metaconfigs/layer-tile-config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -771,8 +771,8 @@
771771
"width": 4
772772
},
773773
{
774-
"field": "dem",
775-
"name": "DEM Path",
774+
"field": "url",
775+
"name": "DEM URL",
776776
"description": "",
777777
"type": "text",
778778
"width": 8

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mmgis",
3-
"version": "5.0.10-20260518",
3+
"version": "5.0.11-20260519",
44
"description": "A web-based mapping and localization solution for science operation on planetary missions.",
55
"homepage": "build",
66
"repository": {

src/essence/Tools/Measure/MeasureTool.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,7 @@ let MeasureTool = {
901901
name:
902902
item.name ||
903903
L_.layers.data[name]?.display_name,
904-
path: item.url,
904+
path: item.url || item.dem,
905905
})
906906
}
907907
}

src/essence/Tools/Measure/config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
"width": 4
4848
},
4949
{
50-
"field": "dem",
51-
"name": "DEM Path",
50+
"field": "url",
51+
"name": "DEM URL",
5252
"description": "",
5353
"type": "text",
5454
"width": 8

0 commit comments

Comments
 (0)