Merge pull request #127 from bnema/chore/update-deps
chore: update dependencies and add dependabot auto-merge
26 files · +1417 -679
A .github/CODEOWNERS +2 -0
| @@ -0,0 +1,2 @@ | |||
| 1 | + | # Default owner for everything | |
| 2 | + | * @bnema | |
| @@ -0,0 +1,2 @@ | |||||
| 1 | + | # Default owner for everything | |||
| 2 | + | * @bnema | |||
A .github/dependabot.yml +28 -0
| @@ -0,0 +1,28 @@ | |||
| 1 | + | version: 2 | |
| 2 | + | updates: | |
| 3 | + | - package-ecosystem: gomod | |
| 4 | + | directory: / | |
| 5 | + | schedule: | |
| 6 | + | interval: weekly | |
| 7 | + | groups: | |
| 8 | + | go-dependencies: | |
| 9 | + | patterns: | |
| 10 | + | - "*" | |
| 11 | + | ||
| 12 | + | - package-ecosystem: npm | |
| 13 | + | directory: /webui | |
| 14 | + | schedule: | |
| 15 | + | interval: weekly | |
| 16 | + | groups: | |
| 17 | + | npm-dependencies: | |
| 18 | + | patterns: | |
| 19 | + | - "*" | |
| 20 | + | ||
| 21 | + | - package-ecosystem: github-actions | |
| 22 | + | directory: / | |
| 23 | + | schedule: | |
| 24 | + | interval: weekly | |
| 25 | + | groups: | |
| 26 | + | github-actions: | |
| 27 | + | patterns: | |
| 28 | + | - "*" | |
| @@ -0,0 +1,28 @@ | |||||
| 1 | + | version: 2 | |||
| 2 | + | updates: | |||
| 3 | + | - package-ecosystem: gomod | |||
| 4 | + | directory: / | |||
| 5 | + | schedule: | |||
| 6 | + | interval: weekly | |||
| 7 | + | groups: | |||
| 8 | + | go-dependencies: | |||
| 9 | + | patterns: | |||
| 10 | + | - "*" | |||
| 11 | + | ||||
| 12 | + | - package-ecosystem: npm | |||
| 13 | + | directory: /webui | |||
| 14 | + | schedule: | |||
| 15 | + | interval: weekly | |||
| 16 | + | groups: | |||
| 17 | + | npm-dependencies: | |||
| 18 | + | patterns: | |||
| 19 | + | - "*" | |||
| 20 | + | ||||
| 21 | + | - package-ecosystem: github-actions | |||
| 22 | + | directory: / | |||
| 23 | + | schedule: | |||
| 24 | + | interval: weekly | |||
| 25 | + | groups: | |||
| 26 | + | github-actions: | |||
| 27 | + | patterns: | |||
| 28 | + | - "*" | |||
A .github/workflows/dependabot-auto-merge.yml +25 -0
| @@ -0,0 +1,25 @@ | |||
| 1 | + | name: Dependabot auto-merge | |
| 2 | + | ||
| 3 | + | on: pull_request | |
| 4 | + | ||
| 5 | + | permissions: | |
| 6 | + | contents: write | |
| 7 | + | pull-requests: write | |
| 8 | + | ||
| 9 | + | jobs: | |
| 10 | + | dependabot: | |
| 11 | + | runs-on: ubuntu-latest | |
| 12 | + | if: github.actor == 'dependabot[bot]' | |
| 13 | + | steps: | |
| 14 | + | - name: Dependabot metadata | |
| 15 | + | id: metadata | |
| 16 | + | uses: dependabot/fetch-metadata@v2 | |
| 17 | + | with: | |
| 18 | + | github-token: "${{ secrets.GITHUB_TOKEN }}" | |
| 19 | + | ||
| 20 | + | - name: Auto-merge patch and minor updates | |
| 21 | + | if: steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor' | |
| 22 | + | run: gh pr merge --auto --squash "$PR_URL" | |
| 23 | + | env: | |
| 24 | + | PR_URL: ${{ github.event.pull_request.html_url }} | |
| 25 | + | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| @@ -0,0 +1,25 @@ | |||||
| 1 | + | name: Dependabot auto-merge | |||
| 2 | + | ||||
| 3 | + | on: pull_request | |||
| 4 | + | ||||
| 5 | + | permissions: | |||
| 6 | + | contents: write | |||
| 7 | + | pull-requests: write | |||
| 8 | + | ||||
| 9 | + | jobs: | |||
| 10 | + | dependabot: | |||
| 11 | + | runs-on: ubuntu-latest | |||
| 12 | + | if: github.actor == 'dependabot[bot]' | |||
| 13 | + | steps: | |||
| 14 | + | - name: Dependabot metadata | |||
| 15 | + | id: metadata | |||
| 16 | + | uses: dependabot/fetch-metadata@v2 | |||
| 17 | + | with: | |||
| 18 | + | github-token: "${{ secrets.GITHUB_TOKEN }}" | |||
| 19 | + | ||||
| 20 | + | - name: Auto-merge patch and minor updates | |||
| 21 | + | if: steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor' | |||
| 22 | + | run: gh pr merge --auto --squash "$PR_URL" | |||
| 23 | + | env: | |||
| 24 | + | PR_URL: ${{ github.event.pull_request.html_url }} | |||
| 25 | + | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |||
M CHANGELOG.md +7 -0
| @@ -2,6 +2,13 @@ | |||
| 2 | 2 | ||
| 3 | 3 | All notable changes to this project will be documented in this file. | |
| 4 | 4 | ||
| 5 | + | ## [Unreleased] | |
| 6 | + | ||
| 7 | + | ### Fixed | |
| 8 | + | - **Session snapshot FK constraint**: Fixed SQLite foreign key constraint violation when snapshot service tried to save before session was persisted to database. Added ready flag and callback notification pattern. | |
| 9 | + | - **Stacked pane index out of bounds**: Fixed crash when domain model and UI got out of sync during stacked pane operations. Added bounds checking and proper rollback when UI updates fail. | |
| 10 | + | - **Noisy gesture navigation logs**: Mouse button back/forward navigation errors (expected when no history) now log at debug level instead of error level. | |
| 11 | + | ||
| 5 | 12 | ## [0.25.0] - 2026-01-08 | |
| 6 | 13 | ||
| 7 | 14 | ### Added | |
| @@ -2,6 +2,13 @@ | |||||
| 2 | 2 | ||||
| 3 | All notable changes to this project will be documented in this file. | 3 | All notable changes to this project will be documented in this file. | ||
| 4 | 4 | ||||
| 5 | + | ## [Unreleased] | |||
| 6 | + | ||||
| 7 | + | ### Fixed | |||
| 8 | + | - **Session snapshot FK constraint**: Fixed SQLite foreign key constraint violation when snapshot service tried to save before session was persisted to database. Added ready flag and callback notification pattern. | |||
| 9 | + | - **Stacked pane index out of bounds**: Fixed crash when domain model and UI got out of sync during stacked pane operations. Added bounds checking and proper rollback when UI updates fail. | |||
| 10 | + | - **Noisy gesture navigation logs**: Mouse button back/forward navigation errors (expected when no history) now log at debug level instead of error level. | |||
| 11 | + | ||||
| 5 | ## [0.25.0] - 2026-01-08 | 12 | ## [0.25.0] - 2026-01-08 | ||
| 6 | 13 | ||||
| 7 | ### Added | 14 | ### Added | ||
M cmd/dumber/main.go +96 -32
| @@ -29,6 +29,7 @@ import ( | |||
| 29 | 29 | "github.com/bnema/dumber/internal/logging" | |
| 30 | 30 | "github.com/bnema/dumber/internal/ui" | |
| 31 | 31 | "github.com/bnema/dumber/internal/ui/theme" | |
| 32 | + | "github.com/rs/zerolog" | |
| 32 | 33 | ) | |
| 33 | 34 | ||
| 34 | 35 | // Build-time variables (set via ldflags). | |
| @@ -75,17 +76,12 @@ func runGUI() int { | |||
| 75 | 76 | cfg := initConfig() | |
| 76 | 77 | timer.Mark("config") | |
| 77 | 78 | ||
| 78 | - | ctx := initStartupContext(cfg) | |
| 79 | + | ctx := initStartupContextWithTrace(cfg) | |
| 79 | 80 | timer.Mark("logger") | |
| 80 | 81 | bootstrapLog := logging.FromContext(ctx) | |
| 81 | 82 | ||
| 82 | - | // Parallel phase: directories and theme setup | |
| 83 | - | initResult, err := bootstrap.RunParallelInit(bootstrap.ParallelInitInput{ | |
| 84 | - | Ctx: ctx, | |
| 85 | - | Config: cfg, | |
| 86 | - | }) | |
| 83 | + | initResult, err := runParallelInitPhase(ctx, cfg) | |
| 87 | 84 | if err != nil { | |
| 88 | - | handleParallelInitError(ctx, err) | |
| 89 | 85 | return 1 | |
| 90 | 86 | } | |
| 91 | 87 | timer.MarkDuration("parallel_phase", initResult.Duration) | |
| @@ -101,44 +97,27 @@ func runGUI() int { | |||
| 101 | 97 | } | |
| 102 | 98 | timer.Mark("db_webkit_parallel") | |
| 103 | 99 | ||
| 104 | - | browserSession, sessionCtx, err := bootstrap.StartBrowserSession(ctx, cfg, repos.session, !needsEagerDB) | |
| 105 | - | if err != nil { | |
| 106 | - | bootstrapLog.Fatal().Err(err).Msg("failed to start session") | |
| 107 | - | } | |
| 108 | - | if browserSession.LogCleanup != nil { | |
| 109 | - | defer browserSession.LogCleanup() | |
| 110 | - | } | |
| 111 | - | defer func() { _ = browserSession.End(sessionCtx) }() | |
| 100 | + | ctx, browserSession, sessionCleanup := initBrowserSession(ctx, cfg, repos, bootstrapLog) | |
| 101 | + | defer sessionCleanup() | |
| 112 | 102 | timer.Mark("session") | |
| 113 | 103 | ||
| 114 | - | ctx = sessionCtx | |
| 115 | 104 | log := logging.FromContext(ctx) | |
| 105 | + | logging.Trace().UpdateLogger(log) | |
| 106 | + | ||
| 116 | 107 | if stack.MessageRouter != nil { | |
| 117 | 108 | stack.MessageRouter.SetBaseContext(ctx) | |
| 118 | 109 | } | |
| 119 | 110 | ||
| 120 | - | // Repositories and use cases | |
| 121 | 111 | useCases := createUseCases(repos, cfg) | |
| 122 | 112 | if needsEagerDB { | |
| 123 | 113 | handleAutoRestore(ctx, cfg, useCases, browserSession.Session.ID) | |
| 124 | 114 | } | |
| 125 | 115 | ||
| 126 | 116 | idleInhibitor := idle.NewPortalInhibitor(ctx) | |
| 127 | - | defer func() { | |
| 128 | - | if idleInhibitor != nil { | |
| 129 | - | _ = idleInhibitor.Close() | |
| 130 | - | } | |
| 131 | - | }() | |
| 117 | + | defer closeIdleInhibitor(idleInhibitor) | |
| 132 | 118 | timer.Mark("use_cases") | |
| 133 | 119 | ||
| 134 | - | // Build UI | |
| 135 | - | uiDeps := buildUIDependencies( | |
| 136 | - | ctx, cfg, initResult.ThemeManager, | |
| 137 | - | initResult.ColorResolver, initResult.AdwaitaDetector, | |
| 138 | - | &stack, repos, useCases, idleInhibitor, browserSession.Session.ID, | |
| 139 | - | ) | |
| 140 | - | configureDeferredInit(uiDeps, cfg, browserSession) | |
| 141 | - | app, err := ui.New(uiDeps) | |
| 120 | + | app, err := buildAndConfigureApp(ctx, cfg, initResult, &stack, repos, useCases, idleInhibitor, browserSession) | |
| 142 | 121 | if err != nil { | |
| 143 | 122 | log.Error().Err(err).Msg("failed to create application") | |
| 144 | 123 | return 1 | |
| @@ -146,12 +125,83 @@ func runGUI() int { | |||
| 146 | 125 | timer.Mark("ui_deps") | |
| 147 | 126 | timer.Log(ctx) | |
| 148 | 127 | ||
| 149 | - | // Signal handling | |
| 150 | 128 | setupSignalHandler(ctx, app) | |
| 151 | 129 | ||
| 152 | 130 | return app.Run(ctx, os.Args) | |
| 153 | 131 | } | |
| 154 | 132 | ||
| 133 | + | func initStartupContextWithTrace(cfg *config.Config) context.Context { | |
| 134 | + | logging.InitStartupTrace(cfg.Logging.Level) | |
| 135 | + | logging.Trace().Mark("config_loaded") | |
| 136 | + | ||
| 137 | + | ctx := initStartupContext(cfg) | |
| 138 | + | bootstrapLog := logging.FromContext(ctx) | |
| 139 | + | ||
| 140 | + | logging.Trace().SetLogger(bootstrapLog) | |
| 141 | + | logging.Trace().Mark("logger_init") | |
| 142 | + | ||
| 143 | + | return ctx | |
| 144 | + | } | |
| 145 | + | ||
| 146 | + | func runParallelInitPhase(ctx context.Context, cfg *config.Config) (*bootstrap.ParallelInitResult, error) { | |
| 147 | + | logging.Trace().Mark("parallel_start") | |
| 148 | + | initResult, err := bootstrap.RunParallelInit(bootstrap.ParallelInitInput{ | |
| 149 | + | Ctx: ctx, | |
| 150 | + | Config: cfg, | |
| 151 | + | }) | |
| 152 | + | if err != nil { | |
| 153 | + | handleParallelInitError(ctx, err) | |
| 154 | + | return nil, err | |
| 155 | + | } | |
| 156 | + | logging.Trace().Mark("parallel_done") | |
| 157 | + | return initResult, nil | |
| 158 | + | } | |
| 159 | + | ||
| 160 | + | func initBrowserSession( | |
| 161 | + | ctx context.Context, | |
| 162 | + | cfg *config.Config, | |
| 163 | + | repos *repositories, | |
| 164 | + | bootstrapLog *zerolog.Logger, | |
| 165 | + | ) (context.Context, *bootstrap.BrowserSession, func()) { | |
| 166 | + | deferPersist := restoreSessionID == "" && !cfg.Session.AutoRestore | |
| 167 | + | browserSession, sessionCtx, err := bootstrap.StartBrowserSession(ctx, cfg, repos.session, deferPersist) | |
| 168 | + | if err != nil { | |
| 169 | + | bootstrapLog.Fatal().Err(err).Msg("failed to start session") | |
| 170 | + | } | |
| 171 | + | cleanup := func() { | |
| 172 | + | if browserSession.LogCleanup != nil { | |
| 173 | + | browserSession.LogCleanup() | |
| 174 | + | } | |
| 175 | + | _ = browserSession.End(sessionCtx) | |
| 176 | + | } | |
| 177 | + | return sessionCtx, browserSession, cleanup | |
| 178 | + | } | |
| 179 | + | ||
| 180 | + | func closeIdleInhibitor(inhibitor port.IdleInhibitor) { | |
| 181 | + | if inhibitor != nil { | |
| 182 | + | _ = inhibitor.Close() | |
| 183 | + | } | |
| 184 | + | } | |
| 185 | + | ||
| 186 | + | func buildAndConfigureApp( | |
| 187 | + | ctx context.Context, | |
| 188 | + | cfg *config.Config, | |
| 189 | + | initResult *bootstrap.ParallelInitResult, | |
| 190 | + | stack *bootstrap.WebKitStack, | |
| 191 | + | repos *repositories, | |
| 192 | + | useCases *useCases, | |
| 193 | + | idleInhibitor port.IdleInhibitor, | |
| 194 | + | browserSession *bootstrap.BrowserSession, | |
| 195 | + | ) (*ui.App, error) { | |
| 196 | + | uiDeps := buildUIDependencies( | |
| 197 | + | ctx, cfg, initResult.ThemeManager, | |
| 198 | + | initResult.ColorResolver, initResult.AdwaitaDetector, | |
| 199 | + | stack, repos, useCases, idleInhibitor, browserSession.Session.ID, | |
| 200 | + | ) | |
| 201 | + | configureDeferredInit(uiDeps, cfg, browserSession) | |
| 202 | + | return ui.New(uiDeps) | |
| 203 | + | } | |
| 204 | + | ||
| 155 | 205 | func initStartupContext(cfg *config.Config) context.Context { | |
| 156 | 206 | deps.ApplyPrefixEnv(cfg.Runtime.Prefix) | |
| 157 | 207 | bootstrapLogger := logging.NewFromConfigValuesWithTimeFormat( | |
| @@ -217,6 +267,11 @@ func configureDeferredInit( | |||
| 217 | 267 | if uiDeps == nil { | |
| 218 | 268 | return | |
| 219 | 269 | } | |
| 270 | + | ||
| 271 | + | // If session was already persisted (not deferred), mark snapshot service ready immediately | |
| 272 | + | // via callback that will be set by the app after initialization | |
| 273 | + | sessionAlreadyPersisted := session == nil || session.Persist == nil | |
| 274 | + | ||
| 220 | 275 | uiDeps.OnFirstWebViewShown = func(cbCtx context.Context) { | |
| 221 | 276 | logger := logging.FromContext(cbCtx) | |
| 222 | 277 | bgCtx := logging.WithContext(context.Background(), *logger) | |
| @@ -227,10 +282,19 @@ func configureDeferredInit( | |||
| 227 | 282 | }) | |
| 228 | 283 | logDeferredInitResults(bgCtx, result) | |
| 229 | 284 | }() | |
| 230 | - | if session != nil && session.Persist != nil { | |
| 285 | + | ||
| 286 | + | if sessionAlreadyPersisted { | |
| 287 | + | // Session was persisted eagerly, notify immediately | |
| 288 | + | if uiDeps.OnSessionPersisted != nil { | |
| 289 | + | uiDeps.OnSessionPersisted() | |
| 290 | + | } | |
| 291 | + | } else if session.Persist != nil { | |
| 292 | + | // Session persist is deferred, notify after it completes | |
| 231 | 293 | go func() { | |
| 232 | 294 | if persistErr := session.Persist(bgCtx); persistErr != nil { | |
| 233 | 295 | logger.Error().Err(persistErr).Msg("deferred session persistence failed") | |
| 296 | + | } else if uiDeps.OnSessionPersisted != nil { | |
| 297 | + | uiDeps.OnSessionPersisted() | |
| 234 | 298 | } | |
| 235 | 299 | }() | |
| 236 | 300 | } | |
| @@ -29,6 +29,7 @@ import ( | |||||
| 29 | "github.com/bnema/dumber/internal/logging" | 29 | "github.com/bnema/dumber/internal/logging" | ||
| 30 | "github.com/bnema/dumber/internal/ui" | 30 | "github.com/bnema/dumber/internal/ui" | ||
| 31 | "github.com/bnema/dumber/internal/ui/theme" | 31 | "github.com/bnema/dumber/internal/ui/theme" | ||
| 32 | + | "github.com/rs/zerolog" | |||
| 32 | ) | 33 | ) | ||
| 33 | 34 | ||||
| 34 | // Build-time variables (set via ldflags). | 35 | // Build-time variables (set via ldflags). | ||
| @@ -75,17 +76,12 @@ func runGUI() int { | |||||
| 75 | cfg := initConfig() | 76 | cfg := initConfig() | ||
| 76 | timer.Mark("config") | 77 | timer.Mark("config") | ||
| 77 | 78 | ||||
| 78 | - | ctx := initStartupContext(cfg) | 79 | + | ctx := initStartupContextWithTrace(cfg) |
| 79 | timer.Mark("logger") | 80 | timer.Mark("logger") | ||
| 80 | bootstrapLog := logging.FromContext(ctx) | 81 | bootstrapLog := logging.FromContext(ctx) | ||
| 81 | 82 | ||||
| 82 | - | // Parallel phase: directories and theme setup | 83 | + | initResult, err := runParallelInitPhase(ctx, cfg) |
| 83 | - | initResult, err := bootstrap.RunParallelInit(bootstrap.ParallelInitInput{ | |||
| 84 | - | Ctx: ctx, | |||
| 85 | - | Config: cfg, | |||
| 86 | - | }) | |||
| 87 | if err != nil { | 84 | if err != nil { | ||
| 88 | - | handleParallelInitError(ctx, err) | |||
| 89 | return 1 | 85 | return 1 | ||
| 90 | } | 86 | } | ||
| 91 | timer.MarkDuration("parallel_phase", initResult.Duration) | 87 | timer.MarkDuration("parallel_phase", initResult.Duration) | ||
| @@ -101,44 +97,27 @@ func runGUI() int { | |||||
| 101 | } | 97 | } | ||
| 102 | timer.Mark("db_webkit_parallel") | 98 | timer.Mark("db_webkit_parallel") | ||
| 103 | 99 | ||||
| 104 | - | browserSession, sessionCtx, err := bootstrap.StartBrowserSession(ctx, cfg, repos.session, !needsEagerDB) | 100 | + | ctx, browserSession, sessionCleanup := initBrowserSession(ctx, cfg, repos, bootstrapLog) |
| 105 | - | if err != nil { | 101 | + | defer sessionCleanup() |
| 106 | - | bootstrapLog.Fatal().Err(err).Msg("failed to start session") | |||
| 107 | - | } | |||
| 108 | - | if browserSession.LogCleanup != nil { | |||
| 109 | - | defer browserSession.LogCleanup() | |||
| 110 | - | } | |||
| 111 | - | defer func() { _ = browserSession.End(sessionCtx) }() | |||
| 112 | timer.Mark("session") | 102 | timer.Mark("session") | ||
| 113 | 103 | ||||
| 114 | - | ctx = sessionCtx | |||
| 115 | log := logging.FromContext(ctx) | 104 | log := logging.FromContext(ctx) | ||
| 105 | + | logging.Trace().UpdateLogger(log) | |||
| 106 | + | ||||
| 116 | if stack.MessageRouter != nil { | 107 | if stack.MessageRouter != nil { | ||
| 117 | stack.MessageRouter.SetBaseContext(ctx) | 108 | stack.MessageRouter.SetBaseContext(ctx) | ||
| 118 | } | 109 | } | ||
| 119 | 110 | ||||
| 120 | - | // Repositories and use cases | |||
| 121 | useCases := createUseCases(repos, cfg) | 111 | useCases := createUseCases(repos, cfg) | ||
| 122 | if needsEagerDB { | 112 | if needsEagerDB { | ||
| 123 | handleAutoRestore(ctx, cfg, useCases, browserSession.Session.ID) | 113 | handleAutoRestore(ctx, cfg, useCases, browserSession.Session.ID) | ||
| 124 | } | 114 | } | ||
| 125 | 115 | ||||
| 126 | idleInhibitor := idle.NewPortalInhibitor(ctx) | 116 | idleInhibitor := idle.NewPortalInhibitor(ctx) | ||
| 127 | - | defer func() { | 117 | + | defer closeIdleInhibitor(idleInhibitor) |
| 128 | - | if idleInhibitor != nil { | |||
| 129 | - | _ = idleInhibitor.Close() | |||
| 130 | - | } | |||
| 131 | - | }() | |||
| 132 | timer.Mark("use_cases") | 118 | timer.Mark("use_cases") | ||
| 133 | 119 | ||||
| 134 | - | // Build UI | 120 | + | app, err := buildAndConfigureApp(ctx, cfg, initResult, &stack, repos, useCases, idleInhibitor, browserSession) |
| 135 | - | uiDeps := buildUIDependencies( | |||
| 136 | - | ctx, cfg, initResult.ThemeManager, | |||
| 137 | - | initResult.ColorResolver, initResult.AdwaitaDetector, | |||
| 138 | - | &stack, repos, useCases, idleInhibitor, browserSession.Session.ID, | |||
| 139 | - | ) | |||
| 140 | - | configureDeferredInit(uiDeps, cfg, browserSession) | |||
| 141 | - | app, err := ui.New(uiDeps) | |||
| 142 | if err != nil { | 121 | if err != nil { | ||
| 143 | log.Error().Err(err).Msg("failed to create application") | 122 | log.Error().Err(err).Msg("failed to create application") | ||
| 144 | return 1 | 123 | return 1 | ||
| @@ -146,12 +125,83 @@ func runGUI() int { | |||||
| 146 | timer.Mark("ui_deps") | 125 | timer.Mark("ui_deps") | ||
| 147 | timer.Log(ctx) | 126 | timer.Log(ctx) | ||
| 148 | 127 | ||||
| 149 | - | // Signal handling | |||
| 150 | setupSignalHandler(ctx, app) | 128 | setupSignalHandler(ctx, app) | ||
| 151 | 129 | ||||
| 152 | return app.Run(ctx, os.Args) | 130 | return app.Run(ctx, os.Args) | ||
| 153 | } | 131 | } | ||
| 154 | 132 | ||||
| 133 | + | func initStartupContextWithTrace(cfg *config.Config) context.Context { | |||
| 134 | + | logging.InitStartupTrace(cfg.Logging.Level) | |||
| 135 | + | logging.Trace().Mark("config_loaded") | |||
| 136 | + | ||||
| 137 | + | ctx := initStartupContext(cfg) | |||
| 138 | + | bootstrapLog := logging.FromContext(ctx) | |||
| 139 | + | ||||
| 140 | + | logging.Trace().SetLogger(bootstrapLog) | |||
| 141 | + | logging.Trace().Mark("logger_init") | |||
| 142 | + | ||||
| 143 | + | return ctx | |||
| 144 | + | } | |||
| 145 | + | ||||
| 146 | + | func runParallelInitPhase(ctx context.Context, cfg *config.Config) (*bootstrap.ParallelInitResult, error) { | |||
| 147 | + | logging.Trace().Mark("parallel_start") | |||
| 148 | + | initResult, err := bootstrap.RunParallelInit(bootstrap.ParallelInitInput{ | |||
| 149 | + | Ctx: ctx, | |||
| 150 | + | Config: cfg, | |||
| 151 | + | }) | |||
| 152 | + | if err != nil { | |||
| 153 | + | handleParallelInitError(ctx, err) | |||
| 154 | + | return nil, err | |||
| 155 | + | } | |||
| 156 | + | logging.Trace().Mark("parallel_done") | |||
| 157 | + | return initResult, nil | |||
| 158 | + | } | |||
| 159 | + | ||||
| 160 | + | func initBrowserSession( | |||
| 161 | + | ctx context.Context, | |||
| 162 | + | cfg *config.Config, | |||
| 163 | + | repos *repositories, | |||
| 164 | + | bootstrapLog *zerolog.Logger, | |||
| 165 | + | ) (context.Context, *bootstrap.BrowserSession, func()) { | |||
| 166 | + | deferPersist := restoreSessionID == "" && !cfg.Session.AutoRestore | |||
| 167 | + | browserSession, sessionCtx, err := bootstrap.StartBrowserSession(ctx, cfg, repos.session, deferPersist) | |||
| 168 | + | if err != nil { | |||
| 169 | + | bootstrapLog.Fatal().Err(err).Msg("failed to start session") | |||
| 170 | + | } | |||
| 171 | + | cleanup := func() { | |||
| 172 | + | if browserSession.LogCleanup != nil { | |||
| 173 | + | browserSession.LogCleanup() | |||
| 174 | + | } | |||
| 175 | + | _ = browserSession.End(sessionCtx) | |||
| 176 | + | } | |||
| 177 | + | return sessionCtx, browserSession, cleanup | |||
| 178 | + | } | |||
| 179 | + | ||||
| 180 | + | func closeIdleInhibitor(inhibitor port.IdleInhibitor) { | |||
| 181 | + | if inhibitor != nil { | |||
| 182 | + | _ = inhibitor.Close() | |||
| 183 | + | } | |||
| 184 | + | } | |||
| 185 | + | ||||
| 186 | + | func buildAndConfigureApp( | |||
| 187 | + | ctx context.Context, | |||
| 188 | + | cfg *config.Config, | |||
| 189 | + | initResult *bootstrap.ParallelInitResult, | |||
| 190 | + | stack *bootstrap.WebKitStack, | |||
| 191 | + | repos *repositories, | |||
| 192 | + | useCases *useCases, | |||
| 193 | + | idleInhibitor port.IdleInhibitor, | |||
| 194 | + | browserSession *bootstrap.BrowserSession, | |||
| 195 | + | ) (*ui.App, error) { | |||
| 196 | + | uiDeps := buildUIDependencies( | |||
| 197 | + | ctx, cfg, initResult.ThemeManager, | |||
| 198 | + | initResult.ColorResolver, initResult.AdwaitaDetector, | |||
| 199 | + | stack, repos, useCases, idleInhibitor, browserSession.Session.ID, | |||
| 200 | + | ) | |||
| 201 | + | configureDeferredInit(uiDeps, cfg, browserSession) | |||
| 202 | + | return ui.New(uiDeps) | |||
| 203 | + | } | |||
| 204 | + | ||||
| 155 | func initStartupContext(cfg *config.Config) context.Context { | 205 | func initStartupContext(cfg *config.Config) context.Context { | ||
| 156 | deps.ApplyPrefixEnv(cfg.Runtime.Prefix) | 206 | deps.ApplyPrefixEnv(cfg.Runtime.Prefix) | ||
| 157 | bootstrapLogger := logging.NewFromConfigValuesWithTimeFormat( | 207 | bootstrapLogger := logging.NewFromConfigValuesWithTimeFormat( | ||
| @@ -217,6 +267,11 @@ func configureDeferredInit( | |||||
| 217 | if uiDeps == nil { | 267 | if uiDeps == nil { | ||
| 218 | return | 268 | return | ||
| 219 | } | 269 | } | ||
| 270 | + | ||||
| 271 | + | // If session was already persisted (not deferred), mark snapshot service ready immediately | |||
| 272 | + | // via callback that will be set by the app after initialization | |||
| 273 | + | sessionAlreadyPersisted := session == nil || session.Persist == nil | |||
| 274 | + | ||||
| 220 | uiDeps.OnFirstWebViewShown = func(cbCtx context.Context) { | 275 | uiDeps.OnFirstWebViewShown = func(cbCtx context.Context) { | ||
| 221 | logger := logging.FromContext(cbCtx) | 276 | logger := logging.FromContext(cbCtx) | ||
| 222 | bgCtx := logging.WithContext(context.Background(), *logger) | 277 | bgCtx := logging.WithContext(context.Background(), *logger) | ||
| @@ -227,10 +282,19 @@ func configureDeferredInit( | |||||
| 227 | }) | 282 | }) | ||
| 228 | logDeferredInitResults(bgCtx, result) | 283 | logDeferredInitResults(bgCtx, result) | ||
| 229 | }() | 284 | }() | ||
| 230 | - | if session != nil && session.Persist != nil { | 285 | + | |
| 286 | + | if sessionAlreadyPersisted { | |||
| 287 | + | // Session was persisted eagerly, notify immediately | |||
| 288 | + | if uiDeps.OnSessionPersisted != nil { | |||
| 289 | + | uiDeps.OnSessionPersisted() | |||
| 290 | + | } | |||
| 291 | + | } else if session.Persist != nil { | |||
| 292 | + | // Session persist is deferred, notify after it completes | |||
| 231 | go func() { | 293 | go func() { | ||
| 232 | if persistErr := session.Persist(bgCtx); persistErr != nil { | 294 | if persistErr := session.Persist(bgCtx); persistErr != nil { | ||
| 233 | logger.Error().Err(persistErr).Msg("deferred session persistence failed") | 295 | logger.Error().Err(persistErr).Msg("deferred session persistence failed") | ||
| 296 | + | } else if uiDeps.OnSessionPersisted != nil { | |||
| 297 | + | uiDeps.OnSessionPersisted() | |||
| 234 | } | 298 | } | ||
| 235 | }() | 299 | }() | ||
| 236 | } | 300 | } | ||
M go.mod +23 -20
| @@ -8,17 +8,17 @@ require ( | |||
| 8 | 8 | github.com/charmbracelet/bubbletea v1.3.10 | |
| 9 | 9 | github.com/charmbracelet/lipgloss v1.1.0 | |
| 10 | 10 | github.com/fsnotify/fsnotify v1.9.0 | |
| 11 | - | github.com/godbus/dbus/v5 v5.2.1 | |
| 12 | - | github.com/jwijenbergh/puregotk v0.0.0-20251222174431-73930527faa3 | |
| 13 | - | github.com/ncruces/go-sqlite3 v0.30.3 | |
| 11 | + | github.com/godbus/dbus/v5 v5.2.2 | |
| 12 | + | github.com/jwijenbergh/puregotk v0.0.0-20260115100645-c78e1521129b | |
| 13 | + | github.com/ncruces/go-sqlite3 v0.30.4 | |
| 14 | 14 | github.com/pelletier/go-toml/v2 v2.2.4 | |
| 15 | 15 | github.com/pressly/goose/v3 v3.26.0 | |
| 16 | - | github.com/rs/zerolog v1.33.0 | |
| 16 | + | github.com/rs/zerolog v1.34.0 | |
| 17 | 17 | github.com/spf13/cobra v1.10.2 | |
| 18 | 18 | github.com/spf13/viper v1.21.0 | |
| 19 | 19 | github.com/stretchr/testify v1.11.1 | |
| 20 | - | golang.org/x/image v0.34.0 | |
| 21 | - | golang.org/x/sys v0.38.0 | |
| 20 | + | golang.org/x/image v0.35.0 | |
| 21 | + | golang.org/x/sys v0.40.0 | |
| 22 | 22 | gopkg.in/yaml.v3 v3.0.1 | |
| 23 | 23 | ) | |
| 24 | 24 | ||
| @@ -27,21 +27,24 @@ replace github.com/jwijenbergh/puregotk => github.com/bnema/puregotk v0.0.0-2025 | |||
| 27 | 27 | require ( | |
| 28 | 28 | github.com/atotto/clipboard v0.1.4 // indirect | |
| 29 | 29 | github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect | |
| 30 | - | github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect | |
| 31 | - | github.com/charmbracelet/x/ansi v0.10.1 // indirect | |
| 32 | - | github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect | |
| 33 | - | github.com/charmbracelet/x/term v0.2.1 // indirect | |
| 34 | - | github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect | |
| 30 | + | github.com/charmbracelet/colorprofile v0.4.1 // indirect | |
| 31 | + | github.com/charmbracelet/x/ansi v0.11.4 // indirect | |
| 32 | + | github.com/charmbracelet/x/cellbuf v0.0.14 // indirect | |
| 33 | + | github.com/charmbracelet/x/term v0.2.2 // indirect | |
| 34 | + | github.com/clipperhouse/displaywidth v0.7.0 // indirect | |
| 35 | + | github.com/clipperhouse/stringish v0.1.1 // indirect | |
| 36 | + | github.com/clipperhouse/uax29/v2 v2.3.1 // indirect | |
| 37 | + | github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect | |
| 35 | 38 | github.com/davecgh/go-spew v1.1.1 // indirect | |
| 36 | 39 | github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect | |
| 37 | - | github.com/go-viper/mapstructure/v2 v2.4.0 // indirect | |
| 40 | + | github.com/go-viper/mapstructure/v2 v2.5.0 // indirect | |
| 38 | 41 | github.com/inconshreveable/mousetrap v1.1.0 // indirect | |
| 39 | 42 | github.com/jwijenbergh/purego v0.0.0-20251017112123-b71757b9ba42 // indirect | |
| 40 | - | github.com/lucasb-eyer/go-colorful v1.2.0 // indirect | |
| 41 | - | github.com/mattn/go-colorable v0.1.13 // indirect | |
| 43 | + | github.com/lucasb-eyer/go-colorful v1.3.0 // indirect | |
| 44 | + | github.com/mattn/go-colorable v0.1.14 // indirect | |
| 42 | 45 | github.com/mattn/go-isatty v0.0.20 // indirect | |
| 43 | 46 | github.com/mattn/go-localereader v0.0.1 // indirect | |
| 44 | - | github.com/mattn/go-runewidth v0.0.16 // indirect | |
| 47 | + | github.com/mattn/go-runewidth v0.0.19 // indirect | |
| 45 | 48 | github.com/mfridman/interpolate v0.0.2 // indirect | |
| 46 | 49 | github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect | |
| 47 | 50 | github.com/muesli/cancelreader v0.2.2 // indirect | |
| @@ -50,19 +53,19 @@ require ( | |||
| 50 | 53 | github.com/pmezard/go-difflib v1.0.0 // indirect | |
| 51 | 54 | github.com/rivo/uniseg v0.4.7 // indirect | |
| 52 | 55 | github.com/russross/blackfriday/v2 v2.1.0 // indirect | |
| 53 | - | github.com/sagikazarmark/locafero v0.11.0 // indirect | |
| 56 | + | github.com/sagikazarmark/locafero v0.12.0 // indirect | |
| 54 | 57 | github.com/sahilm/fuzzy v0.1.1 // indirect | |
| 55 | 58 | github.com/sethvargo/go-retry v0.3.0 // indirect | |
| 56 | - | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect | |
| 57 | 59 | github.com/spf13/afero v1.15.0 // indirect | |
| 58 | 60 | github.com/spf13/cast v1.10.0 // indirect | |
| 59 | 61 | github.com/spf13/pflag v1.0.10 // indirect | |
| 60 | - | github.com/stretchr/objx v0.5.2 // indirect | |
| 62 | + | github.com/stretchr/objx v0.5.3 // indirect | |
| 61 | 63 | github.com/subosito/gotenv v1.6.0 // indirect | |
| 62 | - | github.com/tetratelabs/wazero v1.10.1 // indirect | |
| 64 | + | github.com/tetratelabs/wazero v1.11.0 // indirect | |
| 63 | 65 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect | |
| 64 | 66 | go.uber.org/multierr v1.11.0 // indirect | |
| 65 | 67 | go.yaml.in/yaml/v3 v3.0.4 // indirect | |
| 66 | 68 | golang.org/x/sync v0.19.0 // indirect | |
| 67 | - | golang.org/x/text v0.32.0 // indirect | |
| 69 | + | golang.org/x/text v0.33.0 // indirect | |
| 70 | + | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect | |
| 68 | 71 | ) | |
| @@ -8,17 +8,17 @@ require ( | |||||
| 8 | github.com/charmbracelet/bubbletea v1.3.10 | 8 | github.com/charmbracelet/bubbletea v1.3.10 | ||
| 9 | github.com/charmbracelet/lipgloss v1.1.0 | 9 | github.com/charmbracelet/lipgloss v1.1.0 | ||
| 10 | github.com/fsnotify/fsnotify v1.9.0 | 10 | github.com/fsnotify/fsnotify v1.9.0 | ||
| 11 | - | github.com/godbus/dbus/v5 v5.2.1 | 11 | + | github.com/godbus/dbus/v5 v5.2.2 |
| 12 | - | github.com/jwijenbergh/puregotk v0.0.0-20251222174431-73930527faa3 | 12 | + | github.com/jwijenbergh/puregotk v0.0.0-20260115100645-c78e1521129b |
| 13 | - | github.com/ncruces/go-sqlite3 v0.30.3 | 13 | + | github.com/ncruces/go-sqlite3 v0.30.4 |
| 14 | github.com/pelletier/go-toml/v2 v2.2.4 | 14 | github.com/pelletier/go-toml/v2 v2.2.4 | ||
| 15 | github.com/pressly/goose/v3 v3.26.0 | 15 | github.com/pressly/goose/v3 v3.26.0 | ||
| 16 | - | github.com/rs/zerolog v1.33.0 | 16 | + | github.com/rs/zerolog v1.34.0 |
| 17 | github.com/spf13/cobra v1.10.2 | 17 | github.com/spf13/cobra v1.10.2 | ||
| 18 | github.com/spf13/viper v1.21.0 | 18 | github.com/spf13/viper v1.21.0 | ||
| 19 | github.com/stretchr/testify v1.11.1 | 19 | github.com/stretchr/testify v1.11.1 | ||
| 20 | - | golang.org/x/image v0.34.0 | 20 | + | golang.org/x/image v0.35.0 |
| 21 | - | golang.org/x/sys v0.38.0 | 21 | + | golang.org/x/sys v0.40.0 |
| 22 | gopkg.in/yaml.v3 v3.0.1 | 22 | gopkg.in/yaml.v3 v3.0.1 | ||
| 23 | ) | 23 | ) | ||
| 24 | 24 | ||||
| @@ -27,21 +27,24 @@ replace github.com/jwijenbergh/puregotk => github.com/bnema/puregotk v0.0.0-2025 | |||||
| 27 | require ( | 27 | require ( | ||
| 28 | github.com/atotto/clipboard v0.1.4 // indirect | 28 | github.com/atotto/clipboard v0.1.4 // indirect | ||
| 29 | github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect | 29 | github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect | ||
| 30 | - | github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect | 30 | + | github.com/charmbracelet/colorprofile v0.4.1 // indirect |
| 31 | - | github.com/charmbracelet/x/ansi v0.10.1 // indirect | 31 | + | github.com/charmbracelet/x/ansi v0.11.4 // indirect |
| 32 | - | github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect | 32 | + | github.com/charmbracelet/x/cellbuf v0.0.14 // indirect |
| 33 | - | github.com/charmbracelet/x/term v0.2.1 // indirect | 33 | + | github.com/charmbracelet/x/term v0.2.2 // indirect |
| 34 | - | github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect | 34 | + | github.com/clipperhouse/displaywidth v0.7.0 // indirect |
| 35 | + | github.com/clipperhouse/stringish v0.1.1 // indirect | |||
| 36 | + | github.com/clipperhouse/uax29/v2 v2.3.1 // indirect | |||
| 37 | + | github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect | |||
| 35 | github.com/davecgh/go-spew v1.1.1 // indirect | 38 | github.com/davecgh/go-spew v1.1.1 // indirect | ||
| 36 | github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect | 39 | github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect | ||
| 37 | - | github.com/go-viper/mapstructure/v2 v2.4.0 // indirect | 40 | + | github.com/go-viper/mapstructure/v2 v2.5.0 // indirect |
| 38 | github.com/inconshreveable/mousetrap v1.1.0 // indirect | 41 | github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||
| 39 | github.com/jwijenbergh/purego v0.0.0-20251017112123-b71757b9ba42 // indirect | 42 | github.com/jwijenbergh/purego v0.0.0-20251017112123-b71757b9ba42 // indirect | ||
| 40 | - | github.com/lucasb-eyer/go-colorful v1.2.0 // indirect | 43 | + | github.com/lucasb-eyer/go-colorful v1.3.0 // indirect |
| 41 | - | github.com/mattn/go-colorable v0.1.13 // indirect | 44 | + | github.com/mattn/go-colorable v0.1.14 // indirect |
| 42 | github.com/mattn/go-isatty v0.0.20 // indirect | 45 | github.com/mattn/go-isatty v0.0.20 // indirect | ||
| 43 | github.com/mattn/go-localereader v0.0.1 // indirect | 46 | github.com/mattn/go-localereader v0.0.1 // indirect | ||
| 44 | - | github.com/mattn/go-runewidth v0.0.16 // indirect | 47 | + | github.com/mattn/go-runewidth v0.0.19 // indirect |
| 45 | github.com/mfridman/interpolate v0.0.2 // indirect | 48 | github.com/mfridman/interpolate v0.0.2 // indirect | ||
| 46 | github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect | 49 | github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect | ||
| 47 | github.com/muesli/cancelreader v0.2.2 // indirect | 50 | github.com/muesli/cancelreader v0.2.2 // indirect | ||
| @@ -50,19 +53,19 @@ require ( | |||||
| 50 | github.com/pmezard/go-difflib v1.0.0 // indirect | 53 | github.com/pmezard/go-difflib v1.0.0 // indirect | ||
| 51 | github.com/rivo/uniseg v0.4.7 // indirect | 54 | github.com/rivo/uniseg v0.4.7 // indirect | ||
| 52 | github.com/russross/blackfriday/v2 v2.1.0 // indirect | 55 | github.com/russross/blackfriday/v2 v2.1.0 // indirect | ||
| 53 | - | github.com/sagikazarmark/locafero v0.11.0 // indirect | 56 | + | github.com/sagikazarmark/locafero v0.12.0 // indirect |
| 54 | github.com/sahilm/fuzzy v0.1.1 // indirect | 57 | github.com/sahilm/fuzzy v0.1.1 // indirect | ||
| 55 | github.com/sethvargo/go-retry v0.3.0 // indirect | 58 | github.com/sethvargo/go-retry v0.3.0 // indirect | ||
| 56 | - | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect | |||
| 57 | github.com/spf13/afero v1.15.0 // indirect | 59 | github.com/spf13/afero v1.15.0 // indirect | ||
| 58 | github.com/spf13/cast v1.10.0 // indirect | 60 | github.com/spf13/cast v1.10.0 // indirect | ||
| 59 | github.com/spf13/pflag v1.0.10 // indirect | 61 | github.com/spf13/pflag v1.0.10 // indirect | ||
| 60 | - | github.com/stretchr/objx v0.5.2 // indirect | 62 | + | github.com/stretchr/objx v0.5.3 // indirect |
| 61 | github.com/subosito/gotenv v1.6.0 // indirect | 63 | github.com/subosito/gotenv v1.6.0 // indirect | ||
| 62 | - | github.com/tetratelabs/wazero v1.10.1 // indirect | 64 | + | github.com/tetratelabs/wazero v1.11.0 // indirect |
| 63 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect | 65 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect | ||
| 64 | go.uber.org/multierr v1.11.0 // indirect | 66 | go.uber.org/multierr v1.11.0 // indirect | ||
| 65 | go.yaml.in/yaml/v3 v3.0.4 // indirect | 67 | go.yaml.in/yaml/v3 v3.0.4 // indirect | ||
| 66 | golang.org/x/sync v0.19.0 // indirect | 68 | golang.org/x/sync v0.19.0 // indirect | ||
| 67 | - | golang.org/x/text v0.32.0 // indirect | 69 | + | golang.org/x/text v0.33.0 // indirect |
| 70 | + | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect | |||
| 68 | ) | 71 | ) | ||
M go.sum +43 -38 generated file: collapsed
M internal/application/usecase/navigate.go +5 -2
| @@ -17,6 +17,9 @@ const ( | |||
| 17 | 17 | // historyQueueSize is the buffer size for the async history queue. | |
| 18 | 18 | // If the queue is full, new records are dropped with a warning. | |
| 19 | 19 | historyQueueSize = 100 | |
| 20 | + | ||
| 21 | + | // logURLMaxLen is the max length for URLs in log messages. | |
| 22 | + | logURLMaxLen = 60 | |
| 20 | 23 | ) | |
| 21 | 24 | ||
| 22 | 25 | // historyRecord holds data for async history recording. | |
| @@ -137,7 +140,7 @@ func (uc *NavigateUseCase) RecordHistory(ctx context.Context, url string) { | |||
| 137 | 140 | // Non-blocking send to async queue | |
| 138 | 141 | select { | |
| 139 | 142 | case uc.historyQueue <- historyRecord{url: url, timestamp: now}: | |
| 140 | - | log.Debug().Str("url", url).Msg("history record queued") | |
| 143 | + | log.Debug().Str("url", logging.TruncateURL(url, logURLMaxLen)).Msg("history record queued") | |
| 141 | 144 | default: | |
| 142 | 145 | // Queue full - log warning but don't block navigation | |
| 143 | 146 | log.Warn().Str("url", url).Msg("history queue full, dropping record") | |
| @@ -205,7 +208,7 @@ func (uc *NavigateUseCase) UpdateHistoryTitle(ctx context.Context, url, title st | |||
| 205 | 208 | ||
| 206 | 209 | // Normalize URL to match storage (e.g., github.com/ -> github.com) | |
| 207 | 210 | url = normalizeURLForHistory(url) | |
| 208 | - | log.Debug().Str("url", url).Str("title", title).Msg("updating history title") | |
| 211 | + | log.Debug().Str("url", logging.TruncateURL(url, logURLMaxLen)).Str("title", title).Msg("updating history title") | |
| 209 | 212 | ||
| 210 | 213 | entry, err := uc.historyRepo.FindByURL(ctx, url) | |
| 211 | 214 | if err != nil { | |
| @@ -17,6 +17,9 @@ const ( | |||||
| 17 | // historyQueueSize is the buffer size for the async history queue. | 17 | // historyQueueSize is the buffer size for the async history queue. | ||
| 18 | // If the queue is full, new records are dropped with a warning. | 18 | // If the queue is full, new records are dropped with a warning. | ||
| 19 | historyQueueSize = 100 | 19 | historyQueueSize = 100 | ||
| 20 | + | ||||
| 21 | + | // logURLMaxLen is the max length for URLs in log messages. | |||
| 22 | + | logURLMaxLen = 60 | |||
| 20 | ) | 23 | ) | ||
| 21 | 24 | ||||
| 22 | // historyRecord holds data for async history recording. | 25 | // historyRecord holds data for async history recording. | ||
| @@ -137,7 +140,7 @@ func (uc *NavigateUseCase) RecordHistory(ctx context.Context, url string) { | |||||
| 137 | // Non-blocking send to async queue | 140 | // Non-blocking send to async queue | ||
| 138 | select { | 141 | select { | ||
| 139 | case uc.historyQueue <- historyRecord{url: url, timestamp: now}: | 142 | case uc.historyQueue <- historyRecord{url: url, timestamp: now}: | ||
| 140 | - | log.Debug().Str("url", url).Msg("history record queued") | 143 | + | log.Debug().Str("url", logging.TruncateURL(url, logURLMaxLen)).Msg("history record queued") |
| 141 | default: | 144 | default: | ||
| 142 | // Queue full - log warning but don't block navigation | 145 | // Queue full - log warning but don't block navigation | ||
| 143 | log.Warn().Str("url", url).Msg("history queue full, dropping record") | 146 | log.Warn().Str("url", url).Msg("history queue full, dropping record") | ||
| @@ -205,7 +208,7 @@ func (uc *NavigateUseCase) UpdateHistoryTitle(ctx context.Context, url, title st | |||||
| 205 | 208 | ||||
| 206 | // Normalize URL to match storage (e.g., github.com/ -> github.com) | 209 | // Normalize URL to match storage (e.g., github.com/ -> github.com) | ||
| 207 | url = normalizeURLForHistory(url) | 210 | url = normalizeURLForHistory(url) | ||
| 208 | - | log.Debug().Str("url", url).Str("title", title).Msg("updating history title") | 211 | + | log.Debug().Str("url", logging.TruncateURL(url, logURLMaxLen)).Str("title", title).Msg("updating history title") |
| 209 | 212 | ||||
| 210 | entry, err := uc.historyRepo.FindByURL(ctx, url) | 213 | entry, err := uc.historyRepo.FindByURL(ctx, url) | ||
| 211 | if err != nil { | 214 | if err != nil { | ||
M internal/bootstrap/webkit_stack.go +84 -39
| @@ -11,6 +11,7 @@ import ( | |||
| 11 | 11 | "github.com/bnema/dumber/internal/infrastructure/env" | |
| 12 | 12 | "github.com/bnema/dumber/internal/infrastructure/filtering" | |
| 13 | 13 | "github.com/bnema/dumber/internal/infrastructure/webkit" | |
| 14 | + | "github.com/bnema/dumber/internal/logging" | |
| 14 | 15 | "github.com/bnema/dumber/internal/ui/theme" | |
| 15 | 16 | "github.com/rs/zerolog" | |
| 16 | 17 | ) | |
| @@ -38,14 +39,44 @@ type WebKitStack struct { | |||
| 38 | 39 | func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |
| 39 | 40 | ctx := input.Ctx | |
| 40 | 41 | cfg := input.Config | |
| 41 | - | dataDir := input.DataDir | |
| 42 | - | cacheDir := input.CacheDir | |
| 43 | - | themeManager := input.ThemeManager | |
| 44 | - | colorResolver := input.ColorResolver | |
| 45 | 42 | logger := input.Logger | |
| 46 | - | // Detect hardware for performance profile scaling | |
| 43 | + | ||
| 44 | + | perfSettings := surveyHardwareAndResolveProfile(ctx, cfg, logger) | |
| 45 | + | ||
| 46 | + | configureRenderingEnvironment(ctx, cfg, &perfSettings, logger) | |
| 47 | + | logging.Trace().Mark("render_env") | |
| 48 | + | ||
| 49 | + | wkOpts := buildWebKitContextOptions(input.DataDir, input.CacheDir, &perfSettings) | |
| 50 | + | wkCtx, err := webkit.NewWebKitContextWithOptions(ctx, wkOpts) | |
| 51 | + | if err != nil { | |
| 52 | + | logger.Fatal().Err(err).Msg("failed to initialize WebKit context") | |
| 53 | + | } | |
| 54 | + | logging.Trace().Mark("webkit_context") | |
| 55 | + | ||
| 56 | + | filterManager := initFilterManager(ctx, cfg, input.DataDir, logger) | |
| 57 | + | ||
| 58 | + | schemeHandler := webkit.NewDumbSchemeHandler(ctx) | |
| 59 | + | schemeHandler.SetAssets(assets.WebUIAssets) | |
| 60 | + | schemeHandler.RegisterWithContext(wkCtx) | |
| 61 | + | ||
| 62 | + | settings, injector, messageRouter := initWebKitComponents(ctx, cfg, input.ThemeManager, input.ColorResolver, logger) | |
| 63 | + | ||
| 64 | + | pool := initWebViewPool(ctx, wkCtx, settings, injector, messageRouter, input.ThemeManager, filterManager, &perfSettings, logger) | |
| 65 | + | ||
| 66 | + | return WebKitStack{ | |
| 67 | + | Context: wkCtx, | |
| 68 | + | Settings: settings, | |
| 69 | + | Injector: injector, | |
| 70 | + | MessageRouter: messageRouter, | |
| 71 | + | Pool: pool, | |
| 72 | + | FilterManager: filterManager, | |
| 73 | + | } | |
| 74 | + | } | |
| 75 | + | ||
| 76 | + | func surveyHardwareAndResolveProfile(ctx context.Context, cfg *config.Config, logger zerolog.Logger) config.ResolvedPerformanceSettings { | |
| 47 | 77 | hwSurveyor := env.NewHardwareSurveyor() | |
| 48 | 78 | hwInfo := hwSurveyor.Survey(ctx) | |
| 79 | + | logging.Trace().Mark("hardware_survey") | |
| 49 | 80 | logger.Info(). | |
| 50 | 81 | Int("cpu_cores", hwInfo.CPUCores). | |
| 51 | 82 | Int("cpu_threads", hwInfo.CPUThreads). | |
| @@ -54,8 +85,8 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||
| 54 | 85 | Uint64("vram_mb", hwInfo.VRAM/(1024*1024)). | |
| 55 | 86 | Msg("hardware survey completed") | |
| 56 | 87 | ||
| 57 | - | // Resolve performance profile to get actual settings | |
| 58 | 88 | perfSettings := config.ResolvePerformanceProfile(&cfg.Performance, &hwInfo) | |
| 89 | + | logging.Trace().Mark("performance_profile") | |
| 59 | 90 | logger.Info(). | |
| 60 | 91 | Str("profile", string(cfg.Performance.Profile)). | |
| 61 | 92 | Int("skia_cpu_threads", perfSettings.SkiaCPUPaintingThreads). | |
| @@ -63,17 +94,16 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||
| 63 | 94 | Int("webview_pool_prewarm", perfSettings.WebViewPoolPrewarmCount). | |
| 64 | 95 | Msg("resolved performance profile") | |
| 65 | 96 | ||
| 66 | - | // Configure rendering environment (must happen before WebKit/GTK init) | |
| 67 | - | configureRenderingEnvironment(ctx, cfg, &perfSettings, logger) | |
| 97 | + | return perfSettings | |
| 98 | + | } | |
| 68 | 99 | ||
| 69 | - | // Build WebKitContext options with memory pressure settings | |
| 100 | + | func buildWebKitContextOptions(dataDir, cacheDir string, perfSettings *config.ResolvedPerformanceSettings) port.WebKitContextOptions { | |
| 70 | 101 | wkOpts := port.WebKitContextOptions{ | |
| 71 | 102 | DataDir: dataDir, | |
| 72 | 103 | CacheDir: cacheDir, | |
| 73 | 104 | } | |
| 74 | 105 | ||
| 75 | - | // Configure web process memory pressure if any setting is configured | |
| 76 | - | if hasWebProcessMemoryConfig(&perfSettings) { | |
| 106 | + | if hasWebProcessMemoryConfig(perfSettings) { | |
| 77 | 107 | wkOpts.WebProcessMemory = &port.MemoryPressureConfig{ | |
| 78 | 108 | MemoryLimitMB: perfSettings.WebProcessMemoryLimitMB, | |
| 79 | 109 | PollIntervalSec: perfSettings.WebProcessMemoryPollIntervalSec, | |
| @@ -82,8 +112,7 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||
| 82 | 112 | } | |
| 83 | 113 | } | |
| 84 | 114 | ||
| 85 | - | // Configure network process memory pressure if any setting is configured | |
| 86 | - | if hasNetworkProcessMemoryConfig(&perfSettings) { | |
| 115 | + | if hasNetworkProcessMemoryConfig(perfSettings) { | |
| 87 | 116 | wkOpts.NetworkProcessMemory = &port.MemoryPressureConfig{ | |
| 88 | 117 | MemoryLimitMB: perfSettings.NetworkProcessMemoryLimitMB, | |
| 89 | 118 | PollIntervalSec: perfSettings.NetworkProcessMemoryPollIntervalSec, | |
| @@ -92,11 +121,10 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||
| 92 | 121 | } | |
| 93 | 122 | } | |
| 94 | 123 | ||
| 95 | - | wkCtx, err := webkit.NewWebKitContextWithOptions(ctx, wkOpts) | |
| 96 | - | if err != nil { | |
| 97 | - | logger.Fatal().Err(err).Msg("failed to initialize WebKit context") | |
| 98 | - | } | |
| 124 | + | return wkOpts | |
| 125 | + | } | |
| 99 | 126 | ||
| 127 | + | func initFilterManager(ctx context.Context, cfg *config.Config, dataDir string, logger zerolog.Logger) *filtering.Manager { | |
| 100 | 128 | filterStoreDir := filepath.Join(dataDir, "filters", "store") | |
| 101 | 129 | filterJSONDir := filepath.Join(dataDir, "filters", "json") | |
| 102 | 130 | filterManager, err := filtering.NewManager(filtering.ManagerConfig{ | |
| @@ -107,20 +135,25 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||
| 107 | 135 | }) | |
| 108 | 136 | if err != nil { | |
| 109 | 137 | logger.Warn().Err(err).Msg("failed to create filter manager, continuing without content filtering") | |
| 110 | - | } else { | |
| 111 | - | if err := filterManager.Initialize(ctx); err != nil { | |
| 112 | - | logger.Warn().Err(err).Msg("failed to initialize filters, will load async") | |
| 113 | - | } | |
| 138 | + | return nil | |
| 114 | 139 | } | |
| 140 | + | if err := filterManager.Initialize(ctx); err != nil { | |
| 141 | + | logger.Warn().Err(err).Msg("failed to initialize filters, will load async") | |
| 142 | + | } | |
| 143 | + | logging.Trace().Mark("filter_manager") | |
| 144 | + | return filterManager | |
| 145 | + | } | |
| 115 | 146 | ||
| 116 | - | schemeHandler := webkit.NewDumbSchemeHandler(ctx) | |
| 117 | - | schemeHandler.SetAssets(assets.WebUIAssets) | |
| 118 | - | schemeHandler.RegisterWithContext(wkCtx) | |
| 119 | - | ||
| 147 | + | func initWebKitComponents( | |
| 148 | + | ctx context.Context, | |
| 149 | + | cfg *config.Config, | |
| 150 | + | themeManager *theme.Manager, | |
| 151 | + | colorResolver port.ColorSchemeResolver, | |
| 152 | + | logger zerolog.Logger, | |
| 153 | + | ) (*webkit.SettingsManager, *webkit.ContentInjector, *webkit.MessageRouter) { | |
| 120 | 154 | settings := webkit.NewSettingsManager(ctx, cfg) | |
| 121 | 155 | injector := webkit.NewContentInjector(colorResolver) | |
| 122 | 156 | ||
| 123 | - | // Set up auto-copy on selection config getter | |
| 124 | 157 | injector.SetAutoCopyConfigGetter(func() bool { | |
| 125 | 158 | return config.Get().Clipboard.AutoCopyOnSelection | |
| 126 | 159 | }) | |
| @@ -132,13 +165,28 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||
| 132 | 165 | } | |
| 133 | 166 | ||
| 134 | 167 | messageRouter := webkit.NewMessageRouter(ctx) | |
| 168 | + | logging.Trace().Mark("settings_manager") | |
| 169 | + | ||
| 170 | + | return settings, injector, messageRouter | |
| 171 | + | } | |
| 172 | + | ||
| 173 | + | func initWebViewPool( | |
| 174 | + | ctx context.Context, | |
| 175 | + | wkCtx *webkit.WebKitContext, | |
| 176 | + | settings *webkit.SettingsManager, | |
| 177 | + | injector *webkit.ContentInjector, | |
| 178 | + | messageRouter *webkit.MessageRouter, | |
| 179 | + | themeManager *theme.Manager, | |
| 180 | + | filterManager *filtering.Manager, | |
| 181 | + | perfSettings *config.ResolvedPerformanceSettings, | |
| 182 | + | logger zerolog.Logger, | |
| 183 | + | ) *webkit.WebViewPool { | |
| 135 | 184 | poolCfg := webkit.DefaultPoolConfig() | |
| 136 | - | // Override prewarm count from resolved profile settings | |
| 137 | 185 | if perfSettings.WebViewPoolPrewarmCount > 0 { | |
| 138 | 186 | poolCfg.PrewarmCount = perfSettings.WebViewPoolPrewarmCount | |
| 139 | 187 | } | |
| 140 | 188 | pool := webkit.NewWebViewPool(ctx, wkCtx, settings, poolCfg, injector, messageRouter) | |
| 141 | - | // Ensure prewarmed WebViews pick up the theme background color. | |
| 189 | + | ||
| 142 | 190 | bgR, bgG, bgB, bgA := themeManager.GetBackgroundRGBA() | |
| 143 | 191 | pool.SetBackgroundColor(bgR, bgG, bgB, bgA) | |
| 144 | 192 | ||
| @@ -146,21 +194,12 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||
| 146 | 194 | pool.SetFilterApplier(filterManager) | |
| 147 | 195 | } | |
| 148 | 196 | ||
| 149 | - | // Pre-create ONE WebView synchronously for instant first navigation. | |
| 150 | - | // This is the heaviest operation but happens before window is shown, | |
| 151 | - | // so users perceive it as part of the normal "loading" phase. | |
| 152 | 197 | if err := pool.PrewarmFirst(ctx); err != nil { | |
| 153 | 198 | logger.Warn().Err(err).Msg("failed to prewarm first webview, first tab may be slower") | |
| 154 | 199 | } | |
| 200 | + | logging.Trace().Mark("pool_prewarm_first") | |
| 155 | 201 | ||
| 156 | - | return WebKitStack{ | |
| 157 | - | Context: wkCtx, | |
| 158 | - | Settings: settings, | |
| 159 | - | Injector: injector, | |
| 160 | - | MessageRouter: messageRouter, | |
| 161 | - | Pool: pool, | |
| 162 | - | FilterManager: filterManager, | |
| 163 | - | } | |
| 202 | + | return pool | |
| 164 | 203 | } | |
| 165 | 204 | ||
| 166 | 205 | // hasWebProcessMemoryConfig returns true if any web process memory setting is configured. | |
| @@ -187,6 +226,12 @@ func configureRenderingEnvironment( | |||
| 187 | 226 | perfSettings *config.ResolvedPerformanceSettings, | |
| 188 | 227 | logger zerolog.Logger, | |
| 189 | 228 | ) { | |
| 229 | + | // Install GLib log handler FIRST if configured (must be before any GTK/GLib calls) | |
| 230 | + | if cfg.Logging.CaptureGTKLogs { | |
| 231 | + | enableDebug := cfg.Logging.Level == "debug" || cfg.Logging.Level == "trace" | |
| 232 | + | logging.InstallGLibLogHandler(ctx, logger, enableDebug) | |
| 233 | + | } | |
| 234 | + | ||
| 190 | 235 | renderEnv := env.NewManager() | |
| 191 | 236 | gpuVendor := renderEnv.DetectGPUVendor(ctx) | |
| 192 | 237 | renderSettings := port.RenderingEnvSettings{ | |
| @@ -11,6 +11,7 @@ import ( | |||||
| 11 | "github.com/bnema/dumber/internal/infrastructure/env" | 11 | "github.com/bnema/dumber/internal/infrastructure/env" | ||
| 12 | "github.com/bnema/dumber/internal/infrastructure/filtering" | 12 | "github.com/bnema/dumber/internal/infrastructure/filtering" | ||
| 13 | "github.com/bnema/dumber/internal/infrastructure/webkit" | 13 | "github.com/bnema/dumber/internal/infrastructure/webkit" | ||
| 14 | + | "github.com/bnema/dumber/internal/logging" | |||
| 14 | "github.com/bnema/dumber/internal/ui/theme" | 15 | "github.com/bnema/dumber/internal/ui/theme" | ||
| 15 | "github.com/rs/zerolog" | 16 | "github.com/rs/zerolog" | ||
| 16 | ) | 17 | ) | ||
| @@ -38,14 +39,44 @@ type WebKitStack struct { | |||||
| 38 | func BuildWebKitStack(input WebKitStackInput) WebKitStack { | 39 | func BuildWebKitStack(input WebKitStackInput) WebKitStack { | ||
| 39 | ctx := input.Ctx | 40 | ctx := input.Ctx | ||
| 40 | cfg := input.Config | 41 | cfg := input.Config | ||
| 41 | - | dataDir := input.DataDir | |||
| 42 | - | cacheDir := input.CacheDir | |||
| 43 | - | themeManager := input.ThemeManager | |||
| 44 | - | colorResolver := input.ColorResolver | |||
| 45 | logger := input.Logger | 42 | logger := input.Logger | ||
| 46 | - | // Detect hardware for performance profile scaling | 43 | + | |
| 44 | + | perfSettings := surveyHardwareAndResolveProfile(ctx, cfg, logger) | |||
| 45 | + | ||||
| 46 | + | configureRenderingEnvironment(ctx, cfg, &perfSettings, logger) | |||
| 47 | + | logging.Trace().Mark("render_env") | |||
| 48 | + | ||||
| 49 | + | wkOpts := buildWebKitContextOptions(input.DataDir, input.CacheDir, &perfSettings) | |||
| 50 | + | wkCtx, err := webkit.NewWebKitContextWithOptions(ctx, wkOpts) | |||
| 51 | + | if err != nil { | |||
| 52 | + | logger.Fatal().Err(err).Msg("failed to initialize WebKit context") | |||
| 53 | + | } | |||
| 54 | + | logging.Trace().Mark("webkit_context") | |||
| 55 | + | ||||
| 56 | + | filterManager := initFilterManager(ctx, cfg, input.DataDir, logger) | |||
| 57 | + | ||||
| 58 | + | schemeHandler := webkit.NewDumbSchemeHandler(ctx) | |||
| 59 | + | schemeHandler.SetAssets(assets.WebUIAssets) | |||
| 60 | + | schemeHandler.RegisterWithContext(wkCtx) | |||
| 61 | + | ||||
| 62 | + | settings, injector, messageRouter := initWebKitComponents(ctx, cfg, input.ThemeManager, input.ColorResolver, logger) | |||
| 63 | + | ||||
| 64 | + | pool := initWebViewPool(ctx, wkCtx, settings, injector, messageRouter, input.ThemeManager, filterManager, &perfSettings, logger) | |||
| 65 | + | ||||
| 66 | + | return WebKitStack{ | |||
| 67 | + | Context: wkCtx, | |||
| 68 | + | Settings: settings, | |||
| 69 | + | Injector: injector, | |||
| 70 | + | MessageRouter: messageRouter, | |||
| 71 | + | Pool: pool, | |||
| 72 | + | FilterManager: filterManager, | |||
| 73 | + | } | |||
| 74 | + | } | |||
| 75 | + | ||||
| 76 | + | func surveyHardwareAndResolveProfile(ctx context.Context, cfg *config.Config, logger zerolog.Logger) config.ResolvedPerformanceSettings { | |||
| 47 | hwSurveyor := env.NewHardwareSurveyor() | 77 | hwSurveyor := env.NewHardwareSurveyor() | ||
| 48 | hwInfo := hwSurveyor.Survey(ctx) | 78 | hwInfo := hwSurveyor.Survey(ctx) | ||
| 79 | + | logging.Trace().Mark("hardware_survey") | |||
| 49 | logger.Info(). | 80 | logger.Info(). | ||
| 50 | Int("cpu_cores", hwInfo.CPUCores). | 81 | Int("cpu_cores", hwInfo.CPUCores). | ||
| 51 | Int("cpu_threads", hwInfo.CPUThreads). | 82 | Int("cpu_threads", hwInfo.CPUThreads). | ||
| @@ -54,8 +85,8 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||||
| 54 | Uint64("vram_mb", hwInfo.VRAM/(1024*1024)). | 85 | Uint64("vram_mb", hwInfo.VRAM/(1024*1024)). | ||
| 55 | Msg("hardware survey completed") | 86 | Msg("hardware survey completed") | ||
| 56 | 87 | ||||
| 57 | - | // Resolve performance profile to get actual settings | |||
| 58 | perfSettings := config.ResolvePerformanceProfile(&cfg.Performance, &hwInfo) | 88 | perfSettings := config.ResolvePerformanceProfile(&cfg.Performance, &hwInfo) | ||
| 89 | + | logging.Trace().Mark("performance_profile") | |||
| 59 | logger.Info(). | 90 | logger.Info(). | ||
| 60 | Str("profile", string(cfg.Performance.Profile)). | 91 | Str("profile", string(cfg.Performance.Profile)). | ||
| 61 | Int("skia_cpu_threads", perfSettings.SkiaCPUPaintingThreads). | 92 | Int("skia_cpu_threads", perfSettings.SkiaCPUPaintingThreads). | ||
| @@ -63,17 +94,16 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||||
| 63 | Int("webview_pool_prewarm", perfSettings.WebViewPoolPrewarmCount). | 94 | Int("webview_pool_prewarm", perfSettings.WebViewPoolPrewarmCount). | ||
| 64 | Msg("resolved performance profile") | 95 | Msg("resolved performance profile") | ||
| 65 | 96 | ||||
| 66 | - | // Configure rendering environment (must happen before WebKit/GTK init) | 97 | + | return perfSettings |
| 67 | - | configureRenderingEnvironment(ctx, cfg, &perfSettings, logger) | 98 | + | } |
| 68 | 99 | ||||
| 69 | - | // Build WebKitContext options with memory pressure settings | 100 | + | func buildWebKitContextOptions(dataDir, cacheDir string, perfSettings *config.ResolvedPerformanceSettings) port.WebKitContextOptions { |
| 70 | wkOpts := port.WebKitContextOptions{ | 101 | wkOpts := port.WebKitContextOptions{ | ||
| 71 | DataDir: dataDir, | 102 | DataDir: dataDir, | ||
| 72 | CacheDir: cacheDir, | 103 | CacheDir: cacheDir, | ||
| 73 | } | 104 | } | ||
| 74 | 105 | ||||
| 75 | - | // Configure web process memory pressure if any setting is configured | 106 | + | if hasWebProcessMemoryConfig(perfSettings) { |
| 76 | - | if hasWebProcessMemoryConfig(&perfSettings) { | |||
| 77 | wkOpts.WebProcessMemory = &port.MemoryPressureConfig{ | 107 | wkOpts.WebProcessMemory = &port.MemoryPressureConfig{ | ||
| 78 | MemoryLimitMB: perfSettings.WebProcessMemoryLimitMB, | 108 | MemoryLimitMB: perfSettings.WebProcessMemoryLimitMB, | ||
| 79 | PollIntervalSec: perfSettings.WebProcessMemoryPollIntervalSec, | 109 | PollIntervalSec: perfSettings.WebProcessMemoryPollIntervalSec, | ||
| @@ -82,8 +112,7 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||||
| 82 | } | 112 | } | ||
| 83 | } | 113 | } | ||
| 84 | 114 | ||||
| 85 | - | // Configure network process memory pressure if any setting is configured | 115 | + | if hasNetworkProcessMemoryConfig(perfSettings) { |
| 86 | - | if hasNetworkProcessMemoryConfig(&perfSettings) { | |||
| 87 | wkOpts.NetworkProcessMemory = &port.MemoryPressureConfig{ | 116 | wkOpts.NetworkProcessMemory = &port.MemoryPressureConfig{ | ||
| 88 | MemoryLimitMB: perfSettings.NetworkProcessMemoryLimitMB, | 117 | MemoryLimitMB: perfSettings.NetworkProcessMemoryLimitMB, | ||
| 89 | PollIntervalSec: perfSettings.NetworkProcessMemoryPollIntervalSec, | 118 | PollIntervalSec: perfSettings.NetworkProcessMemoryPollIntervalSec, | ||
| @@ -92,11 +121,10 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||||
| 92 | } | 121 | } | ||
| 93 | } | 122 | } | ||
| 94 | 123 | ||||
| 95 | - | wkCtx, err := webkit.NewWebKitContextWithOptions(ctx, wkOpts) | 124 | + | return wkOpts |
| 96 | - | if err != nil { | 125 | + | } |
| 97 | - | logger.Fatal().Err(err).Msg("failed to initialize WebKit context") | |||
| 98 | - | } | |||
| 99 | 126 | ||||
| 127 | + | func initFilterManager(ctx context.Context, cfg *config.Config, dataDir string, logger zerolog.Logger) *filtering.Manager { | |||
| 100 | filterStoreDir := filepath.Join(dataDir, "filters", "store") | 128 | filterStoreDir := filepath.Join(dataDir, "filters", "store") | ||
| 101 | filterJSONDir := filepath.Join(dataDir, "filters", "json") | 129 | filterJSONDir := filepath.Join(dataDir, "filters", "json") | ||
| 102 | filterManager, err := filtering.NewManager(filtering.ManagerConfig{ | 130 | filterManager, err := filtering.NewManager(filtering.ManagerConfig{ | ||
| @@ -107,20 +135,25 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||||
| 107 | }) | 135 | }) | ||
| 108 | if err != nil { | 136 | if err != nil { | ||
| 109 | logger.Warn().Err(err).Msg("failed to create filter manager, continuing without content filtering") | 137 | logger.Warn().Err(err).Msg("failed to create filter manager, continuing without content filtering") | ||
| 110 | - | } else { | 138 | + | return nil |
| 111 | - | if err := filterManager.Initialize(ctx); err != nil { | |||
| 112 | - | logger.Warn().Err(err).Msg("failed to initialize filters, will load async") | |||
| 113 | - | } | |||
| 114 | } | 139 | } | ||
| 140 | + | if err := filterManager.Initialize(ctx); err != nil { | |||
| 141 | + | logger.Warn().Err(err).Msg("failed to initialize filters, will load async") | |||
| 142 | + | } | |||
| 143 | + | logging.Trace().Mark("filter_manager") | |||
| 144 | + | return filterManager | |||
| 145 | + | } | |||
| 115 | 146 | ||||
| 116 | - | schemeHandler := webkit.NewDumbSchemeHandler(ctx) | 147 | + | func initWebKitComponents( |
| 117 | - | schemeHandler.SetAssets(assets.WebUIAssets) | 148 | + | ctx context.Context, |
| 118 | - | schemeHandler.RegisterWithContext(wkCtx) | 149 | + | cfg *config.Config, |
| 119 | - | 150 | + | themeManager *theme.Manager, | |
| 151 | + | colorResolver port.ColorSchemeResolver, | |||
| 152 | + | logger zerolog.Logger, | |||
| 153 | + | ) (*webkit.SettingsManager, *webkit.ContentInjector, *webkit.MessageRouter) { | |||
| 120 | settings := webkit.NewSettingsManager(ctx, cfg) | 154 | settings := webkit.NewSettingsManager(ctx, cfg) | ||
| 121 | injector := webkit.NewContentInjector(colorResolver) | 155 | injector := webkit.NewContentInjector(colorResolver) | ||
| 122 | 156 | ||||
| 123 | - | // Set up auto-copy on selection config getter | |||
| 124 | injector.SetAutoCopyConfigGetter(func() bool { | 157 | injector.SetAutoCopyConfigGetter(func() bool { | ||
| 125 | return config.Get().Clipboard.AutoCopyOnSelection | 158 | return config.Get().Clipboard.AutoCopyOnSelection | ||
| 126 | }) | 159 | }) | ||
| @@ -132,13 +165,28 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||||
| 132 | } | 165 | } | ||
| 133 | 166 | ||||
| 134 | messageRouter := webkit.NewMessageRouter(ctx) | 167 | messageRouter := webkit.NewMessageRouter(ctx) | ||
| 168 | + | logging.Trace().Mark("settings_manager") | |||
| 169 | + | ||||
| 170 | + | return settings, injector, messageRouter | |||
| 171 | + | } | |||
| 172 | + | ||||
| 173 | + | func initWebViewPool( | |||
| 174 | + | ctx context.Context, | |||
| 175 | + | wkCtx *webkit.WebKitContext, | |||
| 176 | + | settings *webkit.SettingsManager, | |||
| 177 | + | injector *webkit.ContentInjector, | |||
| 178 | + | messageRouter *webkit.MessageRouter, | |||
| 179 | + | themeManager *theme.Manager, | |||
| 180 | + | filterManager *filtering.Manager, | |||
| 181 | + | perfSettings *config.ResolvedPerformanceSettings, | |||
| 182 | + | logger zerolog.Logger, | |||
| 183 | + | ) *webkit.WebViewPool { | |||
| 135 | poolCfg := webkit.DefaultPoolConfig() | 184 | poolCfg := webkit.DefaultPoolConfig() | ||
| 136 | - | // Override prewarm count from resolved profile settings | |||
| 137 | if perfSettings.WebViewPoolPrewarmCount > 0 { | 185 | if perfSettings.WebViewPoolPrewarmCount > 0 { | ||
| 138 | poolCfg.PrewarmCount = perfSettings.WebViewPoolPrewarmCount | 186 | poolCfg.PrewarmCount = perfSettings.WebViewPoolPrewarmCount | ||
| 139 | } | 187 | } | ||
| 140 | pool := webkit.NewWebViewPool(ctx, wkCtx, settings, poolCfg, injector, messageRouter) | 188 | pool := webkit.NewWebViewPool(ctx, wkCtx, settings, poolCfg, injector, messageRouter) | ||
| 141 | - | // Ensure prewarmed WebViews pick up the theme background color. | 189 | + | |
| 142 | bgR, bgG, bgB, bgA := themeManager.GetBackgroundRGBA() | 190 | bgR, bgG, bgB, bgA := themeManager.GetBackgroundRGBA() | ||
| 143 | pool.SetBackgroundColor(bgR, bgG, bgB, bgA) | 191 | pool.SetBackgroundColor(bgR, bgG, bgB, bgA) | ||
| 144 | 192 | ||||
| @@ -146,21 +194,12 @@ func BuildWebKitStack(input WebKitStackInput) WebKitStack { | |||||
| 146 | pool.SetFilterApplier(filterManager) | 194 | pool.SetFilterApplier(filterManager) | ||
| 147 | } | 195 | } | ||
| 148 | 196 | ||||
| 149 | - | // Pre-create ONE WebView synchronously for instant first navigation. | |||
| 150 | - | // This is the heaviest operation but happens before window is shown, | |||
| 151 | - | // so users perceive it as part of the normal "loading" phase. | |||
| 152 | if err := pool.PrewarmFirst(ctx); err != nil { | 197 | if err := pool.PrewarmFirst(ctx); err != nil { | ||
| 153 | logger.Warn().Err(err).Msg("failed to prewarm first webview, first tab may be slower") | 198 | logger.Warn().Err(err).Msg("failed to prewarm first webview, first tab may be slower") | ||
| 154 | } | 199 | } | ||
| 200 | + | logging.Trace().Mark("pool_prewarm_first") | |||
| 155 | 201 | ||||
| 156 | - | return WebKitStack{ | 202 | + | return pool |
| 157 | - | Context: wkCtx, | |||
| 158 | - | Settings: settings, | |||
| 159 | - | Injector: injector, | |||
| 160 | - | MessageRouter: messageRouter, | |||
| 161 | - | Pool: pool, | |||
| 162 | - | FilterManager: filterManager, | |||
| 163 | - | } | |||
| 164 | } | 203 | } | ||
| 165 | 204 | ||||
| 166 | // hasWebProcessMemoryConfig returns true if any web process memory setting is configured. | 205 | // hasWebProcessMemoryConfig returns true if any web process memory setting is configured. | ||
| @@ -187,6 +226,12 @@ func configureRenderingEnvironment( | |||||
| 187 | perfSettings *config.ResolvedPerformanceSettings, | 226 | perfSettings *config.ResolvedPerformanceSettings, | ||
| 188 | logger zerolog.Logger, | 227 | logger zerolog.Logger, | ||
| 189 | ) { | 228 | ) { | ||
| 229 | + | // Install GLib log handler FIRST if configured (must be before any GTK/GLib calls) | |||
| 230 | + | if cfg.Logging.CaptureGTKLogs { | |||
| 231 | + | enableDebug := cfg.Logging.Level == "debug" || cfg.Logging.Level == "trace" | |||
| 232 | + | logging.InstallGLibLogHandler(ctx, logger, enableDebug) | |||
| 233 | + | } | |||
| 234 | + | ||||
| 190 | renderEnv := env.NewManager() | 235 | renderEnv := env.NewManager() | ||
| 191 | gpuVendor := renderEnv.DetectGPUVendor(ctx) | 236 | gpuVendor := renderEnv.DetectGPUVendor(ctx) | ||
| 192 | renderSettings := port.RenderingEnvSettings{ | 237 | renderSettings := port.RenderingEnvSettings{ | ||
M internal/infrastructure/config/defaults.go +1 -0
| @@ -110,6 +110,7 @@ func DefaultConfig() *Config { | |||
| 110 | 110 | LogDir: getDefaultLogDir(), | |
| 111 | 111 | EnableFileLog: true, | |
| 112 | 112 | CaptureConsole: false, // Disabled by default | |
| 113 | + | CaptureGTKLogs: false, // Disabled by default | |
| 113 | 114 | }, | |
| 114 | 115 | Appearance: AppearanceConfig{ | |
| 115 | 116 | SansFont: "Fira Sans", | |
| @@ -110,6 +110,7 @@ func DefaultConfig() *Config { | |||||
| 110 | LogDir: getDefaultLogDir(), | 110 | LogDir: getDefaultLogDir(), | ||
| 111 | EnableFileLog: true, | 111 | EnableFileLog: true, | ||
| 112 | CaptureConsole: false, // Disabled by default | 112 | CaptureConsole: false, // Disabled by default | ||
| 113 | + | CaptureGTKLogs: false, // Disabled by default | |||
| 113 | }, | 114 | }, | ||
| 114 | Appearance: AppearanceConfig{ | 115 | Appearance: AppearanceConfig{ | ||
| 115 | SansFont: "Fira Sans", | 116 | SansFont: "Fira Sans", | ||
M internal/infrastructure/config/loader.go +1 -0
| @@ -397,6 +397,7 @@ func (m *Manager) setLoggingDefaults(defaults *Config) { | |||
| 397 | 397 | m.viper.SetDefault("logging.log_dir", defaults.Logging.LogDir) | |
| 398 | 398 | m.viper.SetDefault("logging.enable_file_log", defaults.Logging.EnableFileLog) | |
| 399 | 399 | m.viper.SetDefault("logging.capture_console", defaults.Logging.CaptureConsole) | |
| 400 | + | m.viper.SetDefault("logging.capture_gtk_logs", defaults.Logging.CaptureGTKLogs) | |
| 400 | 401 | } | |
| 401 | 402 | ||
| 402 | 403 | func (m *Manager) setDebugDefaults(defaults *Config) { | |
| @@ -397,6 +397,7 @@ func (m *Manager) setLoggingDefaults(defaults *Config) { | |||||
| 397 | m.viper.SetDefault("logging.log_dir", defaults.Logging.LogDir) | 397 | m.viper.SetDefault("logging.log_dir", defaults.Logging.LogDir) | ||
| 398 | m.viper.SetDefault("logging.enable_file_log", defaults.Logging.EnableFileLog) | 398 | m.viper.SetDefault("logging.enable_file_log", defaults.Logging.EnableFileLog) | ||
| 399 | m.viper.SetDefault("logging.capture_console", defaults.Logging.CaptureConsole) | 399 | m.viper.SetDefault("logging.capture_console", defaults.Logging.CaptureConsole) | ||
| 400 | + | m.viper.SetDefault("logging.capture_gtk_logs", defaults.Logging.CaptureGTKLogs) | |||
| 400 | } | 401 | } | ||
| 401 | 402 | ||||
| 402 | func (m *Manager) setDebugDefaults(defaults *Config) { | 403 | func (m *Manager) setDebugDefaults(defaults *Config) { | ||
M internal/infrastructure/config/schema.go +3 -0
| @@ -298,6 +298,9 @@ type LoggingConfig struct { | |||
| 298 | 298 | ||
| 299 | 299 | // Capture browser console to logs | |
| 300 | 300 | CaptureConsole bool `mapstructure:"capture_console" yaml:"capture_console" toml:"capture_console" json:"capture_console"` | |
| 301 | + | ||
| 302 | + | // Capture GTK4/WebKitGTK6 messages to session logs | |
| 303 | + | CaptureGTKLogs bool `mapstructure:"capture_gtk_logs" yaml:"capture_gtk_logs" toml:"capture_gtk_logs" json:"capture_gtk_logs"` | |
| 301 | 304 | } | |
| 302 | 305 | ||
| 303 | 306 | // AppearanceConfig holds UI/rendering preferences. | |
| @@ -298,6 +298,9 @@ type LoggingConfig struct { | |||||
| 298 | 298 | ||||
| 299 | // Capture browser console to logs | 299 | // Capture browser console to logs | ||
| 300 | CaptureConsole bool `mapstructure:"capture_console" yaml:"capture_console" toml:"capture_console" json:"capture_console"` | 300 | CaptureConsole bool `mapstructure:"capture_console" yaml:"capture_console" toml:"capture_console" json:"capture_console"` | ||
| 301 | + | ||||
| 302 | + | // Capture GTK4/WebKitGTK6 messages to session logs | |||
| 303 | + | CaptureGTKLogs bool `mapstructure:"capture_gtk_logs" yaml:"capture_gtk_logs" toml:"capture_gtk_logs" json:"capture_gtk_logs"` | |||
| 301 | } | 304 | } | ||
| 302 | 305 | ||||
| 303 | // AppearanceConfig holds UI/rendering preferences. | 306 | // AppearanceConfig holds UI/rendering preferences. | ||
M internal/infrastructure/persistence/sqlite/history_repo.go +3 -1
| @@ -14,6 +14,8 @@ import ( | |||
| 14 | 14 | "github.com/bnema/dumber/internal/logging" | |
| 15 | 15 | ) | |
| 16 | 16 | ||
| 17 | + | const logURLMaxLen = 60 | |
| 18 | + | ||
| 17 | 19 | type historyRepo struct { | |
| 18 | 20 | queries *sqlc.Queries | |
| 19 | 21 | } | |
| @@ -25,7 +27,7 @@ func NewHistoryRepository(db *sql.DB) repository.HistoryRepository { | |||
| 25 | 27 | ||
| 26 | 28 | func (r *historyRepo) Save(ctx context.Context, entry *entity.HistoryEntry) error { | |
| 27 | 29 | log := logging.FromContext(ctx) | |
| 28 | - | log.Debug().Str("url", entry.URL).Msg("saving history entry") | |
| 30 | + | log.Debug().Str("url", logging.TruncateURL(entry.URL, logURLMaxLen)).Msg("saving history entry") | |
| 29 | 31 | ||
| 30 | 32 | return r.queries.UpsertHistory(ctx, sqlc.UpsertHistoryParams{ | |
| 31 | 33 | Url: entry.URL, | |
| @@ -14,6 +14,8 @@ import ( | |||||
| 14 | "github.com/bnema/dumber/internal/logging" | 14 | "github.com/bnema/dumber/internal/logging" | ||
| 15 | ) | 15 | ) | ||
| 16 | 16 | ||||
| 17 | + | const logURLMaxLen = 60 | |||
| 18 | + | ||||
| 17 | type historyRepo struct { | 19 | type historyRepo struct { | ||
| 18 | queries *sqlc.Queries | 20 | queries *sqlc.Queries | ||
| 19 | } | 21 | } | ||
| @@ -25,7 +27,7 @@ func NewHistoryRepository(db *sql.DB) repository.HistoryRepository { | |||||
| 25 | 27 | ||||
| 26 | func (r *historyRepo) Save(ctx context.Context, entry *entity.HistoryEntry) error { | 28 | func (r *historyRepo) Save(ctx context.Context, entry *entity.HistoryEntry) error { | ||
| 27 | log := logging.FromContext(ctx) | 29 | log := logging.FromContext(ctx) | ||
| 28 | - | log.Debug().Str("url", entry.URL).Msg("saving history entry") | 30 | + | log.Debug().Str("url", logging.TruncateURL(entry.URL, logURLMaxLen)).Msg("saving history entry") |
| 29 | 31 | ||||
| 30 | return r.queries.UpsertHistory(ctx, sqlc.UpsertHistoryParams{ | 32 | return r.queries.UpsertHistory(ctx, sqlc.UpsertHistoryParams{ | ||
| 31 | Url: entry.URL, | 33 | Url: entry.URL, | ||
M internal/infrastructure/snapshot/service.go +17 -0
| @@ -19,6 +19,7 @@ type Service struct { | |||
| 19 | 19 | mu sync.Mutex | |
| 20 | 20 | timer *time.Timer | |
| 21 | 21 | dirty bool | |
| 22 | + | ready bool // true when session is persisted to DB and snapshots can be saved | |
| 22 | 23 | ctx context.Context | |
| 23 | 24 | cancel context.CancelFunc | |
| 24 | 25 | } | |
| @@ -48,6 +49,15 @@ func (s *Service) Start(ctx context.Context) { | |||
| 48 | 49 | logging.FromContext(ctx).Debug().Dur("interval", s.interval).Msg("snapshot service started") | |
| 49 | 50 | } | |
| 50 | 51 | ||
| 52 | + | // SetReady marks the service as ready to save snapshots. | |
| 53 | + | // Call this after the session has been persisted to the database | |
| 54 | + | // to avoid FK constraint violations. | |
| 55 | + | func (s *Service) SetReady() { | |
| 56 | + | s.mu.Lock() | |
| 57 | + | defer s.mu.Unlock() | |
| 58 | + | s.ready = true | |
| 59 | + | } | |
| 60 | + | ||
| 51 | 61 | // Stop stops the service and saves final state. | |
| 52 | 62 | func (s *Service) Stop(ctx context.Context) error { | |
| 53 | 63 | s.mu.Lock() | |
| @@ -111,6 +121,13 @@ func (s *Service) SaveNow(ctx context.Context) error { | |||
| 111 | 121 | ||
| 112 | 122 | func (s *Service) saveSnapshot(ctx context.Context) error { | |
| 113 | 123 | s.mu.Lock() | |
| 124 | + | ready := s.ready | |
| 125 | + | if !ready { | |
| 126 | + | // Don't clear dirty if not ready - keep pending snapshot for later | |
| 127 | + | s.mu.Unlock() | |
| 128 | + | return nil | |
| 129 | + | } | |
| 130 | + | // Only clear dirty when we're actually going to save | |
| 114 | 131 | s.dirty = false | |
| 115 | 132 | s.mu.Unlock() | |
| 116 | 133 | ||
| @@ -19,6 +19,7 @@ type Service struct { | |||||
| 19 | mu sync.Mutex | 19 | mu sync.Mutex | ||
| 20 | timer *time.Timer | 20 | timer *time.Timer | ||
| 21 | dirty bool | 21 | dirty bool | ||
| 22 | + | ready bool // true when session is persisted to DB and snapshots can be saved | |||
| 22 | ctx context.Context | 23 | ctx context.Context | ||
| 23 | cancel context.CancelFunc | 24 | cancel context.CancelFunc | ||
| 24 | } | 25 | } | ||
| @@ -48,6 +49,15 @@ func (s *Service) Start(ctx context.Context) { | |||||
| 48 | logging.FromContext(ctx).Debug().Dur("interval", s.interval).Msg("snapshot service started") | 49 | logging.FromContext(ctx).Debug().Dur("interval", s.interval).Msg("snapshot service started") | ||
| 49 | } | 50 | } | ||
| 50 | 51 | ||||
| 52 | + | // SetReady marks the service as ready to save snapshots. | |||
| 53 | + | // Call this after the session has been persisted to the database | |||
| 54 | + | // to avoid FK constraint violations. | |||
| 55 | + | func (s *Service) SetReady() { | |||
| 56 | + | s.mu.Lock() | |||
| 57 | + | defer s.mu.Unlock() | |||
| 58 | + | s.ready = true | |||
| 59 | + | } | |||
| 60 | + | ||||
| 51 | // Stop stops the service and saves final state. | 61 | // Stop stops the service and saves final state. | ||
| 52 | func (s *Service) Stop(ctx context.Context) error { | 62 | func (s *Service) Stop(ctx context.Context) error { | ||
| 53 | s.mu.Lock() | 63 | s.mu.Lock() | ||
| @@ -111,6 +121,13 @@ func (s *Service) SaveNow(ctx context.Context) error { | |||||
| 111 | 121 | ||||
| 112 | func (s *Service) saveSnapshot(ctx context.Context) error { | 122 | func (s *Service) saveSnapshot(ctx context.Context) error { | ||
| 113 | s.mu.Lock() | 123 | s.mu.Lock() | ||
| 124 | + | ready := s.ready | |||
| 125 | + | if !ready { | |||
| 126 | + | // Don't clear dirty if not ready - keep pending snapshot for later | |||
| 127 | + | s.mu.Unlock() | |||
| 128 | + | return nil | |||
| 129 | + | } | |||
| 130 | + | // Only clear dirty when we're actually going to save | |||
| 114 | s.dirty = false | 131 | s.dirty = false | ||
| 115 | s.mu.Unlock() | 132 | s.mu.Unlock() | ||
| 116 | 133 | ||||
M internal/infrastructure/webkit/pool.go +2 -1
| @@ -312,7 +312,8 @@ func (p *WebViewPool) PrewarmAsync(ctx context.Context, count int) { | |||
| 312 | 312 | schedule() | |
| 313 | 313 | return false | |
| 314 | 314 | }) | |
| 315 | - | glib.IdleAdd(&cb, 0) | |
| 315 | + | // Use LOW priority so initial navigation and other high-priority work runs first | |
| 316 | + | glib.IdleAddFull(glib.PRIORITY_LOW, &cb, 0, nil) | |
| 316 | 317 | } | |
| 317 | 318 | ||
| 318 | 319 | schedule() | |
| @@ -312,7 +312,8 @@ func (p *WebViewPool) PrewarmAsync(ctx context.Context, count int) { | |||||
| 312 | schedule() | 312 | schedule() | ||
| 313 | return false | 313 | return false | ||
| 314 | }) | 314 | }) | ||
| 315 | - | glib.IdleAdd(&cb, 0) | 315 | + | // Use LOW priority so initial navigation and other high-priority work runs first |
| 316 | + | glib.IdleAddFull(glib.PRIORITY_LOW, &cb, 0, nil) | |||
| 316 | } | 317 | } | ||
| 317 | 318 | ||||
| 318 | schedule() | 319 | schedule() | ||
M internal/infrastructure/webkit/webview.go +25 -0
| @@ -327,11 +327,20 @@ func NewWebViewWithRelated(ctx context.Context, parent *WebView, settings *Setti | |||
| 327 | 327 | return nil, fmt.Errorf("parent webview %d is destroyed", parent.id) | |
| 328 | 328 | } | |
| 329 | 329 | ||
| 330 | + | log.Debug(). | |
| 331 | + | Uint64("parent_ptr", uint64(parent.inner.GoPointer())). | |
| 332 | + | Msg("creating related webview with parent pointer") | |
| 333 | + | ||
| 330 | 334 | inner := webkit.NewWebViewWithRelatedView(parent.inner) | |
| 331 | 335 | if inner == nil { | |
| 332 | 336 | return nil, fmt.Errorf("failed to create related webkit webview") | |
| 333 | 337 | } | |
| 334 | 338 | ||
| 339 | + | log.Debug(). | |
| 340 | + | Uint64("new_ptr", uint64(inner.GoPointer())). | |
| 341 | + | Uint64("new_widget_ptr", uint64(inner.Widget.GoPointer())). | |
| 342 | + | Msg("related webview created, checking pointers") | |
| 343 | + | ||
| 335 | 344 | wv := &WebView{ | |
| 336 | 345 | inner: inner, | |
| 337 | 346 | isRelated: true, // Shares web process with parent - must not terminate process on destroy | |
| @@ -441,11 +450,18 @@ func (wv *WebView) connectCreateSignal() { | |||
| 441 | 450 | ParentID: wv.id, | |
| 442 | 451 | } | |
| 443 | 452 | ||
| 453 | + | wv.logger.Debug().Msg("create signal: invoking OnCreate handler") | |
| 444 | 454 | newWV := wv.OnCreate(popupReq) | |
| 455 | + | wv.logger.Debug().Bool("nil", newWV == nil).Msg("create signal: OnCreate returned") | |
| 445 | 456 | if newWV == nil { | |
| 446 | 457 | return gtk.Widget{} // Block popup | |
| 447 | 458 | } | |
| 448 | 459 | ||
| 460 | + | wv.logger.Debug(). | |
| 461 | + | Uint64("parent_id", uint64(wv.id)). | |
| 462 | + | Uint64("popup_id", uint64(newWV.id)). | |
| 463 | + | Msg("create signal: returning webview widget to WebKit") | |
| 464 | + | ||
| 449 | 465 | return newWV.inner.Widget | |
| 450 | 466 | } | |
| 451 | 467 | sigID := wv.inner.ConnectCreate(&createCb) | |
| @@ -889,6 +905,15 @@ func (wv *WebView) SetBackgroundColor(r, g, b, a float32) { | |||
| 889 | 905 | wv.inner.SetBackgroundColor(rgba) | |
| 890 | 906 | } | |
| 891 | 907 | ||
| 908 | + | // Show makes the WebView widget visible. | |
| 909 | + | // This should be called after the WebView is ready to be displayed. | |
| 910 | + | func (wv *WebView) Show() { | |
| 911 | + | if wv.destroyed.Load() { | |
| 912 | + | return | |
| 913 | + | } | |
| 914 | + | wv.inner.SetVisible(true) | |
| 915 | + | } | |
| 916 | + | ||
| 892 | 917 | // State returns the current WebView state as a snapshot. | |
| 893 | 918 | func (wv *WebView) State() port.WebViewState { | |
| 894 | 919 | return port.WebViewState{ | |
| @@ -327,11 +327,20 @@ func NewWebViewWithRelated(ctx context.Context, parent *WebView, settings *Setti | |||||
| 327 | return nil, fmt.Errorf("parent webview %d is destroyed", parent.id) | 327 | return nil, fmt.Errorf("parent webview %d is destroyed", parent.id) | ||
| 328 | } | 328 | } | ||
| 329 | 329 | ||||
| 330 | + | log.Debug(). | |||
| 331 | + | Uint64("parent_ptr", uint64(parent.inner.GoPointer())). | |||
| 332 | + | Msg("creating related webview with parent pointer") | |||
| 333 | + | ||||
| 330 | inner := webkit.NewWebViewWithRelatedView(parent.inner) | 334 | inner := webkit.NewWebViewWithRelatedView(parent.inner) | ||
| 331 | if inner == nil { | 335 | if inner == nil { | ||
| 332 | return nil, fmt.Errorf("failed to create related webkit webview") | 336 | return nil, fmt.Errorf("failed to create related webkit webview") | ||
| 333 | } | 337 | } | ||
| 334 | 338 | ||||
| 339 | + | log.Debug(). | |||
| 340 | + | Uint64("new_ptr", uint64(inner.GoPointer())). | |||
| 341 | + | Uint64("new_widget_ptr", uint64(inner.Widget.GoPointer())). | |||
| 342 | + | Msg("related webview created, checking pointers") | |||
| 343 | + | ||||
| 335 | wv := &WebView{ | 344 | wv := &WebView{ | ||
| 336 | inner: inner, | 345 | inner: inner, | ||
| 337 | isRelated: true, // Shares web process with parent - must not terminate process on destroy | 346 | isRelated: true, // Shares web process with parent - must not terminate process on destroy | ||
| @@ -441,11 +450,18 @@ func (wv *WebView) connectCreateSignal() { | |||||
| 441 | ParentID: wv.id, | 450 | ParentID: wv.id, | ||
| 442 | } | 451 | } | ||
| 443 | 452 | ||||
| 453 | + | wv.logger.Debug().Msg("create signal: invoking OnCreate handler") | |||
| 444 | newWV := wv.OnCreate(popupReq) | 454 | newWV := wv.OnCreate(popupReq) | ||
| 455 | + | wv.logger.Debug().Bool("nil", newWV == nil).Msg("create signal: OnCreate returned") | |||
| 445 | if newWV == nil { | 456 | if newWV == nil { | ||
| 446 | return gtk.Widget{} // Block popup | 457 | return gtk.Widget{} // Block popup | ||
| 447 | } | 458 | } | ||
| 448 | 459 | ||||
| 460 | + | wv.logger.Debug(). | |||
| 461 | + | Uint64("parent_id", uint64(wv.id)). | |||
| 462 | + | Uint64("popup_id", uint64(newWV.id)). | |||
| 463 | + | Msg("create signal: returning webview widget to WebKit") | |||
| 464 | + | ||||
| 449 | return newWV.inner.Widget | 465 | return newWV.inner.Widget | ||
| 450 | } | 466 | } | ||
| 451 | sigID := wv.inner.ConnectCreate(&createCb) | 467 | sigID := wv.inner.ConnectCreate(&createCb) | ||
| @@ -889,6 +905,15 @@ func (wv *WebView) SetBackgroundColor(r, g, b, a float32) { | |||||
| 889 | wv.inner.SetBackgroundColor(rgba) | 905 | wv.inner.SetBackgroundColor(rgba) | ||
| 890 | } | 906 | } | ||
| 891 | 907 | ||||
| 908 | + | // Show makes the WebView widget visible. | |||
| 909 | + | // This should be called after the WebView is ready to be displayed. | |||
| 910 | + | func (wv *WebView) Show() { | |||
| 911 | + | if wv.destroyed.Load() { | |||
| 912 | + | return | |||
| 913 | + | } | |||
| 914 | + | wv.inner.SetVisible(true) | |||
| 915 | + | } | |||
| 916 | + | ||||
| 892 | // State returns the current WebView state as a snapshot. | 917 | // State returns the current WebView state as a snapshot. | ||
| 893 | func (wv *WebView) State() port.WebViewState { | 918 | func (wv *WebView) State() port.WebViewState { | ||
| 894 | return port.WebViewState{ | 919 | return port.WebViewState{ | ||
A internal/logging/glib.go +70 -0
| @@ -0,0 +1,70 @@ | |||
| 1 | + | package logging | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "context" | |
| 5 | + | "sync" | |
| 6 | + | ||
| 7 | + | "github.com/jwijenbergh/puregotk/v4/glib" | |
| 8 | + | "github.com/rs/zerolog" | |
| 9 | + | ) | |
| 10 | + | ||
| 11 | + | // glibLogger holds the logger for the GLib handler. | |
| 12 | + | // We need this because the GLib callback doesn't support passing Go pointers directly. | |
| 13 | + | var ( | |
| 14 | + | glibLogger zerolog.Logger | |
| 15 | + | glibLoggerOnce sync.Once | |
| 16 | + | ) | |
| 17 | + | ||
| 18 | + | // InstallGLibLogHandler installs a custom GLib log handler that routes | |
| 19 | + | // GTK4/WebKitGTK6/GLib messages to the provided zerolog logger. | |
| 20 | + | // This must be called before GTK/WebKit initialization. | |
| 21 | + | // The handler captures messages from all GLib-based libraries (GTK, GDK, WebKit, etc.) | |
| 22 | + | // If enableDebug is true, GLib debug messages will also be captured (useful when log level is debug/trace). | |
| 23 | + | func InstallGLibLogHandler(ctx context.Context, logger zerolog.Logger, enableDebug bool) { | |
| 24 | + | log := FromContext(ctx) | |
| 25 | + | ||
| 26 | + | glibLoggerOnce.Do(func() { | |
| 27 | + | glibLogger = logger | |
| 28 | + | ||
| 29 | + | // Only enable GLib debug messages if requested (matches app log level) | |
| 30 | + | if enableDebug { | |
| 31 | + | glib.LogSetDebugEnabled(true) | |
| 32 | + | } | |
| 33 | + | ||
| 34 | + | // Install our custom handler for all log messages | |
| 35 | + | handler := glib.LogFunc(glibLogHandler) | |
| 36 | + | glib.LogSetDefaultHandler(&handler, 0) | |
| 37 | + | ||
| 38 | + | log.Info().Bool("debug_enabled", enableDebug).Msg("GLib log handler installed") | |
| 39 | + | }) | |
| 40 | + | } | |
| 41 | + | ||
| 42 | + | // glibLogHandler is the callback invoked by GLib for all log messages. | |
| 43 | + | func glibLogHandler(domain string, level glib.LogLevelFlags, message string, _ uintptr) { | |
| 44 | + | // Map GLib log levels to zerolog levels | |
| 45 | + | var event *zerolog.Event | |
| 46 | + | ||
| 47 | + | switch { | |
| 48 | + | case level&glib.GLogLevelErrorValue != 0: | |
| 49 | + | event = glibLogger.Error() | |
| 50 | + | case level&glib.GLogLevelCriticalValue != 0: | |
| 51 | + | event = glibLogger.Error() | |
| 52 | + | case level&glib.GLogLevelWarningValue != 0: | |
| 53 | + | event = glibLogger.Warn() | |
| 54 | + | case level&glib.GLogLevelMessageValue != 0: | |
| 55 | + | event = glibLogger.Info() | |
| 56 | + | case level&glib.GLogLevelInfoValue != 0: | |
| 57 | + | event = glibLogger.Info() | |
| 58 | + | case level&glib.GLogLevelDebugValue != 0: | |
| 59 | + | event = glibLogger.Debug() | |
| 60 | + | default: | |
| 61 | + | event = glibLogger.Debug() | |
| 62 | + | } | |
| 63 | + | ||
| 64 | + | // Add domain if present | |
| 65 | + | if domain != "" { | |
| 66 | + | event = event.Str("glib_domain", domain) | |
| 67 | + | } | |
| 68 | + | ||
| 69 | + | event.Msg(message) | |
| 70 | + | } | |
| @@ -0,0 +1,70 @@ | |||||
| 1 | + | package logging | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "context" | |||
| 5 | + | "sync" | |||
| 6 | + | ||||
| 7 | + | "github.com/jwijenbergh/puregotk/v4/glib" | |||
| 8 | + | "github.com/rs/zerolog" | |||
| 9 | + | ) | |||
| 10 | + | ||||
| 11 | + | // glibLogger holds the logger for the GLib handler. | |||
| 12 | + | // We need this because the GLib callback doesn't support passing Go pointers directly. | |||
| 13 | + | var ( | |||
| 14 | + | glibLogger zerolog.Logger | |||
| 15 | + | glibLoggerOnce sync.Once | |||
| 16 | + | ) | |||
| 17 | + | ||||
| 18 | + | // InstallGLibLogHandler installs a custom GLib log handler that routes | |||
| 19 | + | // GTK4/WebKitGTK6/GLib messages to the provided zerolog logger. | |||
| 20 | + | // This must be called before GTK/WebKit initialization. | |||
| 21 | + | // The handler captures messages from all GLib-based libraries (GTK, GDK, WebKit, etc.) | |||
| 22 | + | // If enableDebug is true, GLib debug messages will also be captured (useful when log level is debug/trace). | |||
| 23 | + | func InstallGLibLogHandler(ctx context.Context, logger zerolog.Logger, enableDebug bool) { | |||
| 24 | + | log := FromContext(ctx) | |||
| 25 | + | ||||
| 26 | + | glibLoggerOnce.Do(func() { | |||
| 27 | + | glibLogger = logger | |||
| 28 | + | ||||
| 29 | + | // Only enable GLib debug messages if requested (matches app log level) | |||
| 30 | + | if enableDebug { | |||
| 31 | + | glib.LogSetDebugEnabled(true) | |||
| 32 | + | } | |||
| 33 | + | ||||
| 34 | + | // Install our custom handler for all log messages | |||
| 35 | + | handler := glib.LogFunc(glibLogHandler) | |||
| 36 | + | glib.LogSetDefaultHandler(&handler, 0) | |||
| 37 | + | ||||
| 38 | + | log.Info().Bool("debug_enabled", enableDebug).Msg("GLib log handler installed") | |||
| 39 | + | }) | |||
| 40 | + | } | |||
| 41 | + | ||||
| 42 | + | // glibLogHandler is the callback invoked by GLib for all log messages. | |||
| 43 | + | func glibLogHandler(domain string, level glib.LogLevelFlags, message string, _ uintptr) { | |||
| 44 | + | // Map GLib log levels to zerolog levels | |||
| 45 | + | var event *zerolog.Event | |||
| 46 | + | ||||
| 47 | + | switch { | |||
| 48 | + | case level&glib.GLogLevelErrorValue != 0: | |||
| 49 | + | event = glibLogger.Error() | |||
| 50 | + | case level&glib.GLogLevelCriticalValue != 0: | |||
| 51 | + | event = glibLogger.Error() | |||
| 52 | + | case level&glib.GLogLevelWarningValue != 0: | |||
| 53 | + | event = glibLogger.Warn() | |||
| 54 | + | case level&glib.GLogLevelMessageValue != 0: | |||
| 55 | + | event = glibLogger.Info() | |||
| 56 | + | case level&glib.GLogLevelInfoValue != 0: | |||
| 57 | + | event = glibLogger.Info() | |||
| 58 | + | case level&glib.GLogLevelDebugValue != 0: | |||
| 59 | + | event = glibLogger.Debug() | |||
| 60 | + | default: | |||
| 61 | + | event = glibLogger.Debug() | |||
| 62 | + | } | |||
| 63 | + | ||||
| 64 | + | // Add domain if present | |||
| 65 | + | if domain != "" { | |||
| 66 | + | event = event.Str("glib_domain", domain) | |||
| 67 | + | } | |||
| 68 | + | ||||
| 69 | + | event.Msg(message) | |||
| 70 | + | } | |||
M internal/logging/logger.go +8 -0
| @@ -189,3 +189,11 @@ func ParseLevel(level string) zerolog.Level { | |||
| 189 | 189 | return zerolog.InfoLevel | |
| 190 | 190 | } | |
| 191 | 191 | } | |
| 192 | + | ||
| 193 | + | // TruncateURL truncates a URL to maxLen characters for logging. | |
| 194 | + | func TruncateURL(url string, maxLen int) string { | |
| 195 | + | if len(url) <= maxLen { | |
| 196 | + | return url | |
| 197 | + | } | |
| 198 | + | return url[:maxLen] + "..." | |
| 199 | + | } | |
| @@ -189,3 +189,11 @@ func ParseLevel(level string) zerolog.Level { | |||||
| 189 | return zerolog.InfoLevel | 189 | return zerolog.InfoLevel | ||
| 190 | } | 190 | } | ||
| 191 | } | 191 | } | ||
| 192 | + | ||||
| 193 | + | // TruncateURL truncates a URL to maxLen characters for logging. | |||
| 194 | + | func TruncateURL(url string, maxLen int) string { | |||
| 195 | + | if len(url) <= maxLen { | |||
| 196 | + | return url | |||
| 197 | + | } | |||
| 198 | + | return url[:maxLen] + "..." | |||
| 199 | + | } | |||
A internal/logging/startup_trace.go +220 -0
| @@ -0,0 +1,220 @@ | |||
| 1 | + | package logging | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "fmt" | |
| 5 | + | "strings" | |
| 6 | + | "sync" | |
| 7 | + | "time" | |
| 8 | + | ||
| 9 | + | "github.com/rs/zerolog" | |
| 10 | + | ) | |
| 11 | + | ||
| 12 | + | // StartupTrace tracks cold start milestones from process launch to first paint. | |
| 13 | + | // Thread-safe for use across goroutines. | |
| 14 | + | // Enabled only when log level is debug or trace. | |
| 15 | + | type StartupTrace struct { | |
| 16 | + | mu sync.Mutex | |
| 17 | + | t0 time.Time | |
| 18 | + | milestones []Milestone | |
| 19 | + | enabled bool | |
| 20 | + | logger *zerolog.Logger | |
| 21 | + | buffered []Milestone // milestones recorded before logger is set | |
| 22 | + | finished bool | |
| 23 | + | } | |
| 24 | + | ||
| 25 | + | // Milestone represents a timing checkpoint during startup. | |
| 26 | + | type Milestone struct { | |
| 27 | + | Name string | |
| 28 | + | Elapsed time.Duration // time since t0 | |
| 29 | + | Delta time.Duration // time since previous milestone | |
| 30 | + | } | |
| 31 | + | ||
| 32 | + | var ( | |
| 33 | + | globalTrace *StartupTrace | |
| 34 | + | globalTraceMu sync.Mutex | |
| 35 | + | globalTraceOnce sync.Once | |
| 36 | + | ) | |
| 37 | + | ||
| 38 | + | // InitStartupTrace initializes the global startup trace. | |
| 39 | + | // Call this as early as possible in main() to capture T0. | |
| 40 | + | // The trace is enabled only if the given log level is debug or trace. | |
| 41 | + | func InitStartupTrace(logLevel string) { | |
| 42 | + | globalTraceOnce.Do(func() { | |
| 43 | + | enabled := logLevel == "debug" || logLevel == "trace" | |
| 44 | + | globalTraceMu.Lock() | |
| 45 | + | globalTrace = &StartupTrace{ | |
| 46 | + | t0: time.Now(), | |
| 47 | + | milestones: make([]Milestone, 0, 32), | |
| 48 | + | enabled: enabled, | |
| 49 | + | buffered: make([]Milestone, 0, 8), | |
| 50 | + | } | |
| 51 | + | globalTraceMu.Unlock() | |
| 52 | + | ||
| 53 | + | if enabled { | |
| 54 | + | // Record process_start as first milestone | |
| 55 | + | globalTrace.Mark("process_start") | |
| 56 | + | } | |
| 57 | + | }) | |
| 58 | + | } | |
| 59 | + | ||
| 60 | + | // Trace returns the global startup trace instance. | |
| 61 | + | // Returns a no-op trace if not initialized or disabled. | |
| 62 | + | func Trace() *StartupTrace { | |
| 63 | + | globalTraceMu.Lock() | |
| 64 | + | defer globalTraceMu.Unlock() | |
| 65 | + | if globalTrace == nil { | |
| 66 | + | // Return a disabled no-op trace | |
| 67 | + | return &StartupTrace{enabled: false} | |
| 68 | + | } | |
| 69 | + | return globalTrace | |
| 70 | + | } | |
| 71 | + | ||
| 72 | + | // SetLogger sets the logger for emitting milestone logs. | |
| 73 | + | // Flushes any buffered milestones that were recorded before the logger was set. | |
| 74 | + | func (st *StartupTrace) SetLogger(logger *zerolog.Logger) { | |
| 75 | + | if st == nil || !st.enabled { | |
| 76 | + | return | |
| 77 | + | } | |
| 78 | + | ||
| 79 | + | st.mu.Lock() | |
| 80 | + | defer st.mu.Unlock() | |
| 81 | + | ||
| 82 | + | st.logger = logger | |
| 83 | + | ||
| 84 | + | // Flush buffered milestones | |
| 85 | + | for _, m := range st.buffered { | |
| 86 | + | st.emitMilestone(m) | |
| 87 | + | } | |
| 88 | + | st.buffered = nil | |
| 89 | + | } | |
| 90 | + | ||
| 91 | + | // UpdateLogger updates the logger and re-emits all milestones to the new logger. | |
| 92 | + | // Call this after the session file logger is available to capture milestones in the log file. | |
| 93 | + | func (st *StartupTrace) UpdateLogger(logger *zerolog.Logger) { | |
| 94 | + | if st == nil || !st.enabled { | |
| 95 | + | return | |
| 96 | + | } | |
| 97 | + | ||
| 98 | + | st.mu.Lock() | |
| 99 | + | defer st.mu.Unlock() | |
| 100 | + | ||
| 101 | + | st.logger = logger | |
| 102 | + | ||
| 103 | + | // Re-emit all milestones to the new logger | |
| 104 | + | for _, m := range st.milestones { | |
| 105 | + | st.emitMilestone(m) | |
| 106 | + | } | |
| 107 | + | } | |
| 108 | + | ||
| 109 | + | // Mark records a milestone with the given name. | |
| 110 | + | // Emits a debug log line showing elapsed time and delta from previous milestone. | |
| 111 | + | func (st *StartupTrace) Mark(name string) { | |
| 112 | + | if st == nil || !st.enabled { | |
| 113 | + | return | |
| 114 | + | } | |
| 115 | + | ||
| 116 | + | st.mu.Lock() | |
| 117 | + | defer st.mu.Unlock() | |
| 118 | + | ||
| 119 | + | if st.finished { | |
| 120 | + | return | |
| 121 | + | } | |
| 122 | + | ||
| 123 | + | now := time.Now() | |
| 124 | + | elapsed := now.Sub(st.t0) | |
| 125 | + | ||
| 126 | + | var delta time.Duration | |
| 127 | + | if len(st.milestones) > 0 { | |
| 128 | + | delta = elapsed - st.milestones[len(st.milestones)-1].Elapsed | |
| 129 | + | } | |
| 130 | + | ||
| 131 | + | m := Milestone{ | |
| 132 | + | Name: name, | |
| 133 | + | Elapsed: elapsed, | |
| 134 | + | Delta: delta, | |
| 135 | + | } | |
| 136 | + | st.milestones = append(st.milestones, m) | |
| 137 | + | ||
| 138 | + | if st.logger != nil { | |
| 139 | + | st.emitMilestone(m) | |
| 140 | + | } else { | |
| 141 | + | // Buffer until logger is set | |
| 142 | + | st.buffered = append(st.buffered, m) | |
| 143 | + | } | |
| 144 | + | } | |
| 145 | + | ||
| 146 | + | // emitMilestone logs a single milestone. Caller must hold mutex. | |
| 147 | + | func (st *StartupTrace) emitMilestone(m Milestone) { | |
| 148 | + | if st.logger == nil { | |
| 149 | + | return | |
| 150 | + | } | |
| 151 | + | ||
| 152 | + | elapsedMs := m.Elapsed.Milliseconds() | |
| 153 | + | ||
| 154 | + | event := st.logger.Debug(). | |
| 155 | + | Str("milestone", m.Name). | |
| 156 | + | Int64("t_ms", elapsedMs) | |
| 157 | + | ||
| 158 | + | if m.Delta > 0 { | |
| 159 | + | event = event.Int64("delta_ms", m.Delta.Milliseconds()) | |
| 160 | + | } | |
| 161 | + | ||
| 162 | + | // Format: startup_trace: milestone_name (T+123ms, +45ms) | |
| 163 | + | if m.Delta > 0 { | |
| 164 | + | event.Msgf("startup_trace: %s (T+%dms, +%dms)", m.Name, elapsedMs, m.Delta.Milliseconds()) | |
| 165 | + | } else { | |
| 166 | + | event.Msgf("startup_trace: %s (T+%dms)", m.Name, elapsedMs) | |
| 167 | + | } | |
| 168 | + | } | |
| 169 | + | ||
| 170 | + | // Finish marks the startup trace as complete and emits a summary. | |
| 171 | + | // Called on first_paint milestone. | |
| 172 | + | func (st *StartupTrace) Finish() { | |
| 173 | + | if st == nil || !st.enabled { | |
| 174 | + | return | |
| 175 | + | } | |
| 176 | + | ||
| 177 | + | st.mu.Lock() | |
| 178 | + | defer st.mu.Unlock() | |
| 179 | + | ||
| 180 | + | if st.finished { | |
| 181 | + | return | |
| 182 | + | } | |
| 183 | + | st.finished = true | |
| 184 | + | ||
| 185 | + | if st.logger == nil { | |
| 186 | + | return | |
| 187 | + | } | |
| 188 | + | ||
| 189 | + | // Build summary string | |
| 190 | + | total := time.Since(st.t0) | |
| 191 | + | var parts []string | |
| 192 | + | for _, m := range st.milestones { | |
| 193 | + | parts = append(parts, fmt.Sprintf("%s:%d", m.Name, m.Elapsed.Milliseconds())) | |
| 194 | + | } | |
| 195 | + | summary := strings.Join(parts, ",") | |
| 196 | + | ||
| 197 | + | st.logger.Info(). | |
| 198 | + | Int64("total_ms", total.Milliseconds()). | |
| 199 | + | Str("milestones", summary). | |
| 200 | + | Msg("startup_trace: cold start complete") | |
| 201 | + | } | |
| 202 | + | ||
| 203 | + | // Enabled returns whether the trace is active. | |
| 204 | + | func (st *StartupTrace) Enabled() bool { | |
| 205 | + | if st == nil { | |
| 206 | + | return false | |
| 207 | + | } | |
| 208 | + | return st.enabled | |
| 209 | + | } | |
| 210 | + | ||
| 211 | + | // TotalElapsed returns the total time since T0. | |
| 212 | + | func (st *StartupTrace) TotalElapsed() time.Duration { | |
| 213 | + | if st == nil || !st.enabled { | |
| 214 | + | return 0 | |
| 215 | + | } | |
| 216 | + | ||
| 217 | + | st.mu.Lock() | |
| 218 | + | defer st.mu.Unlock() | |
| 219 | + | return time.Since(st.t0) | |
| 220 | + | } | |
| @@ -0,0 +1,220 @@ | |||||
| 1 | + | package logging | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "fmt" | |||
| 5 | + | "strings" | |||
| 6 | + | "sync" | |||
| 7 | + | "time" | |||
| 8 | + | ||||
| 9 | + | "github.com/rs/zerolog" | |||
| 10 | + | ) | |||
| 11 | + | ||||
| 12 | + | // StartupTrace tracks cold start milestones from process launch to first paint. | |||
| 13 | + | // Thread-safe for use across goroutines. | |||
| 14 | + | // Enabled only when log level is debug or trace. | |||
| 15 | + | type StartupTrace struct { | |||
| 16 | + | mu sync.Mutex | |||
| 17 | + | t0 time.Time | |||
| 18 | + | milestones []Milestone | |||
| 19 | + | enabled bool | |||
| 20 | + | logger *zerolog.Logger | |||
| 21 | + | buffered []Milestone // milestones recorded before logger is set | |||
| 22 | + | finished bool | |||
| 23 | + | } | |||
| 24 | + | ||||
| 25 | + | // Milestone represents a timing checkpoint during startup. | |||
| 26 | + | type Milestone struct { | |||
| 27 | + | Name string | |||
| 28 | + | Elapsed time.Duration // time since t0 | |||
| 29 | + | Delta time.Duration // time since previous milestone | |||
| 30 | + | } | |||
| 31 | + | ||||
| 32 | + | var ( | |||
| 33 | + | globalTrace *StartupTrace | |||
| 34 | + | globalTraceMu sync.Mutex | |||
| 35 | + | globalTraceOnce sync.Once | |||
| 36 | + | ) | |||
| 37 | + | ||||
| 38 | + | // InitStartupTrace initializes the global startup trace. | |||
| 39 | + | // Call this as early as possible in main() to capture T0. | |||
| 40 | + | // The trace is enabled only if the given log level is debug or trace. | |||
| 41 | + | func InitStartupTrace(logLevel string) { | |||
| 42 | + | globalTraceOnce.Do(func() { | |||
| 43 | + | enabled := logLevel == "debug" || logLevel == "trace" | |||
| 44 | + | globalTraceMu.Lock() | |||
| 45 | + | globalTrace = &StartupTrace{ | |||
| 46 | + | t0: time.Now(), | |||
| 47 | + | milestones: make([]Milestone, 0, 32), | |||
| 48 | + | enabled: enabled, | |||
| 49 | + | buffered: make([]Milestone, 0, 8), | |||
| 50 | + | } | |||
| 51 | + | globalTraceMu.Unlock() | |||
| 52 | + | ||||
| 53 | + | if enabled { | |||
| 54 | + | // Record process_start as first milestone | |||
| 55 | + | globalTrace.Mark("process_start") | |||
| 56 | + | } | |||
| 57 | + | }) | |||
| 58 | + | } | |||
| 59 | + | ||||
| 60 | + | // Trace returns the global startup trace instance. | |||
| 61 | + | // Returns a no-op trace if not initialized or disabled. | |||
| 62 | + | func Trace() *StartupTrace { | |||
| 63 | + | globalTraceMu.Lock() | |||
| 64 | + | defer globalTraceMu.Unlock() | |||
| 65 | + | if globalTrace == nil { | |||
| 66 | + | // Return a disabled no-op trace | |||
| 67 | + | return &StartupTrace{enabled: false} | |||
| 68 | + | } | |||
| 69 | + | return globalTrace | |||
| 70 | + | } | |||
| 71 | + | ||||
| 72 | + | // SetLogger sets the logger for emitting milestone logs. | |||
| 73 | + | // Flushes any buffered milestones that were recorded before the logger was set. | |||
| 74 | + | func (st *StartupTrace) SetLogger(logger *zerolog.Logger) { | |||
| 75 | + | if st == nil || !st.enabled { | |||
| 76 | + | return | |||
| 77 | + | } | |||
| 78 | + | ||||
| 79 | + | st.mu.Lock() | |||
| 80 | + | defer st.mu.Unlock() | |||
| 81 | + | ||||
| 82 | + | st.logger = logger | |||
| 83 | + | ||||
| 84 | + | // Flush buffered milestones | |||
| 85 | + | for _, m := range st.buffered { | |||
| 86 | + | st.emitMilestone(m) | |||
| 87 | + | } | |||
| 88 | + | st.buffered = nil | |||
| 89 | + | } | |||
| 90 | + | ||||
| 91 | + | // UpdateLogger updates the logger and re-emits all milestones to the new logger. | |||
| 92 | + | // Call this after the session file logger is available to capture milestones in the log file. | |||
| 93 | + | func (st *StartupTrace) UpdateLogger(logger *zerolog.Logger) { | |||
| 94 | + | if st == nil || !st.enabled { | |||
| 95 | + | return | |||
| 96 | + | } | |||
| 97 | + | ||||
| 98 | + | st.mu.Lock() | |||
| 99 | + | defer st.mu.Unlock() | |||
| 100 | + | ||||
| 101 | + | st.logger = logger | |||
| 102 | + | ||||
| 103 | + | // Re-emit all milestones to the new logger | |||
| 104 | + | for _, m := range st.milestones { | |||
| 105 | + | st.emitMilestone(m) | |||
| 106 | + | } | |||
| 107 | + | } | |||
| 108 | + | ||||
| 109 | + | // Mark records a milestone with the given name. | |||
| 110 | + | // Emits a debug log line showing elapsed time and delta from previous milestone. | |||
| 111 | + | func (st *StartupTrace) Mark(name string) { | |||
| 112 | + | if st == nil || !st.enabled { | |||
| 113 | + | return | |||
| 114 | + | } | |||
| 115 | + | ||||
| 116 | + | st.mu.Lock() | |||
| 117 | + | defer st.mu.Unlock() | |||
| 118 | + | ||||
| 119 | + | if st.finished { | |||
| 120 | + | return | |||
| 121 | + | } | |||
| 122 | + | ||||
| 123 | + | now := time.Now() | |||
| 124 | + | elapsed := now.Sub(st.t0) | |||
| 125 | + | ||||
| 126 | + | var delta time.Duration | |||
| 127 | + | if len(st.milestones) > 0 { | |||
| 128 | + | delta = elapsed - st.milestones[len(st.milestones)-1].Elapsed | |||
| 129 | + | } | |||
| 130 | + | ||||
| 131 | + | m := Milestone{ | |||
| 132 | + | Name: name, | |||
| 133 | + | Elapsed: elapsed, | |||
| 134 | + | Delta: delta, | |||
| 135 | + | } | |||
| 136 | + | st.milestones = append(st.milestones, m) | |||
| 137 | + | ||||
| 138 | + | if st.logger != nil { | |||
| 139 | + | st.emitMilestone(m) | |||
| 140 | + | } else { | |||
| 141 | + | // Buffer until logger is set | |||
| 142 | + | st.buffered = append(st.buffered, m) | |||
| 143 | + | } | |||
| 144 | + | } | |||
| 145 | + | ||||
| 146 | + | // emitMilestone logs a single milestone. Caller must hold mutex. | |||
| 147 | + | func (st *StartupTrace) emitMilestone(m Milestone) { | |||
| 148 | + | if st.logger == nil { | |||
| 149 | + | return | |||
| 150 | + | } | |||
| 151 | + | ||||
| 152 | + | elapsedMs := m.Elapsed.Milliseconds() | |||
| 153 | + | ||||
| 154 | + | event := st.logger.Debug(). | |||
| 155 | + | Str("milestone", m.Name). | |||
| 156 | + | Int64("t_ms", elapsedMs) | |||
| 157 | + | ||||
| 158 | + | if m.Delta > 0 { | |||
| 159 | + | event = event.Int64("delta_ms", m.Delta.Milliseconds()) | |||
| 160 | + | } | |||
| 161 | + | ||||
| 162 | + | // Format: startup_trace: milestone_name (T+123ms, +45ms) | |||
| 163 | + | if m.Delta > 0 { | |||
| 164 | + | event.Msgf("startup_trace: %s (T+%dms, +%dms)", m.Name, elapsedMs, m.Delta.Milliseconds()) | |||
| 165 | + | } else { | |||
| 166 | + | event.Msgf("startup_trace: %s (T+%dms)", m.Name, elapsedMs) | |||
| 167 | + | } | |||
| 168 | + | } | |||
| 169 | + | ||||
| 170 | + | // Finish marks the startup trace as complete and emits a summary. | |||
| 171 | + | // Called on first_paint milestone. | |||
| 172 | + | func (st *StartupTrace) Finish() { | |||
| 173 | + | if st == nil || !st.enabled { | |||
| 174 | + | return | |||
| 175 | + | } | |||
| 176 | + | ||||
| 177 | + | st.mu.Lock() | |||
| 178 | + | defer st.mu.Unlock() | |||
| 179 | + | ||||
| 180 | + | if st.finished { | |||
| 181 | + | return | |||
| 182 | + | } | |||
| 183 | + | st.finished = true | |||
| 184 | + | ||||
| 185 | + | if st.logger == nil { | |||
| 186 | + | return | |||
| 187 | + | } | |||
| 188 | + | ||||
| 189 | + | // Build summary string | |||
| 190 | + | total := time.Since(st.t0) | |||
| 191 | + | var parts []string | |||
| 192 | + | for _, m := range st.milestones { | |||
| 193 | + | parts = append(parts, fmt.Sprintf("%s:%d", m.Name, m.Elapsed.Milliseconds())) | |||
| 194 | + | } | |||
| 195 | + | summary := strings.Join(parts, ",") | |||
| 196 | + | ||||
| 197 | + | st.logger.Info(). | |||
| 198 | + | Int64("total_ms", total.Milliseconds()). | |||
| 199 | + | Str("milestones", summary). | |||
| 200 | + | Msg("startup_trace: cold start complete") | |||
| 201 | + | } | |||
| 202 | + | ||||
| 203 | + | // Enabled returns whether the trace is active. | |||
| 204 | + | func (st *StartupTrace) Enabled() bool { | |||
| 205 | + | if st == nil { | |||
| 206 | + | return false | |||
| 207 | + | } | |||
| 208 | + | return st.enabled | |||
| 209 | + | } | |||
| 210 | + | ||||
| 211 | + | // TotalElapsed returns the total time since T0. | |||
| 212 | + | func (st *StartupTrace) TotalElapsed() time.Duration { | |||
| 213 | + | if st == nil || !st.enabled { | |||
| 214 | + | return 0 | |||
| 215 | + | } | |||
| 216 | + | ||||
| 217 | + | st.mu.Lock() | |||
| 218 | + | defer st.mu.Unlock() | |||
| 219 | + | return time.Since(st.t0) | |||
| 220 | + | } | |||
M internal/ui/app.go +52 -14
| @@ -115,6 +115,10 @@ type App struct { | |||
| 115 | 115 | insertAccentUC *usecase.InsertAccentUseCase | |
| 116 | 116 | accentFocusProvider *textinput.FocusProvider | |
| 117 | 117 | ||
| 118 | + | // Deferred initialization - runs after first load_started to avoid blocking initial navigation | |
| 119 | + | deferredInitOnce sync.Once | |
| 120 | + | deferredInitFn func() | |
| 121 | + | ||
| 118 | 122 | // lifecycle | |
| 119 | 123 | cancel context.CancelCauseFunc | |
| 120 | 124 | } | |
| @@ -182,6 +186,7 @@ func (a *App) Run(ctx context.Context, args []string) int { | |||
| 182 | 186 | // Initialize libadwaita once (required before using StyleManager). | |
| 183 | 187 | // This also initializes GTK implicitly. | |
| 184 | 188 | adw.Init() | |
| 189 | + | logging.Trace().Mark("gtk_init") | |
| 185 | 190 | ||
| 186 | 191 | // Mark adwaita detector as available now that adw.Init() is complete. | |
| 187 | 192 | // This enables the highest-priority color scheme detector. | |
| @@ -203,6 +208,7 @@ func (a *App) Run(ctx context.Context, args []string) int { | |||
| 203 | 208 | return 1 | |
| 204 | 209 | } | |
| 205 | 210 | defer a.gtkApp.Unref() | |
| 211 | + | logging.Trace().Mark("gtk_app_created") | |
| 206 | 212 | ||
| 207 | 213 | // Connect activate signal | |
| 208 | 214 | activateCb := func(_ gio.Application) { | |
| @@ -236,6 +242,7 @@ func (a *App) onActivate(ctx context.Context) { | |||
| 236 | 242 | log.Error().Err(err).Msg("failed to create main window") | |
| 237 | 243 | return | |
| 238 | 244 | } | |
| 245 | + | logging.Trace().Mark("window_created") | |
| 239 | 246 | ||
| 240 | 247 | a.initLayoutInfrastructure() | |
| 241 | 248 | a.initAppToasterOverlay() | |
| @@ -244,6 +251,7 @@ func (a *App) onActivate(ctx context.Context) { | |||
| 244 | 251 | a.initDownloadHandler(ctx) | |
| 245 | 252 | ||
| 246 | 253 | a.initCoordinators(ctx) | |
| 254 | + | logging.Trace().Mark("coordinators_init") | |
| 247 | 255 | a.initKeyboardHandler(ctx) | |
| 248 | 256 | a.initOmniboxConfig(ctx) | |
| 249 | 257 | a.initFindBarConfig() | |
| @@ -252,8 +260,6 @@ func (a *App) onActivate(ctx context.Context) { | |||
| 252 | 260 | a.initSnapshotService(ctx) | |
| 253 | 261 | a.initUpdateCoordinator(ctx) | |
| 254 | 262 | a.createInitialTab(ctx) | |
| 255 | - | // Prewarm the remaining WebViews after the initial tab starts loading. | |
| 256 | - | a.prewarmWebViewPoolAsync(ctx) | |
| 257 | 263 | a.finalizeActivation(ctx) | |
| 258 | 264 | } | |
| 259 | 265 | ||
| @@ -1016,6 +1022,11 @@ func (a *App) initSnapshotService(ctx context.Context) { | |||
| 1016 | 1022 | a.snapshotService = snapshot.NewService(a.deps.SnapshotUC, a, intervalMs) | |
| 1017 | 1023 | a.snapshotService.Start(ctx) | |
| 1018 | 1024 | ||
| 1025 | + | // Set up callback for main.go to notify when session is persisted | |
| 1026 | + | a.deps.OnSessionPersisted = func() { | |
| 1027 | + | a.snapshotService.SetReady() | |
| 1028 | + | } | |
| 1029 | + | ||
| 1019 | 1030 | log.Debug().Int("interval_ms", intervalMs).Msg("snapshot service started") | |
| 1020 | 1031 | } | |
| 1021 | 1032 | ||
| @@ -1149,26 +1160,48 @@ func (a *App) restoreSession(ctx context.Context, sessionID entity.SessionID) er | |||
| 1149 | 1160 | func (a *App) finalizeActivation(ctx context.Context) { | |
| 1150 | 1161 | log := logging.FromContext(ctx) | |
| 1151 | 1162 | ||
| 1152 | - | // Show the window. | |
| 1163 | + | // Show the window | |
| 1153 | 1164 | if a.mainWindow != nil { | |
| 1154 | 1165 | a.mainWindow.Show() | |
| 1155 | 1166 | } | |
| 1156 | 1167 | log.Info().Msg("main window displayed") | |
| 1157 | 1168 | ||
| 1158 | - | // Start watching config for appearance changes. | |
| 1159 | - | a.initConfigWatcher(ctx) | |
| 1169 | + | // Defer non-critical initialization until after first navigation starts. | |
| 1170 | + | // This keeps pool prewarm, config watcher, and filter loading from | |
| 1171 | + | // competing with the initial page load. | |
| 1172 | + | a.runAfterFirstLoadStarted(func() { | |
| 1173 | + | a.prewarmWebViewPoolAsync(ctx) | |
| 1174 | + | a.initConfigWatcher(ctx) | |
| 1175 | + | a.initFilteringAsync(ctx) | |
| 1176 | + | a.checkConfigMigration(ctx) | |
| 1177 | + | }) | |
| 1178 | + | } | |
| 1160 | 1179 | ||
| 1161 | - | // Ensure the current appearance config is applied once at startup. | |
| 1162 | - | // This avoids the WebUI showing default tokens until the first config change event. | |
| 1163 | - | if a.deps != nil { | |
| 1164 | - | a.applyAppearanceConfig(ctx, a.deps.Config) | |
| 1165 | - | } | |
| 1180 | + | // runAfterFirstLoadStarted schedules work to run after the first navigation starts. | |
| 1181 | + | // This keeps the GTK main loop free to process the initial load_uri() quickly, | |
| 1182 | + | // reducing the gap between webview_attached and load_started. | |
| 1183 | + | func (a *App) runAfterFirstLoadStarted(fn func()) { | |
| 1184 | + | a.deferredInitFn = fn | |
| 1185 | + | } | |
| 1166 | 1186 | ||
| 1167 | - | // Start async filter loading after window is visible. | |
| 1168 | - | a.initFilteringAsync(ctx) | |
| 1187 | + | // triggerDeferredInit is called from ContentCoordinator on first load_started. | |
| 1188 | + | // It runs deferred initialization at LOW priority so navigation continues unblocked. | |
| 1189 | + | func (a *App) triggerDeferredInit(ctx context.Context) { | |
| 1190 | + | a.deferredInitOnce.Do(func() { | |
| 1191 | + | if a.deferredInitFn == nil { | |
| 1192 | + | return | |
| 1193 | + | } | |
| 1194 | + | log := logging.FromContext(ctx) | |
| 1195 | + | log.Debug().Msg("triggering deferred initialization") | |
| 1169 | 1196 | ||
| 1170 | - | // Check for config migration after window is visible. | |
| 1171 | - | a.checkConfigMigration(ctx) | |
| 1197 | + | fn := a.deferredInitFn | |
| 1198 | + | cb := glib.SourceFunc(func(_ uintptr) bool { | |
| 1199 | + | fn() | |
| 1200 | + | return false | |
| 1201 | + | }) | |
| 1202 | + | // Use LOW priority so navigation processing continues first | |
| 1203 | + | glib.IdleAddFull(glib.PRIORITY_LOW, &cb, 0, nil) | |
| 1204 | + | }) | |
| 1172 | 1205 | } | |
| 1173 | 1206 | ||
| 1174 | 1207 | // onShutdown is called when the GTK application is shutting down. | |
| @@ -1242,6 +1275,11 @@ func (a *App) initCoordinators(ctx context.Context) { | |||
| 1242 | 1275 | a.contentCoord.SetIdleInhibitor(a.deps.IdleInhibitor) | |
| 1243 | 1276 | } | |
| 1244 | 1277 | ||
| 1278 | + | // Wire deferred init trigger - runs after first navigation starts | |
| 1279 | + | a.contentCoord.SetOnFirstLoadStarted(func() { | |
| 1280 | + | a.triggerDeferredInit(ctx) | |
| 1281 | + | }) | |
| 1282 | + | ||
| 1245 | 1283 | // 2. Tab Coordinator | |
| 1246 | 1284 | a.tabCoord = coordinator.NewTabCoordinator(ctx, coordinator.TabCoordinatorConfig{ | |
| 1247 | 1285 | TabsUC: a.tabsUC, | |
| @@ -115,6 +115,10 @@ type App struct { | |||||
| 115 | insertAccentUC *usecase.InsertAccentUseCase | 115 | insertAccentUC *usecase.InsertAccentUseCase | ||
| 116 | accentFocusProvider *textinput.FocusProvider | 116 | accentFocusProvider *textinput.FocusProvider | ||
| 117 | 117 | ||||
| 118 | + | // Deferred initialization - runs after first load_started to avoid blocking initial navigation | |||
| 119 | + | deferredInitOnce sync.Once | |||
| 120 | + | deferredInitFn func() | |||
| 121 | + | ||||
| 118 | // lifecycle | 122 | // lifecycle | ||
| 119 | cancel context.CancelCauseFunc | 123 | cancel context.CancelCauseFunc | ||
| 120 | } | 124 | } | ||
| @@ -182,6 +186,7 @@ func (a *App) Run(ctx context.Context, args []string) int { | |||||
| 182 | // Initialize libadwaita once (required before using StyleManager). | 186 | // Initialize libadwaita once (required before using StyleManager). | ||
| 183 | // This also initializes GTK implicitly. | 187 | // This also initializes GTK implicitly. | ||
| 184 | adw.Init() | 188 | adw.Init() | ||
| 189 | + | logging.Trace().Mark("gtk_init") | |||
| 185 | 190 | ||||
| 186 | // Mark adwaita detector as available now that adw.Init() is complete. | 191 | // Mark adwaita detector as available now that adw.Init() is complete. | ||
| 187 | // This enables the highest-priority color scheme detector. | 192 | // This enables the highest-priority color scheme detector. | ||
| @@ -203,6 +208,7 @@ func (a *App) Run(ctx context.Context, args []string) int { | |||||
| 203 | return 1 | 208 | return 1 | ||
| 204 | } | 209 | } | ||
| 205 | defer a.gtkApp.Unref() | 210 | defer a.gtkApp.Unref() | ||
| 211 | + | logging.Trace().Mark("gtk_app_created") | |||
| 206 | 212 | ||||
| 207 | // Connect activate signal | 213 | // Connect activate signal | ||
| 208 | activateCb := func(_ gio.Application) { | 214 | activateCb := func(_ gio.Application) { | ||
| @@ -236,6 +242,7 @@ func (a *App) onActivate(ctx context.Context) { | |||||
| 236 | log.Error().Err(err).Msg("failed to create main window") | 242 | log.Error().Err(err).Msg("failed to create main window") | ||
| 237 | return | 243 | return | ||
| 238 | } | 244 | } | ||
| 245 | + | logging.Trace().Mark("window_created") | |||
| 239 | 246 | ||||
| 240 | a.initLayoutInfrastructure() | 247 | a.initLayoutInfrastructure() | ||
| 241 | a.initAppToasterOverlay() | 248 | a.initAppToasterOverlay() | ||
| @@ -244,6 +251,7 @@ func (a *App) onActivate(ctx context.Context) { | |||||
| 244 | a.initDownloadHandler(ctx) | 251 | a.initDownloadHandler(ctx) | ||
| 245 | 252 | ||||
| 246 | a.initCoordinators(ctx) | 253 | a.initCoordinators(ctx) | ||
| 254 | + | logging.Trace().Mark("coordinators_init") | |||
| 247 | a.initKeyboardHandler(ctx) | 255 | a.initKeyboardHandler(ctx) | ||
| 248 | a.initOmniboxConfig(ctx) | 256 | a.initOmniboxConfig(ctx) | ||
| 249 | a.initFindBarConfig() | 257 | a.initFindBarConfig() | ||
| @@ -252,8 +260,6 @@ func (a *App) onActivate(ctx context.Context) { | |||||
| 252 | a.initSnapshotService(ctx) | 260 | a.initSnapshotService(ctx) | ||
| 253 | a.initUpdateCoordinator(ctx) | 261 | a.initUpdateCoordinator(ctx) | ||
| 254 | a.createInitialTab(ctx) | 262 | a.createInitialTab(ctx) | ||
| 255 | - | // Prewarm the remaining WebViews after the initial tab starts loading. | |||
| 256 | - | a.prewarmWebViewPoolAsync(ctx) | |||
| 257 | a.finalizeActivation(ctx) | 263 | a.finalizeActivation(ctx) | ||
| 258 | } | 264 | } | ||
| 259 | 265 | ||||
| @@ -1016,6 +1022,11 @@ func (a *App) initSnapshotService(ctx context.Context) { | |||||
| 1016 | a.snapshotService = snapshot.NewService(a.deps.SnapshotUC, a, intervalMs) | 1022 | a.snapshotService = snapshot.NewService(a.deps.SnapshotUC, a, intervalMs) | ||
| 1017 | a.snapshotService.Start(ctx) | 1023 | a.snapshotService.Start(ctx) | ||
| 1018 | 1024 | ||||
| 1025 | + | // Set up callback for main.go to notify when session is persisted | |||
| 1026 | + | a.deps.OnSessionPersisted = func() { | |||
| 1027 | + | a.snapshotService.SetReady() | |||
| 1028 | + | } | |||
| 1029 | + | ||||
| 1019 | log.Debug().Int("interval_ms", intervalMs).Msg("snapshot service started") | 1030 | log.Debug().Int("interval_ms", intervalMs).Msg("snapshot service started") | ||
| 1020 | } | 1031 | } | ||
| 1021 | 1032 | ||||
| @@ -1149,26 +1160,48 @@ func (a *App) restoreSession(ctx context.Context, sessionID entity.SessionID) er | |||||
| 1149 | func (a *App) finalizeActivation(ctx context.Context) { | 1160 | func (a *App) finalizeActivation(ctx context.Context) { | ||
| 1150 | log := logging.FromContext(ctx) | 1161 | log := logging.FromContext(ctx) | ||
| 1151 | 1162 | ||||
| 1152 | - | // Show the window. | 1163 | + | // Show the window |
| 1153 | if a.mainWindow != nil { | 1164 | if a.mainWindow != nil { | ||
| 1154 | a.mainWindow.Show() | 1165 | a.mainWindow.Show() | ||
| 1155 | } | 1166 | } | ||
| 1156 | log.Info().Msg("main window displayed") | 1167 | log.Info().Msg("main window displayed") | ||
| 1157 | 1168 | ||||
| 1158 | - | // Start watching config for appearance changes. | 1169 | + | // Defer non-critical initialization until after first navigation starts. |
| 1159 | - | a.initConfigWatcher(ctx) | 1170 | + | // This keeps pool prewarm, config watcher, and filter loading from |
| 1171 | + | // competing with the initial page load. | |||
| 1172 | + | a.runAfterFirstLoadStarted(func() { | |||
| 1173 | + | a.prewarmWebViewPoolAsync(ctx) | |||
| 1174 | + | a.initConfigWatcher(ctx) | |||
| 1175 | + | a.initFilteringAsync(ctx) | |||
| 1176 | + | a.checkConfigMigration(ctx) | |||
| 1177 | + | }) | |||
| 1178 | + | } | |||
| 1160 | 1179 | ||||
| 1161 | - | // Ensure the current appearance config is applied once at startup. | 1180 | + | // runAfterFirstLoadStarted schedules work to run after the first navigation starts. |
| 1162 | - | // This avoids the WebUI showing default tokens until the first config change event. | 1181 | + | // This keeps the GTK main loop free to process the initial load_uri() quickly, |
| 1163 | - | if a.deps != nil { | 1182 | + | // reducing the gap between webview_attached and load_started. |
| 1164 | - | a.applyAppearanceConfig(ctx, a.deps.Config) | 1183 | + | func (a *App) runAfterFirstLoadStarted(fn func()) { |
| 1165 | - | } | 1184 | + | a.deferredInitFn = fn |
| 1185 | + | } | |||
| 1166 | 1186 | ||||
| 1167 | - | // Start async filter loading after window is visible. | 1187 | + | // triggerDeferredInit is called from ContentCoordinator on first load_started. |
| 1168 | - | a.initFilteringAsync(ctx) | 1188 | + | // It runs deferred initialization at LOW priority so navigation continues unblocked. |
| 1189 | + | func (a *App) triggerDeferredInit(ctx context.Context) { | |||
| 1190 | + | a.deferredInitOnce.Do(func() { | |||
| 1191 | + | if a.deferredInitFn == nil { | |||
| 1192 | + | return | |||
| 1193 | + | } | |||
| 1194 | + | log := logging.FromContext(ctx) | |||
| 1195 | + | log.Debug().Msg("triggering deferred initialization") | |||
| 1169 | 1196 | ||||
| 1170 | - | // Check for config migration after window is visible. | 1197 | + | fn := a.deferredInitFn |
| 1171 | - | a.checkConfigMigration(ctx) | 1198 | + | cb := glib.SourceFunc(func(_ uintptr) bool { |
| 1199 | + | fn() | |||
| 1200 | + | return false | |||
| 1201 | + | }) | |||
| 1202 | + | // Use LOW priority so navigation processing continues first | |||
| 1203 | + | glib.IdleAddFull(glib.PRIORITY_LOW, &cb, 0, nil) | |||
| 1204 | + | }) | |||
| 1172 | } | 1205 | } | ||
| 1173 | 1206 | ||||
| 1174 | // onShutdown is called when the GTK application is shutting down. | 1207 | // onShutdown is called when the GTK application is shutting down. | ||
| @@ -1242,6 +1275,11 @@ func (a *App) initCoordinators(ctx context.Context) { | |||||
| 1242 | a.contentCoord.SetIdleInhibitor(a.deps.IdleInhibitor) | 1275 | a.contentCoord.SetIdleInhibitor(a.deps.IdleInhibitor) | ||
| 1243 | } | 1276 | } | ||
| 1244 | 1277 | ||||
| 1278 | + | // Wire deferred init trigger - runs after first navigation starts | |||
| 1279 | + | a.contentCoord.SetOnFirstLoadStarted(func() { | |||
| 1280 | + | a.triggerDeferredInit(ctx) | |||
| 1281 | + | }) | |||
| 1282 | + | ||||
| 1245 | // 2. Tab Coordinator | 1283 | // 2. Tab Coordinator | ||
| 1246 | a.tabCoord = coordinator.NewTabCoordinator(ctx, coordinator.TabCoordinatorConfig{ | 1284 | a.tabCoord = coordinator.NewTabCoordinator(ctx, coordinator.TabCoordinatorConfig{ | ||
| 1247 | TabsUC: a.tabsUC, | 1285 | TabsUC: a.tabsUC, | ||
M internal/ui/coordinator/content.go +185 -79
| @@ -21,7 +21,10 @@ import ( | |||
| 21 | 21 | "github.com/jwijenbergh/puregotk/v4/gdk" | |
| 22 | 22 | ) | |
| 23 | 23 | ||
| 24 | - | const aboutBlankURI = "about:blank" | |
| 24 | + | const ( | |
| 25 | + | aboutBlankURI = "about:blank" | |
| 26 | + | logURLMaxLen = 80 | |
| 27 | + | ) | |
| 25 | 28 | ||
| 26 | 29 | // ContentCoordinator manages WebView lifecycle, title tracking, and content attachment. | |
| 27 | 30 | type ContentCoordinator struct { | |
| @@ -95,6 +98,10 @@ type ContentCoordinator struct { | |||
| 95 | 98 | ||
| 96 | 99 | // Callback when WebView gains focus (for accent picker text input targeting) | |
| 97 | 100 | onWebViewFocused func(paneID entity.PaneID, wv *webkit.WebView) | |
| 101 | + | ||
| 102 | + | // Callback for first load_started event (triggers deferred initialization) | |
| 103 | + | onFirstLoadStarted func() | |
| 104 | + | loadStartedOnce sync.Once | |
| 98 | 105 | } | |
| 99 | 106 | ||
| 100 | 107 | type pendingThemeUpdate struct { | |
| @@ -173,6 +180,13 @@ func (c *ContentCoordinator) SetOnWebViewFocused(fn func(paneID entity.PaneID, w | |||
| 173 | 180 | c.onWebViewFocused = fn | |
| 174 | 181 | } | |
| 175 | 182 | ||
| 183 | + | // SetOnFirstLoadStarted sets the callback for when the first navigation starts. | |
| 184 | + | // This is used to trigger deferred initialization after the initial load_uri() | |
| 185 | + | // has been processed by the GTK main loop. | |
| 186 | + | func (c *ContentCoordinator) SetOnFirstLoadStarted(fn func()) { | |
| 187 | + | c.onFirstLoadStarted = fn | |
| 188 | + | } | |
| 189 | + | ||
| 176 | 190 | // EnsureWebView acquires or reuses a WebView for the given pane. | |
| 177 | 191 | func (c *ContentCoordinator) EnsureWebView(ctx context.Context, paneID entity.PaneID) (*webkit.WebView, error) { | |
| 178 | 192 | log := logging.FromContext(ctx) | |
| @@ -185,10 +199,16 @@ func (c *ContentCoordinator) EnsureWebView(ctx context.Context, paneID entity.Pa | |||
| 185 | 199 | return nil, fmt.Errorf("webview pool not configured") | |
| 186 | 200 | } | |
| 187 | 201 | ||
| 202 | + | // Mark tab_created on first webview (first tab) | |
| 203 | + | if len(c.webViews) == 0 { | |
| 204 | + | logging.Trace().Mark("tab_created") | |
| 205 | + | } | |
| 206 | + | ||
| 188 | 207 | wv, err := c.pool.Acquire(ctx) | |
| 189 | 208 | if err != nil { | |
| 190 | 209 | return nil, err | |
| 191 | 210 | } | |
| 211 | + | logging.Trace().Mark("webview_acquired") | |
| 192 | 212 | ||
| 193 | 213 | c.webViews[paneID] = wv | |
| 194 | 214 | ||
| @@ -331,6 +351,7 @@ func (c *ContentCoordinator) AttachToWorkspace(ctx context.Context, ws *entity.W | |||
| 331 | 351 | if err := wsView.SetWebViewWidget(pane.ID, widget); err != nil { | |
| 332 | 352 | log.Warn().Err(err).Str("pane_id", string(pane.ID)).Msg("failed to attach webview widget") | |
| 333 | 353 | } | |
| 354 | + | logging.Trace().Mark("webview_attached") | |
| 334 | 355 | } | |
| 335 | 356 | } | |
| 336 | 357 | ||
| @@ -908,6 +929,7 @@ func (c *ContentCoordinator) PreloadCachedFavicon(ctx context.Context, paneID en | |||
| 908 | 929 | // Also shows the WebView widget (it's hidden during creation to avoid white flash). | |
| 909 | 930 | func (c *ContentCoordinator) onLoadCommitted(ctx context.Context, paneID entity.PaneID, wv *webkit.WebView) { | |
| 910 | 931 | log := logging.FromContext(ctx) | |
| 932 | + | logging.Trace().Mark("load_committed") | |
| 911 | 933 | ||
| 912 | 934 | url := wv.URI() | |
| 913 | 935 | if url == "" { | |
| @@ -1020,6 +1042,16 @@ func (c *ContentCoordinator) updatePaneURI(paneID entity.PaneID, url string) { | |||
| 1020 | 1042 | ||
| 1021 | 1043 | // onLoadStarted shows the progress bar when page loading begins. | |
| 1022 | 1044 | func (c *ContentCoordinator) onLoadStarted(paneID entity.PaneID) { | |
| 1045 | + | logging.Trace().Mark("load_started") | |
| 1046 | + | ||
| 1047 | + | // Trigger deferred initialization on first load_started. | |
| 1048 | + | // This ensures non-critical init runs after initial navigation starts. | |
| 1049 | + | c.loadStartedOnce.Do(func() { | |
| 1050 | + | if c.onFirstLoadStarted != nil { | |
| 1051 | + | c.onFirstLoadStarted() | |
| 1052 | + | } | |
| 1053 | + | }) | |
| 1054 | + | ||
| 1023 | 1055 | _, wsView := c.getActiveWS() | |
| 1024 | 1056 | if wsView == nil { | |
| 1025 | 1057 | return | |
| @@ -1106,6 +1138,11 @@ func (c *ContentCoordinator) revealIfPending(ctx context.Context, paneID entity. | |||
| 1106 | 1138 | Str("reason", reason). | |
| 1107 | 1139 | Msg("webview revealed") | |
| 1108 | 1140 | } | |
| 1141 | + | ||
| 1142 | + | // Mark first_paint and finish startup trace | |
| 1143 | + | logging.Trace().Mark("first_paint") | |
| 1144 | + | logging.Trace().Finish() | |
| 1145 | + | ||
| 1109 | 1146 | if c.onWebViewShown != nil { | |
| 1110 | 1147 | c.onWebViewShown(paneID) | |
| 1111 | 1148 | } | |
| @@ -1170,8 +1207,34 @@ func (c *ContentCoordinator) SetupPopupHandling(ctx context.Context, paneID enti | |||
| 1170 | 1207 | log.Debug().Str("pane_id", string(paneID)).Msg("popup handling configured for webview") | |
| 1171 | 1208 | } | |
| 1172 | 1209 | ||
| 1210 | + | // createPopupPane creates a new pane entity for a popup window. | |
| 1211 | + | func (c *ContentCoordinator) createPopupPane( | |
| 1212 | + | popupID port.WebViewID, | |
| 1213 | + | parentPaneID entity.PaneID, | |
| 1214 | + | targetURI string, | |
| 1215 | + | ) (entity.PaneID, *entity.Pane) { | |
| 1216 | + | var paneID entity.PaneID | |
| 1217 | + | if c.generateID != nil { | |
| 1218 | + | paneID = entity.PaneID(c.generateID()) | |
| 1219 | + | } else { | |
| 1220 | + | paneID = entity.PaneID(fmt.Sprintf("popup_%d", popupID)) | |
| 1221 | + | } | |
| 1222 | + | ||
| 1223 | + | popupPane := entity.NewPane(paneID) | |
| 1224 | + | popupPane.WindowType = entity.WindowPopup | |
| 1225 | + | popupPane.IsRelated = true | |
| 1226 | + | popupPane.ParentPaneID = &parentPaneID | |
| 1227 | + | popupPane.URI = targetURI | |
| 1228 | + | ||
| 1229 | + | return paneID, popupPane | |
| 1230 | + | } | |
| 1231 | + | ||
| 1173 | 1232 | // handlePopupCreate handles the WebKit "create" signal for popup windows. | |
| 1174 | 1233 | // Returns a new related WebView if popup is allowed, nil to block. | |
| 1234 | + | // | |
| 1235 | + | // IMPORTANT: The WebView MUST be added to a GtkWindow hierarchy BEFORE this | |
| 1236 | + | // signal handler returns. Otherwise WebKit won't establish window.opener. | |
| 1237 | + | // The WebView stays hidden until ready-to-show signal is received. | |
| 1175 | 1238 | func (c *ContentCoordinator) handlePopupCreate( | |
| 1176 | 1239 | ctx context.Context, | |
| 1177 | 1240 | parentPaneID entity.PaneID, | |
| @@ -1199,7 +1262,7 @@ func (c *ContentCoordinator) handlePopupCreate( | |||
| 1199 | 1262 | return nil | |
| 1200 | 1263 | } | |
| 1201 | 1264 | ||
| 1202 | - | // Create related WebView for session sharing | |
| 1265 | + | // Create related WebView for session sharing (created hidden) | |
| 1203 | 1266 | parentID := parentWV.ID() | |
| 1204 | 1267 | popupWV, err := c.factory.CreateRelated(ctx, parentID) | |
| 1205 | 1268 | if err != nil { | |
| @@ -1209,9 +1272,63 @@ func (c *ContentCoordinator) handlePopupCreate( | |||
| 1209 | 1272 | ||
| 1210 | 1273 | // Detect popup type | |
| 1211 | 1274 | popupType := DetectPopupType(req.FrameName) | |
| 1212 | - | ||
| 1213 | - | // Store pending popup for ready-to-show handling | |
| 1214 | 1275 | popupID := popupWV.ID() | |
| 1276 | + | ||
| 1277 | + | // Determine behavior from config | |
| 1278 | + | behavior := GetBehavior(popupType, c.popupConfig) | |
| 1279 | + | placement := "right" | |
| 1280 | + | if c.popupConfig != nil { | |
| 1281 | + | placement = c.popupConfig.Placement | |
| 1282 | + | } | |
| 1283 | + | ||
| 1284 | + | // Create popup pane entity | |
| 1285 | + | paneID, popupPane := c.createPopupPane(popupID, parentPaneID, req.TargetURI) | |
| 1286 | + | ||
| 1287 | + | // Check OAuth configuration | |
| 1288 | + | hasConfig := c.popupConfig != nil | |
| 1289 | + | oauthEnabled := hasConfig && c.popupConfig.OAuthAutoClose | |
| 1290 | + | isOAuth := IsOAuthURL(req.TargetURI) | |
| 1291 | + | log.Debug(). | |
| 1292 | + | Bool("has_config", hasConfig). | |
| 1293 | + | Bool("oauth_enabled", oauthEnabled). | |
| 1294 | + | Bool("is_oauth", isOAuth). | |
| 1295 | + | Str("uri", logging.TruncateURL(req.TargetURI, logURLMaxLen)). | |
| 1296 | + | Msg("popup OAuth check") | |
| 1297 | + | ||
| 1298 | + | // Insert into workspace IMMEDIATELY (WebView stays hidden) | |
| 1299 | + | // This is required for WebKit to establish window.opener relationship | |
| 1300 | + | if c.onInsertPopup != nil { | |
| 1301 | + | popupInput := InsertPopupInput{ | |
| 1302 | + | ParentPaneID: parentPaneID, | |
| 1303 | + | PopupPane: popupPane, | |
| 1304 | + | WebView: popupWV, | |
| 1305 | + | Behavior: behavior, | |
| 1306 | + | Placement: placement, | |
| 1307 | + | PopupType: popupType, | |
| 1308 | + | TargetURI: req.TargetURI, | |
| 1309 | + | } | |
| 1310 | + | ||
| 1311 | + | if err := c.onInsertPopup(ctx, popupInput); err != nil { | |
| 1312 | + | log.Error().Err(err).Msg("failed to insert popup into workspace") | |
| 1313 | + | popupWV.Destroy() | |
| 1314 | + | return nil | |
| 1315 | + | } | |
| 1316 | + | } | |
| 1317 | + | ||
| 1318 | + | // Register WebView in our map (after successful insertion) | |
| 1319 | + | c.webViews[paneID] = popupWV | |
| 1320 | + | ||
| 1321 | + | // Setup standard callbacks (after successful insertion to avoid leak) | |
| 1322 | + | c.setupWebViewCallbacks(ctx, paneID, popupWV) | |
| 1323 | + | ||
| 1324 | + | // Setup OAuth auto-close if configured | |
| 1325 | + | if hasConfig && oauthEnabled && isOAuth { | |
| 1326 | + | popupPane.AutoClose = true | |
| 1327 | + | c.setupOAuthAutoClose(ctx, paneID, popupWV) | |
| 1328 | + | log.Debug().Str("pane_id", string(paneID)).Msg("OAuth auto-close enabled for popup") | |
| 1329 | + | } | |
| 1330 | + | ||
| 1331 | + | // Store pending popup for ready-to-show handling (just visibility now) | |
| 1215 | 1332 | pending := &PendingPopup{ | |
| 1216 | 1333 | WebView: popupWV, | |
| 1217 | 1334 | ParentPaneID: parentPaneID, | |
| @@ -1227,7 +1344,7 @@ func (c *ContentCoordinator) handlePopupCreate( | |||
| 1227 | 1344 | c.pendingPopups[popupID] = pending | |
| 1228 | 1345 | c.popupMu.Unlock() | |
| 1229 | 1346 | ||
| 1230 | - | // Wire ready-to-show and close signals | |
| 1347 | + | // Wire ready-to-show (now just for visibility) and close signals | |
| 1231 | 1348 | popupWV.OnReadyToShow = func() { | |
| 1232 | 1349 | c.handlePopupReadyToShow(ctx, popupID) | |
| 1233 | 1350 | } | |
| @@ -1237,15 +1354,17 @@ func (c *ContentCoordinator) handlePopupCreate( | |||
| 1237 | 1354 | ||
| 1238 | 1355 | log.Info(). | |
| 1239 | 1356 | Uint64("popup_id", uint64(popupID)). | |
| 1357 | + | Str("pane_id", string(paneID)). | |
| 1240 | 1358 | Str("popup_type", popupType.String()). | |
| 1241 | - | Str("target_uri", req.TargetURI). | |
| 1242 | - | Msg("popup created, awaiting ready-to-show") | |
| 1359 | + | Str("target_uri", logging.TruncateURL(req.TargetURI, logURLMaxLen)). | |
| 1360 | + | Msg("popup inserted (hidden), awaiting ready-to-show for visibility") | |
| 1243 | 1361 | ||
| 1244 | 1362 | return popupWV | |
| 1245 | 1363 | } | |
| 1246 | 1364 | ||
| 1247 | 1365 | // handlePopupReadyToShow handles the WebKit "ready-to-show" signal. | |
| 1248 | - | // This is called when the popup is configured and ready to be displayed. | |
| 1366 | + | // The popup WebView was already inserted into the workspace (hidden) during | |
| 1367 | + | // the create signal. This handler just makes it visible. | |
| 1249 | 1368 | func (c *ContentCoordinator) handlePopupReadyToShow(ctx context.Context, popupID port.WebViewID) { | |
| 1250 | 1369 | log := logging.FromContext(ctx) | |
| 1251 | 1370 | ||
| @@ -1265,67 +1384,17 @@ func (c *ContentCoordinator) handlePopupReadyToShow(ctx context.Context, popupID | |||
| 1265 | 1384 | log.Debug(). | |
| 1266 | 1385 | Uint64("popup_id", uint64(popupID)). | |
| 1267 | 1386 | Str("popup_type", pending.PopupType.String()). | |
| 1268 | - | Msg("popup ready to show") | |
| 1269 | - | ||
| 1270 | - | // Determine behavior from config | |
| 1271 | - | behavior := GetBehavior(pending.PopupType, c.popupConfig) | |
| 1272 | - | placement := "right" | |
| 1273 | - | if c.popupConfig != nil { | |
| 1274 | - | placement = c.popupConfig.Placement | |
| 1275 | - | } | |
| 1276 | - | ||
| 1277 | - | // Create popup pane entity | |
| 1278 | - | var paneID entity.PaneID | |
| 1279 | - | if c.generateID != nil { | |
| 1280 | - | paneID = entity.PaneID(c.generateID()) | |
| 1281 | - | } else { | |
| 1282 | - | paneID = entity.PaneID(fmt.Sprintf("popup_%d", popupID)) | |
| 1283 | - | } | |
| 1387 | + | Msg("popup ready to show - making visible") | |
| 1284 | 1388 | ||
| 1285 | - | popupPane := entity.NewPane(paneID) | |
| 1286 | - | popupPane.WindowType = entity.WindowPopup | |
| 1287 | - | popupPane.IsRelated = true | |
| 1288 | - | popupPane.ParentPaneID = &pending.ParentPaneID | |
| 1289 | - | popupPane.URI = pending.TargetURI | |
| 1290 | - | ||
| 1291 | - | // Enable OAuth auto-close if configured | |
| 1292 | - | if c.popupConfig != nil && c.popupConfig.OAuthAutoClose && IsOAuthURL(pending.TargetURI) { | |
| 1293 | - | popupPane.AutoClose = true | |
| 1294 | - | c.setupOAuthAutoClose(ctx, paneID, pending.WebView) | |
| 1295 | - | } | |
| 1296 | - | ||
| 1297 | - | // Register WebView in our map | |
| 1298 | - | c.webViews[paneID] = pending.WebView | |
| 1299 | - | ||
| 1300 | - | // Setup standard callbacks | |
| 1301 | - | c.setupWebViewCallbacks(ctx, paneID, pending.WebView) | |
| 1302 | - | ||
| 1303 | - | // Request insertion into workspace | |
| 1304 | - | if c.onInsertPopup != nil { | |
| 1305 | - | popupInput := InsertPopupInput{ | |
| 1306 | - | ParentPaneID: pending.ParentPaneID, | |
| 1307 | - | PopupPane: popupPane, | |
| 1308 | - | WebView: pending.WebView, | |
| 1309 | - | Behavior: behavior, | |
| 1310 | - | Placement: placement, | |
| 1311 | - | PopupType: pending.PopupType, | |
| 1312 | - | TargetURI: pending.TargetURI, | |
| 1313 | - | } | |
| 1314 | - | ||
| 1315 | - | if err := c.onInsertPopup(ctx, popupInput); err != nil { | |
| 1316 | - | log.Error().Err(err).Msg("failed to insert popup into workspace") | |
| 1317 | - | // Clean up on failure | |
| 1318 | - | delete(c.webViews, paneID) | |
| 1319 | - | pending.WebView.Destroy() | |
| 1320 | - | return | |
| 1321 | - | } | |
| 1389 | + | // Make the WebView visible now that it's ready | |
| 1390 | + | if pending.WebView != nil { | |
| 1391 | + | pending.WebView.Show() | |
| 1322 | 1392 | } | |
| 1323 | 1393 | ||
| 1324 | 1394 | log.Info(). | |
| 1325 | - | Str("pane_id", string(paneID)). | |
| 1326 | - | Str("behavior", string(behavior)). | |
| 1327 | - | Str("placement", placement). | |
| 1328 | - | Msg("popup inserted into workspace") | |
| 1395 | + | Uint64("popup_id", uint64(popupID)). | |
| 1396 | + | Str("target_uri", logging.TruncateURL(pending.TargetURI, logURLMaxLen)). | |
| 1397 | + | Msg("popup now visible") | |
| 1329 | 1398 | } | |
| 1330 | 1399 | ||
| 1331 | 1400 | // handlePopupClose handles the WebKit "close" signal for popup windows. | |
| @@ -1426,9 +1495,44 @@ func (c *ContentCoordinator) setupWebViewCallbacks(ctx context.Context, paneID e | |||
| 1426 | 1495 | } | |
| 1427 | 1496 | ||
| 1428 | 1497 | // setupOAuthAutoClose monitors the popup for OAuth callback URLs and auto-closes. | |
| 1498 | + | // It uses URL pattern detection for standard OAuth callbacks (code=, access_token=, etc.) | |
| 1499 | + | // For providers using postMessage (like Google Sign-In), we rely on the provider calling | |
| 1500 | + | // window.close() which triggers WebKit's close signal. | |
| 1501 | + | // A long safety timeout (30s) catches popups that get stuck. | |
| 1429 | 1502 | func (c *ContentCoordinator) setupOAuthAutoClose(ctx context.Context, paneID entity.PaneID, wv *webkit.WebView) { | |
| 1430 | 1503 | log := logging.FromContext(ctx) | |
| 1431 | 1504 | ||
| 1505 | + | // Safety timeout - only triggers if popup gets stuck (provider should close via window.close) | |
| 1506 | + | var safetyTimer *time.Timer | |
| 1507 | + | var safetyTimerMu sync.Mutex | |
| 1508 | + | const oauthSafetyTimeout = 30 * time.Second | |
| 1509 | + | ||
| 1510 | + | startSafetyTimer := func() { | |
| 1511 | + | safetyTimerMu.Lock() | |
| 1512 | + | defer safetyTimerMu.Unlock() | |
| 1513 | + | if safetyTimer != nil { | |
| 1514 | + | safetyTimer.Stop() | |
| 1515 | + | } | |
| 1516 | + | safetyTimer = time.AfterFunc(oauthSafetyTimeout, func() { | |
| 1517 | + | if wv != nil && !wv.IsDestroyed() { | |
| 1518 | + | log.Warn().Str("pane", string(paneID)).Msg("oauth safety timeout, closing stuck popup") | |
| 1519 | + | wv.Close() | |
| 1520 | + | } | |
| 1521 | + | }) | |
| 1522 | + | } | |
| 1523 | + | ||
| 1524 | + | cancelSafetyTimer := func() { | |
| 1525 | + | safetyTimerMu.Lock() | |
| 1526 | + | defer safetyTimerMu.Unlock() | |
| 1527 | + | if safetyTimer != nil { | |
| 1528 | + | safetyTimer.Stop() | |
| 1529 | + | safetyTimer = nil | |
| 1530 | + | } | |
| 1531 | + | } | |
| 1532 | + | ||
| 1533 | + | // Start safety timer immediately | |
| 1534 | + | startSafetyTimer() | |
| 1535 | + | ||
| 1432 | 1536 | // Wrap the existing OnURIChanged to also check for OAuth callbacks | |
| 1433 | 1537 | originalURIChanged := wv.OnURIChanged | |
| 1434 | 1538 | wv.OnURIChanged = func(uri string) { | |
| @@ -1437,39 +1541,32 @@ func (c *ContentCoordinator) setupOAuthAutoClose(ctx context.Context, paneID ent | |||
| 1437 | 1541 | originalURIChanged(uri) | |
| 1438 | 1542 | } | |
| 1439 | 1543 | ||
| 1440 | - | // Check for OAuth callback | |
| 1544 | + | // Check for OAuth callback (URL-based detection) | |
| 1441 | 1545 | if ShouldAutoClose(uri) { | |
| 1442 | - | log.Info(). | |
| 1443 | - | Str("pane_id", string(paneID)). | |
| 1444 | - | Str("uri", uri). | |
| 1445 | - | Msg("OAuth callback detected, auto-closing popup") | |
| 1446 | - | ||
| 1447 | - | // Trigger close after a short delay to let the page process | |
| 1546 | + | cancelSafetyTimer() | |
| 1547 | + | log.Info().Str("pane", string(paneID)).Msg("oauth callback detected, closing") | |
| 1448 | 1548 | go func() { | |
| 1449 | 1549 | time.Sleep(500 * time.Millisecond) | |
| 1450 | 1550 | if wv != nil && !wv.IsDestroyed() { | |
| 1451 | - | // This will trigger handlePopupClose | |
| 1452 | 1551 | wv.Close() | |
| 1453 | 1552 | } | |
| 1454 | 1553 | }() | |
| 1455 | 1554 | } | |
| 1456 | 1555 | } | |
| 1457 | 1556 | ||
| 1458 | - | // Also check on load committed for immediate redirects | |
| 1557 | + | // Monitor load events for URL-based detection | |
| 1459 | 1558 | originalLoadChanged := wv.OnLoadChanged | |
| 1460 | 1559 | wv.OnLoadChanged = func(event webkit.LoadEvent) { | |
| 1461 | 1560 | if originalLoadChanged != nil { | |
| 1462 | 1561 | originalLoadChanged(event) | |
| 1463 | 1562 | } | |
| 1464 | 1563 | ||
| 1564 | + | // Check URL on commit for immediate detection | |
| 1465 | 1565 | if event == webkit.LoadCommitted { | |
| 1466 | 1566 | uri := wv.URI() | |
| 1467 | 1567 | if ShouldAutoClose(uri) { | |
| 1468 | - | log.Info(). | |
| 1469 | - | Str("pane_id", string(paneID)). | |
| 1470 | - | Str("uri", uri). | |
| 1471 | - | Msg("OAuth callback detected on load, auto-closing popup") | |
| 1472 | - | ||
| 1568 | + | cancelSafetyTimer() | |
| 1569 | + | log.Info().Str("pane", string(paneID)).Msg("oauth callback on load, closing") | |
| 1473 | 1570 | go func() { | |
| 1474 | 1571 | time.Sleep(500 * time.Millisecond) | |
| 1475 | 1572 | if wv != nil && !wv.IsDestroyed() { | |
| @@ -1479,6 +1576,15 @@ func (c *ContentCoordinator) setupOAuthAutoClose(ctx context.Context, paneID ent | |||
| 1479 | 1576 | } | |
| 1480 | 1577 | } | |
| 1481 | 1578 | } | |
| 1579 | + | ||
| 1580 | + | // Wrap OnClose to cancel safety timer when popup closes normally | |
| 1581 | + | originalOnClose := wv.OnClose | |
| 1582 | + | wv.OnClose = func() { | |
| 1583 | + | cancelSafetyTimer() | |
| 1584 | + | if originalOnClose != nil { | |
| 1585 | + | originalOnClose() | |
| 1586 | + | } | |
| 1587 | + | } | |
| 1482 | 1588 | } | |
| 1483 | 1589 | ||
| 1484 | 1590 | // handleLinkMiddleClick handles middle-click / Ctrl+click on links. | |
| @@ -21,7 +21,10 @@ import ( | |||||
| 21 | "github.com/jwijenbergh/puregotk/v4/gdk" | 21 | "github.com/jwijenbergh/puregotk/v4/gdk" | ||
| 22 | ) | 22 | ) | ||
| 23 | 23 | ||||
| 24 | - | const aboutBlankURI = "about:blank" | 24 | + | const ( |
| 25 | + | aboutBlankURI = "about:blank" | |||
| 26 | + | logURLMaxLen = 80 | |||
| 27 | + | ) | |||
| 25 | 28 | ||||
| 26 | // ContentCoordinator manages WebView lifecycle, title tracking, and content attachment. | 29 | // ContentCoordinator manages WebView lifecycle, title tracking, and content attachment. | ||
| 27 | type ContentCoordinator struct { | 30 | type ContentCoordinator struct { | ||
| @@ -95,6 +98,10 @@ type ContentCoordinator struct { | |||||
| 95 | 98 | ||||
| 96 | // Callback when WebView gains focus (for accent picker text input targeting) | 99 | // Callback when WebView gains focus (for accent picker text input targeting) | ||
| 97 | onWebViewFocused func(paneID entity.PaneID, wv *webkit.WebView) | 100 | onWebViewFocused func(paneID entity.PaneID, wv *webkit.WebView) | ||
| 101 | + | ||||
| 102 | + | // Callback for first load_started event (triggers deferred initialization) | |||
| 103 | + | onFirstLoadStarted func() | |||
| 104 | + | loadStartedOnce sync.Once | |||
| 98 | } | 105 | } | ||
| 99 | 106 | ||||
| 100 | type pendingThemeUpdate struct { | 107 | type pendingThemeUpdate struct { | ||
| @@ -173,6 +180,13 @@ func (c *ContentCoordinator) SetOnWebViewFocused(fn func(paneID entity.PaneID, w | |||||
| 173 | c.onWebViewFocused = fn | 180 | c.onWebViewFocused = fn | ||
| 174 | } | 181 | } | ||
| 175 | 182 | ||||
| 183 | + | // SetOnFirstLoadStarted sets the callback for when the first navigation starts. | |||
| 184 | + | // This is used to trigger deferred initialization after the initial load_uri() | |||
| 185 | + | // has been processed by the GTK main loop. | |||
| 186 | + | func (c *ContentCoordinator) SetOnFirstLoadStarted(fn func()) { | |||
| 187 | + | c.onFirstLoadStarted = fn | |||
| 188 | + | } | |||
| 189 | + | ||||
| 176 | // EnsureWebView acquires or reuses a WebView for the given pane. | 190 | // EnsureWebView acquires or reuses a WebView for the given pane. | ||
| 177 | func (c *ContentCoordinator) EnsureWebView(ctx context.Context, paneID entity.PaneID) (*webkit.WebView, error) { | 191 | func (c *ContentCoordinator) EnsureWebView(ctx context.Context, paneID entity.PaneID) (*webkit.WebView, error) { | ||
| 178 | log := logging.FromContext(ctx) | 192 | log := logging.FromContext(ctx) | ||
| @@ -185,10 +199,16 @@ func (c *ContentCoordinator) EnsureWebView(ctx context.Context, paneID entity.Pa | |||||
| 185 | return nil, fmt.Errorf("webview pool not configured") | 199 | return nil, fmt.Errorf("webview pool not configured") | ||
| 186 | } | 200 | } | ||
| 187 | 201 | ||||
| 202 | + | // Mark tab_created on first webview (first tab) | |||
| 203 | + | if len(c.webViews) == 0 { | |||
| 204 | + | logging.Trace().Mark("tab_created") | |||
| 205 | + | } | |||
| 206 | + | ||||
| 188 | wv, err := c.pool.Acquire(ctx) | 207 | wv, err := c.pool.Acquire(ctx) | ||
| 189 | if err != nil { | 208 | if err != nil { | ||
| 190 | return nil, err | 209 | return nil, err | ||
| 191 | } | 210 | } | ||
| 211 | + | logging.Trace().Mark("webview_acquired") | |||
| 192 | 212 | ||||
| 193 | c.webViews[paneID] = wv | 213 | c.webViews[paneID] = wv | ||
| 194 | 214 | ||||
| @@ -331,6 +351,7 @@ func (c *ContentCoordinator) AttachToWorkspace(ctx context.Context, ws *entity.W | |||||
| 331 | if err := wsView.SetWebViewWidget(pane.ID, widget); err != nil { | 351 | if err := wsView.SetWebViewWidget(pane.ID, widget); err != nil { | ||
| 332 | log.Warn().Err(err).Str("pane_id", string(pane.ID)).Msg("failed to attach webview widget") | 352 | log.Warn().Err(err).Str("pane_id", string(pane.ID)).Msg("failed to attach webview widget") | ||
| 333 | } | 353 | } | ||
| 354 | + | logging.Trace().Mark("webview_attached") | |||
| 334 | } | 355 | } | ||
| 335 | } | 356 | } | ||
| 336 | 357 | ||||
| @@ -908,6 +929,7 @@ func (c *ContentCoordinator) PreloadCachedFavicon(ctx context.Context, paneID en | |||||
| 908 | // Also shows the WebView widget (it's hidden during creation to avoid white flash). | 929 | // Also shows the WebView widget (it's hidden during creation to avoid white flash). | ||
| 909 | func (c *ContentCoordinator) onLoadCommitted(ctx context.Context, paneID entity.PaneID, wv *webkit.WebView) { | 930 | func (c *ContentCoordinator) onLoadCommitted(ctx context.Context, paneID entity.PaneID, wv *webkit.WebView) { | ||
| 910 | log := logging.FromContext(ctx) | 931 | log := logging.FromContext(ctx) | ||
| 932 | + | logging.Trace().Mark("load_committed") | |||
| 911 | 933 | ||||
| 912 | url := wv.URI() | 934 | url := wv.URI() | ||
| 913 | if url == "" { | 935 | if url == "" { | ||
| @@ -1020,6 +1042,16 @@ func (c *ContentCoordinator) updatePaneURI(paneID entity.PaneID, url string) { | |||||
| 1020 | 1042 | ||||
| 1021 | // onLoadStarted shows the progress bar when page loading begins. | 1043 | // onLoadStarted shows the progress bar when page loading begins. | ||
| 1022 | func (c *ContentCoordinator) onLoadStarted(paneID entity.PaneID) { | 1044 | func (c *ContentCoordinator) onLoadStarted(paneID entity.PaneID) { | ||
| 1045 | + | logging.Trace().Mark("load_started") | |||
| 1046 | + | ||||
| 1047 | + | // Trigger deferred initialization on first load_started. | |||
| 1048 | + | // This ensures non-critical init runs after initial navigation starts. | |||
| 1049 | + | c.loadStartedOnce.Do(func() { | |||
| 1050 | + | if c.onFirstLoadStarted != nil { | |||
| 1051 | + | c.onFirstLoadStarted() | |||
| 1052 | + | } | |||
| 1053 | + | }) | |||
| 1054 | + | ||||
| 1023 | _, wsView := c.getActiveWS() | 1055 | _, wsView := c.getActiveWS() | ||
| 1024 | if wsView == nil { | 1056 | if wsView == nil { | ||
| 1025 | return | 1057 | return | ||
| @@ -1106,6 +1138,11 @@ func (c *ContentCoordinator) revealIfPending(ctx context.Context, paneID entity. | |||||
| 1106 | Str("reason", reason). | 1138 | Str("reason", reason). | ||
| 1107 | Msg("webview revealed") | 1139 | Msg("webview revealed") | ||
| 1108 | } | 1140 | } | ||
| 1141 | + | ||||
| 1142 | + | // Mark first_paint and finish startup trace | |||
| 1143 | + | logging.Trace().Mark("first_paint") | |||
| 1144 | + | logging.Trace().Finish() | |||
| 1145 | + | ||||
| 1109 | if c.onWebViewShown != nil { | 1146 | if c.onWebViewShown != nil { | ||
| 1110 | c.onWebViewShown(paneID) | 1147 | c.onWebViewShown(paneID) | ||
| 1111 | } | 1148 | } | ||
| @@ -1170,8 +1207,34 @@ func (c *ContentCoordinator) SetupPopupHandling(ctx context.Context, paneID enti | |||||
| 1170 | log.Debug().Str("pane_id", string(paneID)).Msg("popup handling configured for webview") | 1207 | log.Debug().Str("pane_id", string(paneID)).Msg("popup handling configured for webview") | ||
| 1171 | } | 1208 | } | ||
| 1172 | 1209 | ||||
| 1210 | + | // createPopupPane creates a new pane entity for a popup window. | |||
| 1211 | + | func (c *ContentCoordinator) createPopupPane( | |||
| 1212 | + | popupID port.WebViewID, | |||
| 1213 | + | parentPaneID entity.PaneID, | |||
| 1214 | + | targetURI string, | |||
| 1215 | + | ) (entity.PaneID, *entity.Pane) { | |||
| 1216 | + | var paneID entity.PaneID | |||
| 1217 | + | if c.generateID != nil { | |||
| 1218 | + | paneID = entity.PaneID(c.generateID()) | |||
| 1219 | + | } else { | |||
| 1220 | + | paneID = entity.PaneID(fmt.Sprintf("popup_%d", popupID)) | |||
| 1221 | + | } | |||
| 1222 | + | ||||
| 1223 | + | popupPane := entity.NewPane(paneID) | |||
| 1224 | + | popupPane.WindowType = entity.WindowPopup | |||
| 1225 | + | popupPane.IsRelated = true | |||
| 1226 | + | popupPane.ParentPaneID = &parentPaneID | |||
| 1227 | + | popupPane.URI = targetURI | |||
| 1228 | + | ||||
| 1229 | + | return paneID, popupPane | |||
| 1230 | + | } | |||
| 1231 | + | ||||
| 1173 | // handlePopupCreate handles the WebKit "create" signal for popup windows. | 1232 | // handlePopupCreate handles the WebKit "create" signal for popup windows. | ||
| 1174 | // Returns a new related WebView if popup is allowed, nil to block. | 1233 | // Returns a new related WebView if popup is allowed, nil to block. | ||
| 1234 | + | // | |||
| 1235 | + | // IMPORTANT: The WebView MUST be added to a GtkWindow hierarchy BEFORE this | |||
| 1236 | + | // signal handler returns. Otherwise WebKit won't establish window.opener. | |||
| 1237 | + | // The WebView stays hidden until ready-to-show signal is received. | |||
| 1175 | func (c *ContentCoordinator) handlePopupCreate( | 1238 | func (c *ContentCoordinator) handlePopupCreate( | ||
| 1176 | ctx context.Context, | 1239 | ctx context.Context, | ||
| 1177 | parentPaneID entity.PaneID, | 1240 | parentPaneID entity.PaneID, | ||
| @@ -1199,7 +1262,7 @@ func (c *ContentCoordinator) handlePopupCreate( | |||||
| 1199 | return nil | 1262 | return nil | ||
| 1200 | } | 1263 | } | ||
| 1201 | 1264 | ||||
| 1202 | - | // Create related WebView for session sharing | 1265 | + | // Create related WebView for session sharing (created hidden) |
| 1203 | parentID := parentWV.ID() | 1266 | parentID := parentWV.ID() | ||
| 1204 | popupWV, err := c.factory.CreateRelated(ctx, parentID) | 1267 | popupWV, err := c.factory.CreateRelated(ctx, parentID) | ||
| 1205 | if err != nil { | 1268 | if err != nil { | ||
| @@ -1209,9 +1272,63 @@ func (c *ContentCoordinator) handlePopupCreate( | |||||
| 1209 | 1272 | ||||
| 1210 | // Detect popup type | 1273 | // Detect popup type | ||
| 1211 | popupType := DetectPopupType(req.FrameName) | 1274 | popupType := DetectPopupType(req.FrameName) | ||
| 1212 | - | ||||
| 1213 | - | // Store pending popup for ready-to-show handling | |||
| 1214 | popupID := popupWV.ID() | 1275 | popupID := popupWV.ID() | ||
| 1276 | + | ||||
| 1277 | + | // Determine behavior from config | |||
| 1278 | + | behavior := GetBehavior(popupType, c.popupConfig) | |||
| 1279 | + | placement := "right" | |||
| 1280 | + | if c.popupConfig != nil { | |||
| 1281 | + | placement = c.popupConfig.Placement | |||
| 1282 | + | } | |||
| 1283 | + | ||||
| 1284 | + | // Create popup pane entity | |||
| 1285 | + | paneID, popupPane := c.createPopupPane(popupID, parentPaneID, req.TargetURI) | |||
| 1286 | + | ||||
| 1287 | + | // Check OAuth configuration | |||
| 1288 | + | hasConfig := c.popupConfig != nil | |||
| 1289 | + | oauthEnabled := hasConfig && c.popupConfig.OAuthAutoClose | |||
| 1290 | + | isOAuth := IsOAuthURL(req.TargetURI) | |||
| 1291 | + | log.Debug(). | |||
| 1292 | + | Bool("has_config", hasConfig). | |||
| 1293 | + | Bool("oauth_enabled", oauthEnabled). | |||
| 1294 | + | Bool("is_oauth", isOAuth). | |||
| 1295 | + | Str("uri", logging.TruncateURL(req.TargetURI, logURLMaxLen)). | |||
| 1296 | + | Msg("popup OAuth check") | |||
| 1297 | + | ||||
| 1298 | + | // Insert into workspace IMMEDIATELY (WebView stays hidden) | |||
| 1299 | + | // This is required for WebKit to establish window.opener relationship | |||
| 1300 | + | if c.onInsertPopup != nil { | |||
| 1301 | + | popupInput := InsertPopupInput{ | |||
| 1302 | + | ParentPaneID: parentPaneID, | |||
| 1303 | + | PopupPane: popupPane, | |||
| 1304 | + | WebView: popupWV, | |||
| 1305 | + | Behavior: behavior, | |||
| 1306 | + | Placement: placement, | |||
| 1307 | + | PopupType: popupType, | |||
| 1308 | + | TargetURI: req.TargetURI, | |||
| 1309 | + | } | |||
| 1310 | + | ||||
| 1311 | + | if err := c.onInsertPopup(ctx, popupInput); err != nil { | |||
| 1312 | + | log.Error().Err(err).Msg("failed to insert popup into workspace") | |||
| 1313 | + | popupWV.Destroy() | |||
| 1314 | + | return nil | |||
| 1315 | + | } | |||
| 1316 | + | } | |||
| 1317 | + | ||||
| 1318 | + | // Register WebView in our map (after successful insertion) | |||
| 1319 | + | c.webViews[paneID] = popupWV | |||
| 1320 | + | ||||
| 1321 | + | // Setup standard callbacks (after successful insertion to avoid leak) | |||
| 1322 | + | c.setupWebViewCallbacks(ctx, paneID, popupWV) | |||
| 1323 | + | ||||
| 1324 | + | // Setup OAuth auto-close if configured | |||
| 1325 | + | if hasConfig && oauthEnabled && isOAuth { | |||
| 1326 | + | popupPane.AutoClose = true | |||
| 1327 | + | c.setupOAuthAutoClose(ctx, paneID, popupWV) | |||
| 1328 | + | log.Debug().Str("pane_id", string(paneID)).Msg("OAuth auto-close enabled for popup") | |||
| 1329 | + | } | |||
| 1330 | + | ||||
| 1331 | + | // Store pending popup for ready-to-show handling (just visibility now) | |||
| 1215 | pending := &PendingPopup{ | 1332 | pending := &PendingPopup{ | ||
| 1216 | WebView: popupWV, | 1333 | WebView: popupWV, | ||
| 1217 | ParentPaneID: parentPaneID, | 1334 | ParentPaneID: parentPaneID, | ||
| @@ -1227,7 +1344,7 @@ func (c *ContentCoordinator) handlePopupCreate( | |||||
| 1227 | c.pendingPopups[popupID] = pending | 1344 | c.pendingPopups[popupID] = pending | ||
| 1228 | c.popupMu.Unlock() | 1345 | c.popupMu.Unlock() | ||
| 1229 | 1346 | ||||
| 1230 | - | // Wire ready-to-show and close signals | 1347 | + | // Wire ready-to-show (now just for visibility) and close signals |
| 1231 | popupWV.OnReadyToShow = func() { | 1348 | popupWV.OnReadyToShow = func() { | ||
| 1232 | c.handlePopupReadyToShow(ctx, popupID) | 1349 | c.handlePopupReadyToShow(ctx, popupID) | ||
| 1233 | } | 1350 | } | ||
| @@ -1237,15 +1354,17 @@ func (c *ContentCoordinator) handlePopupCreate( | |||||
| 1237 | 1354 | ||||
| 1238 | log.Info(). | 1355 | log.Info(). | ||
| 1239 | Uint64("popup_id", uint64(popupID)). | 1356 | Uint64("popup_id", uint64(popupID)). | ||
| 1357 | + | Str("pane_id", string(paneID)). | |||
| 1240 | Str("popup_type", popupType.String()). | 1358 | Str("popup_type", popupType.String()). | ||
| 1241 | - | Str("target_uri", req.TargetURI). | 1359 | + | Str("target_uri", logging.TruncateURL(req.TargetURI, logURLMaxLen)). |
| 1242 | - | Msg("popup created, awaiting ready-to-show") | 1360 | + | Msg("popup inserted (hidden), awaiting ready-to-show for visibility") |
| 1243 | 1361 | ||||
| 1244 | return popupWV | 1362 | return popupWV | ||
| 1245 | } | 1363 | } | ||
| 1246 | 1364 | ||||
| 1247 | // handlePopupReadyToShow handles the WebKit "ready-to-show" signal. | 1365 | // handlePopupReadyToShow handles the WebKit "ready-to-show" signal. | ||
| 1248 | - | // This is called when the popup is configured and ready to be displayed. | 1366 | + | // The popup WebView was already inserted into the workspace (hidden) during |
| 1367 | + | // the create signal. This handler just makes it visible. | |||
| 1249 | func (c *ContentCoordinator) handlePopupReadyToShow(ctx context.Context, popupID port.WebViewID) { | 1368 | func (c *ContentCoordinator) handlePopupReadyToShow(ctx context.Context, popupID port.WebViewID) { | ||
| 1250 | log := logging.FromContext(ctx) | 1369 | log := logging.FromContext(ctx) | ||
| 1251 | 1370 | ||||
| @@ -1265,67 +1384,17 @@ func (c *ContentCoordinator) handlePopupReadyToShow(ctx context.Context, popupID | |||||
| 1265 | log.Debug(). | 1384 | log.Debug(). | ||
| 1266 | Uint64("popup_id", uint64(popupID)). | 1385 | Uint64("popup_id", uint64(popupID)). | ||
| 1267 | Str("popup_type", pending.PopupType.String()). | 1386 | Str("popup_type", pending.PopupType.String()). | ||
| 1268 | - | Msg("popup ready to show") | 1387 | + | Msg("popup ready to show - making visible") |
| 1269 | - | ||||
| 1270 | - | // Determine behavior from config | |||
| 1271 | - | behavior := GetBehavior(pending.PopupType, c.popupConfig) | |||
| 1272 | - | placement := "right" | |||
| 1273 | - | if c.popupConfig != nil { | |||
| 1274 | - | placement = c.popupConfig.Placement | |||
| 1275 | - | } | |||
| 1276 | - | ||||
| 1277 | - | // Create popup pane entity | |||
| 1278 | - | var paneID entity.PaneID | |||
| 1279 | - | if c.generateID != nil { | |||
| 1280 | - | paneID = entity.PaneID(c.generateID()) | |||
| 1281 | - | } else { | |||
| 1282 | - | paneID = entity.PaneID(fmt.Sprintf("popup_%d", popupID)) | |||
| 1283 | - | } | |||
| 1284 | 1388 | ||||
| 1285 | - | popupPane := entity.NewPane(paneID) | 1389 | + | // Make the WebView visible now that it's ready |
| 1286 | - | popupPane.WindowType = entity.WindowPopup | 1390 | + | if pending.WebView != nil { |
| 1287 | - | popupPane.IsRelated = true | 1391 | + | pending.WebView.Show() |
| 1288 | - | popupPane.ParentPaneID = &pending.ParentPaneID | |||
| 1289 | - | popupPane.URI = pending.TargetURI | |||
| 1290 | - | ||||
| 1291 | - | // Enable OAuth auto-close if configured | |||
| 1292 | - | if c.popupConfig != nil && c.popupConfig.OAuthAutoClose && IsOAuthURL(pending.TargetURI) { | |||
| 1293 | - | popupPane.AutoClose = true | |||
| 1294 | - | c.setupOAuthAutoClose(ctx, paneID, pending.WebView) | |||
| 1295 | - | } | |||
| 1296 | - | ||||
| 1297 | - | // Register WebView in our map | |||
| 1298 | - | c.webViews[paneID] = pending.WebView | |||
| 1299 | - | ||||
| 1300 | - | // Setup standard callbacks | |||
| 1301 | - | c.setupWebViewCallbacks(ctx, paneID, pending.WebView) | |||
| 1302 | - | ||||
| 1303 | - | // Request insertion into workspace | |||
| 1304 | - | if c.onInsertPopup != nil { | |||
| 1305 | - | popupInput := InsertPopupInput{ | |||
| 1306 | - | ParentPaneID: pending.ParentPaneID, | |||
| 1307 | - | PopupPane: popupPane, | |||
| 1308 | - | WebView: pending.WebView, | |||
| 1309 | - | Behavior: behavior, | |||
| 1310 | - | Placement: placement, | |||
| 1311 | - | PopupType: pending.PopupType, | |||
| 1312 | - | TargetURI: pending.TargetURI, | |||
| 1313 | - | } | |||
| 1314 | - | ||||
| 1315 | - | if err := c.onInsertPopup(ctx, popupInput); err != nil { | |||
| 1316 | - | log.Error().Err(err).Msg("failed to insert popup into workspace") | |||
| 1317 | - | // Clean up on failure | |||
| 1318 | - | delete(c.webViews, paneID) | |||
| 1319 | - | pending.WebView.Destroy() | |||
| 1320 | - | return | |||
| 1321 | - | } | |||
| 1322 | } | 1392 | } | ||
| 1323 | 1393 | ||||
| 1324 | log.Info(). | 1394 | log.Info(). | ||
| 1325 | - | Str("pane_id", string(paneID)). | 1395 | + | Uint64("popup_id", uint64(popupID)). |
| 1326 | - | Str("behavior", string(behavior)). | 1396 | + | Str("target_uri", logging.TruncateURL(pending.TargetURI, logURLMaxLen)). |
| 1327 | - | Str("placement", placement). | 1397 | + | Msg("popup now visible") |
| 1328 | - | Msg("popup inserted into workspace") | |||
| 1329 | } | 1398 | } | ||
| 1330 | 1399 | ||||
| 1331 | // handlePopupClose handles the WebKit "close" signal for popup windows. | 1400 | // handlePopupClose handles the WebKit "close" signal for popup windows. | ||
| @@ -1426,9 +1495,44 @@ func (c *ContentCoordinator) setupWebViewCallbacks(ctx context.Context, paneID e | |||||
| 1426 | } | 1495 | } | ||
| 1427 | 1496 | ||||
| 1428 | // setupOAuthAutoClose monitors the popup for OAuth callback URLs and auto-closes. | 1497 | // setupOAuthAutoClose monitors the popup for OAuth callback URLs and auto-closes. | ||
| 1498 | + | // It uses URL pattern detection for standard OAuth callbacks (code=, access_token=, etc.) | |||
| 1499 | + | // For providers using postMessage (like Google Sign-In), we rely on the provider calling | |||
| 1500 | + | // window.close() which triggers WebKit's close signal. | |||
| 1501 | + | // A long safety timeout (30s) catches popups that get stuck. | |||
| 1429 | func (c *ContentCoordinator) setupOAuthAutoClose(ctx context.Context, paneID entity.PaneID, wv *webkit.WebView) { | 1502 | func (c *ContentCoordinator) setupOAuthAutoClose(ctx context.Context, paneID entity.PaneID, wv *webkit.WebView) { | ||
| 1430 | log := logging.FromContext(ctx) | 1503 | log := logging.FromContext(ctx) | ||
| 1431 | 1504 | ||||
| 1505 | + | // Safety timeout - only triggers if popup gets stuck (provider should close via window.close) | |||
| 1506 | + | var safetyTimer *time.Timer | |||
| 1507 | + | var safetyTimerMu sync.Mutex | |||
| 1508 | + | const oauthSafetyTimeout = 30 * time.Second | |||
| 1509 | + | ||||
| 1510 | + | startSafetyTimer := func() { | |||
| 1511 | + | safetyTimerMu.Lock() | |||
| 1512 | + | defer safetyTimerMu.Unlock() | |||
| 1513 | + | if safetyTimer != nil { | |||
| 1514 | + | safetyTimer.Stop() | |||
| 1515 | + | } | |||
| 1516 | + | safetyTimer = time.AfterFunc(oauthSafetyTimeout, func() { | |||
| 1517 | + | if wv != nil && !wv.IsDestroyed() { | |||
| 1518 | + | log.Warn().Str("pane", string(paneID)).Msg("oauth safety timeout, closing stuck popup") | |||
| 1519 | + | wv.Close() | |||
| 1520 | + | } | |||
| 1521 | + | }) | |||
| 1522 | + | } | |||
| 1523 | + | ||||
| 1524 | + | cancelSafetyTimer := func() { | |||
| 1525 | + | safetyTimerMu.Lock() | |||
| 1526 | + | defer safetyTimerMu.Unlock() | |||
| 1527 | + | if safetyTimer != nil { | |||
| 1528 | + | safetyTimer.Stop() | |||
| 1529 | + | safetyTimer = nil | |||
| 1530 | + | } | |||
| 1531 | + | } | |||
| 1532 | + | ||||
| 1533 | + | // Start safety timer immediately | |||
| 1534 | + | startSafetyTimer() | |||
| 1535 | + | ||||
| 1432 | // Wrap the existing OnURIChanged to also check for OAuth callbacks | 1536 | // Wrap the existing OnURIChanged to also check for OAuth callbacks | ||
| 1433 | originalURIChanged := wv.OnURIChanged | 1537 | originalURIChanged := wv.OnURIChanged | ||
| 1434 | wv.OnURIChanged = func(uri string) { | 1538 | wv.OnURIChanged = func(uri string) { | ||
| @@ -1437,39 +1541,32 @@ func (c *ContentCoordinator) setupOAuthAutoClose(ctx context.Context, paneID ent | |||||
| 1437 | originalURIChanged(uri) | 1541 | originalURIChanged(uri) | ||
| 1438 | } | 1542 | } | ||
| 1439 | 1543 | ||||
| 1440 | - | // Check for OAuth callback | 1544 | + | // Check for OAuth callback (URL-based detection) |
| 1441 | if ShouldAutoClose(uri) { | 1545 | if ShouldAutoClose(uri) { | ||
| 1442 | - | log.Info(). | 1546 | + | cancelSafetyTimer() |
| 1443 | - | Str("pane_id", string(paneID)). | 1547 | + | log.Info().Str("pane", string(paneID)).Msg("oauth callback detected, closing") |
| 1444 | - | Str("uri", uri). | |||
| 1445 | - | Msg("OAuth callback detected, auto-closing popup") | |||
| 1446 | - | ||||
| 1447 | - | // Trigger close after a short delay to let the page process | |||
| 1448 | go func() { | 1548 | go func() { | ||
| 1449 | time.Sleep(500 * time.Millisecond) | 1549 | time.Sleep(500 * time.Millisecond) | ||
| 1450 | if wv != nil && !wv.IsDestroyed() { | 1550 | if wv != nil && !wv.IsDestroyed() { | ||
| 1451 | - | // This will trigger handlePopupClose | |||
| 1452 | wv.Close() | 1551 | wv.Close() | ||
| 1453 | } | 1552 | } | ||
| 1454 | }() | 1553 | }() | ||
| 1455 | } | 1554 | } | ||
| 1456 | } | 1555 | } | ||
| 1457 | 1556 | ||||
| 1458 | - | // Also check on load committed for immediate redirects | 1557 | + | // Monitor load events for URL-based detection |
| 1459 | originalLoadChanged := wv.OnLoadChanged | 1558 | originalLoadChanged := wv.OnLoadChanged | ||
| 1460 | wv.OnLoadChanged = func(event webkit.LoadEvent) { | 1559 | wv.OnLoadChanged = func(event webkit.LoadEvent) { | ||
| 1461 | if originalLoadChanged != nil { | 1560 | if originalLoadChanged != nil { | ||
| 1462 | originalLoadChanged(event) | 1561 | originalLoadChanged(event) | ||
| 1463 | } | 1562 | } | ||
| 1464 | 1563 | ||||
| 1564 | + | // Check URL on commit for immediate detection | |||
| 1465 | if event == webkit.LoadCommitted { | 1565 | if event == webkit.LoadCommitted { | ||
| 1466 | uri := wv.URI() | 1566 | uri := wv.URI() | ||
| 1467 | if ShouldAutoClose(uri) { | 1567 | if ShouldAutoClose(uri) { | ||
| 1468 | - | log.Info(). | 1568 | + | cancelSafetyTimer() |
| 1469 | - | Str("pane_id", string(paneID)). | 1569 | + | log.Info().Str("pane", string(paneID)).Msg("oauth callback on load, closing") |
| 1470 | - | Str("uri", uri). | |||
| 1471 | - | Msg("OAuth callback detected on load, auto-closing popup") | |||
| 1472 | - | ||||
| 1473 | go func() { | 1570 | go func() { | ||
| 1474 | time.Sleep(500 * time.Millisecond) | 1571 | time.Sleep(500 * time.Millisecond) | ||
| 1475 | if wv != nil && !wv.IsDestroyed() { | 1572 | if wv != nil && !wv.IsDestroyed() { | ||
| @@ -1479,6 +1576,15 @@ func (c *ContentCoordinator) setupOAuthAutoClose(ctx context.Context, paneID ent | |||||
| 1479 | } | 1576 | } | ||
| 1480 | } | 1577 | } | ||
| 1481 | } | 1578 | } | ||
| 1579 | + | ||||
| 1580 | + | // Wrap OnClose to cancel safety timer when popup closes normally | |||
| 1581 | + | originalOnClose := wv.OnClose | |||
| 1582 | + | wv.OnClose = func() { | |||
| 1583 | + | cancelSafetyTimer() | |||
| 1584 | + | if originalOnClose != nil { | |||
| 1585 | + | originalOnClose() | |||
| 1586 | + | } | |||
| 1587 | + | } | |||
| 1482 | } | 1588 | } | ||
| 1483 | 1589 | ||||
| 1484 | // handleLinkMiddleClick handles middle-click / Ctrl+click on links. | 1590 | // handleLinkMiddleClick handles middle-click / Ctrl+click on links. | ||
M internal/ui/coordinator/oauth.go +0 -1
| @@ -101,7 +101,6 @@ func IsOAuthCallback(url string) bool { | |||
| 101 | 101 | // - Errors: error=, error_description= | |
| 102 | 102 | // - Various OAuth providers (Google, GitHub, Auth0, etc.) | |
| 103 | 103 | func ShouldAutoClose(url string) bool { | |
| 104 | - | // Only auto-close on callback URLs that have OAuth response params | |
| 105 | 104 | return IsOAuthCallback(url) | |
| 106 | 105 | } | |
| 107 | 106 | ||
| @@ -101,7 +101,6 @@ func IsOAuthCallback(url string) bool { | |||||
| 101 | // - Errors: error=, error_description= | 101 | // - Errors: error=, error_description= | ||
| 102 | // - Various OAuth providers (Google, GitHub, Auth0, etc.) | 102 | // - Various OAuth providers (Google, GitHub, Auth0, etc.) | ||
| 103 | func ShouldAutoClose(url string) bool { | 103 | func ShouldAutoClose(url string) bool { | ||
| 104 | - | // Only auto-close on callback URLs that have OAuth response params | |||
| 105 | return IsOAuthCallback(url) | 104 | return IsOAuthCallback(url) | ||
| 106 | } | 105 | } | ||
| 107 | 106 | ||||
M internal/ui/coordinator/workspace.go +57 -6
| @@ -1135,11 +1135,24 @@ func (c *WorkspaceCoordinator) syncStackedPaneTitles(ctx context.Context, stacke | |||
| 1135 | 1135 | return | |
| 1136 | 1136 | } | |
| 1137 | 1137 | ||
| 1138 | + | // Get UI pane count to avoid index out of bounds when domain and UI are out of sync | |
| 1139 | + | uiPaneCount := stackedView.Count() | |
| 1140 | + | ||
| 1138 | 1141 | for i, child := range stackNode.Children { | |
| 1139 | 1142 | if child.Pane == nil { | |
| 1140 | 1143 | continue | |
| 1141 | 1144 | } | |
| 1142 | 1145 | ||
| 1146 | + | // Skip if index exceeds UI pane count (domain/UI desync) | |
| 1147 | + | if i >= uiPaneCount { | |
| 1148 | + | log.Debug(). | |
| 1149 | + | Int("index", i). | |
| 1150 | + | Int("ui_count", uiPaneCount). | |
| 1151 | + | Str("pane_id", string(child.Pane.ID)). | |
| 1152 | + | Msg("skipping title sync: index exceeds UI pane count") | |
| 1153 | + | continue | |
| 1154 | + | } | |
| 1155 | + | ||
| 1143 | 1156 | title := c.contentCoord.GetTitle(child.Pane.ID) | |
| 1144 | 1157 | if title == "" { | |
| 1145 | 1158 | title = child.Pane.Title | |
| @@ -1798,11 +1811,13 @@ func (c *WorkspaceCoordinator) insertPopupStacked(ctx context.Context, input Ins | |||
| 1798 | 1811 | return fmt.Errorf("parent pane not found: %s", input.ParentPaneID) | |
| 1799 | 1812 | } | |
| 1800 | 1813 | ||
| 1801 | - | // Resolve or create stack node | |
| 1802 | - | stackNode := c.resolveOrCreateStackNode(ctx, parentNode, input.ParentPaneID) | |
| 1814 | + | // Resolve or create stack node (track conversion for potential rollback) | |
| 1815 | + | stackNode, conversionInfo := c.resolveOrCreateStackNode(ctx, parentNode, input.ParentPaneID) | |
| 1803 | 1816 | ||
| 1804 | 1817 | // Add popup pane to stack using use case | |
| 1805 | 1818 | if _, err := c.panesUC.AddToStack(ctx, ws, stackNode, input.PopupPane); err != nil { | |
| 1819 | + | // Rollback stack conversion if we created a new stack | |
| 1820 | + | conversionInfo.revert() | |
| 1806 | 1821 | return fmt.Errorf("failed to add popup to stack: %w", err) | |
| 1807 | 1822 | } | |
| 1808 | 1823 | ||
| @@ -1812,6 +1827,17 @@ func (c *WorkspaceCoordinator) insertPopupStacked(ctx context.Context, input Ins | |||
| 1812 | 1827 | } | |
| 1813 | 1828 | ||
| 1814 | 1829 | if err := c.attachPopupPaneView(ctx, input, wsView, stackNode, log); err != nil { | |
| 1830 | + | // UI update failed - rollback domain changes to maintain consistency | |
| 1831 | + | log.Warn().Err(err).Msg("rolling back domain changes due to UI failure") | |
| 1832 | + | ||
| 1833 | + | // Remove popup pane from stack | |
| 1834 | + | if removeErr := c.panesUC.RemoveFromStack(ctx, stackNode, input.PopupPane.ID); removeErr != nil { | |
| 1835 | + | log.Error().Err(removeErr).Msg("failed to rollback popup pane addition") | |
| 1836 | + | } | |
| 1837 | + | ||
| 1838 | + | // Revert stack conversion if we created a new stack | |
| 1839 | + | conversionInfo.revert() | |
| 1840 | + | ||
| 1815 | 1841 | return err | |
| 1816 | 1842 | } | |
| 1817 | 1843 | ||
| @@ -1823,14 +1849,35 @@ func (c *WorkspaceCoordinator) insertPopupStacked(ctx context.Context, input Ins | |||
| 1823 | 1849 | return nil | |
| 1824 | 1850 | } | |
| 1825 | 1851 | ||
| 1852 | + | // stackConversionInfo holds state needed to revert a leaf-to-stack conversion. | |
| 1853 | + | type stackConversionInfo struct { | |
| 1854 | + | wasConverted bool // true if resolveOrCreateStackNode converted a leaf to a stack | |
| 1855 | + | originalPane *entity.Pane // the pane that was in the node before conversion | |
| 1856 | + | node *entity.PaneNode // the node that was converted | |
| 1857 | + | } | |
| 1858 | + | ||
| 1859 | + | // revert undoes a leaf-to-stack conversion. | |
| 1860 | + | func (info *stackConversionInfo) revert() { | |
| 1861 | + | if !info.wasConverted || info.node == nil { | |
| 1862 | + | return | |
| 1863 | + | } | |
| 1864 | + | ||
| 1865 | + | // Restore node to leaf state | |
| 1866 | + | info.node.Pane = info.originalPane | |
| 1867 | + | info.node.IsStacked = false | |
| 1868 | + | info.node.ActiveStackIndex = 0 | |
| 1869 | + | info.node.Children = nil | |
| 1870 | + | } | |
| 1871 | + | ||
| 1826 | 1872 | // resolveOrCreateStackNode finds an existing stack or creates one for popup insertion. | |
| 1827 | 1873 | // Note: For popups, we can't use CreateStack use case since it creates a new pane, | |
| 1828 | 1874 | // but we already have the popup pane. This conversion is a special case. | |
| 1875 | + | // Returns the stack node and conversion info for potential rollback. | |
| 1829 | 1876 | func (c *WorkspaceCoordinator) resolveOrCreateStackNode( | |
| 1830 | 1877 | ctx context.Context, | |
| 1831 | 1878 | parentNode *entity.PaneNode, | |
| 1832 | 1879 | parentPaneID entity.PaneID, | |
| 1833 | - | ) *entity.PaneNode { | |
| 1880 | + | ) (*entity.PaneNode, stackConversionInfo) { | |
| 1834 | 1881 | log := logging.FromContext(ctx) | |
| 1835 | 1882 | ||
| 1836 | 1883 | // Check if parent is already in a stack | |
| @@ -1838,7 +1885,7 @@ func (c *WorkspaceCoordinator) resolveOrCreateStackNode( | |||
| 1838 | 1885 | log.Debug(). | |
| 1839 | 1886 | Str("stack_id", parentNode.Parent.ID). | |
| 1840 | 1887 | Msg("using existing parent stack for popup") | |
| 1841 | - | return parentNode.Parent | |
| 1888 | + | return parentNode.Parent, stackConversionInfo{} | |
| 1842 | 1889 | } | |
| 1843 | 1890 | ||
| 1844 | 1891 | // Check if parent is already a stack container | |
| @@ -1846,7 +1893,7 @@ func (c *WorkspaceCoordinator) resolveOrCreateStackNode( | |||
| 1846 | 1893 | log.Debug(). | |
| 1847 | 1894 | Str("stack_id", parentNode.ID). | |
| 1848 | 1895 | Msg("parent is already a stack container") | |
| 1849 | - | return parentNode | |
| 1896 | + | return parentNode, stackConversionInfo{} | |
| 1850 | 1897 | } | |
| 1851 | 1898 | ||
| 1852 | 1899 | // Need to convert leaf to stack for popup insertion. | |
| @@ -1880,7 +1927,11 @@ func (c *WorkspaceCoordinator) resolveOrCreateStackNode( | |||
| 1880 | 1927 | Str("original_pane", string(originalPane.ID)). | |
| 1881 | 1928 | Msg("converted leaf to stacked node for popup") | |
| 1882 | 1929 | ||
| 1883 | - | return parentNode | |
| 1930 | + | return parentNode, stackConversionInfo{ | |
| 1931 | + | wasConverted: true, | |
| 1932 | + | originalPane: originalPane, | |
| 1933 | + | node: parentNode, | |
| 1934 | + | } | |
| 1884 | 1935 | } | |
| 1885 | 1936 | ||
| 1886 | 1937 | func (c *WorkspaceCoordinator) attachPopupPaneView( | |
| @@ -1135,11 +1135,24 @@ func (c *WorkspaceCoordinator) syncStackedPaneTitles(ctx context.Context, stacke | |||||
| 1135 | return | 1135 | return | ||
| 1136 | } | 1136 | } | ||
| 1137 | 1137 | ||||
| 1138 | + | // Get UI pane count to avoid index out of bounds when domain and UI are out of sync | |||
| 1139 | + | uiPaneCount := stackedView.Count() | |||
| 1140 | + | ||||
| 1138 | for i, child := range stackNode.Children { | 1141 | for i, child := range stackNode.Children { | ||
| 1139 | if child.Pane == nil { | 1142 | if child.Pane == nil { | ||
| 1140 | continue | 1143 | continue | ||
| 1141 | } | 1144 | } | ||
| 1142 | 1145 | ||||
| 1146 | + | // Skip if index exceeds UI pane count (domain/UI desync) | |||
| 1147 | + | if i >= uiPaneCount { | |||
| 1148 | + | log.Debug(). | |||
| 1149 | + | Int("index", i). | |||
| 1150 | + | Int("ui_count", uiPaneCount). | |||
| 1151 | + | Str("pane_id", string(child.Pane.ID)). | |||
| 1152 | + | Msg("skipping title sync: index exceeds UI pane count") | |||
| 1153 | + | continue | |||
| 1154 | + | } | |||
| 1155 | + | ||||
| 1143 | title := c.contentCoord.GetTitle(child.Pane.ID) | 1156 | title := c.contentCoord.GetTitle(child.Pane.ID) | ||
| 1144 | if title == "" { | 1157 | if title == "" { | ||
| 1145 | title = child.Pane.Title | 1158 | title = child.Pane.Title | ||
| @@ -1798,11 +1811,13 @@ func (c *WorkspaceCoordinator) insertPopupStacked(ctx context.Context, input Ins | |||||
| 1798 | return fmt.Errorf("parent pane not found: %s", input.ParentPaneID) | 1811 | return fmt.Errorf("parent pane not found: %s", input.ParentPaneID) | ||
| 1799 | } | 1812 | } | ||
| 1800 | 1813 | ||||
| 1801 | - | // Resolve or create stack node | 1814 | + | // Resolve or create stack node (track conversion for potential rollback) |
| 1802 | - | stackNode := c.resolveOrCreateStackNode(ctx, parentNode, input.ParentPaneID) | 1815 | + | stackNode, conversionInfo := c.resolveOrCreateStackNode(ctx, parentNode, input.ParentPaneID) |
| 1803 | 1816 | ||||
| 1804 | // Add popup pane to stack using use case | 1817 | // Add popup pane to stack using use case | ||
| 1805 | if _, err := c.panesUC.AddToStack(ctx, ws, stackNode, input.PopupPane); err != nil { | 1818 | if _, err := c.panesUC.AddToStack(ctx, ws, stackNode, input.PopupPane); err != nil { | ||
| 1819 | + | // Rollback stack conversion if we created a new stack | |||
| 1820 | + | conversionInfo.revert() | |||
| 1806 | return fmt.Errorf("failed to add popup to stack: %w", err) | 1821 | return fmt.Errorf("failed to add popup to stack: %w", err) | ||
| 1807 | } | 1822 | } | ||
| 1808 | 1823 | ||||
| @@ -1812,6 +1827,17 @@ func (c *WorkspaceCoordinator) insertPopupStacked(ctx context.Context, input Ins | |||||
| 1812 | } | 1827 | } | ||
| 1813 | 1828 | ||||
| 1814 | if err := c.attachPopupPaneView(ctx, input, wsView, stackNode, log); err != nil { | 1829 | if err := c.attachPopupPaneView(ctx, input, wsView, stackNode, log); err != nil { | ||
| 1830 | + | // UI update failed - rollback domain changes to maintain consistency | |||
| 1831 | + | log.Warn().Err(err).Msg("rolling back domain changes due to UI failure") | |||
| 1832 | + | ||||
| 1833 | + | // Remove popup pane from stack | |||
| 1834 | + | if removeErr := c.panesUC.RemoveFromStack(ctx, stackNode, input.PopupPane.ID); removeErr != nil { | |||
| 1835 | + | log.Error().Err(removeErr).Msg("failed to rollback popup pane addition") | |||
| 1836 | + | } | |||
| 1837 | + | ||||
| 1838 | + | // Revert stack conversion if we created a new stack | |||
| 1839 | + | conversionInfo.revert() | |||
| 1840 | + | ||||
| 1815 | return err | 1841 | return err | ||
| 1816 | } | 1842 | } | ||
| 1817 | 1843 | ||||
| @@ -1823,14 +1849,35 @@ func (c *WorkspaceCoordinator) insertPopupStacked(ctx context.Context, input Ins | |||||
| 1823 | return nil | 1849 | return nil | ||
| 1824 | } | 1850 | } | ||
| 1825 | 1851 | ||||
| 1852 | + | // stackConversionInfo holds state needed to revert a leaf-to-stack conversion. | |||
| 1853 | + | type stackConversionInfo struct { | |||
| 1854 | + | wasConverted bool // true if resolveOrCreateStackNode converted a leaf to a stack | |||
| 1855 | + | originalPane *entity.Pane // the pane that was in the node before conversion | |||
| 1856 | + | node *entity.PaneNode // the node that was converted | |||
| 1857 | + | } | |||
| 1858 | + | ||||
| 1859 | + | // revert undoes a leaf-to-stack conversion. | |||
| 1860 | + | func (info *stackConversionInfo) revert() { | |||
| 1861 | + | if !info.wasConverted || info.node == nil { | |||
| 1862 | + | return | |||
| 1863 | + | } | |||
| 1864 | + | ||||
| 1865 | + | // Restore node to leaf state | |||
| 1866 | + | info.node.Pane = info.originalPane | |||
| 1867 | + | info.node.IsStacked = false | |||
| 1868 | + | info.node.ActiveStackIndex = 0 | |||
| 1869 | + | info.node.Children = nil | |||
| 1870 | + | } | |||
| 1871 | + | ||||
| 1826 | // resolveOrCreateStackNode finds an existing stack or creates one for popup insertion. | 1872 | // resolveOrCreateStackNode finds an existing stack or creates one for popup insertion. | ||
| 1827 | // Note: For popups, we can't use CreateStack use case since it creates a new pane, | 1873 | // Note: For popups, we can't use CreateStack use case since it creates a new pane, | ||
| 1828 | // but we already have the popup pane. This conversion is a special case. | 1874 | // but we already have the popup pane. This conversion is a special case. | ||
| 1875 | + | // Returns the stack node and conversion info for potential rollback. | |||
| 1829 | func (c *WorkspaceCoordinator) resolveOrCreateStackNode( | 1876 | func (c *WorkspaceCoordinator) resolveOrCreateStackNode( | ||
| 1830 | ctx context.Context, | 1877 | ctx context.Context, | ||
| 1831 | parentNode *entity.PaneNode, | 1878 | parentNode *entity.PaneNode, | ||
| 1832 | parentPaneID entity.PaneID, | 1879 | parentPaneID entity.PaneID, | ||
| 1833 | - | ) *entity.PaneNode { | 1880 | + | ) (*entity.PaneNode, stackConversionInfo) { |
| 1834 | log := logging.FromContext(ctx) | 1881 | log := logging.FromContext(ctx) | ||
| 1835 | 1882 | ||||
| 1836 | // Check if parent is already in a stack | 1883 | // Check if parent is already in a stack | ||
| @@ -1838,7 +1885,7 @@ func (c *WorkspaceCoordinator) resolveOrCreateStackNode( | |||||
| 1838 | log.Debug(). | 1885 | log.Debug(). | ||
| 1839 | Str("stack_id", parentNode.Parent.ID). | 1886 | Str("stack_id", parentNode.Parent.ID). | ||
| 1840 | Msg("using existing parent stack for popup") | 1887 | Msg("using existing parent stack for popup") | ||
| 1841 | - | return parentNode.Parent | 1888 | + | return parentNode.Parent, stackConversionInfo{} |
| 1842 | } | 1889 | } | ||
| 1843 | 1890 | ||||
| 1844 | // Check if parent is already a stack container | 1891 | // Check if parent is already a stack container | ||
| @@ -1846,7 +1893,7 @@ func (c *WorkspaceCoordinator) resolveOrCreateStackNode( | |||||
| 1846 | log.Debug(). | 1893 | log.Debug(). | ||
| 1847 | Str("stack_id", parentNode.ID). | 1894 | Str("stack_id", parentNode.ID). | ||
| 1848 | Msg("parent is already a stack container") | 1895 | Msg("parent is already a stack container") | ||
| 1849 | - | return parentNode | 1896 | + | return parentNode, stackConversionInfo{} |
| 1850 | } | 1897 | } | ||
| 1851 | 1898 | ||||
| 1852 | // Need to convert leaf to stack for popup insertion. | 1899 | // Need to convert leaf to stack for popup insertion. | ||
| @@ -1880,7 +1927,11 @@ func (c *WorkspaceCoordinator) resolveOrCreateStackNode( | |||||
| 1880 | Str("original_pane", string(originalPane.ID)). | 1927 | Str("original_pane", string(originalPane.ID)). | ||
| 1881 | Msg("converted leaf to stacked node for popup") | 1928 | Msg("converted leaf to stacked node for popup") | ||
| 1882 | 1929 | ||||
| 1883 | - | return parentNode | 1930 | + | return parentNode, stackConversionInfo{ |
| 1931 | + | wasConverted: true, | |||
| 1932 | + | originalPane: originalPane, | |||
| 1933 | + | node: parentNode, | |||
| 1934 | + | } | |||
| 1884 | } | 1935 | } | ||
| 1885 | 1936 | ||||
| 1886 | func (c *WorkspaceCoordinator) attachPopupPaneView( | 1937 | func (c *WorkspaceCoordinator) attachPopupPaneView( | ||
M internal/ui/deps.go +1 -0
| @@ -25,6 +25,7 @@ type Dependencies struct { | |||
| 25 | 25 | InitialURL string // URL to open on startup (optional) | |
| 26 | 26 | RestoreSessionID string // Session ID to restore on startup (optional) | |
| 27 | 27 | OnFirstWebViewShown func(context.Context) | |
| 28 | + | OnSessionPersisted func() // Called by main after session is persisted to DB | |
| 28 | 29 | ||
| 29 | 30 | // Theme and color scheme management | |
| 30 | 31 | Theme *theme.Manager | |
| @@ -25,6 +25,7 @@ type Dependencies struct { | |||||
| 25 | InitialURL string // URL to open on startup (optional) | 25 | InitialURL string // URL to open on startup (optional) | ||
| 26 | RestoreSessionID string // Session ID to restore on startup (optional) | 26 | RestoreSessionID string // Session ID to restore on startup (optional) | ||
| 27 | OnFirstWebViewShown func(context.Context) | 27 | OnFirstWebViewShown func(context.Context) | ||
| 28 | + | OnSessionPersisted func() // Called by main after session is persisted to DB | |||
| 28 | 29 | ||||
| 29 | // Theme and color scheme management | 30 | // Theme and color scheme management | ||
| 30 | Theme *theme.Manager | 31 | Theme *theme.Manager | ||
M internal/ui/input/gesture.go +14 -5
| @@ -107,11 +107,20 @@ func (h *GestureHandler) handlePressed(nPress int) { | |||
| 107 | 107 | if handler != nil { | |
| 108 | 108 | if err := handler(h.ctx, action); err != nil { | |
| 109 | 109 | log := logging.FromContext(h.ctx) | |
| 110 | - | log.Error(). | |
| 111 | - | Err(err). | |
| 112 | - | Str("action", string(action)). | |
| 113 | - | Uint("button", button). | |
| 114 | - | Msg("gesture action handler error") | |
| 110 | + | // Navigation errors are expected (e.g., no back/forward history) | |
| 111 | + | if action == ActionGoBack || action == ActionGoForward { | |
| 112 | + | log.Debug(). | |
| 113 | + | Err(err). | |
| 114 | + | Str("action", string(action)). | |
| 115 | + | Uint("button", button). | |
| 116 | + | Msg("gesture navigation not available") | |
| 117 | + | } else { | |
| 118 | + | log.Error(). | |
| 119 | + | Err(err). | |
| 120 | + | Str("action", string(action)). | |
| 121 | + | Uint("button", button). | |
| 122 | + | Msg("gesture action handler error") | |
| 123 | + | } | |
| 115 | 124 | } | |
| 116 | 125 | } | |
| 117 | 126 | } | |
| @@ -107,11 +107,20 @@ func (h *GestureHandler) handlePressed(nPress int) { | |||||
| 107 | if handler != nil { | 107 | if handler != nil { | ||
| 108 | if err := handler(h.ctx, action); err != nil { | 108 | if err := handler(h.ctx, action); err != nil { | ||
| 109 | log := logging.FromContext(h.ctx) | 109 | log := logging.FromContext(h.ctx) | ||
| 110 | - | log.Error(). | 110 | + | // Navigation errors are expected (e.g., no back/forward history) |
| 111 | - | Err(err). | 111 | + | if action == ActionGoBack || action == ActionGoForward { |
| 112 | - | Str("action", string(action)). | 112 | + | log.Debug(). |
| 113 | - | Uint("button", button). | 113 | + | Err(err). |
| 114 | - | Msg("gesture action handler error") | 114 | + | Str("action", string(action)). |
| 115 | + | Uint("button", button). | |||
| 116 | + | Msg("gesture navigation not available") | |||
| 117 | + | } else { | |||
| 118 | + | log.Error(). | |||
| 119 | + | Err(err). | |||
| 120 | + | Str("action", string(action)). | |||
| 121 | + | Uint("button", button). | |||
| 122 | + | Msg("gesture action handler error") | |||
| 123 | + | } | |||
| 115 | } | 124 | } | ||
| 116 | } | 125 | } | ||
| 117 | } | 126 | } | ||
M webui/package-lock.json +445 -441
| @@ -442,9 +442,9 @@ | |||
| 442 | 442 | } | |
| 443 | 443 | }, | |
| 444 | 444 | "node_modules/@eslint-community/eslint-utils": { | |
| 445 | - | "version": "4.9.0", | |
| 446 | - | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", | |
| 447 | - | "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", | |
| 445 | + | "version": "4.9.1", | |
| 446 | + | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", | |
| 447 | + | "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", | |
| 448 | 448 | "dev": true, | |
| 449 | 449 | "license": "MIT", | |
| 450 | 450 | "dependencies": { | |
| @@ -719,17 +719,17 @@ | |||
| 719 | 719 | } | |
| 720 | 720 | }, | |
| 721 | 721 | "node_modules/@parcel/watcher": { | |
| 722 | - | "version": "2.5.1", | |
| 723 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", | |
| 724 | - | "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", | |
| 722 | + | "version": "2.5.4", | |
| 723 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.4.tgz", | |
| 724 | + | "integrity": "sha512-WYa2tUVV5HiArWPB3ydlOc4R2ivq0IDrlqhMi3l7mVsFEXNcTfxYFPIHXHXIh/ca/y/V5N4E1zecyxdIBjYnkQ==", | |
| 725 | 725 | "dev": true, | |
| 726 | 726 | "hasInstallScript": true, | |
| 727 | 727 | "license": "MIT", | |
| 728 | 728 | "dependencies": { | |
| 729 | - | "detect-libc": "^1.0.3", | |
| 729 | + | "detect-libc": "^2.0.3", | |
| 730 | 730 | "is-glob": "^4.0.3", | |
| 731 | - | "micromatch": "^4.0.5", | |
| 732 | - | "node-addon-api": "^7.0.0" | |
| 731 | + | "node-addon-api": "^7.0.0", | |
| 732 | + | "picomatch": "^4.0.3" | |
| 733 | 733 | }, | |
| 734 | 734 | "engines": { | |
| 735 | 735 | "node": ">= 10.0.0" | |
| @@ -739,25 +739,25 @@ | |||
| 739 | 739 | "url": "https://opencollective.com/parcel" | |
| 740 | 740 | }, | |
| 741 | 741 | "optionalDependencies": { | |
| 742 | - | "@parcel/watcher-android-arm64": "2.5.1", | |
| 743 | - | "@parcel/watcher-darwin-arm64": "2.5.1", | |
| 744 | - | "@parcel/watcher-darwin-x64": "2.5.1", | |
| 745 | - | "@parcel/watcher-freebsd-x64": "2.5.1", | |
| 746 | - | "@parcel/watcher-linux-arm-glibc": "2.5.1", | |
| 747 | - | "@parcel/watcher-linux-arm-musl": "2.5.1", | |
| 748 | - | "@parcel/watcher-linux-arm64-glibc": "2.5.1", | |
| 749 | - | "@parcel/watcher-linux-arm64-musl": "2.5.1", | |
| 750 | - | "@parcel/watcher-linux-x64-glibc": "2.5.1", | |
| 751 | - | "@parcel/watcher-linux-x64-musl": "2.5.1", | |
| 752 | - | "@parcel/watcher-win32-arm64": "2.5.1", | |
| 753 | - | "@parcel/watcher-win32-ia32": "2.5.1", | |
| 754 | - | "@parcel/watcher-win32-x64": "2.5.1" | |
| 742 | + | "@parcel/watcher-android-arm64": "2.5.4", | |
| 743 | + | "@parcel/watcher-darwin-arm64": "2.5.4", | |
| 744 | + | "@parcel/watcher-darwin-x64": "2.5.4", | |
| 745 | + | "@parcel/watcher-freebsd-x64": "2.5.4", | |
| 746 | + | "@parcel/watcher-linux-arm-glibc": "2.5.4", | |
| 747 | + | "@parcel/watcher-linux-arm-musl": "2.5.4", | |
| 748 | + | "@parcel/watcher-linux-arm64-glibc": "2.5.4", | |
| 749 | + | "@parcel/watcher-linux-arm64-musl": "2.5.4", | |
| 750 | + | "@parcel/watcher-linux-x64-glibc": "2.5.4", | |
| 751 | + | "@parcel/watcher-linux-x64-musl": "2.5.4", | |
| 752 | + | "@parcel/watcher-win32-arm64": "2.5.4", | |
| 753 | + | "@parcel/watcher-win32-ia32": "2.5.4", | |
| 754 | + | "@parcel/watcher-win32-x64": "2.5.4" | |
| 755 | 755 | } | |
| 756 | 756 | }, | |
| 757 | 757 | "node_modules/@parcel/watcher-android-arm64": { | |
| 758 | - | "version": "2.5.1", | |
| 759 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", | |
| 760 | - | "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", | |
| 758 | + | "version": "2.5.4", | |
| 759 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.4.tgz", | |
| 760 | + | "integrity": "sha512-hoh0vx4v+b3BNI7Cjoy2/B0ARqcwVNrzN/n7DLq9ZB4I3lrsvhrkCViJyfTj/Qi5xM9YFiH4AmHGK6pgH1ss7g==", | |
| 761 | 761 | "cpu": [ | |
| 762 | 762 | "arm64" | |
| 763 | 763 | ], | |
| @@ -776,9 +776,9 @@ | |||
| 776 | 776 | } | |
| 777 | 777 | }, | |
| 778 | 778 | "node_modules/@parcel/watcher-darwin-arm64": { | |
| 779 | - | "version": "2.5.1", | |
| 780 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", | |
| 781 | - | "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", | |
| 779 | + | "version": "2.5.4", | |
| 780 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.4.tgz", | |
| 781 | + | "integrity": "sha512-kphKy377pZiWpAOyTgQYPE5/XEKVMaj6VUjKT5VkNyUJlr2qZAn8gIc7CPzx+kbhvqHDT9d7EqdOqRXT6vk0zw==", | |
| 782 | 782 | "cpu": [ | |
| 783 | 783 | "arm64" | |
| 784 | 784 | ], | |
| @@ -797,9 +797,9 @@ | |||
| 797 | 797 | } | |
| 798 | 798 | }, | |
| 799 | 799 | "node_modules/@parcel/watcher-darwin-x64": { | |
| 800 | - | "version": "2.5.1", | |
| 801 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", | |
| 802 | - | "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", | |
| 800 | + | "version": "2.5.4", | |
| 801 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.4.tgz", | |
| 802 | + | "integrity": "sha512-UKaQFhCtNJW1A9YyVz3Ju7ydf6QgrpNQfRZ35wNKUhTQ3dxJ/3MULXN5JN/0Z80V/KUBDGa3RZaKq1EQT2a2gg==", | |
| 803 | 803 | "cpu": [ | |
| 804 | 804 | "x64" | |
| 805 | 805 | ], | |
| @@ -818,9 +818,9 @@ | |||
| 818 | 818 | } | |
| 819 | 819 | }, | |
| 820 | 820 | "node_modules/@parcel/watcher-freebsd-x64": { | |
| 821 | - | "version": "2.5.1", | |
| 822 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", | |
| 823 | - | "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", | |
| 821 | + | "version": "2.5.4", | |
| 822 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.4.tgz", | |
| 823 | + | "integrity": "sha512-Dib0Wv3Ow/m2/ttvLdeI2DBXloO7t3Z0oCp4bAb2aqyqOjKPPGrg10pMJJAQ7tt8P4V2rwYwywkDhUia/FgS+Q==", | |
| 824 | 824 | "cpu": [ | |
| 825 | 825 | "x64" | |
| 826 | 826 | ], | |
| @@ -839,9 +839,9 @@ | |||
| 839 | 839 | } | |
| 840 | 840 | }, | |
| 841 | 841 | "node_modules/@parcel/watcher-linux-arm-glibc": { | |
| 842 | - | "version": "2.5.1", | |
| 843 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", | |
| 844 | - | "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", | |
| 842 | + | "version": "2.5.4", | |
| 843 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.4.tgz", | |
| 844 | + | "integrity": "sha512-I5Vb769pdf7Q7Sf4KNy8Pogl/URRCKu9ImMmnVKYayhynuyGYMzuI4UOWnegQNa2sGpsPSbzDsqbHNMyeyPCgw==", | |
| 845 | 845 | "cpu": [ | |
| 846 | 846 | "arm" | |
| 847 | 847 | ], | |
| @@ -860,9 +860,9 @@ | |||
| 860 | 860 | } | |
| 861 | 861 | }, | |
| 862 | 862 | "node_modules/@parcel/watcher-linux-arm-musl": { | |
| 863 | - | "version": "2.5.1", | |
| 864 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", | |
| 865 | - | "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", | |
| 863 | + | "version": "2.5.4", | |
| 864 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.4.tgz", | |
| 865 | + | "integrity": "sha512-kGO8RPvVrcAotV4QcWh8kZuHr9bXi9a3bSZw7kFarYR0+fGliU7hd/zevhjw8fnvIKG3J9EO5G6sXNGCSNMYPQ==", | |
| 866 | 866 | "cpu": [ | |
| 867 | 867 | "arm" | |
| 868 | 868 | ], | |
| @@ -881,9 +881,9 @@ | |||
| 881 | 881 | } | |
| 882 | 882 | }, | |
| 883 | 883 | "node_modules/@parcel/watcher-linux-arm64-glibc": { | |
| 884 | - | "version": "2.5.1", | |
| 885 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", | |
| 886 | - | "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", | |
| 884 | + | "version": "2.5.4", | |
| 885 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.4.tgz", | |
| 886 | + | "integrity": "sha512-KU75aooXhqGFY2W5/p8DYYHt4hrjHZod8AhcGAmhzPn/etTa+lYCDB2b1sJy3sWJ8ahFVTdy+EbqSBvMx3iFlw==", | |
| 887 | 887 | "cpu": [ | |
| 888 | 888 | "arm64" | |
| 889 | 889 | ], | |
| @@ -902,9 +902,9 @@ | |||
| 902 | 902 | } | |
| 903 | 903 | }, | |
| 904 | 904 | "node_modules/@parcel/watcher-linux-arm64-musl": { | |
| 905 | - | "version": "2.5.1", | |
| 906 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", | |
| 907 | - | "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", | |
| 905 | + | "version": "2.5.4", | |
| 906 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.4.tgz", | |
| 907 | + | "integrity": "sha512-Qx8uNiIekVutnzbVdrgSanM+cbpDD3boB1f8vMtnuG5Zau4/bdDbXyKwIn0ToqFhIuob73bcxV9NwRm04/hzHQ==", | |
| 908 | 908 | "cpu": [ | |
| 909 | 909 | "arm64" | |
| 910 | 910 | ], | |
| @@ -923,9 +923,9 @@ | |||
| 923 | 923 | } | |
| 924 | 924 | }, | |
| 925 | 925 | "node_modules/@parcel/watcher-linux-x64-glibc": { | |
| 926 | - | "version": "2.5.1", | |
| 927 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", | |
| 928 | - | "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", | |
| 926 | + | "version": "2.5.4", | |
| 927 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.4.tgz", | |
| 928 | + | "integrity": "sha512-UYBQvhYmgAv61LNUn24qGQdjtycFBKSK3EXr72DbJqX9aaLbtCOO8+1SkKhD/GNiJ97ExgcHBrukcYhVjrnogA==", | |
| 929 | 929 | "cpu": [ | |
| 930 | 930 | "x64" | |
| 931 | 931 | ], | |
| @@ -944,9 +944,9 @@ | |||
| 944 | 944 | } | |
| 945 | 945 | }, | |
| 946 | 946 | "node_modules/@parcel/watcher-linux-x64-musl": { | |
| 947 | - | "version": "2.5.1", | |
| 948 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", | |
| 949 | - | "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", | |
| 947 | + | "version": "2.5.4", | |
| 948 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.4.tgz", | |
| 949 | + | "integrity": "sha512-YoRWCVgxv8akZrMhdyVi6/TyoeeMkQ0PGGOf2E4omODrvd1wxniXP+DBynKoHryStks7l+fDAMUBRzqNHrVOpg==", | |
| 950 | 950 | "cpu": [ | |
| 951 | 951 | "x64" | |
| 952 | 952 | ], | |
| @@ -965,9 +965,9 @@ | |||
| 965 | 965 | } | |
| 966 | 966 | }, | |
| 967 | 967 | "node_modules/@parcel/watcher-win32-arm64": { | |
| 968 | - | "version": "2.5.1", | |
| 969 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", | |
| 970 | - | "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", | |
| 968 | + | "version": "2.5.4", | |
| 969 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.4.tgz", | |
| 970 | + | "integrity": "sha512-iby+D/YNXWkiQNYcIhg8P5hSjzXEHaQrk2SLrWOUD7VeC4Ohu0WQvmV+HDJokZVJ2UjJ4AGXW3bx7Lls9Ln4TQ==", | |
| 971 | 971 | "cpu": [ | |
| 972 | 972 | "arm64" | |
| 973 | 973 | ], | |
| @@ -986,9 +986,9 @@ | |||
| 986 | 986 | } | |
| 987 | 987 | }, | |
| 988 | 988 | "node_modules/@parcel/watcher-win32-ia32": { | |
| 989 | - | "version": "2.5.1", | |
| 990 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", | |
| 991 | - | "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", | |
| 989 | + | "version": "2.5.4", | |
| 990 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.4.tgz", | |
| 991 | + | "integrity": "sha512-vQN+KIReG0a2ZDpVv8cgddlf67J8hk1WfZMMP7sMeZmJRSmEax5xNDNWKdgqSe2brOKTQQAs3aCCUal2qBHAyg==", | |
| 992 | 992 | "cpu": [ | |
| 993 | 993 | "ia32" | |
| 994 | 994 | ], | |
| @@ -1007,9 +1007,9 @@ | |||
| 1007 | 1007 | } | |
| 1008 | 1008 | }, | |
| 1009 | 1009 | "node_modules/@parcel/watcher-win32-x64": { | |
| 1010 | - | "version": "2.5.1", | |
| 1011 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", | |
| 1012 | - | "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", | |
| 1010 | + | "version": "2.5.4", | |
| 1011 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.4.tgz", | |
| 1012 | + | "integrity": "sha512-3A6efb6BOKwyw7yk9ro2vus2YTt2nvcd56AuzxdMiVOxL9umDyN5PKkKfZ/gZ9row41SjVmTVQNWQhaRRGpOKw==", | |
| 1013 | 1013 | "cpu": [ | |
| 1014 | 1014 | "x64" | |
| 1015 | 1015 | ], | |
| @@ -1028,9 +1028,9 @@ | |||
| 1028 | 1028 | } | |
| 1029 | 1029 | }, | |
| 1030 | 1030 | "node_modules/@rollup/rollup-android-arm-eabi": { | |
| 1031 | - | "version": "4.53.3", | |
| 1032 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", | |
| 1033 | - | "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", | |
| 1031 | + | "version": "4.56.0", | |
| 1032 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.56.0.tgz", | |
| 1033 | + | "integrity": "sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==", | |
| 1034 | 1034 | "cpu": [ | |
| 1035 | 1035 | "arm" | |
| 1036 | 1036 | ], | |
| @@ -1042,9 +1042,9 @@ | |||
| 1042 | 1042 | ] | |
| 1043 | 1043 | }, | |
| 1044 | 1044 | "node_modules/@rollup/rollup-android-arm64": { | |
| 1045 | - | "version": "4.53.3", | |
| 1046 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", | |
| 1047 | - | "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", | |
| 1045 | + | "version": "4.56.0", | |
| 1046 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.56.0.tgz", | |
| 1047 | + | "integrity": "sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==", | |
| 1048 | 1048 | "cpu": [ | |
| 1049 | 1049 | "arm64" | |
| 1050 | 1050 | ], | |
| @@ -1056,9 +1056,9 @@ | |||
| 1056 | 1056 | ] | |
| 1057 | 1057 | }, | |
| 1058 | 1058 | "node_modules/@rollup/rollup-darwin-arm64": { | |
| 1059 | - | "version": "4.53.3", | |
| 1060 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", | |
| 1061 | - | "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", | |
| 1059 | + | "version": "4.56.0", | |
| 1060 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.56.0.tgz", | |
| 1061 | + | "integrity": "sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==", | |
| 1062 | 1062 | "cpu": [ | |
| 1063 | 1063 | "arm64" | |
| 1064 | 1064 | ], | |
| @@ -1070,9 +1070,9 @@ | |||
| 1070 | 1070 | ] | |
| 1071 | 1071 | }, | |
| 1072 | 1072 | "node_modules/@rollup/rollup-darwin-x64": { | |
| 1073 | - | "version": "4.53.3", | |
| 1074 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", | |
| 1075 | - | "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", | |
| 1073 | + | "version": "4.56.0", | |
| 1074 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.56.0.tgz", | |
| 1075 | + | "integrity": "sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==", | |
| 1076 | 1076 | "cpu": [ | |
| 1077 | 1077 | "x64" | |
| 1078 | 1078 | ], | |
| @@ -1084,9 +1084,9 @@ | |||
| 1084 | 1084 | ] | |
| 1085 | 1085 | }, | |
| 1086 | 1086 | "node_modules/@rollup/rollup-freebsd-arm64": { | |
| 1087 | - | "version": "4.53.3", | |
| 1088 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", | |
| 1089 | - | "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", | |
| 1087 | + | "version": "4.56.0", | |
| 1088 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.56.0.tgz", | |
| 1089 | + | "integrity": "sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==", | |
| 1090 | 1090 | "cpu": [ | |
| 1091 | 1091 | "arm64" | |
| 1092 | 1092 | ], | |
| @@ -1098,9 +1098,9 @@ | |||
| 1098 | 1098 | ] | |
| 1099 | 1099 | }, | |
| 1100 | 1100 | "node_modules/@rollup/rollup-freebsd-x64": { | |
| 1101 | - | "version": "4.53.3", | |
| 1102 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", | |
| 1103 | - | "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", | |
| 1101 | + | "version": "4.56.0", | |
| 1102 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.56.0.tgz", | |
| 1103 | + | "integrity": "sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==", | |
| 1104 | 1104 | "cpu": [ | |
| 1105 | 1105 | "x64" | |
| 1106 | 1106 | ], | |
| @@ -1112,9 +1112,9 @@ | |||
| 1112 | 1112 | ] | |
| 1113 | 1113 | }, | |
| 1114 | 1114 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { | |
| 1115 | - | "version": "4.53.3", | |
| 1116 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", | |
| 1117 | - | "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", | |
| 1115 | + | "version": "4.56.0", | |
| 1116 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.56.0.tgz", | |
| 1117 | + | "integrity": "sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==", | |
| 1118 | 1118 | "cpu": [ | |
| 1119 | 1119 | "arm" | |
| 1120 | 1120 | ], | |
| @@ -1126,9 +1126,9 @@ | |||
| 1126 | 1126 | ] | |
| 1127 | 1127 | }, | |
| 1128 | 1128 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { | |
| 1129 | - | "version": "4.53.3", | |
| 1130 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", | |
| 1131 | - | "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", | |
| 1129 | + | "version": "4.56.0", | |
| 1130 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.56.0.tgz", | |
| 1131 | + | "integrity": "sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==", | |
| 1132 | 1132 | "cpu": [ | |
| 1133 | 1133 | "arm" | |
| 1134 | 1134 | ], | |
| @@ -1140,9 +1140,9 @@ | |||
| 1140 | 1140 | ] | |
| 1141 | 1141 | }, | |
| 1142 | 1142 | "node_modules/@rollup/rollup-linux-arm64-gnu": { | |
| 1143 | - | "version": "4.53.3", | |
| 1144 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", | |
| 1145 | - | "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", | |
| 1143 | + | "version": "4.56.0", | |
| 1144 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.56.0.tgz", | |
| 1145 | + | "integrity": "sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==", | |
| 1146 | 1146 | "cpu": [ | |
| 1147 | 1147 | "arm64" | |
| 1148 | 1148 | ], | |
| @@ -1154,9 +1154,9 @@ | |||
| 1154 | 1154 | ] | |
| 1155 | 1155 | }, | |
| 1156 | 1156 | "node_modules/@rollup/rollup-linux-arm64-musl": { | |
| 1157 | - | "version": "4.53.3", | |
| 1158 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", | |
| 1159 | - | "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", | |
| 1157 | + | "version": "4.56.0", | |
| 1158 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.56.0.tgz", | |
| 1159 | + | "integrity": "sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==", | |
| 1160 | 1160 | "cpu": [ | |
| 1161 | 1161 | "arm64" | |
| 1162 | 1162 | ], | |
| @@ -1168,9 +1168,23 @@ | |||
| 1168 | 1168 | ] | |
| 1169 | 1169 | }, | |
| 1170 | 1170 | "node_modules/@rollup/rollup-linux-loong64-gnu": { | |
| 1171 | - | "version": "4.53.3", | |
| 1172 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", | |
| 1173 | - | "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", | |
| 1171 | + | "version": "4.56.0", | |
| 1172 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.56.0.tgz", | |
| 1173 | + | "integrity": "sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==", | |
| 1174 | + | "cpu": [ | |
| 1175 | + | "loong64" | |
| 1176 | + | ], | |
| 1177 | + | "dev": true, | |
| 1178 | + | "license": "MIT", | |
| 1179 | + | "optional": true, | |
| 1180 | + | "os": [ | |
| 1181 | + | "linux" | |
| 1182 | + | ] | |
| 1183 | + | }, | |
| 1184 | + | "node_modules/@rollup/rollup-linux-loong64-musl": { | |
| 1185 | + | "version": "4.56.0", | |
| 1186 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.56.0.tgz", | |
| 1187 | + | "integrity": "sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==", | |
| 1174 | 1188 | "cpu": [ | |
| 1175 | 1189 | "loong64" | |
| 1176 | 1190 | ], | |
| @@ -1182,9 +1196,23 @@ | |||
| 1182 | 1196 | ] | |
| 1183 | 1197 | }, | |
| 1184 | 1198 | "node_modules/@rollup/rollup-linux-ppc64-gnu": { | |
| 1185 | - | "version": "4.53.3", | |
| 1186 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", | |
| 1187 | - | "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", | |
| 1199 | + | "version": "4.56.0", | |
| 1200 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.56.0.tgz", | |
| 1201 | + | "integrity": "sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==", | |
| 1202 | + | "cpu": [ | |
| 1203 | + | "ppc64" | |
| 1204 | + | ], | |
| 1205 | + | "dev": true, | |
| 1206 | + | "license": "MIT", | |
| 1207 | + | "optional": true, | |
| 1208 | + | "os": [ | |
| 1209 | + | "linux" | |
| 1210 | + | ] | |
| 1211 | + | }, | |
| 1212 | + | "node_modules/@rollup/rollup-linux-ppc64-musl": { | |
| 1213 | + | "version": "4.56.0", | |
| 1214 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.56.0.tgz", | |
| 1215 | + | "integrity": "sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==", | |
| 1188 | 1216 | "cpu": [ | |
| 1189 | 1217 | "ppc64" | |
| 1190 | 1218 | ], | |
| @@ -1196,9 +1224,9 @@ | |||
| 1196 | 1224 | ] | |
| 1197 | 1225 | }, | |
| 1198 | 1226 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { | |
| 1199 | - | "version": "4.53.3", | |
| 1200 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", | |
| 1201 | - | "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", | |
| 1227 | + | "version": "4.56.0", | |
| 1228 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.56.0.tgz", | |
| 1229 | + | "integrity": "sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==", | |
| 1202 | 1230 | "cpu": [ | |
| 1203 | 1231 | "riscv64" | |
| 1204 | 1232 | ], | |
| @@ -1210,9 +1238,9 @@ | |||
| 1210 | 1238 | ] | |
| 1211 | 1239 | }, | |
| 1212 | 1240 | "node_modules/@rollup/rollup-linux-riscv64-musl": { | |
| 1213 | - | "version": "4.53.3", | |
| 1214 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", | |
| 1215 | - | "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", | |
| 1241 | + | "version": "4.56.0", | |
| 1242 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.56.0.tgz", | |
| 1243 | + | "integrity": "sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==", | |
| 1216 | 1244 | "cpu": [ | |
| 1217 | 1245 | "riscv64" | |
| 1218 | 1246 | ], | |
| @@ -1224,9 +1252,9 @@ | |||
| 1224 | 1252 | ] | |
| 1225 | 1253 | }, | |
| 1226 | 1254 | "node_modules/@rollup/rollup-linux-s390x-gnu": { | |
| 1227 | - | "version": "4.53.3", | |
| 1228 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", | |
| 1229 | - | "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", | |
| 1255 | + | "version": "4.56.0", | |
| 1256 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.56.0.tgz", | |
| 1257 | + | "integrity": "sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==", | |
| 1230 | 1258 | "cpu": [ | |
| 1231 | 1259 | "s390x" | |
| 1232 | 1260 | ], | |
| @@ -1238,9 +1266,9 @@ | |||
| 1238 | 1266 | ] | |
| 1239 | 1267 | }, | |
| 1240 | 1268 | "node_modules/@rollup/rollup-linux-x64-gnu": { | |
| 1241 | - | "version": "4.53.3", | |
| 1242 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", | |
| 1243 | - | "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", | |
| 1269 | + | "version": "4.56.0", | |
| 1270 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.56.0.tgz", | |
| 1271 | + | "integrity": "sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==", | |
| 1244 | 1272 | "cpu": [ | |
| 1245 | 1273 | "x64" | |
| 1246 | 1274 | ], | |
| @@ -1252,9 +1280,9 @@ | |||
| 1252 | 1280 | ] | |
| 1253 | 1281 | }, | |
| 1254 | 1282 | "node_modules/@rollup/rollup-linux-x64-musl": { | |
| 1255 | - | "version": "4.53.3", | |
| 1256 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", | |
| 1257 | - | "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", | |
| 1283 | + | "version": "4.56.0", | |
| 1284 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.56.0.tgz", | |
| 1285 | + | "integrity": "sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==", | |
| 1258 | 1286 | "cpu": [ | |
| 1259 | 1287 | "x64" | |
| 1260 | 1288 | ], | |
| @@ -1265,10 +1293,24 @@ | |||
| 1265 | 1293 | "linux" | |
| 1266 | 1294 | ] | |
| 1267 | 1295 | }, | |
| 1296 | + | "node_modules/@rollup/rollup-openbsd-x64": { | |
| 1297 | + | "version": "4.56.0", | |
| 1298 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.56.0.tgz", | |
| 1299 | + | "integrity": "sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==", | |
| 1300 | + | "cpu": [ | |
| 1301 | + | "x64" | |
| 1302 | + | ], | |
| 1303 | + | "dev": true, | |
| 1304 | + | "license": "MIT", | |
| 1305 | + | "optional": true, | |
| 1306 | + | "os": [ | |
| 1307 | + | "openbsd" | |
| 1308 | + | ] | |
| 1309 | + | }, | |
| 1268 | 1310 | "node_modules/@rollup/rollup-openharmony-arm64": { | |
| 1269 | - | "version": "4.53.3", | |
| 1270 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", | |
| 1271 | - | "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", | |
| 1311 | + | "version": "4.56.0", | |
| 1312 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.56.0.tgz", | |
| 1313 | + | "integrity": "sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==", | |
| 1272 | 1314 | "cpu": [ | |
| 1273 | 1315 | "arm64" | |
| 1274 | 1316 | ], | |
| @@ -1280,9 +1322,9 @@ | |||
| 1280 | 1322 | ] | |
| 1281 | 1323 | }, | |
| 1282 | 1324 | "node_modules/@rollup/rollup-win32-arm64-msvc": { | |
| 1283 | - | "version": "4.53.3", | |
| 1284 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", | |
| 1285 | - | "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", | |
| 1325 | + | "version": "4.56.0", | |
| 1326 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.56.0.tgz", | |
| 1327 | + | "integrity": "sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==", | |
| 1286 | 1328 | "cpu": [ | |
| 1287 | 1329 | "arm64" | |
| 1288 | 1330 | ], | |
| @@ -1294,9 +1336,9 @@ | |||
| 1294 | 1336 | ] | |
| 1295 | 1337 | }, | |
| 1296 | 1338 | "node_modules/@rollup/rollup-win32-ia32-msvc": { | |
| 1297 | - | "version": "4.53.3", | |
| 1298 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", | |
| 1299 | - | "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", | |
| 1339 | + | "version": "4.56.0", | |
| 1340 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.56.0.tgz", | |
| 1341 | + | "integrity": "sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==", | |
| 1300 | 1342 | "cpu": [ | |
| 1301 | 1343 | "ia32" | |
| 1302 | 1344 | ], | |
| @@ -1308,9 +1350,9 @@ | |||
| 1308 | 1350 | ] | |
| 1309 | 1351 | }, | |
| 1310 | 1352 | "node_modules/@rollup/rollup-win32-x64-gnu": { | |
| 1311 | - | "version": "4.53.3", | |
| 1312 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", | |
| 1313 | - | "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", | |
| 1353 | + | "version": "4.56.0", | |
| 1354 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.56.0.tgz", | |
| 1355 | + | "integrity": "sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==", | |
| 1314 | 1356 | "cpu": [ | |
| 1315 | 1357 | "x64" | |
| 1316 | 1358 | ], | |
| @@ -1322,9 +1364,9 @@ | |||
| 1322 | 1364 | ] | |
| 1323 | 1365 | }, | |
| 1324 | 1366 | "node_modules/@rollup/rollup-win32-x64-msvc": { | |
| 1325 | - | "version": "4.53.3", | |
| 1326 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", | |
| 1327 | - | "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", | |
| 1367 | + | "version": "4.56.0", | |
| 1368 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.56.0.tgz", | |
| 1369 | + | "integrity": "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==", | |
| 1328 | 1370 | "cpu": [ | |
| 1329 | 1371 | "x64" | |
| 1330 | 1372 | ], | |
| @@ -1386,37 +1428,37 @@ | |||
| 1386 | 1428 | } | |
| 1387 | 1429 | }, | |
| 1388 | 1430 | "node_modules/@swc/helpers": { | |
| 1389 | - | "version": "0.5.17", | |
| 1390 | - | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", | |
| 1391 | - | "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", | |
| 1431 | + | "version": "0.5.18", | |
| 1432 | + | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz", | |
| 1433 | + | "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==", | |
| 1392 | 1434 | "license": "Apache-2.0", | |
| 1393 | 1435 | "dependencies": { | |
| 1394 | 1436 | "tslib": "^2.8.0" | |
| 1395 | 1437 | } | |
| 1396 | 1438 | }, | |
| 1397 | 1439 | "node_modules/@tailwindcss/cli": { | |
| 1398 | - | "version": "4.1.17", | |
| 1399 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.17.tgz", | |
| 1400 | - | "integrity": "sha512-jUIxcyUNlCC2aNPnyPEWU/L2/ik3pB4fF3auKGXr8AvN3T3OFESVctFKOBoPZQaZJIeUpPn1uCLp0MRxuek8gg==", | |
| 1440 | + | "version": "4.1.18", | |
| 1441 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.18.tgz", | |
| 1442 | + | "integrity": "sha512-sMZ+lZbDyxwjD2E0L7oRUjJ01Ffjtme5OtjvvnC+cV4CEDcbqzbp25TCpxHj6kWLU9+DlqJOiNgSOgctC2aZmg==", | |
| 1401 | 1443 | "dev": true, | |
| 1402 | 1444 | "license": "MIT", | |
| 1403 | 1445 | "dependencies": { | |
| 1404 | 1446 | "@parcel/watcher": "^2.5.1", | |
| 1405 | - | "@tailwindcss/node": "4.1.17", | |
| 1406 | - | "@tailwindcss/oxide": "4.1.17", | |
| 1447 | + | "@tailwindcss/node": "4.1.18", | |
| 1448 | + | "@tailwindcss/oxide": "4.1.18", | |
| 1407 | 1449 | "enhanced-resolve": "^5.18.3", | |
| 1408 | 1450 | "mri": "^1.2.0", | |
| 1409 | 1451 | "picocolors": "^1.1.1", | |
| 1410 | - | "tailwindcss": "4.1.17" | |
| 1452 | + | "tailwindcss": "4.1.18" | |
| 1411 | 1453 | }, | |
| 1412 | 1454 | "bin": { | |
| 1413 | 1455 | "tailwindcss": "dist/index.mjs" | |
| 1414 | 1456 | } | |
| 1415 | 1457 | }, | |
| 1416 | 1458 | "node_modules/@tailwindcss/node": { | |
| 1417 | - | "version": "4.1.17", | |
| 1418 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.17.tgz", | |
| 1419 | - | "integrity": "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==", | |
| 1459 | + | "version": "4.1.18", | |
| 1460 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", | |
| 1461 | + | "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", | |
| 1420 | 1462 | "dev": true, | |
| 1421 | 1463 | "license": "MIT", | |
| 1422 | 1464 | "dependencies": { | |
| @@ -1426,37 +1468,37 @@ | |||
| 1426 | 1468 | "lightningcss": "1.30.2", | |
| 1427 | 1469 | "magic-string": "^0.30.21", | |
| 1428 | 1470 | "source-map-js": "^1.2.1", | |
| 1429 | - | "tailwindcss": "4.1.17" | |
| 1471 | + | "tailwindcss": "4.1.18" | |
| 1430 | 1472 | } | |
| 1431 | 1473 | }, | |
| 1432 | 1474 | "node_modules/@tailwindcss/oxide": { | |
| 1433 | - | "version": "4.1.17", | |
| 1434 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.17.tgz", | |
| 1435 | - | "integrity": "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA==", | |
| 1475 | + | "version": "4.1.18", | |
| 1476 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", | |
| 1477 | + | "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", | |
| 1436 | 1478 | "dev": true, | |
| 1437 | 1479 | "license": "MIT", | |
| 1438 | 1480 | "engines": { | |
| 1439 | 1481 | "node": ">= 10" | |
| 1440 | 1482 | }, | |
| 1441 | 1483 | "optionalDependencies": { | |
| 1442 | - | "@tailwindcss/oxide-android-arm64": "4.1.17", | |
| 1443 | - | "@tailwindcss/oxide-darwin-arm64": "4.1.17", | |
| 1444 | - | "@tailwindcss/oxide-darwin-x64": "4.1.17", | |
| 1445 | - | "@tailwindcss/oxide-freebsd-x64": "4.1.17", | |
| 1446 | - | "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", | |
| 1447 | - | "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", | |
| 1448 | - | "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", | |
| 1449 | - | "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", | |
| 1450 | - | "@tailwindcss/oxide-linux-x64-musl": "4.1.17", | |
| 1451 | - | "@tailwindcss/oxide-wasm32-wasi": "4.1.17", | |
| 1452 | - | "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", | |
| 1453 | - | "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" | |
| 1484 | + | "@tailwindcss/oxide-android-arm64": "4.1.18", | |
| 1485 | + | "@tailwindcss/oxide-darwin-arm64": "4.1.18", | |
| 1486 | + | "@tailwindcss/oxide-darwin-x64": "4.1.18", | |
| 1487 | + | "@tailwindcss/oxide-freebsd-x64": "4.1.18", | |
| 1488 | + | "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", | |
| 1489 | + | "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", | |
| 1490 | + | "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", | |
| 1491 | + | "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", | |
| 1492 | + | "@tailwindcss/oxide-linux-x64-musl": "4.1.18", | |
| 1493 | + | "@tailwindcss/oxide-wasm32-wasi": "4.1.18", | |
| 1494 | + | "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", | |
| 1495 | + | "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" | |
| 1454 | 1496 | } | |
| 1455 | 1497 | }, | |
| 1456 | 1498 | "node_modules/@tailwindcss/oxide-android-arm64": { | |
| 1457 | - | "version": "4.1.17", | |
| 1458 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.17.tgz", | |
| 1459 | - | "integrity": "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==", | |
| 1499 | + | "version": "4.1.18", | |
| 1500 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", | |
| 1501 | + | "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", | |
| 1460 | 1502 | "cpu": [ | |
| 1461 | 1503 | "arm64" | |
| 1462 | 1504 | ], | |
| @@ -1471,9 +1513,9 @@ | |||
| 1471 | 1513 | } | |
| 1472 | 1514 | }, | |
| 1473 | 1515 | "node_modules/@tailwindcss/oxide-darwin-arm64": { | |
| 1474 | - | "version": "4.1.17", | |
| 1475 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.17.tgz", | |
| 1476 | - | "integrity": "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==", | |
| 1516 | + | "version": "4.1.18", | |
| 1517 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", | |
| 1518 | + | "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", | |
| 1477 | 1519 | "cpu": [ | |
| 1478 | 1520 | "arm64" | |
| 1479 | 1521 | ], | |
| @@ -1488,9 +1530,9 @@ | |||
| 1488 | 1530 | } | |
| 1489 | 1531 | }, | |
| 1490 | 1532 | "node_modules/@tailwindcss/oxide-darwin-x64": { | |
| 1491 | - | "version": "4.1.17", | |
| 1492 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.17.tgz", | |
| 1493 | - | "integrity": "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==", | |
| 1533 | + | "version": "4.1.18", | |
| 1534 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", | |
| 1535 | + | "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", | |
| 1494 | 1536 | "cpu": [ | |
| 1495 | 1537 | "x64" | |
| 1496 | 1538 | ], | |
| @@ -1505,9 +1547,9 @@ | |||
| 1505 | 1547 | } | |
| 1506 | 1548 | }, | |
| 1507 | 1549 | "node_modules/@tailwindcss/oxide-freebsd-x64": { | |
| 1508 | - | "version": "4.1.17", | |
| 1509 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.17.tgz", | |
| 1510 | - | "integrity": "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==", | |
| 1550 | + | "version": "4.1.18", | |
| 1551 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", | |
| 1552 | + | "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", | |
| 1511 | 1553 | "cpu": [ | |
| 1512 | 1554 | "x64" | |
| 1513 | 1555 | ], | |
| @@ -1522,9 +1564,9 @@ | |||
| 1522 | 1564 | } | |
| 1523 | 1565 | }, | |
| 1524 | 1566 | "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { | |
| 1525 | - | "version": "4.1.17", | |
| 1526 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.17.tgz", | |
| 1527 | - | "integrity": "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==", | |
| 1567 | + | "version": "4.1.18", | |
| 1568 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", | |
| 1569 | + | "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", | |
| 1528 | 1570 | "cpu": [ | |
| 1529 | 1571 | "arm" | |
| 1530 | 1572 | ], | |
| @@ -1539,9 +1581,9 @@ | |||
| 1539 | 1581 | } | |
| 1540 | 1582 | }, | |
| 1541 | 1583 | "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { | |
| 1542 | - | "version": "4.1.17", | |
| 1543 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.17.tgz", | |
| 1544 | - | "integrity": "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==", | |
| 1584 | + | "version": "4.1.18", | |
| 1585 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", | |
| 1586 | + | "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", | |
| 1545 | 1587 | "cpu": [ | |
| 1546 | 1588 | "arm64" | |
| 1547 | 1589 | ], | |
| @@ -1556,9 +1598,9 @@ | |||
| 1556 | 1598 | } | |
| 1557 | 1599 | }, | |
| 1558 | 1600 | "node_modules/@tailwindcss/oxide-linux-arm64-musl": { | |
| 1559 | - | "version": "4.1.17", | |
| 1560 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.17.tgz", | |
| 1561 | - | "integrity": "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==", | |
| 1601 | + | "version": "4.1.18", | |
| 1602 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", | |
| 1603 | + | "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", | |
| 1562 | 1604 | "cpu": [ | |
| 1563 | 1605 | "arm64" | |
| 1564 | 1606 | ], | |
| @@ -1573,9 +1615,9 @@ | |||
| 1573 | 1615 | } | |
| 1574 | 1616 | }, | |
| 1575 | 1617 | "node_modules/@tailwindcss/oxide-linux-x64-gnu": { | |
| 1576 | - | "version": "4.1.17", | |
| 1577 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.17.tgz", | |
| 1578 | - | "integrity": "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==", | |
| 1618 | + | "version": "4.1.18", | |
| 1619 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", | |
| 1620 | + | "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", | |
| 1579 | 1621 | "cpu": [ | |
| 1580 | 1622 | "x64" | |
| 1581 | 1623 | ], | |
| @@ -1590,9 +1632,9 @@ | |||
| 1590 | 1632 | } | |
| 1591 | 1633 | }, | |
| 1592 | 1634 | "node_modules/@tailwindcss/oxide-linux-x64-musl": { | |
| 1593 | - | "version": "4.1.17", | |
| 1594 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.17.tgz", | |
| 1595 | - | "integrity": "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==", | |
| 1635 | + | "version": "4.1.18", | |
| 1636 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", | |
| 1637 | + | "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", | |
| 1596 | 1638 | "cpu": [ | |
| 1597 | 1639 | "x64" | |
| 1598 | 1640 | ], | |
| @@ -1607,9 +1649,9 @@ | |||
| 1607 | 1649 | } | |
| 1608 | 1650 | }, | |
| 1609 | 1651 | "node_modules/@tailwindcss/oxide-wasm32-wasi": { | |
| 1610 | - | "version": "4.1.17", | |
| 1611 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.17.tgz", | |
| 1612 | - | "integrity": "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==", | |
| 1652 | + | "version": "4.1.18", | |
| 1653 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", | |
| 1654 | + | "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", | |
| 1613 | 1655 | "bundleDependencies": [ | |
| 1614 | 1656 | "@napi-rs/wasm-runtime", | |
| 1615 | 1657 | "@emnapi/core", | |
| @@ -1625,10 +1667,10 @@ | |||
| 1625 | 1667 | "license": "MIT", | |
| 1626 | 1668 | "optional": true, | |
| 1627 | 1669 | "dependencies": { | |
| 1628 | - | "@emnapi/core": "^1.6.0", | |
| 1629 | - | "@emnapi/runtime": "^1.6.0", | |
| 1670 | + | "@emnapi/core": "^1.7.1", | |
| 1671 | + | "@emnapi/runtime": "^1.7.1", | |
| 1630 | 1672 | "@emnapi/wasi-threads": "^1.1.0", | |
| 1631 | - | "@napi-rs/wasm-runtime": "^1.0.7", | |
| 1673 | + | "@napi-rs/wasm-runtime": "^1.1.0", | |
| 1632 | 1674 | "@tybys/wasm-util": "^0.10.1", | |
| 1633 | 1675 | "tslib": "^2.4.0" | |
| 1634 | 1676 | }, | |
| @@ -1637,9 +1679,9 @@ | |||
| 1637 | 1679 | } | |
| 1638 | 1680 | }, | |
| 1639 | 1681 | "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { | |
| 1640 | - | "version": "4.1.17", | |
| 1641 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.17.tgz", | |
| 1642 | - | "integrity": "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==", | |
| 1682 | + | "version": "4.1.18", | |
| 1683 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", | |
| 1684 | + | "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", | |
| 1643 | 1685 | "cpu": [ | |
| 1644 | 1686 | "arm64" | |
| 1645 | 1687 | ], | |
| @@ -1654,9 +1696,9 @@ | |||
| 1654 | 1696 | } | |
| 1655 | 1697 | }, | |
| 1656 | 1698 | "node_modules/@tailwindcss/oxide-win32-x64-msvc": { | |
| 1657 | - | "version": "4.1.17", | |
| 1658 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.17.tgz", | |
| 1659 | - | "integrity": "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==", | |
| 1699 | + | "version": "4.1.18", | |
| 1700 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", | |
| 1701 | + | "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", | |
| 1660 | 1702 | "cpu": [ | |
| 1661 | 1703 | "x64" | |
| 1662 | 1704 | ], | |
| @@ -1671,17 +1713,17 @@ | |||
| 1671 | 1713 | } | |
| 1672 | 1714 | }, | |
| 1673 | 1715 | "node_modules/@tailwindcss/postcss": { | |
| 1674 | - | "version": "4.1.17", | |
| 1675 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.17.tgz", | |
| 1676 | - | "integrity": "sha512-+nKl9N9mN5uJ+M7dBOOCzINw94MPstNR/GtIhz1fpZysxL/4a+No64jCBD6CPN+bIHWFx3KWuu8XJRrj/572Dw==", | |
| 1716 | + | "version": "4.1.18", | |
| 1717 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz", | |
| 1718 | + | "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==", | |
| 1677 | 1719 | "dev": true, | |
| 1678 | 1720 | "license": "MIT", | |
| 1679 | 1721 | "dependencies": { | |
| 1680 | 1722 | "@alloc/quick-lru": "^5.2.0", | |
| 1681 | - | "@tailwindcss/node": "4.1.17", | |
| 1682 | - | "@tailwindcss/oxide": "4.1.17", | |
| 1723 | + | "@tailwindcss/node": "4.1.18", | |
| 1724 | + | "@tailwindcss/oxide": "4.1.18", | |
| 1683 | 1725 | "postcss": "^8.4.41", | |
| 1684 | - | "tailwindcss": "4.1.17" | |
| 1726 | + | "tailwindcss": "4.1.18" | |
| 1685 | 1727 | } | |
| 1686 | 1728 | }, | |
| 1687 | 1729 | "node_modules/@types/estree": { | |
| @@ -1691,9 +1733,9 @@ | |||
| 1691 | 1733 | "license": "MIT" | |
| 1692 | 1734 | }, | |
| 1693 | 1735 | "node_modules/@types/node": { | |
| 1694 | - | "version": "20.19.25", | |
| 1695 | - | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", | |
| 1696 | - | "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", | |
| 1736 | + | "version": "20.19.30", | |
| 1737 | + | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", | |
| 1738 | + | "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", | |
| 1697 | 1739 | "dev": true, | |
| 1698 | 1740 | "license": "MIT", | |
| 1699 | 1741 | "peer": true, | |
| @@ -1766,15 +1808,15 @@ | |||
| 1766 | 1808 | } | |
| 1767 | 1809 | }, | |
| 1768 | 1810 | "node_modules/@typescript-eslint/project-service": { | |
| 1769 | - | "version": "8.48.1", | |
| 1770 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.1.tgz", | |
| 1771 | - | "integrity": "sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==", | |
| 1811 | + | "version": "8.53.1", | |
| 1812 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.1.tgz", | |
| 1813 | + | "integrity": "sha512-WYC4FB5Ra0xidsmlPb+1SsnaSKPmS3gsjIARwbEkHkoWloQmuzcfypljaJcR78uyLA1h8sHdWWPHSLDI+MtNog==", | |
| 1772 | 1814 | "dev": true, | |
| 1773 | 1815 | "license": "MIT", | |
| 1774 | 1816 | "dependencies": { | |
| 1775 | - | "@typescript-eslint/tsconfig-utils": "^8.48.1", | |
| 1776 | - | "@typescript-eslint/types": "^8.48.1", | |
| 1777 | - | "debug": "^4.3.4" | |
| 1817 | + | "@typescript-eslint/tsconfig-utils": "^8.53.1", | |
| 1818 | + | "@typescript-eslint/types": "^8.53.1", | |
| 1819 | + | "debug": "^4.4.3" | |
| 1778 | 1820 | }, | |
| 1779 | 1821 | "engines": { | |
| 1780 | 1822 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | |
| @@ -1788,9 +1830,9 @@ | |||
| 1788 | 1830 | } | |
| 1789 | 1831 | }, | |
| 1790 | 1832 | "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { | |
| 1791 | - | "version": "8.48.1", | |
| 1792 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.1.tgz", | |
| 1793 | - | "integrity": "sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==", | |
| 1833 | + | "version": "8.53.1", | |
| 1834 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz", | |
| 1835 | + | "integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==", | |
| 1794 | 1836 | "dev": true, | |
| 1795 | 1837 | "license": "MIT", | |
| 1796 | 1838 | "engines": { | |
| @@ -1820,9 +1862,9 @@ | |||
| 1820 | 1862 | } | |
| 1821 | 1863 | }, | |
| 1822 | 1864 | "node_modules/@typescript-eslint/tsconfig-utils": { | |
| 1823 | - | "version": "8.48.1", | |
| 1824 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.1.tgz", | |
| 1825 | - | "integrity": "sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==", | |
| 1865 | + | "version": "8.53.1", | |
| 1866 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.1.tgz", | |
| 1867 | + | "integrity": "sha512-qfvLXS6F6b1y43pnf0pPbXJ+YoXIC7HKg0UGZ27uMIemKMKA6XH2DTxsEDdpdN29D+vHV07x/pnlPNVLhdhWiA==", | |
| 1826 | 1868 | "dev": true, | |
| 1827 | 1869 | "license": "MIT", | |
| 1828 | 1870 | "engines": { | |
| @@ -2048,9 +2090,9 @@ | |||
| 2048 | 2090 | } | |
| 2049 | 2091 | }, | |
| 2050 | 2092 | "node_modules/autoprefixer": { | |
| 2051 | - | "version": "10.4.22", | |
| 2052 | - | "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.22.tgz", | |
| 2053 | - | "integrity": "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==", | |
| 2093 | + | "version": "10.4.23", | |
| 2094 | + | "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", | |
| 2095 | + | "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", | |
| 2054 | 2096 | "dev": true, | |
| 2055 | 2097 | "funding": [ | |
| 2056 | 2098 | { | |
| @@ -2068,10 +2110,9 @@ | |||
| 2068 | 2110 | ], | |
| 2069 | 2111 | "license": "MIT", | |
| 2070 | 2112 | "dependencies": { | |
| 2071 | - | "browserslist": "^4.27.0", | |
| 2072 | - | "caniuse-lite": "^1.0.30001754", | |
| 2113 | + | "browserslist": "^4.28.1", | |
| 2114 | + | "caniuse-lite": "^1.0.30001760", | |
| 2073 | 2115 | "fraction.js": "^5.3.4", | |
| 2074 | - | "normalize-range": "^0.1.2", | |
| 2075 | 2116 | "picocolors": "^1.1.1", | |
| 2076 | 2117 | "postcss-value-parser": "^4.2.0" | |
| 2077 | 2118 | }, | |
| @@ -2102,9 +2143,9 @@ | |||
| 2102 | 2143 | "license": "MIT" | |
| 2103 | 2144 | }, | |
| 2104 | 2145 | "node_modules/baseline-browser-mapping": { | |
| 2105 | - | "version": "2.9.3", | |
| 2106 | - | "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.3.tgz", | |
| 2107 | - | "integrity": "sha512-8QdH6czo+G7uBsNo0GiUfouPN1lRzKdJTGnKXwe12gkFbnnOUaUKGN55dMkfy+mnxmvjwl9zcI4VncczcVXDhA==", | |
| 2146 | + | "version": "2.9.17", | |
| 2147 | + | "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.17.tgz", | |
| 2148 | + | "integrity": "sha512-agD0MgJFUP/4nvjqzIB29zRPUuCF7Ge6mEv9s8dHrtYD7QWXRcx75rOADE/d5ah1NI+0vkDl0yorDd5U852IQQ==", | |
| 2108 | 2149 | "dev": true, | |
| 2109 | 2150 | "license": "Apache-2.0", | |
| 2110 | 2151 | "bin": { | |
| @@ -2112,9 +2153,9 @@ | |||
| 2112 | 2153 | } | |
| 2113 | 2154 | }, | |
| 2114 | 2155 | "node_modules/bits-ui": { | |
| 2115 | - | "version": "2.14.4", | |
| 2116 | - | "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.14.4.tgz", | |
| 2117 | - | "integrity": "sha512-W6kenhnbd/YVvur+DKkaVJ6GldE53eLewur5AhUCqslYQ0vjZr8eWlOfwZnMiPB+PF5HMVqf61vXBvmyrAmPWg==", | |
| 2156 | + | "version": "2.15.4", | |
| 2157 | + | "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.15.4.tgz", | |
| 2158 | + | "integrity": "sha512-7H9YUfp03KOk1LVDh8wPYSRPxlZgG/GRWLNSA8QC73/8Z8ytun+DWJhIuibyFyz7A0cP/RANVcB4iDrbY8q+Og==", | |
| 2118 | 2159 | "license": "MIT", | |
| 2119 | 2160 | "dependencies": { | |
| 2120 | 2161 | "@floating-ui/core": "^1.7.1", | |
| @@ -2204,9 +2245,9 @@ | |||
| 2204 | 2245 | } | |
| 2205 | 2246 | }, | |
| 2206 | 2247 | "node_modules/caniuse-lite": { | |
| 2207 | - | "version": "1.0.30001759", | |
| 2208 | - | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz", | |
| 2209 | - | "integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==", | |
| 2248 | + | "version": "1.0.30001766", | |
| 2249 | + | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", | |
| 2250 | + | "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", | |
| 2210 | 2251 | "dev": true, | |
| 2211 | 2252 | "funding": [ | |
| 2212 | 2253 | { | |
| @@ -2360,22 +2401,19 @@ | |||
| 2360 | 2401 | } | |
| 2361 | 2402 | }, | |
| 2362 | 2403 | "node_modules/detect-libc": { | |
| 2363 | - | "version": "1.0.3", | |
| 2364 | - | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", | |
| 2365 | - | "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", | |
| 2404 | + | "version": "2.1.2", | |
| 2405 | + | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", | |
| 2406 | + | "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", | |
| 2366 | 2407 | "dev": true, | |
| 2367 | 2408 | "license": "Apache-2.0", | |
| 2368 | - | "bin": { | |
| 2369 | - | "detect-libc": "bin/detect-libc.js" | |
| 2370 | - | }, | |
| 2371 | 2409 | "engines": { | |
| 2372 | - | "node": ">=0.10" | |
| 2410 | + | "node": ">=8" | |
| 2373 | 2411 | } | |
| 2374 | 2412 | }, | |
| 2375 | 2413 | "node_modules/devalue": { | |
| 2376 | - | "version": "5.5.0", | |
| 2377 | - | "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.5.0.tgz", | |
| 2378 | - | "integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==", | |
| 2414 | + | "version": "5.6.2", | |
| 2415 | + | "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz", | |
| 2416 | + | "integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==", | |
| 2379 | 2417 | "license": "MIT" | |
| 2380 | 2418 | }, | |
| 2381 | 2419 | "node_modules/dir-glob": { | |
| @@ -2405,16 +2443,16 @@ | |||
| 2405 | 2443 | } | |
| 2406 | 2444 | }, | |
| 2407 | 2445 | "node_modules/electron-to-chromium": { | |
| 2408 | - | "version": "1.5.266", | |
| 2409 | - | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.266.tgz", | |
| 2410 | - | "integrity": "sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==", | |
| 2446 | + | "version": "1.5.277", | |
| 2447 | + | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.277.tgz", | |
| 2448 | + | "integrity": "sha512-wKXFZw4erWmmOz5N/grBoJ2XrNJGDFMu2+W5ACHza5rHtvsqrK4gb6rnLC7XxKB9WlJ+RmyQatuEXmtm86xbnw==", | |
| 2411 | 2449 | "dev": true, | |
| 2412 | 2450 | "license": "ISC" | |
| 2413 | 2451 | }, | |
| 2414 | 2452 | "node_modules/enhanced-resolve": { | |
| 2415 | - | "version": "5.18.3", | |
| 2416 | - | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", | |
| 2417 | - | "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", | |
| 2453 | + | "version": "5.18.4", | |
| 2454 | + | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", | |
| 2455 | + | "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", | |
| 2418 | 2456 | "dev": true, | |
| 2419 | 2457 | "license": "MIT", | |
| 2420 | 2458 | "dependencies": { | |
| @@ -2624,9 +2662,9 @@ | |||
| 2624 | 2662 | } | |
| 2625 | 2663 | }, | |
| 2626 | 2664 | "node_modules/esquery": { | |
| 2627 | - | "version": "1.6.0", | |
| 2628 | - | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", | |
| 2629 | - | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", | |
| 2665 | + | "version": "1.7.0", | |
| 2666 | + | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", | |
| 2667 | + | "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", | |
| 2630 | 2668 | "dev": true, | |
| 2631 | 2669 | "license": "BSD-3-Clause", | |
| 2632 | 2670 | "dependencies": { | |
| @@ -2637,9 +2675,9 @@ | |||
| 2637 | 2675 | } | |
| 2638 | 2676 | }, | |
| 2639 | 2677 | "node_modules/esrap": { | |
| 2640 | - | "version": "2.2.1", | |
| 2641 | - | "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.1.tgz", | |
| 2642 | - | "integrity": "sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==", | |
| 2678 | + | "version": "2.2.2", | |
| 2679 | + | "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.2.tgz", | |
| 2680 | + | "integrity": "sha512-zA6497ha+qKvoWIK+WM9NAh5ni17sKZKhbS5B3PoYbBvaYHZWoS33zmFybmyqpn07RLUxSmn+RCls2/XF+d0oQ==", | |
| 2643 | 2681 | "license": "MIT", | |
| 2644 | 2682 | "dependencies": { | |
| 2645 | 2683 | "@jridgewell/sourcemap-codec": "^1.4.15" | |
| @@ -2730,15 +2768,33 @@ | |||
| 2730 | 2768 | "license": "MIT" | |
| 2731 | 2769 | }, | |
| 2732 | 2770 | "node_modules/fastq": { | |
| 2733 | - | "version": "1.19.1", | |
| 2734 | - | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", | |
| 2735 | - | "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", | |
| 2771 | + | "version": "1.20.1", | |
| 2772 | + | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", | |
| 2773 | + | "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", | |
| 2736 | 2774 | "dev": true, | |
| 2737 | 2775 | "license": "ISC", | |
| 2738 | 2776 | "dependencies": { | |
| 2739 | 2777 | "reusify": "^1.0.4" | |
| 2740 | 2778 | } | |
| 2741 | 2779 | }, | |
| 2780 | + | "node_modules/fdir": { | |
| 2781 | + | "version": "6.5.0", | |
| 2782 | + | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", | |
| 2783 | + | "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", | |
| 2784 | + | "dev": true, | |
| 2785 | + | "license": "MIT", | |
| 2786 | + | "engines": { | |
| 2787 | + | "node": ">=12.0.0" | |
| 2788 | + | }, | |
| 2789 | + | "peerDependencies": { | |
| 2790 | + | "picomatch": "^3 || ^4" | |
| 2791 | + | }, | |
| 2792 | + | "peerDependenciesMeta": { | |
| 2793 | + | "picomatch": { | |
| 2794 | + | "optional": true | |
| 2795 | + | } | |
| 2796 | + | } | |
| 2797 | + | }, | |
| 2742 | 2798 | "node_modules/file-entry-cache": { | |
| 2743 | 2799 | "version": "6.0.1", | |
| 2744 | 2800 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", | |
| @@ -3426,16 +3482,6 @@ | |||
| 3426 | 3482 | "url": "https://opencollective.com/parcel" | |
| 3427 | 3483 | } | |
| 3428 | 3484 | }, | |
| 3429 | - | "node_modules/lightningcss/node_modules/detect-libc": { | |
| 3430 | - | "version": "2.1.2", | |
| 3431 | - | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", | |
| 3432 | - | "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", | |
| 3433 | - | "dev": true, | |
| 3434 | - | "license": "Apache-2.0", | |
| 3435 | - | "engines": { | |
| 3436 | - | "node": ">=8" | |
| 3437 | - | } | |
| 3438 | - | }, | |
| 3439 | 3485 | "node_modules/locate-character": { | |
| 3440 | 3486 | "version": "3.0.0", | |
| 3441 | 3487 | "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", | |
| @@ -3507,6 +3553,19 @@ | |||
| 3507 | 3553 | "node": ">=8.6" | |
| 3508 | 3554 | } | |
| 3509 | 3555 | }, | |
| 3556 | + | "node_modules/micromatch/node_modules/picomatch": { | |
| 3557 | + | "version": "2.3.1", | |
| 3558 | + | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", | |
| 3559 | + | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", | |
| 3560 | + | "dev": true, | |
| 3561 | + | "license": "MIT", | |
| 3562 | + | "engines": { | |
| 3563 | + | "node": ">=8.6" | |
| 3564 | + | }, | |
| 3565 | + | "funding": { | |
| 3566 | + | "url": "https://github.com/sponsors/jonschlinkert" | |
| 3567 | + | } | |
| 3568 | + | }, | |
| 3510 | 3569 | "node_modules/minimatch": { | |
| 3511 | 3570 | "version": "9.0.5", | |
| 3512 | 3571 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", | |
| @@ -3643,16 +3702,6 @@ | |||
| 3643 | 3702 | "dev": true, | |
| 3644 | 3703 | "license": "MIT" | |
| 3645 | 3704 | }, | |
| 3646 | - | "node_modules/normalize-range": { | |
| 3647 | - | "version": "0.1.2", | |
| 3648 | - | "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", | |
| 3649 | - | "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", | |
| 3650 | - | "dev": true, | |
| 3651 | - | "license": "MIT", | |
| 3652 | - | "engines": { | |
| 3653 | - | "node": ">=0.10.0" | |
| 3654 | - | } | |
| 3655 | - | }, | |
| 3656 | 3705 | "node_modules/once": { | |
| 3657 | 3706 | "version": "1.4.0", | |
| 3658 | 3707 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", | |
| @@ -3774,13 +3823,13 @@ | |||
| 3774 | 3823 | "license": "ISC" | |
| 3775 | 3824 | }, | |
| 3776 | 3825 | "node_modules/picomatch": { | |
| 3777 | - | "version": "2.3.1", | |
| 3778 | - | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", | |
| 3779 | - | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", | |
| 3826 | + | "version": "4.0.3", | |
| 3827 | + | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", | |
| 3828 | + | "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", | |
| 3780 | 3829 | "dev": true, | |
| 3781 | 3830 | "license": "MIT", | |
| 3782 | 3831 | "engines": { | |
| 3783 | - | "node": ">=8.6" | |
| 3832 | + | "node": ">=12" | |
| 3784 | 3833 | }, | |
| 3785 | 3834 | "funding": { | |
| 3786 | 3835 | "url": "https://github.com/sponsors/jonschlinkert" | |
| @@ -3917,9 +3966,9 @@ | |||
| 3917 | 3966 | } | |
| 3918 | 3967 | }, | |
| 3919 | 3968 | "node_modules/rollup": { | |
| 3920 | - | "version": "4.53.3", | |
| 3921 | - | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", | |
| 3922 | - | "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", | |
| 3969 | + | "version": "4.56.0", | |
| 3970 | + | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.56.0.tgz", | |
| 3971 | + | "integrity": "sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==", | |
| 3923 | 3972 | "dev": true, | |
| 3924 | 3973 | "license": "MIT", | |
| 3925 | 3974 | "dependencies": { | |
| @@ -3933,28 +3982,31 @@ | |||
| 3933 | 3982 | "npm": ">=8.0.0" | |
| 3934 | 3983 | }, | |
| 3935 | 3984 | "optionalDependencies": { | |
| 3936 | - | "@rollup/rollup-android-arm-eabi": "4.53.3", | |
| 3937 | - | "@rollup/rollup-android-arm64": "4.53.3", | |
| 3938 | - | "@rollup/rollup-darwin-arm64": "4.53.3", | |
| 3939 | - | "@rollup/rollup-darwin-x64": "4.53.3", | |
| 3940 | - | "@rollup/rollup-freebsd-arm64": "4.53.3", | |
| 3941 | - | "@rollup/rollup-freebsd-x64": "4.53.3", | |
| 3942 | - | "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", | |
| 3943 | - | "@rollup/rollup-linux-arm-musleabihf": "4.53.3", | |
| 3944 | - | "@rollup/rollup-linux-arm64-gnu": "4.53.3", | |
| 3945 | - | "@rollup/rollup-linux-arm64-musl": "4.53.3", | |
| 3946 | - | "@rollup/rollup-linux-loong64-gnu": "4.53.3", | |
| 3947 | - | "@rollup/rollup-linux-ppc64-gnu": "4.53.3", | |
| 3948 | - | "@rollup/rollup-linux-riscv64-gnu": "4.53.3", | |
| 3949 | - | "@rollup/rollup-linux-riscv64-musl": "4.53.3", | |
| 3950 | - | "@rollup/rollup-linux-s390x-gnu": "4.53.3", | |
| 3951 | - | "@rollup/rollup-linux-x64-gnu": "4.53.3", | |
| 3952 | - | "@rollup/rollup-linux-x64-musl": "4.53.3", | |
| 3953 | - | "@rollup/rollup-openharmony-arm64": "4.53.3", | |
| 3954 | - | "@rollup/rollup-win32-arm64-msvc": "4.53.3", | |
| 3955 | - | "@rollup/rollup-win32-ia32-msvc": "4.53.3", | |
| 3956 | - | "@rollup/rollup-win32-x64-gnu": "4.53.3", | |
| 3957 | - | "@rollup/rollup-win32-x64-msvc": "4.53.3", | |
| 3985 | + | "@rollup/rollup-android-arm-eabi": "4.56.0", | |
| 3986 | + | "@rollup/rollup-android-arm64": "4.56.0", | |
| 3987 | + | "@rollup/rollup-darwin-arm64": "4.56.0", | |
| 3988 | + | "@rollup/rollup-darwin-x64": "4.56.0", | |
| 3989 | + | "@rollup/rollup-freebsd-arm64": "4.56.0", | |
| 3990 | + | "@rollup/rollup-freebsd-x64": "4.56.0", | |
| 3991 | + | "@rollup/rollup-linux-arm-gnueabihf": "4.56.0", | |
| 3992 | + | "@rollup/rollup-linux-arm-musleabihf": "4.56.0", | |
| 3993 | + | "@rollup/rollup-linux-arm64-gnu": "4.56.0", | |
| 3994 | + | "@rollup/rollup-linux-arm64-musl": "4.56.0", | |
| 3995 | + | "@rollup/rollup-linux-loong64-gnu": "4.56.0", | |
| 3996 | + | "@rollup/rollup-linux-loong64-musl": "4.56.0", | |
| 3997 | + | "@rollup/rollup-linux-ppc64-gnu": "4.56.0", | |
| 3998 | + | "@rollup/rollup-linux-ppc64-musl": "4.56.0", | |
| 3999 | + | "@rollup/rollup-linux-riscv64-gnu": "4.56.0", | |
| 4000 | + | "@rollup/rollup-linux-riscv64-musl": "4.56.0", | |
| 4001 | + | "@rollup/rollup-linux-s390x-gnu": "4.56.0", | |
| 4002 | + | "@rollup/rollup-linux-x64-gnu": "4.56.0", | |
| 4003 | + | "@rollup/rollup-linux-x64-musl": "4.56.0", | |
| 4004 | + | "@rollup/rollup-openbsd-x64": "4.56.0", | |
| 4005 | + | "@rollup/rollup-openharmony-arm64": "4.56.0", | |
| 4006 | + | "@rollup/rollup-win32-arm64-msvc": "4.56.0", | |
| 4007 | + | "@rollup/rollup-win32-ia32-msvc": "4.56.0", | |
| 4008 | + | "@rollup/rollup-win32-x64-gnu": "4.56.0", | |
| 4009 | + | "@rollup/rollup-win32-x64-msvc": "4.56.0", | |
| 3958 | 4010 | "fsevents": "~2.3.2" | |
| 3959 | 4011 | } | |
| 3960 | 4012 | }, | |
| @@ -4124,9 +4176,9 @@ | |||
| 4124 | 4176 | } | |
| 4125 | 4177 | }, | |
| 4126 | 4178 | "node_modules/svelte": { | |
| 4127 | - | "version": "5.45.5", | |
| 4128 | - | "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.45.5.tgz", | |
| 4129 | - | "integrity": "sha512-2074U+vObO5Zs8/qhxtBwdi6ZXNIhEBTzNmUFjiZexLxTdt9vq96D/0pnQELl6YcpLMD7pZ2dhXKByfGS8SAdg==", | |
| 4179 | + | "version": "5.48.0", | |
| 4180 | + | "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.48.0.tgz", | |
| 4181 | + | "integrity": "sha512-+NUe82VoFP1RQViZI/esojx70eazGF4u0O/9ucqZ4rPcOZD+n5EVp17uYsqwdzjUjZyTpGKunHbDziW6AIAVkQ==", | |
| 4130 | 4182 | "license": "MIT", | |
| 4131 | 4183 | "peer": true, | |
| 4132 | 4184 | "dependencies": { | |
| @@ -4138,7 +4190,7 @@ | |||
| 4138 | 4190 | "aria-query": "^5.3.1", | |
| 4139 | 4191 | "axobject-query": "^4.1.0", | |
| 4140 | 4192 | "clsx": "^2.1.1", | |
| 4141 | - | "devalue": "^5.5.0", | |
| 4193 | + | "devalue": "^5.6.2", | |
| 4142 | 4194 | "esm-env": "^1.2.1", | |
| 4143 | 4195 | "esrap": "^2.2.1", | |
| 4144 | 4196 | "is-reference": "^3.0.3", | |
| @@ -4151,15 +4203,18 @@ | |||
| 4151 | 4203 | } | |
| 4152 | 4204 | }, | |
| 4153 | 4205 | "node_modules/svelte-awesome-color-picker": { | |
| 4154 | - | "version": "4.1.0", | |
| 4155 | - | "resolved": "https://registry.npmjs.org/svelte-awesome-color-picker/-/svelte-awesome-color-picker-4.1.0.tgz", | |
| 4156 | - | "integrity": "sha512-afiSB3eTBlqu96f4+rjBvqG3eCaLwuneNYHe587Wr4Ien6yQWeztGZunPT0FmiI7wFFBVNUlJQLYutII8LfQUg==", | |
| 4206 | + | "version": "4.1.1", | |
| 4207 | + | "resolved": "https://registry.npmjs.org/svelte-awesome-color-picker/-/svelte-awesome-color-picker-4.1.1.tgz", | |
| 4208 | + | "integrity": "sha512-k4APFGBFN8EpvUS0UJfdlqj8xDekMbqGBwnDYBK1QCY8kcTXSO8c7SitEk70MkiYOIByOgXlHcjaipy6H7dpAw==", | |
| 4157 | 4209 | "dev": true, | |
| 4158 | 4210 | "license": "MIT", | |
| 4159 | 4211 | "dependencies": { | |
| 4160 | 4212 | "colord": "^2.9.3", | |
| 4161 | 4213 | "svelte-awesome-slider": "2.0.0" | |
| 4162 | 4214 | }, | |
| 4215 | + | "engines": { | |
| 4216 | + | "node": ">=24" | |
| 4217 | + | }, | |
| 4163 | 4218 | "peerDependencies": { | |
| 4164 | 4219 | "svelte": "^5.0.0" | |
| 4165 | 4220 | } | |
| @@ -4175,9 +4230,9 @@ | |||
| 4175 | 4230 | } | |
| 4176 | 4231 | }, | |
| 4177 | 4232 | "node_modules/svelte-check": { | |
| 4178 | - | "version": "4.3.4", | |
| 4179 | - | "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.4.tgz", | |
| 4180 | - | "integrity": "sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==", | |
| 4233 | + | "version": "4.3.5", | |
| 4234 | + | "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.5.tgz", | |
| 4235 | + | "integrity": "sha512-e4VWZETyXaKGhpkxOXP+B/d0Fp/zKViZoJmneZWe/05Y2aqSKj3YN2nLfYPJBQ87WEiY4BQCQ9hWGu9mPT1a1Q==", | |
| 4181 | 4236 | "dev": true, | |
| 4182 | 4237 | "license": "MIT", | |
| 4183 | 4238 | "dependencies": { | |
| @@ -4198,24 +4253,6 @@ | |||
| 4198 | 4253 | "typescript": ">=5.0.0" | |
| 4199 | 4254 | } | |
| 4200 | 4255 | }, | |
| 4201 | - | "node_modules/svelte-check/node_modules/fdir": { | |
| 4202 | - | "version": "6.5.0", | |
| 4203 | - | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", | |
| 4204 | - | "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", | |
| 4205 | - | "dev": true, | |
| 4206 | - | "license": "MIT", | |
| 4207 | - | "engines": { | |
| 4208 | - | "node": ">=12.0.0" | |
| 4209 | - | }, | |
| 4210 | - | "peerDependencies": { | |
| 4211 | - | "picomatch": "^3 || ^4" | |
| 4212 | - | }, | |
| 4213 | - | "peerDependenciesMeta": { | |
| 4214 | - | "picomatch": { | |
| 4215 | - | "optional": true | |
| 4216 | - | } | |
| 4217 | - | } | |
| 4218 | - | }, | |
| 4219 | 4256 | "node_modules/svelte-toolbelt": { | |
| 4220 | 4257 | "version": "0.10.6", | |
| 4221 | 4258 | "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.10.6.tgz", | |
| @@ -4237,9 +4274,9 @@ | |||
| 4237 | 4274 | } | |
| 4238 | 4275 | }, | |
| 4239 | 4276 | "node_modules/tabbable": { | |
| 4240 | - | "version": "6.3.0", | |
| 4241 | - | "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz", | |
| 4242 | - | "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==", | |
| 4277 | + | "version": "6.4.0", | |
| 4278 | + | "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", | |
| 4279 | + | "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", | |
| 4243 | 4280 | "license": "MIT" | |
| 4244 | 4281 | }, | |
| 4245 | 4282 | "node_modules/tailwind-merge": { | |
| @@ -4274,9 +4311,9 @@ | |||
| 4274 | 4311 | } | |
| 4275 | 4312 | }, | |
| 4276 | 4313 | "node_modules/tailwindcss": { | |
| 4277 | - | "version": "4.1.17", | |
| 4278 | - | "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.17.tgz", | |
| 4279 | - | "integrity": "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==", | |
| 4314 | + | "version": "4.1.18", | |
| 4315 | + | "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", | |
| 4316 | + | "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", | |
| 4280 | 4317 | "dev": true, | |
| 4281 | 4318 | "license": "MIT", | |
| 4282 | 4319 | "peer": true | |
| @@ -4319,38 +4356,6 @@ | |||
| 4319 | 4356 | "url": "https://github.com/sponsors/SuperchupuDev" | |
| 4320 | 4357 | } | |
| 4321 | 4358 | }, | |
| 4322 | - | "node_modules/tinyglobby/node_modules/fdir": { | |
| 4323 | - | "version": "6.5.0", | |
| 4324 | - | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", | |
| 4325 | - | "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", | |
| 4326 | - | "dev": true, | |
| 4327 | - | "license": "MIT", | |
| 4328 | - | "engines": { | |
| 4329 | - | "node": ">=12.0.0" | |
| 4330 | - | }, | |
| 4331 | - | "peerDependencies": { | |
| 4332 | - | "picomatch": "^3 || ^4" | |
| 4333 | - | }, | |
| 4334 | - | "peerDependenciesMeta": { | |
| 4335 | - | "picomatch": { | |
| 4336 | - | "optional": true | |
| 4337 | - | } | |
| 4338 | - | } | |
| 4339 | - | }, | |
| 4340 | - | "node_modules/tinyglobby/node_modules/picomatch": { | |
| 4341 | - | "version": "4.0.3", | |
| 4342 | - | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", | |
| 4343 | - | "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", | |
| 4344 | - | "dev": true, | |
| 4345 | - | "license": "MIT", | |
| 4346 | - | "peer": true, | |
| 4347 | - | "engines": { | |
| 4348 | - | "node": ">=12" | |
| 4349 | - | }, | |
| 4350 | - | "funding": { | |
| 4351 | - | "url": "https://github.com/sponsors/jonschlinkert" | |
| 4352 | - | } | |
| 4353 | - | }, | |
| 4354 | 4359 | "node_modules/to-regex-range": { | |
| 4355 | 4360 | "version": "5.0.1", | |
| 4356 | 4361 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", | |
| @@ -4435,16 +4440,16 @@ | |||
| 4435 | 4440 | } | |
| 4436 | 4441 | }, | |
| 4437 | 4442 | "node_modules/typescript-eslint": { | |
| 4438 | - | "version": "8.48.1", | |
| 4439 | - | "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.48.1.tgz", | |
| 4440 | - | "integrity": "sha512-FbOKN1fqNoXp1hIl5KYpObVrp0mCn+CLgn479nmu2IsRMrx2vyv74MmsBLVlhg8qVwNFGbXSp8fh1zp8pEoC2A==", | |
| 4443 | + | "version": "8.53.1", | |
| 4444 | + | "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.1.tgz", | |
| 4445 | + | "integrity": "sha512-gB+EVQfP5RDElh9ittfXlhZJdjSU4jUSTyE2+ia8CYyNvet4ElfaLlAIqDvQV9JPknKx0jQH1racTYe/4LaLSg==", | |
| 4441 | 4446 | "dev": true, | |
| 4442 | 4447 | "license": "MIT", | |
| 4443 | 4448 | "dependencies": { | |
| 4444 | - | "@typescript-eslint/eslint-plugin": "8.48.1", | |
| 4445 | - | "@typescript-eslint/parser": "8.48.1", | |
| 4446 | - | "@typescript-eslint/typescript-estree": "8.48.1", | |
| 4447 | - | "@typescript-eslint/utils": "8.48.1" | |
| 4449 | + | "@typescript-eslint/eslint-plugin": "8.53.1", | |
| 4450 | + | "@typescript-eslint/parser": "8.53.1", | |
| 4451 | + | "@typescript-eslint/typescript-estree": "8.53.1", | |
| 4452 | + | "@typescript-eslint/utils": "8.53.1" | |
| 4448 | 4453 | }, | |
| 4449 | 4454 | "engines": { | |
| 4450 | 4455 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | |
| @@ -4459,21 +4464,20 @@ | |||
| 4459 | 4464 | } | |
| 4460 | 4465 | }, | |
| 4461 | 4466 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { | |
| 4462 | - | "version": "8.48.1", | |
| 4463 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.48.1.tgz", | |
| 4464 | - | "integrity": "sha512-X63hI1bxl5ohelzr0LY5coufyl0LJNthld+abwxpCoo6Gq+hSqhKwci7MUWkXo67mzgUK6YFByhmaHmUcuBJmA==", | |
| 4467 | + | "version": "8.53.1", | |
| 4468 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.1.tgz", | |
| 4469 | + | "integrity": "sha512-cFYYFZ+oQFi6hUnBTbLRXfTJiaQtYE3t4O692agbBl+2Zy+eqSKWtPjhPXJu1G7j4RLjKgeJPDdq3EqOwmX5Ag==", | |
| 4465 | 4470 | "dev": true, | |
| 4466 | 4471 | "license": "MIT", | |
| 4467 | 4472 | "dependencies": { | |
| 4468 | - | "@eslint-community/regexpp": "^4.10.0", | |
| 4469 | - | "@typescript-eslint/scope-manager": "8.48.1", | |
| 4470 | - | "@typescript-eslint/type-utils": "8.48.1", | |
| 4471 | - | "@typescript-eslint/utils": "8.48.1", | |
| 4472 | - | "@typescript-eslint/visitor-keys": "8.48.1", | |
| 4473 | - | "graphemer": "^1.4.0", | |
| 4474 | - | "ignore": "^7.0.0", | |
| 4473 | + | "@eslint-community/regexpp": "^4.12.2", | |
| 4474 | + | "@typescript-eslint/scope-manager": "8.53.1", | |
| 4475 | + | "@typescript-eslint/type-utils": "8.53.1", | |
| 4476 | + | "@typescript-eslint/utils": "8.53.1", | |
| 4477 | + | "@typescript-eslint/visitor-keys": "8.53.1", | |
| 4478 | + | "ignore": "^7.0.5", | |
| 4475 | 4479 | "natural-compare": "^1.4.0", | |
| 4476 | - | "ts-api-utils": "^2.1.0" | |
| 4480 | + | "ts-api-utils": "^2.4.0" | |
| 4477 | 4481 | }, | |
| 4478 | 4482 | "engines": { | |
| 4479 | 4483 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | |
| @@ -4483,24 +4487,24 @@ | |||
| 4483 | 4487 | "url": "https://opencollective.com/typescript-eslint" | |
| 4484 | 4488 | }, | |
| 4485 | 4489 | "peerDependencies": { | |
| 4486 | - | "@typescript-eslint/parser": "^8.48.1", | |
| 4490 | + | "@typescript-eslint/parser": "^8.53.1", | |
| 4487 | 4491 | "eslint": "^8.57.0 || ^9.0.0", | |
| 4488 | 4492 | "typescript": ">=4.8.4 <6.0.0" | |
| 4489 | 4493 | } | |
| 4490 | 4494 | }, | |
| 4491 | 4495 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { | |
| 4492 | - | "version": "8.48.1", | |
| 4493 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.1.tgz", | |
| 4494 | - | "integrity": "sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA==", | |
| 4496 | + | "version": "8.53.1", | |
| 4497 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.1.tgz", | |
| 4498 | + | "integrity": "sha512-nm3cvFN9SqZGXjmw5bZ6cGmvJSyJPn0wU9gHAZZHDnZl2wF9PhHv78Xf06E0MaNk4zLVHL8hb2/c32XvyJOLQg==", | |
| 4495 | 4499 | "dev": true, | |
| 4496 | 4500 | "license": "MIT", | |
| 4497 | 4501 | "peer": true, | |
| 4498 | 4502 | "dependencies": { | |
| 4499 | - | "@typescript-eslint/scope-manager": "8.48.1", | |
| 4500 | - | "@typescript-eslint/types": "8.48.1", | |
| 4501 | - | "@typescript-eslint/typescript-estree": "8.48.1", | |
| 4502 | - | "@typescript-eslint/visitor-keys": "8.48.1", | |
| 4503 | - | "debug": "^4.3.4" | |
| 4503 | + | "@typescript-eslint/scope-manager": "8.53.1", | |
| 4504 | + | "@typescript-eslint/types": "8.53.1", | |
| 4505 | + | "@typescript-eslint/typescript-estree": "8.53.1", | |
| 4506 | + | "@typescript-eslint/visitor-keys": "8.53.1", | |
| 4507 | + | "debug": "^4.4.3" | |
| 4504 | 4508 | }, | |
| 4505 | 4509 | "engines": { | |
| 4506 | 4510 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | |
| @@ -4515,14 +4519,14 @@ | |||
| 4515 | 4519 | } | |
| 4516 | 4520 | }, | |
| 4517 | 4521 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { | |
| 4518 | - | "version": "8.48.1", | |
| 4519 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.1.tgz", | |
| 4520 | - | "integrity": "sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==", | |
| 4522 | + | "version": "8.53.1", | |
| 4523 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.1.tgz", | |
| 4524 | + | "integrity": "sha512-Lu23yw1uJMFY8cUeq7JlrizAgeQvWugNQzJp8C3x8Eo5Jw5Q2ykMdiiTB9vBVOOUBysMzmRRmUfwFrZuI2C4SQ==", | |
| 4521 | 4525 | "dev": true, | |
| 4522 | 4526 | "license": "MIT", | |
| 4523 | 4527 | "dependencies": { | |
| 4524 | - | "@typescript-eslint/types": "8.48.1", | |
| 4525 | - | "@typescript-eslint/visitor-keys": "8.48.1" | |
| 4528 | + | "@typescript-eslint/types": "8.53.1", | |
| 4529 | + | "@typescript-eslint/visitor-keys": "8.53.1" | |
| 4526 | 4530 | }, | |
| 4527 | 4531 | "engines": { | |
| 4528 | 4532 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | |
| @@ -4533,17 +4537,17 @@ | |||
| 4533 | 4537 | } | |
| 4534 | 4538 | }, | |
| 4535 | 4539 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { | |
| 4536 | - | "version": "8.48.1", | |
| 4537 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.48.1.tgz", | |
| 4538 | - | "integrity": "sha512-1jEop81a3LrJQLTf/1VfPQdhIY4PlGDBc/i67EVWObrtvcziysbLN3oReexHOM6N3jyXgCrkBsZpqwH0hiDOQg==", | |
| 4540 | + | "version": "8.53.1", | |
| 4541 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.1.tgz", | |
| 4542 | + | "integrity": "sha512-MOrdtNvyhy0rHyv0ENzub1d4wQYKb2NmIqG7qEqPWFW7Mpy2jzFC3pQ2yKDvirZB7jypm5uGjF2Qqs6OIqu47w==", | |
| 4539 | 4543 | "dev": true, | |
| 4540 | 4544 | "license": "MIT", | |
| 4541 | 4545 | "dependencies": { | |
| 4542 | - | "@typescript-eslint/types": "8.48.1", | |
| 4543 | - | "@typescript-eslint/typescript-estree": "8.48.1", | |
| 4544 | - | "@typescript-eslint/utils": "8.48.1", | |
| 4545 | - | "debug": "^4.3.4", | |
| 4546 | - | "ts-api-utils": "^2.1.0" | |
| 4546 | + | "@typescript-eslint/types": "8.53.1", | |
| 4547 | + | "@typescript-eslint/typescript-estree": "8.53.1", | |
| 4548 | + | "@typescript-eslint/utils": "8.53.1", | |
| 4549 | + | "debug": "^4.4.3", | |
| 4550 | + | "ts-api-utils": "^2.4.0" | |
| 4547 | 4551 | }, | |
| 4548 | 4552 | "engines": { | |
| 4549 | 4553 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | |
| @@ -4558,9 +4562,9 @@ | |||
| 4558 | 4562 | } | |
| 4559 | 4563 | }, | |
| 4560 | 4564 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { | |
| 4561 | - | "version": "8.48.1", | |
| 4562 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.1.tgz", | |
| 4563 | - | "integrity": "sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==", | |
| 4565 | + | "version": "8.53.1", | |
| 4566 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz", | |
| 4567 | + | "integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==", | |
| 4564 | 4568 | "dev": true, | |
| 4565 | 4569 | "license": "MIT", | |
| 4566 | 4570 | "engines": { | |
| @@ -4572,21 +4576,21 @@ | |||
| 4572 | 4576 | } | |
| 4573 | 4577 | }, | |
| 4574 | 4578 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { | |
| 4575 | - | "version": "8.48.1", | |
| 4576 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.1.tgz", | |
| 4577 | - | "integrity": "sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==", | |
| 4579 | + | "version": "8.53.1", | |
| 4580 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.1.tgz", | |
| 4581 | + | "integrity": "sha512-RGlVipGhQAG4GxV1s34O91cxQ/vWiHJTDHbXRr0li2q/BGg3RR/7NM8QDWgkEgrwQYCvmJV9ichIwyoKCQ+DTg==", | |
| 4578 | 4582 | "dev": true, | |
| 4579 | 4583 | "license": "MIT", | |
| 4580 | 4584 | "dependencies": { | |
| 4581 | - | "@typescript-eslint/project-service": "8.48.1", | |
| 4582 | - | "@typescript-eslint/tsconfig-utils": "8.48.1", | |
| 4583 | - | "@typescript-eslint/types": "8.48.1", | |
| 4584 | - | "@typescript-eslint/visitor-keys": "8.48.1", | |
| 4585 | - | "debug": "^4.3.4", | |
| 4586 | - | "minimatch": "^9.0.4", | |
| 4587 | - | "semver": "^7.6.0", | |
| 4585 | + | "@typescript-eslint/project-service": "8.53.1", | |
| 4586 | + | "@typescript-eslint/tsconfig-utils": "8.53.1", | |
| 4587 | + | "@typescript-eslint/types": "8.53.1", | |
| 4588 | + | "@typescript-eslint/visitor-keys": "8.53.1", | |
| 4589 | + | "debug": "^4.4.3", | |
| 4590 | + | "minimatch": "^9.0.5", | |
| 4591 | + | "semver": "^7.7.3", | |
| 4588 | 4592 | "tinyglobby": "^0.2.15", | |
| 4589 | - | "ts-api-utils": "^2.1.0" | |
| 4593 | + | "ts-api-utils": "^2.4.0" | |
| 4590 | 4594 | }, | |
| 4591 | 4595 | "engines": { | |
| 4592 | 4596 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | |
| @@ -4600,16 +4604,16 @@ | |||
| 4600 | 4604 | } | |
| 4601 | 4605 | }, | |
| 4602 | 4606 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { | |
| 4603 | - | "version": "8.48.1", | |
| 4604 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.1.tgz", | |
| 4605 | - | "integrity": "sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==", | |
| 4607 | + | "version": "8.53.1", | |
| 4608 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.1.tgz", | |
| 4609 | + | "integrity": "sha512-c4bMvGVWW4hv6JmDUEG7fSYlWOl3II2I4ylt0NM+seinYQlZMQIaKaXIIVJWt9Ofh6whrpM+EdDQXKXjNovvrg==", | |
| 4606 | 4610 | "dev": true, | |
| 4607 | 4611 | "license": "MIT", | |
| 4608 | 4612 | "dependencies": { | |
| 4609 | - | "@eslint-community/eslint-utils": "^4.7.0", | |
| 4610 | - | "@typescript-eslint/scope-manager": "8.48.1", | |
| 4611 | - | "@typescript-eslint/types": "8.48.1", | |
| 4612 | - | "@typescript-eslint/typescript-estree": "8.48.1" | |
| 4613 | + | "@eslint-community/eslint-utils": "^4.9.1", | |
| 4614 | + | "@typescript-eslint/scope-manager": "8.53.1", | |
| 4615 | + | "@typescript-eslint/types": "8.53.1", | |
| 4616 | + | "@typescript-eslint/typescript-estree": "8.53.1" | |
| 4613 | 4617 | }, | |
| 4614 | 4618 | "engines": { | |
| 4615 | 4619 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | |
| @@ -4624,13 +4628,13 @@ | |||
| 4624 | 4628 | } | |
| 4625 | 4629 | }, | |
| 4626 | 4630 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { | |
| 4627 | - | "version": "8.48.1", | |
| 4628 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.1.tgz", | |
| 4629 | - | "integrity": "sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==", | |
| 4631 | + | "version": "8.53.1", | |
| 4632 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.1.tgz", | |
| 4633 | + | "integrity": "sha512-oy+wV7xDKFPRyNggmXuZQSBzvoLnpmJs+GhzRhPjrxl2b/jIlyjVokzm47CZCDUdXKr2zd7ZLodPfOBpOPyPlg==", | |
| 4630 | 4634 | "dev": true, | |
| 4631 | 4635 | "license": "MIT", | |
| 4632 | 4636 | "dependencies": { | |
| 4633 | - | "@typescript-eslint/types": "8.48.1", | |
| 4637 | + | "@typescript-eslint/types": "8.53.1", | |
| 4634 | 4638 | "eslint-visitor-keys": "^4.2.1" | |
| 4635 | 4639 | }, | |
| 4636 | 4640 | "engines": { | |
| @@ -4665,9 +4669,9 @@ | |||
| 4665 | 4669 | } | |
| 4666 | 4670 | }, | |
| 4667 | 4671 | "node_modules/typescript-eslint/node_modules/ts-api-utils": { | |
| 4668 | - | "version": "2.1.0", | |
| 4669 | - | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", | |
| 4670 | - | "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", | |
| 4672 | + | "version": "2.4.0", | |
| 4673 | + | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", | |
| 4674 | + | "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", | |
| 4671 | 4675 | "dev": true, | |
| 4672 | 4676 | "license": "MIT", | |
| 4673 | 4677 | "engines": { | |
| @@ -4685,9 +4689,9 @@ | |||
| 4685 | 4689 | "license": "MIT" | |
| 4686 | 4690 | }, | |
| 4687 | 4691 | "node_modules/update-browserslist-db": { | |
| 4688 | - | "version": "1.2.2", | |
| 4689 | - | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", | |
| 4690 | - | "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", | |
| 4692 | + | "version": "1.2.3", | |
| 4693 | + | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", | |
| 4694 | + | "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", | |
| 4691 | 4695 | "dev": true, | |
| 4692 | 4696 | "funding": [ | |
| 4693 | 4697 | { | |
| @@ -442,9 +442,9 @@ | |||||
| 442 | } | 442 | } | ||
| 443 | }, | 443 | }, | ||
| 444 | "node_modules/@eslint-community/eslint-utils": { | 444 | "node_modules/@eslint-community/eslint-utils": { | ||
| 445 | - | "version": "4.9.0", | 445 | + | "version": "4.9.1", |
| 446 | - | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", | 446 | + | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", |
| 447 | - | "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", | 447 | + | "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", |
| 448 | "dev": true, | 448 | "dev": true, | ||
| 449 | "license": "MIT", | 449 | "license": "MIT", | ||
| 450 | "dependencies": { | 450 | "dependencies": { | ||
| @@ -719,17 +719,17 @@ | |||||
| 719 | } | 719 | } | ||
| 720 | }, | 720 | }, | ||
| 721 | "node_modules/@parcel/watcher": { | 721 | "node_modules/@parcel/watcher": { | ||
| 722 | - | "version": "2.5.1", | 722 | + | "version": "2.5.4", |
| 723 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", | 723 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.4.tgz", |
| 724 | - | "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", | 724 | + | "integrity": "sha512-WYa2tUVV5HiArWPB3ydlOc4R2ivq0IDrlqhMi3l7mVsFEXNcTfxYFPIHXHXIh/ca/y/V5N4E1zecyxdIBjYnkQ==", |
| 725 | "dev": true, | 725 | "dev": true, | ||
| 726 | "hasInstallScript": true, | 726 | "hasInstallScript": true, | ||
| 727 | "license": "MIT", | 727 | "license": "MIT", | ||
| 728 | "dependencies": { | 728 | "dependencies": { | ||
| 729 | - | "detect-libc": "^1.0.3", | 729 | + | "detect-libc": "^2.0.3", |
| 730 | "is-glob": "^4.0.3", | 730 | "is-glob": "^4.0.3", | ||
| 731 | - | "micromatch": "^4.0.5", | 731 | + | "node-addon-api": "^7.0.0", |
| 732 | - | "node-addon-api": "^7.0.0" | 732 | + | "picomatch": "^4.0.3" |
| 733 | }, | 733 | }, | ||
| 734 | "engines": { | 734 | "engines": { | ||
| 735 | "node": ">= 10.0.0" | 735 | "node": ">= 10.0.0" | ||
| @@ -739,25 +739,25 @@ | |||||
| 739 | "url": "https://opencollective.com/parcel" | 739 | "url": "https://opencollective.com/parcel" | ||
| 740 | }, | 740 | }, | ||
| 741 | "optionalDependencies": { | 741 | "optionalDependencies": { | ||
| 742 | - | "@parcel/watcher-android-arm64": "2.5.1", | 742 | + | "@parcel/watcher-android-arm64": "2.5.4", |
| 743 | - | "@parcel/watcher-darwin-arm64": "2.5.1", | 743 | + | "@parcel/watcher-darwin-arm64": "2.5.4", |
| 744 | - | "@parcel/watcher-darwin-x64": "2.5.1", | 744 | + | "@parcel/watcher-darwin-x64": "2.5.4", |
| 745 | - | "@parcel/watcher-freebsd-x64": "2.5.1", | 745 | + | "@parcel/watcher-freebsd-x64": "2.5.4", |
| 746 | - | "@parcel/watcher-linux-arm-glibc": "2.5.1", | 746 | + | "@parcel/watcher-linux-arm-glibc": "2.5.4", |
| 747 | - | "@parcel/watcher-linux-arm-musl": "2.5.1", | 747 | + | "@parcel/watcher-linux-arm-musl": "2.5.4", |
| 748 | - | "@parcel/watcher-linux-arm64-glibc": "2.5.1", | 748 | + | "@parcel/watcher-linux-arm64-glibc": "2.5.4", |
| 749 | - | "@parcel/watcher-linux-arm64-musl": "2.5.1", | 749 | + | "@parcel/watcher-linux-arm64-musl": "2.5.4", |
| 750 | - | "@parcel/watcher-linux-x64-glibc": "2.5.1", | 750 | + | "@parcel/watcher-linux-x64-glibc": "2.5.4", |
| 751 | - | "@parcel/watcher-linux-x64-musl": "2.5.1", | 751 | + | "@parcel/watcher-linux-x64-musl": "2.5.4", |
| 752 | - | "@parcel/watcher-win32-arm64": "2.5.1", | 752 | + | "@parcel/watcher-win32-arm64": "2.5.4", |
| 753 | - | "@parcel/watcher-win32-ia32": "2.5.1", | 753 | + | "@parcel/watcher-win32-ia32": "2.5.4", |
| 754 | - | "@parcel/watcher-win32-x64": "2.5.1" | 754 | + | "@parcel/watcher-win32-x64": "2.5.4" |
| 755 | } | 755 | } | ||
| 756 | }, | 756 | }, | ||
| 757 | "node_modules/@parcel/watcher-android-arm64": { | 757 | "node_modules/@parcel/watcher-android-arm64": { | ||
| 758 | - | "version": "2.5.1", | 758 | + | "version": "2.5.4", |
| 759 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", | 759 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.4.tgz", |
| 760 | - | "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", | 760 | + | "integrity": "sha512-hoh0vx4v+b3BNI7Cjoy2/B0ARqcwVNrzN/n7DLq9ZB4I3lrsvhrkCViJyfTj/Qi5xM9YFiH4AmHGK6pgH1ss7g==", |
| 761 | "cpu": [ | 761 | "cpu": [ | ||
| 762 | "arm64" | 762 | "arm64" | ||
| 763 | ], | 763 | ], | ||
| @@ -776,9 +776,9 @@ | |||||
| 776 | } | 776 | } | ||
| 777 | }, | 777 | }, | ||
| 778 | "node_modules/@parcel/watcher-darwin-arm64": { | 778 | "node_modules/@parcel/watcher-darwin-arm64": { | ||
| 779 | - | "version": "2.5.1", | 779 | + | "version": "2.5.4", |
| 780 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", | 780 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.4.tgz", |
| 781 | - | "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", | 781 | + | "integrity": "sha512-kphKy377pZiWpAOyTgQYPE5/XEKVMaj6VUjKT5VkNyUJlr2qZAn8gIc7CPzx+kbhvqHDT9d7EqdOqRXT6vk0zw==", |
| 782 | "cpu": [ | 782 | "cpu": [ | ||
| 783 | "arm64" | 783 | "arm64" | ||
| 784 | ], | 784 | ], | ||
| @@ -797,9 +797,9 @@ | |||||
| 797 | } | 797 | } | ||
| 798 | }, | 798 | }, | ||
| 799 | "node_modules/@parcel/watcher-darwin-x64": { | 799 | "node_modules/@parcel/watcher-darwin-x64": { | ||
| 800 | - | "version": "2.5.1", | 800 | + | "version": "2.5.4", |
| 801 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", | 801 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.4.tgz", |
| 802 | - | "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", | 802 | + | "integrity": "sha512-UKaQFhCtNJW1A9YyVz3Ju7ydf6QgrpNQfRZ35wNKUhTQ3dxJ/3MULXN5JN/0Z80V/KUBDGa3RZaKq1EQT2a2gg==", |
| 803 | "cpu": [ | 803 | "cpu": [ | ||
| 804 | "x64" | 804 | "x64" | ||
| 805 | ], | 805 | ], | ||
| @@ -818,9 +818,9 @@ | |||||
| 818 | } | 818 | } | ||
| 819 | }, | 819 | }, | ||
| 820 | "node_modules/@parcel/watcher-freebsd-x64": { | 820 | "node_modules/@parcel/watcher-freebsd-x64": { | ||
| 821 | - | "version": "2.5.1", | 821 | + | "version": "2.5.4", |
| 822 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", | 822 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.4.tgz", |
| 823 | - | "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", | 823 | + | "integrity": "sha512-Dib0Wv3Ow/m2/ttvLdeI2DBXloO7t3Z0oCp4bAb2aqyqOjKPPGrg10pMJJAQ7tt8P4V2rwYwywkDhUia/FgS+Q==", |
| 824 | "cpu": [ | 824 | "cpu": [ | ||
| 825 | "x64" | 825 | "x64" | ||
| 826 | ], | 826 | ], | ||
| @@ -839,9 +839,9 @@ | |||||
| 839 | } | 839 | } | ||
| 840 | }, | 840 | }, | ||
| 841 | "node_modules/@parcel/watcher-linux-arm-glibc": { | 841 | "node_modules/@parcel/watcher-linux-arm-glibc": { | ||
| 842 | - | "version": "2.5.1", | 842 | + | "version": "2.5.4", |
| 843 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", | 843 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.4.tgz", |
| 844 | - | "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", | 844 | + | "integrity": "sha512-I5Vb769pdf7Q7Sf4KNy8Pogl/URRCKu9ImMmnVKYayhynuyGYMzuI4UOWnegQNa2sGpsPSbzDsqbHNMyeyPCgw==", |
| 845 | "cpu": [ | 845 | "cpu": [ | ||
| 846 | "arm" | 846 | "arm" | ||
| 847 | ], | 847 | ], | ||
| @@ -860,9 +860,9 @@ | |||||
| 860 | } | 860 | } | ||
| 861 | }, | 861 | }, | ||
| 862 | "node_modules/@parcel/watcher-linux-arm-musl": { | 862 | "node_modules/@parcel/watcher-linux-arm-musl": { | ||
| 863 | - | "version": "2.5.1", | 863 | + | "version": "2.5.4", |
| 864 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", | 864 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.4.tgz", |
| 865 | - | "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", | 865 | + | "integrity": "sha512-kGO8RPvVrcAotV4QcWh8kZuHr9bXi9a3bSZw7kFarYR0+fGliU7hd/zevhjw8fnvIKG3J9EO5G6sXNGCSNMYPQ==", |
| 866 | "cpu": [ | 866 | "cpu": [ | ||
| 867 | "arm" | 867 | "arm" | ||
| 868 | ], | 868 | ], | ||
| @@ -881,9 +881,9 @@ | |||||
| 881 | } | 881 | } | ||
| 882 | }, | 882 | }, | ||
| 883 | "node_modules/@parcel/watcher-linux-arm64-glibc": { | 883 | "node_modules/@parcel/watcher-linux-arm64-glibc": { | ||
| 884 | - | "version": "2.5.1", | 884 | + | "version": "2.5.4", |
| 885 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", | 885 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.4.tgz", |
| 886 | - | "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", | 886 | + | "integrity": "sha512-KU75aooXhqGFY2W5/p8DYYHt4hrjHZod8AhcGAmhzPn/etTa+lYCDB2b1sJy3sWJ8ahFVTdy+EbqSBvMx3iFlw==", |
| 887 | "cpu": [ | 887 | "cpu": [ | ||
| 888 | "arm64" | 888 | "arm64" | ||
| 889 | ], | 889 | ], | ||
| @@ -902,9 +902,9 @@ | |||||
| 902 | } | 902 | } | ||
| 903 | }, | 903 | }, | ||
| 904 | "node_modules/@parcel/watcher-linux-arm64-musl": { | 904 | "node_modules/@parcel/watcher-linux-arm64-musl": { | ||
| 905 | - | "version": "2.5.1", | 905 | + | "version": "2.5.4", |
| 906 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", | 906 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.4.tgz", |
| 907 | - | "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", | 907 | + | "integrity": "sha512-Qx8uNiIekVutnzbVdrgSanM+cbpDD3boB1f8vMtnuG5Zau4/bdDbXyKwIn0ToqFhIuob73bcxV9NwRm04/hzHQ==", |
| 908 | "cpu": [ | 908 | "cpu": [ | ||
| 909 | "arm64" | 909 | "arm64" | ||
| 910 | ], | 910 | ], | ||
| @@ -923,9 +923,9 @@ | |||||
| 923 | } | 923 | } | ||
| 924 | }, | 924 | }, | ||
| 925 | "node_modules/@parcel/watcher-linux-x64-glibc": { | 925 | "node_modules/@parcel/watcher-linux-x64-glibc": { | ||
| 926 | - | "version": "2.5.1", | 926 | + | "version": "2.5.4", |
| 927 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", | 927 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.4.tgz", |
| 928 | - | "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", | 928 | + | "integrity": "sha512-UYBQvhYmgAv61LNUn24qGQdjtycFBKSK3EXr72DbJqX9aaLbtCOO8+1SkKhD/GNiJ97ExgcHBrukcYhVjrnogA==", |
| 929 | "cpu": [ | 929 | "cpu": [ | ||
| 930 | "x64" | 930 | "x64" | ||
| 931 | ], | 931 | ], | ||
| @@ -944,9 +944,9 @@ | |||||
| 944 | } | 944 | } | ||
| 945 | }, | 945 | }, | ||
| 946 | "node_modules/@parcel/watcher-linux-x64-musl": { | 946 | "node_modules/@parcel/watcher-linux-x64-musl": { | ||
| 947 | - | "version": "2.5.1", | 947 | + | "version": "2.5.4", |
| 948 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", | 948 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.4.tgz", |
| 949 | - | "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", | 949 | + | "integrity": "sha512-YoRWCVgxv8akZrMhdyVi6/TyoeeMkQ0PGGOf2E4omODrvd1wxniXP+DBynKoHryStks7l+fDAMUBRzqNHrVOpg==", |
| 950 | "cpu": [ | 950 | "cpu": [ | ||
| 951 | "x64" | 951 | "x64" | ||
| 952 | ], | 952 | ], | ||
| @@ -965,9 +965,9 @@ | |||||
| 965 | } | 965 | } | ||
| 966 | }, | 966 | }, | ||
| 967 | "node_modules/@parcel/watcher-win32-arm64": { | 967 | "node_modules/@parcel/watcher-win32-arm64": { | ||
| 968 | - | "version": "2.5.1", | 968 | + | "version": "2.5.4", |
| 969 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", | 969 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.4.tgz", |
| 970 | - | "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", | 970 | + | "integrity": "sha512-iby+D/YNXWkiQNYcIhg8P5hSjzXEHaQrk2SLrWOUD7VeC4Ohu0WQvmV+HDJokZVJ2UjJ4AGXW3bx7Lls9Ln4TQ==", |
| 971 | "cpu": [ | 971 | "cpu": [ | ||
| 972 | "arm64" | 972 | "arm64" | ||
| 973 | ], | 973 | ], | ||
| @@ -986,9 +986,9 @@ | |||||
| 986 | } | 986 | } | ||
| 987 | }, | 987 | }, | ||
| 988 | "node_modules/@parcel/watcher-win32-ia32": { | 988 | "node_modules/@parcel/watcher-win32-ia32": { | ||
| 989 | - | "version": "2.5.1", | 989 | + | "version": "2.5.4", |
| 990 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", | 990 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.4.tgz", |
| 991 | - | "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", | 991 | + | "integrity": "sha512-vQN+KIReG0a2ZDpVv8cgddlf67J8hk1WfZMMP7sMeZmJRSmEax5xNDNWKdgqSe2brOKTQQAs3aCCUal2qBHAyg==", |
| 992 | "cpu": [ | 992 | "cpu": [ | ||
| 993 | "ia32" | 993 | "ia32" | ||
| 994 | ], | 994 | ], | ||
| @@ -1007,9 +1007,9 @@ | |||||
| 1007 | } | 1007 | } | ||
| 1008 | }, | 1008 | }, | ||
| 1009 | "node_modules/@parcel/watcher-win32-x64": { | 1009 | "node_modules/@parcel/watcher-win32-x64": { | ||
| 1010 | - | "version": "2.5.1", | 1010 | + | "version": "2.5.4", |
| 1011 | - | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", | 1011 | + | "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.4.tgz", |
| 1012 | - | "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", | 1012 | + | "integrity": "sha512-3A6efb6BOKwyw7yk9ro2vus2YTt2nvcd56AuzxdMiVOxL9umDyN5PKkKfZ/gZ9row41SjVmTVQNWQhaRRGpOKw==", |
| 1013 | "cpu": [ | 1013 | "cpu": [ | ||
| 1014 | "x64" | 1014 | "x64" | ||
| 1015 | ], | 1015 | ], | ||
| @@ -1028,9 +1028,9 @@ | |||||
| 1028 | } | 1028 | } | ||
| 1029 | }, | 1029 | }, | ||
| 1030 | "node_modules/@rollup/rollup-android-arm-eabi": { | 1030 | "node_modules/@rollup/rollup-android-arm-eabi": { | ||
| 1031 | - | "version": "4.53.3", | 1031 | + | "version": "4.56.0", |
| 1032 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", | 1032 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.56.0.tgz", |
| 1033 | - | "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", | 1033 | + | "integrity": "sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==", |
| 1034 | "cpu": [ | 1034 | "cpu": [ | ||
| 1035 | "arm" | 1035 | "arm" | ||
| 1036 | ], | 1036 | ], | ||
| @@ -1042,9 +1042,9 @@ | |||||
| 1042 | ] | 1042 | ] | ||
| 1043 | }, | 1043 | }, | ||
| 1044 | "node_modules/@rollup/rollup-android-arm64": { | 1044 | "node_modules/@rollup/rollup-android-arm64": { | ||
| 1045 | - | "version": "4.53.3", | 1045 | + | "version": "4.56.0", |
| 1046 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", | 1046 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.56.0.tgz", |
| 1047 | - | "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", | 1047 | + | "integrity": "sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==", |
| 1048 | "cpu": [ | 1048 | "cpu": [ | ||
| 1049 | "arm64" | 1049 | "arm64" | ||
| 1050 | ], | 1050 | ], | ||
| @@ -1056,9 +1056,9 @@ | |||||
| 1056 | ] | 1056 | ] | ||
| 1057 | }, | 1057 | }, | ||
| 1058 | "node_modules/@rollup/rollup-darwin-arm64": { | 1058 | "node_modules/@rollup/rollup-darwin-arm64": { | ||
| 1059 | - | "version": "4.53.3", | 1059 | + | "version": "4.56.0", |
| 1060 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", | 1060 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.56.0.tgz", |
| 1061 | - | "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", | 1061 | + | "integrity": "sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==", |
| 1062 | "cpu": [ | 1062 | "cpu": [ | ||
| 1063 | "arm64" | 1063 | "arm64" | ||
| 1064 | ], | 1064 | ], | ||
| @@ -1070,9 +1070,9 @@ | |||||
| 1070 | ] | 1070 | ] | ||
| 1071 | }, | 1071 | }, | ||
| 1072 | "node_modules/@rollup/rollup-darwin-x64": { | 1072 | "node_modules/@rollup/rollup-darwin-x64": { | ||
| 1073 | - | "version": "4.53.3", | 1073 | + | "version": "4.56.0", |
| 1074 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", | 1074 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.56.0.tgz", |
| 1075 | - | "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", | 1075 | + | "integrity": "sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==", |
| 1076 | "cpu": [ | 1076 | "cpu": [ | ||
| 1077 | "x64" | 1077 | "x64" | ||
| 1078 | ], | 1078 | ], | ||
| @@ -1084,9 +1084,9 @@ | |||||
| 1084 | ] | 1084 | ] | ||
| 1085 | }, | 1085 | }, | ||
| 1086 | "node_modules/@rollup/rollup-freebsd-arm64": { | 1086 | "node_modules/@rollup/rollup-freebsd-arm64": { | ||
| 1087 | - | "version": "4.53.3", | 1087 | + | "version": "4.56.0", |
| 1088 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", | 1088 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.56.0.tgz", |
| 1089 | - | "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", | 1089 | + | "integrity": "sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==", |
| 1090 | "cpu": [ | 1090 | "cpu": [ | ||
| 1091 | "arm64" | 1091 | "arm64" | ||
| 1092 | ], | 1092 | ], | ||
| @@ -1098,9 +1098,9 @@ | |||||
| 1098 | ] | 1098 | ] | ||
| 1099 | }, | 1099 | }, | ||
| 1100 | "node_modules/@rollup/rollup-freebsd-x64": { | 1100 | "node_modules/@rollup/rollup-freebsd-x64": { | ||
| 1101 | - | "version": "4.53.3", | 1101 | + | "version": "4.56.0", |
| 1102 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", | 1102 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.56.0.tgz", |
| 1103 | - | "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", | 1103 | + | "integrity": "sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==", |
| 1104 | "cpu": [ | 1104 | "cpu": [ | ||
| 1105 | "x64" | 1105 | "x64" | ||
| 1106 | ], | 1106 | ], | ||
| @@ -1112,9 +1112,9 @@ | |||||
| 1112 | ] | 1112 | ] | ||
| 1113 | }, | 1113 | }, | ||
| 1114 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { | 1114 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { | ||
| 1115 | - | "version": "4.53.3", | 1115 | + | "version": "4.56.0", |
| 1116 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", | 1116 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.56.0.tgz", |
| 1117 | - | "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", | 1117 | + | "integrity": "sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==", |
| 1118 | "cpu": [ | 1118 | "cpu": [ | ||
| 1119 | "arm" | 1119 | "arm" | ||
| 1120 | ], | 1120 | ], | ||
| @@ -1126,9 +1126,9 @@ | |||||
| 1126 | ] | 1126 | ] | ||
| 1127 | }, | 1127 | }, | ||
| 1128 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { | 1128 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { | ||
| 1129 | - | "version": "4.53.3", | 1129 | + | "version": "4.56.0", |
| 1130 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", | 1130 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.56.0.tgz", |
| 1131 | - | "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", | 1131 | + | "integrity": "sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==", |
| 1132 | "cpu": [ | 1132 | "cpu": [ | ||
| 1133 | "arm" | 1133 | "arm" | ||
| 1134 | ], | 1134 | ], | ||
| @@ -1140,9 +1140,9 @@ | |||||
| 1140 | ] | 1140 | ] | ||
| 1141 | }, | 1141 | }, | ||
| 1142 | "node_modules/@rollup/rollup-linux-arm64-gnu": { | 1142 | "node_modules/@rollup/rollup-linux-arm64-gnu": { | ||
| 1143 | - | "version": "4.53.3", | 1143 | + | "version": "4.56.0", |
| 1144 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", | 1144 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.56.0.tgz", |
| 1145 | - | "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", | 1145 | + | "integrity": "sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==", |
| 1146 | "cpu": [ | 1146 | "cpu": [ | ||
| 1147 | "arm64" | 1147 | "arm64" | ||
| 1148 | ], | 1148 | ], | ||
| @@ -1154,9 +1154,9 @@ | |||||
| 1154 | ] | 1154 | ] | ||
| 1155 | }, | 1155 | }, | ||
| 1156 | "node_modules/@rollup/rollup-linux-arm64-musl": { | 1156 | "node_modules/@rollup/rollup-linux-arm64-musl": { | ||
| 1157 | - | "version": "4.53.3", | 1157 | + | "version": "4.56.0", |
| 1158 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", | 1158 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.56.0.tgz", |
| 1159 | - | "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", | 1159 | + | "integrity": "sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==", |
| 1160 | "cpu": [ | 1160 | "cpu": [ | ||
| 1161 | "arm64" | 1161 | "arm64" | ||
| 1162 | ], | 1162 | ], | ||
| @@ -1168,9 +1168,23 @@ | |||||
| 1168 | ] | 1168 | ] | ||
| 1169 | }, | 1169 | }, | ||
| 1170 | "node_modules/@rollup/rollup-linux-loong64-gnu": { | 1170 | "node_modules/@rollup/rollup-linux-loong64-gnu": { | ||
| 1171 | - | "version": "4.53.3", | 1171 | + | "version": "4.56.0", |
| 1172 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", | 1172 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.56.0.tgz", |
| 1173 | - | "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", | 1173 | + | "integrity": "sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==", |
| 1174 | + | "cpu": [ | |||
| 1175 | + | "loong64" | |||
| 1176 | + | ], | |||
| 1177 | + | "dev": true, | |||
| 1178 | + | "license": "MIT", | |||
| 1179 | + | "optional": true, | |||
| 1180 | + | "os": [ | |||
| 1181 | + | "linux" | |||
| 1182 | + | ] | |||
| 1183 | + | }, | |||
| 1184 | + | "node_modules/@rollup/rollup-linux-loong64-musl": { | |||
| 1185 | + | "version": "4.56.0", | |||
| 1186 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.56.0.tgz", | |||
| 1187 | + | "integrity": "sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==", | |||
| 1174 | "cpu": [ | 1188 | "cpu": [ | ||
| 1175 | "loong64" | 1189 | "loong64" | ||
| 1176 | ], | 1190 | ], | ||
| @@ -1182,9 +1196,23 @@ | |||||
| 1182 | ] | 1196 | ] | ||
| 1183 | }, | 1197 | }, | ||
| 1184 | "node_modules/@rollup/rollup-linux-ppc64-gnu": { | 1198 | "node_modules/@rollup/rollup-linux-ppc64-gnu": { | ||
| 1185 | - | "version": "4.53.3", | 1199 | + | "version": "4.56.0", |
| 1186 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", | 1200 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.56.0.tgz", |
| 1187 | - | "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", | 1201 | + | "integrity": "sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==", |
| 1202 | + | "cpu": [ | |||
| 1203 | + | "ppc64" | |||
| 1204 | + | ], | |||
| 1205 | + | "dev": true, | |||
| 1206 | + | "license": "MIT", | |||
| 1207 | + | "optional": true, | |||
| 1208 | + | "os": [ | |||
| 1209 | + | "linux" | |||
| 1210 | + | ] | |||
| 1211 | + | }, | |||
| 1212 | + | "node_modules/@rollup/rollup-linux-ppc64-musl": { | |||
| 1213 | + | "version": "4.56.0", | |||
| 1214 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.56.0.tgz", | |||
| 1215 | + | "integrity": "sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==", | |||
| 1188 | "cpu": [ | 1216 | "cpu": [ | ||
| 1189 | "ppc64" | 1217 | "ppc64" | ||
| 1190 | ], | 1218 | ], | ||
| @@ -1196,9 +1224,9 @@ | |||||
| 1196 | ] | 1224 | ] | ||
| 1197 | }, | 1225 | }, | ||
| 1198 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { | 1226 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { | ||
| 1199 | - | "version": "4.53.3", | 1227 | + | "version": "4.56.0", |
| 1200 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", | 1228 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.56.0.tgz", |
| 1201 | - | "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", | 1229 | + | "integrity": "sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==", |
| 1202 | "cpu": [ | 1230 | "cpu": [ | ||
| 1203 | "riscv64" | 1231 | "riscv64" | ||
| 1204 | ], | 1232 | ], | ||
| @@ -1210,9 +1238,9 @@ | |||||
| 1210 | ] | 1238 | ] | ||
| 1211 | }, | 1239 | }, | ||
| 1212 | "node_modules/@rollup/rollup-linux-riscv64-musl": { | 1240 | "node_modules/@rollup/rollup-linux-riscv64-musl": { | ||
| 1213 | - | "version": "4.53.3", | 1241 | + | "version": "4.56.0", |
| 1214 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", | 1242 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.56.0.tgz", |
| 1215 | - | "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", | 1243 | + | "integrity": "sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==", |
| 1216 | "cpu": [ | 1244 | "cpu": [ | ||
| 1217 | "riscv64" | 1245 | "riscv64" | ||
| 1218 | ], | 1246 | ], | ||
| @@ -1224,9 +1252,9 @@ | |||||
| 1224 | ] | 1252 | ] | ||
| 1225 | }, | 1253 | }, | ||
| 1226 | "node_modules/@rollup/rollup-linux-s390x-gnu": { | 1254 | "node_modules/@rollup/rollup-linux-s390x-gnu": { | ||
| 1227 | - | "version": "4.53.3", | 1255 | + | "version": "4.56.0", |
| 1228 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", | 1256 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.56.0.tgz", |
| 1229 | - | "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", | 1257 | + | "integrity": "sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==", |
| 1230 | "cpu": [ | 1258 | "cpu": [ | ||
| 1231 | "s390x" | 1259 | "s390x" | ||
| 1232 | ], | 1260 | ], | ||
| @@ -1238,9 +1266,9 @@ | |||||
| 1238 | ] | 1266 | ] | ||
| 1239 | }, | 1267 | }, | ||
| 1240 | "node_modules/@rollup/rollup-linux-x64-gnu": { | 1268 | "node_modules/@rollup/rollup-linux-x64-gnu": { | ||
| 1241 | - | "version": "4.53.3", | 1269 | + | "version": "4.56.0", |
| 1242 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", | 1270 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.56.0.tgz", |
| 1243 | - | "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", | 1271 | + | "integrity": "sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==", |
| 1244 | "cpu": [ | 1272 | "cpu": [ | ||
| 1245 | "x64" | 1273 | "x64" | ||
| 1246 | ], | 1274 | ], | ||
| @@ -1252,9 +1280,9 @@ | |||||
| 1252 | ] | 1280 | ] | ||
| 1253 | }, | 1281 | }, | ||
| 1254 | "node_modules/@rollup/rollup-linux-x64-musl": { | 1282 | "node_modules/@rollup/rollup-linux-x64-musl": { | ||
| 1255 | - | "version": "4.53.3", | 1283 | + | "version": "4.56.0", |
| 1256 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", | 1284 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.56.0.tgz", |
| 1257 | - | "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", | 1285 | + | "integrity": "sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==", |
| 1258 | "cpu": [ | 1286 | "cpu": [ | ||
| 1259 | "x64" | 1287 | "x64" | ||
| 1260 | ], | 1288 | ], | ||
| @@ -1265,10 +1293,24 @@ | |||||
| 1265 | "linux" | 1293 | "linux" | ||
| 1266 | ] | 1294 | ] | ||
| 1267 | }, | 1295 | }, | ||
| 1296 | + | "node_modules/@rollup/rollup-openbsd-x64": { | |||
| 1297 | + | "version": "4.56.0", | |||
| 1298 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.56.0.tgz", | |||
| 1299 | + | "integrity": "sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==", | |||
| 1300 | + | "cpu": [ | |||
| 1301 | + | "x64" | |||
| 1302 | + | ], | |||
| 1303 | + | "dev": true, | |||
| 1304 | + | "license": "MIT", | |||
| 1305 | + | "optional": true, | |||
| 1306 | + | "os": [ | |||
| 1307 | + | "openbsd" | |||
| 1308 | + | ] | |||
| 1309 | + | }, | |||
| 1268 | "node_modules/@rollup/rollup-openharmony-arm64": { | 1310 | "node_modules/@rollup/rollup-openharmony-arm64": { | ||
| 1269 | - | "version": "4.53.3", | 1311 | + | "version": "4.56.0", |
| 1270 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", | 1312 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.56.0.tgz", |
| 1271 | - | "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", | 1313 | + | "integrity": "sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==", |
| 1272 | "cpu": [ | 1314 | "cpu": [ | ||
| 1273 | "arm64" | 1315 | "arm64" | ||
| 1274 | ], | 1316 | ], | ||
| @@ -1280,9 +1322,9 @@ | |||||
| 1280 | ] | 1322 | ] | ||
| 1281 | }, | 1323 | }, | ||
| 1282 | "node_modules/@rollup/rollup-win32-arm64-msvc": { | 1324 | "node_modules/@rollup/rollup-win32-arm64-msvc": { | ||
| 1283 | - | "version": "4.53.3", | 1325 | + | "version": "4.56.0", |
| 1284 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", | 1326 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.56.0.tgz", |
| 1285 | - | "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", | 1327 | + | "integrity": "sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==", |
| 1286 | "cpu": [ | 1328 | "cpu": [ | ||
| 1287 | "arm64" | 1329 | "arm64" | ||
| 1288 | ], | 1330 | ], | ||
| @@ -1294,9 +1336,9 @@ | |||||
| 1294 | ] | 1336 | ] | ||
| 1295 | }, | 1337 | }, | ||
| 1296 | "node_modules/@rollup/rollup-win32-ia32-msvc": { | 1338 | "node_modules/@rollup/rollup-win32-ia32-msvc": { | ||
| 1297 | - | "version": "4.53.3", | 1339 | + | "version": "4.56.0", |
| 1298 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", | 1340 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.56.0.tgz", |
| 1299 | - | "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", | 1341 | + | "integrity": "sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==", |
| 1300 | "cpu": [ | 1342 | "cpu": [ | ||
| 1301 | "ia32" | 1343 | "ia32" | ||
| 1302 | ], | 1344 | ], | ||
| @@ -1308,9 +1350,9 @@ | |||||
| 1308 | ] | 1350 | ] | ||
| 1309 | }, | 1351 | }, | ||
| 1310 | "node_modules/@rollup/rollup-win32-x64-gnu": { | 1352 | "node_modules/@rollup/rollup-win32-x64-gnu": { | ||
| 1311 | - | "version": "4.53.3", | 1353 | + | "version": "4.56.0", |
| 1312 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", | 1354 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.56.0.tgz", |
| 1313 | - | "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", | 1355 | + | "integrity": "sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==", |
| 1314 | "cpu": [ | 1356 | "cpu": [ | ||
| 1315 | "x64" | 1357 | "x64" | ||
| 1316 | ], | 1358 | ], | ||
| @@ -1322,9 +1364,9 @@ | |||||
| 1322 | ] | 1364 | ] | ||
| 1323 | }, | 1365 | }, | ||
| 1324 | "node_modules/@rollup/rollup-win32-x64-msvc": { | 1366 | "node_modules/@rollup/rollup-win32-x64-msvc": { | ||
| 1325 | - | "version": "4.53.3", | 1367 | + | "version": "4.56.0", |
| 1326 | - | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", | 1368 | + | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.56.0.tgz", |
| 1327 | - | "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", | 1369 | + | "integrity": "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==", |
| 1328 | "cpu": [ | 1370 | "cpu": [ | ||
| 1329 | "x64" | 1371 | "x64" | ||
| 1330 | ], | 1372 | ], | ||
| @@ -1386,37 +1428,37 @@ | |||||
| 1386 | } | 1428 | } | ||
| 1387 | }, | 1429 | }, | ||
| 1388 | "node_modules/@swc/helpers": { | 1430 | "node_modules/@swc/helpers": { | ||
| 1389 | - | "version": "0.5.17", | 1431 | + | "version": "0.5.18", |
| 1390 | - | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", | 1432 | + | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz", |
| 1391 | - | "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", | 1433 | + | "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==", |
| 1392 | "license": "Apache-2.0", | 1434 | "license": "Apache-2.0", | ||
| 1393 | "dependencies": { | 1435 | "dependencies": { | ||
| 1394 | "tslib": "^2.8.0" | 1436 | "tslib": "^2.8.0" | ||
| 1395 | } | 1437 | } | ||
| 1396 | }, | 1438 | }, | ||
| 1397 | "node_modules/@tailwindcss/cli": { | 1439 | "node_modules/@tailwindcss/cli": { | ||
| 1398 | - | "version": "4.1.17", | 1440 | + | "version": "4.1.18", |
| 1399 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.17.tgz", | 1441 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.18.tgz", |
| 1400 | - | "integrity": "sha512-jUIxcyUNlCC2aNPnyPEWU/L2/ik3pB4fF3auKGXr8AvN3T3OFESVctFKOBoPZQaZJIeUpPn1uCLp0MRxuek8gg==", | 1442 | + | "integrity": "sha512-sMZ+lZbDyxwjD2E0L7oRUjJ01Ffjtme5OtjvvnC+cV4CEDcbqzbp25TCpxHj6kWLU9+DlqJOiNgSOgctC2aZmg==", |
| 1401 | "dev": true, | 1443 | "dev": true, | ||
| 1402 | "license": "MIT", | 1444 | "license": "MIT", | ||
| 1403 | "dependencies": { | 1445 | "dependencies": { | ||
| 1404 | "@parcel/watcher": "^2.5.1", | 1446 | "@parcel/watcher": "^2.5.1", | ||
| 1405 | - | "@tailwindcss/node": "4.1.17", | 1447 | + | "@tailwindcss/node": "4.1.18", |
| 1406 | - | "@tailwindcss/oxide": "4.1.17", | 1448 | + | "@tailwindcss/oxide": "4.1.18", |
| 1407 | "enhanced-resolve": "^5.18.3", | 1449 | "enhanced-resolve": "^5.18.3", | ||
| 1408 | "mri": "^1.2.0", | 1450 | "mri": "^1.2.0", | ||
| 1409 | "picocolors": "^1.1.1", | 1451 | "picocolors": "^1.1.1", | ||
| 1410 | - | "tailwindcss": "4.1.17" | 1452 | + | "tailwindcss": "4.1.18" |
| 1411 | }, | 1453 | }, | ||
| 1412 | "bin": { | 1454 | "bin": { | ||
| 1413 | "tailwindcss": "dist/index.mjs" | 1455 | "tailwindcss": "dist/index.mjs" | ||
| 1414 | } | 1456 | } | ||
| 1415 | }, | 1457 | }, | ||
| 1416 | "node_modules/@tailwindcss/node": { | 1458 | "node_modules/@tailwindcss/node": { | ||
| 1417 | - | "version": "4.1.17", | 1459 | + | "version": "4.1.18", |
| 1418 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.17.tgz", | 1460 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", |
| 1419 | - | "integrity": "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==", | 1461 | + | "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", |
| 1420 | "dev": true, | 1462 | "dev": true, | ||
| 1421 | "license": "MIT", | 1463 | "license": "MIT", | ||
| 1422 | "dependencies": { | 1464 | "dependencies": { | ||
| @@ -1426,37 +1468,37 @@ | |||||
| 1426 | "lightningcss": "1.30.2", | 1468 | "lightningcss": "1.30.2", | ||
| 1427 | "magic-string": "^0.30.21", | 1469 | "magic-string": "^0.30.21", | ||
| 1428 | "source-map-js": "^1.2.1", | 1470 | "source-map-js": "^1.2.1", | ||
| 1429 | - | "tailwindcss": "4.1.17" | 1471 | + | "tailwindcss": "4.1.18" |
| 1430 | } | 1472 | } | ||
| 1431 | }, | 1473 | }, | ||
| 1432 | "node_modules/@tailwindcss/oxide": { | 1474 | "node_modules/@tailwindcss/oxide": { | ||
| 1433 | - | "version": "4.1.17", | 1475 | + | "version": "4.1.18", |
| 1434 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.17.tgz", | 1476 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", |
| 1435 | - | "integrity": "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA==", | 1477 | + | "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", |
| 1436 | "dev": true, | 1478 | "dev": true, | ||
| 1437 | "license": "MIT", | 1479 | "license": "MIT", | ||
| 1438 | "engines": { | 1480 | "engines": { | ||
| 1439 | "node": ">= 10" | 1481 | "node": ">= 10" | ||
| 1440 | }, | 1482 | }, | ||
| 1441 | "optionalDependencies": { | 1483 | "optionalDependencies": { | ||
| 1442 | - | "@tailwindcss/oxide-android-arm64": "4.1.17", | 1484 | + | "@tailwindcss/oxide-android-arm64": "4.1.18", |
| 1443 | - | "@tailwindcss/oxide-darwin-arm64": "4.1.17", | 1485 | + | "@tailwindcss/oxide-darwin-arm64": "4.1.18", |
| 1444 | - | "@tailwindcss/oxide-darwin-x64": "4.1.17", | 1486 | + | "@tailwindcss/oxide-darwin-x64": "4.1.18", |
| 1445 | - | "@tailwindcss/oxide-freebsd-x64": "4.1.17", | 1487 | + | "@tailwindcss/oxide-freebsd-x64": "4.1.18", |
| 1446 | - | "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", | 1488 | + | "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", |
| 1447 | - | "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", | 1489 | + | "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", |
| 1448 | - | "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", | 1490 | + | "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", |
| 1449 | - | "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", | 1491 | + | "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", |
| 1450 | - | "@tailwindcss/oxide-linux-x64-musl": "4.1.17", | 1492 | + | "@tailwindcss/oxide-linux-x64-musl": "4.1.18", |
| 1451 | - | "@tailwindcss/oxide-wasm32-wasi": "4.1.17", | 1493 | + | "@tailwindcss/oxide-wasm32-wasi": "4.1.18", |
| 1452 | - | "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", | 1494 | + | "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", |
| 1453 | - | "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" | 1495 | + | "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" |
| 1454 | } | 1496 | } | ||
| 1455 | }, | 1497 | }, | ||
| 1456 | "node_modules/@tailwindcss/oxide-android-arm64": { | 1498 | "node_modules/@tailwindcss/oxide-android-arm64": { | ||
| 1457 | - | "version": "4.1.17", | 1499 | + | "version": "4.1.18", |
| 1458 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.17.tgz", | 1500 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", |
| 1459 | - | "integrity": "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==", | 1501 | + | "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", |
| 1460 | "cpu": [ | 1502 | "cpu": [ | ||
| 1461 | "arm64" | 1503 | "arm64" | ||
| 1462 | ], | 1504 | ], | ||
| @@ -1471,9 +1513,9 @@ | |||||
| 1471 | } | 1513 | } | ||
| 1472 | }, | 1514 | }, | ||
| 1473 | "node_modules/@tailwindcss/oxide-darwin-arm64": { | 1515 | "node_modules/@tailwindcss/oxide-darwin-arm64": { | ||
| 1474 | - | "version": "4.1.17", | 1516 | + | "version": "4.1.18", |
| 1475 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.17.tgz", | 1517 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", |
| 1476 | - | "integrity": "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==", | 1518 | + | "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", |
| 1477 | "cpu": [ | 1519 | "cpu": [ | ||
| 1478 | "arm64" | 1520 | "arm64" | ||
| 1479 | ], | 1521 | ], | ||
| @@ -1488,9 +1530,9 @@ | |||||
| 1488 | } | 1530 | } | ||
| 1489 | }, | 1531 | }, | ||
| 1490 | "node_modules/@tailwindcss/oxide-darwin-x64": { | 1532 | "node_modules/@tailwindcss/oxide-darwin-x64": { | ||
| 1491 | - | "version": "4.1.17", | 1533 | + | "version": "4.1.18", |
| 1492 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.17.tgz", | 1534 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", |
| 1493 | - | "integrity": "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==", | 1535 | + | "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", |
| 1494 | "cpu": [ | 1536 | "cpu": [ | ||
| 1495 | "x64" | 1537 | "x64" | ||
| 1496 | ], | 1538 | ], | ||
| @@ -1505,9 +1547,9 @@ | |||||
| 1505 | } | 1547 | } | ||
| 1506 | }, | 1548 | }, | ||
| 1507 | "node_modules/@tailwindcss/oxide-freebsd-x64": { | 1549 | "node_modules/@tailwindcss/oxide-freebsd-x64": { | ||
| 1508 | - | "version": "4.1.17", | 1550 | + | "version": "4.1.18", |
| 1509 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.17.tgz", | 1551 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", |
| 1510 | - | "integrity": "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==", | 1552 | + | "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", |
| 1511 | "cpu": [ | 1553 | "cpu": [ | ||
| 1512 | "x64" | 1554 | "x64" | ||
| 1513 | ], | 1555 | ], | ||
| @@ -1522,9 +1564,9 @@ | |||||
| 1522 | } | 1564 | } | ||
| 1523 | }, | 1565 | }, | ||
| 1524 | "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { | 1566 | "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { | ||
| 1525 | - | "version": "4.1.17", | 1567 | + | "version": "4.1.18", |
| 1526 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.17.tgz", | 1568 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", |
| 1527 | - | "integrity": "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==", | 1569 | + | "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", |
| 1528 | "cpu": [ | 1570 | "cpu": [ | ||
| 1529 | "arm" | 1571 | "arm" | ||
| 1530 | ], | 1572 | ], | ||
| @@ -1539,9 +1581,9 @@ | |||||
| 1539 | } | 1581 | } | ||
| 1540 | }, | 1582 | }, | ||
| 1541 | "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { | 1583 | "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { | ||
| 1542 | - | "version": "4.1.17", | 1584 | + | "version": "4.1.18", |
| 1543 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.17.tgz", | 1585 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", |
| 1544 | - | "integrity": "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==", | 1586 | + | "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", |
| 1545 | "cpu": [ | 1587 | "cpu": [ | ||
| 1546 | "arm64" | 1588 | "arm64" | ||
| 1547 | ], | 1589 | ], | ||
| @@ -1556,9 +1598,9 @@ | |||||
| 1556 | } | 1598 | } | ||
| 1557 | }, | 1599 | }, | ||
| 1558 | "node_modules/@tailwindcss/oxide-linux-arm64-musl": { | 1600 | "node_modules/@tailwindcss/oxide-linux-arm64-musl": { | ||
| 1559 | - | "version": "4.1.17", | 1601 | + | "version": "4.1.18", |
| 1560 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.17.tgz", | 1602 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", |
| 1561 | - | "integrity": "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==", | 1603 | + | "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", |
| 1562 | "cpu": [ | 1604 | "cpu": [ | ||
| 1563 | "arm64" | 1605 | "arm64" | ||
| 1564 | ], | 1606 | ], | ||
| @@ -1573,9 +1615,9 @@ | |||||
| 1573 | } | 1615 | } | ||
| 1574 | }, | 1616 | }, | ||
| 1575 | "node_modules/@tailwindcss/oxide-linux-x64-gnu": { | 1617 | "node_modules/@tailwindcss/oxide-linux-x64-gnu": { | ||
| 1576 | - | "version": "4.1.17", | 1618 | + | "version": "4.1.18", |
| 1577 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.17.tgz", | 1619 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", |
| 1578 | - | "integrity": "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==", | 1620 | + | "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", |
| 1579 | "cpu": [ | 1621 | "cpu": [ | ||
| 1580 | "x64" | 1622 | "x64" | ||
| 1581 | ], | 1623 | ], | ||
| @@ -1590,9 +1632,9 @@ | |||||
| 1590 | } | 1632 | } | ||
| 1591 | }, | 1633 | }, | ||
| 1592 | "node_modules/@tailwindcss/oxide-linux-x64-musl": { | 1634 | "node_modules/@tailwindcss/oxide-linux-x64-musl": { | ||
| 1593 | - | "version": "4.1.17", | 1635 | + | "version": "4.1.18", |
| 1594 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.17.tgz", | 1636 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", |
| 1595 | - | "integrity": "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==", | 1637 | + | "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", |
| 1596 | "cpu": [ | 1638 | "cpu": [ | ||
| 1597 | "x64" | 1639 | "x64" | ||
| 1598 | ], | 1640 | ], | ||
| @@ -1607,9 +1649,9 @@ | |||||
| 1607 | } | 1649 | } | ||
| 1608 | }, | 1650 | }, | ||
| 1609 | "node_modules/@tailwindcss/oxide-wasm32-wasi": { | 1651 | "node_modules/@tailwindcss/oxide-wasm32-wasi": { | ||
| 1610 | - | "version": "4.1.17", | 1652 | + | "version": "4.1.18", |
| 1611 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.17.tgz", | 1653 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", |
| 1612 | - | "integrity": "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==", | 1654 | + | "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", |
| 1613 | "bundleDependencies": [ | 1655 | "bundleDependencies": [ | ||
| 1614 | "@napi-rs/wasm-runtime", | 1656 | "@napi-rs/wasm-runtime", | ||
| 1615 | "@emnapi/core", | 1657 | "@emnapi/core", | ||
| @@ -1625,10 +1667,10 @@ | |||||
| 1625 | "license": "MIT", | 1667 | "license": "MIT", | ||
| 1626 | "optional": true, | 1668 | "optional": true, | ||
| 1627 | "dependencies": { | 1669 | "dependencies": { | ||
| 1628 | - | "@emnapi/core": "^1.6.0", | 1670 | + | "@emnapi/core": "^1.7.1", |
| 1629 | - | "@emnapi/runtime": "^1.6.0", | 1671 | + | "@emnapi/runtime": "^1.7.1", |
| 1630 | "@emnapi/wasi-threads": "^1.1.0", | 1672 | "@emnapi/wasi-threads": "^1.1.0", | ||
| 1631 | - | "@napi-rs/wasm-runtime": "^1.0.7", | 1673 | + | "@napi-rs/wasm-runtime": "^1.1.0", |
| 1632 | "@tybys/wasm-util": "^0.10.1", | 1674 | "@tybys/wasm-util": "^0.10.1", | ||
| 1633 | "tslib": "^2.4.0" | 1675 | "tslib": "^2.4.0" | ||
| 1634 | }, | 1676 | }, | ||
| @@ -1637,9 +1679,9 @@ | |||||
| 1637 | } | 1679 | } | ||
| 1638 | }, | 1680 | }, | ||
| 1639 | "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { | 1681 | "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { | ||
| 1640 | - | "version": "4.1.17", | 1682 | + | "version": "4.1.18", |
| 1641 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.17.tgz", | 1683 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", |
| 1642 | - | "integrity": "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==", | 1684 | + | "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", |
| 1643 | "cpu": [ | 1685 | "cpu": [ | ||
| 1644 | "arm64" | 1686 | "arm64" | ||
| 1645 | ], | 1687 | ], | ||
| @@ -1654,9 +1696,9 @@ | |||||
| 1654 | } | 1696 | } | ||
| 1655 | }, | 1697 | }, | ||
| 1656 | "node_modules/@tailwindcss/oxide-win32-x64-msvc": { | 1698 | "node_modules/@tailwindcss/oxide-win32-x64-msvc": { | ||
| 1657 | - | "version": "4.1.17", | 1699 | + | "version": "4.1.18", |
| 1658 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.17.tgz", | 1700 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", |
| 1659 | - | "integrity": "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==", | 1701 | + | "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", |
| 1660 | "cpu": [ | 1702 | "cpu": [ | ||
| 1661 | "x64" | 1703 | "x64" | ||
| 1662 | ], | 1704 | ], | ||
| @@ -1671,17 +1713,17 @@ | |||||
| 1671 | } | 1713 | } | ||
| 1672 | }, | 1714 | }, | ||
| 1673 | "node_modules/@tailwindcss/postcss": { | 1715 | "node_modules/@tailwindcss/postcss": { | ||
| 1674 | - | "version": "4.1.17", | 1716 | + | "version": "4.1.18", |
| 1675 | - | "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.17.tgz", | 1717 | + | "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz", |
| 1676 | - | "integrity": "sha512-+nKl9N9mN5uJ+M7dBOOCzINw94MPstNR/GtIhz1fpZysxL/4a+No64jCBD6CPN+bIHWFx3KWuu8XJRrj/572Dw==", | 1718 | + | "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==", |
| 1677 | "dev": true, | 1719 | "dev": true, | ||
| 1678 | "license": "MIT", | 1720 | "license": "MIT", | ||
| 1679 | "dependencies": { | 1721 | "dependencies": { | ||
| 1680 | "@alloc/quick-lru": "^5.2.0", | 1722 | "@alloc/quick-lru": "^5.2.0", | ||
| 1681 | - | "@tailwindcss/node": "4.1.17", | 1723 | + | "@tailwindcss/node": "4.1.18", |
| 1682 | - | "@tailwindcss/oxide": "4.1.17", | 1724 | + | "@tailwindcss/oxide": "4.1.18", |
| 1683 | "postcss": "^8.4.41", | 1725 | "postcss": "^8.4.41", | ||
| 1684 | - | "tailwindcss": "4.1.17" | 1726 | + | "tailwindcss": "4.1.18" |
| 1685 | } | 1727 | } | ||
| 1686 | }, | 1728 | }, | ||
| 1687 | "node_modules/@types/estree": { | 1729 | "node_modules/@types/estree": { | ||
| @@ -1691,9 +1733,9 @@ | |||||
| 1691 | "license": "MIT" | 1733 | "license": "MIT" | ||
| 1692 | }, | 1734 | }, | ||
| 1693 | "node_modules/@types/node": { | 1735 | "node_modules/@types/node": { | ||
| 1694 | - | "version": "20.19.25", | 1736 | + | "version": "20.19.30", |
| 1695 | - | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", | 1737 | + | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", |
| 1696 | - | "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", | 1738 | + | "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", |
| 1697 | "dev": true, | 1739 | "dev": true, | ||
| 1698 | "license": "MIT", | 1740 | "license": "MIT", | ||
| 1699 | "peer": true, | 1741 | "peer": true, | ||
| @@ -1766,15 +1808,15 @@ | |||||
| 1766 | } | 1808 | } | ||
| 1767 | }, | 1809 | }, | ||
| 1768 | "node_modules/@typescript-eslint/project-service": { | 1810 | "node_modules/@typescript-eslint/project-service": { | ||
| 1769 | - | "version": "8.48.1", | 1811 | + | "version": "8.53.1", |
| 1770 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.1.tgz", | 1812 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.1.tgz", |
| 1771 | - | "integrity": "sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==", | 1813 | + | "integrity": "sha512-WYC4FB5Ra0xidsmlPb+1SsnaSKPmS3gsjIARwbEkHkoWloQmuzcfypljaJcR78uyLA1h8sHdWWPHSLDI+MtNog==", |
| 1772 | "dev": true, | 1814 | "dev": true, | ||
| 1773 | "license": "MIT", | 1815 | "license": "MIT", | ||
| 1774 | "dependencies": { | 1816 | "dependencies": { | ||
| 1775 | - | "@typescript-eslint/tsconfig-utils": "^8.48.1", | 1817 | + | "@typescript-eslint/tsconfig-utils": "^8.53.1", |
| 1776 | - | "@typescript-eslint/types": "^8.48.1", | 1818 | + | "@typescript-eslint/types": "^8.53.1", |
| 1777 | - | "debug": "^4.3.4" | 1819 | + | "debug": "^4.4.3" |
| 1778 | }, | 1820 | }, | ||
| 1779 | "engines": { | 1821 | "engines": { | ||
| 1780 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | 1822 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||
| @@ -1788,9 +1830,9 @@ | |||||
| 1788 | } | 1830 | } | ||
| 1789 | }, | 1831 | }, | ||
| 1790 | "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { | 1832 | "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { | ||
| 1791 | - | "version": "8.48.1", | 1833 | + | "version": "8.53.1", |
| 1792 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.1.tgz", | 1834 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz", |
| 1793 | - | "integrity": "sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==", | 1835 | + | "integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==", |
| 1794 | "dev": true, | 1836 | "dev": true, | ||
| 1795 | "license": "MIT", | 1837 | "license": "MIT", | ||
| 1796 | "engines": { | 1838 | "engines": { | ||
| @@ -1820,9 +1862,9 @@ | |||||
| 1820 | } | 1862 | } | ||
| 1821 | }, | 1863 | }, | ||
| 1822 | "node_modules/@typescript-eslint/tsconfig-utils": { | 1864 | "node_modules/@typescript-eslint/tsconfig-utils": { | ||
| 1823 | - | "version": "8.48.1", | 1865 | + | "version": "8.53.1", |
| 1824 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.1.tgz", | 1866 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.1.tgz", |
| 1825 | - | "integrity": "sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==", | 1867 | + | "integrity": "sha512-qfvLXS6F6b1y43pnf0pPbXJ+YoXIC7HKg0UGZ27uMIemKMKA6XH2DTxsEDdpdN29D+vHV07x/pnlPNVLhdhWiA==", |
| 1826 | "dev": true, | 1868 | "dev": true, | ||
| 1827 | "license": "MIT", | 1869 | "license": "MIT", | ||
| 1828 | "engines": { | 1870 | "engines": { | ||
| @@ -2048,9 +2090,9 @@ | |||||
| 2048 | } | 2090 | } | ||
| 2049 | }, | 2091 | }, | ||
| 2050 | "node_modules/autoprefixer": { | 2092 | "node_modules/autoprefixer": { | ||
| 2051 | - | "version": "10.4.22", | 2093 | + | "version": "10.4.23", |
| 2052 | - | "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.22.tgz", | 2094 | + | "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", |
| 2053 | - | "integrity": "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==", | 2095 | + | "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", |
| 2054 | "dev": true, | 2096 | "dev": true, | ||
| 2055 | "funding": [ | 2097 | "funding": [ | ||
| 2056 | { | 2098 | { | ||
| @@ -2068,10 +2110,9 @@ | |||||
| 2068 | ], | 2110 | ], | ||
| 2069 | "license": "MIT", | 2111 | "license": "MIT", | ||
| 2070 | "dependencies": { | 2112 | "dependencies": { | ||
| 2071 | - | "browserslist": "^4.27.0", | 2113 | + | "browserslist": "^4.28.1", |
| 2072 | - | "caniuse-lite": "^1.0.30001754", | 2114 | + | "caniuse-lite": "^1.0.30001760", |
| 2073 | "fraction.js": "^5.3.4", | 2115 | "fraction.js": "^5.3.4", | ||
| 2074 | - | "normalize-range": "^0.1.2", | |||
| 2075 | "picocolors": "^1.1.1", | 2116 | "picocolors": "^1.1.1", | ||
| 2076 | "postcss-value-parser": "^4.2.0" | 2117 | "postcss-value-parser": "^4.2.0" | ||
| 2077 | }, | 2118 | }, | ||
| @@ -2102,9 +2143,9 @@ | |||||
| 2102 | "license": "MIT" | 2143 | "license": "MIT" | ||
| 2103 | }, | 2144 | }, | ||
| 2104 | "node_modules/baseline-browser-mapping": { | 2145 | "node_modules/baseline-browser-mapping": { | ||
| 2105 | - | "version": "2.9.3", | 2146 | + | "version": "2.9.17", |
| 2106 | - | "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.3.tgz", | 2147 | + | "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.17.tgz", |
| 2107 | - | "integrity": "sha512-8QdH6czo+G7uBsNo0GiUfouPN1lRzKdJTGnKXwe12gkFbnnOUaUKGN55dMkfy+mnxmvjwl9zcI4VncczcVXDhA==", | 2148 | + | "integrity": "sha512-agD0MgJFUP/4nvjqzIB29zRPUuCF7Ge6mEv9s8dHrtYD7QWXRcx75rOADE/d5ah1NI+0vkDl0yorDd5U852IQQ==", |
| 2108 | "dev": true, | 2149 | "dev": true, | ||
| 2109 | "license": "Apache-2.0", | 2150 | "license": "Apache-2.0", | ||
| 2110 | "bin": { | 2151 | "bin": { | ||
| @@ -2112,9 +2153,9 @@ | |||||
| 2112 | } | 2153 | } | ||
| 2113 | }, | 2154 | }, | ||
| 2114 | "node_modules/bits-ui": { | 2155 | "node_modules/bits-ui": { | ||
| 2115 | - | "version": "2.14.4", | 2156 | + | "version": "2.15.4", |
| 2116 | - | "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.14.4.tgz", | 2157 | + | "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.15.4.tgz", |
| 2117 | - | "integrity": "sha512-W6kenhnbd/YVvur+DKkaVJ6GldE53eLewur5AhUCqslYQ0vjZr8eWlOfwZnMiPB+PF5HMVqf61vXBvmyrAmPWg==", | 2158 | + | "integrity": "sha512-7H9YUfp03KOk1LVDh8wPYSRPxlZgG/GRWLNSA8QC73/8Z8ytun+DWJhIuibyFyz7A0cP/RANVcB4iDrbY8q+Og==", |
| 2118 | "license": "MIT", | 2159 | "license": "MIT", | ||
| 2119 | "dependencies": { | 2160 | "dependencies": { | ||
| 2120 | "@floating-ui/core": "^1.7.1", | 2161 | "@floating-ui/core": "^1.7.1", | ||
| @@ -2204,9 +2245,9 @@ | |||||
| 2204 | } | 2245 | } | ||
| 2205 | }, | 2246 | }, | ||
| 2206 | "node_modules/caniuse-lite": { | 2247 | "node_modules/caniuse-lite": { | ||
| 2207 | - | "version": "1.0.30001759", | 2248 | + | "version": "1.0.30001766", |
| 2208 | - | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz", | 2249 | + | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", |
| 2209 | - | "integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==", | 2250 | + | "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", |
| 2210 | "dev": true, | 2251 | "dev": true, | ||
| 2211 | "funding": [ | 2252 | "funding": [ | ||
| 2212 | { | 2253 | { | ||
| @@ -2360,22 +2401,19 @@ | |||||
| 2360 | } | 2401 | } | ||
| 2361 | }, | 2402 | }, | ||
| 2362 | "node_modules/detect-libc": { | 2403 | "node_modules/detect-libc": { | ||
| 2363 | - | "version": "1.0.3", | 2404 | + | "version": "2.1.2", |
| 2364 | - | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", | 2405 | + | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", |
| 2365 | - | "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", | 2406 | + | "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", |
| 2366 | "dev": true, | 2407 | "dev": true, | ||
| 2367 | "license": "Apache-2.0", | 2408 | "license": "Apache-2.0", | ||
| 2368 | - | "bin": { | |||
| 2369 | - | "detect-libc": "bin/detect-libc.js" | |||
| 2370 | - | }, | |||
| 2371 | "engines": { | 2409 | "engines": { | ||
| 2372 | - | "node": ">=0.10" | 2410 | + | "node": ">=8" |
| 2373 | } | 2411 | } | ||
| 2374 | }, | 2412 | }, | ||
| 2375 | "node_modules/devalue": { | 2413 | "node_modules/devalue": { | ||
| 2376 | - | "version": "5.5.0", | 2414 | + | "version": "5.6.2", |
| 2377 | - | "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.5.0.tgz", | 2415 | + | "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz", |
| 2378 | - | "integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==", | 2416 | + | "integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==", |
| 2379 | "license": "MIT" | 2417 | "license": "MIT" | ||
| 2380 | }, | 2418 | }, | ||
| 2381 | "node_modules/dir-glob": { | 2419 | "node_modules/dir-glob": { | ||
| @@ -2405,16 +2443,16 @@ | |||||
| 2405 | } | 2443 | } | ||
| 2406 | }, | 2444 | }, | ||
| 2407 | "node_modules/electron-to-chromium": { | 2445 | "node_modules/electron-to-chromium": { | ||
| 2408 | - | "version": "1.5.266", | 2446 | + | "version": "1.5.277", |
| 2409 | - | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.266.tgz", | 2447 | + | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.277.tgz", |
| 2410 | - | "integrity": "sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==", | 2448 | + | "integrity": "sha512-wKXFZw4erWmmOz5N/grBoJ2XrNJGDFMu2+W5ACHza5rHtvsqrK4gb6rnLC7XxKB9WlJ+RmyQatuEXmtm86xbnw==", |
| 2411 | "dev": true, | 2449 | "dev": true, | ||
| 2412 | "license": "ISC" | 2450 | "license": "ISC" | ||
| 2413 | }, | 2451 | }, | ||
| 2414 | "node_modules/enhanced-resolve": { | 2452 | "node_modules/enhanced-resolve": { | ||
| 2415 | - | "version": "5.18.3", | 2453 | + | "version": "5.18.4", |
| 2416 | - | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", | 2454 | + | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", |
| 2417 | - | "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", | 2455 | + | "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", |
| 2418 | "dev": true, | 2456 | "dev": true, | ||
| 2419 | "license": "MIT", | 2457 | "license": "MIT", | ||
| 2420 | "dependencies": { | 2458 | "dependencies": { | ||
| @@ -2624,9 +2662,9 @@ | |||||
| 2624 | } | 2662 | } | ||
| 2625 | }, | 2663 | }, | ||
| 2626 | "node_modules/esquery": { | 2664 | "node_modules/esquery": { | ||
| 2627 | - | "version": "1.6.0", | 2665 | + | "version": "1.7.0", |
| 2628 | - | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", | 2666 | + | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", |
| 2629 | - | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", | 2667 | + | "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", |
| 2630 | "dev": true, | 2668 | "dev": true, | ||
| 2631 | "license": "BSD-3-Clause", | 2669 | "license": "BSD-3-Clause", | ||
| 2632 | "dependencies": { | 2670 | "dependencies": { | ||
| @@ -2637,9 +2675,9 @@ | |||||
| 2637 | } | 2675 | } | ||
| 2638 | }, | 2676 | }, | ||
| 2639 | "node_modules/esrap": { | 2677 | "node_modules/esrap": { | ||
| 2640 | - | "version": "2.2.1", | 2678 | + | "version": "2.2.2", |
| 2641 | - | "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.1.tgz", | 2679 | + | "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.2.tgz", |
| 2642 | - | "integrity": "sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==", | 2680 | + | "integrity": "sha512-zA6497ha+qKvoWIK+WM9NAh5ni17sKZKhbS5B3PoYbBvaYHZWoS33zmFybmyqpn07RLUxSmn+RCls2/XF+d0oQ==", |
| 2643 | "license": "MIT", | 2681 | "license": "MIT", | ||
| 2644 | "dependencies": { | 2682 | "dependencies": { | ||
| 2645 | "@jridgewell/sourcemap-codec": "^1.4.15" | 2683 | "@jridgewell/sourcemap-codec": "^1.4.15" | ||
| @@ -2730,15 +2768,33 @@ | |||||
| 2730 | "license": "MIT" | 2768 | "license": "MIT" | ||
| 2731 | }, | 2769 | }, | ||
| 2732 | "node_modules/fastq": { | 2770 | "node_modules/fastq": { | ||
| 2733 | - | "version": "1.19.1", | 2771 | + | "version": "1.20.1", |
| 2734 | - | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", | 2772 | + | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", |
| 2735 | - | "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", | 2773 | + | "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", |
| 2736 | "dev": true, | 2774 | "dev": true, | ||
| 2737 | "license": "ISC", | 2775 | "license": "ISC", | ||
| 2738 | "dependencies": { | 2776 | "dependencies": { | ||
| 2739 | "reusify": "^1.0.4" | 2777 | "reusify": "^1.0.4" | ||
| 2740 | } | 2778 | } | ||
| 2741 | }, | 2779 | }, | ||
| 2780 | + | "node_modules/fdir": { | |||
| 2781 | + | "version": "6.5.0", | |||
| 2782 | + | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", | |||
| 2783 | + | "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", | |||
| 2784 | + | "dev": true, | |||
| 2785 | + | "license": "MIT", | |||
| 2786 | + | "engines": { | |||
| 2787 | + | "node": ">=12.0.0" | |||
| 2788 | + | }, | |||
| 2789 | + | "peerDependencies": { | |||
| 2790 | + | "picomatch": "^3 || ^4" | |||
| 2791 | + | }, | |||
| 2792 | + | "peerDependenciesMeta": { | |||
| 2793 | + | "picomatch": { | |||
| 2794 | + | "optional": true | |||
| 2795 | + | } | |||
| 2796 | + | } | |||
| 2797 | + | }, | |||
| 2742 | "node_modules/file-entry-cache": { | 2798 | "node_modules/file-entry-cache": { | ||
| 2743 | "version": "6.0.1", | 2799 | "version": "6.0.1", | ||
| 2744 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", | 2800 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", | ||
| @@ -3426,16 +3482,6 @@ | |||||
| 3426 | "url": "https://opencollective.com/parcel" | 3482 | "url": "https://opencollective.com/parcel" | ||
| 3427 | } | 3483 | } | ||
| 3428 | }, | 3484 | }, | ||
| 3429 | - | "node_modules/lightningcss/node_modules/detect-libc": { | |||
| 3430 | - | "version": "2.1.2", | |||
| 3431 | - | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", | |||
| 3432 | - | "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", | |||
| 3433 | - | "dev": true, | |||
| 3434 | - | "license": "Apache-2.0", | |||
| 3435 | - | "engines": { | |||
| 3436 | - | "node": ">=8" | |||
| 3437 | - | } | |||
| 3438 | - | }, | |||
| 3439 | "node_modules/locate-character": { | 3485 | "node_modules/locate-character": { | ||
| 3440 | "version": "3.0.0", | 3486 | "version": "3.0.0", | ||
| 3441 | "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", | 3487 | "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", | ||
| @@ -3507,6 +3553,19 @@ | |||||
| 3507 | "node": ">=8.6" | 3553 | "node": ">=8.6" | ||
| 3508 | } | 3554 | } | ||
| 3509 | }, | 3555 | }, | ||
| 3556 | + | "node_modules/micromatch/node_modules/picomatch": { | |||
| 3557 | + | "version": "2.3.1", | |||
| 3558 | + | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", | |||
| 3559 | + | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", | |||
| 3560 | + | "dev": true, | |||
| 3561 | + | "license": "MIT", | |||
| 3562 | + | "engines": { | |||
| 3563 | + | "node": ">=8.6" | |||
| 3564 | + | }, | |||
| 3565 | + | "funding": { | |||
| 3566 | + | "url": "https://github.com/sponsors/jonschlinkert" | |||
| 3567 | + | } | |||
| 3568 | + | }, | |||
| 3510 | "node_modules/minimatch": { | 3569 | "node_modules/minimatch": { | ||
| 3511 | "version": "9.0.5", | 3570 | "version": "9.0.5", | ||
| 3512 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", | 3571 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", | ||
| @@ -3643,16 +3702,6 @@ | |||||
| 3643 | "dev": true, | 3702 | "dev": true, | ||
| 3644 | "license": "MIT" | 3703 | "license": "MIT" | ||
| 3645 | }, | 3704 | }, | ||
| 3646 | - | "node_modules/normalize-range": { | |||
| 3647 | - | "version": "0.1.2", | |||
| 3648 | - | "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", | |||
| 3649 | - | "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", | |||
| 3650 | - | "dev": true, | |||
| 3651 | - | "license": "MIT", | |||
| 3652 | - | "engines": { | |||
| 3653 | - | "node": ">=0.10.0" | |||
| 3654 | - | } | |||
| 3655 | - | }, | |||
| 3656 | "node_modules/once": { | 3705 | "node_modules/once": { | ||
| 3657 | "version": "1.4.0", | 3706 | "version": "1.4.0", | ||
| 3658 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", | 3707 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", | ||
| @@ -3774,13 +3823,13 @@ | |||||
| 3774 | "license": "ISC" | 3823 | "license": "ISC" | ||
| 3775 | }, | 3824 | }, | ||
| 3776 | "node_modules/picomatch": { | 3825 | "node_modules/picomatch": { | ||
| 3777 | - | "version": "2.3.1", | 3826 | + | "version": "4.0.3", |
| 3778 | - | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", | 3827 | + | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", |
| 3779 | - | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", | 3828 | + | "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", |
| 3780 | "dev": true, | 3829 | "dev": true, | ||
| 3781 | "license": "MIT", | 3830 | "license": "MIT", | ||
| 3782 | "engines": { | 3831 | "engines": { | ||
| 3783 | - | "node": ">=8.6" | 3832 | + | "node": ">=12" |
| 3784 | }, | 3833 | }, | ||
| 3785 | "funding": { | 3834 | "funding": { | ||
| 3786 | "url": "https://github.com/sponsors/jonschlinkert" | 3835 | "url": "https://github.com/sponsors/jonschlinkert" | ||
| @@ -3917,9 +3966,9 @@ | |||||
| 3917 | } | 3966 | } | ||
| 3918 | }, | 3967 | }, | ||
| 3919 | "node_modules/rollup": { | 3968 | "node_modules/rollup": { | ||
| 3920 | - | "version": "4.53.3", | 3969 | + | "version": "4.56.0", |
| 3921 | - | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", | 3970 | + | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.56.0.tgz", |
| 3922 | - | "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", | 3971 | + | "integrity": "sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==", |
| 3923 | "dev": true, | 3972 | "dev": true, | ||
| 3924 | "license": "MIT", | 3973 | "license": "MIT", | ||
| 3925 | "dependencies": { | 3974 | "dependencies": { | ||
| @@ -3933,28 +3982,31 @@ | |||||
| 3933 | "npm": ">=8.0.0" | 3982 | "npm": ">=8.0.0" | ||
| 3934 | }, | 3983 | }, | ||
| 3935 | "optionalDependencies": { | 3984 | "optionalDependencies": { | ||
| 3936 | - | "@rollup/rollup-android-arm-eabi": "4.53.3", | 3985 | + | "@rollup/rollup-android-arm-eabi": "4.56.0", |
| 3937 | - | "@rollup/rollup-android-arm64": "4.53.3", | 3986 | + | "@rollup/rollup-android-arm64": "4.56.0", |
| 3938 | - | "@rollup/rollup-darwin-arm64": "4.53.3", | 3987 | + | "@rollup/rollup-darwin-arm64": "4.56.0", |
| 3939 | - | "@rollup/rollup-darwin-x64": "4.53.3", | 3988 | + | "@rollup/rollup-darwin-x64": "4.56.0", |
| 3940 | - | "@rollup/rollup-freebsd-arm64": "4.53.3", | 3989 | + | "@rollup/rollup-freebsd-arm64": "4.56.0", |
| 3941 | - | "@rollup/rollup-freebsd-x64": "4.53.3", | 3990 | + | "@rollup/rollup-freebsd-x64": "4.56.0", |
| 3942 | - | "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", | 3991 | + | "@rollup/rollup-linux-arm-gnueabihf": "4.56.0", |
| 3943 | - | "@rollup/rollup-linux-arm-musleabihf": "4.53.3", | 3992 | + | "@rollup/rollup-linux-arm-musleabihf": "4.56.0", |
| 3944 | - | "@rollup/rollup-linux-arm64-gnu": "4.53.3", | 3993 | + | "@rollup/rollup-linux-arm64-gnu": "4.56.0", |
| 3945 | - | "@rollup/rollup-linux-arm64-musl": "4.53.3", | 3994 | + | "@rollup/rollup-linux-arm64-musl": "4.56.0", |
| 3946 | - | "@rollup/rollup-linux-loong64-gnu": "4.53.3", | 3995 | + | "@rollup/rollup-linux-loong64-gnu": "4.56.0", |
| 3947 | - | "@rollup/rollup-linux-ppc64-gnu": "4.53.3", | 3996 | + | "@rollup/rollup-linux-loong64-musl": "4.56.0", |
| 3948 | - | "@rollup/rollup-linux-riscv64-gnu": "4.53.3", | 3997 | + | "@rollup/rollup-linux-ppc64-gnu": "4.56.0", |
| 3949 | - | "@rollup/rollup-linux-riscv64-musl": "4.53.3", | 3998 | + | "@rollup/rollup-linux-ppc64-musl": "4.56.0", |
| 3950 | - | "@rollup/rollup-linux-s390x-gnu": "4.53.3", | 3999 | + | "@rollup/rollup-linux-riscv64-gnu": "4.56.0", |
| 3951 | - | "@rollup/rollup-linux-x64-gnu": "4.53.3", | 4000 | + | "@rollup/rollup-linux-riscv64-musl": "4.56.0", |
| 3952 | - | "@rollup/rollup-linux-x64-musl": "4.53.3", | 4001 | + | "@rollup/rollup-linux-s390x-gnu": "4.56.0", |
| 3953 | - | "@rollup/rollup-openharmony-arm64": "4.53.3", | 4002 | + | "@rollup/rollup-linux-x64-gnu": "4.56.0", |
| 3954 | - | "@rollup/rollup-win32-arm64-msvc": "4.53.3", | 4003 | + | "@rollup/rollup-linux-x64-musl": "4.56.0", |
| 3955 | - | "@rollup/rollup-win32-ia32-msvc": "4.53.3", | 4004 | + | "@rollup/rollup-openbsd-x64": "4.56.0", |
| 3956 | - | "@rollup/rollup-win32-x64-gnu": "4.53.3", | 4005 | + | "@rollup/rollup-openharmony-arm64": "4.56.0", |
| 3957 | - | "@rollup/rollup-win32-x64-msvc": "4.53.3", | 4006 | + | "@rollup/rollup-win32-arm64-msvc": "4.56.0", |
| 4007 | + | "@rollup/rollup-win32-ia32-msvc": "4.56.0", | |||
| 4008 | + | "@rollup/rollup-win32-x64-gnu": "4.56.0", | |||
| 4009 | + | "@rollup/rollup-win32-x64-msvc": "4.56.0", | |||
| 3958 | "fsevents": "~2.3.2" | 4010 | "fsevents": "~2.3.2" | ||
| 3959 | } | 4011 | } | ||
| 3960 | }, | 4012 | }, | ||
| @@ -4124,9 +4176,9 @@ | |||||
| 4124 | } | 4176 | } | ||
| 4125 | }, | 4177 | }, | ||
| 4126 | "node_modules/svelte": { | 4178 | "node_modules/svelte": { | ||
| 4127 | - | "version": "5.45.5", | 4179 | + | "version": "5.48.0", |
| 4128 | - | "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.45.5.tgz", | 4180 | + | "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.48.0.tgz", |
| 4129 | - | "integrity": "sha512-2074U+vObO5Zs8/qhxtBwdi6ZXNIhEBTzNmUFjiZexLxTdt9vq96D/0pnQELl6YcpLMD7pZ2dhXKByfGS8SAdg==", | 4181 | + | "integrity": "sha512-+NUe82VoFP1RQViZI/esojx70eazGF4u0O/9ucqZ4rPcOZD+n5EVp17uYsqwdzjUjZyTpGKunHbDziW6AIAVkQ==", |
| 4130 | "license": "MIT", | 4182 | "license": "MIT", | ||
| 4131 | "peer": true, | 4183 | "peer": true, | ||
| 4132 | "dependencies": { | 4184 | "dependencies": { | ||
| @@ -4138,7 +4190,7 @@ | |||||
| 4138 | "aria-query": "^5.3.1", | 4190 | "aria-query": "^5.3.1", | ||
| 4139 | "axobject-query": "^4.1.0", | 4191 | "axobject-query": "^4.1.0", | ||
| 4140 | "clsx": "^2.1.1", | 4192 | "clsx": "^2.1.1", | ||
| 4141 | - | "devalue": "^5.5.0", | 4193 | + | "devalue": "^5.6.2", |
| 4142 | "esm-env": "^1.2.1", | 4194 | "esm-env": "^1.2.1", | ||
| 4143 | "esrap": "^2.2.1", | 4195 | "esrap": "^2.2.1", | ||
| 4144 | "is-reference": "^3.0.3", | 4196 | "is-reference": "^3.0.3", | ||
| @@ -4151,15 +4203,18 @@ | |||||
| 4151 | } | 4203 | } | ||
| 4152 | }, | 4204 | }, | ||
| 4153 | "node_modules/svelte-awesome-color-picker": { | 4205 | "node_modules/svelte-awesome-color-picker": { | ||
| 4154 | - | "version": "4.1.0", | 4206 | + | "version": "4.1.1", |
| 4155 | - | "resolved": "https://registry.npmjs.org/svelte-awesome-color-picker/-/svelte-awesome-color-picker-4.1.0.tgz", | 4207 | + | "resolved": "https://registry.npmjs.org/svelte-awesome-color-picker/-/svelte-awesome-color-picker-4.1.1.tgz", |
| 4156 | - | "integrity": "sha512-afiSB3eTBlqu96f4+rjBvqG3eCaLwuneNYHe587Wr4Ien6yQWeztGZunPT0FmiI7wFFBVNUlJQLYutII8LfQUg==", | 4208 | + | "integrity": "sha512-k4APFGBFN8EpvUS0UJfdlqj8xDekMbqGBwnDYBK1QCY8kcTXSO8c7SitEk70MkiYOIByOgXlHcjaipy6H7dpAw==", |
| 4157 | "dev": true, | 4209 | "dev": true, | ||
| 4158 | "license": "MIT", | 4210 | "license": "MIT", | ||
| 4159 | "dependencies": { | 4211 | "dependencies": { | ||
| 4160 | "colord": "^2.9.3", | 4212 | "colord": "^2.9.3", | ||
| 4161 | "svelte-awesome-slider": "2.0.0" | 4213 | "svelte-awesome-slider": "2.0.0" | ||
| 4162 | }, | 4214 | }, | ||
| 4215 | + | "engines": { | |||
| 4216 | + | "node": ">=24" | |||
| 4217 | + | }, | |||
| 4163 | "peerDependencies": { | 4218 | "peerDependencies": { | ||
| 4164 | "svelte": "^5.0.0" | 4219 | "svelte": "^5.0.0" | ||
| 4165 | } | 4220 | } | ||
| @@ -4175,9 +4230,9 @@ | |||||
| 4175 | } | 4230 | } | ||
| 4176 | }, | 4231 | }, | ||
| 4177 | "node_modules/svelte-check": { | 4232 | "node_modules/svelte-check": { | ||
| 4178 | - | "version": "4.3.4", | 4233 | + | "version": "4.3.5", |
| 4179 | - | "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.4.tgz", | 4234 | + | "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.5.tgz", |
| 4180 | - | "integrity": "sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==", | 4235 | + | "integrity": "sha512-e4VWZETyXaKGhpkxOXP+B/d0Fp/zKViZoJmneZWe/05Y2aqSKj3YN2nLfYPJBQ87WEiY4BQCQ9hWGu9mPT1a1Q==", |
| 4181 | "dev": true, | 4236 | "dev": true, | ||
| 4182 | "license": "MIT", | 4237 | "license": "MIT", | ||
| 4183 | "dependencies": { | 4238 | "dependencies": { | ||
| @@ -4198,24 +4253,6 @@ | |||||
| 4198 | "typescript": ">=5.0.0" | 4253 | "typescript": ">=5.0.0" | ||
| 4199 | } | 4254 | } | ||
| 4200 | }, | 4255 | }, | ||
| 4201 | - | "node_modules/svelte-check/node_modules/fdir": { | |||
| 4202 | - | "version": "6.5.0", | |||
| 4203 | - | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", | |||
| 4204 | - | "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", | |||
| 4205 | - | "dev": true, | |||
| 4206 | - | "license": "MIT", | |||
| 4207 | - | "engines": { | |||
| 4208 | - | "node": ">=12.0.0" | |||
| 4209 | - | }, | |||
| 4210 | - | "peerDependencies": { | |||
| 4211 | - | "picomatch": "^3 || ^4" | |||
| 4212 | - | }, | |||
| 4213 | - | "peerDependenciesMeta": { | |||
| 4214 | - | "picomatch": { | |||
| 4215 | - | "optional": true | |||
| 4216 | - | } | |||
| 4217 | - | } | |||
| 4218 | - | }, | |||
| 4219 | "node_modules/svelte-toolbelt": { | 4256 | "node_modules/svelte-toolbelt": { | ||
| 4220 | "version": "0.10.6", | 4257 | "version": "0.10.6", | ||
| 4221 | "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.10.6.tgz", | 4258 | "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.10.6.tgz", | ||
| @@ -4237,9 +4274,9 @@ | |||||
| 4237 | } | 4274 | } | ||
| 4238 | }, | 4275 | }, | ||
| 4239 | "node_modules/tabbable": { | 4276 | "node_modules/tabbable": { | ||
| 4240 | - | "version": "6.3.0", | 4277 | + | "version": "6.4.0", |
| 4241 | - | "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz", | 4278 | + | "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", |
| 4242 | - | "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==", | 4279 | + | "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", |
| 4243 | "license": "MIT" | 4280 | "license": "MIT" | ||
| 4244 | }, | 4281 | }, | ||
| 4245 | "node_modules/tailwind-merge": { | 4282 | "node_modules/tailwind-merge": { | ||
| @@ -4274,9 +4311,9 @@ | |||||
| 4274 | } | 4311 | } | ||
| 4275 | }, | 4312 | }, | ||
| 4276 | "node_modules/tailwindcss": { | 4313 | "node_modules/tailwindcss": { | ||
| 4277 | - | "version": "4.1.17", | 4314 | + | "version": "4.1.18", |
| 4278 | - | "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.17.tgz", | 4315 | + | "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", |
| 4279 | - | "integrity": "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==", | 4316 | + | "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", |
| 4280 | "dev": true, | 4317 | "dev": true, | ||
| 4281 | "license": "MIT", | 4318 | "license": "MIT", | ||
| 4282 | "peer": true | 4319 | "peer": true | ||
| @@ -4319,38 +4356,6 @@ | |||||
| 4319 | "url": "https://github.com/sponsors/SuperchupuDev" | 4356 | "url": "https://github.com/sponsors/SuperchupuDev" | ||
| 4320 | } | 4357 | } | ||
| 4321 | }, | 4358 | }, | ||
| 4322 | - | "node_modules/tinyglobby/node_modules/fdir": { | |||
| 4323 | - | "version": "6.5.0", | |||
| 4324 | - | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", | |||
| 4325 | - | "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", | |||
| 4326 | - | "dev": true, | |||
| 4327 | - | "license": "MIT", | |||
| 4328 | - | "engines": { | |||
| 4329 | - | "node": ">=12.0.0" | |||
| 4330 | - | }, | |||
| 4331 | - | "peerDependencies": { | |||
| 4332 | - | "picomatch": "^3 || ^4" | |||
| 4333 | - | }, | |||
| 4334 | - | "peerDependenciesMeta": { | |||
| 4335 | - | "picomatch": { | |||
| 4336 | - | "optional": true | |||
| 4337 | - | } | |||
| 4338 | - | } | |||
| 4339 | - | }, | |||
| 4340 | - | "node_modules/tinyglobby/node_modules/picomatch": { | |||
| 4341 | - | "version": "4.0.3", | |||
| 4342 | - | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", | |||
| 4343 | - | "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", | |||
| 4344 | - | "dev": true, | |||
| 4345 | - | "license": "MIT", | |||
| 4346 | - | "peer": true, | |||
| 4347 | - | "engines": { | |||
| 4348 | - | "node": ">=12" | |||
| 4349 | - | }, | |||
| 4350 | - | "funding": { | |||
| 4351 | - | "url": "https://github.com/sponsors/jonschlinkert" | |||
| 4352 | - | } | |||
| 4353 | - | }, | |||
| 4354 | "node_modules/to-regex-range": { | 4359 | "node_modules/to-regex-range": { | ||
| 4355 | "version": "5.0.1", | 4360 | "version": "5.0.1", | ||
| 4356 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", | 4361 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", | ||
| @@ -4435,16 +4440,16 @@ | |||||
| 4435 | } | 4440 | } | ||
| 4436 | }, | 4441 | }, | ||
| 4437 | "node_modules/typescript-eslint": { | 4442 | "node_modules/typescript-eslint": { | ||
| 4438 | - | "version": "8.48.1", | 4443 | + | "version": "8.53.1", |
| 4439 | - | "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.48.1.tgz", | 4444 | + | "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.1.tgz", |
| 4440 | - | "integrity": "sha512-FbOKN1fqNoXp1hIl5KYpObVrp0mCn+CLgn479nmu2IsRMrx2vyv74MmsBLVlhg8qVwNFGbXSp8fh1zp8pEoC2A==", | 4445 | + | "integrity": "sha512-gB+EVQfP5RDElh9ittfXlhZJdjSU4jUSTyE2+ia8CYyNvet4ElfaLlAIqDvQV9JPknKx0jQH1racTYe/4LaLSg==", |
| 4441 | "dev": true, | 4446 | "dev": true, | ||
| 4442 | "license": "MIT", | 4447 | "license": "MIT", | ||
| 4443 | "dependencies": { | 4448 | "dependencies": { | ||
| 4444 | - | "@typescript-eslint/eslint-plugin": "8.48.1", | 4449 | + | "@typescript-eslint/eslint-plugin": "8.53.1", |
| 4445 | - | "@typescript-eslint/parser": "8.48.1", | 4450 | + | "@typescript-eslint/parser": "8.53.1", |
| 4446 | - | "@typescript-eslint/typescript-estree": "8.48.1", | 4451 | + | "@typescript-eslint/typescript-estree": "8.53.1", |
| 4447 | - | "@typescript-eslint/utils": "8.48.1" | 4452 | + | "@typescript-eslint/utils": "8.53.1" |
| 4448 | }, | 4453 | }, | ||
| 4449 | "engines": { | 4454 | "engines": { | ||
| 4450 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | 4455 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||
| @@ -4459,21 +4464,20 @@ | |||||
| 4459 | } | 4464 | } | ||
| 4460 | }, | 4465 | }, | ||
| 4461 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { | 4466 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { | ||
| 4462 | - | "version": "8.48.1", | 4467 | + | "version": "8.53.1", |
| 4463 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.48.1.tgz", | 4468 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.1.tgz", |
| 4464 | - | "integrity": "sha512-X63hI1bxl5ohelzr0LY5coufyl0LJNthld+abwxpCoo6Gq+hSqhKwci7MUWkXo67mzgUK6YFByhmaHmUcuBJmA==", | 4469 | + | "integrity": "sha512-cFYYFZ+oQFi6hUnBTbLRXfTJiaQtYE3t4O692agbBl+2Zy+eqSKWtPjhPXJu1G7j4RLjKgeJPDdq3EqOwmX5Ag==", |
| 4465 | "dev": true, | 4470 | "dev": true, | ||
| 4466 | "license": "MIT", | 4471 | "license": "MIT", | ||
| 4467 | "dependencies": { | 4472 | "dependencies": { | ||
| 4468 | - | "@eslint-community/regexpp": "^4.10.0", | 4473 | + | "@eslint-community/regexpp": "^4.12.2", |
| 4469 | - | "@typescript-eslint/scope-manager": "8.48.1", | 4474 | + | "@typescript-eslint/scope-manager": "8.53.1", |
| 4470 | - | "@typescript-eslint/type-utils": "8.48.1", | 4475 | + | "@typescript-eslint/type-utils": "8.53.1", |
| 4471 | - | "@typescript-eslint/utils": "8.48.1", | 4476 | + | "@typescript-eslint/utils": "8.53.1", |
| 4472 | - | "@typescript-eslint/visitor-keys": "8.48.1", | 4477 | + | "@typescript-eslint/visitor-keys": "8.53.1", |
| 4473 | - | "graphemer": "^1.4.0", | 4478 | + | "ignore": "^7.0.5", |
| 4474 | - | "ignore": "^7.0.0", | |||
| 4475 | "natural-compare": "^1.4.0", | 4479 | "natural-compare": "^1.4.0", | ||
| 4476 | - | "ts-api-utils": "^2.1.0" | 4480 | + | "ts-api-utils": "^2.4.0" |
| 4477 | }, | 4481 | }, | ||
| 4478 | "engines": { | 4482 | "engines": { | ||
| 4479 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | 4483 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||
| @@ -4483,24 +4487,24 @@ | |||||
| 4483 | "url": "https://opencollective.com/typescript-eslint" | 4487 | "url": "https://opencollective.com/typescript-eslint" | ||
| 4484 | }, | 4488 | }, | ||
| 4485 | "peerDependencies": { | 4489 | "peerDependencies": { | ||
| 4486 | - | "@typescript-eslint/parser": "^8.48.1", | 4490 | + | "@typescript-eslint/parser": "^8.53.1", |
| 4487 | "eslint": "^8.57.0 || ^9.0.0", | 4491 | "eslint": "^8.57.0 || ^9.0.0", | ||
| 4488 | "typescript": ">=4.8.4 <6.0.0" | 4492 | "typescript": ">=4.8.4 <6.0.0" | ||
| 4489 | } | 4493 | } | ||
| 4490 | }, | 4494 | }, | ||
| 4491 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { | 4495 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { | ||
| 4492 | - | "version": "8.48.1", | 4496 | + | "version": "8.53.1", |
| 4493 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.1.tgz", | 4497 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.1.tgz", |
| 4494 | - | "integrity": "sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA==", | 4498 | + | "integrity": "sha512-nm3cvFN9SqZGXjmw5bZ6cGmvJSyJPn0wU9gHAZZHDnZl2wF9PhHv78Xf06E0MaNk4zLVHL8hb2/c32XvyJOLQg==", |
| 4495 | "dev": true, | 4499 | "dev": true, | ||
| 4496 | "license": "MIT", | 4500 | "license": "MIT", | ||
| 4497 | "peer": true, | 4501 | "peer": true, | ||
| 4498 | "dependencies": { | 4502 | "dependencies": { | ||
| 4499 | - | "@typescript-eslint/scope-manager": "8.48.1", | 4503 | + | "@typescript-eslint/scope-manager": "8.53.1", |
| 4500 | - | "@typescript-eslint/types": "8.48.1", | 4504 | + | "@typescript-eslint/types": "8.53.1", |
| 4501 | - | "@typescript-eslint/typescript-estree": "8.48.1", | 4505 | + | "@typescript-eslint/typescript-estree": "8.53.1", |
| 4502 | - | "@typescript-eslint/visitor-keys": "8.48.1", | 4506 | + | "@typescript-eslint/visitor-keys": "8.53.1", |
| 4503 | - | "debug": "^4.3.4" | 4507 | + | "debug": "^4.4.3" |
| 4504 | }, | 4508 | }, | ||
| 4505 | "engines": { | 4509 | "engines": { | ||
| 4506 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | 4510 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||
| @@ -4515,14 +4519,14 @@ | |||||
| 4515 | } | 4519 | } | ||
| 4516 | }, | 4520 | }, | ||
| 4517 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { | 4521 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { | ||
| 4518 | - | "version": "8.48.1", | 4522 | + | "version": "8.53.1", |
| 4519 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.1.tgz", | 4523 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.1.tgz", |
| 4520 | - | "integrity": "sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==", | 4524 | + | "integrity": "sha512-Lu23yw1uJMFY8cUeq7JlrizAgeQvWugNQzJp8C3x8Eo5Jw5Q2ykMdiiTB9vBVOOUBysMzmRRmUfwFrZuI2C4SQ==", |
| 4521 | "dev": true, | 4525 | "dev": true, | ||
| 4522 | "license": "MIT", | 4526 | "license": "MIT", | ||
| 4523 | "dependencies": { | 4527 | "dependencies": { | ||
| 4524 | - | "@typescript-eslint/types": "8.48.1", | 4528 | + | "@typescript-eslint/types": "8.53.1", |
| 4525 | - | "@typescript-eslint/visitor-keys": "8.48.1" | 4529 | + | "@typescript-eslint/visitor-keys": "8.53.1" |
| 4526 | }, | 4530 | }, | ||
| 4527 | "engines": { | 4531 | "engines": { | ||
| 4528 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | 4532 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||
| @@ -4533,17 +4537,17 @@ | |||||
| 4533 | } | 4537 | } | ||
| 4534 | }, | 4538 | }, | ||
| 4535 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { | 4539 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { | ||
| 4536 | - | "version": "8.48.1", | 4540 | + | "version": "8.53.1", |
| 4537 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.48.1.tgz", | 4541 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.1.tgz", |
| 4538 | - | "integrity": "sha512-1jEop81a3LrJQLTf/1VfPQdhIY4PlGDBc/i67EVWObrtvcziysbLN3oReexHOM6N3jyXgCrkBsZpqwH0hiDOQg==", | 4542 | + | "integrity": "sha512-MOrdtNvyhy0rHyv0ENzub1d4wQYKb2NmIqG7qEqPWFW7Mpy2jzFC3pQ2yKDvirZB7jypm5uGjF2Qqs6OIqu47w==", |
| 4539 | "dev": true, | 4543 | "dev": true, | ||
| 4540 | "license": "MIT", | 4544 | "license": "MIT", | ||
| 4541 | "dependencies": { | 4545 | "dependencies": { | ||
| 4542 | - | "@typescript-eslint/types": "8.48.1", | 4546 | + | "@typescript-eslint/types": "8.53.1", |
| 4543 | - | "@typescript-eslint/typescript-estree": "8.48.1", | 4547 | + | "@typescript-eslint/typescript-estree": "8.53.1", |
| 4544 | - | "@typescript-eslint/utils": "8.48.1", | 4548 | + | "@typescript-eslint/utils": "8.53.1", |
| 4545 | - | "debug": "^4.3.4", | 4549 | + | "debug": "^4.4.3", |
| 4546 | - | "ts-api-utils": "^2.1.0" | 4550 | + | "ts-api-utils": "^2.4.0" |
| 4547 | }, | 4551 | }, | ||
| 4548 | "engines": { | 4552 | "engines": { | ||
| 4549 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | 4553 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||
| @@ -4558,9 +4562,9 @@ | |||||
| 4558 | } | 4562 | } | ||
| 4559 | }, | 4563 | }, | ||
| 4560 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { | 4564 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { | ||
| 4561 | - | "version": "8.48.1", | 4565 | + | "version": "8.53.1", |
| 4562 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.1.tgz", | 4566 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz", |
| 4563 | - | "integrity": "sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==", | 4567 | + | "integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==", |
| 4564 | "dev": true, | 4568 | "dev": true, | ||
| 4565 | "license": "MIT", | 4569 | "license": "MIT", | ||
| 4566 | "engines": { | 4570 | "engines": { | ||
| @@ -4572,21 +4576,21 @@ | |||||
| 4572 | } | 4576 | } | ||
| 4573 | }, | 4577 | }, | ||
| 4574 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { | 4578 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { | ||
| 4575 | - | "version": "8.48.1", | 4579 | + | "version": "8.53.1", |
| 4576 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.1.tgz", | 4580 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.1.tgz", |
| 4577 | - | "integrity": "sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==", | 4581 | + | "integrity": "sha512-RGlVipGhQAG4GxV1s34O91cxQ/vWiHJTDHbXRr0li2q/BGg3RR/7NM8QDWgkEgrwQYCvmJV9ichIwyoKCQ+DTg==", |
| 4578 | "dev": true, | 4582 | "dev": true, | ||
| 4579 | "license": "MIT", | 4583 | "license": "MIT", | ||
| 4580 | "dependencies": { | 4584 | "dependencies": { | ||
| 4581 | - | "@typescript-eslint/project-service": "8.48.1", | 4585 | + | "@typescript-eslint/project-service": "8.53.1", |
| 4582 | - | "@typescript-eslint/tsconfig-utils": "8.48.1", | 4586 | + | "@typescript-eslint/tsconfig-utils": "8.53.1", |
| 4583 | - | "@typescript-eslint/types": "8.48.1", | 4587 | + | "@typescript-eslint/types": "8.53.1", |
| 4584 | - | "@typescript-eslint/visitor-keys": "8.48.1", | 4588 | + | "@typescript-eslint/visitor-keys": "8.53.1", |
| 4585 | - | "debug": "^4.3.4", | 4589 | + | "debug": "^4.4.3", |
| 4586 | - | "minimatch": "^9.0.4", | 4590 | + | "minimatch": "^9.0.5", |
| 4587 | - | "semver": "^7.6.0", | 4591 | + | "semver": "^7.7.3", |
| 4588 | "tinyglobby": "^0.2.15", | 4592 | "tinyglobby": "^0.2.15", | ||
| 4589 | - | "ts-api-utils": "^2.1.0" | 4593 | + | "ts-api-utils": "^2.4.0" |
| 4590 | }, | 4594 | }, | ||
| 4591 | "engines": { | 4595 | "engines": { | ||
| 4592 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | 4596 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||
| @@ -4600,16 +4604,16 @@ | |||||
| 4600 | } | 4604 | } | ||
| 4601 | }, | 4605 | }, | ||
| 4602 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { | 4606 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { | ||
| 4603 | - | "version": "8.48.1", | 4607 | + | "version": "8.53.1", |
| 4604 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.1.tgz", | 4608 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.1.tgz", |
| 4605 | - | "integrity": "sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==", | 4609 | + | "integrity": "sha512-c4bMvGVWW4hv6JmDUEG7fSYlWOl3II2I4ylt0NM+seinYQlZMQIaKaXIIVJWt9Ofh6whrpM+EdDQXKXjNovvrg==", |
| 4606 | "dev": true, | 4610 | "dev": true, | ||
| 4607 | "license": "MIT", | 4611 | "license": "MIT", | ||
| 4608 | "dependencies": { | 4612 | "dependencies": { | ||
| 4609 | - | "@eslint-community/eslint-utils": "^4.7.0", | 4613 | + | "@eslint-community/eslint-utils": "^4.9.1", |
| 4610 | - | "@typescript-eslint/scope-manager": "8.48.1", | 4614 | + | "@typescript-eslint/scope-manager": "8.53.1", |
| 4611 | - | "@typescript-eslint/types": "8.48.1", | 4615 | + | "@typescript-eslint/types": "8.53.1", |
| 4612 | - | "@typescript-eslint/typescript-estree": "8.48.1" | 4616 | + | "@typescript-eslint/typescript-estree": "8.53.1" |
| 4613 | }, | 4617 | }, | ||
| 4614 | "engines": { | 4618 | "engines": { | ||
| 4615 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | 4619 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||
| @@ -4624,13 +4628,13 @@ | |||||
| 4624 | } | 4628 | } | ||
| 4625 | }, | 4629 | }, | ||
| 4626 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { | 4630 | "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { | ||
| 4627 | - | "version": "8.48.1", | 4631 | + | "version": "8.53.1", |
| 4628 | - | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.1.tgz", | 4632 | + | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.1.tgz", |
| 4629 | - | "integrity": "sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==", | 4633 | + | "integrity": "sha512-oy+wV7xDKFPRyNggmXuZQSBzvoLnpmJs+GhzRhPjrxl2b/jIlyjVokzm47CZCDUdXKr2zd7ZLodPfOBpOPyPlg==", |
| 4630 | "dev": true, | 4634 | "dev": true, | ||
| 4631 | "license": "MIT", | 4635 | "license": "MIT", | ||
| 4632 | "dependencies": { | 4636 | "dependencies": { | ||
| 4633 | - | "@typescript-eslint/types": "8.48.1", | 4637 | + | "@typescript-eslint/types": "8.53.1", |
| 4634 | "eslint-visitor-keys": "^4.2.1" | 4638 | "eslint-visitor-keys": "^4.2.1" | ||
| 4635 | }, | 4639 | }, | ||
| 4636 | "engines": { | 4640 | "engines": { | ||
| @@ -4665,9 +4669,9 @@ | |||||
| 4665 | } | 4669 | } | ||
| 4666 | }, | 4670 | }, | ||
| 4667 | "node_modules/typescript-eslint/node_modules/ts-api-utils": { | 4671 | "node_modules/typescript-eslint/node_modules/ts-api-utils": { | ||
| 4668 | - | "version": "2.1.0", | 4672 | + | "version": "2.4.0", |
| 4669 | - | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", | 4673 | + | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", |
| 4670 | - | "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", | 4674 | + | "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", |
| 4671 | "dev": true, | 4675 | "dev": true, | ||
| 4672 | "license": "MIT", | 4676 | "license": "MIT", | ||
| 4673 | "engines": { | 4677 | "engines": { | ||
| @@ -4685,9 +4689,9 @@ | |||||
| 4685 | "license": "MIT" | 4689 | "license": "MIT" | ||
| 4686 | }, | 4690 | }, | ||
| 4687 | "node_modules/update-browserslist-db": { | 4691 | "node_modules/update-browserslist-db": { | ||
| 4688 | - | "version": "1.2.2", | 4692 | + | "version": "1.2.3", |
| 4689 | - | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", | 4693 | + | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", |
| 4690 | - | "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", | 4694 | + | "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", |
| 4691 | "dev": true, | 4695 | "dev": true, | ||
| 4692 | "funding": [ | 4696 | "funding": [ | ||
| 4693 | { | 4697 | { | ||