From beb458b3b98220358a8f47cc2020191dcc4b34ba Mon Sep 17 00:00:00 2001 From: Gianmarco Date: Fri, 30 Jan 2026 12:11:02 +0100 Subject: [PATCH] TileHome --- .../.idea.TecniStamp/.idea/dataSources.xml | 12 + TecniStamp/TecniStamp.Domain/Sezione.cs | 5 + .../bin/Debug/net8.0/TecniStamp.Domain.dll | Bin 9216 -> 9728 bytes .../bin/Debug/net8.0/TecniStamp.Domain.pdb | Bin 13184 -> 13340 bytes .../net8.0/TecniStamp.Domain.AssemblyInfo.cs | 2 +- ...TecniStamp.Domain.AssemblyInfoInputs.cache | 2 +- .../obj/Debug/net8.0/TecniStamp.Domain.dll | Bin 9216 -> 9728 bytes .../obj/Debug/net8.0/TecniStamp.Domain.pdb | Bin 13184 -> 13340 bytes .../Debug/net8.0/ref/TecniStamp.Domain.dll | Bin 8192 -> 8704 bytes .../Debug/net8.0/refint/TecniStamp.Domain.dll | Bin 8192 -> 8704 bytes .../20260130092911_SezioneParent.Designer.cs | 374 + .../20260130092911_SezioneParent.cs | 59 + .../TecniStampDbContextModelSnapshot.cs | 14 + .../net8.0/TecniStamp.Infrastructure.dll | Bin 44032 -> 48640 bytes .../net8.0/TecniStamp.Infrastructure.pdb | Bin 18096 -> 19252 bytes .../TecniStamp.Infrastructure.AssemblyInfo.cs | 2 +- ...mp.Infrastructure.AssemblyInfoInputs.cache | 2 +- ...rastructure.csproj.AssemblyReference.cache | Bin 22193 -> 22193 bytes ...rastructure.csproj.CoreCompileInputs.cache | 2 +- .../net8.0/TecniStamp.Infrastructure.dll | Bin 44032 -> 48640 bytes .../net8.0/TecniStamp.Infrastructure.pdb | Bin 18096 -> 19252 bytes .../net8.0/ref/TecniStamp.Infrastructure.dll | Bin 9216 -> 9216 bytes .../refint/TecniStamp.Infrastructure.dll | Bin 9216 -> 9216 bytes .../Interfaces/IManagerService.cs | 2 + .../Interfaces/IPermissionService.cs | 8 + .../Interfaces/ISezioneService.cs | 8 + .../TecniStamp.Service/ManagerService.cs | 6 +- .../TecniStamp.Service/PermissionService.cs | 13 + .../TecniStamp.Service/SezioneService.cs | 13 + .../bin/Debug/net8.0/TecniStamp.Service.dll | Bin 8192 -> 9216 bytes .../bin/Debug/net8.0/TecniStamp.Service.pdb | Bin 24312 -> 24832 bytes .../net8.0/TecniStamp.Service.AssemblyInfo.cs | 2 +- ...ecniStamp.Service.AssemblyInfoInputs.cache | 2 +- ...amp.Service.csproj.AssemblyReference.cache | Bin 25487 -> 23948 bytes ...amp.Service.csproj.CoreCompileInputs.cache | 2 +- .../obj/Debug/net8.0/TecniStamp.Service.dll | Bin 8192 -> 9216 bytes .../obj/Debug/net8.0/TecniStamp.Service.pdb | Bin 24312 -> 24832 bytes .../Debug/net8.0/ref/TecniStamp.Service.dll | Bin 7168 -> 7680 bytes .../net8.0/refint/TecniStamp.Service.dll | Bin 7168 -> 7680 bytes .../Components/Layout/MainLayout.razor | 29 + .../Components/Pages/Account/Login.razor | 4 +- .../TecniStamp/Components/Pages/Home.razor | 26 +- TecniStamp/TecniStamp/Components/Routes.razor | 25 +- .../TecniStamp/Utils/MembershipUtils.cs | 22 + .../bin/Debug/net8.0/TecniStamp.dll | Bin 48128 -> 56832 bytes .../bin/Debug/net8.0/TecniStamp.exe | Bin 150016 -> 150016 bytes .../bin/Debug/net8.0/TecniStamp.pdb | Bin 45172 -> 47548 bytes .../Debug/net8.0/TecniStamp.AssemblyInfo.cs | 2 +- .../TecniStamp.AssemblyInfoInputs.cache | 2 +- .../TecniStamp.csproj.CoreCompileInputs.cache | 2 +- .../obj/Debug/net8.0/TecniStamp.dll | Bin 48128 -> 56832 bytes .../obj/Debug/net8.0/TecniStamp.pdb | Bin 45172 -> 47548 bytes .../TecniStamp/obj/Debug/net8.0/apphost.exe | Bin 150016 -> 150016 bytes .../obj/Debug/net8.0/ref/TecniStamp.dll | Bin 11264 -> 12800 bytes .../obj/Debug/net8.0/refint/TecniStamp.dll | Bin 11264 -> 12800 bytes .../@hotwired/turbo/dist/turbo.es2017-esm.js | 7178 ++++ .../@hotwired/turbo/dist/turbo.es2017-umd.js | 7217 ++++ .../libs/@melloware/coloris/dist/coloris.css | 577 + .../libs/@melloware/coloris/dist/coloris.d.ts | 476 + .../@melloware/coloris/dist/coloris.min.css | 1 + .../@melloware/coloris/dist/esm/coloris.js | 1327 + .../coloris/dist/esm/coloris.min.js | 1 + .../@melloware/coloris/dist/esm/package.json | 3 + .../@melloware/coloris/dist/umd/coloris.js | 1349 + .../coloris/dist/umd/coloris.min.js | 1 + .../@melloware/coloris/dist/umd/package.json | 3 + .../libs/apexcharts/dist/apexcharts.amd.js | 2 + .../libs/apexcharts/dist/apexcharts.common.js | 14 + .../libs/apexcharts/dist/apexcharts.css | 683 + .../libs/apexcharts/dist/apexcharts.esm.js | 14 + .../libs/apexcharts/dist/apexcharts.js | 32269 ++++++++++++++++ .../libs/apexcharts/dist/apexcharts.min.js | 14 + .../libs/apexcharts/dist/locales/ar.json | 63 + .../libs/apexcharts/dist/locales/be-cyrl.json | 55 + .../libs/apexcharts/dist/locales/be-latn.json | 55 + .../libs/apexcharts/dist/locales/ca.json | 55 + .../libs/apexcharts/dist/locales/cs.json | 55 + .../libs/apexcharts/dist/locales/da.json | 55 + .../libs/apexcharts/dist/locales/de.json | 55 + .../libs/apexcharts/dist/locales/el.json | 55 + .../libs/apexcharts/dist/locales/en.json | 55 + .../libs/apexcharts/dist/locales/es.json | 55 + .../libs/apexcharts/dist/locales/et.json | 63 + .../libs/apexcharts/dist/locales/fa.json | 55 + .../libs/apexcharts/dist/locales/fi.json | 55 + .../libs/apexcharts/dist/locales/fr.json | 55 + .../libs/apexcharts/dist/locales/he.json | 55 + .../libs/apexcharts/dist/locales/hi.json | 55 + .../libs/apexcharts/dist/locales/hr.json | 55 + .../libs/apexcharts/dist/locales/hu.json | 64 + .../libs/apexcharts/dist/locales/hy.json | 55 + .../libs/apexcharts/dist/locales/id.json | 47 + .../libs/apexcharts/dist/locales/it.json | 55 + .../libs/apexcharts/dist/locales/ja.json | 55 + .../libs/apexcharts/dist/locales/ka.json | 55 + .../libs/apexcharts/dist/locales/ko.json | 55 + .../libs/apexcharts/dist/locales/lt.json | 55 + .../libs/apexcharts/dist/locales/lv.json | 64 + .../libs/apexcharts/dist/locales/ms.json | 63 + .../libs/apexcharts/dist/locales/nb.json | 55 + .../libs/apexcharts/dist/locales/nl.json | 55 + .../libs/apexcharts/dist/locales/pl.json | 55 + .../libs/apexcharts/dist/locales/pt-br.json | 55 + .../libs/apexcharts/dist/locales/pt.json | 55 + .../libs/apexcharts/dist/locales/rs.json | 55 + .../libs/apexcharts/dist/locales/ru.json | 55 + .../libs/apexcharts/dist/locales/se.json | 55 + .../libs/apexcharts/dist/locales/sk.json | 55 + .../libs/apexcharts/dist/locales/sl.json | 55 + .../libs/apexcharts/dist/locales/sq.json | 55 + .../libs/apexcharts/dist/locales/th.json | 55 + .../libs/apexcharts/dist/locales/tr.json | 55 + .../libs/apexcharts/dist/locales/ua.json | 55 + .../libs/apexcharts/dist/locales/vi.json | 63 + .../libs/apexcharts/dist/locales/zh-cn.json | 55 + .../libs/apexcharts/dist/locales/zh-tw.json | 55 + .../libs/autosize/dist/autosize.esm.js | 1 + .../wwwroot/libs/autosize/dist/autosize.js | 231 + .../libs/autosize/dist/autosize.min.js | 1 + .../wwwroot/libs/clipboard/dist/clipboard.js | 890 + .../libs/clipboard/dist/clipboard.min.js | 7 + .../wwwroot/libs/countup.js/dist/countUp.d.ts | 68 + .../wwwroot/libs/countup.js/dist/countUp.js | 311 + .../libs/countup.js/dist/countUp.min.js | 1 + .../libs/countup.js/dist/countUp.umd.js | 1 + .../dist/requestAnimationFrame.polyfill.js | 26 + .../wwwroot/libs/dropzone/dist/basic.css | 1 + .../wwwroot/libs/dropzone/dist/basic.css.map | 1 + .../libs/dropzone/dist/dropzone-min.js | 2 + .../libs/dropzone/dist/dropzone-min.js.map | 1 + .../wwwroot/libs/dropzone/dist/dropzone.css | 1 + .../libs/dropzone/dist/dropzone.css.map | 1 + .../wwwroot/libs/dropzone/dist/dropzone.js | 3068 ++ .../libs/dropzone/dist/dropzone.js.map | 1 + .../wwwroot/libs/dropzone/dist/dropzone.mjs | 2111 + .../libs/dropzone/dist/dropzone.mjs.map | 1 + .../wwwroot/libs/imask/dist/imask.cjs | 3635 ++ .../wwwroot/libs/imask/dist/imask.cjs.map | 1 + .../wwwroot/libs/imask/dist/imask.js | 3641 ++ .../wwwroot/libs/imask/dist/imask.js.map | 1 + .../wwwroot/libs/imask/dist/imask.min.js | 2 + .../wwwroot/libs/imask/dist/imask.min.js.map | 1 + .../wwwroot/libs/list.js/dist/list.js | 2020 + .../wwwroot/libs/list.js/dist/list.js.map | 1 + .../wwwroot/libs/list.js/dist/list.min.js | 2 + .../wwwroot/libs/list.js/dist/list.min.js.map | 1 + .../wwwroot/libs/litepicker/dist/bundle.js | 52 + .../libs/litepicker/dist/css/litepicker.css | 13 + .../dist/css/plugins/keyboardnav.js.css | 12 + .../dist/css/plugins/mobilefriendly.js.css | 133 + .../dist/css/plugins/multiselect.js.css | 54 + .../litepicker/dist/css/plugins/ranges.js.css | 81 + .../wwwroot/libs/litepicker/dist/js/main.js | 13 + .../libs/litepicker/dist/litepicker.amd.js | 12 + .../litepicker/dist/litepicker.commonjs2.js | 12 + .../libs/litepicker/dist/litepicker.js | 12 + .../libs/litepicker/dist/litepicker.umd.js | 12 + .../litepicker/dist/nocss/litepicker.amd.js | 12 + .../dist/nocss/litepicker.commonjs2.js | 12 + .../libs/litepicker/dist/nocss/litepicker.js | 12 + .../litepicker/dist/nocss/litepicker.umd.js | 12 + .../dist/nocss/plugins/keyboardnav.js | 11 + .../dist/nocss/plugins/mobilefriendly.js | 11 + .../dist/nocss/plugins/multiselect.js | 11 + .../litepicker/dist/nocss/plugins/ranges.js | 11 + .../litepicker/dist/plugins/keyboardnav.js | 11 + .../litepicker/dist/plugins/mobilefriendly.js | 11 + .../litepicker/dist/plugins/multiselect.js | 11 + .../libs/litepicker/dist/plugins/ranges.js | 11 + .../libs/litepicker/dist/types/calendar.d.ts | 14 + .../libs/litepicker/dist/types/core.d.ts | 23 + .../libs/litepicker/dist/types/datetime.d.ts | 41 + .../libs/litepicker/dist/types/index.d.ts | 4 + .../litepicker/dist/types/interfaces.d.ts | 80 + .../litepicker/dist/types/litepicker.d.ts | 25 + .../libs/litepicker/dist/types/methods.d.ts | 20 + .../libs/litepicker/dist/types/utils.d.ts | 4 + .../libs/litepicker/dist/types/window.d.ts | 6 + .../libs/nouislider/dist/nouislider.css | 304 + .../libs/nouislider/dist/nouislider.d.ts | 198 + .../libs/nouislider/dist/nouislider.js | 2341 ++ .../libs/nouislider/dist/nouislider.min.css | 1 + .../libs/nouislider/dist/nouislider.min.js | 1 + .../libs/nouislider/dist/nouislider.min.mjs | 1 + .../libs/nouislider/dist/nouislider.mjs | 2330 ++ .../wwwroot/libs/plyr/dist/plyr.css | 1 + .../TecniStamp/wwwroot/libs/plyr/dist/plyr.js | 8758 +++++ .../wwwroot/libs/plyr/dist/plyr.min.js | 2 + .../wwwroot/libs/plyr/dist/plyr.min.js.map | 1 + .../wwwroot/libs/plyr/dist/plyr.min.mjs | 1 + .../wwwroot/libs/plyr/dist/plyr.min.mjs.map | 1 + .../wwwroot/libs/plyr/dist/plyr.mjs | 8750 +++++ .../wwwroot/libs/plyr/dist/plyr.polyfilled.js | 9230 +++++ .../libs/plyr/dist/plyr.polyfilled.min.js | 2 + .../libs/plyr/dist/plyr.polyfilled.min.js.map | 1 + .../libs/plyr/dist/plyr.polyfilled.min.mjs | 1 + .../plyr/dist/plyr.polyfilled.min.mjs.map | 1 + .../libs/plyr/dist/plyr.polyfilled.mjs | 9222 +++++ .../wwwroot/libs/plyr/dist/plyr.svg | 1 + .../wwwroot/libs/typed.js/dist/typed.cjs | 2 + .../wwwroot/libs/typed.js/dist/typed.cjs.map | 1 + .../libs/typed.js/dist/typed.module.js | 2 + .../libs/typed.js/dist/typed.module.js.map | 1 + .../wwwroot/libs/typed.js/dist/typed.umd.js | 3 + .../libs/typed.js/dist/typed.umd.js.map | 1 + 205 files changed, 112156 insertions(+), 24 deletions(-) create mode 100644 TecniStamp/.idea/.idea.TecniStamp/.idea/dataSources.xml create mode 100644 TecniStamp/TecniStamp.Infrastructure/Migrations/20260130092911_SezioneParent.Designer.cs create mode 100644 TecniStamp/TecniStamp.Infrastructure/Migrations/20260130092911_SezioneParent.cs create mode 100644 TecniStamp/TecniStamp.Service/Interfaces/IPermissionService.cs create mode 100644 TecniStamp/TecniStamp.Service/Interfaces/ISezioneService.cs create mode 100644 TecniStamp/TecniStamp.Service/PermissionService.cs create mode 100644 TecniStamp/TecniStamp.Service/SezioneService.cs create mode 100644 TecniStamp/TecniStamp/Utils/MembershipUtils.cs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@hotwired/turbo/dist/turbo.es2017-esm.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@hotwired/turbo/dist/turbo.es2017-umd.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@melloware/coloris/dist/coloris.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@melloware/coloris/dist/coloris.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@melloware/coloris/dist/coloris.min.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@melloware/coloris/dist/esm/coloris.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@melloware/coloris/dist/esm/coloris.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@melloware/coloris/dist/esm/package.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@melloware/coloris/dist/umd/coloris.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@melloware/coloris/dist/umd/coloris.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/@melloware/coloris/dist/umd/package.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/apexcharts.amd.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/apexcharts.common.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/apexcharts.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/apexcharts.esm.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/apexcharts.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/apexcharts.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/ar.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/be-cyrl.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/be-latn.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/ca.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/cs.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/da.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/de.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/el.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/en.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/es.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/et.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/fa.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/fi.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/fr.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/he.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/hi.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/hr.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/hu.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/hy.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/id.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/it.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/ja.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/ka.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/ko.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/lt.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/lv.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/ms.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/nb.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/nl.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/pl.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/pt-br.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/pt.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/rs.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/ru.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/se.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/sk.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/sl.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/sq.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/th.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/tr.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/ua.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/vi.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/zh-cn.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/apexcharts/dist/locales/zh-tw.json create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/autosize/dist/autosize.esm.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/autosize/dist/autosize.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/autosize/dist/autosize.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/clipboard/dist/clipboard.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/clipboard/dist/clipboard.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/countup.js/dist/countUp.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/countup.js/dist/countUp.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/countup.js/dist/countUp.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/countup.js/dist/countUp.umd.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/countup.js/dist/requestAnimationFrame.polyfill.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/basic.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/basic.css.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/dropzone-min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/dropzone-min.js.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/dropzone.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/dropzone.css.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/dropzone.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/dropzone.js.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/dropzone.mjs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/dropzone/dist/dropzone.mjs.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/imask/dist/imask.cjs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/imask/dist/imask.cjs.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/imask/dist/imask.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/imask/dist/imask.js.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/imask/dist/imask.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/imask/dist/imask.min.js.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/list.js/dist/list.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/list.js/dist/list.js.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/list.js/dist/list.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/list.js/dist/list.min.js.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/bundle.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/css/litepicker.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/css/plugins/keyboardnav.js.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/css/plugins/mobilefriendly.js.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/css/plugins/multiselect.js.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/css/plugins/ranges.js.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/js/main.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/litepicker.amd.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/litepicker.commonjs2.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/litepicker.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/litepicker.umd.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/nocss/litepicker.amd.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/nocss/litepicker.commonjs2.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/nocss/litepicker.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/nocss/litepicker.umd.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/nocss/plugins/keyboardnav.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/nocss/plugins/mobilefriendly.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/nocss/plugins/multiselect.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/nocss/plugins/ranges.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/plugins/keyboardnav.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/plugins/mobilefriendly.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/plugins/multiselect.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/plugins/ranges.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/types/calendar.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/types/core.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/types/datetime.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/types/index.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/types/interfaces.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/types/litepicker.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/types/methods.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/types/utils.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/litepicker/dist/types/window.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/nouislider/dist/nouislider.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/nouislider/dist/nouislider.d.ts create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/nouislider/dist/nouislider.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/nouislider/dist/nouislider.min.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/nouislider/dist/nouislider.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/nouislider/dist/nouislider.min.mjs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/nouislider/dist/nouislider.mjs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.css create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.min.js.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.min.mjs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.min.mjs.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.mjs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.polyfilled.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.polyfilled.min.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.polyfilled.min.js.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.polyfilled.min.mjs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.polyfilled.min.mjs.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.polyfilled.mjs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/plyr/dist/plyr.svg create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/typed.js/dist/typed.cjs create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/typed.js/dist/typed.cjs.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/typed.js/dist/typed.module.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/typed.js/dist/typed.module.js.map create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/typed.js/dist/typed.umd.js create mode 100644 TecniStamp/TecniStamp/wwwroot/libs/typed.js/dist/typed.umd.js.map diff --git a/TecniStamp/.idea/.idea.TecniStamp/.idea/dataSources.xml b/TecniStamp/.idea/.idea.TecniStamp/.idea/dataSources.xml new file mode 100644 index 0000000..273bf26 --- /dev/null +++ b/TecniStamp/.idea/.idea.TecniStamp/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + sqlserver.jb + true + com.jetbrains.jdbc.sqlserver.SqlServerDriver + Server=192.168.0.233\SQL2019 + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/TecniStamp/TecniStamp.Domain/Sezione.cs b/TecniStamp/TecniStamp.Domain/Sezione.cs index b257dd0..64cb421 100644 --- a/TecniStamp/TecniStamp.Domain/Sezione.cs +++ b/TecniStamp/TecniStamp.Domain/Sezione.cs @@ -7,6 +7,11 @@ public class Sezione : EntitaBase { public string Nome { get; set; } public int Ordinamento { get; set; } + public string? Icona { get; set; } [InverseProperty(nameof(Feature.Sezione))] public List Features { get; set; } + + [ForeignKey(nameof(Parent))] + public Guid? ParentId { get; set; } + public Sezione Parent { get; set; } } \ No newline at end of file diff --git a/TecniStamp/TecniStamp.Domain/bin/Debug/net8.0/TecniStamp.Domain.dll b/TecniStamp/TecniStamp.Domain/bin/Debug/net8.0/TecniStamp.Domain.dll index 978865b6b8cfcc34dfa53383d0946cbae833ca30..e70a03f11643c5815aa8350d2892cf69e8d5afee 100644 GIT binary patch delta 3616 zcmchadu$Zf6~@oKGu~N0S>yO^?A^5!f+1jg*Wj(4c1?&J7XuEjkR}mcV}mHcw18rY z)r^fL#|~`-nM%O|B{oS>Ahb;h(wzfsYvN}&Rz)o zU8%F0Z_e*Kch0?g=g#bG?-RW(hX%us|8YSdnQex`!E{wcR0_kFG>T;( zt|^6j!$cPgh?IA^WSQ5hH>tRHQn#eVx#!A_`r)|ujo#<=S`mL3z^?bc_4uoHWaAyK zEY&?_M0RCZTR)WmM(~ay0gTWcLjoA+IC+W*9?l_3qe`#Uu6UF(iOOFjdLG9SKjL+J zcW>|7wui7~JDWCd$C$xvEp-GS}P@% zr*OF((Hr(O;`J!%qo-ip%fNtTk2~x>i319n?+a^Oaz3H}($so1h0ow~3~tG@;EtwbI3**jfkuP(KBI zT|Wa&7QL=FBmRrtcGpREkdQ9dSi9gKRx6>~E$;FU;@cJv^t$z7#k&>2Jjq~oC9 z8#?BkCWk&Tbi#QLG-c>r`$O{6XNG=fp99T;(Eot{i2V_z(lwKO%l-s(GfC2Y8vW-! z$_^2>e{gCU;aEPBomPjD7(H8e^+SiD_^-oe_RL*0f7{Qm&Eh930a1`P_i1AbD&lud_B zGE*G~4I6si-;Wz?)KIs75OgX@GBY_eW^zX{>>N64=xq!;hb9d@_wwjg|d?pGOQKUE*3?K&t<$SC^@@Wo%yad8@1U24>vXcH@8 zl$}1!rTfI`lQyFgk4ii)@q|%sKO^z1QFh3ZVHss7)#8~8iW3rbL%4k-Ixf&?l$~ZY zJ)qmfNf>3nSK>aS>CB#(YR=vXs_sq=(y;Nw<;^&&A|^)5pMO%R<@Kdeq>ieC+(%sQ zTTM$4*FZHzaPKRMLN(Qb6lNxZxDKQ!2Gw}4T!y$Fs;L2cWG=L|#+&s(iLv z6T3UR_BMA&CJEl*?3Fe*_by~FwmCgEn|)b14axM_XwGf>fp5?K_Dt_+K}Fz2XWxn2 zKN@H{d-VOU^TQ{{$EFG_{aBk`r0 zxTs3wUu!6EhX4Qo delta 3171 zcmb`JeQXrR8OEQTUGE-eWA1zyV`DpaX9LEGgYEM-ZTW~BhZrkH1d3a=_>6I6k&@I9 zOoQ4z#}yx;iQ;UVmMBuO(?lhzf>J{wO4^!0NfD`(s$Z!n(OINOs8O1Rl(b5u_L=vl zG*SP}p61#2_sr}&b2GD}&8*AZ@z{anJITAJV6H5Z@qDWuD5v4(%yS(R&uuCk=>YE1 z#wuXOo=C(B`hf!S{q4ZrK|XD;d0LB}<=W27TSZ zqL7E)BwLmMR`5b)YtXAUTOGkswJywNE^0TanvUS#YELN1Ks&*1yD6BqJO5`~x0@;| z)!v%`r#7kVZpC|A;ueajSTO&XQv*@z4Q4j?^PQ& z;C{vt9d~V9+sS)|d?c84mix>LJ@zsd=9VY+^RDMddrd4Bi_Qd`adoU~r}9QT7YSGE zOU@Q=9v=6!KQHequ8WWxqrW{*YmMmVMPCv9r=$Icbp{_7CD8>(CwfYBl<8bt63x1Q zVmb?2-=>D~e%>w=a&b;_9#*=$Py~b~+3_B>)I-yMLJwL0BIt3hyYU=xpMr7pN=Mm#Ddul8&E|j@Ll8)|wR=8nJZNaGXOYGYU9iWwV-6YmqkVw%9YePBC|{7La^!~!oPhXD z4j1-u0E3yq$ju#UpAyCxDZ2zCcSIisyhrl?|noX&5`_x2r{Ow znmt5tz)%Bwh+x9dG1uRVC=MGu=|)IXhQfTX2+tWR;e$n(Hl+7V45tj~VaIUR&=%Is z$7_bRvu-|qZ%8j_F)kV6g8IZO2K9v_{->614*Ix5qEwgvvCj)*88w0i(RR_*qH9Ih=lnjorKuK%sm1u3=+~((4pPf- zlp5iItMxqcLvfr&UvMJ-W~(lk&EMeHsoSs>E!6G!jOxcuv>1Mw~O^oX0rUtE~8!wZBkZmI_$9W82z_HOjU)l;A=^MQNQH zwhr-ujMR=9WjBE}w}eBV5$Ci~-F;T#S)+J8<-{;-bON3oH3O6ueQ` z6co*?^s}z6gC{LS6<;TZ=XxHGQnq#ux2UYPnNMeG668 zly?iY+i9ToI4#uNQ$KQ7Fn-MKyx~ZOcKpQaq17x&f9C2A7D=3Y>^_M0`N4WIN*dH?TS5|88i*!34Tcq@7|m@MjcyB-)GO?Lelm8-n*M6>U!7n_Su%=>%ij-S_n+^4{7vh?zaDs`Y5GW+t!mop8(Rj`L-nnx z!IqYR^iZlX)!2~U+MFI}ZXDd!Hqcbx)Ru1DHWd7(yu`_~pn@yq^+B@Y*2dd^S$iH< zPp{&D_OqPj_w!kOaGFaGHO8`(rJJ9f-Q~eU70Jj?*BpQEWPWtbiT!I1es8hABsgC2 zV52crvoUq<;}5Mo_kPE>jxEV#uRO`;|9c(RaeN}NKt0klca+aZ;?+rGd1SYm%nlOdiBGuF(M3ub!oiek+}!z^^)}e$_D@t^S)e HQSbc+*Fgi5 diff --git a/TecniStamp/TecniStamp.Domain/bin/Debug/net8.0/TecniStamp.Domain.pdb b/TecniStamp/TecniStamp.Domain/bin/Debug/net8.0/TecniStamp.Domain.pdb index f8491580b56691acb58156195a0b03b27e0e0977..895dc142de9ba37141c62bcbcc8c1fa3c4019981 100644 GIT binary patch delta 1024 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 delta 3171 zcmb`JeQXrR8OEQTUGE-eWA1zyV`DpaX9LEGgYEM-ZTW~BhZrkH1d3a=_>6I6k&@I9 zOoQ4z#}yx;iQ;UVmMBuO(?lhzf>J{wO4^!0NfD`(s$Z!n(OINOs8O1Rl(b5u_L=vl zG*SP}p61#2_sr}&b2GD}&8*AZ@z{anJITAJV6H5Z@qDWuD5v4(%yS(R&uuCk=>YE1 z#wuXOo=C(B`hf!S{q4ZrK|XD;d0LB}<=W27TSZ zqL7E)BwLmMR`5b)YtXAUTOGkswJywNE^0TanvUS#YELN1Ks&*1yD6BqJO5`~x0@;| z)!v%`r#7kVZpC|A;ueajSTO&XQv*@z4Q4j?^PQ& z;C{vt9d~V9+sS)|d?c84mix>LJ@zsd=9VY+^RDMddrd4Bi_Qd`adoU~r}9QT7YSGE zOU@Q=9v=6!KQHequ8WWxqrW{*YmMmVMPCv9r=$Icbp{_7CD8>(CwfYBl<8bt63x1Q zVmb?2-=>D~e%>w=a&b;_9#*=$Py~b~+3_B>)I-yMLJwL0BIt3hyYU=xpMr7pN=Mm#Ddul8&E|j@Ll8)|wR=8nJZNaGXOYGYU9iWwV-6YmqkVw%9YePBC|{7La^!~!oPhXD z4j1-u0E3yq$ju#UpAyCxDZ2zCcSIisyhrl?|noX&5`_x2r{Ow znmt5tz)%Bwh+x9dG1uRVC=MGu=|)IXhQfTX2+tWR;e$n(Hl+7V45tj~VaIUR&=%Is z$7_bRvu-|qZ%8j_F)kV6g8IZO2K9v_{->614*Ix5qEwgvvCj)*88w0i(RR_*qH9Ih=lnjorKuK%sm1u3=+~((4pPf- zlp5iItMxqcLvfr&UvMJ-W~(lk&EMeHsoSs>E!6G!jOxcuv>1Mw~O^oX0rUtE~8!wZBkZmI_$9W82z_HOjU)l;A=^MQNQH zwhr-ujMR=9WjBE}w}eBV5$Ci~-F;T#S)+J8<-{;-bON3oH3O6ueQ` z6co*?^s}z6gC{LS6<;TZ=XxHGQnq#ux2UYPnNMeG668 zly?iY+i9ToI4#uNQ$KQ7Fn-MKyx~ZOcKpQaq17x&f9C2A7D=3Y>^_M0`N4WIN*dH?TS5|88i*!34Tcq@7|m@MjcyB-)GO?Lelm8-n*M6>U!7n_Su%=>%ij-S_n+^4{7vh?zaDs`Y5GW+t!mop8(Rj`L-nnx z!IqYR^iZlX)!2~U+MFI}ZXDd!Hqcbx)Ru1DHWd7(yu`_~pn@yq^+B@Y*2dd^S$iH< zPp{&D_OqPj_w!kOaGFaGHO8`(rJJ9f-Q~eU70Jj?*BpQEWPWtbiT!I1es8hABsgC2 zV52crvoUq<;}5Mo_kPE>jxEV#uRO`;|9c(RaeN}NKt0klca+aZ;?+rGd1SYm%nlOdiBGuF(M3ub!oiek+}!z^^)}e$_D@t^S)e HQSbc+*Fgi5 diff --git a/TecniStamp/TecniStamp.Domain/obj/Debug/net8.0/TecniStamp.Domain.pdb b/TecniStamp/TecniStamp.Domain/obj/Debug/net8.0/TecniStamp.Domain.pdb index f8491580b56691acb58156195a0b03b27e0e0977..895dc142de9ba37141c62bcbcc8c1fa3c4019981 100644 GIT binary patch delta 1024 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 delta 2468 zcmc&$ZEO@p7=CANcYD{;>-9K#$daU z`#jIgJF_#hv)kX$pV<3GcprT*M44-v!sP`bLKJ}DPK$lbLm#(#=QR^GDWQXC%w;7* zfdZl#;BFXYR)xIV+8~ zRt-KP4ZoEw&D4k(|5UlEWpx97+d$f_V@AxZ2MeJTqo~^JQ4AEN#Zd%`(uv;IRIJ>` zTuXF=t}(tY7wSdyIQll|3sz3c#hO9qT^E4mjNeHWUuWFG$`Otqa4j*BXfHQ=PpYKP zFb->n&_IyFpMm)_?CK>iX7vQ+Q<2t7ewx$|@^I9&s$r@>AI0UUR-R@U?F})itpJWSx;*d zYAA#5xLAgES+-R8a@be!r0soc!gQ$AA0(G;`gM`Rj*697h-}i6VoeUaEY@LrWWC=+ ztHVmem{r5}rl>uKO_Q0*p}%U+QJ!7(FHEz;%H@mL_Sr5LOEZVLM zi3>oN{2urN{Rq6FT>(br@4&eH8<=jjRlA9JgO-QmKdq!Q?9zQu$~fnsrt(XU({)-^ z9JnR*0in7%WK9;GnOjK}*rD@)lIHVE;ZC5W1z^}f))8N|8Krv>$AA(q&ML&!KuI;w z1YR03#C6aFHcmBZ{pnXLy2xCkcnUJ#6|974J_h`6?KS;&?L(zmyNip&r`9{gA6e`C zYetUyztODsgQ43$EzSlfM15T(TGN&6j?~7wYHB)@-LYsaT9w>Xo$RcRcBSe% zvNqLCgzbxA0C54Ob#`{d(n5{?M=~EL%IH>cVyL1-wl!OQp|KHfS=iN7M-jX-Yp9Eo z)QwopK^J%pb+QtJt4bBvCd^3^dNp_#4v{*dH(<} C{(-gt diff --git a/TecniStamp/TecniStamp.Domain/obj/Debug/net8.0/refint/TecniStamp.Domain.dll b/TecniStamp/TecniStamp.Domain/obj/Debug/net8.0/refint/TecniStamp.Domain.dll index dbc4564bbfef6b41eda3908c9a112d970c1cbc3e..b33be3b570601624dd1a265b10378b8f4f3ebc25 100644 GIT binary patch delta 2824 zcmcImZERCj7=F*`y?1N7k2}W3Hmh_S@+HRBb!;6URzPG!SqWna$&j^c!AXS38WSb) z7ANSG80P)sN1`K$Q3O92_`^h9Lb5m#2|q9pUCa!Lm%Pj{>` zt8PZmj#g-wMIEJ)KwYbFOVX(;LNr-PB#^Yljv8~9OnQhKUqTBnQH_CkU1~@Fwk-py zS8oN8hG*mYb(BDCs`&Bs?JMw1fj?~@H=3*n*uA(RaOP~0mHr3of65-sAVc%OUE@;dWt_`+knv}!^k-fD79QVnw+X4zy~}u3 zJB<{A6xNB;nupH1QdEYj{y-jDqNQjWl^Vx+I;aOO!5@?2@{;DyFwAy7*kfQNxJ~*; zQ=XA!^L526gR0oPA~L3rnaybon#XLHd`50W$5t{7AGJ_-+HJG}CF2EM#d~ENMI&k| zdy3;?Df;EuR$&&f>+q!G6ScGH z)kINM!|{Hno&t82tYiW8>D#HuX*yd^6|gn(MJ)T=5Ixc=U<>7Lay#BK`Ffu5@SdD^ zCsTE@@IG@%RiW~1pSF*@j`yDSj>E>?&ua(p7Bl_E-Gka;hh>Ui>hx1N^GwyZ%<)ux ztvuaNOR3y3KgEK{v$yrHz;hElsDD?$Nc3R$wGgWvPt_vNQt)Pwm77}{<_xE)S|&9P zyGqFdrdCO<{zo#tn=y#(ton=YUo80^=^ALHmIweMwP!W66MZO)RGYx+QvPCp}1M z#zERj*Tf*}Bdi=?gqiIi4p6DIg;p_cD$#PBD^;+q=}revTuI?NAoWUXIg@Lr~Vr z5st?grx;07^CE4hiGlr0{F+J{u`iT1+Gbfm`0YhyjTRLt)z27V>}5 zG7TrFj)TjnO?7OTsYV%?sZz!B10cf zB1yGEeGM0GdqMeUGaINLVIxq|EIb9>50o?;PeF6+8|BSbkRC$(Fi=tx7OJ2SP*O9P zpoKt*U(061VW6Zo{AvnX1eCNGnxG{>i4%7b;zxj5T5Z_E>k_tb_Kz0Jb+nEfK(mKT z@4TbBlJ9JBhP6BMOxoX=A5YtoOl@lK+rBME1KG&#t9WvTlB2O5$!)3j1UnfrdZgk< zZF=6!TXwqI_uv0(hpWd$TT?L9mk1|g$z)SJ7HVlqgu|Od!FV_r4krTfP^dK)YHp1s zVno=ik`XgSO!ncLfX6Gy$c%3PRMRmn)s-*Cn<|bB*H_DQm%XNT%nrzNqh)msu1;0_ z5Z+`0qBMPC|O{|A$GryiV+5~Zjp$5<) delta 2468 zcmc&$ZEO@p7=CANcYD{;>-9K#$daU z`#jIgJF_#hv)kX$pV<3GcprT*M44-v!sP`bLKJ}DPK$lbLm#(#=QR^GDWQXC%w;7* zfdZl#;BFXYR)xIV+8~ zRt-KP4ZoEw&D4k(|5UlEWpx97+d$f_V@AxZ2MeJTqo~^JQ4AEN#Zd%`(uv;IRIJ>` zTuXF=t}(tY7wSdyIQll|3sz3c#hO9qT^E4mjNeHWUuWFG$`Otqa4j*BXfHQ=PpYKP zFb->n&_IyFpMm)_?CK>iX7vQ+Q<2t7ewx$|@^I9&s$r@>AI0UUR-R@U?F})itpJWSx;*d zYAA#5xLAgES+-R8a@be!r0soc!gQ$AA0(G;`gM`Rj*697h-}i6VoeUaEY@LrWWC=+ ztHVmem{r5}rl>uKO_Q0*p}%U+QJ!7(FHEz;%H@mL_Sr5LOEZVLM zi3>oN{2urN{Rq6FT>(br@4&eH8<=jjRlA9JgO-QmKdq!Q?9zQu$~fnsrt(XU({)-^ z9JnR*0in7%WK9;GnOjK}*rD@)lIHVE;ZC5W1z^}f))8N|8Krv>$AA(q&ML&!KuI;w z1YR03#C6aFHcmBZ{pnXLy2xCkcnUJ#6|974J_h`6?KS;&?L(zmyNip&r`9{gA6e`C zYetUyztODsgQ43$EzSlfM15T(TGN&6j?~7wYHB)@-LYsaT9w>Xo$RcRcBSe% zvNqLCgzbxA0C54Ob#`{d(n5{?M=~EL%IH>cVyL1-wl!OQp|KHfS=iN7M-jX-Yp9Eo z)QwopK^J%pb+QtJt4bBvCd^3^dNp_#4v{*dH(<} C{(-gt diff --git a/TecniStamp/TecniStamp.Infrastructure/Migrations/20260130092911_SezioneParent.Designer.cs b/TecniStamp/TecniStamp.Infrastructure/Migrations/20260130092911_SezioneParent.Designer.cs new file mode 100644 index 0000000..78e4d35 --- /dev/null +++ b/TecniStamp/TecniStamp.Infrastructure/Migrations/20260130092911_SezioneParent.Designer.cs @@ -0,0 +1,374 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using TecniStamp.Infrastructure.DAL.Context; + +#nullable disable + +namespace TecniStamp.Infrastructure.Migrations +{ + [DbContext(typeof(TecniStampDbContext))] + [Migration("20260130092911_SezioneParent")] + partial class SezioneParent + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("TecniStamp.Domain.Feature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DataCreazione") + .HasColumnType("datetime2"); + + b.Property("DataModifica") + .HasColumnType("datetime2"); + + b.Property("Descrizione") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Eliminato") + .HasColumnType("bit"); + + b.Property("IdUtenteCreazione") + .HasColumnType("uniqueidentifier"); + + b.Property("IdUtenteModifica") + .HasColumnType("uniqueidentifier"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Ordinamento") + .HasColumnType("int"); + + b.Property("SezioneId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IdUtenteCreazione"); + + b.HasIndex("IdUtenteModifica"); + + b.HasIndex("SezioneId"); + + b.ToTable("Feature"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DataCreazione") + .HasColumnType("datetime2"); + + b.Property("DataModifica") + .HasColumnType("datetime2"); + + b.Property("Eliminato") + .HasColumnType("bit"); + + b.Property("IdFeature") + .HasColumnType("uniqueidentifier"); + + b.Property("IdUtenteCreazione") + .HasColumnType("uniqueidentifier"); + + b.Property("IdUtenteModifica") + .HasColumnType("uniqueidentifier"); + + b.Property("RuoloId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("IdFeature"); + + b.HasIndex("IdUtenteCreazione"); + + b.HasIndex("IdUtenteModifica"); + + b.HasIndex("RuoloId"); + + b.ToTable("Permission"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Ruolo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DataCreazione") + .HasColumnType("datetime2"); + + b.Property("DataModifica") + .HasColumnType("datetime2"); + + b.Property("Eliminato") + .HasColumnType("bit"); + + b.Property("IdUtenteCreazione") + .HasColumnType("uniqueidentifier"); + + b.Property("IdUtenteModifica") + .HasColumnType("uniqueidentifier"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("IdUtenteCreazione"); + + b.HasIndex("IdUtenteModifica"); + + b.ToTable("Ruolo"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Sezione", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DataCreazione") + .HasColumnType("datetime2"); + + b.Property("DataModifica") + .HasColumnType("datetime2"); + + b.Property("Eliminato") + .HasColumnType("bit"); + + b.Property("Icona") + .HasColumnType("nvarchar(max)"); + + b.Property("IdUtenteCreazione") + .HasColumnType("uniqueidentifier"); + + b.Property("IdUtenteModifica") + .HasColumnType("uniqueidentifier"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Ordinamento") + .HasColumnType("int"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("IdUtenteCreazione"); + + b.HasIndex("IdUtenteModifica"); + + b.HasIndex("ParentId"); + + b.ToTable("Sezione"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Utente", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Cognome") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DataCreazione") + .HasColumnType("datetime2"); + + b.Property("DataModifica") + .HasColumnType("datetime2"); + + b.Property("Eliminato") + .HasColumnType("bit"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IdUtenteCreazione") + .HasColumnType("uniqueidentifier"); + + b.Property("IdUtenteModifica") + .HasColumnType("uniqueidentifier"); + + b.Property("Nome") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RuoloId") + .HasColumnType("uniqueidentifier"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("IdUtenteCreazione"); + + b.HasIndex("IdUtenteModifica"); + + b.HasIndex("RuoloId"); + + b.ToTable("Utente"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Feature", b => + { + b.HasOne("TecniStamp.Domain.Utente", "UtenteCreazione") + .WithMany() + .HasForeignKey("IdUtenteCreazione"); + + b.HasOne("TecniStamp.Domain.Utente", "UtenteModifica") + .WithMany() + .HasForeignKey("IdUtenteModifica"); + + b.HasOne("TecniStamp.Domain.Sezione", "Sezione") + .WithMany("Features") + .HasForeignKey("SezioneId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Sezione"); + + b.Navigation("UtenteCreazione"); + + b.Navigation("UtenteModifica"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Permission", b => + { + b.HasOne("TecniStamp.Domain.Feature", "Feature") + .WithMany() + .HasForeignKey("IdFeature") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("TecniStamp.Domain.Utente", "UtenteCreazione") + .WithMany() + .HasForeignKey("IdUtenteCreazione"); + + b.HasOne("TecniStamp.Domain.Utente", "UtenteModifica") + .WithMany() + .HasForeignKey("IdUtenteModifica"); + + b.HasOne("TecniStamp.Domain.Ruolo", "Ruolo") + .WithMany("Permessi") + .HasForeignKey("RuoloId"); + + b.Navigation("Feature"); + + b.Navigation("Ruolo"); + + b.Navigation("UtenteCreazione"); + + b.Navigation("UtenteModifica"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Ruolo", b => + { + b.HasOne("TecniStamp.Domain.Utente", "UtenteCreazione") + .WithMany() + .HasForeignKey("IdUtenteCreazione"); + + b.HasOne("TecniStamp.Domain.Utente", "UtenteModifica") + .WithMany() + .HasForeignKey("IdUtenteModifica"); + + b.Navigation("UtenteCreazione"); + + b.Navigation("UtenteModifica"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Sezione", b => + { + b.HasOne("TecniStamp.Domain.Utente", "UtenteCreazione") + .WithMany() + .HasForeignKey("IdUtenteCreazione"); + + b.HasOne("TecniStamp.Domain.Utente", "UtenteModifica") + .WithMany() + .HasForeignKey("IdUtenteModifica"); + + b.HasOne("TecniStamp.Domain.Sezione", "Parent") + .WithMany() + .HasForeignKey("ParentId"); + + b.Navigation("Parent"); + + b.Navigation("UtenteCreazione"); + + b.Navigation("UtenteModifica"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Utente", b => + { + b.HasOne("TecniStamp.Domain.Utente", "UtenteCreazione") + .WithMany() + .HasForeignKey("IdUtenteCreazione"); + + b.HasOne("TecniStamp.Domain.Utente", "UtenteModifica") + .WithMany() + .HasForeignKey("IdUtenteModifica"); + + b.HasOne("TecniStamp.Domain.Ruolo", "Ruolo") + .WithMany("Utenti") + .HasForeignKey("RuoloId"); + + b.Navigation("Ruolo"); + + b.Navigation("UtenteCreazione"); + + b.Navigation("UtenteModifica"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Ruolo", b => + { + b.Navigation("Permessi"); + + b.Navigation("Utenti"); + }); + + modelBuilder.Entity("TecniStamp.Domain.Sezione", b => + { + b.Navigation("Features"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/TecniStamp/TecniStamp.Infrastructure/Migrations/20260130092911_SezioneParent.cs b/TecniStamp/TecniStamp.Infrastructure/Migrations/20260130092911_SezioneParent.cs new file mode 100644 index 0000000..8aef80a --- /dev/null +++ b/TecniStamp/TecniStamp.Infrastructure/Migrations/20260130092911_SezioneParent.cs @@ -0,0 +1,59 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace TecniStamp.Infrastructure.Migrations +{ + /// + public partial class SezioneParent : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Icona", + table: "Sezione", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "ParentId", + table: "Sezione", + type: "uniqueidentifier", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Sezione_ParentId", + table: "Sezione", + column: "ParentId"); + + migrationBuilder.AddForeignKey( + name: "FK_Sezione_Sezione_ParentId", + table: "Sezione", + column: "ParentId", + principalTable: "Sezione", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Sezione_Sezione_ParentId", + table: "Sezione"); + + migrationBuilder.DropIndex( + name: "IX_Sezione_ParentId", + table: "Sezione"); + + migrationBuilder.DropColumn( + name: "Icona", + table: "Sezione"); + + migrationBuilder.DropColumn( + name: "ParentId", + table: "Sezione"); + } + } +} diff --git a/TecniStamp/TecniStamp.Infrastructure/Migrations/TecniStampDbContextModelSnapshot.cs b/TecniStamp/TecniStamp.Infrastructure/Migrations/TecniStampDbContextModelSnapshot.cs index 4f5707f..09490c4 100644 --- a/TecniStamp/TecniStamp.Infrastructure/Migrations/TecniStampDbContextModelSnapshot.cs +++ b/TecniStamp/TecniStamp.Infrastructure/Migrations/TecniStampDbContextModelSnapshot.cs @@ -160,6 +160,9 @@ namespace TecniStamp.Infrastructure.Migrations b.Property("Eliminato") .HasColumnType("bit"); + b.Property("Icona") + .HasColumnType("nvarchar(max)"); + b.Property("IdUtenteCreazione") .HasColumnType("uniqueidentifier"); @@ -173,12 +176,17 @@ namespace TecniStamp.Infrastructure.Migrations b.Property("Ordinamento") .HasColumnType("int"); + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + b.HasKey("Id"); b.HasIndex("IdUtenteCreazione"); b.HasIndex("IdUtenteModifica"); + b.HasIndex("ParentId"); + b.ToTable("Sezione"); }); @@ -314,6 +322,12 @@ namespace TecniStamp.Infrastructure.Migrations .WithMany() .HasForeignKey("IdUtenteModifica"); + b.HasOne("TecniStamp.Domain.Sezione", "Parent") + .WithMany() + .HasForeignKey("ParentId"); + + b.Navigation("Parent"); + b.Navigation("UtenteCreazione"); b.Navigation("UtenteModifica"); diff --git a/TecniStamp/TecniStamp.Infrastructure/bin/Debug/net8.0/TecniStamp.Infrastructure.dll b/TecniStamp/TecniStamp.Infrastructure/bin/Debug/net8.0/TecniStamp.Infrastructure.dll index eacce43df25d6042275cef242deca2b696479804..3f70764ca38819550c659ed512bc296fced9574d 100644 GIT binary patch literal 48640 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 diff --git a/TecniStamp/TecniStamp.Infrastructure/bin/Debug/net8.0/TecniStamp.Infrastructure.pdb b/TecniStamp/TecniStamp.Infrastructure/bin/Debug/net8.0/TecniStamp.Infrastructure.pdb index 46e4c24c56fb671b56bfb11036a06c9897e36adc..213162d6851e6eaf7735995b56baa0b8de23e370 100644 GIT binary patch delta 2991 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 diff --git a/TecniStamp/TecniStamp.Infrastructure/obj/Debug/net8.0/TecniStamp.Infrastructure.pdb b/TecniStamp/TecniStamp.Infrastructure/obj/Debug/net8.0/TecniStamp.Infrastructure.pdb index 46e4c24c56fb671b56bfb11036a06c9897e36adc..213162d6851e6eaf7735995b56baa0b8de23e370 100644 GIT binary patch delta 2991 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 diff --git a/TecniStamp/TecniStamp.Infrastructure/obj/Debug/net8.0/refint/TecniStamp.Infrastructure.dll b/TecniStamp/TecniStamp.Infrastructure/obj/Debug/net8.0/refint/TecniStamp.Infrastructure.dll index 6ce0e627d27998c43fede78cb89beaba41aa79ba..80e94fa2dcc9723530fe6254fcfa79aceee0e595 100644 GIT binary patch delta 1531 zcmaKse`s4(6vxlK_uco>HBHmBYZDFFM=g}KmY3#r?V}SCHfj7t3t85=q4u>&Wez&l zRsYa!Y3R^`KUlnzfgmgn#u)lfGjWay3vMtFHrV`Q;6DZh|C9b#aQ}Gj*%Bjy3Fq^^ z-*e7AFUifjYnipo*$w0VC2zC*ahz}F%2y7A=5qiufUkLguu-{mNi)kgz`mu+;;=aQ%du zHHV(RU;zxA#>oMI%UWkwSB@;dbwaPY+6iFbbs(38YpBCoPv>6Thu1skht#*`@N>8j z5*Sg84vYxKD;Nwzuhw;~C5BKP)-RpAEXGZ^EPj#^IB!j=ZEHHqaC)0HXTE^Fx-$%Y z=srQ$h7pE!>vijMRP7+_FnoanbLe_oTon3R+#p2NI{~Gx2VP>^O15Q-k2r(b6pn^l z5Rs2KZ@NcAi60{{M?PsVeI_J>2p%@8(h5q6S};>fnyAi*Y%MoAad@g>JZnd>U>e2jDJp7#<*#&}EFm6gbGe zFok>>GRQ3D4!GG|?xPkQ>GYs#ZwfBwZu@E9p9E;Cce%y1$>aO}dyOlO{7y z+9$n6x^^+-4cR`nhCIS|kZhB;U z)OW#C?IwB)+XG-!r#eDbFk5)<$g$7IcgH9FyswsGtNk{E_?R=c+esuH z#~bq!i8ovCyQ&_>o>hOvB9Vi|eh3SpLda+#$=7mM@Vt7$+?A2iBJ=Re4h4Xv<|8t&m z-h4doTN$nlUp#GGw4dIop9{;c3iX@&0=@!}16>n9(5Oc`eHFk*ekl)xbwu{-FGWt4 z);4a6eKPpzcSk?l-gP#6?N#lC@a^?CKG?J*He_gsdks@am?&g`xlTY(e@c&9eLE`_ z(0d$sN$Z?VI)8ZP>*<4s+^*9Bz@W8vERS=fgRb5^_W3Sa=g33fv$kxdMtn>`W6?&@ zL9vrUP`KTm6>ZWgwcq|{P1qLF!VUGr?7)xqX1#3hPPx;)_PBMP`b>%-zPEGsB~mt2 zB#5gtZj4;VD%XupUH51`;~m|&ECoh0bPGI0hq)|e%N;ZRllqyrdv=C|v64R3eb=<; zMsHf)cS^Nto<~NTvfl3W{AF~la_h~AvRk!?*}ux&7HQ>a)$Wgop;dNR=9ITp%**{P z_YiTTtlHkz_=C2;<8)8^t=ZScHnii4+D1S9bz%rjVlN&Ow_t%7hoAQBKtFK^DdGrr z5%ZisK+K|sBgPQE!B50P_``5GGs&4M>l)7DU!w+%C1aj5zu*Tvo>fgYzq>{)vKGP} zw@J8}2`Wfp*){yQ@A>I8E=4_T1hgoILGn>ps zW<AoZetkpBI08wHM?V@w7|MVZT-I@i}I1mWf`gvEUKGSuAo||_cVjW($L#%Cl zvF?Es-Hr7d#zkK`8cUX(ax@h$C6h&`9FN6g1J2~2Qyh$yrqabkG?8{vQ)PX*=dkV% zeWXW2!9Zf=HQ+uTdkT6w)FU$meI|6W5tRke2!v-;E{!N+NTLJ>Wzs1+Jtgu<6gd;8 psv863CNW4X5@WPy3Te^_>Pe7tsB;SC#=?i&rJP9cd#E0@{s$dY@tObt diff --git a/TecniStamp/TecniStamp.Service/Interfaces/IManagerService.cs b/TecniStamp/TecniStamp.Service/Interfaces/IManagerService.cs index 882a1e3..1c85580 100644 --- a/TecniStamp/TecniStamp.Service/Interfaces/IManagerService.cs +++ b/TecniStamp/TecniStamp.Service/Interfaces/IManagerService.cs @@ -2,5 +2,7 @@ public interface IManagerService { + IPermissionService PermissionService { get; set; } + ISezioneService SezioneService { get; set; } IUserService UtenteService { get; set; } } \ No newline at end of file diff --git a/TecniStamp/TecniStamp.Service/Interfaces/IPermissionService.cs b/TecniStamp/TecniStamp.Service/Interfaces/IPermissionService.cs new file mode 100644 index 0000000..4020e71 --- /dev/null +++ b/TecniStamp/TecniStamp.Service/Interfaces/IPermissionService.cs @@ -0,0 +1,8 @@ +using OAService.Service.Servizi.Interfacce; +using TecniStamp.Domain; + +namespace TecniStamp.Service.Interfaces; + +public interface IPermissionService : ITService +{ +} \ No newline at end of file diff --git a/TecniStamp/TecniStamp.Service/Interfaces/ISezioneService.cs b/TecniStamp/TecniStamp.Service/Interfaces/ISezioneService.cs new file mode 100644 index 0000000..3439568 --- /dev/null +++ b/TecniStamp/TecniStamp.Service/Interfaces/ISezioneService.cs @@ -0,0 +1,8 @@ +using OAService.Service.Servizi.Interfacce; +using TecniStamp.Domain; + +namespace TecniStamp.Service.Interfaces; + +public interface ISezioneService : ITService +{ +} \ No newline at end of file diff --git a/TecniStamp/TecniStamp.Service/ManagerService.cs b/TecniStamp/TecniStamp.Service/ManagerService.cs index 3da68f9..c247d03 100644 --- a/TecniStamp/TecniStamp.Service/ManagerService.cs +++ b/TecniStamp/TecniStamp.Service/ManagerService.cs @@ -4,10 +4,14 @@ namespace TecniStamp.Service; public class ManagerService : IManagerService { - public ManagerService(IUserService userService) + public ManagerService(IUserService userService, ISezioneService sezioneService, IPermissionService permissionService) { UtenteService = userService; + SezioneService = sezioneService; + PermissionService = permissionService; } + public IPermissionService PermissionService { get; set; } + public ISezioneService SezioneService { get; set; } public IUserService UtenteService { get; set; } } \ No newline at end of file diff --git a/TecniStamp/TecniStamp.Service/PermissionService.cs b/TecniStamp/TecniStamp.Service/PermissionService.cs new file mode 100644 index 0000000..0fe76b1 --- /dev/null +++ b/TecniStamp/TecniStamp.Service/PermissionService.cs @@ -0,0 +1,13 @@ +using OAService.Service.Servizi.Implementazioni; +using TecniStamp.Domain; +using TecniStamp.Service.Interfaces; +using TecniStamp.Service.Repository; + +namespace TecniStamp.Service; + +public class PermissionService : TService, IPermissionService +{ + public PermissionService(ITecniStampUnitOfWork unitOfWork) : base(unitOfWork) + { + } +} \ No newline at end of file diff --git a/TecniStamp/TecniStamp.Service/SezioneService.cs b/TecniStamp/TecniStamp.Service/SezioneService.cs new file mode 100644 index 0000000..e45fe04 --- /dev/null +++ b/TecniStamp/TecniStamp.Service/SezioneService.cs @@ -0,0 +1,13 @@ +using OAService.Service.Servizi.Implementazioni; +using TecniStamp.Domain; +using TecniStamp.Service.Interfaces; +using TecniStamp.Service.Repository; + +namespace TecniStamp.Service; + +public class SezioneService : TService, ISezioneService +{ + public SezioneService(ITecniStampUnitOfWork unitOfWork) : base(unitOfWork) + { + } +} \ No newline at end of file diff --git a/TecniStamp/TecniStamp.Service/bin/Debug/net8.0/TecniStamp.Service.dll b/TecniStamp/TecniStamp.Service/bin/Debug/net8.0/TecniStamp.Service.dll index 8537c0eb7091b380973615b194bf325cd2a71418..e3b4e983052e34b96daf8f730349c9b3d903709f 100644 GIT binary patch literal 9216 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 KZIl1=8Ten{rGlRT delta 3294 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 delta 1574 zcma)6dr(wW7(eIU-FxrK@)nSXx`HN1JR}BrgFGYzOdc!TMFd1t0ttCJ>;MbPLy^W7 zE>ePm22p7$fbJB1$0k(=?50D1>0p^k*(ZGFDKG+MK zH9N5TOp8H4>7dxHqvT%oqxe0iVH!mmeX1eSLI}zrYmgNnA`qPg+Z<_tVGCjh0y*b5 z!Ec0G6W&1cgDi2*AK5vT_6bHG8sQ9uWbkvArg9Pk+6ZNP_s+5|?c z2?B)xvVhHioq)w8M%5&NngkeqBOqWSsZk_yV@c%0GAPiKg0oCdDF zEMM|MS%}wT;nwE6iWTS@D+I!~70xbW0Qr01i(%9w69e)cg{y*OLbMUYpV|oiDy9ey z<3*i?5>spg*d7##1<03@U69~o!AAsoy-P3AQ*<#)aYR>LXpst)=x+R zOHA5H@5`1>R@=WHs8Bq9zs|dwyzp~f`nOVXdrqsqW23IIBB$S@qM|3=+lq>U<#maJSmhN37Mbg$@#sn)CmWqoc<8F%XGvnj$ zH5w1>4?jSw6IV;K%BBacLQ1CNDwuP&g?lM@q8BSelDq81r7sHS=)V422Y+a)Pf5I= zl{sO*DtSOFf$rWFR+M1$DCv&6o;%UpqAfp`*RtNLGFBb>V{%rO(o*SSxMRj4Y~Oud z^~ItGgDHvu*v3()swx=1S{*MPtg>tW!lA{JymbB4ia=F@NURYgS=oO}Cqs4L zaK^{fyZf=E@ujY6&{ZeNHzV5h)vNWsA%9)p(AyBZKQ+2$$Ihs84pARJ49(Awi(@TM z&TaOwt{)S;IA}9c_V#6kVR8B8p|B@z5hI;07L}cS3jZU%!DVe-xki`nOb8pEkMs;U zo;?25Br*GR%c#c&|7_3wBkHk}A9|FCJM-J_^|+spsJ&4q99etg0_#*O24Qt^gu8pYyJO)f8H(;5SK z-gdMQK0X4Ty&1tUVC7KZIT@LWhfKIWSAFicm?MEv#kd1SmGi2JSIxY-!K+?g{lcr4 z{HG)kTP=VspIJxj&gav|$e3XG8adpxJ$oGAAR8MCDcQ35yu4M*rN^dhdV@fj2Dr=K t;g~qTH>o45sS`$qWcW*OEX9$Q8R1_s7@Ai>fAWB_T#>a@(9 zR4aXbeP=8E(BjmhV*PZzvdogiqD+0gywdd468(b2Dp-0kd=SHkozU{5z2}yEJgvBRcuNq6EyY$+==Y zlY6AOHrp#_Ve{W=675vbBOJgW2Z&6zQvnC^<_9Wwn6V_@N)i$jC~h4z*m3%Ifd)HD zf|@)*S8Os+aPvG(V{D!#Ibi`UC(h$QODC__;+@s*gQek5SxAVBnG~X9v9BQ&(q_Fd3AG}euW~Ij7(A{iU?4~YFA$XBm>>x L?c01f@FX_?wHb+$ diff --git a/TecniStamp/TecniStamp.Service/obj/Debug/net8.0/TecniStamp.Service.csproj.CoreCompileInputs.cache b/TecniStamp/TecniStamp.Service/obj/Debug/net8.0/TecniStamp.Service.csproj.CoreCompileInputs.cache index f8d40a5..52b6918 100644 --- a/TecniStamp/TecniStamp.Service/obj/Debug/net8.0/TecniStamp.Service.csproj.CoreCompileInputs.cache +++ b/TecniStamp/TecniStamp.Service/obj/Debug/net8.0/TecniStamp.Service.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -6f36ef590baa862fa6c219f800cbd2689a35fdf3b6b551ee322edc6d6ab32433 +5cdf6308242000d7551312b189cb9d792c9ce6661e9a7ca09dc3e9c42ffba30c diff --git a/TecniStamp/TecniStamp.Service/obj/Debug/net8.0/TecniStamp.Service.dll b/TecniStamp/TecniStamp.Service/obj/Debug/net8.0/TecniStamp.Service.dll index 8537c0eb7091b380973615b194bf325cd2a71418..e3b4e983052e34b96daf8f730349c9b3d903709f 100644 GIT binary patch literal 9216 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 KZIl1=8Ten{rGlRT delta 3294 zcmZ`*d2p2F8GoMlyLLZv?0%aBag1G=QK`$RI^LS~et5+5#e_2+6WR zCk&S}#ZRb1Ne4w|q-w^JnU)OJatt{Aqoa7W)*%Bj*col7*fP$vgWBKo?vjdQzuouu z+{b%;y94tFI)1jRyy(ySUZ?DHiOORWxPfRA6m~{=sCECZzMD6{m1wajI*8se_QxYR zD~WO-&uJmL*N>|y{tB*kj}$=_!9xs*j1x+Hz&2G&2vT;;c_fi3yn^4T@%i!XvyX4}q?oD1lST zf`hG6ju0b-xtMlg$`sNsCXW&bsmln7GEBm)twn*!x*(TDsof{mT-7h+i^5V&T@_ZPGqK24jcim`_J0Z| z#QIfR4HO%&kZ#2CtVA7{shw)#%~rxzDtJpT7J9+*)zR2Ps!vQ2OZ9^;L@OYrXeHZ; zm6(ELw`V3iVXP!#tJ}WFOi)iNY$v9|fyN4N)jNrLf6R>XWdC!sZdMMKuVOpVqoCJ> zU;2|r)~;W(2@63#$VYw9ie*db$KXT4-?ePP9MFEqIexEI-GV8}u_AP*J%pctQIGL0 z4D7AWBAKu^S`PZBt>W~jCQgXfUNEj%HqA5zx2WG+`4p1PB*$23+Eiga0DYe!*sgJz z#!oe#P@*5z8C;!VuaZ1Jw*$ZjHQ$7sHVpw?^tsKl@njW9?c% zHMUK^V@dR^CD=@Y4_o3{s`;29>F%Un$ED}YUdN+un&lKx$obgz=%hKzDWPrJ{}7t< zsM0xSN2$YZw94sS=PAOGzC@DlJ+np@hIR|!qRA&jJ9!4r8kY`2vT?0VdIq-T^ceQa zzzT`_B@u|J4Q(}Ap*O9qGNrzk!P#ykXGr6kAc zyx9xfYpq4;yVZK&0c#`hlCu?fo1J25bqDY<8ssH0X@BRWQELdAZY_NjO!84y^uw&Q ziH9I<(o$MnUtoiFWsLk14YQmQdCun^aYosqw__rS=NU+2^4p12H z1)`6F5{Ij+pYyp={(q8`AD7aW6bw?a4wMo$4sxZIF7vC{f0s_+JwtSv-{k4~kTX4t zGs|>8`eb@t<0WhbQ_DCi+J{BH>65Wu!mMN1hDr=qudzkxLF``M2l;bB_9 z$LUYh#ea1!0#7?1(o8yGU#As3Y~7&u=}ls8Mgtb7-=|-q@Jy;w6FG?8pUiV;*s9}& z+G!!IbKttpS^#{(p2%_9M6anh_0hjn75#|zaWy@F-?Mt0=TEqvB6J;CN)c606;uYS zqx*qP^ayYUrGTBZ2Y8R@)3g+%LnrN|Rdhpj>ZEfuuGIQfTEB`Orzg2r-lNh0;>;iWaVFgTbP)SY{UElQLJ$S7?2e z<~v!|U@q&1w1(7+(5$8B=^Wk%hy(ka^Wiv(M#0Cp6V3)c3P(_a zT!bksWf1xtphF%_g*Hmnz!;9;?T|b0|6&QPr@v7ZH~SlNBk37Pee+VuZCT92(8vw= z>QnO#x)|=s*Zuza4So~w^ZxZ3ALus)est~?n||)&q<)XyS~y=9aWPSO^9AThO>?p| zLVtAHXea*S{1($aMT;oJi)gyPJns{~J3s0l&40+B8>;e8hSrSKhUXe1+X~L8&}@6| znQMoS-E;6z=*FZi@4V(OoYNGMt^p|NVU`b;EX%N}d5wdiZpsO;~5=aE4w7og-%Ixo_!|%G&122zmZLhgFywb3} zN{j;2M&HT~IN4Qzt_vf_u*2(Y=+HObXLwx3@x%i`=d46}uTrxGZj7f(GhP>#QMwC( z%`DgxnFV_SRf2l?WyQ<{LIa7cqra>8*wprh#@3$X>V~$ap4QgxRV~Tx zmd2jm_U`6}=JsS;?`oVPCcmd-#yqrzUIL6eGyZ&#{N7>WMN6d9-55{fkMGkH$Ibdu zL?BjU#PNqcKFJ>|DG#kETl3)1@xr@y{v~I|slhi6`k~VP#;kJ9O{L`i&w`#Wubleq z%YS^%#~;rA;g{@tgpciy7peZ%k@rdu^GIH_)mYq44b(`j)I&*H4Ze+8i92u}?XRD&?~_wPkJ!cm~60v1pG#-w+`TzAFG+Bmj&Cm?C74Ou%siNC0q#HVGau zSxB@&amyr)5jbRrF@X3a8sP}=q7j951J?p~0Cxe~VvJlcg_Z)x0Dl5p3p@bKP!#f} zFq#Lv6}S?(6}S^v#KFjcL!n^crNGC5FLEdiDxfi{peakTSV1LU!y~ zJXS+)KcpEL;{t{?DVv^-Ci4Wk^E?X{;}ck9ctejqeoE1;fownkW1+UNU|7>Qfh?Y7y!rzVhPDO zLJj6Jj&Sob{c}(*8S@CNl<~nd3SyRF21ykv@B^4!u>QQcqMR3zeAWo7vdexk$3FiYwOlUU`z`cseeo ze$aXn#qrDE7nSRILcL{USC6wg+|)=OnygOx&)qpjVs;GesmYlmKERf_$XmXcv}dPq ziA%e{(8!iPvHt6UmmbaEJ0|w^Q|2RSkAxEZl}OHJu~+_BWy|uQhcyN7*@SK5i|!ph z7yni7`i9PN6^{J-hGG1L>coWP=#+${3|o1KS`{B1oDvn6=%MvJ1H~;0CsgYZq?vuQH6Bp34>ANw>!jRM+jx3;G8_3Ym+Qy*tlF%oO;~ z9+h~jRkD4B;opm(vscEpaHDv+*|~YS1-Zqnm)_++MV{h_DKi>thNjkS6kqq1C0l;X zJ-%gThs9m5Rhh+swf*DUPL_*NYC!$7yW4Z3^q}|Emb3?+b2GlsE_h{IIMb;?TT>Iln>+{Aj~l8i=_(874XJ7yi)s5W zbgy%NYU^;cr_8&%uytW^^RvN~-Y5H;T~j~v33aWQV()6BsWg~&{-dyWUD7(rFGsqK z-la*YJ{Z(lC2I6LGx>#+>(5=K+kUTJ?A~kcu7BazuELCvvZ=mP1kI9k(M|c~bg93` zoXHL4J!39?Coc~w$=iB!`mU&~89s&g+q|r<1U}9zNpYyyw=3-Tn0t5nJDw~xu&$CV ztAE_I)1+|wgTV>886xjyEb2bmFkxNIPZFLN#yrem8gtmw`kDCcBh&fQ7mNzI7_k;w zJ*sU!^jnGDYoF`@e`AZm`M24+h|zDYh>e8?aie-hJz0`>Q<2tL*ymkzYLnTxft4v=VEI$3tQY@z6L5v9A<6mMz(V8_|+o#C%T7Ibyycrk$8>FyRbo zu(aWnA)2lwBiA8v*OIZ*5KSb1R>piO4~~Nd4rj7$%1FhV9I}y|bVPd`F<%Zvl8{IS z+DH~8w9u0bm|CA4=!_St)35d8sNPC_UE delta 1574 zcma)6dr(wW7(eIU-FxrK@)nSXx`HN1JR}BrgFGYzOdc!TMFd1t0ttCJ>;MbPLy^W7 zE>ePm22p7$fbJB1$0k(=?50D1>0p^k*(ZGFDKG+MK zH9N5TOp8H4>7dxHqvT%oqxe0iVH!mmeX1eSLI}zrYmgNnA`qPg+Z<_tVGCjh0y*b5 z!Ec0G6W&1cgDi2*AK5vT_6bHG8sQ9uWbkvArg9Pk+6ZNP_s+5|?c z2?B)xvVhHioq)w8M%5&NngkeqBOqWSsZk_yV@c%0GAPiKg0oCdDF zEMM|MS%}wT;nwE6iWTS@D+I!~70xbW0Qr01i(%9w69e)cg{y*OLbMUYpV|oiDy9ey z<3*i?5>spg*d7##1<03@U69~o!AAsoy-P3AQ*<#)aYR>LXpst)=x+R zOHA5H@5`1>R@=WHs8Bq9zs|dwyzp~f`nOVXdrqsqW23IIBB$S@qM|3=+lq>U<#maJSmhN37Mbg$@#sn)CmWqoc<8F%XGvnj$ zH5w1>4?jSw6IV;K%BBacLQ1CNDwuP&g?lM@q8BSelDq81r7sHS=)V422Y+a)Pf5I= zl{sO*DtSOFf$rWFR+M1$DCv&6o;%UpqAfp`*RtNLGFBb>V{%rO(o*SSxMRj4Y~Oud z^~ItGgDHvu*v3()swx=1S{*MPtg>tW!lA{JymbB4ia=F@NURYgS=oO}Cqs4L zaK^{fyZf=E@ujY6&{ZeNHzV5h)vNWsA%9)p(AyBZKQ+2$$Ihs84pARJ49(Awi(@TM z&TaOwt{)S;IA}9c_V#6kVR8B8p|B@z5hI;07L}cS3jZU%!DVe-xki`nOb8pEkMs;U zo;?25Br*GR%c#c&|7_3wBkHk}A9|FCJM-J_^|+spsJ&4q99etg0_#*O24Qt^gu8pYyJO)f8H(;5SK z-gdMQK0X4Ty&1tUVC7KZIT@LWhfKIWSAFicm?MEv#kd1SmGi2JSIxY-!K+?g{lcr4 z{HG)kTP=VspIJxj&gav|$e3XG8adpxJ$oGAAR8MCDcQ35yu4M*rN^dhdV@fj2Dr=K t;g~qTH>o453$g6#nj;d2g0>%JeZUr8ae-AXG~;wSzEHwOEaS7}^vx#RyE>fiwzYTTwJH zqqu=oCAu<6LeI0 zQ>;3#!z>B!E~V7W;(Ghc8K%NJWM-JEA;T**Pm?A8jfJNZSi#k`35qihA4Ll#uu zF}%nj8LpN@di0gk3ga=d^U=Y@Gdv??S={Fzp%U6c=Ttf)+Hiort+YzC;mu|#hhexq zlBS`+CMkO#d0(DwANBc66lo4x23o-Zo^EA{_4dugUCuUS9Xw{=gVtu5*=-f`>_G|A}%(LA85w_gy8^^xH%RG`JzMt^MI2JMcnSR7~s(F8uNe>?*Q1FpuNrPjQEHu*4 zT#wJVWclYnN6ZI2YGdpp)2cVj;89)}3;$%9&WH6R z250lGorq7UG9Gv3kIpDsn678ydpaaW<2QVbrSKK#cN#LU6v~Ld7=44#l)$57FQn zVi`6nZYA>m3#r80#6|c(Bpie++Cj)-{h&%I_w*`EG2)$$K5WMfbfMO&=Ri*}^_Ylh z#8c2htifX98E7Lm;$GrBJV|W9KH|lAli05M<-}|=Ze)Y`nzRL1;y2Tx_A1rWYIk7^ zb|RygQ~f5@x2Up9l|gMgsLJDtZ>hdt^>;P?uqxlGGORJk8tKwkKu8}q6+0d8uHp~R zS=gSrq37y#nf6TYhMukr)@1ru{zvNjKS>*Tt&v#^S~IL^d8`V@O_|%noNh-j&Mqrtlrp^Bt)aLjm7BXeKbi`T#y^u; z1rh?u;LJi3p4|K%SIawlsa5XXKJnrD#)f29cPf+4WEwlu$vKVPsnqIZLuaZXmFiA( zCX;j1$=P$$-D&VL@@s2x>`Xrs74h57dngul`wQP?GP!%iZXTFYZspp%FJe1~O3Kgj zEonpp&uSOC`PZ1?`!~a1BRXj%F^87uDXb=Ipqe5I@8-XAC$%KzYUFIKyOH+1$?HO` P`LD`d4f=IBkO=$>IoG}k delta 2055 zcmZ8ie`r;86#snhefRFY>-P5E+fQf6n{R6y)_8lH+p>{Qr%j7FLybnDzHM(ZhJsp_ zWWI?gMF!6MhyD?vMt?XXw2@);Pgv5RB*dT$Y$6GPB_yPXMxS%u+sy9ce7@&=&iS76 z{c+yCV_jpNhu&IHee&!@6rO1;h|e)eAVMOTC;wSJKJjAsqt!s45SxI@wx6jgp92)r zK19c3ey#O{-*5W7Kq;v-CE|Z#7Me=`s%bDaldg5oMBbe{^;5;h>fW*7#PXA`y)-!) z4csy{m}UZbR#GfDSeFL6!hm7Y4u6f?_{QjTI$^uW+WqvNu!uQqlmWXHtJU$V5oTHwwdl0(jij6F zq>1lS_jn#(+F=|qJ=6{Mu)sPa-oG_6Y8|Cs0?Tnxr%X8{Ll1e6+wvU`H*DXDA=ish zrxJZm6O9MhfVe-9CEjti5bp-I zVNF^Vc%b@l-~i+D){W4&ILI@av9932tR<1-ytceAcf-7nBYMM<=0eFu=LGNgVbW8N zSZ7!?@4H~GIiGU}GbLnR;eWv_QvRVOV;-11o~3!ycSP3%ixi$K<^|#zLHXt)qC{WSE~3eFbt-W|O)zN)4)e5c|kw756H?Px<}I9K$=9Fvs9C z=?BVxs4?eNKd&+0C|+0Qx_W<8#x_#kF;X{fzQ{2}LaBPCx{a)Kh0*fLz&b_7;=McU z;UeB-P}}t?zGlN-a;9cc7>hrfu{M7eZ&~JeoMrJ0L*$EzMTqeo;9)+`x71^UG*KF` zn18gD{&-2k?nj0HSxLi&9yXLT+<%{bH6P`+t2xu*65Wq7o$GNK^8O5Br;f#iu?)8y zzbpKm-&=A08ZCbnKN>sG|JnKE$Ll^-G;LP-PR z=OcJ}$;MptM{lv^28-N^=!l8++OA5mqbv0c&w~#Q%~%(RBUYzsxfeGTu?(lgdV_Ih zj8Jvr^{oD8Fm4fJWBc>9BCHi?KPo za8YJpQEDjLInb7D>&$dyhyB}?DUa*nB7%JPjn|g@T~(3T<-$i#*7v9A>G9f1YkIZ6 zv+Agyw2n=NtK03qP9%{+JBIjz9H!pEKfw^~b_^)fO0P%@twAgz4iHm}$)b~b8|So9 Z%W!5E!@fUnYbc%nY-5Rje#etV{{r*jLQwz! diff --git a/TecniStamp/TecniStamp.Service/obj/Debug/net8.0/refint/TecniStamp.Service.dll b/TecniStamp/TecniStamp.Service/obj/Debug/net8.0/refint/TecniStamp.Service.dll index 2d854508ed9dbf2288cab6e1837a0535849f03ba..b72858784f6bda35378e4490d4240ec00c6e57ad 100644 GIT binary patch delta 2726 zcmZuzX>3$g6#nj;d2g0>%JeZUr8ae-AXG~;wSzEHwOEaS7}^vx#RyE>fiwzYTTwJH zqqu=oCAu<6LeI0 zQ>;3#!z>B!E~V7W;(Ghc8K%NJWM-JEA;T**Pm?A8jfJNZSi#k`35qihA4Ll#uu zF}%nj8LpN@di0gk3ga=d^U=Y@Gdv??S={Fzp%U6c=Ttf)+Hiort+YzC;mu|#hhexq zlBS`+CMkO#d0(DwANBc66lo4x23o-Zo^EA{_4dugUCuUS9Xw{=gVtu5*=-f`>_G|A}%(LA85w_gy8^^xH%RG`JzMt^MI2JMcnSR7~s(F8uNe>?*Q1FpuNrPjQEHu*4 zT#wJVWclYnN6ZI2YGdpp)2cVj;89)}3;$%9&WH6R z250lGorq7UG9Gv3kIpDsn678ydpaaW<2QVbrSKK#cN#LU6v~Ld7=44#l)$57FQn zVi`6nZYA>m3#r80#6|c(Bpie++Cj)-{h&%I_w*`EG2)$$K5WMfbfMO&=Ri*}^_Ylh z#8c2htifX98E7Lm;$GrBJV|W9KH|lAli05M<-}|=Ze)Y`nzRL1;y2Tx_A1rWYIk7^ zb|RygQ~f5@x2Up9l|gMgsLJDtZ>hdt^>;P?uqxlGGORJk8tKwkKu8}q6+0d8uHp~R zS=gSrq37y#nf6TYhMukr)@1ru{zvNjKS>*Tt&v#^S~IL^d8`V@O_|%noNh-j&Mqrtlrp^Bt)aLjm7BXeKbi`T#y^u; z1rh?u;LJi3p4|K%SIawlsa5XXKJnrD#)f29cPf+4WEwlu$vKVPsnqIZLuaZXmFiA( zCX;j1$=P$$-D&VL@@s2x>`Xrs74h57dngul`wQP?GP!%iZXTFYZspp%FJe1~O3Kgj zEonpp&uSOC`PZ1?`!~a1BRXj%F^87uDXb=Ipqe5I@8-XAC$%KzYUFIKyOH+1$?HO` P`LD`d4f=IBkO=$>IoG}k delta 2055 zcmZ8ie`r;86#snhefRFY>-P5E+fQf6n{R6y)_8lH+p>{Qr%j7FLybnDzHM(ZhJsp_ zWWI?gMF!6MhyD?vMt?XXw2@);Pgv5RB*dT$Y$6GPB_yPXMxS%u+sy9ce7@&=&iS76 z{c+yCV_jpNhu&IHee&!@6rO1;h|e)eAVMOTC;wSJKJjAsqt!s45SxI@wx6jgp92)r zK19c3ey#O{-*5W7Kq;v-CE|Z#7Me=`s%bDaldg5oMBbe{^;5;h>fW*7#PXA`y)-!) z4csy{m}UZbR#GfDSeFL6!hm7Y4u6f?_{QjTI$^uW+WqvNu!uQqlmWXHtJU$V5oTHwwdl0(jij6F zq>1lS_jn#(+F=|qJ=6{Mu)sPa-oG_6Y8|Cs0?Tnxr%X8{Ll1e6+wvU`H*DXDA=ish zrxJZm6O9MhfVe-9CEjti5bp-I zVNF^Vc%b@l-~i+D){W4&ILI@av9932tR<1-ytceAcf-7nBYMM<=0eFu=LGNgVbW8N zSZ7!?@4H~GIiGU}GbLnR;eWv_QvRVOV;-11o~3!ycSP3%ixi$K<^|#zLHXt)qC{WSE~3eFbt-W|O)zN)4)e5c|kw756H?Px<}I9K$=9Fvs9C z=?BVxs4?eNKd&+0C|+0Qx_W<8#x_#kF;X{fzQ{2}LaBPCx{a)Kh0*fLz&b_7;=McU z;UeB-P}}t?zGlN-a;9cc7>hrfu{M7eZ&~JeoMrJ0L*$EzMTqeo;9)+`x71^UG*KF` zn18gD{&-2k?nj0HSxLi&9yXLT+<%{bH6P`+t2xu*65Wq7o$GNK^8O5Br;f#iu?)8y zzbpKm-&=A08ZCbnKN>sG|JnKE$Ll^-G;LP-PR z=OcJ}$;MptM{lv^28-N^=!l8++OA5mqbv0c&w~#Q%~%(RBUYzsxfeGTu?(lgdV_Ih zj8Jvr^{oD8Fm4fJWBc>9BCHi?KPo za8YJpQEDjLInb7D>&$dyhyB}?DUa*nB7%JPjn|g@T~(3T<-$i#*7v9A>G9f1YkIZ6 zv+Agyw2n=NtK03qP9%{+JBIjz9H!pEKfw^~b_^)fO0P%@twAgz4iHm}$)b~b8|So9 Z%W!5E!@fUnYbc%nY-5Rje#etV{{r*jLQwz! diff --git a/TecniStamp/TecniStamp/Components/Layout/MainLayout.razor b/TecniStamp/TecniStamp/Components/Layout/MainLayout.razor index a7ebcef..e7580eb 100644 --- a/TecniStamp/TecniStamp/Components/Layout/MainLayout.razor +++ b/TecniStamp/TecniStamp/Components/Layout/MainLayout.razor @@ -1,5 +1,34 @@ @inherits LayoutComponentBase +
+ +
+ @Body
diff --git a/TecniStamp/TecniStamp/Components/Pages/Account/Login.razor b/TecniStamp/TecniStamp/Components/Pages/Account/Login.razor index 9cb402c..5ba9652 100644 --- a/TecniStamp/TecniStamp/Components/Pages/Account/Login.razor +++ b/TecniStamp/TecniStamp/Components/Pages/Account/Login.razor @@ -1,5 +1,5 @@ @layout LoginLayout -@page "/" +@page "/account/login" @using System.Security.Claims @using Microsoft.AspNetCore.Authentication @using Microsoft.AspNetCore.Authentication.Cookies @@ -87,6 +87,6 @@ var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); await httpContext.SignInAsync(principal); - _navManager.NavigateTo("/home"); + _navManager.NavigateTo("/"); } } \ No newline at end of file diff --git a/TecniStamp/TecniStamp/Components/Pages/Home.razor b/TecniStamp/TecniStamp/Components/Pages/Home.razor index 6c5b8f3..d2b3c0f 100644 --- a/TecniStamp/TecniStamp/Components/Pages/Home.razor +++ b/TecniStamp/TecniStamp/Components/Pages/Home.razor @@ -1,10 +1,28 @@ @attribute [Authorize] -@page "/home" +@page "/" @using Microsoft.AspNetCore.Authorization +@using Microsoft.EntityFrameworkCore +@using TecniStamp.Components.Widget +@using TecniStamp.Domain +@using TecniStamp.Utils -Home +@foreach (var item in TileList) +{ + +} -

Hello, world!

+@code { + public List TileList { get; set; } = new(); + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); -Welcome to your new app. \ No newline at end of file + var roleId = await MembershipUtils.GetRoleId(_auth); + TileList = (await _managerService.PermissionService.RicercaQueryable( + x => x.RuoloId == roleId && x.Feature.Sezione.ParentId == null, + includi:x => x.Include(y => y.Feature).ThenInclude(z => z.Sezione), + ordinamento:x => x.OrderBy(y => y.Feature.Sezione.Ordinamento))).ToList(); + } +} \ No newline at end of file diff --git a/TecniStamp/TecniStamp/Components/Routes.razor b/TecniStamp/TecniStamp/Components/Routes.razor index ae94e9e..ec8963e 100644 --- a/TecniStamp/TecniStamp/Components/Routes.razor +++ b/TecniStamp/TecniStamp/Components/Routes.razor @@ -1,6 +1,19 @@ - - - - - - \ No newline at end of file + + + + + + + + + + + + + + +

Pagina non trovata.

+
+
+
+
\ No newline at end of file diff --git a/TecniStamp/TecniStamp/Utils/MembershipUtils.cs b/TecniStamp/TecniStamp/Utils/MembershipUtils.cs new file mode 100644 index 0000000..8491cba --- /dev/null +++ b/TecniStamp/TecniStamp/Utils/MembershipUtils.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Components.Authorization; + +namespace TecniStamp.Utils; + +public static class MembershipUtils +{ + public static async Task GetUserId(AuthenticationStateProvider auth) + { + var state = await auth.GetAuthenticationStateAsync(); + var idClaim = state.User.FindFirst("UserId")?.Value; + + return Guid.Parse(idClaim ?? Guid.Empty.ToString()); + } + + public static async Task GetRoleId(AuthenticationStateProvider auth) + { + var state = await auth.GetAuthenticationStateAsync(); + var idClaim = state.User.FindFirst("RoleId")?.Value; + + return Guid.Parse(idClaim ?? Guid.Empty.ToString()); + } +} diff --git a/TecniStamp/TecniStamp/bin/Debug/net8.0/TecniStamp.dll b/TecniStamp/TecniStamp/bin/Debug/net8.0/TecniStamp.dll index 633c62deea0eb037358864c0e93c8670952fa5e4..7d805580c2fa6e851ba6341b5c46bd7bf4fe6c10 100644 GIT binary patch literal 56832 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

^PY@cd>KPM#=~Do6g?L|O6-KHOW8q7mX8AYR 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 delta 99 zcmZpe!r1^sEsR^3WZeBN7z`MU7|a+_7!n!MfNXOHV<6iM2$R4f#z0vRHU#pL8BBp> g5|A_ks!3(A0J2ShdQ5<;M1& diff --git a/TecniStamp/TecniStamp/bin/Debug/net8.0/TecniStamp.pdb b/TecniStamp/TecniStamp/bin/Debug/net8.0/TecniStamp.pdb index 57488ed3dfd3913f2c38a8a750c66c345dba6e72..c52542162cfa195d1f227c2ae2ed4fdcd4706129 100644 GIT binary patch delta 12430 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 delta 10089 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 diff --git a/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.AssemblyInfo.cs b/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.AssemblyInfo.cs index 44f0083..2e7ce14 100644 --- a/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.AssemblyInfo.cs +++ b/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.AssemblyInfo.cs @@ -13,7 +13,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("TecniStamp")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8026daf073d66baf32321ac5ab52de8b4048a7ef")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+314cd9eaee3ba473d99f41b9199d0b448a458ada")] [assembly: System.Reflection.AssemblyProductAttribute("TecniStamp")] [assembly: System.Reflection.AssemblyTitleAttribute("TecniStamp")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.AssemblyInfoInputs.cache b/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.AssemblyInfoInputs.cache index cabe78d..3c774c7 100644 --- a/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.AssemblyInfoInputs.cache +++ b/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.AssemblyInfoInputs.cache @@ -1 +1 @@ -1f7f487751bfee95cd57d1b77a4707df04c069b6f440027b707e738eff50f573 +256c08859c76d0ad37b687b6fc285fc502f575ed65c6f504adb5700405fd1dba diff --git a/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.csproj.CoreCompileInputs.cache b/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.csproj.CoreCompileInputs.cache index dd3bb18..255afbd 100644 --- a/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.csproj.CoreCompileInputs.cache +++ b/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -6d9778cdcf6acf5332bad6ce78c8186ce6aa998b6281ef4e207f5dda3aeaa290 +69f31d796ff147eb9cc06e595ab2be7d1454b53b3cd4a832ad8bcdb0a60e327f diff --git a/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.dll b/TecniStamp/TecniStamp/obj/Debug/net8.0/TecniStamp.dll index 633c62deea0eb037358864c0e93c8670952fa5e4..7d805580c2fa6e851ba6341b5c46bd7bf4fe6c10 100644 GIT binary patch literal 56832 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

^PY@cd>KPM#=~Do6g?L|O6-KHOW8q7mX8AYR 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 delta 10089 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 diff --git a/TecniStamp/TecniStamp/obj/Debug/net8.0/apphost.exe b/TecniStamp/TecniStamp/obj/Debug/net8.0/apphost.exe index e8f8285e092c8d7a81c27bab9870b15cd6ea931b..9f7b4fe2ab2aba799a662bacb205fe23d18fbda0 100644 GIT binary patch delta 99 zcmZpe!r1^sEsR^3WZeCY84MXr7?K%M7%Ul584`gwmBE-H3CJ>GFbA?g;+70)K%OB` f)DlR7_$dqqK%NN@T7XrWg6R~7#O>McOjDTv$-@!@ delta 99 zcmZpe!r1^sEsR^3WZeBN7z`MU7|a+_7!n!MfNXOHV<6iM2$R4f#z0vRHU#pL8BBp> g5|A_ks!3(A0J2ShdQ5<;M1& diff --git a/TecniStamp/TecniStamp/obj/Debug/net8.0/ref/TecniStamp.dll b/TecniStamp/TecniStamp/obj/Debug/net8.0/ref/TecniStamp.dll index d7623c1c57d5da12b8613f26906376ca92934e71..197104f89aa9394b6c52ac98ec6198debf823253 100644 GIT binary patch literal 12800 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 delta 4186 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 diff --git a/TecniStamp/TecniStamp/obj/Debug/net8.0/refint/TecniStamp.dll b/TecniStamp/TecniStamp/obj/Debug/net8.0/refint/TecniStamp.dll index d7623c1c57d5da12b8613f26906376ca92934e71..197104f89aa9394b6c52ac98ec6198debf823253 100644 GIT binary patch literal 12800 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 delta 4186 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 diff --git a/TecniStamp/TecniStamp/wwwroot/libs/@hotwired/turbo/dist/turbo.es2017-esm.js b/TecniStamp/TecniStamp/wwwroot/libs/@hotwired/turbo/dist/turbo.es2017-esm.js new file mode 100644 index 0000000..c895234 --- /dev/null +++ b/TecniStamp/TecniStamp/wwwroot/libs/@hotwired/turbo/dist/turbo.es2017-esm.js @@ -0,0 +1,7178 @@ +/*! +Turbo 8.0.13 +Copyright © 2025 37signals LLC + */ +/** + * The MIT License (MIT) + * + * Copyright (c) 2019 Javan Makhmali + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +(function (prototype) { + if (typeof prototype.requestSubmit == "function") return + + prototype.requestSubmit = function (submitter) { + if (submitter) { + validateSubmitter(submitter, this); + submitter.click(); + } else { + submitter = document.createElement("input"); + submitter.type = "submit"; + submitter.hidden = true; + this.appendChild(submitter); + submitter.click(); + this.removeChild(submitter); + } + }; + + function validateSubmitter(submitter, form) { + submitter instanceof HTMLElement || raise(TypeError, "parameter 1 is not of type 'HTMLElement'"); + submitter.type == "submit" || raise(TypeError, "The specified element is not a submit button"); + submitter.form == form || + raise(DOMException, "The specified element is not owned by this form element", "NotFoundError"); + } + + function raise(errorConstructor, message, name) { + throw new errorConstructor("Failed to execute 'requestSubmit' on 'HTMLFormElement': " + message + ".", name) + } +})(HTMLFormElement.prototype); + +const submittersByForm = new WeakMap(); + +function findSubmitterFromClickTarget(target) { + const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null; + const candidate = element ? element.closest("input, button") : null; + return candidate?.type == "submit" ? candidate : null +} + +function clickCaptured(event) { + const submitter = findSubmitterFromClickTarget(event.target); + + if (submitter && submitter.form) { + submittersByForm.set(submitter.form, submitter); + } +} + +(function () { + if ("submitter" in Event.prototype) return + + let prototype = window.Event.prototype; + // Certain versions of Safari 15 have a bug where they won't + // populate the submitter. This hurts TurboDrive's enable/disable detection. + // See https://bugs.webkit.org/show_bug.cgi?id=229660 + if ("SubmitEvent" in window) { + const prototypeOfSubmitEvent = window.SubmitEvent.prototype; + + if (/Apple Computer/.test(navigator.vendor) && !("submitter" in prototypeOfSubmitEvent)) { + prototype = prototypeOfSubmitEvent; + } else { + return // polyfill not needed + } + } + + addEventListener("click", clickCaptured, true); + + Object.defineProperty(prototype, "submitter", { + get() { + if (this.type == "submit" && this.target instanceof HTMLFormElement) { + return submittersByForm.get(this.target) + } + } + }); +})(); + +const FrameLoadingStyle = { + eager: "eager", + lazy: "lazy" +}; + +/** + * Contains a fragment of HTML which is updated based on navigation within + * it (e.g. via links or form submissions). + * + * @customElement turbo-frame + * @example + * + * + * Show all expanded messages in this frame. + * + * + *

+ * Show response from this form within this frame. + * + * + */ +class FrameElement extends HTMLElement { + static delegateConstructor = undefined + + loaded = Promise.resolve() + + static get observedAttributes() { + return ["disabled", "loading", "src"] + } + + constructor() { + super(); + this.delegate = new FrameElement.delegateConstructor(this); + } + + connectedCallback() { + this.delegate.connect(); + } + + disconnectedCallback() { + this.delegate.disconnect(); + } + + reload() { + return this.delegate.sourceURLReloaded() + } + + attributeChangedCallback(name) { + if (name == "loading") { + this.delegate.loadingStyleChanged(); + } else if (name == "src") { + this.delegate.sourceURLChanged(); + } else if (name == "disabled") { + this.delegate.disabledChanged(); + } + } + + /** + * Gets the URL to lazily load source HTML from + */ + get src() { + return this.getAttribute("src") + } + + /** + * Sets the URL to lazily load source HTML from + */ + set src(value) { + if (value) { + this.setAttribute("src", value); + } else { + this.removeAttribute("src"); + } + } + + /** + * Gets the refresh mode for the frame. + */ + get refresh() { + return this.getAttribute("refresh") + } + + /** + * Sets the refresh mode for the frame. + */ + set refresh(value) { + if (value) { + this.setAttribute("refresh", value); + } else { + this.removeAttribute("refresh"); + } + } + + get shouldReloadWithMorph() { + return this.src && this.refresh === "morph" + } + + /** + * Determines if the element is loading + */ + get loading() { + return frameLoadingStyleFromString(this.getAttribute("loading") || "") + } + + /** + * Sets the value of if the element is loading + */ + set loading(value) { + if (value) { + this.setAttribute("loading", value); + } else { + this.removeAttribute("loading"); + } + } + + /** + * Gets the disabled state of the frame. + * + * If disabled, no requests will be intercepted by the frame. + */ + get disabled() { + return this.hasAttribute("disabled") + } + + /** + * Sets the disabled state of the frame. + * + * If disabled, no requests will be intercepted by the frame. + */ + set disabled(value) { + if (value) { + this.setAttribute("disabled", ""); + } else { + this.removeAttribute("disabled"); + } + } + + /** + * Gets the autoscroll state of the frame. + * + * If true, the frame will be scrolled into view automatically on update. + */ + get autoscroll() { + return this.hasAttribute("autoscroll") + } + + /** + * Sets the autoscroll state of the frame. + * + * If true, the frame will be scrolled into view automatically on update. + */ + set autoscroll(value) { + if (value) { + this.setAttribute("autoscroll", ""); + } else { + this.removeAttribute("autoscroll"); + } + } + + /** + * Determines if the element has finished loading + */ + get complete() { + return !this.delegate.isLoading + } + + /** + * Gets the active state of the frame. + * + * If inactive, source changes will not be observed. + */ + get isActive() { + return this.ownerDocument === document && !this.isPreview + } + + /** + * Sets the active state of the frame. + * + * If inactive, source changes will not be observed. + */ + get isPreview() { + return this.ownerDocument?.documentElement?.hasAttribute("data-turbo-preview") + } +} + +function frameLoadingStyleFromString(style) { + switch (style.toLowerCase()) { + case "lazy": + return FrameLoadingStyle.lazy + default: + return FrameLoadingStyle.eager + } +} + +const drive = { + enabled: true, + progressBarDelay: 500, + unvisitableExtensions: new Set( + [ + ".7z", ".aac", ".apk", ".avi", ".bmp", ".bz2", ".css", ".csv", ".deb", ".dmg", ".doc", + ".docx", ".exe", ".gif", ".gz", ".heic", ".heif", ".ico", ".iso", ".jpeg", ".jpg", + ".js", ".json", ".m4a", ".mkv", ".mov", ".mp3", ".mp4", ".mpeg", ".mpg", ".msi", + ".ogg", ".ogv", ".pdf", ".pkg", ".png", ".ppt", ".pptx", ".rar", ".rtf", + ".svg", ".tar", ".tif", ".tiff", ".txt", ".wav", ".webm", ".webp", ".wma", ".wmv", + ".xls", ".xlsx", ".xml", ".zip" + ] + ) +}; + +function activateScriptElement(element) { + if (element.getAttribute("data-turbo-eval") == "false") { + return element + } else { + const createdScriptElement = document.createElement("script"); + const cspNonce = getCspNonce(); + if (cspNonce) { + createdScriptElement.nonce = cspNonce; + } + createdScriptElement.textContent = element.textContent; + createdScriptElement.async = false; + copyElementAttributes(createdScriptElement, element); + return createdScriptElement + } +} + +function copyElementAttributes(destinationElement, sourceElement) { + for (const { name, value } of sourceElement.attributes) { + destinationElement.setAttribute(name, value); + } +} + +function createDocumentFragment(html) { + const template = document.createElement("template"); + template.innerHTML = html; + return template.content +} + +function dispatch(eventName, { target, cancelable, detail } = {}) { + const event = new CustomEvent(eventName, { + cancelable, + bubbles: true, + composed: true, + detail + }); + + if (target && target.isConnected) { + target.dispatchEvent(event); + } else { + document.documentElement.dispatchEvent(event); + } + + return event +} + +function cancelEvent(event) { + event.preventDefault(); + event.stopImmediatePropagation(); +} + +function nextRepaint() { + if (document.visibilityState === "hidden") { + return nextEventLoopTick() + } else { + return nextAnimationFrame() + } +} + +function nextAnimationFrame() { + return new Promise((resolve) => requestAnimationFrame(() => resolve())) +} + +function nextEventLoopTick() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)) +} + +function nextMicrotask() { + return Promise.resolve() +} + +function parseHTMLDocument(html = "") { + return new DOMParser().parseFromString(html, "text/html") +} + +function unindent(strings, ...values) { + const lines = interpolate(strings, values).replace(/^\n/, "").split("\n"); + const match = lines[0].match(/^\s+/); + const indent = match ? match[0].length : 0; + return lines.map((line) => line.slice(indent)).join("\n") +} + +function interpolate(strings, values) { + return strings.reduce((result, string, i) => { + const value = values[i] == undefined ? "" : values[i]; + return result + string + value + }, "") +} + +function uuid() { + return Array.from({ length: 36 }) + .map((_, i) => { + if (i == 8 || i == 13 || i == 18 || i == 23) { + return "-" + } else if (i == 14) { + return "4" + } else if (i == 19) { + return (Math.floor(Math.random() * 4) + 8).toString(16) + } else { + return Math.floor(Math.random() * 15).toString(16) + } + }) + .join("") +} + +function getAttribute(attributeName, ...elements) { + for (const value of elements.map((element) => element?.getAttribute(attributeName))) { + if (typeof value == "string") return value + } + + return null +} + +function hasAttribute(attributeName, ...elements) { + return elements.some((element) => element && element.hasAttribute(attributeName)) +} + +function markAsBusy(...elements) { + for (const element of elements) { + if (element.localName == "turbo-frame") { + element.setAttribute("busy", ""); + } + element.setAttribute("aria-busy", "true"); + } +} + +function clearBusyState(...elements) { + for (const element of elements) { + if (element.localName == "turbo-frame") { + element.removeAttribute("busy"); + } + + element.removeAttribute("aria-busy"); + } +} + +function waitForLoad(element, timeoutInMilliseconds = 2000) { + return new Promise((resolve) => { + const onComplete = () => { + element.removeEventListener("error", onComplete); + element.removeEventListener("load", onComplete); + resolve(); + }; + + element.addEventListener("load", onComplete, { once: true }); + element.addEventListener("error", onComplete, { once: true }); + setTimeout(resolve, timeoutInMilliseconds); + }) +} + +function getHistoryMethodForAction(action) { + switch (action) { + case "replace": + return history.replaceState + case "advance": + case "restore": + return history.pushState + } +} + +function isAction(action) { + return action == "advance" || action == "replace" || action == "restore" +} + +function getVisitAction(...elements) { + const action = getAttribute("data-turbo-action", ...elements); + + return isAction(action) ? action : null +} + +function getMetaElement(name) { + return document.querySelector(`meta[name="${name}"]`) +} + +function getMetaContent(name) { + const element = getMetaElement(name); + return element && element.content +} + +function getCspNonce() { + const element = getMetaElement("csp-nonce"); + + if (element) { + const { nonce, content } = element; + return nonce == "" ? content : nonce + } +} + +function setMetaContent(name, content) { + let element = getMetaElement(name); + + if (!element) { + element = document.createElement("meta"); + element.setAttribute("name", name); + + document.head.appendChild(element); + } + + element.setAttribute("content", content); + + return element +} + +function findClosestRecursively(element, selector) { + if (element instanceof Element) { + return ( + element.closest(selector) || findClosestRecursively(element.assignedSlot || element.getRootNode()?.host, selector) + ) + } +} + +function elementIsFocusable(element) { + const inertDisabledOrHidden = "[inert], :disabled, [hidden], details:not([open]), dialog:not([open])"; + + return !!element && element.closest(inertDisabledOrHidden) == null && typeof element.focus == "function" +} + +function queryAutofocusableElement(elementOrDocumentFragment) { + return Array.from(elementOrDocumentFragment.querySelectorAll("[autofocus]")).find(elementIsFocusable) +} + +async function around(callback, reader) { + const before = reader(); + + callback(); + + await nextAnimationFrame(); + + const after = reader(); + + return [before, after] +} + +function doesNotTargetIFrame(name) { + if (name === "_blank") { + return false + } else if (name) { + for (const element of document.getElementsByName(name)) { + if (element instanceof HTMLIFrameElement) return false + } + + return true + } else { + return true + } +} + +function findLinkFromClickTarget(target) { + return findClosestRecursively(target, "a[href]:not([target^=_]):not([download])") +} + +function getLocationForLink(link) { + return expandURL(link.getAttribute("href") || "") +} + +function debounce(fn, delay) { + let timeoutId = null; + + return (...args) => { + const callback = () => fn.apply(this, args); + clearTimeout(timeoutId); + timeoutId = setTimeout(callback, delay); + } +} + +const submitter = { + "aria-disabled": { + beforeSubmit: submitter => { + submitter.setAttribute("aria-disabled", "true"); + submitter.addEventListener("click", cancelEvent); + }, + + afterSubmit: submitter => { + submitter.removeAttribute("aria-disabled"); + submitter.removeEventListener("click", cancelEvent); + } + }, + + "disabled": { + beforeSubmit: submitter => submitter.disabled = true, + afterSubmit: submitter => submitter.disabled = false + } +}; + +class Config { + #submitter = null + + constructor(config) { + Object.assign(this, config); + } + + get submitter() { + return this.#submitter + } + + set submitter(value) { + this.#submitter = submitter[value] || value; + } +} + +const forms = new Config({ + mode: "on", + submitter: "disabled" +}); + +const config = { + drive, + forms +}; + +function expandURL(locatable) { + return new URL(locatable.toString(), document.baseURI) +} + +function getAnchor(url) { + let anchorMatch; + if (url.hash) { + return url.hash.slice(1) + // eslint-disable-next-line no-cond-assign + } else if ((anchorMatch = url.href.match(/#(.*)$/))) { + return anchorMatch[1] + } +} + +function getAction$1(form, submitter) { + const action = submitter?.getAttribute("formaction") || form.getAttribute("action") || form.action; + + return expandURL(action) +} + +function getExtension(url) { + return (getLastPathComponent(url).match(/\.[^.]*$/) || [])[0] || "" +} + +function isPrefixedBy(baseURL, url) { + const prefix = getPrefix(url); + return baseURL.href === expandURL(prefix).href || baseURL.href.startsWith(prefix) +} + +function locationIsVisitable(location, rootLocation) { + return isPrefixedBy(location, rootLocation) && !config.drive.unvisitableExtensions.has(getExtension(location)) +} + +function getRequestURL(url) { + const anchor = getAnchor(url); + return anchor != null ? url.href.slice(0, -(anchor.length + 1)) : url.href +} + +function toCacheKey(url) { + return getRequestURL(url) +} + +function urlsAreEqual(left, right) { + return expandURL(left).href == expandURL(right).href +} + +function getPathComponents(url) { + return url.pathname.split("/").slice(1) +} + +function getLastPathComponent(url) { + return getPathComponents(url).slice(-1)[0] +} + +function getPrefix(url) { + return addTrailingSlash(url.origin + url.pathname) +} + +function addTrailingSlash(value) { + return value.endsWith("/") ? value : value + "/" +} + +class FetchResponse { + constructor(response) { + this.response = response; + } + + get succeeded() { + return this.response.ok + } + + get failed() { + return !this.succeeded + } + + get clientError() { + return this.statusCode >= 400 && this.statusCode <= 499 + } + + get serverError() { + return this.statusCode >= 500 && this.statusCode <= 599 + } + + get redirected() { + return this.response.redirected + } + + get location() { + return expandURL(this.response.url) + } + + get isHTML() { + return this.contentType && this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/) + } + + get statusCode() { + return this.response.status + } + + get contentType() { + return this.header("Content-Type") + } + + get responseText() { + return this.response.clone().text() + } + + get responseHTML() { + if (this.isHTML) { + return this.response.clone().text() + } else { + return Promise.resolve(undefined) + } + } + + header(name) { + return this.response.headers.get(name) + } +} + +class LimitedSet extends Set { + constructor(maxSize) { + super(); + this.maxSize = maxSize; + } + + add(value) { + if (this.size >= this.maxSize) { + const iterator = this.values(); + const oldestValue = iterator.next().value; + this.delete(oldestValue); + } + super.add(value); + } +} + +const recentRequests = new LimitedSet(20); + +const nativeFetch = window.fetch; + +function fetchWithTurboHeaders(url, options = {}) { + const modifiedHeaders = new Headers(options.headers || {}); + const requestUID = uuid(); + recentRequests.add(requestUID); + modifiedHeaders.append("X-Turbo-Request-Id", requestUID); + + return nativeFetch(url, { + ...options, + headers: modifiedHeaders + }) +} + +function fetchMethodFromString(method) { + switch (method.toLowerCase()) { + case "get": + return FetchMethod.get + case "post": + return FetchMethod.post + case "put": + return FetchMethod.put + case "patch": + return FetchMethod.patch + case "delete": + return FetchMethod.delete + } +} + +const FetchMethod = { + get: "get", + post: "post", + put: "put", + patch: "patch", + delete: "delete" +}; + +function fetchEnctypeFromString(encoding) { + switch (encoding.toLowerCase()) { + case FetchEnctype.multipart: + return FetchEnctype.multipart + case FetchEnctype.plain: + return FetchEnctype.plain + default: + return FetchEnctype.urlEncoded + } +} + +const FetchEnctype = { + urlEncoded: "application/x-www-form-urlencoded", + multipart: "multipart/form-data", + plain: "text/plain" +}; + +class FetchRequest { + abortController = new AbortController() + #resolveRequestPromise = (_value) => {} + + constructor(delegate, method, location, requestBody = new URLSearchParams(), target = null, enctype = FetchEnctype.urlEncoded) { + const [url, body] = buildResourceAndBody(expandURL(location), method, requestBody, enctype); + + this.delegate = delegate; + this.url = url; + this.target = target; + this.fetchOptions = { + credentials: "same-origin", + redirect: "follow", + method: method.toUpperCase(), + headers: { ...this.defaultHeaders }, + body: body, + signal: this.abortSignal, + referrer: this.delegate.referrer?.href + }; + this.enctype = enctype; + } + + get method() { + return this.fetchOptions.method + } + + set method(value) { + const fetchBody = this.isSafe ? this.url.searchParams : this.fetchOptions.body || new FormData(); + const fetchMethod = fetchMethodFromString(value) || FetchMethod.get; + + this.url.search = ""; + + const [url, body] = buildResourceAndBody(this.url, fetchMethod, fetchBody, this.enctype); + + this.url = url; + this.fetchOptions.body = body; + this.fetchOptions.method = fetchMethod.toUpperCase(); + } + + get headers() { + return this.fetchOptions.headers + } + + set headers(value) { + this.fetchOptions.headers = value; + } + + get body() { + if (this.isSafe) { + return this.url.searchParams + } else { + return this.fetchOptions.body + } + } + + set body(value) { + this.fetchOptions.body = value; + } + + get location() { + return this.url + } + + get params() { + return this.url.searchParams + } + + get entries() { + return this.body ? Array.from(this.body.entries()) : [] + } + + cancel() { + this.abortController.abort(); + } + + async perform() { + const { fetchOptions } = this; + this.delegate.prepareRequest(this); + const event = await this.#allowRequestToBeIntercepted(fetchOptions); + try { + this.delegate.requestStarted(this); + + if (event.detail.fetchRequest) { + this.response = event.detail.fetchRequest.response; + } else { + this.response = fetchWithTurboHeaders(this.url.href, fetchOptions); + } + + const response = await this.response; + return await this.receive(response) + } catch (error) { + if (error.name !== "AbortError") { + if (this.#willDelegateErrorHandling(error)) { + this.delegate.requestErrored(this, error); + } + throw error + } + } finally { + this.delegate.requestFinished(this); + } + } + + async receive(response) { + const fetchResponse = new FetchResponse(response); + const event = dispatch("turbo:before-fetch-response", { + cancelable: true, + detail: { fetchResponse }, + target: this.target + }); + if (event.defaultPrevented) { + this.delegate.requestPreventedHandlingResponse(this, fetchResponse); + } else if (fetchResponse.succeeded) { + this.delegate.requestSucceededWithResponse(this, fetchResponse); + } else { + this.delegate.requestFailedWithResponse(this, fetchResponse); + } + return fetchResponse + } + + get defaultHeaders() { + return { + Accept: "text/html, application/xhtml+xml" + } + } + + get isSafe() { + return isSafe(this.method) + } + + get abortSignal() { + return this.abortController.signal + } + + acceptResponseType(mimeType) { + this.headers["Accept"] = [mimeType, this.headers["Accept"]].join(", "); + } + + async #allowRequestToBeIntercepted(fetchOptions) { + const requestInterception = new Promise((resolve) => (this.#resolveRequestPromise = resolve)); + const event = dispatch("turbo:before-fetch-request", { + cancelable: true, + detail: { + fetchOptions, + url: this.url, + resume: this.#resolveRequestPromise + }, + target: this.target + }); + this.url = event.detail.url; + if (event.defaultPrevented) await requestInterception; + + return event + } + + #willDelegateErrorHandling(error) { + const event = dispatch("turbo:fetch-request-error", { + target: this.target, + cancelable: true, + detail: { request: this, error: error } + }); + + return !event.defaultPrevented + } +} + +function isSafe(fetchMethod) { + return fetchMethodFromString(fetchMethod) == FetchMethod.get +} + +function buildResourceAndBody(resource, method, requestBody, enctype) { + const searchParams = + Array.from(requestBody).length > 0 ? new URLSearchParams(entriesExcludingFiles(requestBody)) : resource.searchParams; + + if (isSafe(method)) { + return [mergeIntoURLSearchParams(resource, searchParams), null] + } else if (enctype == FetchEnctype.urlEncoded) { + return [resource, searchParams] + } else { + return [resource, requestBody] + } +} + +function entriesExcludingFiles(requestBody) { + const entries = []; + + for (const [name, value] of requestBody) { + if (value instanceof File) continue + else entries.push([name, value]); + } + + return entries +} + +function mergeIntoURLSearchParams(url, requestBody) { + const searchParams = new URLSearchParams(entriesExcludingFiles(requestBody)); + + url.search = searchParams.toString(); + + return url +} + +class AppearanceObserver { + started = false + + constructor(delegate, element) { + this.delegate = delegate; + this.element = element; + this.intersectionObserver = new IntersectionObserver(this.intersect); + } + + start() { + if (!this.started) { + this.started = true; + this.intersectionObserver.observe(this.element); + } + } + + stop() { + if (this.started) { + this.started = false; + this.intersectionObserver.unobserve(this.element); + } + } + + intersect = (entries) => { + const lastEntry = entries.slice(-1)[0]; + if (lastEntry?.isIntersecting) { + this.delegate.elementAppearedInViewport(this.element); + } + } +} + +class StreamMessage { + static contentType = "text/vnd.turbo-stream.html" + + static wrap(message) { + if (typeof message == "string") { + return new this(createDocumentFragment(message)) + } else { + return message + } + } + + constructor(fragment) { + this.fragment = importStreamElements(fragment); + } +} + +function importStreamElements(fragment) { + for (const element of fragment.querySelectorAll("turbo-stream")) { + const streamElement = document.importNode(element, true); + + for (const inertScriptElement of streamElement.templateElement.content.querySelectorAll("script")) { + inertScriptElement.replaceWith(activateScriptElement(inertScriptElement)); + } + + element.replaceWith(streamElement); + } + + return fragment +} + +const PREFETCH_DELAY = 100; + +class PrefetchCache { + #prefetchTimeout = null + #prefetched = null + + get(url) { + if (this.#prefetched && this.#prefetched.url === url && this.#prefetched.expire > Date.now()) { + return this.#prefetched.request + } + } + + setLater(url, request, ttl) { + this.clear(); + + this.#prefetchTimeout = setTimeout(() => { + request.perform(); + this.set(url, request, ttl); + this.#prefetchTimeout = null; + }, PREFETCH_DELAY); + } + + set(url, request, ttl) { + this.#prefetched = { url, request, expire: new Date(new Date().getTime() + ttl) }; + } + + clear() { + if (this.#prefetchTimeout) clearTimeout(this.#prefetchTimeout); + this.#prefetched = null; + } +} + +const cacheTtl = 10 * 1000; +const prefetchCache = new PrefetchCache(); + +const FormSubmissionState = { + initialized: "initialized", + requesting: "requesting", + waiting: "waiting", + receiving: "receiving", + stopping: "stopping", + stopped: "stopped" +}; + +class FormSubmission { + state = FormSubmissionState.initialized + + static confirmMethod(message) { + return Promise.resolve(confirm(message)) + } + + constructor(delegate, formElement, submitter, mustRedirect = false) { + const method = getMethod(formElement, submitter); + const action = getAction(getFormAction(formElement, submitter), method); + const body = buildFormData(formElement, submitter); + const enctype = getEnctype(formElement, submitter); + + this.delegate = delegate; + this.formElement = formElement; + this.submitter = submitter; + this.fetchRequest = new FetchRequest(this, method, action, body, formElement, enctype); + this.mustRedirect = mustRedirect; + } + + get method() { + return this.fetchRequest.method + } + + set method(value) { + this.fetchRequest.method = value; + } + + get action() { + return this.fetchRequest.url.toString() + } + + set action(value) { + this.fetchRequest.url = expandURL(value); + } + + get body() { + return this.fetchRequest.body + } + + get enctype() { + return this.fetchRequest.enctype + } + + get isSafe() { + return this.fetchRequest.isSafe + } + + get location() { + return this.fetchRequest.url + } + + // The submission process + + async start() { + const { initialized, requesting } = FormSubmissionState; + const confirmationMessage = getAttribute("data-turbo-confirm", this.submitter, this.formElement); + + if (typeof confirmationMessage === "string") { + const confirmMethod = typeof config.forms.confirm === "function" ? + config.forms.confirm : + FormSubmission.confirmMethod; + + const answer = await confirmMethod(confirmationMessage, this.formElement, this.submitter); + if (!answer) { + return + } + } + + if (this.state == initialized) { + this.state = requesting; + return this.fetchRequest.perform() + } + } + + stop() { + const { stopping, stopped } = FormSubmissionState; + if (this.state != stopping && this.state != stopped) { + this.state = stopping; + this.fetchRequest.cancel(); + return true + } + } + + // Fetch request delegate + + prepareRequest(request) { + if (!request.isSafe) { + const token = getCookieValue(getMetaContent("csrf-param")) || getMetaContent("csrf-token"); + if (token) { + request.headers["X-CSRF-Token"] = token; + } + } + + if (this.requestAcceptsTurboStreamResponse(request)) { + request.acceptResponseType(StreamMessage.contentType); + } + } + + requestStarted(_request) { + this.state = FormSubmissionState.waiting; + if (this.submitter) config.forms.submitter.beforeSubmit(this.submitter); + this.setSubmitsWith(); + markAsBusy(this.formElement); + dispatch("turbo:submit-start", { + target: this.formElement, + detail: { formSubmission: this } + }); + this.delegate.formSubmissionStarted(this); + } + + requestPreventedHandlingResponse(request, response) { + prefetchCache.clear(); + + this.result = { success: response.succeeded, fetchResponse: response }; + } + + requestSucceededWithResponse(request, response) { + if (response.clientError || response.serverError) { + this.delegate.formSubmissionFailedWithResponse(this, response); + return + } + + prefetchCache.clear(); + + if (this.requestMustRedirect(request) && responseSucceededWithoutRedirect(response)) { + const error = new Error("Form responses must redirect to another location"); + this.delegate.formSubmissionErrored(this, error); + } else { + this.state = FormSubmissionState.receiving; + this.result = { success: true, fetchResponse: response }; + this.delegate.formSubmissionSucceededWithResponse(this, response); + } + } + + requestFailedWithResponse(request, response) { + this.result = { success: false, fetchResponse: response }; + this.delegate.formSubmissionFailedWithResponse(this, response); + } + + requestErrored(request, error) { + this.result = { success: false, error }; + this.delegate.formSubmissionErrored(this, error); + } + + requestFinished(_request) { + this.state = FormSubmissionState.stopped; + if (this.submitter) config.forms.submitter.afterSubmit(this.submitter); + this.resetSubmitterText(); + clearBusyState(this.formElement); + dispatch("turbo:submit-end", { + target: this.formElement, + detail: { formSubmission: this, ...this.result } + }); + this.delegate.formSubmissionFinished(this); + } + + // Private + + setSubmitsWith() { + if (!this.submitter || !this.submitsWith) return + + if (this.submitter.matches("button")) { + this.originalSubmitText = this.submitter.innerHTML; + this.submitter.innerHTML = this.submitsWith; + } else if (this.submitter.matches("input")) { + const input = this.submitter; + this.originalSubmitText = input.value; + input.value = this.submitsWith; + } + } + + resetSubmitterText() { + if (!this.submitter || !this.originalSubmitText) return + + if (this.submitter.matches("button")) { + this.submitter.innerHTML = this.originalSubmitText; + } else if (this.submitter.matches("input")) { + const input = this.submitter; + input.value = this.originalSubmitText; + } + } + + requestMustRedirect(request) { + return !request.isSafe && this.mustRedirect + } + + requestAcceptsTurboStreamResponse(request) { + return !request.isSafe || hasAttribute("data-turbo-stream", this.submitter, this.formElement) + } + + get submitsWith() { + return this.submitter?.getAttribute("data-turbo-submits-with") + } +} + +function buildFormData(formElement, submitter) { + const formData = new FormData(formElement); + const name = submitter?.getAttribute("name"); + const value = submitter?.getAttribute("value"); + + if (name) { + formData.append(name, value || ""); + } + + return formData +} + +function getCookieValue(cookieName) { + if (cookieName != null) { + const cookies = document.cookie ? document.cookie.split("; ") : []; + const cookie = cookies.find((cookie) => cookie.startsWith(cookieName)); + if (cookie) { + const value = cookie.split("=").slice(1).join("="); + return value ? decodeURIComponent(value) : undefined + } + } +} + +function responseSucceededWithoutRedirect(response) { + return response.statusCode == 200 && !response.redirected +} + +function getFormAction(formElement, submitter) { + const formElementAction = typeof formElement.action === "string" ? formElement.action : null; + + if (submitter?.hasAttribute("formaction")) { + return submitter.getAttribute("formaction") || "" + } else { + return formElement.getAttribute("action") || formElementAction || "" + } +} + +function getAction(formAction, fetchMethod) { + const action = expandURL(formAction); + + if (isSafe(fetchMethod)) { + action.search = ""; + } + + return action +} + +function getMethod(formElement, submitter) { + const method = submitter?.getAttribute("formmethod") || formElement.getAttribute("method") || ""; + return fetchMethodFromString(method.toLowerCase()) || FetchMethod.get +} + +function getEnctype(formElement, submitter) { + return fetchEnctypeFromString(submitter?.getAttribute("formenctype") || formElement.enctype) +} + +class Snapshot { + constructor(element) { + this.element = element; + } + + get activeElement() { + return this.element.ownerDocument.activeElement + } + + get children() { + return [...this.element.children] + } + + hasAnchor(anchor) { + return this.getElementForAnchor(anchor) != null + } + + getElementForAnchor(anchor) { + return anchor ? this.element.querySelector(`[id='${anchor}'], a[name='${anchor}']`) : null + } + + get isConnected() { + return this.element.isConnected + } + + get firstAutofocusableElement() { + return queryAutofocusableElement(this.element) + } + + get permanentElements() { + return queryPermanentElementsAll(this.element) + } + + getPermanentElementById(id) { + return getPermanentElementById(this.element, id) + } + + getPermanentElementMapForSnapshot(snapshot) { + const permanentElementMap = {}; + + for (const currentPermanentElement of this.permanentElements) { + const { id } = currentPermanentElement; + const newPermanentElement = snapshot.getPermanentElementById(id); + if (newPermanentElement) { + permanentElementMap[id] = [currentPermanentElement, newPermanentElement]; + } + } + + return permanentElementMap + } +} + +function getPermanentElementById(node, id) { + return node.querySelector(`#${id}[data-turbo-permanent]`) +} + +function queryPermanentElementsAll(node) { + return node.querySelectorAll("[id][data-turbo-permanent]") +} + +class FormSubmitObserver { + started = false + + constructor(delegate, eventTarget) { + this.delegate = delegate; + this.eventTarget = eventTarget; + } + + start() { + if (!this.started) { + this.eventTarget.addEventListener("submit", this.submitCaptured, true); + this.started = true; + } + } + + stop() { + if (this.started) { + this.eventTarget.removeEventListener("submit", this.submitCaptured, true); + this.started = false; + } + } + + submitCaptured = () => { + this.eventTarget.removeEventListener("submit", this.submitBubbled, false); + this.eventTarget.addEventListener("submit", this.submitBubbled, false); + } + + submitBubbled = (event) => { + if (!event.defaultPrevented) { + const form = event.target instanceof HTMLFormElement ? event.target : undefined; + const submitter = event.submitter || undefined; + + if ( + form && + submissionDoesNotDismissDialog(form, submitter) && + submissionDoesNotTargetIFrame(form, submitter) && + this.delegate.willSubmitForm(form, submitter) + ) { + event.preventDefault(); + event.stopImmediatePropagation(); + this.delegate.formSubmitted(form, submitter); + } + } + } +} + +function submissionDoesNotDismissDialog(form, submitter) { + const method = submitter?.getAttribute("formmethod") || form.getAttribute("method"); + + return method != "dialog" +} + +function submissionDoesNotTargetIFrame(form, submitter) { + const target = submitter?.getAttribute("formtarget") || form.getAttribute("target"); + + return doesNotTargetIFrame(target) +} + +class View { + #resolveRenderPromise = (_value) => {} + #resolveInterceptionPromise = (_value) => {} + + constructor(delegate, element) { + this.delegate = delegate; + this.element = element; + } + + // Scrolling + + scrollToAnchor(anchor) { + const element = this.snapshot.getElementForAnchor(anchor); + if (element) { + this.scrollToElement(element); + this.focusElement(element); + } else { + this.scrollToPosition({ x: 0, y: 0 }); + } + } + + scrollToAnchorFromLocation(location) { + this.scrollToAnchor(getAnchor(location)); + } + + scrollToElement(element) { + element.scrollIntoView(); + } + + focusElement(element) { + if (element instanceof HTMLElement) { + if (element.hasAttribute("tabindex")) { + element.focus(); + } else { + element.setAttribute("tabindex", "-1"); + element.focus(); + element.removeAttribute("tabindex"); + } + } + } + + scrollToPosition({ x, y }) { + this.scrollRoot.scrollTo(x, y); + } + + scrollToTop() { + this.scrollToPosition({ x: 0, y: 0 }); + } + + get scrollRoot() { + return window + } + + // Rendering + + async render(renderer) { + const { isPreview, shouldRender, willRender, newSnapshot: snapshot } = renderer; + + // A workaround to ignore tracked element mismatch reloads when performing + // a promoted Visit from a frame navigation + const shouldInvalidate = willRender; + + if (shouldRender) { + try { + this.renderPromise = new Promise((resolve) => (this.#resolveRenderPromise = resolve)); + this.renderer = renderer; + await this.prepareToRenderSnapshot(renderer); + + const renderInterception = new Promise((resolve) => (this.#resolveInterceptionPromise = resolve)); + const options = { resume: this.#resolveInterceptionPromise, render: this.renderer.renderElement, renderMethod: this.renderer.renderMethod }; + const immediateRender = this.delegate.allowsImmediateRender(snapshot, options); + if (!immediateRender) await renderInterception; + + await this.renderSnapshot(renderer); + this.delegate.viewRenderedSnapshot(snapshot, isPreview, this.renderer.renderMethod); + this.delegate.preloadOnLoadLinksForView(this.element); + this.finishRenderingSnapshot(renderer); + } finally { + delete this.renderer; + this.#resolveRenderPromise(undefined); + delete this.renderPromise; + } + } else if (shouldInvalidate) { + this.invalidate(renderer.reloadReason); + } + } + + invalidate(reason) { + this.delegate.viewInvalidated(reason); + } + + async prepareToRenderSnapshot(renderer) { + this.markAsPreview(renderer.isPreview); + await renderer.prepareToRender(); + } + + markAsPreview(isPreview) { + if (isPreview) { + this.element.setAttribute("data-turbo-preview", ""); + } else { + this.element.removeAttribute("data-turbo-preview"); + } + } + + markVisitDirection(direction) { + this.element.setAttribute("data-turbo-visit-direction", direction); + } + + unmarkVisitDirection() { + this.element.removeAttribute("data-turbo-visit-direction"); + } + + async renderSnapshot(renderer) { + await renderer.render(); + } + + finishRenderingSnapshot(renderer) { + renderer.finishRendering(); + } +} + +class FrameView extends View { + missing() { + this.element.innerHTML = `Content missing`; + } + + get snapshot() { + return new Snapshot(this.element) + } +} + +class LinkInterceptor { + constructor(delegate, element) { + this.delegate = delegate; + this.element = element; + } + + start() { + this.element.addEventListener("click", this.clickBubbled); + document.addEventListener("turbo:click", this.linkClicked); + document.addEventListener("turbo:before-visit", this.willVisit); + } + + stop() { + this.element.removeEventListener("click", this.clickBubbled); + document.removeEventListener("turbo:click", this.linkClicked); + document.removeEventListener("turbo:before-visit", this.willVisit); + } + + clickBubbled = (event) => { + if (this.clickEventIsSignificant(event)) { + this.clickEvent = event; + } else { + delete this.clickEvent; + } + } + + linkClicked = (event) => { + if (this.clickEvent && this.clickEventIsSignificant(event)) { + if (this.delegate.shouldInterceptLinkClick(event.target, event.detail.url, event.detail.originalEvent)) { + this.clickEvent.preventDefault(); + event.preventDefault(); + this.delegate.linkClickIntercepted(event.target, event.detail.url, event.detail.originalEvent); + } + } + delete this.clickEvent; + } + + willVisit = (_event) => { + delete this.clickEvent; + } + + clickEventIsSignificant(event) { + const target = event.composed ? event.target?.parentElement : event.target; + const element = findLinkFromClickTarget(target) || target; + + return element instanceof Element && element.closest("turbo-frame, html") == this.element + } +} + +class LinkClickObserver { + started = false + + constructor(delegate, eventTarget) { + this.delegate = delegate; + this.eventTarget = eventTarget; + } + + start() { + if (!this.started) { + this.eventTarget.addEventListener("click", this.clickCaptured, true); + this.started = true; + } + } + + stop() { + if (this.started) { + this.eventTarget.removeEventListener("click", this.clickCaptured, true); + this.started = false; + } + } + + clickCaptured = () => { + this.eventTarget.removeEventListener("click", this.clickBubbled, false); + this.eventTarget.addEventListener("click", this.clickBubbled, false); + } + + clickBubbled = (event) => { + if (event instanceof MouseEvent && this.clickEventIsSignificant(event)) { + const target = (event.composedPath && event.composedPath()[0]) || event.target; + const link = findLinkFromClickTarget(target); + if (link && doesNotTargetIFrame(link.target)) { + const location = getLocationForLink(link); + if (this.delegate.willFollowLinkToLocation(link, location, event)) { + event.preventDefault(); + this.delegate.followedLinkToLocation(link, location); + } + } + } + } + + clickEventIsSignificant(event) { + return !( + (event.target && event.target.isContentEditable) || + event.defaultPrevented || + event.which > 1 || + event.altKey || + event.ctrlKey || + event.metaKey || + event.shiftKey + ) + } +} + +class FormLinkClickObserver { + constructor(delegate, element) { + this.delegate = delegate; + this.linkInterceptor = new LinkClickObserver(this, element); + } + + start() { + this.linkInterceptor.start(); + } + + stop() { + this.linkInterceptor.stop(); + } + + // Link hover observer delegate + + canPrefetchRequestToLocation(link, location) { + return false + } + + prefetchAndCacheRequestToLocation(link, location) { + return + } + + // Link click observer delegate + + willFollowLinkToLocation(link, location, originalEvent) { + return ( + this.delegate.willSubmitFormLinkToLocation(link, location, originalEvent) && + (link.hasAttribute("data-turbo-method") || link.hasAttribute("data-turbo-stream")) + ) + } + + followedLinkToLocation(link, location) { + const form = document.createElement("form"); + + const type = "hidden"; + for (const [name, value] of location.searchParams) { + form.append(Object.assign(document.createElement("input"), { type, name, value })); + } + + const action = Object.assign(location, { search: "" }); + form.setAttribute("data-turbo", "true"); + form.setAttribute("action", action.href); + form.setAttribute("hidden", ""); + + const method = link.getAttribute("data-turbo-method"); + if (method) form.setAttribute("method", method); + + const turboFrame = link.getAttribute("data-turbo-frame"); + if (turboFrame) form.setAttribute("data-turbo-frame", turboFrame); + + const turboAction = getVisitAction(link); + if (turboAction) form.setAttribute("data-turbo-action", turboAction); + + const turboConfirm = link.getAttribute("data-turbo-confirm"); + if (turboConfirm) form.setAttribute("data-turbo-confirm", turboConfirm); + + const turboStream = link.hasAttribute("data-turbo-stream"); + if (turboStream) form.setAttribute("data-turbo-stream", ""); + + this.delegate.submittedFormLinkToLocation(link, location, form); + + document.body.appendChild(form); + form.addEventListener("turbo:submit-end", () => form.remove(), { once: true }); + requestAnimationFrame(() => form.requestSubmit()); + } +} + +class Bardo { + static async preservingPermanentElements(delegate, permanentElementMap, callback) { + const bardo = new this(delegate, permanentElementMap); + bardo.enter(); + await callback(); + bardo.leave(); + } + + constructor(delegate, permanentElementMap) { + this.delegate = delegate; + this.permanentElementMap = permanentElementMap; + } + + enter() { + for (const id in this.permanentElementMap) { + const [currentPermanentElement, newPermanentElement] = this.permanentElementMap[id]; + this.delegate.enteringBardo(currentPermanentElement, newPermanentElement); + this.replaceNewPermanentElementWithPlaceholder(newPermanentElement); + } + } + + leave() { + for (const id in this.permanentElementMap) { + const [currentPermanentElement] = this.permanentElementMap[id]; + this.replaceCurrentPermanentElementWithClone(currentPermanentElement); + this.replacePlaceholderWithPermanentElement(currentPermanentElement); + this.delegate.leavingBardo(currentPermanentElement); + } + } + + replaceNewPermanentElementWithPlaceholder(permanentElement) { + const placeholder = createPlaceholderForPermanentElement(permanentElement); + permanentElement.replaceWith(placeholder); + } + + replaceCurrentPermanentElementWithClone(permanentElement) { + const clone = permanentElement.cloneNode(true); + permanentElement.replaceWith(clone); + } + + replacePlaceholderWithPermanentElement(permanentElement) { + const placeholder = this.getPlaceholderById(permanentElement.id); + placeholder?.replaceWith(permanentElement); + } + + getPlaceholderById(id) { + return this.placeholders.find((element) => element.content == id) + } + + get placeholders() { + return [...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")] + } +} + +function createPlaceholderForPermanentElement(permanentElement) { + const element = document.createElement("meta"); + element.setAttribute("name", "turbo-permanent-placeholder"); + element.setAttribute("content", permanentElement.id); + return element +} + +class Renderer { + #activeElement = null + + static renderElement(currentElement, newElement) { + // Abstract method + } + + constructor(currentSnapshot, newSnapshot, isPreview, willRender = true) { + this.currentSnapshot = currentSnapshot; + this.newSnapshot = newSnapshot; + this.isPreview = isPreview; + this.willRender = willRender; + this.renderElement = this.constructor.renderElement; + this.promise = new Promise((resolve, reject) => (this.resolvingFunctions = { resolve, reject })); + } + + get shouldRender() { + return true + } + + get shouldAutofocus() { + return true + } + + get reloadReason() { + return + } + + prepareToRender() { + return + } + + render() { + // Abstract method + } + + finishRendering() { + if (this.resolvingFunctions) { + this.resolvingFunctions.resolve(); + delete this.resolvingFunctions; + } + } + + async preservingPermanentElements(callback) { + await Bardo.preservingPermanentElements(this, this.permanentElementMap, callback); + } + + focusFirstAutofocusableElement() { + if (this.shouldAutofocus) { + const element = this.connectedSnapshot.firstAutofocusableElement; + if (element) { + element.focus(); + } + } + } + + // Bardo delegate + + enteringBardo(currentPermanentElement) { + if (this.#activeElement) return + + if (currentPermanentElement.contains(this.currentSnapshot.activeElement)) { + this.#activeElement = this.currentSnapshot.activeElement; + } + } + + leavingBardo(currentPermanentElement) { + if (currentPermanentElement.contains(this.#activeElement) && this.#activeElement instanceof HTMLElement) { + this.#activeElement.focus(); + + this.#activeElement = null; + } + } + + get connectedSnapshot() { + return this.newSnapshot.isConnected ? this.newSnapshot : this.currentSnapshot + } + + get currentElement() { + return this.currentSnapshot.element + } + + get newElement() { + return this.newSnapshot.element + } + + get permanentElementMap() { + return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot) + } + + get renderMethod() { + return "replace" + } +} + +class FrameRenderer extends Renderer { + static renderElement(currentElement, newElement) { + const destinationRange = document.createRange(); + destinationRange.selectNodeContents(currentElement); + destinationRange.deleteContents(); + + const frameElement = newElement; + const sourceRange = frameElement.ownerDocument?.createRange(); + if (sourceRange) { + sourceRange.selectNodeContents(frameElement); + currentElement.appendChild(sourceRange.extractContents()); + } + } + + constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) { + super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender); + this.delegate = delegate; + } + + get shouldRender() { + return true + } + + async render() { + await nextRepaint(); + this.preservingPermanentElements(() => { + this.loadFrameElement(); + }); + this.scrollFrameIntoView(); + await nextRepaint(); + this.focusFirstAutofocusableElement(); + await nextRepaint(); + this.activateScriptElements(); + } + + loadFrameElement() { + this.delegate.willRenderFrame(this.currentElement, this.newElement); + this.renderElement(this.currentElement, this.newElement); + } + + scrollFrameIntoView() { + if (this.currentElement.autoscroll || this.newElement.autoscroll) { + const element = this.currentElement.firstElementChild; + const block = readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"), "end"); + const behavior = readScrollBehavior(this.currentElement.getAttribute("data-autoscroll-behavior"), "auto"); + + if (element) { + element.scrollIntoView({ block, behavior }); + return true + } + } + return false + } + + activateScriptElements() { + for (const inertScriptElement of this.newScriptElements) { + const activatedScriptElement = activateScriptElement(inertScriptElement); + inertScriptElement.replaceWith(activatedScriptElement); + } + } + + get newScriptElements() { + return this.currentElement.querySelectorAll("script") + } +} + +function readScrollLogicalPosition(value, defaultValue) { + if (value == "end" || value == "start" || value == "center" || value == "nearest") { + return value + } else { + return defaultValue + } +} + +function readScrollBehavior(value, defaultValue) { + if (value == "auto" || value == "smooth") { + return value + } else { + return defaultValue + } +} + +/** + * @typedef {object} ConfigHead + * + * @property {'merge' | 'append' | 'morph' | 'none'} [style] + * @property {boolean} [block] + * @property {boolean} [ignore] + * @property {function(Element): boolean} [shouldPreserve] + * @property {function(Element): boolean} [shouldReAppend] + * @property {function(Element): boolean} [shouldRemove] + * @property {function(Element, {added: Node[], kept: Element[], removed: Element[]}): void} [afterHeadMorphed] + */ + +/** + * @typedef {object} ConfigCallbacks + * + * @property {function(Node): boolean} [beforeNodeAdded] + * @property {function(Node): void} [afterNodeAdded] + * @property {function(Element, Node): boolean} [beforeNodeMorphed] + * @property {function(Element, Node): void} [afterNodeMorphed] + * @property {function(Element): boolean} [beforeNodeRemoved] + * @property {function(Element): void} [afterNodeRemoved] + * @property {function(string, Element, "update" | "remove"): boolean} [beforeAttributeUpdated] + */ + +/** + * @typedef {object} Config + * + * @property {'outerHTML' | 'innerHTML'} [morphStyle] + * @property {boolean} [ignoreActive] + * @property {boolean} [ignoreActiveValue] + * @property {boolean} [restoreFocus] + * @property {ConfigCallbacks} [callbacks] + * @property {ConfigHead} [head] + */ + +/** + * @typedef {function} NoOp + * + * @returns {void} + */ + +/** + * @typedef {object} ConfigHeadInternal + * + * @property {'merge' | 'append' | 'morph' | 'none'} style + * @property {boolean} [block] + * @property {boolean} [ignore] + * @property {(function(Element): boolean) | NoOp} shouldPreserve + * @property {(function(Element): boolean) | NoOp} shouldReAppend + * @property {(function(Element): boolean) | NoOp} shouldRemove + * @property {(function(Element, {added: Node[], kept: Element[], removed: Element[]}): void) | NoOp} afterHeadMorphed + */ + +/** + * @typedef {object} ConfigCallbacksInternal + * + * @property {(function(Node): boolean) | NoOp} beforeNodeAdded + * @property {(function(Node): void) | NoOp} afterNodeAdded + * @property {(function(Node, Node): boolean) | NoOp} beforeNodeMorphed + * @property {(function(Node, Node): void) | NoOp} afterNodeMorphed + * @property {(function(Node): boolean) | NoOp} beforeNodeRemoved + * @property {(function(Node): void) | NoOp} afterNodeRemoved + * @property {(function(string, Element, "update" | "remove"): boolean) | NoOp} beforeAttributeUpdated + */ + +/** + * @typedef {object} ConfigInternal + * + * @property {'outerHTML' | 'innerHTML'} morphStyle + * @property {boolean} [ignoreActive] + * @property {boolean} [ignoreActiveValue] + * @property {boolean} [restoreFocus] + * @property {ConfigCallbacksInternal} callbacks + * @property {ConfigHeadInternal} head + */ + +/** + * @typedef {Object} IdSets + * @property {Set} persistentIds + * @property {Map>} idMap + */ + +/** + * @typedef {Function} Morph + * + * @param {Element | Document} oldNode + * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent + * @param {Config} [config] + * @returns {undefined | Node[]} + */ + +// base IIFE to define idiomorph +/** + * + * @type {{defaults: ConfigInternal, morph: Morph}} + */ +var Idiomorph = (function () { + + /** + * @typedef {object} MorphContext + * + * @property {Element} target + * @property {Element} newContent + * @property {ConfigInternal} config + * @property {ConfigInternal['morphStyle']} morphStyle + * @property {ConfigInternal['ignoreActive']} ignoreActive + * @property {ConfigInternal['ignoreActiveValue']} ignoreActiveValue + * @property {ConfigInternal['restoreFocus']} restoreFocus + * @property {Map>} idMap + * @property {Set} persistentIds + * @property {ConfigInternal['callbacks']} callbacks + * @property {ConfigInternal['head']} head + * @property {HTMLDivElement} pantry + */ + + //============================================================================= + // AND NOW IT BEGINS... + //============================================================================= + + const noOp = () => {}; + /** + * Default configuration values, updatable by users now + * @type {ConfigInternal} + */ + const defaults = { + morphStyle: "outerHTML", + callbacks: { + beforeNodeAdded: noOp, + afterNodeAdded: noOp, + beforeNodeMorphed: noOp, + afterNodeMorphed: noOp, + beforeNodeRemoved: noOp, + afterNodeRemoved: noOp, + beforeAttributeUpdated: noOp, + }, + head: { + style: "merge", + shouldPreserve: (elt) => elt.getAttribute("im-preserve") === "true", + shouldReAppend: (elt) => elt.getAttribute("im-re-append") === "true", + shouldRemove: noOp, + afterHeadMorphed: noOp, + }, + restoreFocus: true, + }; + + /** + * Core idiomorph function for morphing one DOM tree to another + * + * @param {Element | Document} oldNode + * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent + * @param {Config} [config] + * @returns {Promise | Node[]} + */ + function morph(oldNode, newContent, config = {}) { + oldNode = normalizeElement(oldNode); + const newNode = normalizeParent(newContent); + const ctx = createMorphContext(oldNode, newNode, config); + + const morphedNodes = saveAndRestoreFocus(ctx, () => { + return withHeadBlocking( + ctx, + oldNode, + newNode, + /** @param {MorphContext} ctx */ (ctx) => { + if (ctx.morphStyle === "innerHTML") { + morphChildren(ctx, oldNode, newNode); + return Array.from(oldNode.childNodes); + } else { + return morphOuterHTML(ctx, oldNode, newNode); + } + }, + ); + }); + + ctx.pantry.remove(); + return morphedNodes; + } + + /** + * Morph just the outerHTML of the oldNode to the newContent + * We have to be careful because the oldNode could have siblings which need to be untouched + * @param {MorphContext} ctx + * @param {Element} oldNode + * @param {Element} newNode + * @returns {Node[]} + */ + function morphOuterHTML(ctx, oldNode, newNode) { + const oldParent = normalizeParent(oldNode); + + // basis for calulating which nodes were morphed + // since there may be unmorphed sibling nodes + let childNodes = Array.from(oldParent.childNodes); + const index = childNodes.indexOf(oldNode); + // how many elements are to the right of the oldNode + const rightMargin = childNodes.length - (index + 1); + + morphChildren( + ctx, + oldParent, + newNode, + // these two optional params are the secret sauce + oldNode, // start point for iteration + oldNode.nextSibling, // end point for iteration + ); + + // return just the morphed nodes + childNodes = Array.from(oldParent.childNodes); + return childNodes.slice(index, childNodes.length - rightMargin); + } + + /** + * @param {MorphContext} ctx + * @param {Function} fn + * @returns {Promise | Node[]} + */ + function saveAndRestoreFocus(ctx, fn) { + if (!ctx.config.restoreFocus) return fn(); + let activeElement = + /** @type {HTMLInputElement|HTMLTextAreaElement|null} */ ( + document.activeElement + ); + + // don't bother if the active element is not an input or textarea + if ( + !( + activeElement instanceof HTMLInputElement || + activeElement instanceof HTMLTextAreaElement + ) + ) { + return fn(); + } + + const { id: activeElementId, selectionStart, selectionEnd } = activeElement; + + const results = fn(); + + if (activeElementId && activeElementId !== document.activeElement?.id) { + activeElement = ctx.target.querySelector(`#${activeElementId}`); + activeElement?.focus(); + } + if (activeElement && !activeElement.selectionEnd && selectionEnd) { + activeElement.setSelectionRange(selectionStart, selectionEnd); + } + + return results; + } + + const morphChildren = (function () { + /** + * This is the core algorithm for matching up children. The idea is to use id sets to try to match up + * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but + * by using id sets, we are able to better match up with content deeper in the DOM. + * + * Basic algorithm: + * - for each node in the new content: + * - search self and siblings for an id set match, falling back to a soft match + * - if match found + * - remove any nodes up to the match: + * - pantry persistent nodes + * - delete the rest + * - morph the match + * - elsif no match found, and node is persistent + * - find its match by querying the old root (future) and pantry (past) + * - move it and its children here + * - morph it + * - else + * - create a new node from scratch as a last result + * + * @param {MorphContext} ctx the merge context + * @param {Element} oldParent the old content that we are merging the new content into + * @param {Element} newParent the parent element of the new content + * @param {Node|null} [insertionPoint] the point in the DOM we start morphing at (defaults to first child) + * @param {Node|null} [endPoint] the point in the DOM we stop morphing at (defaults to after last child) + */ + function morphChildren( + ctx, + oldParent, + newParent, + insertionPoint = null, + endPoint = null, + ) { + // normalize + if ( + oldParent instanceof HTMLTemplateElement && + newParent instanceof HTMLTemplateElement + ) { + // @ts-ignore we can pretend the DocumentFragment is an Element + oldParent = oldParent.content; + // @ts-ignore ditto + newParent = newParent.content; + } + insertionPoint ||= oldParent.firstChild; + + // run through all the new content + for (const newChild of newParent.childNodes) { + // once we reach the end of the old parent content skip to the end and insert the rest + if (insertionPoint && insertionPoint != endPoint) { + const bestMatch = findBestMatch( + ctx, + newChild, + insertionPoint, + endPoint, + ); + if (bestMatch) { + // if the node to morph is not at the insertion point then remove/move up to it + if (bestMatch !== insertionPoint) { + removeNodesBetween(ctx, insertionPoint, bestMatch); + } + morphNode(bestMatch, newChild, ctx); + insertionPoint = bestMatch.nextSibling; + continue; + } + } + + // if the matching node is elsewhere in the original content + if (newChild instanceof Element && ctx.persistentIds.has(newChild.id)) { + // move it and all its children here and morph + const movedChild = moveBeforeById( + oldParent, + newChild.id, + insertionPoint, + ctx, + ); + morphNode(movedChild, newChild, ctx); + insertionPoint = movedChild.nextSibling; + continue; + } + + // last resort: insert the new node from scratch + const insertedNode = createNode( + oldParent, + newChild, + insertionPoint, + ctx, + ); + // could be null if beforeNodeAdded prevented insertion + if (insertedNode) { + insertionPoint = insertedNode.nextSibling; + } + } + + // remove any remaining old nodes that didn't match up with new content + while (insertionPoint && insertionPoint != endPoint) { + const tempNode = insertionPoint; + insertionPoint = insertionPoint.nextSibling; + removeNode(ctx, tempNode); + } + } + + /** + * This performs the action of inserting a new node while handling situations where the node contains + * elements with persistent ids and possible state info we can still preserve by moving in and then morphing + * + * @param {Element} oldParent + * @param {Node} newChild + * @param {Node|null} insertionPoint + * @param {MorphContext} ctx + * @returns {Node|null} + */ + function createNode(oldParent, newChild, insertionPoint, ctx) { + if (ctx.callbacks.beforeNodeAdded(newChild) === false) return null; + if (ctx.idMap.has(newChild)) { + // node has children with ids with possible state so create a dummy elt of same type and apply full morph algorithm + const newEmptyChild = document.createElement( + /** @type {Element} */ (newChild).tagName, + ); + oldParent.insertBefore(newEmptyChild, insertionPoint); + morphNode(newEmptyChild, newChild, ctx); + ctx.callbacks.afterNodeAdded(newEmptyChild); + return newEmptyChild; + } else { + // optimisation: no id state to preserve so we can just insert a clone of the newChild and its descendants + const newClonedChild = document.importNode(newChild, true); // importNode to not mutate newParent + oldParent.insertBefore(newClonedChild, insertionPoint); + ctx.callbacks.afterNodeAdded(newClonedChild); + return newClonedChild; + } + } + + //============================================================================= + // Matching Functions + //============================================================================= + const findBestMatch = (function () { + /** + * Scans forward from the startPoint to the endPoint looking for a match + * for the node. It looks for an id set match first, then a soft match. + * We abort softmatching if we find two future soft matches, to reduce churn. + * @param {Node} node + * @param {MorphContext} ctx + * @param {Node | null} startPoint + * @param {Node | null} endPoint + * @returns {Node | null} + */ + function findBestMatch(ctx, node, startPoint, endPoint) { + let softMatch = null; + let nextSibling = node.nextSibling; + let siblingSoftMatchCount = 0; + + let cursor = startPoint; + while (cursor && cursor != endPoint) { + // soft matching is a prerequisite for id set matching + if (isSoftMatch(cursor, node)) { + if (isIdSetMatch(ctx, cursor, node)) { + return cursor; // found an id set match, we're done! + } + + // we haven't yet saved a soft match fallback + if (softMatch === null) { + // the current soft match will hard match something else in the future, leave it + if (!ctx.idMap.has(cursor)) { + // save this as the fallback if we get through the loop without finding a hard match + softMatch = cursor; + } + } + } + if ( + softMatch === null && + nextSibling && + isSoftMatch(cursor, nextSibling) + ) { + // The next new node has a soft match with this node, so + // increment the count of future soft matches + siblingSoftMatchCount++; + nextSibling = nextSibling.nextSibling; + + // If there are two future soft matches, block soft matching for this node to allow + // future siblings to soft match. This is to reduce churn in the DOM when an element + // is prepended. + if (siblingSoftMatchCount >= 2) { + softMatch = undefined; + } + } + + // if the current node contains active element, stop looking for better future matches, + // because if one is found, this node will be moved to the pantry, reparenting it and thus losing focus + if (cursor.contains(document.activeElement)) break; + + cursor = cursor.nextSibling; + } + + return softMatch || null; + } + + /** + * + * @param {MorphContext} ctx + * @param {Node} oldNode + * @param {Node} newNode + * @returns {boolean} + */ + function isIdSetMatch(ctx, oldNode, newNode) { + let oldSet = ctx.idMap.get(oldNode); + let newSet = ctx.idMap.get(newNode); + + if (!newSet || !oldSet) return false; + + for (const id of oldSet) { + // a potential match is an id in the new and old nodes that + // has not already been merged into the DOM + // But the newNode content we call this on has not been + // merged yet and we don't allow duplicate IDs so it is simple + if (newSet.has(id)) { + return true; + } + } + return false; + } + + /** + * + * @param {Node} oldNode + * @param {Node} newNode + * @returns {boolean} + */ + function isSoftMatch(oldNode, newNode) { + // ok to cast: if one is not element, `id` and `tagName` will be undefined and we'll just compare that. + const oldElt = /** @type {Element} */ (oldNode); + const newElt = /** @type {Element} */ (newNode); + + return ( + oldElt.nodeType === newElt.nodeType && + oldElt.tagName === newElt.tagName && + // If oldElt has an `id` with possible state and it doesn't match newElt.id then avoid morphing. + // We'll still match an anonymous node with an IDed newElt, though, because if it got this far, + // its not persistent, and new nodes can't have any hidden state. + (!oldElt.id || oldElt.id === newElt.id) + ); + } + + return findBestMatch; + })(); + + //============================================================================= + // DOM Manipulation Functions + //============================================================================= + + /** + * Gets rid of an unwanted DOM node; strategy depends on nature of its reuse: + * - Persistent nodes will be moved to the pantry for later reuse + * - Other nodes will have their hooks called, and then are removed + * @param {MorphContext} ctx + * @param {Node} node + */ + function removeNode(ctx, node) { + // are we going to id set match this later? + if (ctx.idMap.has(node)) { + // skip callbacks and move to pantry + moveBefore(ctx.pantry, node, null); + } else { + // remove for realsies + if (ctx.callbacks.beforeNodeRemoved(node) === false) return; + node.parentNode?.removeChild(node); + ctx.callbacks.afterNodeRemoved(node); + } + } + + /** + * Remove nodes between the start and end nodes + * @param {MorphContext} ctx + * @param {Node} startInclusive + * @param {Node} endExclusive + * @returns {Node|null} + */ + function removeNodesBetween(ctx, startInclusive, endExclusive) { + /** @type {Node | null} */ + let cursor = startInclusive; + // remove nodes until the endExclusive node + while (cursor && cursor !== endExclusive) { + let tempNode = /** @type {Node} */ (cursor); + cursor = cursor.nextSibling; + removeNode(ctx, tempNode); + } + return cursor; + } + + /** + * Search for an element by id within the document and pantry, and move it using moveBefore. + * + * @param {Element} parentNode - The parent node to which the element will be moved. + * @param {string} id - The ID of the element to be moved. + * @param {Node | null} after - The reference node to insert the element before. + * If `null`, the element is appended as the last child. + * @param {MorphContext} ctx + * @returns {Element} The found element + */ + function moveBeforeById(parentNode, id, after, ctx) { + const target = + /** @type {Element} - will always be found */ + ( + ctx.target.querySelector(`#${id}`) || + ctx.pantry.querySelector(`#${id}`) + ); + removeElementFromAncestorsIdMaps(target, ctx); + moveBefore(parentNode, target, after); + return target; + } + + /** + * Removes an element from its ancestors' id maps. This is needed when an element is moved from the + * "future" via `moveBeforeId`. Otherwise, its erstwhile ancestors could be mistakenly moved to the + * pantry rather than being deleted, preventing their removal hooks from being called. + * + * @param {Element} element - element to remove from its ancestors' id maps + * @param {MorphContext} ctx + */ + function removeElementFromAncestorsIdMaps(element, ctx) { + const id = element.id; + /** @ts-ignore - safe to loop in this way **/ + while ((element = element.parentNode)) { + let idSet = ctx.idMap.get(element); + if (idSet) { + idSet.delete(id); + if (!idSet.size) { + ctx.idMap.delete(element); + } + } + } + } + + /** + * Moves an element before another element within the same parent. + * Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`. + * This is essentialy a forward-compat wrapper. + * + * @param {Element} parentNode - The parent node containing the after element. + * @param {Node} element - The element to be moved. + * @param {Node | null} after - The reference node to insert `element` before. + * If `null`, `element` is appended as the last child. + */ + function moveBefore(parentNode, element, after) { + // @ts-ignore - use proposed moveBefore feature + if (parentNode.moveBefore) { + try { + // @ts-ignore - use proposed moveBefore feature + parentNode.moveBefore(element, after); + } catch (e) { + // fall back to insertBefore as some browsers may fail on moveBefore when trying to move Dom disconnected nodes to pantry + parentNode.insertBefore(element, after); + } + } else { + parentNode.insertBefore(element, after); + } + } + + return morphChildren; + })(); + + //============================================================================= + // Single Node Morphing Code + //============================================================================= + const morphNode = (function () { + /** + * @param {Node} oldNode root node to merge content into + * @param {Node} newContent new content to merge + * @param {MorphContext} ctx the merge context + * @returns {Node | null} the element that ended up in the DOM + */ + function morphNode(oldNode, newContent, ctx) { + if (ctx.ignoreActive && oldNode === document.activeElement) { + // don't morph focused element + return null; + } + + if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) { + return oldNode; + } + + if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) ; else if ( + oldNode instanceof HTMLHeadElement && + ctx.head.style !== "morph" + ) { + // ok to cast: if newContent wasn't also a , it would've got caught in the `!isSoftMatch` branch above + handleHeadElement( + oldNode, + /** @type {HTMLHeadElement} */ (newContent), + ctx, + ); + } else { + morphAttributes(oldNode, newContent, ctx); + if (!ignoreValueOfActiveElement(oldNode, ctx)) { + // @ts-ignore newContent can be a node here because .firstChild will be null + morphChildren(ctx, oldNode, newContent); + } + } + ctx.callbacks.afterNodeMorphed(oldNode, newContent); + return oldNode; + } + + /** + * syncs the oldNode to the newNode, copying over all attributes and + * inner element state from the newNode to the oldNode + * + * @param {Node} oldNode the node to copy attributes & state to + * @param {Node} newNode the node to copy attributes & state from + * @param {MorphContext} ctx the merge context + */ + function morphAttributes(oldNode, newNode, ctx) { + let type = newNode.nodeType; + + // if is an element type, sync the attributes from the + // new node into the new node + if (type === 1 /* element type */) { + const oldElt = /** @type {Element} */ (oldNode); + const newElt = /** @type {Element} */ (newNode); + + const oldAttributes = oldElt.attributes; + const newAttributes = newElt.attributes; + for (const newAttribute of newAttributes) { + if (ignoreAttribute(newAttribute.name, oldElt, "update", ctx)) { + continue; + } + if (oldElt.getAttribute(newAttribute.name) !== newAttribute.value) { + oldElt.setAttribute(newAttribute.name, newAttribute.value); + } + } + // iterate backwards to avoid skipping over items when a delete occurs + for (let i = oldAttributes.length - 1; 0 <= i; i--) { + const oldAttribute = oldAttributes[i]; + + // toAttributes is a live NamedNodeMap, so iteration+mutation is unsafe + // e.g. custom element attribute callbacks can remove other attributes + if (!oldAttribute) continue; + + if (!newElt.hasAttribute(oldAttribute.name)) { + if (ignoreAttribute(oldAttribute.name, oldElt, "remove", ctx)) { + continue; + } + oldElt.removeAttribute(oldAttribute.name); + } + } + + if (!ignoreValueOfActiveElement(oldElt, ctx)) { + syncInputValue(oldElt, newElt, ctx); + } + } + + // sync text nodes + if (type === 8 /* comment */ || type === 3 /* text */) { + if (oldNode.nodeValue !== newNode.nodeValue) { + oldNode.nodeValue = newNode.nodeValue; + } + } + } + + /** + * NB: many bothans died to bring us information: + * + * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js + * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113 + * + * @param {Element} oldElement the element to sync the input value to + * @param {Element} newElement the element to sync the input value from + * @param {MorphContext} ctx the merge context + */ + function syncInputValue(oldElement, newElement, ctx) { + if ( + oldElement instanceof HTMLInputElement && + newElement instanceof HTMLInputElement && + newElement.type !== "file" + ) { + let newValue = newElement.value; + let oldValue = oldElement.value; + + // sync boolean attributes + syncBooleanAttribute(oldElement, newElement, "checked", ctx); + syncBooleanAttribute(oldElement, newElement, "disabled", ctx); + + if (!newElement.hasAttribute("value")) { + if (!ignoreAttribute("value", oldElement, "remove", ctx)) { + oldElement.value = ""; + oldElement.removeAttribute("value"); + } + } else if (oldValue !== newValue) { + if (!ignoreAttribute("value", oldElement, "update", ctx)) { + oldElement.setAttribute("value", newValue); + oldElement.value = newValue; + } + } + // TODO: QUESTION(1cg): this used to only check `newElement` unlike the other branches -- why? + // did I break something? + } else if ( + oldElement instanceof HTMLOptionElement && + newElement instanceof HTMLOptionElement + ) { + syncBooleanAttribute(oldElement, newElement, "selected", ctx); + } else if ( + oldElement instanceof HTMLTextAreaElement && + newElement instanceof HTMLTextAreaElement + ) { + let newValue = newElement.value; + let oldValue = oldElement.value; + if (ignoreAttribute("value", oldElement, "update", ctx)) { + return; + } + if (newValue !== oldValue) { + oldElement.value = newValue; + } + if ( + oldElement.firstChild && + oldElement.firstChild.nodeValue !== newValue + ) { + oldElement.firstChild.nodeValue = newValue; + } + } + } + + /** + * @param {Element} oldElement element to write the value to + * @param {Element} newElement element to read the value from + * @param {string} attributeName the attribute name + * @param {MorphContext} ctx the merge context + */ + function syncBooleanAttribute(oldElement, newElement, attributeName, ctx) { + // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties + const newLiveValue = newElement[attributeName], + // @ts-ignore ditto + oldLiveValue = oldElement[attributeName]; + if (newLiveValue !== oldLiveValue) { + const ignoreUpdate = ignoreAttribute( + attributeName, + oldElement, + "update", + ctx, + ); + if (!ignoreUpdate) { + // update attribute's associated DOM property + // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties + oldElement[attributeName] = newElement[attributeName]; + } + if (newLiveValue) { + if (!ignoreUpdate) { + // https://developer.mozilla.org/en-US/docs/Glossary/Boolean/HTML + // this is the correct way to set a boolean attribute to "true" + oldElement.setAttribute(attributeName, ""); + } + } else { + if (!ignoreAttribute(attributeName, oldElement, "remove", ctx)) { + oldElement.removeAttribute(attributeName); + } + } + } + } + + /** + * @param {string} attr the attribute to be mutated + * @param {Element} element the element that is going to be updated + * @param {"update" | "remove"} updateType + * @param {MorphContext} ctx the merge context + * @returns {boolean} true if the attribute should be ignored, false otherwise + */ + function ignoreAttribute(attr, element, updateType, ctx) { + if ( + attr === "value" && + ctx.ignoreActiveValue && + element === document.activeElement + ) { + return true; + } + return ( + ctx.callbacks.beforeAttributeUpdated(attr, element, updateType) === + false + ); + } + + /** + * @param {Node} possibleActiveElement + * @param {MorphContext} ctx + * @returns {boolean} + */ + function ignoreValueOfActiveElement(possibleActiveElement, ctx) { + return ( + !!ctx.ignoreActiveValue && + possibleActiveElement === document.activeElement && + possibleActiveElement !== document.body + ); + } + + return morphNode; + })(); + + //============================================================================= + // Head Management Functions + //============================================================================= + /** + * @param {MorphContext} ctx + * @param {Element} oldNode + * @param {Element} newNode + * @param {function} callback + * @returns {Node[] | Promise} + */ + function withHeadBlocking(ctx, oldNode, newNode, callback) { + if (ctx.head.block) { + const oldHead = oldNode.querySelector("head"); + const newHead = newNode.querySelector("head"); + if (oldHead && newHead) { + const promises = handleHeadElement(oldHead, newHead, ctx); + // when head promises resolve, proceed ignoring the head tag + return Promise.all(promises).then(() => { + const newCtx = Object.assign(ctx, { + head: { + block: false, + ignore: true, + }, + }); + return callback(newCtx); + }); + } + } + // just proceed if we not head blocking + return callback(ctx); + } + + /** + * The HEAD tag can be handled specially, either w/ a 'merge' or 'append' style + * + * @param {Element} oldHead + * @param {Element} newHead + * @param {MorphContext} ctx + * @returns {Promise[]} + */ + function handleHeadElement(oldHead, newHead, ctx) { + let added = []; + let removed = []; + let preserved = []; + let nodesToAppend = []; + + // put all new head elements into a Map, by their outerHTML + let srcToNewHeadNodes = new Map(); + for (const newHeadChild of newHead.children) { + srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild); + } + + // for each elt in the current head + for (const currentHeadElt of oldHead.children) { + // If the current head element is in the map + let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML); + let isReAppended = ctx.head.shouldReAppend(currentHeadElt); + let isPreserved = ctx.head.shouldPreserve(currentHeadElt); + if (inNewContent || isPreserved) { + if (isReAppended) { + // remove the current version and let the new version replace it and re-execute + removed.push(currentHeadElt); + } else { + // this element already exists and should not be re-appended, so remove it from + // the new content map, preserving it in the DOM + srcToNewHeadNodes.delete(currentHeadElt.outerHTML); + preserved.push(currentHeadElt); + } + } else { + if (ctx.head.style === "append") { + // we are appending and this existing element is not new content + // so if and only if it is marked for re-append do we do anything + if (isReAppended) { + removed.push(currentHeadElt); + nodesToAppend.push(currentHeadElt); + } + } else { + // if this is a merge, we remove this content since it is not in the new head + if (ctx.head.shouldRemove(currentHeadElt) !== false) { + removed.push(currentHeadElt); + } + } + } + } + + // Push the remaining new head elements in the Map into the + // nodes to append to the head tag + nodesToAppend.push(...srcToNewHeadNodes.values()); + + let promises = []; + for (const newNode of nodesToAppend) { + // TODO: This could theoretically be null, based on type + let newElt = /** @type {ChildNode} */ ( + document.createRange().createContextualFragment(newNode.outerHTML) + .firstChild + ); + if (ctx.callbacks.beforeNodeAdded(newElt) !== false) { + if ( + ("href" in newElt && newElt.href) || + ("src" in newElt && newElt.src) + ) { + /** @type {(result?: any) => void} */ let resolve; + let promise = new Promise(function (_resolve) { + resolve = _resolve; + }); + newElt.addEventListener("load", function () { + resolve(); + }); + promises.push(promise); + } + oldHead.appendChild(newElt); + ctx.callbacks.afterNodeAdded(newElt); + added.push(newElt); + } + } + + // remove all removed elements, after we have appended the new elements to avoid + // additional network requests for things like style sheets + for (const removedElement of removed) { + if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) { + oldHead.removeChild(removedElement); + ctx.callbacks.afterNodeRemoved(removedElement); + } + } + + ctx.head.afterHeadMorphed(oldHead, { + added: added, + kept: preserved, + removed: removed, + }); + return promises; + } + + //============================================================================= + // Create Morph Context Functions + //============================================================================= + const createMorphContext = (function () { + /** + * + * @param {Element} oldNode + * @param {Element} newContent + * @param {Config} config + * @returns {MorphContext} + */ + function createMorphContext(oldNode, newContent, config) { + const { persistentIds, idMap } = createIdMaps(oldNode, newContent); + + const mergedConfig = mergeDefaults(config); + const morphStyle = mergedConfig.morphStyle || "outerHTML"; + if (!["innerHTML", "outerHTML"].includes(morphStyle)) { + throw `Do not understand how to morph style ${morphStyle}`; + } + + return { + target: oldNode, + newContent: newContent, + config: mergedConfig, + morphStyle: morphStyle, + ignoreActive: mergedConfig.ignoreActive, + ignoreActiveValue: mergedConfig.ignoreActiveValue, + restoreFocus: mergedConfig.restoreFocus, + idMap: idMap, + persistentIds: persistentIds, + pantry: createPantry(), + callbacks: mergedConfig.callbacks, + head: mergedConfig.head, + }; + } + + /** + * Deep merges the config object and the Idiomorph.defaults object to + * produce a final configuration object + * @param {Config} config + * @returns {ConfigInternal} + */ + function mergeDefaults(config) { + let finalConfig = Object.assign({}, defaults); + + // copy top level stuff into final config + Object.assign(finalConfig, config); + + // copy callbacks into final config (do this to deep merge the callbacks) + finalConfig.callbacks = Object.assign( + {}, + defaults.callbacks, + config.callbacks, + ); + + // copy head config into final config (do this to deep merge the head) + finalConfig.head = Object.assign({}, defaults.head, config.head); + + return finalConfig; + } + + /** + * @returns {HTMLDivElement} + */ + function createPantry() { + const pantry = document.createElement("div"); + pantry.hidden = true; + document.body.insertAdjacentElement("afterend", pantry); + return pantry; + } + + /** + * Returns all elements with an ID contained within the root element and its descendants + * + * @param {Element} root + * @returns {Element[]} + */ + function findIdElements(root) { + let elements = Array.from(root.querySelectorAll("[id]")); + if (root.id) { + elements.push(root); + } + return elements; + } + + /** + * A bottom-up algorithm that populates a map of Element -> IdSet. + * The idSet for a given element is the set of all IDs contained within its subtree. + * As an optimzation, we filter these IDs through the given list of persistent IDs, + * because we don't need to bother considering IDed elements that won't be in the new content. + * + * @param {Map>} idMap + * @param {Set} persistentIds + * @param {Element} root + * @param {Element[]} elements + */ + function populateIdMapWithTree(idMap, persistentIds, root, elements) { + for (const elt of elements) { + if (persistentIds.has(elt.id)) { + /** @type {Element|null} */ + let current = elt; + // walk up the parent hierarchy of that element, adding the id + // of element to the parent's id set + while (current) { + let idSet = idMap.get(current); + // if the id set doesn't exist, create it and insert it in the map + if (idSet == null) { + idSet = new Set(); + idMap.set(current, idSet); + } + idSet.add(elt.id); + + if (current === root) break; + current = current.parentElement; + } + } + } + } + + /** + * This function computes a map of nodes to all ids contained within that node (inclusive of the + * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows + * for a looser definition of "matching" than tradition id matching, and allows child nodes + * to contribute to a parent nodes matching. + * + * @param {Element} oldContent the old content that will be morphed + * @param {Element} newContent the new content to morph to + * @returns {IdSets} + */ + function createIdMaps(oldContent, newContent) { + const oldIdElements = findIdElements(oldContent); + const newIdElements = findIdElements(newContent); + + const persistentIds = createPersistentIds(oldIdElements, newIdElements); + + /** @type {Map>} */ + let idMap = new Map(); + populateIdMapWithTree(idMap, persistentIds, oldContent, oldIdElements); + + /** @ts-ignore - if newContent is a duck-typed parent, pass its single child node as the root to halt upwards iteration */ + const newRoot = newContent.__idiomorphRoot || newContent; + populateIdMapWithTree(idMap, persistentIds, newRoot, newIdElements); + + return { persistentIds, idMap }; + } + + /** + * This function computes the set of ids that persist between the two contents excluding duplicates + * + * @param {Element[]} oldIdElements + * @param {Element[]} newIdElements + * @returns {Set} + */ + function createPersistentIds(oldIdElements, newIdElements) { + let duplicateIds = new Set(); + + /** @type {Map} */ + let oldIdTagNameMap = new Map(); + for (const { id, tagName } of oldIdElements) { + if (oldIdTagNameMap.has(id)) { + duplicateIds.add(id); + } else { + oldIdTagNameMap.set(id, tagName); + } + } + + let persistentIds = new Set(); + for (const { id, tagName } of newIdElements) { + if (persistentIds.has(id)) { + duplicateIds.add(id); + } else if (oldIdTagNameMap.get(id) === tagName) { + persistentIds.add(id); + } + // skip if tag types mismatch because its not possible to morph one tag into another + } + + for (const id of duplicateIds) { + persistentIds.delete(id); + } + return persistentIds; + } + + return createMorphContext; + })(); + + //============================================================================= + // HTML Normalization Functions + //============================================================================= + const { normalizeElement, normalizeParent } = (function () { + /** @type {WeakSet} */ + const generatedByIdiomorph = new WeakSet(); + + /** + * + * @param {Element | Document} content + * @returns {Element} + */ + function normalizeElement(content) { + if (content instanceof Document) { + return content.documentElement; + } else { + return content; + } + } + + /** + * + * @param {null | string | Node | HTMLCollection | Node[] | Document & {generatedByIdiomorph:boolean}} newContent + * @returns {Element} + */ + function normalizeParent(newContent) { + if (newContent == null) { + return document.createElement("div"); // dummy parent element + } else if (typeof newContent === "string") { + return normalizeParent(parseContent(newContent)); + } else if ( + generatedByIdiomorph.has(/** @type {Element} */ (newContent)) + ) { + // the template tag created by idiomorph parsing can serve as a dummy parent + return /** @type {Element} */ (newContent); + } else if (newContent instanceof Node) { + if (newContent.parentNode) { + // we can't use the parent directly because newContent may have siblings + // that we don't want in the morph, and reparenting might be expensive (TODO is it?), + // so we create a duck-typed parent node instead. + return createDuckTypedParent(newContent); + } else { + // a single node is added as a child to a dummy parent + const dummyParent = document.createElement("div"); + dummyParent.append(newContent); + return dummyParent; + } + } else { + // all nodes in the array or HTMLElement collection are consolidated under + // a single dummy parent element + const dummyParent = document.createElement("div"); + for (const elt of [...newContent]) { + dummyParent.append(elt); + } + return dummyParent; + } + } + + /** + * Creates a fake duck-typed parent element to wrap a single node, without actually reparenting it. + * "If it walks like a duck, and quacks like a duck, then it must be a duck!" -- James Whitcomb Riley (1849–1916) + * + * @param {Node} newContent + * @returns {Element} + */ + function createDuckTypedParent(newContent) { + return /** @type {Element} */ ( + /** @type {unknown} */ ({ + childNodes: [newContent], + /** @ts-ignore - cover your eyes for a minute, tsc */ + querySelectorAll: (s) => { + /** @ts-ignore */ + const elements = newContent.querySelectorAll(s); + /** @ts-ignore */ + return newContent.matches(s) ? [newContent, ...elements] : elements; + }, + /** @ts-ignore */ + insertBefore: (n, r) => newContent.parentNode.insertBefore(n, r), + /** @ts-ignore */ + moveBefore: (n, r) => newContent.parentNode.moveBefore(n, r), + // for later use with populateIdMapWithTree to halt upwards iteration + get __idiomorphRoot() { + return newContent; + }, + }) + ); + } + + /** + * + * @param {string} newContent + * @returns {Node | null | DocumentFragment} + */ + function parseContent(newContent) { + let parser = new DOMParser(); + + // remove svgs to avoid false-positive matches on head, etc. + let contentWithSvgsRemoved = newContent.replace( + /]*>|>)([\s\S]*?)<\/svg>/gim, + "", + ); + + // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping + if ( + contentWithSvgsRemoved.match(/<\/html>/) || + contentWithSvgsRemoved.match(/<\/head>/) || + contentWithSvgsRemoved.match(/<\/body>/) + ) { + let content = parser.parseFromString(newContent, "text/html"); + // if it is a full HTML document, return the document itself as the parent container + if (contentWithSvgsRemoved.match(/<\/html>/)) { + generatedByIdiomorph.add(content); + return content; + } else { + // otherwise return the html element as the parent container + let htmlElement = content.firstChild; + if (htmlElement) { + generatedByIdiomorph.add(htmlElement); + } + return htmlElement; + } + } else { + // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help + // deal with touchy tags like tr, tbody, etc. + let responseDoc = parser.parseFromString( + "", + "text/html", + ); + let content = /** @type {HTMLTemplateElement} */ ( + responseDoc.body.querySelector("template") + ).content; + generatedByIdiomorph.add(content); + return content; + } + } + + return { normalizeElement, normalizeParent }; + })(); + + //============================================================================= + // This is what ends up becoming the Idiomorph global object + //============================================================================= + return { + morph, + defaults, + }; +})(); + +function morphElements(currentElement, newElement, { callbacks, ...options } = {}) { + Idiomorph.morph(currentElement, newElement, { + ...options, + callbacks: new DefaultIdiomorphCallbacks(callbacks) + }); +} + +function morphChildren(currentElement, newElement) { + morphElements(currentElement, newElement.childNodes, { + morphStyle: "innerHTML" + }); +} + +class DefaultIdiomorphCallbacks { + #beforeNodeMorphed + + constructor({ beforeNodeMorphed } = {}) { + this.#beforeNodeMorphed = beforeNodeMorphed || (() => true); + } + + beforeNodeAdded = (node) => { + return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id)) + } + + beforeNodeMorphed = (currentElement, newElement) => { + if (currentElement instanceof Element) { + if (!currentElement.hasAttribute("data-turbo-permanent") && this.#beforeNodeMorphed(currentElement, newElement)) { + const event = dispatch("turbo:before-morph-element", { + cancelable: true, + target: currentElement, + detail: { currentElement, newElement } + }); + + return !event.defaultPrevented + } else { + return false + } + } + } + + beforeAttributeUpdated = (attributeName, target, mutationType) => { + const event = dispatch("turbo:before-morph-attribute", { + cancelable: true, + target, + detail: { attributeName, mutationType } + }); + + return !event.defaultPrevented + } + + beforeNodeRemoved = (node) => { + return this.beforeNodeMorphed(node) + } + + afterNodeMorphed = (currentElement, newElement) => { + if (currentElement instanceof Element) { + dispatch("turbo:morph-element", { + target: currentElement, + detail: { currentElement, newElement } + }); + } + } +} + +class MorphingFrameRenderer extends FrameRenderer { + static renderElement(currentElement, newElement) { + dispatch("turbo:before-frame-morph", { + target: currentElement, + detail: { currentElement, newElement } + }); + + morphChildren(currentElement, newElement); + } + + async preservingPermanentElements(callback) { + return await callback() + } +} + +class ProgressBar { + static animationDuration = 300 /*ms*/ + + static get defaultCSS() { + return unindent` + .turbo-progress-bar { + position: fixed; + display: block; + top: 0; + left: 0; + height: 3px; + background: #0076ff; + z-index: 2147483647; + transition: + width ${ProgressBar.animationDuration}ms ease-out, + opacity ${ProgressBar.animationDuration / 2}ms ${ProgressBar.animationDuration / 2}ms ease-in; + transform: translate3d(0, 0, 0); + } + ` + } + + hiding = false + value = 0 + visible = false + + constructor() { + this.stylesheetElement = this.createStylesheetElement(); + this.progressElement = this.createProgressElement(); + this.installStylesheetElement(); + this.setValue(0); + } + + show() { + if (!this.visible) { + this.visible = true; + this.installProgressElement(); + this.startTrickling(); + } + } + + hide() { + if (this.visible && !this.hiding) { + this.hiding = true; + this.fadeProgressElement(() => { + this.uninstallProgressElement(); + this.stopTrickling(); + this.visible = false; + this.hiding = false; + }); + } + } + + setValue(value) { + this.value = value; + this.refresh(); + } + + // Private + + installStylesheetElement() { + document.head.insertBefore(this.stylesheetElement, document.head.firstChild); + } + + installProgressElement() { + this.progressElement.style.width = "0"; + this.progressElement.style.opacity = "1"; + document.documentElement.insertBefore(this.progressElement, document.body); + this.refresh(); + } + + fadeProgressElement(callback) { + this.progressElement.style.opacity = "0"; + setTimeout(callback, ProgressBar.animationDuration * 1.5); + } + + uninstallProgressElement() { + if (this.progressElement.parentNode) { + document.documentElement.removeChild(this.progressElement); + } + } + + startTrickling() { + if (!this.trickleInterval) { + this.trickleInterval = window.setInterval(this.trickle, ProgressBar.animationDuration); + } + } + + stopTrickling() { + window.clearInterval(this.trickleInterval); + delete this.trickleInterval; + } + + trickle = () => { + this.setValue(this.value + Math.random() / 100); + } + + refresh() { + requestAnimationFrame(() => { + this.progressElement.style.width = `${10 + this.value * 90}%`; + }); + } + + createStylesheetElement() { + const element = document.createElement("style"); + element.type = "text/css"; + element.textContent = ProgressBar.defaultCSS; + const cspNonce = getCspNonce(); + if (cspNonce) { + element.nonce = cspNonce; + } + return element + } + + createProgressElement() { + const element = document.createElement("div"); + element.className = "turbo-progress-bar"; + return element + } +} + +class HeadSnapshot extends Snapshot { + detailsByOuterHTML = this.children + .filter((element) => !elementIsNoscript(element)) + .map((element) => elementWithoutNonce(element)) + .reduce((result, element) => { + const { outerHTML } = element; + const details = + outerHTML in result + ? result[outerHTML] + : { + type: elementType(element), + tracked: elementIsTracked(element), + elements: [] + }; + return { + ...result, + [outerHTML]: { + ...details, + elements: [...details.elements, element] + } + } + }, {}) + + get trackedElementSignature() { + return Object.keys(this.detailsByOuterHTML) + .filter((outerHTML) => this.detailsByOuterHTML[outerHTML].tracked) + .join("") + } + + getScriptElementsNotInSnapshot(snapshot) { + return this.getElementsMatchingTypeNotInSnapshot("script", snapshot) + } + + getStylesheetElementsNotInSnapshot(snapshot) { + return this.getElementsMatchingTypeNotInSnapshot("stylesheet", snapshot) + } + + getElementsMatchingTypeNotInSnapshot(matchedType, snapshot) { + return Object.keys(this.detailsByOuterHTML) + .filter((outerHTML) => !(outerHTML in snapshot.detailsByOuterHTML)) + .map((outerHTML) => this.detailsByOuterHTML[outerHTML]) + .filter(({ type }) => type == matchedType) + .map(({ elements: [element] }) => element) + } + + get provisionalElements() { + return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => { + const { type, tracked, elements } = this.detailsByOuterHTML[outerHTML]; + if (type == null && !tracked) { + return [...result, ...elements] + } else if (elements.length > 1) { + return [...result, ...elements.slice(1)] + } else { + return result + } + }, []) + } + + getMetaValue(name) { + const element = this.findMetaElementByName(name); + return element ? element.getAttribute("content") : null + } + + findMetaElementByName(name) { + return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => { + const { + elements: [element] + } = this.detailsByOuterHTML[outerHTML]; + return elementIsMetaElementWithName(element, name) ? element : result + }, undefined | undefined) + } +} + +function elementType(element) { + if (elementIsScript(element)) { + return "script" + } else if (elementIsStylesheet(element)) { + return "stylesheet" + } +} + +function elementIsTracked(element) { + return element.getAttribute("data-turbo-track") == "reload" +} + +function elementIsScript(element) { + const tagName = element.localName; + return tagName == "script" +} + +function elementIsNoscript(element) { + const tagName = element.localName; + return tagName == "noscript" +} + +function elementIsStylesheet(element) { + const tagName = element.localName; + return tagName == "style" || (tagName == "link" && element.getAttribute("rel") == "stylesheet") +} + +function elementIsMetaElementWithName(element, name) { + const tagName = element.localName; + return tagName == "meta" && element.getAttribute("name") == name +} + +function elementWithoutNonce(element) { + if (element.hasAttribute("nonce")) { + element.setAttribute("nonce", ""); + } + + return element +} + +class PageSnapshot extends Snapshot { + static fromHTMLString(html = "") { + return this.fromDocument(parseHTMLDocument(html)) + } + + static fromElement(element) { + return this.fromDocument(element.ownerDocument) + } + + static fromDocument({ documentElement, body, head }) { + return new this(documentElement, body, new HeadSnapshot(head)) + } + + constructor(documentElement, body, headSnapshot) { + super(body); + this.documentElement = documentElement; + this.headSnapshot = headSnapshot; + } + + clone() { + const clonedElement = this.element.cloneNode(true); + + const selectElements = this.element.querySelectorAll("select"); + const clonedSelectElements = clonedElement.querySelectorAll("select"); + + for (const [index, source] of selectElements.entries()) { + const clone = clonedSelectElements[index]; + for (const option of clone.selectedOptions) option.selected = false; + for (const option of source.selectedOptions) clone.options[option.index].selected = true; + } + + for (const clonedPasswordInput of clonedElement.querySelectorAll('input[type="password"]')) { + clonedPasswordInput.value = ""; + } + + return new PageSnapshot(this.documentElement, clonedElement, this.headSnapshot) + } + + get lang() { + return this.documentElement.getAttribute("lang") + } + + get headElement() { + return this.headSnapshot.element + } + + get rootLocation() { + const root = this.getSetting("root") ?? "/"; + return expandURL(root) + } + + get cacheControlValue() { + return this.getSetting("cache-control") + } + + get isPreviewable() { + return this.cacheControlValue != "no-preview" + } + + get isCacheable() { + return this.cacheControlValue != "no-cache" + } + + get isVisitable() { + return this.getSetting("visit-control") != "reload" + } + + get prefersViewTransitions() { + return this.headSnapshot.getMetaValue("view-transition") === "same-origin" + } + + get shouldMorphPage() { + return this.getSetting("refresh-method") === "morph" + } + + get shouldPreserveScrollPosition() { + return this.getSetting("refresh-scroll") === "preserve" + } + + // Private + + getSetting(name) { + return this.headSnapshot.getMetaValue(`turbo-${name}`) + } +} + +class ViewTransitioner { + #viewTransitionStarted = false + #lastOperation = Promise.resolve() + + renderChange(useViewTransition, render) { + if (useViewTransition && this.viewTransitionsAvailable && !this.#viewTransitionStarted) { + this.#viewTransitionStarted = true; + this.#lastOperation = this.#lastOperation.then(async () => { + await document.startViewTransition(render).finished; + }); + } else { + this.#lastOperation = this.#lastOperation.then(render); + } + + return this.#lastOperation + } + + get viewTransitionsAvailable() { + return document.startViewTransition + } +} + +const defaultOptions = { + action: "advance", + historyChanged: false, + visitCachedSnapshot: () => {}, + willRender: true, + updateHistory: true, + shouldCacheSnapshot: true, + acceptsStreamResponse: false +}; + +const TimingMetric = { + visitStart: "visitStart", + requestStart: "requestStart", + requestEnd: "requestEnd", + visitEnd: "visitEnd" +}; + +const VisitState = { + initialized: "initialized", + started: "started", + canceled: "canceled", + failed: "failed", + completed: "completed" +}; + +const SystemStatusCode = { + networkFailure: 0, + timeoutFailure: -1, + contentTypeMismatch: -2 +}; + +const Direction = { + advance: "forward", + restore: "back", + replace: "none" +}; + +class Visit { + identifier = uuid() // Required by turbo-ios + timingMetrics = {} + + followedRedirect = false + historyChanged = false + scrolled = false + shouldCacheSnapshot = true + acceptsStreamResponse = false + snapshotCached = false + state = VisitState.initialized + viewTransitioner = new ViewTransitioner() + + constructor(delegate, location, restorationIdentifier, options = {}) { + this.delegate = delegate; + this.location = location; + this.restorationIdentifier = restorationIdentifier || uuid(); + + const { + action, + historyChanged, + referrer, + snapshot, + snapshotHTML, + response, + visitCachedSnapshot, + willRender, + updateHistory, + shouldCacheSnapshot, + acceptsStreamResponse, + direction + } = { + ...defaultOptions, + ...options + }; + this.action = action; + this.historyChanged = historyChanged; + this.referrer = referrer; + this.snapshot = snapshot; + this.snapshotHTML = snapshotHTML; + this.response = response; + this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action); + this.isPageRefresh = this.view.isPageRefresh(this); + this.visitCachedSnapshot = visitCachedSnapshot; + this.willRender = willRender; + this.updateHistory = updateHistory; + this.scrolled = !willRender; + this.shouldCacheSnapshot = shouldCacheSnapshot; + this.acceptsStreamResponse = acceptsStreamResponse; + this.direction = direction || Direction[action]; + } + + get adapter() { + return this.delegate.adapter + } + + get view() { + return this.delegate.view + } + + get history() { + return this.delegate.history + } + + get restorationData() { + return this.history.getRestorationDataForIdentifier(this.restorationIdentifier) + } + + get silent() { + return this.isSamePage + } + + start() { + if (this.state == VisitState.initialized) { + this.recordTimingMetric(TimingMetric.visitStart); + this.state = VisitState.started; + this.adapter.visitStarted(this); + this.delegate.visitStarted(this); + } + } + + cancel() { + if (this.state == VisitState.started) { + if (this.request) { + this.request.cancel(); + } + this.cancelRender(); + this.state = VisitState.canceled; + } + } + + complete() { + if (this.state == VisitState.started) { + this.recordTimingMetric(TimingMetric.visitEnd); + this.adapter.visitCompleted(this); + this.state = VisitState.completed; + this.followRedirect(); + + if (!this.followedRedirect) { + this.delegate.visitCompleted(this); + } + } + } + + fail() { + if (this.state == VisitState.started) { + this.state = VisitState.failed; + this.adapter.visitFailed(this); + this.delegate.visitCompleted(this); + } + } + + changeHistory() { + if (!this.historyChanged && this.updateHistory) { + const actionForHistory = this.location.href === this.referrer?.href ? "replace" : this.action; + const method = getHistoryMethodForAction(actionForHistory); + this.history.update(method, this.location, this.restorationIdentifier); + this.historyChanged = true; + } + } + + issueRequest() { + if (this.hasPreloadedResponse()) { + this.simulateRequest(); + } else if (this.shouldIssueRequest() && !this.request) { + this.request = new FetchRequest(this, FetchMethod.get, this.location); + this.request.perform(); + } + } + + simulateRequest() { + if (this.response) { + this.startRequest(); + this.recordResponse(); + this.finishRequest(); + } + } + + startRequest() { + this.recordTimingMetric(TimingMetric.requestStart); + this.adapter.visitRequestStarted(this); + } + + recordResponse(response = this.response) { + this.response = response; + if (response) { + const { statusCode } = response; + if (isSuccessful(statusCode)) { + this.adapter.visitRequestCompleted(this); + } else { + this.adapter.visitRequestFailedWithStatusCode(this, statusCode); + } + } + } + + finishRequest() { + this.recordTimingMetric(TimingMetric.requestEnd); + this.adapter.visitRequestFinished(this); + } + + loadResponse() { + if (this.response) { + const { statusCode, responseHTML } = this.response; + this.render(async () => { + if (this.shouldCacheSnapshot) this.cacheSnapshot(); + if (this.view.renderPromise) await this.view.renderPromise; + + if (isSuccessful(statusCode) && responseHTML != null) { + const snapshot = PageSnapshot.fromHTMLString(responseHTML); + await this.renderPageSnapshot(snapshot, false); + + this.adapter.visitRendered(this); + this.complete(); + } else { + await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML), this); + this.adapter.visitRendered(this); + this.fail(); + } + }); + } + } + + getCachedSnapshot() { + const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot(); + + if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) { + if (this.action == "restore" || snapshot.isPreviewable) { + return snapshot + } + } + } + + getPreloadedSnapshot() { + if (this.snapshotHTML) { + return PageSnapshot.fromHTMLString(this.snapshotHTML) + } + } + + hasCachedSnapshot() { + return this.getCachedSnapshot() != null + } + + loadCachedSnapshot() { + const snapshot = this.getCachedSnapshot(); + if (snapshot) { + const isPreview = this.shouldIssueRequest(); + this.render(async () => { + this.cacheSnapshot(); + if (this.isSamePage || this.isPageRefresh) { + this.adapter.visitRendered(this); + } else { + if (this.view.renderPromise) await this.view.renderPromise; + + await this.renderPageSnapshot(snapshot, isPreview); + + this.adapter.visitRendered(this); + if (!isPreview) { + this.complete(); + } + } + }); + } + } + + followRedirect() { + if (this.redirectedToLocation && !this.followedRedirect && this.response?.redirected) { + this.adapter.visitProposedToLocation(this.redirectedToLocation, { + action: "replace", + response: this.response, + shouldCacheSnapshot: false, + willRender: false + }); + this.followedRedirect = true; + } + } + + goToSamePageAnchor() { + if (this.isSamePage) { + this.render(async () => { + this.cacheSnapshot(); + this.performScroll(); + this.changeHistory(); + this.adapter.visitRendered(this); + }); + } + } + + // Fetch request delegate + + prepareRequest(request) { + if (this.acceptsStreamResponse) { + request.acceptResponseType(StreamMessage.contentType); + } + } + + requestStarted() { + this.startRequest(); + } + + requestPreventedHandlingResponse(_request, _response) {} + + async requestSucceededWithResponse(request, response) { + const responseHTML = await response.responseHTML; + const { redirected, statusCode } = response; + if (responseHTML == undefined) { + this.recordResponse({ + statusCode: SystemStatusCode.contentTypeMismatch, + redirected + }); + } else { + this.redirectedToLocation = response.redirected ? response.location : undefined; + this.recordResponse({ statusCode: statusCode, responseHTML, redirected }); + } + } + + async requestFailedWithResponse(request, response) { + const responseHTML = await response.responseHTML; + const { redirected, statusCode } = response; + if (responseHTML == undefined) { + this.recordResponse({ + statusCode: SystemStatusCode.contentTypeMismatch, + redirected + }); + } else { + this.recordResponse({ statusCode: statusCode, responseHTML, redirected }); + } + } + + requestErrored(_request, _error) { + this.recordResponse({ + statusCode: SystemStatusCode.networkFailure, + redirected: false + }); + } + + requestFinished() { + this.finishRequest(); + } + + // Scrolling + + performScroll() { + if (!this.scrolled && !this.view.forceReloaded && !this.view.shouldPreserveScrollPosition(this)) { + if (this.action == "restore") { + this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop(); + } else { + this.scrollToAnchor() || this.view.scrollToTop(); + } + if (this.isSamePage) { + this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation, this.location); + } + + this.scrolled = true; + } + } + + scrollToRestoredPosition() { + const { scrollPosition } = this.restorationData; + if (scrollPosition) { + this.view.scrollToPosition(scrollPosition); + return true + } + } + + scrollToAnchor() { + const anchor = getAnchor(this.location); + if (anchor != null) { + this.view.scrollToAnchor(anchor); + return true + } + } + + // Instrumentation + + recordTimingMetric(metric) { + this.timingMetrics[metric] = new Date().getTime(); + } + + getTimingMetrics() { + return { ...this.timingMetrics } + } + + // Private + + hasPreloadedResponse() { + return typeof this.response == "object" + } + + shouldIssueRequest() { + if (this.isSamePage) { + return false + } else if (this.action == "restore") { + return !this.hasCachedSnapshot() + } else { + return this.willRender + } + } + + cacheSnapshot() { + if (!this.snapshotCached) { + this.view.cacheSnapshot(this.snapshot).then((snapshot) => snapshot && this.visitCachedSnapshot(snapshot)); + this.snapshotCached = true; + } + } + + async render(callback) { + this.cancelRender(); + await new Promise((resolve) => { + this.frame = + document.visibilityState === "hidden" ? setTimeout(() => resolve(), 0) : requestAnimationFrame(() => resolve()); + }); + await callback(); + delete this.frame; + } + + async renderPageSnapshot(snapshot, isPreview) { + await this.viewTransitioner.renderChange(this.view.shouldTransitionTo(snapshot), async () => { + await this.view.renderPage(snapshot, isPreview, this.willRender, this); + this.performScroll(); + }); + } + + cancelRender() { + if (this.frame) { + cancelAnimationFrame(this.frame); + delete this.frame; + } + } +} + +function isSuccessful(statusCode) { + return statusCode >= 200 && statusCode < 300 +} + +class BrowserAdapter { + progressBar = new ProgressBar() + + constructor(session) { + this.session = session; + } + + visitProposedToLocation(location, options) { + if (locationIsVisitable(location, this.navigator.rootLocation)) { + this.navigator.startVisit(location, options?.restorationIdentifier || uuid(), options); + } else { + window.location.href = location.toString(); + } + } + + visitStarted(visit) { + this.location = visit.location; + visit.loadCachedSnapshot(); + visit.issueRequest(); + visit.goToSamePageAnchor(); + } + + visitRequestStarted(visit) { + this.progressBar.setValue(0); + if (visit.hasCachedSnapshot() || visit.action != "restore") { + this.showVisitProgressBarAfterDelay(); + } else { + this.showProgressBar(); + } + } + + visitRequestCompleted(visit) { + visit.loadResponse(); + } + + visitRequestFailedWithStatusCode(visit, statusCode) { + switch (statusCode) { + case SystemStatusCode.networkFailure: + case SystemStatusCode.timeoutFailure: + case SystemStatusCode.contentTypeMismatch: + return this.reload({ + reason: "request_failed", + context: { + statusCode + } + }) + default: + return visit.loadResponse() + } + } + + visitRequestFinished(_visit) {} + + visitCompleted(_visit) { + this.progressBar.setValue(1); + this.hideVisitProgressBar(); + } + + pageInvalidated(reason) { + this.reload(reason); + } + + visitFailed(_visit) { + this.progressBar.setValue(1); + this.hideVisitProgressBar(); + } + + visitRendered(_visit) {} + + // Link prefetching + + linkPrefetchingIsEnabledForLocation(location) { + return true + } + + // Form Submission Delegate + + formSubmissionStarted(_formSubmission) { + this.progressBar.setValue(0); + this.showFormProgressBarAfterDelay(); + } + + formSubmissionFinished(_formSubmission) { + this.progressBar.setValue(1); + this.hideFormProgressBar(); + } + + // Private + + showVisitProgressBarAfterDelay() { + this.visitProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay); + } + + hideVisitProgressBar() { + this.progressBar.hide(); + if (this.visitProgressBarTimeout != null) { + window.clearTimeout(this.visitProgressBarTimeout); + delete this.visitProgressBarTimeout; + } + } + + showFormProgressBarAfterDelay() { + if (this.formProgressBarTimeout == null) { + this.formProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay); + } + } + + hideFormProgressBar() { + this.progressBar.hide(); + if (this.formProgressBarTimeout != null) { + window.clearTimeout(this.formProgressBarTimeout); + delete this.formProgressBarTimeout; + } + } + + showProgressBar = () => { + this.progressBar.show(); + } + + reload(reason) { + dispatch("turbo:reload", { detail: reason }); + + window.location.href = this.location?.toString() || window.location.href; + } + + get navigator() { + return this.session.navigator + } +} + +class CacheObserver { + selector = "[data-turbo-temporary]" + deprecatedSelector = "[data-turbo-cache=false]" + + started = false + + start() { + if (!this.started) { + this.started = true; + addEventListener("turbo:before-cache", this.removeTemporaryElements, false); + } + } + + stop() { + if (this.started) { + this.started = false; + removeEventListener("turbo:before-cache", this.removeTemporaryElements, false); + } + } + + removeTemporaryElements = (_event) => { + for (const element of this.temporaryElements) { + element.remove(); + } + } + + get temporaryElements() { + return [...document.querySelectorAll(this.selector), ...this.temporaryElementsWithDeprecation] + } + + get temporaryElementsWithDeprecation() { + const elements = document.querySelectorAll(this.deprecatedSelector); + + if (elements.length) { + console.warn( + `The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.` + ); + } + + return [...elements] + } +} + +class FrameRedirector { + constructor(session, element) { + this.session = session; + this.element = element; + this.linkInterceptor = new LinkInterceptor(this, element); + this.formSubmitObserver = new FormSubmitObserver(this, element); + } + + start() { + this.linkInterceptor.start(); + this.formSubmitObserver.start(); + } + + stop() { + this.linkInterceptor.stop(); + this.formSubmitObserver.stop(); + } + + // Link interceptor delegate + + shouldInterceptLinkClick(element, _location, _event) { + return this.#shouldRedirect(element) + } + + linkClickIntercepted(element, url, event) { + const frame = this.#findFrameElement(element); + if (frame) { + frame.delegate.linkClickIntercepted(element, url, event); + } + } + + // Form submit observer delegate + + willSubmitForm(element, submitter) { + return ( + element.closest("turbo-frame") == null && + this.#shouldSubmit(element, submitter) && + this.#shouldRedirect(element, submitter) + ) + } + + formSubmitted(element, submitter) { + const frame = this.#findFrameElement(element, submitter); + if (frame) { + frame.delegate.formSubmitted(element, submitter); + } + } + + #shouldSubmit(form, submitter) { + const action = getAction$1(form, submitter); + const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`); + const rootLocation = expandURL(meta?.content ?? "/"); + + return this.#shouldRedirect(form, submitter) && locationIsVisitable(action, rootLocation) + } + + #shouldRedirect(element, submitter) { + const isNavigatable = + element instanceof HTMLFormElement + ? this.session.submissionIsNavigatable(element, submitter) + : this.session.elementIsNavigatable(element); + + if (isNavigatable) { + const frame = this.#findFrameElement(element, submitter); + return frame ? frame != element.closest("turbo-frame") : false + } else { + return false + } + } + + #findFrameElement(element, submitter) { + const id = submitter?.getAttribute("data-turbo-frame") || element.getAttribute("data-turbo-frame"); + if (id && id != "_top") { + const frame = this.element.querySelector(`#${id}:not([disabled])`); + if (frame instanceof FrameElement) { + return frame + } + } + } +} + +class History { + location + restorationIdentifier = uuid() + restorationData = {} + started = false + pageLoaded = false + currentIndex = 0 + + constructor(delegate) { + this.delegate = delegate; + } + + start() { + if (!this.started) { + addEventListener("popstate", this.onPopState, false); + addEventListener("load", this.onPageLoad, false); + this.currentIndex = history.state?.turbo?.restorationIndex || 0; + this.started = true; + this.replace(new URL(window.location.href)); + } + } + + stop() { + if (this.started) { + removeEventListener("popstate", this.onPopState, false); + removeEventListener("load", this.onPageLoad, false); + this.started = false; + } + } + + push(location, restorationIdentifier) { + this.update(history.pushState, location, restorationIdentifier); + } + + replace(location, restorationIdentifier) { + this.update(history.replaceState, location, restorationIdentifier); + } + + update(method, location, restorationIdentifier = uuid()) { + if (method === history.pushState) ++this.currentIndex; + + const state = { turbo: { restorationIdentifier, restorationIndex: this.currentIndex } }; + method.call(history, state, "", location.href); + this.location = location; + this.restorationIdentifier = restorationIdentifier; + } + + // Restoration data + + getRestorationDataForIdentifier(restorationIdentifier) { + return this.restorationData[restorationIdentifier] || {} + } + + updateRestorationData(additionalData) { + const { restorationIdentifier } = this; + const restorationData = this.restorationData[restorationIdentifier]; + this.restorationData[restorationIdentifier] = { + ...restorationData, + ...additionalData + }; + } + + // Scroll restoration + + assumeControlOfScrollRestoration() { + if (!this.previousScrollRestoration) { + this.previousScrollRestoration = history.scrollRestoration ?? "auto"; + history.scrollRestoration = "manual"; + } + } + + relinquishControlOfScrollRestoration() { + if (this.previousScrollRestoration) { + history.scrollRestoration = this.previousScrollRestoration; + delete this.previousScrollRestoration; + } + } + + // Event handlers + + onPopState = (event) => { + if (this.shouldHandlePopState()) { + const { turbo } = event.state || {}; + if (turbo) { + this.location = new URL(window.location.href); + const { restorationIdentifier, restorationIndex } = turbo; + this.restorationIdentifier = restorationIdentifier; + const direction = restorationIndex > this.currentIndex ? "forward" : "back"; + this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location, restorationIdentifier, direction); + this.currentIndex = restorationIndex; + } + } + } + + onPageLoad = async (_event) => { + await nextMicrotask(); + this.pageLoaded = true; + } + + // Private + + shouldHandlePopState() { + // Safari dispatches a popstate event after window's load event, ignore it + return this.pageIsLoaded() + } + + pageIsLoaded() { + return this.pageLoaded || document.readyState == "complete" + } +} + +class LinkPrefetchObserver { + started = false + #prefetchedLink = null + + constructor(delegate, eventTarget) { + this.delegate = delegate; + this.eventTarget = eventTarget; + } + + start() { + if (this.started) return + + if (this.eventTarget.readyState === "loading") { + this.eventTarget.addEventListener("DOMContentLoaded", this.#enable, { once: true }); + } else { + this.#enable(); + } + } + + stop() { + if (!this.started) return + + this.eventTarget.removeEventListener("mouseenter", this.#tryToPrefetchRequest, { + capture: true, + passive: true + }); + this.eventTarget.removeEventListener("mouseleave", this.#cancelRequestIfObsolete, { + capture: true, + passive: true + }); + + this.eventTarget.removeEventListener("turbo:before-fetch-request", this.#tryToUsePrefetchedRequest, true); + this.started = false; + } + + #enable = () => { + this.eventTarget.addEventListener("mouseenter", this.#tryToPrefetchRequest, { + capture: true, + passive: true + }); + this.eventTarget.addEventListener("mouseleave", this.#cancelRequestIfObsolete, { + capture: true, + passive: true + }); + + this.eventTarget.addEventListener("turbo:before-fetch-request", this.#tryToUsePrefetchedRequest, true); + this.started = true; + } + + #tryToPrefetchRequest = (event) => { + if (getMetaContent("turbo-prefetch") === "false") return + + const target = event.target; + const isLink = target.matches && target.matches("a[href]:not([target^=_]):not([download])"); + + if (isLink && this.#isPrefetchable(target)) { + const link = target; + const location = getLocationForLink(link); + + if (this.delegate.canPrefetchRequestToLocation(link, location)) { + this.#prefetchedLink = link; + + const fetchRequest = new FetchRequest( + this, + FetchMethod.get, + location, + new URLSearchParams(), + target + ); + + prefetchCache.setLater(location.toString(), fetchRequest, this.#cacheTtl); + } + } + } + + #cancelRequestIfObsolete = (event) => { + if (event.target === this.#prefetchedLink) this.#cancelPrefetchRequest(); + } + + #cancelPrefetchRequest = () => { + prefetchCache.clear(); + this.#prefetchedLink = null; + } + + #tryToUsePrefetchedRequest = (event) => { + if (event.target.tagName !== "FORM" && event.detail.fetchOptions.method === "GET") { + const cached = prefetchCache.get(event.detail.url.toString()); + + if (cached) { + // User clicked link, use cache response + event.detail.fetchRequest = cached; + } + + prefetchCache.clear(); + } + } + + prepareRequest(request) { + const link = request.target; + + request.headers["X-Sec-Purpose"] = "prefetch"; + + const turboFrame = link.closest("turbo-frame"); + const turboFrameTarget = link.getAttribute("data-turbo-frame") || turboFrame?.getAttribute("target") || turboFrame?.id; + + if (turboFrameTarget && turboFrameTarget !== "_top") { + request.headers["Turbo-Frame"] = turboFrameTarget; + } + } + + // Fetch request interface + + requestSucceededWithResponse() {} + + requestStarted(fetchRequest) {} + + requestErrored(fetchRequest) {} + + requestFinished(fetchRequest) {} + + requestPreventedHandlingResponse(fetchRequest, fetchResponse) {} + + requestFailedWithResponse(fetchRequest, fetchResponse) {} + + get #cacheTtl() { + return Number(getMetaContent("turbo-prefetch-cache-time")) || cacheTtl + } + + #isPrefetchable(link) { + const href = link.getAttribute("href"); + + if (!href) return false + + if (unfetchableLink(link)) return false + if (linkToTheSamePage(link)) return false + if (linkOptsOut(link)) return false + if (nonSafeLink(link)) return false + if (eventPrevented(link)) return false + + return true + } +} + +const unfetchableLink = (link) => { + return link.origin !== document.location.origin || !["http:", "https:"].includes(link.protocol) || link.hasAttribute("target") +}; + +const linkToTheSamePage = (link) => { + return (link.pathname + link.search === document.location.pathname + document.location.search) || link.href.startsWith("#") +}; + +const linkOptsOut = (link) => { + if (link.getAttribute("data-turbo-prefetch") === "false") return true + if (link.getAttribute("data-turbo") === "false") return true + + const turboPrefetchParent = findClosestRecursively(link, "[data-turbo-prefetch]"); + if (turboPrefetchParent && turboPrefetchParent.getAttribute("data-turbo-prefetch") === "false") return true + + return false +}; + +const nonSafeLink = (link) => { + const turboMethod = link.getAttribute("data-turbo-method"); + if (turboMethod && turboMethod.toLowerCase() !== "get") return true + + if (isUJS(link)) return true + if (link.hasAttribute("data-turbo-confirm")) return true + if (link.hasAttribute("data-turbo-stream")) return true + + return false +}; + +const isUJS = (link) => { + return link.hasAttribute("data-remote") || link.hasAttribute("data-behavior") || link.hasAttribute("data-confirm") || link.hasAttribute("data-method") +}; + +const eventPrevented = (link) => { + const event = dispatch("turbo:before-prefetch", { target: link, cancelable: true }); + return event.defaultPrevented +}; + +class Navigator { + constructor(delegate) { + this.delegate = delegate; + } + + proposeVisit(location, options = {}) { + if (this.delegate.allowsVisitingLocationWithAction(location, options.action)) { + this.delegate.visitProposedToLocation(location, options); + } + } + + startVisit(locatable, restorationIdentifier, options = {}) { + this.stop(); + this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, { + referrer: this.location, + ...options + }); + this.currentVisit.start(); + } + + submitForm(form, submitter) { + this.stop(); + this.formSubmission = new FormSubmission(this, form, submitter, true); + + this.formSubmission.start(); + } + + stop() { + if (this.formSubmission) { + this.formSubmission.stop(); + delete this.formSubmission; + } + + if (this.currentVisit) { + this.currentVisit.cancel(); + delete this.currentVisit; + } + } + + get adapter() { + return this.delegate.adapter + } + + get view() { + return this.delegate.view + } + + get rootLocation() { + return this.view.snapshot.rootLocation + } + + get history() { + return this.delegate.history + } + + // Form submission delegate + + formSubmissionStarted(formSubmission) { + // Not all adapters implement formSubmissionStarted + if (typeof this.adapter.formSubmissionStarted === "function") { + this.adapter.formSubmissionStarted(formSubmission); + } + } + + async formSubmissionSucceededWithResponse(formSubmission, fetchResponse) { + if (formSubmission == this.formSubmission) { + const responseHTML = await fetchResponse.responseHTML; + if (responseHTML) { + const shouldCacheSnapshot = formSubmission.isSafe; + if (!shouldCacheSnapshot) { + this.view.clearSnapshotCache(); + } + + const { statusCode, redirected } = fetchResponse; + const action = this.#getActionForFormSubmission(formSubmission, fetchResponse); + const visitOptions = { + action, + shouldCacheSnapshot, + response: { statusCode, responseHTML, redirected } + }; + this.proposeVisit(fetchResponse.location, visitOptions); + } + } + } + + async formSubmissionFailedWithResponse(formSubmission, fetchResponse) { + const responseHTML = await fetchResponse.responseHTML; + + if (responseHTML) { + const snapshot = PageSnapshot.fromHTMLString(responseHTML); + if (fetchResponse.serverError) { + await this.view.renderError(snapshot, this.currentVisit); + } else { + await this.view.renderPage(snapshot, false, true, this.currentVisit); + } + if(!snapshot.shouldPreserveScrollPosition) { + this.view.scrollToTop(); + } + this.view.clearSnapshotCache(); + } + } + + formSubmissionErrored(formSubmission, error) { + console.error(error); + } + + formSubmissionFinished(formSubmission) { + // Not all adapters implement formSubmissionFinished + if (typeof this.adapter.formSubmissionFinished === "function") { + this.adapter.formSubmissionFinished(formSubmission); + } + } + + // Link prefetching + + linkPrefetchingIsEnabledForLocation(location) { + // Not all adapters implement linkPrefetchingIsEnabledForLocation + if (typeof this.adapter.linkPrefetchingIsEnabledForLocation === "function") { + return this.adapter.linkPrefetchingIsEnabledForLocation(location) + } + + return true + } + + // Visit delegate + + visitStarted(visit) { + this.delegate.visitStarted(visit); + } + + visitCompleted(visit) { + this.delegate.visitCompleted(visit); + delete this.currentVisit; + } + + locationWithActionIsSamePage(location, action) { + const anchor = getAnchor(location); + const currentAnchor = getAnchor(this.view.lastRenderedLocation); + const isRestorationToTop = action === "restore" && typeof anchor === "undefined"; + + return ( + action !== "replace" && + getRequestURL(location) === getRequestURL(this.view.lastRenderedLocation) && + (isRestorationToTop || (anchor != null && anchor !== currentAnchor)) + ) + } + + visitScrolledToSamePageLocation(oldURL, newURL) { + this.delegate.visitScrolledToSamePageLocation(oldURL, newURL); + } + + // Visits + + get location() { + return this.history.location + } + + get restorationIdentifier() { + return this.history.restorationIdentifier + } + + #getActionForFormSubmission(formSubmission, fetchResponse) { + const { submitter, formElement } = formSubmission; + return getVisitAction(submitter, formElement) || this.#getDefaultAction(fetchResponse) + } + + #getDefaultAction(fetchResponse) { + const sameLocationRedirect = fetchResponse.redirected && fetchResponse.location.href === this.location?.href; + return sameLocationRedirect ? "replace" : "advance" + } +} + +const PageStage = { + initial: 0, + loading: 1, + interactive: 2, + complete: 3 +}; + +class PageObserver { + stage = PageStage.initial + started = false + + constructor(delegate) { + this.delegate = delegate; + } + + start() { + if (!this.started) { + if (this.stage == PageStage.initial) { + this.stage = PageStage.loading; + } + document.addEventListener("readystatechange", this.interpretReadyState, false); + addEventListener("pagehide", this.pageWillUnload, false); + this.started = true; + } + } + + stop() { + if (this.started) { + document.removeEventListener("readystatechange", this.interpretReadyState, false); + removeEventListener("pagehide", this.pageWillUnload, false); + this.started = false; + } + } + + interpretReadyState = () => { + const { readyState } = this; + if (readyState == "interactive") { + this.pageIsInteractive(); + } else if (readyState == "complete") { + this.pageIsComplete(); + } + } + + pageIsInteractive() { + if (this.stage == PageStage.loading) { + this.stage = PageStage.interactive; + this.delegate.pageBecameInteractive(); + } + } + + pageIsComplete() { + this.pageIsInteractive(); + if (this.stage == PageStage.interactive) { + this.stage = PageStage.complete; + this.delegate.pageLoaded(); + } + } + + pageWillUnload = () => { + this.delegate.pageWillUnload(); + } + + get readyState() { + return document.readyState + } +} + +class ScrollObserver { + started = false + + constructor(delegate) { + this.delegate = delegate; + } + + start() { + if (!this.started) { + addEventListener("scroll", this.onScroll, false); + this.onScroll(); + this.started = true; + } + } + + stop() { + if (this.started) { + removeEventListener("scroll", this.onScroll, false); + this.started = false; + } + } + + onScroll = () => { + this.updatePosition({ x: window.pageXOffset, y: window.pageYOffset }); + } + + // Private + + updatePosition(position) { + this.delegate.scrollPositionChanged(position); + } +} + +class StreamMessageRenderer { + render({ fragment }) { + Bardo.preservingPermanentElements(this, getPermanentElementMapForFragment(fragment), () => { + withAutofocusFromFragment(fragment, () => { + withPreservedFocus(() => { + document.documentElement.appendChild(fragment); + }); + }); + }); + } + + // Bardo delegate + + enteringBardo(currentPermanentElement, newPermanentElement) { + newPermanentElement.replaceWith(currentPermanentElement.cloneNode(true)); + } + + leavingBardo() {} +} + +function getPermanentElementMapForFragment(fragment) { + const permanentElementsInDocument = queryPermanentElementsAll(document.documentElement); + const permanentElementMap = {}; + for (const permanentElementInDocument of permanentElementsInDocument) { + const { id } = permanentElementInDocument; + + for (const streamElement of fragment.querySelectorAll("turbo-stream")) { + const elementInStream = getPermanentElementById(streamElement.templateElement.content, id); + + if (elementInStream) { + permanentElementMap[id] = [permanentElementInDocument, elementInStream]; + } + } + } + + return permanentElementMap +} + +async function withAutofocusFromFragment(fragment, callback) { + const generatedID = `turbo-stream-autofocus-${uuid()}`; + const turboStreams = fragment.querySelectorAll("turbo-stream"); + const elementWithAutofocus = firstAutofocusableElementInStreams(turboStreams); + let willAutofocusId = null; + + if (elementWithAutofocus) { + if (elementWithAutofocus.id) { + willAutofocusId = elementWithAutofocus.id; + } else { + willAutofocusId = generatedID; + } + + elementWithAutofocus.id = willAutofocusId; + } + + callback(); + await nextRepaint(); + + const hasNoActiveElement = document.activeElement == null || document.activeElement == document.body; + + if (hasNoActiveElement && willAutofocusId) { + const elementToAutofocus = document.getElementById(willAutofocusId); + + if (elementIsFocusable(elementToAutofocus)) { + elementToAutofocus.focus(); + } + if (elementToAutofocus && elementToAutofocus.id == generatedID) { + elementToAutofocus.removeAttribute("id"); + } + } +} + +async function withPreservedFocus(callback) { + const [activeElementBeforeRender, activeElementAfterRender] = await around(callback, () => document.activeElement); + + const restoreFocusTo = activeElementBeforeRender && activeElementBeforeRender.id; + + if (restoreFocusTo) { + const elementToFocus = document.getElementById(restoreFocusTo); + + if (elementIsFocusable(elementToFocus) && elementToFocus != activeElementAfterRender) { + elementToFocus.focus(); + } + } +} + +function firstAutofocusableElementInStreams(nodeListOfStreamElements) { + for (const streamElement of nodeListOfStreamElements) { + const elementWithAutofocus = queryAutofocusableElement(streamElement.templateElement.content); + + if (elementWithAutofocus) return elementWithAutofocus + } + + return null +} + +class StreamObserver { + sources = new Set() + #started = false + + constructor(delegate) { + this.delegate = delegate; + } + + start() { + if (!this.#started) { + this.#started = true; + addEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false); + } + } + + stop() { + if (this.#started) { + this.#started = false; + removeEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false); + } + } + + connectStreamSource(source) { + if (!this.streamSourceIsConnected(source)) { + this.sources.add(source); + source.addEventListener("message", this.receiveMessageEvent, false); + } + } + + disconnectStreamSource(source) { + if (this.streamSourceIsConnected(source)) { + this.sources.delete(source); + source.removeEventListener("message", this.receiveMessageEvent, false); + } + } + + streamSourceIsConnected(source) { + return this.sources.has(source) + } + + inspectFetchResponse = (event) => { + const response = fetchResponseFromEvent(event); + if (response && fetchResponseIsStream(response)) { + event.preventDefault(); + this.receiveMessageResponse(response); + } + } + + receiveMessageEvent = (event) => { + if (this.#started && typeof event.data == "string") { + this.receiveMessageHTML(event.data); + } + } + + async receiveMessageResponse(response) { + const html = await response.responseHTML; + if (html) { + this.receiveMessageHTML(html); + } + } + + receiveMessageHTML(html) { + this.delegate.receivedMessageFromStream(StreamMessage.wrap(html)); + } +} + +function fetchResponseFromEvent(event) { + const fetchResponse = event.detail?.fetchResponse; + if (fetchResponse instanceof FetchResponse) { + return fetchResponse + } +} + +function fetchResponseIsStream(response) { + const contentType = response.contentType ?? ""; + return contentType.startsWith(StreamMessage.contentType) +} + +class ErrorRenderer extends Renderer { + static renderElement(currentElement, newElement) { + const { documentElement, body } = document; + + documentElement.replaceChild(newElement, body); + } + + async render() { + this.replaceHeadAndBody(); + this.activateScriptElements(); + } + + replaceHeadAndBody() { + const { documentElement, head } = document; + documentElement.replaceChild(this.newHead, head); + this.renderElement(this.currentElement, this.newElement); + } + + activateScriptElements() { + for (const replaceableElement of this.scriptElements) { + const parentNode = replaceableElement.parentNode; + if (parentNode) { + const element = activateScriptElement(replaceableElement); + parentNode.replaceChild(element, replaceableElement); + } + } + } + + get newHead() { + return this.newSnapshot.headSnapshot.element + } + + get scriptElements() { + return document.documentElement.querySelectorAll("script") + } +} + +class PageRenderer extends Renderer { + static renderElement(currentElement, newElement) { + if (document.body && newElement instanceof HTMLBodyElement) { + document.body.replaceWith(newElement); + } else { + document.documentElement.appendChild(newElement); + } + } + + get shouldRender() { + return this.newSnapshot.isVisitable && this.trackedElementsAreIdentical + } + + get reloadReason() { + if (!this.newSnapshot.isVisitable) { + return { + reason: "turbo_visit_control_is_reload" + } + } + + if (!this.trackedElementsAreIdentical) { + return { + reason: "tracked_element_mismatch" + } + } + } + + async prepareToRender() { + this.#setLanguage(); + await this.mergeHead(); + } + + async render() { + if (this.willRender) { + await this.replaceBody(); + } + } + + finishRendering() { + super.finishRendering(); + if (!this.isPreview) { + this.focusFirstAutofocusableElement(); + } + } + + get currentHeadSnapshot() { + return this.currentSnapshot.headSnapshot + } + + get newHeadSnapshot() { + return this.newSnapshot.headSnapshot + } + + get newElement() { + return this.newSnapshot.element + } + + #setLanguage() { + const { documentElement } = this.currentSnapshot; + const { lang } = this.newSnapshot; + + if (lang) { + documentElement.setAttribute("lang", lang); + } else { + documentElement.removeAttribute("lang"); + } + } + + async mergeHead() { + const mergedHeadElements = this.mergeProvisionalElements(); + const newStylesheetElements = this.copyNewHeadStylesheetElements(); + this.copyNewHeadScriptElements(); + + await mergedHeadElements; + await newStylesheetElements; + + if (this.willRender) { + this.removeUnusedDynamicStylesheetElements(); + } + } + + async replaceBody() { + await this.preservingPermanentElements(async () => { + this.activateNewBody(); + await this.assignNewBody(); + }); + } + + get trackedElementsAreIdentical() { + return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature + } + + async copyNewHeadStylesheetElements() { + const loadingElements = []; + + for (const element of this.newHeadStylesheetElements) { + loadingElements.push(waitForLoad(element)); + + document.head.appendChild(element); + } + + await Promise.all(loadingElements); + } + + copyNewHeadScriptElements() { + for (const element of this.newHeadScriptElements) { + document.head.appendChild(activateScriptElement(element)); + } + } + + removeUnusedDynamicStylesheetElements() { + for (const element of this.unusedDynamicStylesheetElements) { + document.head.removeChild(element); + } + } + + async mergeProvisionalElements() { + const newHeadElements = [...this.newHeadProvisionalElements]; + + for (const element of this.currentHeadProvisionalElements) { + if (!this.isCurrentElementInElementList(element, newHeadElements)) { + document.head.removeChild(element); + } + } + + for (const element of newHeadElements) { + document.head.appendChild(element); + } + } + + isCurrentElementInElementList(element, elementList) { + for (const [index, newElement] of elementList.entries()) { + // if title element... + if (element.tagName == "TITLE") { + if (newElement.tagName != "TITLE") { + continue + } + if (element.innerHTML == newElement.innerHTML) { + elementList.splice(index, 1); + return true + } + } + + // if any other element... + if (newElement.isEqualNode(element)) { + elementList.splice(index, 1); + return true + } + } + + return false + } + + removeCurrentHeadProvisionalElements() { + for (const element of this.currentHeadProvisionalElements) { + document.head.removeChild(element); + } + } + + copyNewHeadProvisionalElements() { + for (const element of this.newHeadProvisionalElements) { + document.head.appendChild(element); + } + } + + activateNewBody() { + document.adoptNode(this.newElement); + this.activateNewBodyScriptElements(); + } + + activateNewBodyScriptElements() { + for (const inertScriptElement of this.newBodyScriptElements) { + const activatedScriptElement = activateScriptElement(inertScriptElement); + inertScriptElement.replaceWith(activatedScriptElement); + } + } + + async assignNewBody() { + await this.renderElement(this.currentElement, this.newElement); + } + + get unusedDynamicStylesheetElements() { + return this.oldHeadStylesheetElements.filter((element) => { + return element.getAttribute("data-turbo-track") === "dynamic" + }) + } + + get oldHeadStylesheetElements() { + return this.currentHeadSnapshot.getStylesheetElementsNotInSnapshot(this.newHeadSnapshot) + } + + get newHeadStylesheetElements() { + return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot) + } + + get newHeadScriptElements() { + return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot) + } + + get currentHeadProvisionalElements() { + return this.currentHeadSnapshot.provisionalElements + } + + get newHeadProvisionalElements() { + return this.newHeadSnapshot.provisionalElements + } + + get newBodyScriptElements() { + return this.newElement.querySelectorAll("script") + } +} + +class MorphingPageRenderer extends PageRenderer { + static renderElement(currentElement, newElement) { + morphElements(currentElement, newElement, { + callbacks: { + beforeNodeMorphed: element => !canRefreshFrame(element) + } + }); + + for (const frame of currentElement.querySelectorAll("turbo-frame")) { + if (canRefreshFrame(frame)) frame.reload(); + } + + dispatch("turbo:morph", { detail: { currentElement, newElement } }); + } + + async preservingPermanentElements(callback) { + return await callback() + } + + get renderMethod() { + return "morph" + } + + get shouldAutofocus() { + return false + } +} + +function canRefreshFrame(frame) { + return frame instanceof FrameElement && + frame.src && + frame.refresh === "morph" && + !frame.closest("[data-turbo-permanent]") +} + +class SnapshotCache { + keys = [] + snapshots = {} + + constructor(size) { + this.size = size; + } + + has(location) { + return toCacheKey(location) in this.snapshots + } + + get(location) { + if (this.has(location)) { + const snapshot = this.read(location); + this.touch(location); + return snapshot + } + } + + put(location, snapshot) { + this.write(location, snapshot); + this.touch(location); + return snapshot + } + + clear() { + this.snapshots = {}; + } + + // Private + + read(location) { + return this.snapshots[toCacheKey(location)] + } + + write(location, snapshot) { + this.snapshots[toCacheKey(location)] = snapshot; + } + + touch(location) { + const key = toCacheKey(location); + const index = this.keys.indexOf(key); + if (index > -1) this.keys.splice(index, 1); + this.keys.unshift(key); + this.trim(); + } + + trim() { + for (const key of this.keys.splice(this.size)) { + delete this.snapshots[key]; + } + } +} + +class PageView extends View { + snapshotCache = new SnapshotCache(10) + lastRenderedLocation = new URL(location.href) + forceReloaded = false + + shouldTransitionTo(newSnapshot) { + return this.snapshot.prefersViewTransitions && newSnapshot.prefersViewTransitions + } + + renderPage(snapshot, isPreview = false, willRender = true, visit) { + const shouldMorphPage = this.isPageRefresh(visit) && this.snapshot.shouldMorphPage; + const rendererClass = shouldMorphPage ? MorphingPageRenderer : PageRenderer; + + const renderer = new rendererClass(this.snapshot, snapshot, isPreview, willRender); + + if (!renderer.shouldRender) { + this.forceReloaded = true; + } else { + visit?.changeHistory(); + } + + return this.render(renderer) + } + + renderError(snapshot, visit) { + visit?.changeHistory(); + const renderer = new ErrorRenderer(this.snapshot, snapshot, false); + return this.render(renderer) + } + + clearSnapshotCache() { + this.snapshotCache.clear(); + } + + async cacheSnapshot(snapshot = this.snapshot) { + if (snapshot.isCacheable) { + this.delegate.viewWillCacheSnapshot(); + const { lastRenderedLocation: location } = this; + await nextEventLoopTick(); + const cachedSnapshot = snapshot.clone(); + this.snapshotCache.put(location, cachedSnapshot); + return cachedSnapshot + } + } + + getCachedSnapshotForLocation(location) { + return this.snapshotCache.get(location) + } + + isPageRefresh(visit) { + return !visit || (this.lastRenderedLocation.pathname === visit.location.pathname && visit.action === "replace") + } + + shouldPreserveScrollPosition(visit) { + return this.isPageRefresh(visit) && this.snapshot.shouldPreserveScrollPosition + } + + get snapshot() { + return PageSnapshot.fromElement(this.element) + } +} + +class Preloader { + selector = "a[data-turbo-preload]" + + constructor(delegate, snapshotCache) { + this.delegate = delegate; + this.snapshotCache = snapshotCache; + } + + start() { + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", this.#preloadAll); + } else { + this.preloadOnLoadLinksForView(document.body); + } + } + + stop() { + document.removeEventListener("DOMContentLoaded", this.#preloadAll); + } + + preloadOnLoadLinksForView(element) { + for (const link of element.querySelectorAll(this.selector)) { + if (this.delegate.shouldPreloadLink(link)) { + this.preloadURL(link); + } + } + } + + async preloadURL(link) { + const location = new URL(link.href); + + if (this.snapshotCache.has(location)) { + return + } + + const fetchRequest = new FetchRequest(this, FetchMethod.get, location, new URLSearchParams(), link); + await fetchRequest.perform(); + } + + // Fetch request delegate + + prepareRequest(fetchRequest) { + fetchRequest.headers["X-Sec-Purpose"] = "prefetch"; + } + + async requestSucceededWithResponse(fetchRequest, fetchResponse) { + try { + const responseHTML = await fetchResponse.responseHTML; + const snapshot = PageSnapshot.fromHTMLString(responseHTML); + + this.snapshotCache.put(fetchRequest.url, snapshot); + } catch (_) { + // If we cannot preload that is ok! + } + } + + requestStarted(fetchRequest) {} + + requestErrored(fetchRequest) {} + + requestFinished(fetchRequest) {} + + requestPreventedHandlingResponse(fetchRequest, fetchResponse) {} + + requestFailedWithResponse(fetchRequest, fetchResponse) {} + + #preloadAll = () => { + this.preloadOnLoadLinksForView(document.body); + } +} + +class Cache { + constructor(session) { + this.session = session; + } + + clear() { + this.session.clearCache(); + } + + resetCacheControl() { + this.#setCacheControl(""); + } + + exemptPageFromCache() { + this.#setCacheControl("no-cache"); + } + + exemptPageFromPreview() { + this.#setCacheControl("no-preview"); + } + + #setCacheControl(value) { + setMetaContent("turbo-cache-control", value); + } +} + +class Session { + navigator = new Navigator(this) + history = new History(this) + view = new PageView(this, document.documentElement) + adapter = new BrowserAdapter(this) + + pageObserver = new PageObserver(this) + cacheObserver = new CacheObserver() + linkPrefetchObserver = new LinkPrefetchObserver(this, document) + linkClickObserver = new LinkClickObserver(this, window) + formSubmitObserver = new FormSubmitObserver(this, document) + scrollObserver = new ScrollObserver(this) + streamObserver = new StreamObserver(this) + formLinkClickObserver = new FormLinkClickObserver(this, document.documentElement) + frameRedirector = new FrameRedirector(this, document.documentElement) + streamMessageRenderer = new StreamMessageRenderer() + cache = new Cache(this) + + enabled = true + started = false + #pageRefreshDebouncePeriod = 150 + + constructor(recentRequests) { + this.recentRequests = recentRequests; + this.preloader = new Preloader(this, this.view.snapshotCache); + this.debouncedRefresh = this.refresh; + this.pageRefreshDebouncePeriod = this.pageRefreshDebouncePeriod; + } + + start() { + if (!this.started) { + this.pageObserver.start(); + this.cacheObserver.start(); + this.linkPrefetchObserver.start(); + this.formLinkClickObserver.start(); + this.linkClickObserver.start(); + this.formSubmitObserver.start(); + this.scrollObserver.start(); + this.streamObserver.start(); + this.frameRedirector.start(); + this.history.start(); + this.preloader.start(); + this.started = true; + this.enabled = true; + } + } + + disable() { + this.enabled = false; + } + + stop() { + if (this.started) { + this.pageObserver.stop(); + this.cacheObserver.stop(); + this.linkPrefetchObserver.stop(); + this.formLinkClickObserver.stop(); + this.linkClickObserver.stop(); + this.formSubmitObserver.stop(); + this.scrollObserver.stop(); + this.streamObserver.stop(); + this.frameRedirector.stop(); + this.history.stop(); + this.preloader.stop(); + this.started = false; + } + } + + registerAdapter(adapter) { + this.adapter = adapter; + } + + visit(location, options = {}) { + const frameElement = options.frame ? document.getElementById(options.frame) : null; + + if (frameElement instanceof FrameElement) { + const action = options.action || getVisitAction(frameElement); + + frameElement.delegate.proposeVisitIfNavigatedWithAction(frameElement, action); + frameElement.src = location.toString(); + } else { + this.navigator.proposeVisit(expandURL(location), options); + } + } + + refresh(url, requestId) { + const isRecentRequest = requestId && this.recentRequests.has(requestId); + const isCurrentUrl = url === document.baseURI; + if (!isRecentRequest && !this.navigator.currentVisit && isCurrentUrl) { + this.visit(url, { action: "replace", shouldCacheSnapshot: false }); + } + } + + connectStreamSource(source) { + this.streamObserver.connectStreamSource(source); + } + + disconnectStreamSource(source) { + this.streamObserver.disconnectStreamSource(source); + } + + renderStreamMessage(message) { + this.streamMessageRenderer.render(StreamMessage.wrap(message)); + } + + clearCache() { + this.view.clearSnapshotCache(); + } + + setProgressBarDelay(delay) { + console.warn( + "Please replace `session.setProgressBarDelay(delay)` with `session.progressBarDelay = delay`. The function is deprecated and will be removed in a future version of Turbo.`" + ); + + this.progressBarDelay = delay; + } + + set progressBarDelay(delay) { + config.drive.progressBarDelay = delay; + } + + get progressBarDelay() { + return config.drive.progressBarDelay + } + + set drive(value) { + config.drive.enabled = value; + } + + get drive() { + return config.drive.enabled + } + + set formMode(value) { + config.forms.mode = value; + } + + get formMode() { + return config.forms.mode + } + + get location() { + return this.history.location + } + + get restorationIdentifier() { + return this.history.restorationIdentifier + } + + get pageRefreshDebouncePeriod() { + return this.#pageRefreshDebouncePeriod + } + + set pageRefreshDebouncePeriod(value) { + this.refresh = debounce(this.debouncedRefresh.bind(this), value); + this.#pageRefreshDebouncePeriod = value; + } + + // Preloader delegate + + shouldPreloadLink(element) { + const isUnsafe = element.hasAttribute("data-turbo-method"); + const isStream = element.hasAttribute("data-turbo-stream"); + const frameTarget = element.getAttribute("data-turbo-frame"); + const frame = frameTarget == "_top" ? + null : + document.getElementById(frameTarget) || findClosestRecursively(element, "turbo-frame:not([disabled])"); + + if (isUnsafe || isStream || frame instanceof FrameElement) { + return false + } else { + const location = new URL(element.href); + + return this.elementIsNavigatable(element) && locationIsVisitable(location, this.snapshot.rootLocation) + } + } + + // History delegate + + historyPoppedToLocationWithRestorationIdentifierAndDirection(location, restorationIdentifier, direction) { + if (this.enabled) { + this.navigator.startVisit(location, restorationIdentifier, { + action: "restore", + historyChanged: true, + direction + }); + } else { + this.adapter.pageInvalidated({ + reason: "turbo_disabled" + }); + } + } + + // Scroll observer delegate + + scrollPositionChanged(position) { + this.history.updateRestorationData({ scrollPosition: position }); + } + + // Form click observer delegate + + willSubmitFormLinkToLocation(link, location) { + return this.elementIsNavigatable(link) && locationIsVisitable(location, this.snapshot.rootLocation) + } + + submittedFormLinkToLocation() {} + + // Link hover observer delegate + + canPrefetchRequestToLocation(link, location) { + return ( + this.elementIsNavigatable(link) && + locationIsVisitable(location, this.snapshot.rootLocation) && + this.navigator.linkPrefetchingIsEnabledForLocation(location) + ) + } + + // Link click observer delegate + + willFollowLinkToLocation(link, location, event) { + return ( + this.elementIsNavigatable(link) && + locationIsVisitable(location, this.snapshot.rootLocation) && + this.applicationAllowsFollowingLinkToLocation(link, location, event) + ) + } + + followedLinkToLocation(link, location) { + const action = this.getActionForLink(link); + const acceptsStreamResponse = link.hasAttribute("data-turbo-stream"); + + this.visit(location.href, { action, acceptsStreamResponse }); + } + + // Navigator delegate + + allowsVisitingLocationWithAction(location, action) { + return this.locationWithActionIsSamePage(location, action) || this.applicationAllowsVisitingLocation(location) + } + + visitProposedToLocation(location, options) { + extendURLWithDeprecatedProperties(location); + this.adapter.visitProposedToLocation(location, options); + } + + // Visit delegate + + visitStarted(visit) { + if (!visit.acceptsStreamResponse) { + markAsBusy(document.documentElement); + this.view.markVisitDirection(visit.direction); + } + extendURLWithDeprecatedProperties(visit.location); + if (!visit.silent) { + this.notifyApplicationAfterVisitingLocation(visit.location, visit.action); + } + } + + visitCompleted(visit) { + this.view.unmarkVisitDirection(); + clearBusyState(document.documentElement); + this.notifyApplicationAfterPageLoad(visit.getTimingMetrics()); + } + + locationWithActionIsSamePage(location, action) { + return this.navigator.locationWithActionIsSamePage(location, action) + } + + visitScrolledToSamePageLocation(oldURL, newURL) { + this.notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL); + } + + // Form submit observer delegate + + willSubmitForm(form, submitter) { + const action = getAction$1(form, submitter); + + return ( + this.submissionIsNavigatable(form, submitter) && + locationIsVisitable(expandURL(action), this.snapshot.rootLocation) + ) + } + + formSubmitted(form, submitter) { + this.navigator.submitForm(form, submitter); + } + + // Page observer delegate + + pageBecameInteractive() { + this.view.lastRenderedLocation = this.location; + this.notifyApplicationAfterPageLoad(); + } + + pageLoaded() { + this.history.assumeControlOfScrollRestoration(); + } + + pageWillUnload() { + this.history.relinquishControlOfScrollRestoration(); + } + + // Stream observer delegate + + receivedMessageFromStream(message) { + this.renderStreamMessage(message); + } + + // Page view delegate + + viewWillCacheSnapshot() { + if (!this.navigator.currentVisit?.silent) { + this.notifyApplicationBeforeCachingSnapshot(); + } + } + + allowsImmediateRender({ element }, options) { + const event = this.notifyApplicationBeforeRender(element, options); + const { + defaultPrevented, + detail: { render } + } = event; + + if (this.view.renderer && render) { + this.view.renderer.renderElement = render; + } + + return !defaultPrevented + } + + viewRenderedSnapshot(_snapshot, _isPreview, renderMethod) { + this.view.lastRenderedLocation = this.history.location; + this.notifyApplicationAfterRender(renderMethod); + } + + preloadOnLoadLinksForView(element) { + this.preloader.preloadOnLoadLinksForView(element); + } + + viewInvalidated(reason) { + this.adapter.pageInvalidated(reason); + } + + // Frame element + + frameLoaded(frame) { + this.notifyApplicationAfterFrameLoad(frame); + } + + frameRendered(fetchResponse, frame) { + this.notifyApplicationAfterFrameRender(fetchResponse, frame); + } + + // Application events + + applicationAllowsFollowingLinkToLocation(link, location, ev) { + const event = this.notifyApplicationAfterClickingLinkToLocation(link, location, ev); + return !event.defaultPrevented + } + + applicationAllowsVisitingLocation(location) { + const event = this.notifyApplicationBeforeVisitingLocation(location); + return !event.defaultPrevented + } + + notifyApplicationAfterClickingLinkToLocation(link, location, event) { + return dispatch("turbo:click", { + target: link, + detail: { url: location.href, originalEvent: event }, + cancelable: true + }) + } + + notifyApplicationBeforeVisitingLocation(location) { + return dispatch("turbo:before-visit", { + detail: { url: location.href }, + cancelable: true + }) + } + + notifyApplicationAfterVisitingLocation(location, action) { + return dispatch("turbo:visit", { detail: { url: location.href, action } }) + } + + notifyApplicationBeforeCachingSnapshot() { + return dispatch("turbo:before-cache") + } + + notifyApplicationBeforeRender(newBody, options) { + return dispatch("turbo:before-render", { + detail: { newBody, ...options }, + cancelable: true + }) + } + + notifyApplicationAfterRender(renderMethod) { + return dispatch("turbo:render", { detail: { renderMethod } }) + } + + notifyApplicationAfterPageLoad(timing = {}) { + return dispatch("turbo:load", { + detail: { url: this.location.href, timing } + }) + } + + notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL) { + dispatchEvent( + new HashChangeEvent("hashchange", { + oldURL: oldURL.toString(), + newURL: newURL.toString() + }) + ); + } + + notifyApplicationAfterFrameLoad(frame) { + return dispatch("turbo:frame-load", { target: frame }) + } + + notifyApplicationAfterFrameRender(fetchResponse, frame) { + return dispatch("turbo:frame-render", { + detail: { fetchResponse }, + target: frame, + cancelable: true + }) + } + + // Helpers + + submissionIsNavigatable(form, submitter) { + if (config.forms.mode == "off") { + return false + } else { + const submitterIsNavigatable = submitter ? this.elementIsNavigatable(submitter) : true; + + if (config.forms.mode == "optin") { + return submitterIsNavigatable && form.closest('[data-turbo="true"]') != null + } else { + return submitterIsNavigatable && this.elementIsNavigatable(form) + } + } + } + + elementIsNavigatable(element) { + const container = findClosestRecursively(element, "[data-turbo]"); + const withinFrame = findClosestRecursively(element, "turbo-frame"); + + // Check if Drive is enabled on the session or we're within a Frame. + if (config.drive.enabled || withinFrame) { + // Element is navigatable by default, unless `data-turbo="false"`. + if (container) { + return container.getAttribute("data-turbo") != "false" + } else { + return true + } + } else { + // Element isn't navigatable by default, unless `data-turbo="true"`. + if (container) { + return container.getAttribute("data-turbo") == "true" + } else { + return false + } + } + } + + // Private + + getActionForLink(link) { + return getVisitAction(link) || "advance" + } + + get snapshot() { + return this.view.snapshot + } +} + +// Older versions of the Turbo Native adapters referenced the +// `Location#absoluteURL` property in their implementations of +// the `Adapter#visitProposedToLocation()` and `#visitStarted()` +// methods. The Location class has since been removed in favor +// of the DOM URL API, and accordingly all Adapter methods now +// receive URL objects. +// +// We alias #absoluteURL to #toString() here to avoid crashing +// older adapters which do not expect URL objects. We should +// consider removing this support at some point in the future. + +function extendURLWithDeprecatedProperties(url) { + Object.defineProperties(url, deprecatedLocationPropertyDescriptors); +} + +const deprecatedLocationPropertyDescriptors = { + absoluteURL: { + get() { + return this.toString() + } + } +}; + +const session = new Session(recentRequests); +const { cache, navigator: navigator$1 } = session; + +/** + * Starts the main session. + * This initialises any necessary observers such as those to monitor + * link interactions. + */ +function start() { + session.start(); +} + +/** + * Registers an adapter for the main session. + * + * @param adapter Adapter to register + */ +function registerAdapter(adapter) { + session.registerAdapter(adapter); +} + +/** + * Performs an application visit to the given location. + * + * @param location Location to visit (a URL or path) + * @param options Options to apply + * @param options.action Type of history navigation to apply ("restore", + * "replace" or "advance") + * @param options.historyChanged Specifies whether the browser history has + * already been changed for this visit or not + * @param options.referrer Specifies the referrer of this visit such that + * navigations to the same page will not result in a new history entry. + * @param options.snapshotHTML Cached snapshot to render + * @param options.response Response of the specified location + */ +function visit(location, options) { + session.visit(location, options); +} + +/** + * Connects a stream source to the main session. + * + * @param source Stream source to connect + */ +function connectStreamSource(source) { + session.connectStreamSource(source); +} + +/** + * Disconnects a stream source from the main session. + * + * @param source Stream source to disconnect + */ +function disconnectStreamSource(source) { + session.disconnectStreamSource(source); +} + +/** + * Renders a stream message to the main session by appending it to the + * current document. + * + * @param message Message to render + */ +function renderStreamMessage(message) { + session.renderStreamMessage(message); +} + +/** + * Removes all entries from the Turbo Drive page cache. + * Call this when state has changed on the server that may affect cached pages. + * + * @deprecated since version 7.2.0 in favor of `Turbo.cache.clear()` + */ +function clearCache() { + console.warn( + "Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`" + ); + session.clearCache(); +} + +/** + * Sets the delay after which the progress bar will appear during navigation. + * + * The progress bar appears after 500ms by default. + * + * Note that this method has no effect when used with the iOS or Android + * adapters. + * + * @param delay Time to delay in milliseconds + */ +function setProgressBarDelay(delay) { + console.warn( + "Please replace `Turbo.setProgressBarDelay(delay)` with `Turbo.config.drive.progressBarDelay = delay`. The top-level function is deprecated and will be removed in a future version of Turbo.`" + ); + config.drive.progressBarDelay = delay; +} + +function setConfirmMethod(confirmMethod) { + console.warn( + "Please replace `Turbo.setConfirmMethod(confirmMethod)` with `Turbo.config.forms.confirm = confirmMethod`. The top-level function is deprecated and will be removed in a future version of Turbo.`" + ); + config.forms.confirm = confirmMethod; +} + +function setFormMode(mode) { + console.warn( + "Please replace `Turbo.setFormMode(mode)` with `Turbo.config.forms.mode = mode`. The top-level function is deprecated and will be removed in a future version of Turbo.`" + ); + config.forms.mode = mode; +} + +var Turbo = /*#__PURE__*/Object.freeze({ + __proto__: null, + navigator: navigator$1, + session: session, + cache: cache, + PageRenderer: PageRenderer, + PageSnapshot: PageSnapshot, + FrameRenderer: FrameRenderer, + fetch: fetchWithTurboHeaders, + config: config, + start: start, + registerAdapter: registerAdapter, + visit: visit, + connectStreamSource: connectStreamSource, + disconnectStreamSource: disconnectStreamSource, + renderStreamMessage: renderStreamMessage, + clearCache: clearCache, + setProgressBarDelay: setProgressBarDelay, + setConfirmMethod: setConfirmMethod, + setFormMode: setFormMode +}); + +class TurboFrameMissingError extends Error {} + +class FrameController { + fetchResponseLoaded = (_fetchResponse) => Promise.resolve() + #currentFetchRequest = null + #resolveVisitPromise = () => {} + #connected = false + #hasBeenLoaded = false + #ignoredAttributes = new Set() + #shouldMorphFrame = false + action = null + + constructor(element) { + this.element = element; + this.view = new FrameView(this, this.element); + this.appearanceObserver = new AppearanceObserver(this, this.element); + this.formLinkClickObserver = new FormLinkClickObserver(this, this.element); + this.linkInterceptor = new LinkInterceptor(this, this.element); + this.restorationIdentifier = uuid(); + this.formSubmitObserver = new FormSubmitObserver(this, this.element); + } + + // Frame delegate + + connect() { + if (!this.#connected) { + this.#connected = true; + if (this.loadingStyle == FrameLoadingStyle.lazy) { + this.appearanceObserver.start(); + } else { + this.#loadSourceURL(); + } + this.formLinkClickObserver.start(); + this.linkInterceptor.start(); + this.formSubmitObserver.start(); + } + } + + disconnect() { + if (this.#connected) { + this.#connected = false; + this.appearanceObserver.stop(); + this.formLinkClickObserver.stop(); + this.linkInterceptor.stop(); + this.formSubmitObserver.stop(); + } + } + + disabledChanged() { + if (this.loadingStyle == FrameLoadingStyle.eager) { + this.#loadSourceURL(); + } + } + + sourceURLChanged() { + if (this.#isIgnoringChangesTo("src")) return + + if (this.element.isConnected) { + this.complete = false; + } + + if (this.loadingStyle == FrameLoadingStyle.eager || this.#hasBeenLoaded) { + this.#loadSourceURL(); + } + } + + sourceURLReloaded() { + const { refresh, src } = this.element; + + this.#shouldMorphFrame = src && refresh === "morph"; + + this.element.removeAttribute("complete"); + this.element.src = null; + this.element.src = src; + return this.element.loaded + } + + loadingStyleChanged() { + if (this.loadingStyle == FrameLoadingStyle.lazy) { + this.appearanceObserver.start(); + } else { + this.appearanceObserver.stop(); + this.#loadSourceURL(); + } + } + + async #loadSourceURL() { + if (this.enabled && this.isActive && !this.complete && this.sourceURL) { + this.element.loaded = this.#visit(expandURL(this.sourceURL)); + this.appearanceObserver.stop(); + await this.element.loaded; + this.#hasBeenLoaded = true; + } + } + + async loadResponse(fetchResponse) { + if (fetchResponse.redirected || (fetchResponse.succeeded && fetchResponse.isHTML)) { + this.sourceURL = fetchResponse.response.url; + } + + try { + const html = await fetchResponse.responseHTML; + if (html) { + const document = parseHTMLDocument(html); + const pageSnapshot = PageSnapshot.fromDocument(document); + + if (pageSnapshot.isVisitable) { + await this.#loadFrameResponse(fetchResponse, document); + } else { + await this.#handleUnvisitableFrameResponse(fetchResponse); + } + } + } finally { + this.#shouldMorphFrame = false; + this.fetchResponseLoaded = () => Promise.resolve(); + } + } + + // Appearance observer delegate + + elementAppearedInViewport(element) { + this.proposeVisitIfNavigatedWithAction(element, getVisitAction(element)); + this.#loadSourceURL(); + } + + // Form link click observer delegate + + willSubmitFormLinkToLocation(link) { + return this.#shouldInterceptNavigation(link) + } + + submittedFormLinkToLocation(link, _location, form) { + const frame = this.#findFrameElement(link); + if (frame) form.setAttribute("data-turbo-frame", frame.id); + } + + // Link interceptor delegate + + shouldInterceptLinkClick(element, _location, _event) { + return this.#shouldInterceptNavigation(element) + } + + linkClickIntercepted(element, location) { + this.#navigateFrame(element, location); + } + + // Form submit observer delegate + + willSubmitForm(element, submitter) { + return element.closest("turbo-frame") == this.element && this.#shouldInterceptNavigation(element, submitter) + } + + formSubmitted(element, submitter) { + if (this.formSubmission) { + this.formSubmission.stop(); + } + + this.formSubmission = new FormSubmission(this, element, submitter); + const { fetchRequest } = this.formSubmission; + this.prepareRequest(fetchRequest); + this.formSubmission.start(); + } + + // Fetch request delegate + + prepareRequest(request) { + request.headers["Turbo-Frame"] = this.id; + + if (this.currentNavigationElement?.hasAttribute("data-turbo-stream")) { + request.acceptResponseType(StreamMessage.contentType); + } + } + + requestStarted(_request) { + markAsBusy(this.element); + } + + requestPreventedHandlingResponse(_request, _response) { + this.#resolveVisitPromise(); + } + + async requestSucceededWithResponse(request, response) { + await this.loadResponse(response); + this.#resolveVisitPromise(); + } + + async requestFailedWithResponse(request, response) { + await this.loadResponse(response); + this.#resolveVisitPromise(); + } + + requestErrored(request, error) { + console.error(error); + this.#resolveVisitPromise(); + } + + requestFinished(_request) { + clearBusyState(this.element); + } + + // Form submission delegate + + formSubmissionStarted({ formElement }) { + markAsBusy(formElement, this.#findFrameElement(formElement)); + } + + formSubmissionSucceededWithResponse(formSubmission, response) { + const frame = this.#findFrameElement(formSubmission.formElement, formSubmission.submitter); + + frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(formSubmission.submitter, formSubmission.formElement, frame)); + frame.delegate.loadResponse(response); + + if (!formSubmission.isSafe) { + session.clearCache(); + } + } + + formSubmissionFailedWithResponse(formSubmission, fetchResponse) { + this.element.delegate.loadResponse(fetchResponse); + session.clearCache(); + } + + formSubmissionErrored(formSubmission, error) { + console.error(error); + } + + formSubmissionFinished({ formElement }) { + clearBusyState(formElement, this.#findFrameElement(formElement)); + } + + // View delegate + + allowsImmediateRender({ element: newFrame }, options) { + const event = dispatch("turbo:before-frame-render", { + target: this.element, + detail: { newFrame, ...options }, + cancelable: true + }); + + const { + defaultPrevented, + detail: { render } + } = event; + + if (this.view.renderer && render) { + this.view.renderer.renderElement = render; + } + + return !defaultPrevented + } + + viewRenderedSnapshot(_snapshot, _isPreview, _renderMethod) {} + + preloadOnLoadLinksForView(element) { + session.preloadOnLoadLinksForView(element); + } + + viewInvalidated() {} + + // Frame renderer delegate + + willRenderFrame(currentElement, _newElement) { + this.previousFrameElement = currentElement.cloneNode(true); + } + + visitCachedSnapshot = ({ element }) => { + const frame = element.querySelector("#" + this.element.id); + + if (frame && this.previousFrameElement) { + frame.replaceChildren(...this.previousFrameElement.children); + } + + delete this.previousFrameElement; + } + + // Private + + async #loadFrameResponse(fetchResponse, document) { + const newFrameElement = await this.extractForeignFrameElement(document.body); + const rendererClass = this.#shouldMorphFrame ? MorphingFrameRenderer : FrameRenderer; + + if (newFrameElement) { + const snapshot = new Snapshot(newFrameElement); + const renderer = new rendererClass(this, this.view.snapshot, snapshot, false, false); + if (this.view.renderPromise) await this.view.renderPromise; + this.changeHistory(); + + await this.view.render(renderer); + this.complete = true; + session.frameRendered(fetchResponse, this.element); + session.frameLoaded(this.element); + await this.fetchResponseLoaded(fetchResponse); + } else if (this.#willHandleFrameMissingFromResponse(fetchResponse)) { + this.#handleFrameMissingFromResponse(fetchResponse); + } + } + + async #visit(url) { + const request = new FetchRequest(this, FetchMethod.get, url, new URLSearchParams(), this.element); + + this.#currentFetchRequest?.cancel(); + this.#currentFetchRequest = request; + + return new Promise((resolve) => { + this.#resolveVisitPromise = () => { + this.#resolveVisitPromise = () => {}; + this.#currentFetchRequest = null; + resolve(); + }; + request.perform(); + }) + } + + #navigateFrame(element, url, submitter) { + const frame = this.#findFrameElement(element, submitter); + + frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(submitter, element, frame)); + + this.#withCurrentNavigationElement(element, () => { + frame.src = url; + }); + } + + proposeVisitIfNavigatedWithAction(frame, action = null) { + this.action = action; + + if (this.action) { + const pageSnapshot = PageSnapshot.fromElement(frame).clone(); + const { visitCachedSnapshot } = frame.delegate; + + frame.delegate.fetchResponseLoaded = async (fetchResponse) => { + if (frame.src) { + const { statusCode, redirected } = fetchResponse; + const responseHTML = await fetchResponse.responseHTML; + const response = { statusCode, redirected, responseHTML }; + const options = { + response, + visitCachedSnapshot, + willRender: false, + updateHistory: false, + restorationIdentifier: this.restorationIdentifier, + snapshot: pageSnapshot + }; + + if (this.action) options.action = this.action; + + session.visit(frame.src, options); + } + }; + } + } + + changeHistory() { + if (this.action) { + const method = getHistoryMethodForAction(this.action); + session.history.update(method, expandURL(this.element.src || ""), this.restorationIdentifier); + } + } + + async #handleUnvisitableFrameResponse(fetchResponse) { + console.warn( + `The response (${fetchResponse.statusCode}) from is performing a full page visit due to turbo-visit-control.` + ); + + await this.#visitResponse(fetchResponse.response); + } + + #willHandleFrameMissingFromResponse(fetchResponse) { + this.element.setAttribute("complete", ""); + + const response = fetchResponse.response; + const visit = async (url, options) => { + if (url instanceof Response) { + this.#visitResponse(url); + } else { + session.visit(url, options); + } + }; + + const event = dispatch("turbo:frame-missing", { + target: this.element, + detail: { response, visit }, + cancelable: true + }); + + return !event.defaultPrevented + } + + #handleFrameMissingFromResponse(fetchResponse) { + this.view.missing(); + this.#throwFrameMissingError(fetchResponse); + } + + #throwFrameMissingError(fetchResponse) { + const message = `The response (${fetchResponse.statusCode}) did not contain the expected and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`; + throw new TurboFrameMissingError(message) + } + + async #visitResponse(response) { + const wrapped = new FetchResponse(response); + const responseHTML = await wrapped.responseHTML; + const { location, redirected, statusCode } = wrapped; + + return session.visit(location, { response: { redirected, statusCode, responseHTML } }) + } + + #findFrameElement(element, submitter) { + const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target"); + return getFrameElementById(id) ?? this.element + } + + async extractForeignFrameElement(container) { + let element; + const id = CSS.escape(this.id); + + try { + element = activateElement(container.querySelector(`turbo-frame#${id}`), this.sourceURL); + if (element) { + return element + } + + element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.sourceURL); + if (element) { + await element.loaded; + return await this.extractForeignFrameElement(element) + } + } catch (error) { + console.error(error); + return new FrameElement() + } + + return null + } + + #formActionIsVisitable(form, submitter) { + const action = getAction$1(form, submitter); + + return locationIsVisitable(expandURL(action), this.rootLocation) + } + + #shouldInterceptNavigation(element, submitter) { + const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target"); + + if (element instanceof HTMLFormElement && !this.#formActionIsVisitable(element, submitter)) { + return false + } + + if (!this.enabled || id == "_top") { + return false + } + + if (id) { + const frameElement = getFrameElementById(id); + if (frameElement) { + return !frameElement.disabled + } + } + + if (!session.elementIsNavigatable(element)) { + return false + } + + if (submitter && !session.elementIsNavigatable(submitter)) { + return false + } + + return true + } + + // Computed properties + + get id() { + return this.element.id + } + + get enabled() { + return !this.element.disabled + } + + get sourceURL() { + if (this.element.src) { + return this.element.src + } + } + + set sourceURL(sourceURL) { + this.#ignoringChangesToAttribute("src", () => { + this.element.src = sourceURL ?? null; + }); + } + + get loadingStyle() { + return this.element.loading + } + + get isLoading() { + return this.formSubmission !== undefined || this.#resolveVisitPromise() !== undefined + } + + get complete() { + return this.element.hasAttribute("complete") + } + + set complete(value) { + if (value) { + this.element.setAttribute("complete", ""); + } else { + this.element.removeAttribute("complete"); + } + } + + get isActive() { + return this.element.isActive && this.#connected + } + + get rootLocation() { + const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`); + const root = meta?.content ?? "/"; + return expandURL(root) + } + + #isIgnoringChangesTo(attributeName) { + return this.#ignoredAttributes.has(attributeName) + } + + #ignoringChangesToAttribute(attributeName, callback) { + this.#ignoredAttributes.add(attributeName); + callback(); + this.#ignoredAttributes.delete(attributeName); + } + + #withCurrentNavigationElement(element, callback) { + this.currentNavigationElement = element; + callback(); + delete this.currentNavigationElement; + } +} + +function getFrameElementById(id) { + if (id != null) { + const element = document.getElementById(id); + if (element instanceof FrameElement) { + return element + } + } +} + +function activateElement(element, currentURL) { + if (element) { + const src = element.getAttribute("src"); + if (src != null && currentURL != null && urlsAreEqual(src, currentURL)) { + throw new Error(`Matching element has a source URL which references itself`) + } + if (element.ownerDocument !== document) { + element = document.importNode(element, true); + } + + if (element instanceof FrameElement) { + element.connectedCallback(); + element.disconnectedCallback(); + return element + } + } +} + +const StreamActions = { + after() { + this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e.nextSibling)); + }, + + append() { + this.removeDuplicateTargetChildren(); + this.targetElements.forEach((e) => e.append(this.templateContent)); + }, + + before() { + this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e)); + }, + + prepend() { + this.removeDuplicateTargetChildren(); + this.targetElements.forEach((e) => e.prepend(this.templateContent)); + }, + + remove() { + this.targetElements.forEach((e) => e.remove()); + }, + + replace() { + const method = this.getAttribute("method"); + + this.targetElements.forEach((targetElement) => { + if (method === "morph") { + morphElements(targetElement, this.templateContent); + } else { + targetElement.replaceWith(this.templateContent); + } + }); + }, + + update() { + const method = this.getAttribute("method"); + + this.targetElements.forEach((targetElement) => { + if (method === "morph") { + morphChildren(targetElement, this.templateContent); + } else { + targetElement.innerHTML = ""; + targetElement.append(this.templateContent); + } + }); + }, + + refresh() { + session.refresh(this.baseURI, this.requestId); + } +}; + +//