password_manager/dist/index.html

7988 lines
256 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0NiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDQ4IDQ2Ij48cGF0aCBmaWxsPSIjODYzYmZmIiBkPSJNMjUuOTQ2IDQ0LjkzOGMtLjY2NC44NDUtMi4wMjEuMzc1LTIuMDIxLS42OThWMzMuOTM3YTIuMjYgMi4yNiAwIDAgMC0yLjI2Mi0yLjI2MkgxMC4yODdjLS45MiAwLTEuNDU2LTEuMDQtLjkyLTEuNzg4bDcuNDgtMTAuNDcxYzEuMDctMS40OTcgMC0zLjU3OC0xLjg0Mi0zLjU3OEgxLjIzN2MtLjkyIDAtMS40NTYtMS4wNC0uOTItMS43ODhMMTAuMDEzLjQ3NGMuMjE0LS4yOTcuNTU2LS40NzQuOTItLjQ3NGgyOC44OTRjLjkyIDAgMS40NTYgMS4wNC45MiAxLjc4OGwtNy40OCAxMC40NzFjLTEuMDcgMS40OTggMCAzLjU3OSAxLjg0MiAzLjU3OWgxMS4zNzdjLjk0MyAwIDEuNDczIDEuMDg4Ljg5IDEuODNMMjUuOTQ3IDQ0Ljk0eiIgc3R5bGU9ImZpbGw6Izg2M2JmZjtmaWxsOmNvbG9yKGRpc3BsYXktcDMgLjUyNTIgLjIzIDEpO2ZpbGwtb3BhY2l0eToxIi8+PG1hc2sgaWQ9ImEiIHdpZHRoPSI0OCIgaGVpZ2h0PSI0NiIgeD0iMCIgeT0iMCIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgc3R5bGU9Im1hc2stdHlwZTphbHBoYSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTI1Ljg0MiA0NC45MzhjLS42NjQuODQ0LTIuMDIxLjM3NS0yLjAyMS0uNjk4VjMzLjkzN2EyLjI2IDIuMjYgMCAwIDAtMi4yNjItMi4yNjJIMTAuMTgzYy0uOTIgMC0xLjQ1Ni0xLjA0LS45Mi0xLjc4OGw3LjQ4LTEwLjQ3MWMxLjA3LTEuNDk4IDAtMy41NzktMS44NDItMy41NzlIMS4xMzNjLS45MiAwLTEuNDU2LTEuMDQtLjkyLTEuNzg3TDkuOTEuNDczYy4yMTQtLjI5Ny41NTYtLjQ3NC45Mi0uNDc0aDI4Ljg5NGMuOTIgMCAxLjQ1NiAxLjA0LjkyIDEuNzg4bC03LjQ4IDEwLjQ3MWMtMS4wNyAxLjQ5OCAwIDMuNTc4IDEuODQyIDMuNTc4aDExLjM3N2MuOTQzIDAgMS40NzMgMS4wODguODkgMS44MzJMMjUuODQzIDQ0Ljk0eiIgc3R5bGU9ImZpbGw6IzAwMDtmaWxsLW9wYWNpdHk6MSIvPjwvbWFzaz48ZyBtYXNrPSJ1cmwoI2EpIj48ZyBmaWx0ZXI9InVybCgjYikiPjxlbGxpcHNlIGN4PSI1LjUwOCIgY3k9IjE0LjcwNCIgZmlsbD0iI2VkZTZmZiIgcng9IjUuNTA4IiByeT0iMTQuNzA0IiBzdHlsZT0iZmlsbDojZWRlNmZmO2ZpbGw6Y29sb3IoZGlzcGxheS1wMyAuOTI3NSAuOTAzMyAxKTtmaWxsLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJtYXRyaXgoLjAwMzI0IDEgMSAtLjAwMzI0IC00LjQ3IDMxLjUxNikiLz48L2c+PGcgZmlsdGVyPSJ1cmwoI2MpIj48ZWxsaXBzZSBjeD0iMTAuMzk5IiBjeT0iMjkuODUxIiBmaWxsPSIjZWRlNmZmIiByeD0iMTAuMzk5IiByeT0iMjkuODUxIiBzdHlsZT0iZmlsbDojZWRlNmZmO2ZpbGw6Y29sb3IoZGlzcGxheS1wMyAuOTI3NSAuOTAzMyAxKTtmaWxsLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJtYXRyaXgoLjAwMzI0IDEgMSAtLjAwMzI0IC0zOS4zMjggNy44ODMpIi8+PC9nPjxnIGZpbHRlcj0idXJsKCNkKSI+PGVsbGlwc2UgY3g9IjUuNTA4IiBjeT0iMzAuNDg3IiBmaWxsPSIjN2UxNGZmIiByeD0iNS41MDgiIHJ5PSIzMC40ODciIHN0eWxlPSJmaWxsOiM3ZTE0ZmY7ZmlsbDpjb2xvcihkaXNwbGF5LXAzIC40OTIyIC4wNzY3IDEpO2ZpbGwtb3BhY2l0eToxIiB0cmFuc2Zvcm09InJvdGF0ZSg4OS44MTQgLTI1LjkxMyAtMTQuNjM5KXNjYWxlKDEgLTEpIi8+PC9nPjxnIGZpbHRlcj0idXJsKCNlKSI+PGVsbGlwc2UgY3g9IjUuNTA4IiBjeT0iMzAuNTk5IiBmaWxsPSIjN2UxNGZmIiByeD0iNS41MDgiIHJ5PSIzMC41OTkiIHN0eWxlPSJmaWxsOiM3ZTE0ZmY7ZmlsbDpjb2xvcihkaXNwbGF5LXAzIC40OTIyIC4wNzY3IDEpO2ZpbGwtb3BhY2l0eToxIiB0cmFuc2Zvcm09InJvdGF0ZSg4OS44MTQgLTMyLjY0NCAtMy4zMzQpc2NhbGUoMSAtMSkiLz48L2c+PGcgZmlsdGVyPSJ1cmwoI2YpIj48ZWxsaXBzZSBjeD0iNS41MDgiIGN5PSIzMC41OTkiIGZpbGw9IiM3ZTE0ZmYiIHJ4PSI1LjUwOCIgcnk9IjMwLjU5OSIgc3R5bGU9ImZpbGw6IzdlMTRmZjtmaWxsOmNvbG9yKGRpc3BsYXktcDMgLjQ5MjIgLjA3NjcgMSk7ZmlsbC1vcGFjaXR5OjEiIHRyYW5zZm9ybT0ibWF0cml4KC4wMDMyNCAxIDEgLS4wMDMyNCAtMzQuMzQgMzAuNDcpIi8+PC9nPjxnIGZpbHRlcj0idXJsKCNnKSI+PGVsbGlwc2UgY3g9IjE0LjA3MiIgY3k9IjIyLjA3OCIgZmlsbD0iI2VkZTZmZiIgcng9IjE0LjA3MiIgcnk9IjIyLjA3OCIgc3R5bGU9ImZpbGw6I2VkZTZmZjtmaWxsOmNvbG9yKGRpc3BsYXktcDMgLjkyNzUgLjkwMzMgMSk7ZmlsbC1vcGFjaXR5OjEiIHRyYW5zZm9ybT0icm90YXRlKDkzLjM1IDI0LjUwNiA0OC40OTMpc2NhbGUoLTEgMSkiLz48L2c+PGcgZmlsdGVyPSJ1cmwoI2gpIj48ZWxsaXBzZSBjeD0iMy40NyIgY3k9IjIxLjUwMSIgZmlsbD0iIzdlMTRmZiIgcng9IjMuNDciIHJ5PSIyMS41MDEiIHN0eWxlPSJmaWxsOiM3ZTE0ZmY7ZmlsbDpjb2xvcihkaXNwbGF5LXAzIC40OTIyIC4wNzY3IDEpO2ZpbGwtb3BhY2l0eToxIiB0cmFuc2Zvcm09InJvdGF0ZSg4OS4wMDkgMjguNzA4IDQ3LjU5KXNjYWxlKC0xIDEpIi8+PC9nPjxnIGZpbHRlcj0idXJsKCNpKSI+PGVsbGlwc2UgY3g9IjMuNDciIGN5PSIyMS41MDEiIGZpbGw9IiM3ZTE0ZmYiIHJ4PSIzLjQ3IiByeT0iMjEuNTAxIiBzdHlsZT0iZmlsbDojN2UxNGZmO2ZpbGw6Y29sb3IoZGlzcGxheS1wMyAuNDkyMiAuMDc2NyAxKTtmaWxsLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJyb3RhdGUoODkuMDA5IDI4LjcwOCA0Ny41OSlzY2FsZSgtMSAxKSIvPjwvZz48ZyBmaWx0ZXI9InVybCgjaikiPjxlbGxpcHNlIGN4PSIuMzg3IiBjeT0iOC45NzIiIGZpbGw9IiM3ZTE0ZmYiIHJ4PSI0LjQwNyIgcnk9IjI5LjEwOCIgc3R5bGU9ImZpbGw6IzdlMTRmZjtmaWxsOmNvbG9yKGRpc3BsYXktcDMgLjQ5MjIgLjA3NjcgMSk7ZmlsbC1vcGFjaXR5OjEiIHRyYW5zZm9ybT0icm90YXRlKDM5LjUxIC4zODcgOC45NzIpIi8+PC9nPjxnIGZpbHRlcj0idXJsKCNrKSI+PGVsbGlwc2UgY3g9IjQ3LjUyMyIgY3k9Ii02LjA5MiIgZmlsbD0iIzdlMTRmZiIgcng9IjQuNDA3IiByeT0iMjkuMTA4IiBzdHlsZT0iZmlsbDojN2UxNGZmO2ZpbGw6Y29sb3IoZGlzcGxheS1wMyAuNDkyMiAuMDc2NyAxKTtmaWxsLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJyb3RhdGUoMzcuODkyIDQ3LjUyMyAtNi4wOTIpIi8+PC9nPjxnIGZpbHRlcj0idXJsKCNsKSI+PGVsbGlwc2UgY3g9IjQxLjQxMiIgY3k9IjYuMzMzIiBmaWxsPSIjNDdiZmZmIiByeD0iNS45NzEiIHJ5PSI5LjY2NSIgc3R5bGU9ImZpbGw6IzQ3YmZmZjtmaWxsOmNvbG9yKGRpc3BsYXktcDMgLjI3OTkgLjc0OCAxKTtmaWxsLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJyb3RhdGUoMzcuODkyIDQxLjQxMiA2LjMzMykiLz48L2c+PGcgZmlsdGVyPSJ1cmwoI20pIj48ZWxsaXBzZSBjeD0iLTEuODc5IiBjeT0iMzguMzMyIiBmaWxsPSIjN2UxNGZmIiByeD0iNC40MDciIHJ5PSIyOS4xMDgiIHN0eWxlPSJmaWxsOiM3ZTE0ZmY7ZmlsbDpjb2xvcihkaXNwbGF5LXAzIC40OTIyIC4wNzY3IDEpO2ZpbGwtb3BhY2l0eToxIiB0cmFuc2Zvcm09InJvdGF0ZSgzNy44OTIgLTEuODggMzguMzMyKSIvPjwvZz48ZyBmaWx0ZXI9InVybCgjbikiPjxlbGxpcHNlIGN4PSItMS44NzkiIGN5PSIzOC4zMzIiIGZpbGw9IiM3ZTE0ZmYiIHJ4PSI0LjQwNyIgcnk9IjI5LjEwOCIgc3R5bGU9ImZpbGw6IzdlMTRmZjtmaWxsOmNvbG9yKGRpc3BsYXktcDMgLjQ5MjIgLjA3NjcgMSk7ZmlsbC1vcGFjaXR5OjEiIHRyYW5zZm9ybT0icm90YXRlKDM3Ljg5MiAtMS44OCAzOC4zMzIpIi8+PC9nPjxnIGZpbHRlcj0idXJsKCNvKSI+PGVsbGlwc2UgY3g9IjM1LjY1MSIgY3k9IjI5LjkwNyIgZmlsbD0iIzdlMTRmZiIgcng9IjQuNDA3IiByeT0iMjkuMTA4IiBzdHlsZT0iZmlsbDojN2UxNGZmO2ZpbGw6Y29sb3IoZGlzcGxheS1wMyAuNDkyMiAuMDc2NyAxKTtmaWxsLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJyb3RhdGUoMzcuODkyIDM1LjY1MSAyOS45MDcpIi8+PC9nPjxnIGZpbHRlcj0idXJsKCNwKSI+PGVsbGlwc2UgY3g9IjM4LjQxOCIgY3k9IjMyLjQiIGZpbGw9IiM0N2JmZmYiIHJ4PSI1Ljk3MSIgcnk9IjE1LjI5NyIgc3R5bGU9ImZpbGw6IzQ3YmZmZjtmaWxsOmNvbG9yKGRpc3BsYXktcDMgLjI3OTkgLjc0OCAxKTtmaWxsLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJyb3RhdGUoMzcuODkyIDM4LjQxOCAzMi40KSIvPjwvZz48L2c+PGRlZnM+PGZpbHRlciBpZD0iYiIgd2lkdGg9IjYwLjA0NSIgaGVpZ2h0PSI0MS42NTQiIHg9Ii0xOS43NyIgeT0iMTYuMTQ5IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz48ZmVHYXVzc2lhbkJsdXIgcmVzdWx0PSJlZmZlY3QxX2ZvcmVncm91bmRCbHVyXzIwMDJfMTcxNTgiIHN0ZERldmlhdGlvbj0iNy42NTkiLz48L2ZpbHRlcj48ZmlsdGVyIGlkPSJjIiB3aWR0aD0iOTAuMzQiIGhlaWdodD0iNTEuNDM3IiB4PSItNTQuNjEzIiB5PSItNy41MzMiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPjxmZUJsZW5kIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPjxmZUdhdXNzaWFuQmx1ciByZXN1bHQ9ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXJfMjAwMl8xNzE1OCIgc3RkRGV2aWF0aW9uPSI3LjY1OSIvPjwvZmlsdGVyPjxmaWx0ZXIgaWQ9ImQiIHdpZHRoPSI3OS4zNTUiIGhlaWdodD0iMjkuNCIgeD0iLTQ5LjY0IiB5PSIyLjAzIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz48ZmVHYXVzc2lhbkJsdXIgcmVzdWx0PSJlZmZlY3QxX2ZvcmVncm91bmRCbHVyXzIwMDJfMTcxNTgiIHN0ZERldmlhdGlvbj0iNC41OTYiLz48L2ZpbHRlcj48ZmlsdGVyIGlkPSJlIiB3aWR0aD0iNzkuNTc5IiBoZWlnaHQ9IjI5LjQiIHg9Ii00NS4wNDUiIHk9IjIwLjAyOSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiPjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9InNoYXBlIi8+PGZlR2F1c3NpYW5CbHVyIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl8yMDAyXzE3MTU4IiBzdGREZXZpYXRpb249IjQuNTk2Ii8+PC9maWx0ZXI+PGZpbHRlciBpZD0iZiIgd2lkdGg9Ijc5LjU3OSIgaGVpZ2h0PSIyOS40IiB4PSItNDMuNTEzIiB5PSIyMS4xNzgiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPjxmZUJsZW5kIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPjxmZUdhdXNzaWFuQmx1ciByZXN1bHQ9ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXJfMjAwMl8xNzE1OCIgc3RkRGV2aWF0aW9uPSI0LjU5NiIvPjwvZmlsdGVyPjxmaWx0ZXIgaWQ9ImciIHdpZHRoPSI3NC43NDkiIGhlaWdodD0iNTguODUyIiB4PSIxNS43NTYiIHk9Ii0xNy45MDEiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPjxmZUJsZW5kIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPjxmZUdhdXNzaWFuQmx1ciByZXN1bHQ9ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXJfMjAwMl8xNzE1OCIgc3RkRGV2aWF0aW9uPSI3LjY1OSIvPjwvZmlsdGVyPjxmaWx0ZXIgaWQ9ImgiIHdpZHRoPSI2MS4zNzciIGhlaWdodD0iMjUuMzYyIiB4PSIyMy41NDgiIHk9IjIuMjg0IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz48ZmVHYXVzc2lhbkJsdXIgcmVzdWx0PSJlZmZlY3QxX2ZvcmVncm91bmRCbHVyXzIwMDJfMTcxNTgiIHN0ZERldmlhdGlvbj0iNC41OTYiLz48L2ZpbHRlcj48ZmlsdGVyIGlkPSJpIiB3aWR0aD0iNjEuMzc3IiBoZWlnaHQ9IjI1LjM2MiIgeD0iMjMuNTQ4IiB5PSIyLjI4NCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiPjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9InNoYXBlIi8+PGZlR2F1c3NpYW5CbHVyIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl8yMDAyXzE3MTU4IiBzdGREZXZpYXRpb249IjQuNTk2Ii8+PC9maWx0ZXI+PGZpbHRlciBpZD0iaiIgd2lkdGg9IjU2LjA0NSIgaGVpZ2h0PSI2My42NDkiIHg9Ii0yNy42MzYiIHk9Ii0yMi44NTMiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPjxmZUJsZW5kIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPjxmZUdhdXNzaWFuQmx1ciByZXN1bHQ9ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXJfMjAwMl8xNzE1OCIgc3RkRGV2aWF0aW9uPSI0LjU5NiIvPjwvZmlsdGVyPjxmaWx0ZXIgaWQ9ImsiIHdpZHRoPSI1NC44MTQiIGhlaWdodD0iNjQuNjQ2IiB4PSIyMC4xMTYiIHk9Ii0zOC40MTUiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPjxmZUJsZW5kIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPjxmZUdhdXNzaWFuQmx1ciByZXN1bHQ9ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXJfMjAwMl8xNzE1OCIgc3RkRGV2aWF0aW9uPSI0LjU5NiIvPjwvZmlsdGVyPjxmaWx0ZXIgaWQ9ImwiIHdpZHRoPSIzMy41NDEiIGhlaWdodD0iMzUuMzEzIiB4PSIyNC42NDEiIHk9Ii0xMS4zMjMiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPjxmZUJsZW5kIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPjxmZUdhdXNzaWFuQmx1ciByZXN1bHQ9ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXJfMjAwMl8xNzE1OCIgc3RkRGV2aWF0aW9uPSI0LjU5NiIvPjwvZmlsdGVyPjxmaWx0ZXIgaWQ9Im0iIHdpZHRoPSI1NC44MTQiIGhlaWdodD0iNjQuNjQ2IiB4PSItMjkuMjg2IiB5PSI2LjAwOSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiPjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9InNoYXBlIi8+PGZlR2F1c3NpYW5CbHVyIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl8yMDAyXzE3MTU4IiBzdGREZXZpYXRpb249IjQuNTk2Ii8+PC9maWx0ZXI+PGZpbHRlciBpZD0ibiIgd2lkdGg9IjU0LjgxNCIgaGVpZ2h0PSI2NC42NDYiIHg9Ii0yOS4yODYiIHk9IjYuMDA5IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz48ZmVHYXVzc2lhbkJsdXIgcmVzdWx0PSJlZmZlY3QxX2ZvcmVncm91bmRCbHVyXzIwMDJfMTcxNTgiIHN0ZERldmlhdGlvbj0iNC41OTYiLz48L2ZpbHRlcj48ZmlsdGVyIGlkPSJvIiB3aWR0aD0iNTQuODE0IiBoZWlnaHQ9IjY0LjY0NiIgeD0iOC4yNDQiIHk9Ii0yLjQxNiIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiPjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9InNoYXBlIi8+PGZlR2F1c3NpYW5CbHVyIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl8yMDAyXzE3MTU4IiBzdGREZXZpYXRpb249IjQuNTk2Ii8+PC9maWx0ZXI+PGZpbHRlciBpZD0icCIgd2lkdGg9IjM5LjQwOSIgaGVpZ2h0PSI0My42MjMiIHg9IjE4LjcxMyIgeT0iMTAuNTg4IiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz48ZmVHYXVzc2lhbkJsdXIgcmVzdWx0PSJlZmZlY3QxX2ZvcmVncm91bmRCbHVyXzIwMDJfMTcxNTgiIHN0ZERldmlhdGlvbj0iNC41OTYiLz48L2ZpbHRlcj48L2RlZnM+PC9zdmc+" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Password Vault</title>
<script type="module" crossorigin>//#region \0vite/modulepreload-polyfill.js
(function polyfill() {
const relList = document.createElement("link").relList;
if (relList && relList.supports && relList.supports("modulepreload")) return;
for (const link of document.querySelectorAll("link[rel=\"modulepreload\"]")) processPreload(link);
new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.type !== "childList") continue;
for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node);
}
}).observe(document, {
childList: true,
subtree: true
});
function getFetchOpts(link) {
const fetchOpts = {};
if (link.integrity) fetchOpts.integrity = link.integrity;
if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy;
if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include";
else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit";
else fetchOpts.credentials = "same-origin";
return fetchOpts;
}
function processPreload(link) {
if (link.ep) return;
link.ep = true;
const fetchOpts = getFetchOpts(link);
fetch(link.href, fetchOpts);
}
})();
//#endregion
//#region node_modules/svelte/src/internal/shared/utils.js
var is_array = Array.isArray;
var index_of = Array.prototype.indexOf;
var includes = Array.prototype.includes;
var array_from = Array.from;
var define_property = Object.defineProperty;
var get_descriptor = Object.getOwnPropertyDescriptor;
var get_descriptors = Object.getOwnPropertyDescriptors;
var object_prototype = Object.prototype;
var array_prototype = Array.prototype;
var get_prototype_of = Object.getPrototypeOf;
var is_extensible = Object.isExtensible;
var noop = () => {};
/** @param {Function} fn */
function run(fn) {
return fn();
}
/** @param {Array<() => void>} arr */
function run_all(arr) {
for (var i = 0; i < arr.length; i++) arr[i]();
}
/**
* TODO replace with Promise.withResolvers once supported widely enough
* @template [T=void]
*/
function deferred() {
/** @type {(value: T) => void} */
var resolve;
/** @type {(reason: any) => void} */
var reject;
return {
promise: new Promise((res, rej) => {
resolve = res;
reject = rej;
}),
resolve,
reject
};
}
var CLEAN = 1024;
var DIRTY = 2048;
var MAYBE_DIRTY = 4096;
var INERT = 8192;
var DESTROYED = 16384;
/** Set once a reaction has run for the first time */
var REACTION_RAN = 32768;
/** Effect is in the process of getting destroyed. Can be observed in child teardown functions */
var DESTROYING = 1 << 25;
/**
* 'Transparent' effects do not create a transition boundary.
* This is on a block effect 99% of the time but may also be on a branch effect if its parent block effect was pruned
*/
var EFFECT_TRANSPARENT = 65536;
var HEAD_EFFECT = 1 << 18;
var EFFECT_PRESERVED = 1 << 19;
var USER_EFFECT = 1 << 20;
var EFFECT_OFFSCREEN = 1 << 25;
/**
* Tells that we marked this derived and its reactions as visited during the "mark as (maybe) dirty"-phase.
* Will be lifted during execution of the derived and during checking its dirty state (both are necessary
* because a derived might be checked but not executed). This is a pure performance optimization flag and
* should not be used for any other purpose!
*/
var WAS_MARKED = 65536;
var REACTION_IS_UPDATING = 1 << 21;
var ASYNC = 1 << 22;
var ERROR_VALUE = 1 << 23;
var STATE_SYMBOL = Symbol("$state");
var LOADING_ATTR_SYMBOL = Symbol("");
/** allow users to ignore aborted signal errors if `reason.name === 'StaleReactionError` */
var STALE_REACTION = new class StaleReactionError extends Error {
name = "StaleReactionError";
message = "The reaction that called `getAbortSignal()` was re-run or destroyed";
}();
var IS_XHTML = !!globalThis.document?.contentType && /* @__PURE__ */ globalThis.document.contentType.includes("xml");
//#endregion
//#region node_modules/svelte/src/internal/client/errors.js
/**
* Cannot create a `$derived(...)` with an `await` expression outside of an effect tree
* @returns {never}
*/
function async_derived_orphan() {
throw new Error(`https://svelte.dev/e/async_derived_orphan`);
}
/**
* Keyed each block has duplicate key `%value%` at indexes %a% and %b%
* @param {string} a
* @param {string} b
* @param {string | undefined | null} [value]
* @returns {never}
*/
function each_key_duplicate(a, b, value) {
throw new Error(`https://svelte.dev/e/each_key_duplicate`);
}
/**
* `%rune%` cannot be used inside an effect cleanup function
* @param {string} rune
* @returns {never}
*/
function effect_in_teardown(rune) {
throw new Error(`https://svelte.dev/e/effect_in_teardown`);
}
/**
* Effect cannot be created inside a `$derived` value that was not itself created inside an effect
* @returns {never}
*/
function effect_in_unowned_derived() {
throw new Error(`https://svelte.dev/e/effect_in_unowned_derived`);
}
/**
* `%rune%` can only be used inside an effect (e.g. during component initialisation)
* @param {string} rune
* @returns {never}
*/
function effect_orphan(rune) {
throw new Error(`https://svelte.dev/e/effect_orphan`);
}
/**
* Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state
* @returns {never}
*/
function effect_update_depth_exceeded() {
throw new Error(`https://svelte.dev/e/effect_update_depth_exceeded`);
}
/**
* Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`.
* @returns {never}
*/
function state_descriptors_fixed() {
throw new Error(`https://svelte.dev/e/state_descriptors_fixed`);
}
/**
* Cannot set prototype of `$state` object
* @returns {never}
*/
function state_prototype_fixed() {
throw new Error(`https://svelte.dev/e/state_prototype_fixed`);
}
/**
* Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
* @returns {never}
*/
function state_unsafe_mutation() {
throw new Error(`https://svelte.dev/e/state_unsafe_mutation`);
}
/**
* A `<svelte:boundary>` `reset` function cannot be called while an error is still being handled
* @returns {never}
*/
function svelte_boundary_reset_onerror() {
throw new Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`);
}
//#endregion
//#region node_modules/svelte/src/constants.js
var HYDRATION_ERROR = {};
var UNINITIALIZED = Symbol();
var NAMESPACE_HTML = "http://www.w3.org/1999/xhtml";
/**
* Reading a derived belonging to a now-destroyed effect may result in stale values
*/
function derived_inert() {
console.warn(`https://svelte.dev/e/derived_inert`);
}
/**
* Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location%
* @param {string | undefined | null} [location]
*/
function hydration_mismatch(location) {
console.warn(`https://svelte.dev/e/hydration_mismatch`);
}
/**
* The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is.
*/
function select_multiple_invalid_value() {
console.warn(`https://svelte.dev/e/select_multiple_invalid_value`);
}
/**
* A `<svelte:boundary>` `reset` function only resets the boundary the first time it is called
*/
function svelte_boundary_reset_noop() {
console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`);
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/hydration.js
/** @import { TemplateNode } from '#client' */
/**
* Use this variable to guard everything related to hydration code so it can be treeshaken out
* if the user doesn't use the `hydrate` method and these code paths are therefore not needed.
*/
var hydrating = false;
/** @param {boolean} value */
function set_hydrating(value) {
hydrating = value;
}
/**
* The node that is currently being hydrated. This starts out as the first node inside the opening
* \x3C!--[--> comment, and updates each time a component calls `$.child(...)` or `$.sibling(...)`.
* When entering a block (e.g. `{#if ...}`), `hydrate_node` is the block opening comment; by the
* time we leave the block it is the closing comment, which serves as the block's anchor.
* @type {TemplateNode}
*/
var hydrate_node;
/** @param {TemplateNode | null} node */
function set_hydrate_node(node) {
if (node === null) {
hydration_mismatch();
throw HYDRATION_ERROR;
}
return hydrate_node = node;
}
function hydrate_next() {
return set_hydrate_node(/* @__PURE__ */ get_next_sibling(hydrate_node));
}
/** @param {TemplateNode} node */
function reset(node) {
if (!hydrating) return;
if (/* @__PURE__ */ get_next_sibling(hydrate_node) !== null) {
hydration_mismatch();
throw HYDRATION_ERROR;
}
hydrate_node = node;
}
function next(count = 1) {
if (hydrating) {
var i = count;
var node = hydrate_node;
while (i--) node = /* @__PURE__ */ get_next_sibling(node);
hydrate_node = node;
}
}
/**
* Skips or removes (depending on {@link remove}) all nodes starting at `hydrate_node` up until the next hydration end comment
* @param {boolean} remove
*/
function skip_nodes(remove = true) {
var depth = 0;
var node = hydrate_node;
while (true) {
if (node.nodeType === 8) {
var data = node.data;
if (data === "]") {
if (depth === 0) return node;
depth -= 1;
} else if (data === "[" || data === "[!" || data[0] === "[" && !isNaN(Number(data.slice(1)))) depth += 1;
}
var next = /* @__PURE__ */ get_next_sibling(node);
if (remove) node.remove();
node = next;
}
}
/**
*
* @param {TemplateNode} node
*/
function read_hydration_instruction(node) {
if (!node || node.nodeType !== 8) {
hydration_mismatch();
throw HYDRATION_ERROR;
}
return node.data;
}
//#endregion
//#region node_modules/svelte/src/internal/client/reactivity/equality.js
/** @import { Equals } from '#client' */
/** @type {Equals} */
function equals(value) {
return value === this.v;
}
/**
* @param {unknown} a
* @param {unknown} b
* @returns {boolean}
*/
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || a !== null && typeof a === "object" || typeof a === "function";
}
/** @type {Equals} */
function safe_equals(value) {
return !safe_not_equal(value, this.v);
}
//#endregion
//#region node_modules/svelte/src/internal/flags/index.js
/** True if experimental.async=true */
var async_mode_flag = false;
/** True if we're not certain that we only have Svelte 5 code in the compilation */
var legacy_mode_flag = false;
function enable_legacy_mode_flag() {
legacy_mode_flag = true;
}
//#endregion
//#region node_modules/svelte/src/internal/client/context.js
/** @import { ComponentContext, DevStackEntry, Effect } from '#client' */
/** @type {ComponentContext | null} */
var component_context = null;
/** @param {ComponentContext | null} context */
function set_component_context(context) {
component_context = context;
}
/**
* @param {Record<string, unknown>} props
* @param {any} runes
* @param {Function} [fn]
* @returns {void}
*/
function push(props, runes = false, fn) {
component_context = {
p: component_context,
i: false,
c: null,
e: null,
s: props,
x: null,
r: active_effect,
l: legacy_mode_flag && !runes ? {
s: null,
u: null,
$: []
} : null
};
}
/**
* @template {Record<string, any>} T
* @param {T} [component]
* @returns {T}
*/
function pop(component) {
var context = component_context;
var effects = context.e;
if (effects !== null) {
context.e = null;
for (var fn of effects) create_user_effect(fn);
}
if (component !== void 0) context.x = component;
context.i = true;
component_context = context.p;
return component ?? {};
}
/** @returns {boolean} */
function is_runes() {
return !legacy_mode_flag || component_context !== null && component_context.l === null;
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/task.js
/** @type {Array<() => void>} */
var micro_tasks = [];
function run_micro_tasks() {
var tasks = micro_tasks;
micro_tasks = [];
run_all(tasks);
}
/**
* @param {() => void} fn
*/
function queue_micro_task(fn) {
if (micro_tasks.length === 0 && !is_flushing_sync) {
var tasks = micro_tasks;
queueMicrotask(() => {
if (tasks === micro_tasks) run_micro_tasks();
});
}
micro_tasks.push(fn);
}
/**
* Synchronously run any queued tasks.
*/
function flush_tasks() {
while (micro_tasks.length > 0) run_micro_tasks();
}
/**
* @param {unknown} error
*/
function handle_error(error) {
var effect = active_effect;
if (effect === null) {
/** @type {Derived} */ active_reaction.f |= ERROR_VALUE;
return error;
}
if ((effect.f & 32768) === 0 && (effect.f & 4) === 0) throw error;
invoke_error_boundary(error, effect);
}
/**
* @param {unknown} error
* @param {Effect | null} effect
*/
function invoke_error_boundary(error, effect) {
while (effect !== null) {
if ((effect.f & 128) !== 0) {
if ((effect.f & 32768) === 0) throw error;
try {
/** @type {Boundary} */ effect.b.error(error);
return;
} catch (e) {
error = e;
}
}
effect = effect.parent;
}
throw error;
}
//#endregion
//#region node_modules/svelte/src/internal/client/reactivity/status.js
/** @import { Derived, Signal } from '#client' */
var STATUS_MASK = ~(DIRTY | MAYBE_DIRTY | CLEAN);
/**
* @param {Signal} signal
* @param {number} status
*/
function set_signal_status(signal, status) {
signal.f = signal.f & STATUS_MASK | status;
}
/**
* Set a derived's status to CLEAN or MAYBE_DIRTY based on its connection state.
* @param {Derived} derived
*/
function update_derived_status(derived) {
if ((derived.f & 512) !== 0 || derived.deps === null) set_signal_status(derived, CLEAN);
else set_signal_status(derived, MAYBE_DIRTY);
}
//#endregion
//#region node_modules/svelte/src/internal/client/reactivity/utils.js
/** @import { Derived, Effect, Value } from '#client' */
/**
* @param {Value[] | null} deps
*/
function clear_marked(deps) {
if (deps === null) return;
for (const dep of deps) {
if ((dep.f & 2) === 0 || (dep.f & 65536) === 0) continue;
dep.f ^= WAS_MARKED;
clear_marked(
/** @type {Derived} */
dep.deps
);
}
}
/**
* @param {Effect} effect
* @param {Set<Effect>} dirty_effects
* @param {Set<Effect>} maybe_dirty_effects
*/
function defer_effect(effect, dirty_effects, maybe_dirty_effects) {
if ((effect.f & 2048) !== 0) dirty_effects.add(effect);
else if ((effect.f & 4096) !== 0) maybe_dirty_effects.add(effect);
clear_marked(effect.deps);
set_signal_status(effect, CLEAN);
}
//#endregion
//#region node_modules/svelte/src/internal/client/reactivity/store.js
/**
* We set this to `true` when updating a store so that we correctly
* schedule effects if the update takes place inside a `$:` effect
*/
var legacy_is_updating_store = false;
//#endregion
//#region node_modules/svelte/src/internal/client/reactivity/batch.js
/** @import { Fork } from 'svelte' */
/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */
/** @type {Set<Batch>} */
var batches = /* @__PURE__ */ new Set();
/** @type {Batch | null} */
var current_batch = null;
/**
* This is needed to avoid overwriting inputs
* @type {Batch | null}
*/
var previous_batch = null;
/**
* When time travelling (i.e. working in one batch, while other batches
* still have ongoing work), we ignore the real values of affected
* signals in favour of their values within the batch
* @type {Map<Value, any> | null}
*/
var batch_values = null;
/** @type {Effect | null} */
var last_scheduled_effect = null;
var is_flushing_sync = false;
var is_processing = false;
/**
* During traversal, this is an array. Newly created effects are (if not immediately
* executed) pushed to this array, rather than going through the scheduling
* rigamarole that would cause another turn of the flush loop.
* @type {Effect[] | null}
*/
var collected_effects = null;
/**
* An array of effects that are marked during traversal as a result of a `set`
* (not `internal_set`) call. These will be added to the next batch and
* trigger another `batch.process()`
* @type {Effect[] | null}
* @deprecated when we get rid of legacy mode and stores, we can get rid of this
*/
var legacy_updates = null;
var flush_count = 0;
var uid = 1;
var Batch = class Batch {
id = uid++;
/**
* The current values of any signals that are updated in this batch.
* Tuple format: [value, is_derived] (note: is_derived is false for deriveds, too, if they were overridden via assignment)
* They keys of this map are identical to `this.#previous`
* @type {Map<Value, [any, boolean]>}
*/
current = /* @__PURE__ */ new Map();
/**
* The values of any signals (sources and deriveds) that are updated in this batch _before_ those updates took place.
* They keys of this map are identical to `this.#current`
* @type {Map<Value, any>}
*/
previous = /* @__PURE__ */ new Map();
/**
* When the batch is committed (and the DOM is updated), we need to remove old branches
* and append new ones by calling the functions added inside (if/each/key/etc) blocks
* @type {Set<(batch: Batch) => void>}
*/
#commit_callbacks = /* @__PURE__ */ new Set();
/**
* If a fork is discarded, we need to destroy any effects that are no longer needed
* @type {Set<(batch: Batch) => void>}
*/
#discard_callbacks = /* @__PURE__ */ new Set();
/**
* Callbacks that should run only when a fork is committed.
* @type {Set<(batch: Batch) => void>}
*/
#fork_commit_callbacks = /* @__PURE__ */ new Set();
/**
* Async effects that are currently in flight
* @type {Map<Effect, number>}
*/
#pending = /* @__PURE__ */ new Map();
/**
* Async effects that are currently in flight, _not_ inside a pending boundary
* @type {Map<Effect, number>}
*/
#blocking_pending = /* @__PURE__ */ new Map();
/**
* A deferred that resolves when the batch is committed, used with `settled()`
* TODO replace with Promise.withResolvers once supported widely enough
* @type {{ promise: Promise<void>, resolve: (value?: any) => void, reject: (reason: unknown) => void } | null}
*/
#deferred = null;
/**
* The root effects that need to be flushed
* @type {Effect[]}
*/
#roots = [];
/**
* Effects created while this batch was active.
* @type {Effect[]}
*/
#new_effects = [];
/**
* Deferred effects (which run after async work has completed) that are DIRTY
* @type {Set<Effect>}
*/
#dirty_effects = /* @__PURE__ */ new Set();
/**
* Deferred effects that are MAYBE_DIRTY
* @type {Set<Effect>}
*/
#maybe_dirty_effects = /* @__PURE__ */ new Set();
/**
* A map of branches that still exist, but will be destroyed when this batch
* is committed — we skip over these during `process`.
* The value contains child effects that were dirty/maybe_dirty before being reset,
* so they can be rescheduled if the branch survives.
* @type {Map<Effect, { d: Effect[], m: Effect[] }>}
*/
#skipped_branches = /* @__PURE__ */ new Map();
/**
* Inverse of #skipped_branches which we need to tell prior batches to unskip them when committing
* @type {Set<Effect>}
*/
#unskipped_branches = /* @__PURE__ */ new Set();
is_fork = false;
#decrement_queued = false;
/** @type {Set<Batch>} */
#blockers = /* @__PURE__ */ new Set();
#is_deferred() {
return this.is_fork || this.#blocking_pending.size > 0;
}
#is_blocked() {
for (const batch of this.#blockers) for (const effect of batch.#blocking_pending.keys()) {
var skipped = false;
var e = effect;
while (e.parent !== null) {
if (this.#skipped_branches.has(e)) {
skipped = true;
break;
}
e = e.parent;
}
if (!skipped) return true;
}
return false;
}
/**
* Add an effect to the #skipped_branches map and reset its children
* @param {Effect} effect
*/
skip_effect(effect) {
if (!this.#skipped_branches.has(effect)) this.#skipped_branches.set(effect, {
d: [],
m: []
});
this.#unskipped_branches.delete(effect);
}
/**
* Remove an effect from the #skipped_branches map and reschedule
* any tracked dirty/maybe_dirty child effects
* @param {Effect} effect
* @param {(e: Effect) => void} callback
*/
unskip_effect(effect, callback = (e) => this.schedule(e)) {
var tracked = this.#skipped_branches.get(effect);
if (tracked) {
this.#skipped_branches.delete(effect);
for (var e of tracked.d) {
set_signal_status(e, DIRTY);
callback(e);
}
for (e of tracked.m) {
set_signal_status(e, MAYBE_DIRTY);
callback(e);
}
}
this.#unskipped_branches.add(effect);
}
#process() {
if (flush_count++ > 1e3) {
batches.delete(this);
infinite_loop_guard();
}
if (!this.#is_deferred()) {
for (const e of this.#dirty_effects) {
this.#maybe_dirty_effects.delete(e);
set_signal_status(e, DIRTY);
this.schedule(e);
}
for (const e of this.#maybe_dirty_effects) {
set_signal_status(e, MAYBE_DIRTY);
this.schedule(e);
}
}
const roots = this.#roots;
this.#roots = [];
this.apply();
/** @type {Effect[]} */
var effects = collected_effects = [];
/** @type {Effect[]} */
var render_effects = [];
/**
* @type {Effect[]}
* @deprecated when we get rid of legacy mode and stores, we can get rid of this
*/
var updates = legacy_updates = [];
for (const root of roots) try {
this.#traverse(root, effects, render_effects);
} catch (e) {
reset_all(root);
throw e;
}
current_batch = null;
if (updates.length > 0) {
var batch = Batch.ensure();
for (const e of updates) batch.schedule(e);
}
collected_effects = null;
legacy_updates = null;
if (this.#is_deferred() || this.#is_blocked()) {
this.#defer_effects(render_effects);
this.#defer_effects(effects);
for (const [e, t] of this.#skipped_branches) reset_branch(e, t);
} else {
if (this.#pending.size === 0) batches.delete(this);
this.#dirty_effects.clear();
this.#maybe_dirty_effects.clear();
for (const fn of this.#commit_callbacks) fn(this);
this.#commit_callbacks.clear();
previous_batch = this;
flush_queued_effects(render_effects);
flush_queued_effects(effects);
previous_batch = null;
this.#deferred?.resolve();
}
var next_batch = current_batch;
if (this.#roots.length > 0) {
const batch = next_batch ??= this;
batch.#roots.push(...this.#roots.filter((r) => !batch.#roots.includes(r)));
}
if (next_batch !== null) {
batches.add(next_batch);
next_batch.#process();
}
if (async_mode_flag && !batches.has(this)) this.#commit();
}
/**
* Traverse the effect tree, executing effects or stashing
* them for later execution as appropriate
* @param {Effect} root
* @param {Effect[]} effects
* @param {Effect[]} render_effects
*/
#traverse(root, effects, render_effects) {
root.f ^= CLEAN;
var effect = root.first;
while (effect !== null) {
var flags = effect.f;
var is_branch = (flags & 96) !== 0;
if (!(is_branch && (flags & 1024) !== 0 || (flags & 8192) !== 0 || this.#skipped_branches.has(effect)) && effect.fn !== null) {
if (is_branch) effect.f ^= CLEAN;
else if ((flags & 4) !== 0) effects.push(effect);
else if (async_mode_flag && (flags & 16777224) !== 0) render_effects.push(effect);
else if (is_dirty(effect)) {
if ((flags & 16) !== 0) this.#maybe_dirty_effects.add(effect);
update_effect(effect);
}
var child = effect.first;
if (child !== null) {
effect = child;
continue;
}
}
while (effect !== null) {
var next = effect.next;
if (next !== null) {
effect = next;
break;
}
effect = effect.parent;
}
}
}
/**
* @param {Effect[]} effects
*/
#defer_effects(effects) {
for (var i = 0; i < effects.length; i += 1) defer_effect(effects[i], this.#dirty_effects, this.#maybe_dirty_effects);
}
/**
* Associate a change to a given source with the current
* batch, noting its previous and current values
* @param {Value} source
* @param {any} value
* @param {boolean} [is_derived]
*/
capture(source, value, is_derived = false) {
if (source.v !== UNINITIALIZED && !this.previous.has(source)) this.previous.set(source, source.v);
if ((source.f & 8388608) === 0) {
this.current.set(source, [value, is_derived]);
batch_values?.set(source, value);
}
if (!this.is_fork) source.v = value;
}
activate() {
current_batch = this;
}
deactivate() {
current_batch = null;
batch_values = null;
}
flush() {
try {
is_processing = true;
current_batch = this;
this.#process();
} finally {
flush_count = 0;
last_scheduled_effect = null;
collected_effects = null;
legacy_updates = null;
is_processing = false;
current_batch = null;
batch_values = null;
old_values.clear();
}
}
discard() {
for (const fn of this.#discard_callbacks) fn(this);
this.#discard_callbacks.clear();
this.#fork_commit_callbacks.clear();
batches.delete(this);
}
/**
* @param {Effect} effect
*/
register_created_effect(effect) {
this.#new_effects.push(effect);
}
#commit() {
for (const batch of batches) {
var is_earlier = batch.id < this.id;
/** @type {Source[]} */
var sources = [];
for (const [source, [value, is_derived]] of this.current) {
if (batch.current.has(source)) {
var batch_value = batch.current.get(source)[0];
if (is_earlier && value !== batch_value) batch.current.set(source, [value, is_derived]);
else continue;
}
sources.push(source);
}
var others = [...batch.current.keys()].filter((s) => !this.current.has(s));
if (others.length === 0) {
if (is_earlier) batch.discard();
} else if (sources.length > 0) {
if (is_earlier) for (const unskipped of this.#unskipped_branches) batch.unskip_effect(unskipped, (e) => {
if ((e.f & 4194320) !== 0) batch.schedule(e);
else batch.#defer_effects([e]);
});
batch.activate();
/** @type {Set<Value>} */
var marked = /* @__PURE__ */ new Set();
/** @type {Map<Reaction, boolean>} */
var checked = /* @__PURE__ */ new Map();
for (var source of sources) mark_effects(source, others, marked, checked);
checked = /* @__PURE__ */ new Map();
var current_unequal = [...batch.current.keys()].filter((c) => this.current.has(c) ? this.current.get(c)[0] !== c : true);
for (const effect of this.#new_effects) if ((effect.f & 155648) === 0 && depends_on(effect, current_unequal, checked)) if ((effect.f & 4194320) !== 0) {
set_signal_status(effect, DIRTY);
batch.schedule(effect);
} else batch.#dirty_effects.add(effect);
if (batch.#roots.length > 0) {
batch.apply();
for (var root of batch.#roots) batch.#traverse(root, [], []);
batch.#roots = [];
}
batch.deactivate();
}
}
for (const batch of batches) if (batch.#blockers.has(this)) {
batch.#blockers.delete(this);
if (batch.#blockers.size === 0 && !batch.#is_deferred()) {
batch.activate();
batch.#process();
}
}
}
/**
* @param {boolean} blocking
* @param {Effect} effect
*/
increment(blocking, effect) {
let pending_count = this.#pending.get(effect) ?? 0;
this.#pending.set(effect, pending_count + 1);
if (blocking) {
let blocking_pending_count = this.#blocking_pending.get(effect) ?? 0;
this.#blocking_pending.set(effect, blocking_pending_count + 1);
}
}
/**
* @param {boolean} blocking
* @param {Effect} effect
* @param {boolean} skip - whether to skip updates (because this is triggered by a stale reaction)
*/
decrement(blocking, effect, skip) {
let pending_count = this.#pending.get(effect) ?? 0;
if (pending_count === 1) this.#pending.delete(effect);
else this.#pending.set(effect, pending_count - 1);
if (blocking) {
let blocking_pending_count = this.#blocking_pending.get(effect) ?? 0;
if (blocking_pending_count === 1) this.#blocking_pending.delete(effect);
else this.#blocking_pending.set(effect, blocking_pending_count - 1);
}
if (this.#decrement_queued || skip) return;
this.#decrement_queued = true;
queue_micro_task(() => {
this.#decrement_queued = false;
this.flush();
});
}
/**
* @param {Set<Effect>} dirty_effects
* @param {Set<Effect>} maybe_dirty_effects
*/
transfer_effects(dirty_effects, maybe_dirty_effects) {
for (const e of dirty_effects) this.#dirty_effects.add(e);
for (const e of maybe_dirty_effects) this.#maybe_dirty_effects.add(e);
dirty_effects.clear();
maybe_dirty_effects.clear();
}
/** @param {(batch: Batch) => void} fn */
oncommit(fn) {
this.#commit_callbacks.add(fn);
}
/** @param {(batch: Batch) => void} fn */
ondiscard(fn) {
this.#discard_callbacks.add(fn);
}
/** @param {(batch: Batch) => void} fn */
on_fork_commit(fn) {
this.#fork_commit_callbacks.add(fn);
}
run_fork_commit_callbacks() {
for (const fn of this.#fork_commit_callbacks) fn(this);
this.#fork_commit_callbacks.clear();
}
settled() {
return (this.#deferred ??= deferred()).promise;
}
static ensure() {
if (current_batch === null) {
const batch = current_batch = new Batch();
if (!is_processing) {
batches.add(current_batch);
if (!is_flushing_sync) queue_micro_task(() => {
if (current_batch !== batch) return;
batch.flush();
});
}
}
return current_batch;
}
apply() {
if (!async_mode_flag || !this.is_fork && batches.size === 1) {
batch_values = null;
return;
}
batch_values = /* @__PURE__ */ new Map();
for (const [source, [value]] of this.current) batch_values.set(source, value);
for (const batch of batches) {
if (batch === this || batch.is_fork) continue;
var intersects = false;
var differs = false;
if (batch.id < this.id) for (const [source, [, is_derived]] of batch.current) {
if (is_derived) continue;
intersects ||= this.current.has(source);
differs ||= !this.current.has(source);
}
if (intersects && differs) this.#blockers.add(batch);
else for (const [source, previous] of batch.previous) if (!batch_values.has(source)) batch_values.set(source, previous);
}
}
/**
*
* @param {Effect} effect
*/
schedule(effect) {
last_scheduled_effect = effect;
if (effect.b?.is_pending && (effect.f & 16777228) !== 0 && (effect.f & 32768) === 0) {
effect.b.defer_effect(effect);
return;
}
var e = effect;
while (e.parent !== null) {
e = e.parent;
var flags = e.f;
if (collected_effects !== null && e === active_effect) {
if (async_mode_flag) return;
if ((active_reaction === null || (active_reaction.f & 2) === 0) && !legacy_is_updating_store) return;
}
if ((flags & 96) !== 0) {
if ((flags & 1024) === 0) return;
e.f ^= CLEAN;
}
}
this.#roots.push(e);
}
};
/**
* Synchronously flush any pending updates.
* Returns void if no callback is provided, otherwise returns the result of calling the callback.
* @template [T=void]
* @param {(() => T) | undefined} [fn]
* @returns {T}
*/
function flushSync(fn) {
var was_flushing_sync = is_flushing_sync;
is_flushing_sync = true;
try {
var result;
if (fn) {
if (current_batch !== null && !current_batch.is_fork) current_batch.flush();
result = fn();
}
while (true) {
flush_tasks();
if (current_batch === null) return result;
current_batch.flush();
}
} finally {
is_flushing_sync = was_flushing_sync;
}
}
function infinite_loop_guard() {
try {
effect_update_depth_exceeded();
} catch (error) {
invoke_error_boundary(error, last_scheduled_effect);
}
}
/** @type {Set<Effect> | null} */
var eager_block_effects = null;
/**
* @param {Array<Effect>} effects
* @returns {void}
*/
function flush_queued_effects(effects) {
var length = effects.length;
if (length === 0) return;
var i = 0;
while (i < length) {
var effect = effects[i++];
if ((effect.f & 24576) === 0 && is_dirty(effect)) {
eager_block_effects = /* @__PURE__ */ new Set();
update_effect(effect);
if (effect.deps === null && effect.first === null && effect.nodes === null && effect.teardown === null && effect.ac === null) unlink_effect(effect);
if (eager_block_effects?.size > 0) {
old_values.clear();
for (const e of eager_block_effects) {
if ((e.f & 24576) !== 0) continue;
/** @type {Effect[]} */
const ordered_effects = [e];
let ancestor = e.parent;
while (ancestor !== null) {
if (eager_block_effects.has(ancestor)) {
eager_block_effects.delete(ancestor);
ordered_effects.push(ancestor);
}
ancestor = ancestor.parent;
}
for (let j = ordered_effects.length - 1; j >= 0; j--) {
const e = ordered_effects[j];
if ((e.f & 24576) !== 0) continue;
update_effect(e);
}
}
eager_block_effects.clear();
}
}
}
eager_block_effects = null;
}
/**
* This is similar to `mark_reactions`, but it only marks async/block effects
* depending on `value` and at least one of the other `sources`, so that
* these effects can re-run after another batch has been committed
* @param {Value} value
* @param {Source[]} sources
* @param {Set<Value>} marked
* @param {Map<Reaction, boolean>} checked
*/
function mark_effects(value, sources, marked, checked) {
if (marked.has(value)) return;
marked.add(value);
if (value.reactions !== null) for (const reaction of value.reactions) {
const flags = reaction.f;
if ((flags & 2) !== 0) mark_effects(reaction, sources, marked, checked);
else if ((flags & 4194320) !== 0 && (flags & 2048) === 0 && depends_on(reaction, sources, checked)) {
set_signal_status(reaction, DIRTY);
schedule_effect(reaction);
}
}
}
/**
* @param {Reaction} reaction
* @param {Source[]} sources
* @param {Map<Reaction, boolean>} checked
*/
function depends_on(reaction, sources, checked) {
const depends = checked.get(reaction);
if (depends !== void 0) return depends;
if (reaction.deps !== null) for (const dep of reaction.deps) {
if (includes.call(sources, dep)) return true;
if ((dep.f & 2) !== 0 && depends_on(dep, sources, checked)) {
checked.set(dep, true);
return true;
}
}
checked.set(reaction, false);
return false;
}
/**
* @param {Effect} effect
* @returns {void}
*/
function schedule_effect(effect) {
/** @type {Batch} */ current_batch.schedule(effect);
}
/**
* Mark all the effects inside a skipped branch CLEAN, so that
* they can be correctly rescheduled later. Tracks dirty and maybe_dirty
* effects so they can be rescheduled if the branch survives.
* @param {Effect} effect
* @param {{ d: Effect[], m: Effect[] }} tracked
*/
function reset_branch(effect, tracked) {
if ((effect.f & 32) !== 0 && (effect.f & 1024) !== 0) return;
if ((effect.f & 2048) !== 0) tracked.d.push(effect);
else if ((effect.f & 4096) !== 0) tracked.m.push(effect);
set_signal_status(effect, CLEAN);
var e = effect.first;
while (e !== null) {
reset_branch(e, tracked);
e = e.next;
}
}
/**
* Mark an entire effect tree clean following an error
* @param {Effect} effect
*/
function reset_all(effect) {
set_signal_status(effect, CLEAN);
var e = effect.first;
while (e !== null) {
reset_all(e);
e = e.next;
}
}
//#endregion
//#region node_modules/svelte/src/reactivity/create-subscriber.js
/**
* Returns a `subscribe` function that integrates external event-based systems with Svelte's reactivity.
* It's particularly useful for integrating with web APIs like `MediaQuery`, `IntersectionObserver`, or `WebSocket`.
*
* If `subscribe` is called inside an effect (including indirectly, for example inside a getter),
* the `start` callback will be called with an `update` function. Whenever `update` is called, the effect re-runs.
*
* If `start` returns a cleanup function, it will be called when the effect is destroyed.
*
* If `subscribe` is called in multiple effects, `start` will only be called once as long as the effects
* are active, and the returned teardown function will only be called when all effects are destroyed.
*
* It's best understood with an example. Here's an implementation of [`MediaQuery`](https://svelte.dev/docs/svelte/svelte-reactivity#MediaQuery):
*
* ```js
* import { createSubscriber } from 'svelte/reactivity';
* import { on } from 'svelte/events';
*
* export class MediaQuery {
* #query;
* #subscribe;
*
* constructor(query) {
* this.#query = window.matchMedia(`(${query})`);
*
* this.#subscribe = createSubscriber((update) => {
* // when the `change` event occurs, re-run any effects that read `this.current`
* const off = on(this.#query, 'change', update);
*
* // stop listening when all the effects are destroyed
* return () => off();
* });
* }
*
* get current() {
* // This makes the getter reactive, if read in an effect
* this.#subscribe();
*
* // Return the current state of the query, whether or not we're in an effect
* return this.#query.matches;
* }
* }
* ```
* @param {(update: () => void) => (() => void) | void} start
* @since 5.7.0
*/
function createSubscriber(start) {
let subscribers = 0;
let version = source(0);
/** @type {(() => void) | void} */
let stop;
return () => {
if (effect_tracking()) {
get(version);
render_effect(() => {
if (subscribers === 0) stop = untrack(() => start(() => increment(version)));
subscribers += 1;
return () => {
queue_micro_task(() => {
subscribers -= 1;
if (subscribers === 0) {
stop?.();
stop = void 0;
increment(version);
}
});
};
});
}
};
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/blocks/boundary.js
/** @import { Effect, Source, TemplateNode, } from '#client' */
/**
* @typedef {{
* onerror?: (error: unknown, reset: () => void) => void;
* failed?: (anchor: Node, error: () => unknown, reset: () => () => void) => void;
* pending?: (anchor: Node) => void;
* }} BoundaryProps
*/
var flags = EFFECT_TRANSPARENT | EFFECT_PRESERVED;
/**
* @param {TemplateNode} node
* @param {BoundaryProps} props
* @param {((anchor: Node) => void)} children
* @param {((error: unknown) => unknown) | undefined} [transform_error]
* @returns {void}
*/
function boundary(node, props, children, transform_error) {
new Boundary(node, props, children, transform_error);
}
var Boundary = class {
/** @type {Boundary | null} */
parent;
is_pending = false;
/**
* API-level transformError transform function. Transforms errors before they reach the `failed` snippet.
* Inherited from parent boundary, or defaults to identity.
* @type {(error: unknown) => unknown}
*/
transform_error;
/** @type {TemplateNode} */
#anchor;
/** @type {TemplateNode | null} */
#hydrate_open = hydrating ? hydrate_node : null;
/** @type {BoundaryProps} */
#props;
/** @type {((anchor: Node) => void)} */
#children;
/** @type {Effect} */
#effect;
/** @type {Effect | null} */
#main_effect = null;
/** @type {Effect | null} */
#pending_effect = null;
/** @type {Effect | null} */
#failed_effect = null;
/** @type {DocumentFragment | null} */
#offscreen_fragment = null;
#local_pending_count = 0;
#pending_count = 0;
#pending_count_update_queued = false;
/** @type {Set<Effect>} */
#dirty_effects = /* @__PURE__ */ new Set();
/** @type {Set<Effect>} */
#maybe_dirty_effects = /* @__PURE__ */ new Set();
/**
* A source containing the number of pending async deriveds/expressions.
* Only created if `$effect.pending()` is used inside the boundary,
* otherwise updating the source results in needless `Batch.ensure()`
* calls followed by no-op flushes
* @type {Source<number> | null}
*/
#effect_pending = null;
#effect_pending_subscriber = createSubscriber(() => {
this.#effect_pending = source(this.#local_pending_count);
return () => {
this.#effect_pending = null;
};
});
/**
* @param {TemplateNode} node
* @param {BoundaryProps} props
* @param {((anchor: Node) => void)} children
* @param {((error: unknown) => unknown) | undefined} [transform_error]
*/
constructor(node, props, children, transform_error) {
this.#anchor = node;
this.#props = props;
this.#children = (anchor) => {
var effect = active_effect;
effect.b = this;
effect.f |= 128;
children(anchor);
};
this.parent = active_effect.b;
this.transform_error = transform_error ?? this.parent?.transform_error ?? ((e) => e);
this.#effect = block(() => {
if (hydrating) {
const comment = this.#hydrate_open;
hydrate_next();
const server_rendered_pending = comment.data === "[!";
if (comment.data.startsWith("[?")) {
const serialized_error = JSON.parse(comment.data.slice(2));
this.#hydrate_failed_content(serialized_error);
} else if (server_rendered_pending) this.#hydrate_pending_content();
else this.#hydrate_resolved_content();
} else this.#render();
}, flags);
if (hydrating) this.#anchor = hydrate_node;
}
#hydrate_resolved_content() {
try {
this.#main_effect = branch(() => this.#children(this.#anchor));
} catch (error) {
this.error(error);
}
}
/**
* @param {unknown} error The deserialized error from the server's hydration comment
*/
#hydrate_failed_content(error) {
const failed = this.#props.failed;
if (!failed) return;
this.#failed_effect = branch(() => {
failed(this.#anchor, () => error, () => () => {});
});
}
#hydrate_pending_content() {
const pending = this.#props.pending;
if (!pending) return;
this.is_pending = true;
this.#pending_effect = branch(() => pending(this.#anchor));
queue_micro_task(() => {
var fragment = this.#offscreen_fragment = document.createDocumentFragment();
var anchor = create_text();
fragment.append(anchor);
this.#main_effect = this.#run(() => {
return branch(() => this.#children(anchor));
});
if (this.#pending_count === 0) {
this.#anchor.before(fragment);
this.#offscreen_fragment = null;
pause_effect(this.#pending_effect, () => {
this.#pending_effect = null;
});
this.#resolve(current_batch);
}
});
}
#render() {
try {
this.is_pending = this.has_pending_snippet();
this.#pending_count = 0;
this.#local_pending_count = 0;
this.#main_effect = branch(() => {
this.#children(this.#anchor);
});
if (this.#pending_count > 0) {
var fragment = this.#offscreen_fragment = document.createDocumentFragment();
move_effect(this.#main_effect, fragment);
const pending = this.#props.pending;
this.#pending_effect = branch(() => pending(this.#anchor));
} else this.#resolve(current_batch);
} catch (error) {
this.error(error);
}
}
/**
* @param {Batch} batch
*/
#resolve(batch) {
this.is_pending = false;
batch.transfer_effects(this.#dirty_effects, this.#maybe_dirty_effects);
}
/**
* Defer an effect inside a pending boundary until the boundary resolves
* @param {Effect} effect
*/
defer_effect(effect) {
defer_effect(effect, this.#dirty_effects, this.#maybe_dirty_effects);
}
/**
* Returns `false` if the effect exists inside a boundary whose pending snippet is shown
* @returns {boolean}
*/
is_rendered() {
return !this.is_pending && (!this.parent || this.parent.is_rendered());
}
has_pending_snippet() {
return !!this.#props.pending;
}
/**
* @template T
* @param {() => T} fn
*/
#run(fn) {
var previous_effect = active_effect;
var previous_reaction = active_reaction;
var previous_ctx = component_context;
set_active_effect(this.#effect);
set_active_reaction(this.#effect);
set_component_context(this.#effect.ctx);
try {
Batch.ensure();
return fn();
} catch (e) {
handle_error(e);
return null;
} finally {
set_active_effect(previous_effect);
set_active_reaction(previous_reaction);
set_component_context(previous_ctx);
}
}
/**
* Updates the pending count associated with the currently visible pending snippet,
* if any, such that we can replace the snippet with content once work is done
* @param {1 | -1} d
* @param {Batch} batch
*/
#update_pending_count(d, batch) {
if (!this.has_pending_snippet()) {
if (this.parent) this.parent.#update_pending_count(d, batch);
return;
}
this.#pending_count += d;
if (this.#pending_count === 0) {
this.#resolve(batch);
if (this.#pending_effect) pause_effect(this.#pending_effect, () => {
this.#pending_effect = null;
});
if (this.#offscreen_fragment) {
this.#anchor.before(this.#offscreen_fragment);
this.#offscreen_fragment = null;
}
}
}
/**
* Update the source that powers `$effect.pending()` inside this boundary,
* and controls when the current `pending` snippet (if any) is removed.
* Do not call from inside the class
* @param {1 | -1} d
* @param {Batch} batch
*/
update_pending_count(d, batch) {
this.#update_pending_count(d, batch);
this.#local_pending_count += d;
if (!this.#effect_pending || this.#pending_count_update_queued) return;
this.#pending_count_update_queued = true;
queue_micro_task(() => {
this.#pending_count_update_queued = false;
if (this.#effect_pending) internal_set(this.#effect_pending, this.#local_pending_count);
});
}
get_effect_pending() {
this.#effect_pending_subscriber();
return get(this.#effect_pending);
}
/** @param {unknown} error */
error(error) {
if (!this.#props.onerror && !this.#props.failed) throw error;
if (current_batch?.is_fork) {
if (this.#main_effect) current_batch.skip_effect(this.#main_effect);
if (this.#pending_effect) current_batch.skip_effect(this.#pending_effect);
if (this.#failed_effect) current_batch.skip_effect(this.#failed_effect);
current_batch.on_fork_commit(() => {
this.#handle_error(error);
});
} else this.#handle_error(error);
}
/**
* @param {unknown} error
*/
#handle_error(error) {
if (this.#main_effect) {
destroy_effect(this.#main_effect);
this.#main_effect = null;
}
if (this.#pending_effect) {
destroy_effect(this.#pending_effect);
this.#pending_effect = null;
}
if (this.#failed_effect) {
destroy_effect(this.#failed_effect);
this.#failed_effect = null;
}
if (hydrating) {
set_hydrate_node(this.#hydrate_open);
next();
set_hydrate_node(skip_nodes());
}
var onerror = this.#props.onerror;
let failed = this.#props.failed;
var did_reset = false;
var calling_on_error = false;
const reset = () => {
if (did_reset) {
svelte_boundary_reset_noop();
return;
}
did_reset = true;
if (calling_on_error) svelte_boundary_reset_onerror();
if (this.#failed_effect !== null) pause_effect(this.#failed_effect, () => {
this.#failed_effect = null;
});
this.#run(() => {
this.#render();
});
};
/** @param {unknown} transformed_error */
const handle_error_result = (transformed_error) => {
try {
calling_on_error = true;
onerror?.(transformed_error, reset);
calling_on_error = false;
} catch (error) {
invoke_error_boundary(error, this.#effect && this.#effect.parent);
}
if (failed) this.#failed_effect = this.#run(() => {
try {
return branch(() => {
var effect = active_effect;
effect.b = this;
effect.f |= 128;
failed(this.#anchor, () => transformed_error, () => reset);
});
} catch (error) {
invoke_error_boundary(error, this.#effect.parent);
return null;
}
});
};
queue_micro_task(() => {
/** @type {unknown} */
var result;
try {
result = this.transform_error(error);
} catch (e) {
invoke_error_boundary(e, this.#effect && this.#effect.parent);
return;
}
if (result !== null && typeof result === "object" && typeof result.then === "function")
/** @type {any} */ result.then(
handle_error_result,
/** @param {unknown} e */
(e) => invoke_error_boundary(e, this.#effect && this.#effect.parent)
);
else handle_error_result(result);
});
}
};
//#endregion
//#region node_modules/svelte/src/internal/client/reactivity/async.js
/** @import { Blocker, Effect, Value } from '#client' */
/**
* @param {Blocker[]} blockers
* @param {Array<() => any>} sync
* @param {Array<() => Promise<any>>} async
* @param {(values: Value[]) => any} fn
*/
function flatten(blockers, sync, async, fn) {
const d = is_runes() ? derived : derived_safe_equal;
var pending = blockers.filter((b) => !b.settled);
if (async.length === 0 && pending.length === 0) {
fn(sync.map(d));
return;
}
var parent = active_effect;
var restore = capture();
var blocker_promise = pending.length === 1 ? pending[0].promise : pending.length > 1 ? Promise.all(pending.map((b) => b.promise)) : null;
/** @param {Value[]} values */
function finish(values) {
restore();
try {
fn(values);
} catch (error) {
if ((parent.f & 16384) === 0) invoke_error_boundary(error, parent);
}
unset_context();
}
if (async.length === 0) {
/** @type {Promise<any>} */ blocker_promise.then(() => finish(sync.map(d)));
return;
}
var decrement_pending = increment_pending();
function run() {
Promise.all(async.map((expression) => /* @__PURE__ */ async_derived(expression))).then((result) => finish([...sync.map(d), ...result])).catch((error) => invoke_error_boundary(error, parent)).finally(() => decrement_pending());
}
if (blocker_promise) blocker_promise.then(() => {
restore();
run();
unset_context();
});
else run();
}
/**
* Captures the current effect context so that we can restore it after
* some asynchronous work has happened (so that e.g. `await a + b`
* causes `b` to be registered as a dependency).
*/
function capture() {
var previous_effect = active_effect;
var previous_reaction = active_reaction;
var previous_component_context = component_context;
var previous_batch = current_batch;
return function restore(activate_batch = true) {
set_active_effect(previous_effect);
set_active_reaction(previous_reaction);
set_component_context(previous_component_context);
if (activate_batch && (previous_effect.f & 16384) === 0) {
previous_batch?.activate();
previous_batch?.apply();
}
};
}
function unset_context(deactivate_batch = true) {
set_active_effect(null);
set_active_reaction(null);
set_component_context(null);
if (deactivate_batch) current_batch?.deactivate();
}
/**
* @returns {(skip?: boolean) => void}
*/
function increment_pending() {
var effect = active_effect;
var boundary = effect.b;
var batch = current_batch;
var blocking = boundary.is_rendered();
boundary.update_pending_count(1, batch);
batch.increment(blocking, effect);
return (skip = false) => {
boundary.update_pending_count(-1, batch);
batch.decrement(blocking, effect, skip);
};
}
/**
* @template V
* @param {() => V} fn
* @returns {Derived<V>}
*/
/* @__NO_SIDE_EFFECTS__ */
function derived(fn) {
var flags = 2 | DIRTY;
if (active_effect !== null) active_effect.f |= EFFECT_PRESERVED;
return {
ctx: component_context,
deps: null,
effects: null,
equals,
f: flags,
fn,
reactions: null,
rv: 0,
v: UNINITIALIZED,
wv: 0,
parent: active_effect,
ac: null
};
}
/**
* @template V
* @param {() => V | Promise<V>} fn
* @param {string} [label]
* @param {string} [location] If provided, print a warning if the value is not read immediately after update
* @returns {Promise<Source<V>>}
*/
/* @__NO_SIDE_EFFECTS__ */
function async_derived(fn, label, location) {
let parent = active_effect;
if (parent === null) async_derived_orphan();
var promise = void 0;
var signal = source(UNINITIALIZED);
var should_suspend = !active_reaction;
/** @type {Map<Batch, ReturnType<typeof deferred<V>>>} */
var deferreds = /* @__PURE__ */ new Map();
async_effect(() => {
var effect = active_effect;
/** @type {ReturnType<typeof deferred<V>>} */
var d = deferred();
promise = d.promise;
try {
Promise.resolve(fn()).then(d.resolve, d.reject).finally(unset_context);
} catch (error) {
d.reject(error);
unset_context();
}
var batch = current_batch;
if (should_suspend) {
if ((effect.f & 32768) !== 0) var decrement_pending = increment_pending();
if (parent.b.is_rendered()) {
deferreds.get(batch)?.reject(STALE_REACTION);
deferreds.delete(batch);
} else {
for (const d of deferreds.values()) d.reject(STALE_REACTION);
deferreds.clear();
}
deferreds.set(batch, d);
}
/**
* @param {any} value
* @param {unknown} error
*/
const handler = (value, error = void 0) => {
if (decrement_pending) decrement_pending(error === STALE_REACTION);
if (error === STALE_REACTION || (effect.f & 16384) !== 0) return;
batch.activate();
if (error) {
signal.f |= ERROR_VALUE;
internal_set(signal, error);
} else {
if ((signal.f & 8388608) !== 0) signal.f ^= ERROR_VALUE;
internal_set(signal, value);
for (const [b, d] of deferreds) {
deferreds.delete(b);
if (b === batch) break;
d.reject(STALE_REACTION);
}
}
batch.deactivate();
};
d.promise.then(handler, (e) => handler(null, e || "unknown"));
});
teardown(() => {
for (const d of deferreds.values()) d.reject(STALE_REACTION);
});
return new Promise((fulfil) => {
/** @param {Promise<V>} p */
function next(p) {
function go() {
if (p === promise) fulfil(signal);
else next(promise);
}
p.then(go, go);
}
next(promise);
});
}
/**
* @template V
* @param {() => V} fn
* @returns {Derived<V>}
*/
/* @__NO_SIDE_EFFECTS__ */
function user_derived(fn) {
const d = /* @__PURE__ */ derived(fn);
if (!async_mode_flag) push_reaction_value(d);
return d;
}
/**
* @template V
* @param {() => V} fn
* @returns {Derived<V>}
*/
/* @__NO_SIDE_EFFECTS__ */
function derived_safe_equal(fn) {
const signal = /* @__PURE__ */ derived(fn);
signal.equals = safe_equals;
return signal;
}
/**
* @param {Derived} derived
* @returns {void}
*/
function destroy_derived_effects(derived) {
var effects = derived.effects;
if (effects !== null) {
derived.effects = null;
for (var i = 0; i < effects.length; i += 1) destroy_effect(effects[i]);
}
}
/**
* @template T
* @param {Derived} derived
* @returns {T}
*/
function execute_derived(derived) {
var value;
var prev_active_effect = active_effect;
var parent = derived.parent;
if (!is_destroying_effect && parent !== null && (parent.f & 24576) !== 0) {
derived_inert();
return derived.v;
}
set_active_effect(parent);
try {
derived.f &= ~WAS_MARKED;
destroy_derived_effects(derived);
value = update_reaction(derived);
} finally {
set_active_effect(prev_active_effect);
}
return value;
}
/**
* @param {Derived} derived
* @returns {void}
*/
function update_derived(derived) {
var value = execute_derived(derived);
if (!derived.equals(value)) {
derived.wv = increment_write_version();
if (!current_batch?.is_fork || derived.deps === null) {
if (current_batch !== null) current_batch.capture(derived, value, true);
else derived.v = value;
if (derived.deps === null) {
set_signal_status(derived, CLEAN);
return;
}
}
}
if (is_destroying_effect) return;
if (batch_values !== null) {
if (effect_tracking() || current_batch?.is_fork) batch_values.set(derived, value);
} else update_derived_status(derived);
}
/**
* @param {Derived} derived
*/
function freeze_derived_effects(derived) {
if (derived.effects === null) return;
for (const e of derived.effects) if (e.teardown || e.ac) {
e.teardown?.();
e.ac?.abort(STALE_REACTION);
e.teardown = noop;
e.ac = null;
remove_reactions(e, 0);
destroy_effect_children(e);
}
}
/**
* @param {Derived} derived
*/
function unfreeze_derived_effects(derived) {
if (derived.effects === null) return;
for (const e of derived.effects) if (e.teardown) update_effect(e);
}
//#endregion
//#region node_modules/svelte/src/internal/client/reactivity/sources.js
/** @import { Derived, Effect, Source, Value } from '#client' */
/** @type {Set<any>} */
var eager_effects = /* @__PURE__ */ new Set();
/** @type {Map<Source, any>} */
var old_values = /* @__PURE__ */ new Map();
var eager_effects_deferred = false;
/**
* @template V
* @param {V} v
* @param {Error | null} [stack]
* @returns {Source<V>}
*/
function source(v, stack) {
return {
f: 0,
v,
reactions: null,
equals,
rv: 0,
wv: 0
};
}
/**
* @template V
* @param {V} v
* @param {Error | null} [stack]
*/
/* @__NO_SIDE_EFFECTS__ */
function state(v, stack) {
const s = source(v, stack);
push_reaction_value(s);
return s;
}
/**
* @template V
* @param {V} initial_value
* @param {boolean} [immutable]
* @returns {Source<V>}
*/
/* @__NO_SIDE_EFFECTS__ */
function mutable_source(initial_value, immutable = false, trackable = true) {
const s = source(initial_value);
if (!immutable) s.equals = safe_equals;
if (legacy_mode_flag && trackable && component_context !== null && component_context.l !== null) (component_context.l.s ??= []).push(s);
return s;
}
/**
* @template V
* @param {Source<V>} source
* @param {V} value
* @param {boolean} [should_proxy]
* @returns {V}
*/
function set(source, value, should_proxy = false) {
if (active_reaction !== null && (!untracking || (active_reaction.f & 131072) !== 0) && is_runes() && (active_reaction.f & 4325394) !== 0 && (current_sources === null || !includes.call(current_sources, source))) state_unsafe_mutation();
return internal_set(source, should_proxy ? proxy(value) : value, legacy_updates);
}
/**
* @template V
* @param {Source<V>} source
* @param {V} value
* @param {Effect[] | null} [updated_during_traversal]
* @returns {V}
*/
function internal_set(source, value, updated_during_traversal = null) {
if (!source.equals(value)) {
old_values.set(source, is_destroying_effect ? value : source.v);
var batch = Batch.ensure();
batch.capture(source, value);
if ((source.f & 2) !== 0) {
const derived = source;
if ((source.f & 2048) !== 0) execute_derived(derived);
if (batch_values === null) update_derived_status(derived);
}
source.wv = increment_write_version();
mark_reactions(source, DIRTY, updated_during_traversal);
if (is_runes() && active_effect !== null && (active_effect.f & 1024) !== 0 && (active_effect.f & 96) === 0) if (untracked_writes === null) set_untracked_writes([source]);
else untracked_writes.push(source);
if (!batch.is_fork && eager_effects.size > 0 && !eager_effects_deferred) flush_eager_effects();
}
return value;
}
function flush_eager_effects() {
eager_effects_deferred = false;
for (const effect of eager_effects) {
if ((effect.f & 1024) !== 0) set_signal_status(effect, MAYBE_DIRTY);
if (is_dirty(effect)) update_effect(effect);
}
eager_effects.clear();
}
/**
* Silently (without using `get`) increment a source
* @param {Source<number>} source
*/
function increment(source) {
set(source, source.v + 1);
}
/**
* @param {Value} signal
* @param {number} status should be DIRTY or MAYBE_DIRTY
* @param {Effect[] | null} updated_during_traversal
* @returns {void}
*/
function mark_reactions(signal, status, updated_during_traversal) {
var reactions = signal.reactions;
if (reactions === null) return;
var runes = is_runes();
var length = reactions.length;
for (var i = 0; i < length; i++) {
var reaction = reactions[i];
var flags = reaction.f;
if (!runes && reaction === active_effect) continue;
var not_dirty = (flags & DIRTY) === 0;
if (not_dirty) set_signal_status(reaction, status);
if ((flags & 2) !== 0) {
var derived = reaction;
batch_values?.delete(derived);
if ((flags & 65536) === 0) {
if (flags & 512 && (active_effect === null || (active_effect.f & 2097152) === 0)) reaction.f |= WAS_MARKED;
mark_reactions(derived, MAYBE_DIRTY, updated_during_traversal);
}
} else if (not_dirty) {
var effect = reaction;
if ((flags & 16) !== 0 && eager_block_effects !== null) eager_block_effects.add(effect);
if (updated_during_traversal !== null) updated_during_traversal.push(effect);
else schedule_effect(effect);
}
}
}
/**
* @template T
* @param {T} value
* @returns {T}
*/
function proxy(value) {
if (typeof value !== "object" || value === null || STATE_SYMBOL in value) return value;
const prototype = get_prototype_of(value);
if (prototype !== object_prototype && prototype !== array_prototype) return value;
/** @type {Map<any, Source<any>>} */
var sources = /* @__PURE__ */ new Map();
var is_proxied_array = is_array(value);
var version = /* @__PURE__ */ state(0);
var stack = null;
var parent_version = update_version;
/**
* Executes the proxy in the context of the reaction it was originally created in, if any
* @template T
* @param {() => T} fn
*/
var with_parent = (fn) => {
if (update_version === parent_version) return fn();
var reaction = active_reaction;
var version = update_version;
set_active_reaction(null);
set_update_version(parent_version);
var result = fn();
set_active_reaction(reaction);
set_update_version(version);
return result;
};
if (is_proxied_array) sources.set("length", /* @__PURE__ */ state(
/** @type {any[]} */
value.length,
stack
));
return new Proxy(value, {
defineProperty(_, prop, descriptor) {
if (!("value" in descriptor) || descriptor.configurable === false || descriptor.enumerable === false || descriptor.writable === false) state_descriptors_fixed();
var s = sources.get(prop);
if (s === void 0) with_parent(() => {
var s = /* @__PURE__ */ state(descriptor.value, stack);
sources.set(prop, s);
return s;
});
else set(s, descriptor.value, true);
return true;
},
deleteProperty(target, prop) {
var s = sources.get(prop);
if (s === void 0) {
if (prop in target) {
const s = with_parent(() => /* @__PURE__ */ state(UNINITIALIZED, stack));
sources.set(prop, s);
increment(version);
}
} else {
set(s, UNINITIALIZED);
increment(version);
}
return true;
},
get(target, prop, receiver) {
if (prop === STATE_SYMBOL) return value;
var s = sources.get(prop);
var exists = prop in target;
if (s === void 0 && (!exists || get_descriptor(target, prop)?.writable)) {
s = with_parent(() => {
return /* @__PURE__ */ state(proxy(exists ? target[prop] : UNINITIALIZED), stack);
});
sources.set(prop, s);
}
if (s !== void 0) {
var v = get(s);
return v === UNINITIALIZED ? void 0 : v;
}
return Reflect.get(target, prop, receiver);
},
getOwnPropertyDescriptor(target, prop) {
var descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
if (descriptor && "value" in descriptor) {
var s = sources.get(prop);
if (s) descriptor.value = get(s);
} else if (descriptor === void 0) {
var source = sources.get(prop);
var value = source?.v;
if (source !== void 0 && value !== UNINITIALIZED) return {
enumerable: true,
configurable: true,
value,
writable: true
};
}
return descriptor;
},
has(target, prop) {
if (prop === STATE_SYMBOL) return true;
var s = sources.get(prop);
var has = s !== void 0 && s.v !== UNINITIALIZED || Reflect.has(target, prop);
if (s !== void 0 || active_effect !== null && (!has || get_descriptor(target, prop)?.writable)) {
if (s === void 0) {
s = with_parent(() => {
return /* @__PURE__ */ state(has ? proxy(target[prop]) : UNINITIALIZED, stack);
});
sources.set(prop, s);
}
if (get(s) === UNINITIALIZED) return false;
}
return has;
},
set(target, prop, value, receiver) {
var s = sources.get(prop);
var has = prop in target;
if (is_proxied_array && prop === "length") for (var i = value; i < s.v; i += 1) {
var other_s = sources.get(i + "");
if (other_s !== void 0) set(other_s, UNINITIALIZED);
else if (i in target) {
other_s = with_parent(() => /* @__PURE__ */ state(UNINITIALIZED, stack));
sources.set(i + "", other_s);
}
}
if (s === void 0) {
if (!has || get_descriptor(target, prop)?.writable) {
s = with_parent(() => /* @__PURE__ */ state(void 0, stack));
set(s, proxy(value));
sources.set(prop, s);
}
} else {
has = s.v !== UNINITIALIZED;
var p = with_parent(() => proxy(value));
set(s, p);
}
var descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
if (descriptor?.set) descriptor.set.call(receiver, value);
if (!has) {
if (is_proxied_array && typeof prop === "string") {
var ls = sources.get("length");
var n = Number(prop);
if (Number.isInteger(n) && n >= ls.v) set(ls, n + 1);
}
increment(version);
}
return true;
},
ownKeys(target) {
get(version);
var own_keys = Reflect.ownKeys(target).filter((key) => {
var source = sources.get(key);
return source === void 0 || source.v !== UNINITIALIZED;
});
for (var [key, source] of sources) if (source.v !== UNINITIALIZED && !(key in target)) own_keys.push(key);
return own_keys;
},
setPrototypeOf() {
state_prototype_fixed();
}
});
}
/**
* @param {any} value
*/
function get_proxied_value(value) {
try {
if (value !== null && typeof value === "object" && STATE_SYMBOL in value) return value[STATE_SYMBOL];
} catch {}
return value;
}
/**
* @param {any} a
* @param {any} b
*/
function is(a, b) {
return Object.is(get_proxied_value(a), get_proxied_value(b));
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/operations.js
/** @import { Effect, TemplateNode } from '#client' */
/** @type {Window} */
var $window;
/** @type {boolean} */
var is_firefox;
/** @type {() => Node | null} */
var first_child_getter;
/** @type {() => Node | null} */
var next_sibling_getter;
/**
* Initialize these lazily to avoid issues when using the runtime in a server context
* where these globals are not available while avoiding a separate server entry point
*/
function init_operations() {
if ($window !== void 0) return;
$window = window;
is_firefox = /Firefox/.test(navigator.userAgent);
var element_prototype = Element.prototype;
var node_prototype = Node.prototype;
var text_prototype = Text.prototype;
first_child_getter = get_descriptor(node_prototype, "firstChild").get;
next_sibling_getter = get_descriptor(node_prototype, "nextSibling").get;
if (is_extensible(element_prototype)) {
element_prototype.__click = void 0;
element_prototype.__className = void 0;
element_prototype.__attributes = null;
element_prototype.__style = void 0;
element_prototype.__e = void 0;
}
if (is_extensible(text_prototype)) text_prototype.__t = void 0;
}
/**
* @param {string} value
* @returns {Text}
*/
function create_text(value = "") {
return document.createTextNode(value);
}
/**
* @template {Node} N
* @param {N} node
*/
/* @__NO_SIDE_EFFECTS__ */
function get_first_child(node) {
return first_child_getter.call(node);
}
/**
* @template {Node} N
* @param {N} node
*/
/* @__NO_SIDE_EFFECTS__ */
function get_next_sibling(node) {
return next_sibling_getter.call(node);
}
/**
* Don't mark this as side-effect-free, hydration needs to walk all nodes
* @template {Node} N
* @param {N} node
* @param {boolean} is_text
* @returns {TemplateNode | null}
*/
function child(node, is_text) {
if (!hydrating) return /* @__PURE__ */ get_first_child(node);
var child = /* @__PURE__ */ get_first_child(hydrate_node);
if (child === null) child = hydrate_node.appendChild(create_text());
else if (is_text && child.nodeType !== 3) {
var text = create_text();
child?.before(text);
set_hydrate_node(text);
return text;
}
if (is_text) merge_text_nodes(child);
set_hydrate_node(child);
return child;
}
/**
* Don't mark this as side-effect-free, hydration needs to walk all nodes
* @param {TemplateNode} node
* @param {boolean} [is_text]
* @returns {TemplateNode | null}
*/
function first_child(node, is_text = false) {
if (!hydrating) {
var first = /* @__PURE__ */ get_first_child(node);
if (first instanceof Comment && first.data === "") return /* @__PURE__ */ get_next_sibling(first);
return first;
}
if (is_text) {
if (hydrate_node?.nodeType !== 3) {
var text = create_text();
hydrate_node?.before(text);
set_hydrate_node(text);
return text;
}
merge_text_nodes(hydrate_node);
}
return hydrate_node;
}
/**
* Don't mark this as side-effect-free, hydration needs to walk all nodes
* @param {TemplateNode} node
* @param {number} count
* @param {boolean} is_text
* @returns {TemplateNode | null}
*/
function sibling(node, count = 1, is_text = false) {
let next_sibling = hydrating ? hydrate_node : node;
var last_sibling;
while (count--) {
last_sibling = next_sibling;
next_sibling = /* @__PURE__ */ get_next_sibling(next_sibling);
}
if (!hydrating) return next_sibling;
if (is_text) {
if (next_sibling?.nodeType !== 3) {
var text = create_text();
if (next_sibling === null) last_sibling?.after(text);
else next_sibling.before(text);
set_hydrate_node(text);
return text;
}
merge_text_nodes(next_sibling);
}
set_hydrate_node(next_sibling);
return next_sibling;
}
/**
* @template {Node} N
* @param {N} node
* @returns {void}
*/
function clear_text_content(node) {
node.textContent = "";
}
/**
* Returns `true` if we're updating the current block, for example `condition` in
* an `{#if condition}` block just changed. In this case, the branch should be
* appended (or removed) at the same time as other updates within the
* current `<svelte:boundary>`
*/
function should_defer_append() {
if (!async_mode_flag) return false;
if (eager_block_effects !== null) return false;
return (active_effect.f & REACTION_RAN) !== 0;
}
/**
* @template {keyof HTMLElementTagNameMap | string} T
* @param {T} tag
* @param {string} [namespace]
* @param {string} [is]
* @returns {T extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[T] : Element}
*/
function create_element(tag, namespace, is) {
let options = is ? { is } : void 0;
return document.createElementNS(namespace ?? "http://www.w3.org/1999/xhtml", tag, options);
}
/**
* Browsers split text nodes larger than 65536 bytes when parsing.
* For hydration to succeed, we need to stitch them back together
* @param {Text} text
*/
function merge_text_nodes(text) {
if (text.nodeValue.length < 65536) return;
let next = text.nextSibling;
while (next !== null && next.nodeType === 3) {
next.remove();
/** @type {string} */ text.nodeValue += next.nodeValue;
next = text.nextSibling;
}
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/elements/misc.js
/**
* The child of a textarea actually corresponds to the defaultValue property, so we need
* to remove it upon hydration to avoid a bug when someone resets the form value.
* @param {HTMLTextAreaElement} dom
* @returns {void}
*/
function remove_textarea_child(dom) {
if (hydrating && /* @__PURE__ */ get_first_child(dom) !== null) clear_text_content(dom);
}
var listening_to_form_reset = false;
function add_form_reset_listener() {
if (!listening_to_form_reset) {
listening_to_form_reset = true;
document.addEventListener("reset", (evt) => {
Promise.resolve().then(() => {
if (!evt.defaultPrevented) for (const e of evt.target.elements) e.__on_r?.();
});
}, { capture: true });
}
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/elements/bindings/shared.js
/**
* @template T
* @param {() => T} fn
*/
function without_reactive_context(fn) {
var previous_reaction = active_reaction;
var previous_effect = active_effect;
set_active_reaction(null);
set_active_effect(null);
try {
return fn();
} finally {
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}
}
/**
* Listen to the given event, and then instantiate a global form reset listener if not already done,
* to notify all bindings when the form is reset
* @param {HTMLElement} element
* @param {string} event
* @param {(is_reset?: true) => void} handler
* @param {(is_reset?: true) => void} [on_reset]
*/
function listen_to_event_and_reset_event(element, event, handler, on_reset = handler) {
element.addEventListener(event, () => without_reactive_context(handler));
const prev = element.__on_r;
if (prev) element.__on_r = () => {
prev();
on_reset(true);
};
else element.__on_r = () => on_reset(true);
add_form_reset_listener();
}
//#endregion
//#region node_modules/svelte/src/internal/client/reactivity/effects.js
/** @import { Blocker, ComponentContext, ComponentContextLegacy, Derived, Effect, TemplateNode, TransitionManager } from '#client' */
/**
* @param {'$effect' | '$effect.pre' | '$inspect'} rune
*/
function validate_effect(rune) {
if (active_effect === null) {
if (active_reaction === null) effect_orphan(rune);
effect_in_unowned_derived();
}
if (is_destroying_effect) effect_in_teardown(rune);
}
/**
* @param {Effect} effect
* @param {Effect} parent_effect
*/
function push_effect(effect, parent_effect) {
var parent_last = parent_effect.last;
if (parent_last === null) parent_effect.last = parent_effect.first = effect;
else {
parent_last.next = effect;
effect.prev = parent_last;
parent_effect.last = effect;
}
}
/**
* @param {number} type
* @param {null | (() => void | (() => void))} fn
* @returns {Effect}
*/
function create_effect(type, fn) {
var parent = active_effect;
if (parent !== null && (parent.f & 8192) !== 0) type |= INERT;
/** @type {Effect} */
var effect = {
ctx: component_context,
deps: null,
nodes: null,
f: type | DIRTY | 512,
first: null,
fn,
last: null,
next: null,
parent,
b: parent && parent.b,
prev: null,
teardown: null,
wv: 0,
ac: null
};
current_batch?.register_created_effect(effect);
/** @type {Effect | null} */
var e = effect;
if ((type & 4) !== 0) if (collected_effects !== null) collected_effects.push(effect);
else Batch.ensure().schedule(effect);
else if (fn !== null) {
try {
update_effect(effect);
} catch (e) {
destroy_effect(effect);
throw e;
}
if (e.deps === null && e.teardown === null && e.nodes === null && e.first === e.last && (e.f & 524288) === 0) {
e = e.first;
if ((type & 16) !== 0 && (type & 65536) !== 0 && e !== null) e.f |= EFFECT_TRANSPARENT;
}
}
if (e !== null) {
e.parent = parent;
if (parent !== null) push_effect(e, parent);
if (active_reaction !== null && (active_reaction.f & 2) !== 0 && (type & 64) === 0) {
var derived = active_reaction;
(derived.effects ??= []).push(e);
}
}
return effect;
}
/**
* Internal representation of `$effect.tracking()`
* @returns {boolean}
*/
function effect_tracking() {
return active_reaction !== null && !untracking;
}
/**
* @param {() => void} fn
*/
function teardown(fn) {
const effect = create_effect(8, null);
set_signal_status(effect, CLEAN);
effect.teardown = fn;
return effect;
}
/**
* Internal representation of `$effect(...)`
* @param {() => void | (() => void)} fn
*/
function user_effect(fn) {
validate_effect("$effect");
var flags = active_effect.f;
if (!active_reaction && (flags & 32) !== 0 && (flags & 32768) === 0) {
var context = component_context;
(context.e ??= []).push(fn);
} else return create_user_effect(fn);
}
/**
* @param {() => void | (() => void)} fn
*/
function create_user_effect(fn) {
return create_effect(4 | USER_EFFECT, fn);
}
/**
* Internal representation of `$effect.pre(...)`
* @param {() => void | (() => void)} fn
* @returns {Effect}
*/
function user_pre_effect(fn) {
validate_effect("$effect.pre");
return create_effect(8 | USER_EFFECT, fn);
}
/**
* An effect root whose children can transition out
* @param {() => void} fn
* @returns {(options?: { outro?: boolean }) => Promise<void>}
*/
function component_root(fn) {
Batch.ensure();
const effect = create_effect(64 | EFFECT_PRESERVED, fn);
return (options = {}) => {
return new Promise((fulfil) => {
if (options.outro) pause_effect(effect, () => {
destroy_effect(effect);
fulfil(void 0);
});
else {
destroy_effect(effect);
fulfil(void 0);
}
});
};
}
/**
* @param {() => void | (() => void)} fn
* @returns {Effect}
*/
function effect(fn) {
return create_effect(4, fn);
}
/**
* @param {() => void | (() => void)} fn
* @returns {Effect}
*/
function async_effect(fn) {
return create_effect(ASYNC | EFFECT_PRESERVED, fn);
}
/**
* @param {() => void | (() => void)} fn
* @returns {Effect}
*/
function render_effect(fn, flags = 0) {
return create_effect(8 | flags, fn);
}
/**
* @param {(...expressions: any) => void | (() => void)} fn
* @param {Array<() => any>} sync
* @param {Array<() => Promise<any>>} async
* @param {Blocker[]} blockers
*/
function template_effect(fn, sync = [], async = [], blockers = []) {
flatten(blockers, sync, async, (values) => {
create_effect(8, () => fn(...values.map(get)));
});
}
/**
* @param {(() => void)} fn
* @param {number} flags
*/
function block(fn, flags = 0) {
return create_effect(16 | flags, fn);
}
/**
* @param {(() => void)} fn
*/
function branch(fn) {
return create_effect(32 | EFFECT_PRESERVED, fn);
}
/**
* @param {Effect} effect
*/
function execute_effect_teardown(effect) {
var teardown = effect.teardown;
if (teardown !== null) {
const previously_destroying_effect = is_destroying_effect;
const previous_reaction = active_reaction;
set_is_destroying_effect(true);
set_active_reaction(null);
try {
teardown.call(null);
} finally {
set_is_destroying_effect(previously_destroying_effect);
set_active_reaction(previous_reaction);
}
}
}
/**
* @param {Effect} signal
* @param {boolean} remove_dom
* @returns {void}
*/
function destroy_effect_children(signal, remove_dom = false) {
var effect = signal.first;
signal.first = signal.last = null;
while (effect !== null) {
const controller = effect.ac;
if (controller !== null) without_reactive_context(() => {
controller.abort(STALE_REACTION);
});
var next = effect.next;
if ((effect.f & 64) !== 0) effect.parent = null;
else destroy_effect(effect, remove_dom);
effect = next;
}
}
/**
* @param {Effect} signal
* @returns {void}
*/
function destroy_block_effect_children(signal) {
var effect = signal.first;
while (effect !== null) {
var next = effect.next;
if ((effect.f & 32) === 0) destroy_effect(effect);
effect = next;
}
}
/**
* @param {Effect} effect
* @param {boolean} [remove_dom]
* @returns {void}
*/
function destroy_effect(effect, remove_dom = true) {
var removed = false;
if ((remove_dom || (effect.f & 262144) !== 0) && effect.nodes !== null && effect.nodes.end !== null) {
remove_effect_dom(effect.nodes.start, effect.nodes.end);
removed = true;
}
set_signal_status(effect, DESTROYING);
destroy_effect_children(effect, remove_dom && !removed);
remove_reactions(effect, 0);
var transitions = effect.nodes && effect.nodes.t;
if (transitions !== null) for (const transition of transitions) transition.stop();
execute_effect_teardown(effect);
effect.f ^= DESTROYING;
effect.f |= DESTROYED;
var parent = effect.parent;
if (parent !== null && parent.first !== null) unlink_effect(effect);
effect.next = effect.prev = effect.teardown = effect.ctx = effect.deps = effect.fn = effect.nodes = effect.ac = effect.b = null;
}
/**
*
* @param {TemplateNode | null} node
* @param {TemplateNode} end
*/
function remove_effect_dom(node, end) {
while (node !== null) {
/** @type {TemplateNode | null} */
var next = node === end ? null : /* @__PURE__ */ get_next_sibling(node);
node.remove();
node = next;
}
}
/**
* Detach an effect from the effect tree, freeing up memory and
* reducing the amount of work that happens on subsequent traversals
* @param {Effect} effect
*/
function unlink_effect(effect) {
var parent = effect.parent;
var prev = effect.prev;
var next = effect.next;
if (prev !== null) prev.next = next;
if (next !== null) next.prev = prev;
if (parent !== null) {
if (parent.first === effect) parent.first = next;
if (parent.last === effect) parent.last = prev;
}
}
/**
* When a block effect is removed, we don't immediately destroy it or yank it
* out of the DOM, because it might have transitions. Instead, we 'pause' it.
* It stays around (in memory, and in the DOM) until outro transitions have
* completed, and if the state change is reversed then we _resume_ it.
* A paused effect does not update, and the DOM subtree becomes inert.
* @param {Effect} effect
* @param {() => void} [callback]
* @param {boolean} [destroy]
*/
function pause_effect(effect, callback, destroy = true) {
/** @type {TransitionManager[]} */
var transitions = [];
pause_children(effect, transitions, true);
var fn = () => {
if (destroy) destroy_effect(effect);
if (callback) callback();
};
var remaining = transitions.length;
if (remaining > 0) {
var check = () => --remaining || fn();
for (var transition of transitions) transition.out(check);
} else fn();
}
/**
* @param {Effect} effect
* @param {TransitionManager[]} transitions
* @param {boolean} local
*/
function pause_children(effect, transitions, local) {
if ((effect.f & 8192) !== 0) return;
effect.f ^= INERT;
var t = effect.nodes && effect.nodes.t;
if (t !== null) {
for (const transition of t) if (transition.is_global || local) transitions.push(transition);
}
var child = effect.first;
while (child !== null) {
var sibling = child.next;
if ((child.f & 64) === 0) {
var transparent = (child.f & 65536) !== 0 || (child.f & 32) !== 0 && (effect.f & 16) !== 0;
pause_children(child, transitions, transparent ? local : false);
}
child = sibling;
}
}
/**
* The opposite of `pause_effect`. We call this if (for example)
* `x` becomes falsy then truthy: `{#if x}...{/if}`
* @param {Effect} effect
*/
function resume_effect(effect) {
resume_children(effect, true);
}
/**
* @param {Effect} effect
* @param {boolean} local
*/
function resume_children(effect, local) {
if ((effect.f & 8192) === 0) return;
effect.f ^= INERT;
if ((effect.f & 1024) === 0) {
set_signal_status(effect, DIRTY);
Batch.ensure().schedule(effect);
}
var child = effect.first;
while (child !== null) {
var sibling = child.next;
var transparent = (child.f & 65536) !== 0 || (child.f & 32) !== 0;
resume_children(child, transparent ? local : false);
child = sibling;
}
var t = effect.nodes && effect.nodes.t;
if (t !== null) {
for (const transition of t) if (transition.is_global || local) transition.in();
}
}
/**
* @param {Effect} effect
* @param {DocumentFragment} fragment
*/
function move_effect(effect, fragment) {
if (!effect.nodes) return;
/** @type {TemplateNode | null} */
var node = effect.nodes.start;
var end = effect.nodes.end;
while (node !== null) {
/** @type {TemplateNode | null} */
var next = node === end ? null : /* @__PURE__ */ get_next_sibling(node);
fragment.append(node);
node = next;
}
}
//#endregion
//#region node_modules/svelte/src/internal/client/legacy.js
/**
* @type {Set<Value> | null}
* @deprecated
*/
var captured_signals = null;
//#endregion
//#region node_modules/svelte/src/internal/client/runtime.js
/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */
var is_updating_effect = false;
var is_destroying_effect = false;
/** @param {boolean} value */
function set_is_destroying_effect(value) {
is_destroying_effect = value;
}
/** @type {null | Reaction} */
var active_reaction = null;
var untracking = false;
/** @param {null | Reaction} reaction */
function set_active_reaction(reaction) {
active_reaction = reaction;
}
/** @type {null | Effect} */
var active_effect = null;
/** @param {null | Effect} effect */
function set_active_effect(effect) {
active_effect = effect;
}
/**
* When sources are created within a reaction, reading and writing
* them within that reaction should not cause a re-run
* @type {null | Source[]}
*/
var current_sources = null;
/** @param {Value} value */
function push_reaction_value(value) {
if (active_reaction !== null && (!async_mode_flag || (active_reaction.f & 2) !== 0)) if (current_sources === null) current_sources = [value];
else current_sources.push(value);
}
/**
* The dependencies of the reaction that is currently being executed. In many cases,
* the dependencies are unchanged between runs, and so this will be `null` unless
* and until a new dependency is accessed — we track this via `skipped_deps`
* @type {null | Value[]}
*/
var new_deps = null;
var skipped_deps = 0;
/**
* Tracks writes that the effect it's executed in doesn't listen to yet,
* so that the dependency can be added to the effect later on if it then reads it
* @type {null | Source[]}
*/
var untracked_writes = null;
/** @param {null | Source[]} value */
function set_untracked_writes(value) {
untracked_writes = value;
}
/**
* @type {number} Used by sources and deriveds for handling updates.
* Version starts from 1 so that unowned deriveds differentiate between a created effect and a run one for tracing
**/
var write_version = 1;
/** @type {number} Used to version each read of a source of derived to avoid duplicating depedencies inside a reaction */
var read_version = 0;
var update_version = read_version;
/** @param {number} value */
function set_update_version(value) {
update_version = value;
}
function increment_write_version() {
return ++write_version;
}
/**
* Determines whether a derived or effect is dirty.
* If it is MAYBE_DIRTY, will set the status to CLEAN
* @param {Reaction} reaction
* @returns {boolean}
*/
function is_dirty(reaction) {
var flags = reaction.f;
if ((flags & 2048) !== 0) return true;
if (flags & 2) reaction.f &= ~WAS_MARKED;
if ((flags & 4096) !== 0) {
var dependencies = reaction.deps;
var length = dependencies.length;
for (var i = 0; i < length; i++) {
var dependency = dependencies[i];
if (is_dirty(dependency)) update_derived(dependency);
if (dependency.wv > reaction.wv) return true;
}
if ((flags & 512) !== 0 && batch_values === null) set_signal_status(reaction, CLEAN);
}
return false;
}
/**
* @param {Value} signal
* @param {Effect} effect
* @param {boolean} [root]
*/
function schedule_possible_effect_self_invalidation(signal, effect, root = true) {
var reactions = signal.reactions;
if (reactions === null) return;
if (!async_mode_flag && current_sources !== null && includes.call(current_sources, signal)) return;
for (var i = 0; i < reactions.length; i++) {
var reaction = reactions[i];
if ((reaction.f & 2) !== 0) schedule_possible_effect_self_invalidation(reaction, effect, false);
else if (effect === reaction) {
if (root) set_signal_status(reaction, DIRTY);
else if ((reaction.f & 1024) !== 0) set_signal_status(reaction, MAYBE_DIRTY);
schedule_effect(reaction);
}
}
}
/** @param {Reaction} reaction */
function update_reaction(reaction) {
var previous_deps = new_deps;
var previous_skipped_deps = skipped_deps;
var previous_untracked_writes = untracked_writes;
var previous_reaction = active_reaction;
var previous_sources = current_sources;
var previous_component_context = component_context;
var previous_untracking = untracking;
var previous_update_version = update_version;
var flags = reaction.f;
new_deps = null;
skipped_deps = 0;
untracked_writes = null;
active_reaction = (flags & 96) === 0 ? reaction : null;
current_sources = null;
set_component_context(reaction.ctx);
untracking = false;
update_version = ++read_version;
if (reaction.ac !== null) {
without_reactive_context(() => {
/** @type {AbortController} */ reaction.ac.abort(STALE_REACTION);
});
reaction.ac = null;
}
try {
reaction.f |= REACTION_IS_UPDATING;
var fn = reaction.fn;
var result = fn();
reaction.f |= REACTION_RAN;
var deps = reaction.deps;
var is_fork = current_batch?.is_fork;
if (new_deps !== null) {
var i;
if (!is_fork) remove_reactions(reaction, skipped_deps);
if (deps !== null && skipped_deps > 0) {
deps.length = skipped_deps + new_deps.length;
for (i = 0; i < new_deps.length; i++) deps[skipped_deps + i] = new_deps[i];
} else reaction.deps = deps = new_deps;
if (effect_tracking() && (reaction.f & 512) !== 0) for (i = skipped_deps; i < deps.length; i++) (deps[i].reactions ??= []).push(reaction);
} else if (!is_fork && deps !== null && skipped_deps < deps.length) {
remove_reactions(reaction, skipped_deps);
deps.length = skipped_deps;
}
if (is_runes() && untracked_writes !== null && !untracking && deps !== null && (reaction.f & 6146) === 0) for (i = 0; i < untracked_writes.length; i++) schedule_possible_effect_self_invalidation(untracked_writes[i], reaction);
if (previous_reaction !== null && previous_reaction !== reaction) {
read_version++;
if (previous_reaction.deps !== null) for (let i = 0; i < previous_skipped_deps; i += 1) previous_reaction.deps[i].rv = read_version;
if (previous_deps !== null) for (const dep of previous_deps) dep.rv = read_version;
if (untracked_writes !== null) if (previous_untracked_writes === null) previous_untracked_writes = untracked_writes;
else previous_untracked_writes.push(...untracked_writes);
}
if ((reaction.f & 8388608) !== 0) reaction.f ^= ERROR_VALUE;
return result;
} catch (error) {
return handle_error(error);
} finally {
reaction.f ^= REACTION_IS_UPDATING;
new_deps = previous_deps;
skipped_deps = previous_skipped_deps;
untracked_writes = previous_untracked_writes;
active_reaction = previous_reaction;
current_sources = previous_sources;
set_component_context(previous_component_context);
untracking = previous_untracking;
update_version = previous_update_version;
}
}
/**
* @template V
* @param {Reaction} signal
* @param {Value<V>} dependency
* @returns {void}
*/
function remove_reaction(signal, dependency) {
let reactions = dependency.reactions;
if (reactions !== null) {
var index = index_of.call(reactions, signal);
if (index !== -1) {
var new_length = reactions.length - 1;
if (new_length === 0) reactions = dependency.reactions = null;
else {
reactions[index] = reactions[new_length];
reactions.pop();
}
}
}
if (reactions === null && (dependency.f & 2) !== 0 && (new_deps === null || !includes.call(new_deps, dependency))) {
var derived = dependency;
if ((derived.f & 512) !== 0) {
derived.f ^= 512;
derived.f &= ~WAS_MARKED;
}
if (derived.v !== UNINITIALIZED) update_derived_status(derived);
freeze_derived_effects(derived);
remove_reactions(derived, 0);
}
}
/**
* @param {Reaction} signal
* @param {number} start_index
* @returns {void}
*/
function remove_reactions(signal, start_index) {
var dependencies = signal.deps;
if (dependencies === null) return;
for (var i = start_index; i < dependencies.length; i++) remove_reaction(signal, dependencies[i]);
}
/**
* @param {Effect} effect
* @returns {void}
*/
function update_effect(effect) {
var flags = effect.f;
if ((flags & 16384) !== 0) return;
set_signal_status(effect, CLEAN);
var previous_effect = active_effect;
var was_updating_effect = is_updating_effect;
active_effect = effect;
is_updating_effect = true;
try {
if ((flags & 16777232) !== 0) destroy_block_effect_children(effect);
else destroy_effect_children(effect);
execute_effect_teardown(effect);
var teardown = update_reaction(effect);
effect.teardown = typeof teardown === "function" ? teardown : null;
effect.wv = write_version;
} finally {
is_updating_effect = was_updating_effect;
active_effect = previous_effect;
}
}
/**
* Returns a promise that resolves once any pending state changes have been applied.
* @returns {Promise<void>}
*/
async function tick() {
if (async_mode_flag) return new Promise((f) => {
requestAnimationFrame(() => f());
setTimeout(() => f());
});
await Promise.resolve();
flushSync();
}
/**
* @template V
* @param {Value<V>} signal
* @returns {V}
*/
function get(signal) {
var is_derived = (signal.f & 2) !== 0;
captured_signals?.add(signal);
if (active_reaction !== null && !untracking) {
if (!(active_effect !== null && (active_effect.f & 16384) !== 0) && (current_sources === null || !includes.call(current_sources, signal))) {
var deps = active_reaction.deps;
if ((active_reaction.f & 2097152) !== 0) {
if (signal.rv < read_version) {
signal.rv = read_version;
if (new_deps === null && deps !== null && deps[skipped_deps] === signal) skipped_deps++;
else if (new_deps === null) new_deps = [signal];
else new_deps.push(signal);
}
} else {
(active_reaction.deps ??= []).push(signal);
var reactions = signal.reactions;
if (reactions === null) signal.reactions = [active_reaction];
else if (!includes.call(reactions, active_reaction)) reactions.push(active_reaction);
}
}
}
if (is_destroying_effect && old_values.has(signal)) return old_values.get(signal);
if (is_derived) {
var derived = signal;
if (is_destroying_effect) {
var value = derived.v;
if ((derived.f & 1024) === 0 && derived.reactions !== null || depends_on_old_values(derived)) value = execute_derived(derived);
old_values.set(derived, value);
return value;
}
var should_connect = (derived.f & 512) === 0 && !untracking && active_reaction !== null && (is_updating_effect || (active_reaction.f & 512) !== 0);
var is_new = (derived.f & REACTION_RAN) === 0;
if (is_dirty(derived)) {
if (should_connect) derived.f |= 512;
update_derived(derived);
}
if (should_connect && !is_new) {
unfreeze_derived_effects(derived);
reconnect(derived);
}
}
if (batch_values?.has(signal)) return batch_values.get(signal);
if ((signal.f & 8388608) !== 0) throw signal.v;
return signal.v;
}
/**
* (Re)connect a disconnected derived, so that it is notified
* of changes in `mark_reactions`
* @param {Derived} derived
*/
function reconnect(derived) {
derived.f |= 512;
if (derived.deps === null) return;
for (const dep of derived.deps) {
(dep.reactions ??= []).push(derived);
if ((dep.f & 2) !== 0 && (dep.f & 512) === 0) {
unfreeze_derived_effects(dep);
reconnect(dep);
}
}
}
/** @param {Derived} derived */
function depends_on_old_values(derived) {
if (derived.v === UNINITIALIZED) return true;
if (derived.deps === null) return false;
for (const dep of derived.deps) {
if (old_values.has(dep)) return true;
if ((dep.f & 2) !== 0 && depends_on_old_values(dep)) return true;
}
return false;
}
/**
* When used inside a [`$derived`](https://svelte.dev/docs/svelte/$derived) or [`$effect`](https://svelte.dev/docs/svelte/$effect),
* any state read inside `fn` will not be treated as a dependency.
*
* ```ts
* $effect(() => {
* // this will run when `data` changes, but not when `time` changes
* save(data, {
* timestamp: untrack(() => time)
* });
* });
* ```
* @template T
* @param {() => T} fn
* @returns {T}
*/
function untrack(fn) {
var previous_untracking = untracking;
try {
untracking = true;
return fn();
} finally {
untracking = previous_untracking;
}
}
/**
* Possibly traverse an object and read all its properties so that they're all reactive in case this is `$state`.
* Does only check first level of an object for performance reasons (heuristic should be good for 99% of all cases).
* @param {any} value
* @returns {void}
*/
function deep_read_state(value) {
if (typeof value !== "object" || !value || value instanceof EventTarget) return;
if (STATE_SYMBOL in value) deep_read(value);
else if (!Array.isArray(value)) for (let key in value) {
const prop = value[key];
if (typeof prop === "object" && prop && STATE_SYMBOL in prop) deep_read(prop);
}
}
/**
* Deeply traverse an object and read all its properties
* so that they're all reactive in case this is `$state`
* @param {any} value
* @param {Set<any>} visited
* @returns {void}
*/
function deep_read(value, visited = /* @__PURE__ */ new Set()) {
if (typeof value === "object" && value !== null && !(value instanceof EventTarget) && !visited.has(value)) {
visited.add(value);
if (value instanceof Date) value.getTime();
for (let key in value) try {
deep_read(value[key], visited);
} catch (e) {}
const proto = get_prototype_of(value);
if (proto !== Object.prototype && proto !== Array.prototype && proto !== Map.prototype && proto !== Set.prototype && proto !== Date.prototype) {
const descriptors = get_descriptors(proto);
for (let key in descriptors) {
const get = descriptors[key].get;
if (get) try {
get.call(value);
} catch (e) {}
}
}
}
}
/**
* Subset of delegated events which should be passive by default.
* These two are already passive via browser defaults on window, document and body.
* But since
* - we're delegating them
* - they happen often
* - they apply to mobile which is generally less performant
* we're marking them as passive by default for other elements, too.
*/
var PASSIVE_EVENTS = ["touchstart", "touchmove"];
/**
* Returns `true` if `name` is a passive event
* @param {string} name
*/
function is_passive_event(name) {
return PASSIVE_EVENTS.includes(name);
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/elements/events.js
/**
* Used on elements, as a map of event type -> event handler,
* and on events themselves to track which element handled an event
*/
var event_symbol = Symbol("events");
/** @type {Set<string>} */
var all_registered_events = /* @__PURE__ */ new Set();
/** @type {Set<(events: Array<string>) => void>} */
var root_event_handles = /* @__PURE__ */ new Set();
/**
* @param {string} event_name
* @param {EventTarget} dom
* @param {EventListener} [handler]
* @param {AddEventListenerOptions} [options]
*/
function create_event(event_name, dom, handler, options = {}) {
/**
* @this {EventTarget}
*/
function target_handler(event) {
if (!options.capture) handle_event_propagation.call(dom, event);
if (!event.cancelBubble) return without_reactive_context(() => {
return handler?.call(this, event);
});
}
if (event_name.startsWith("pointer") || event_name.startsWith("touch") || event_name === "wheel") queue_micro_task(() => {
dom.addEventListener(event_name, target_handler, options);
});
else dom.addEventListener(event_name, target_handler, options);
return target_handler;
}
/**
* @param {string} event_name
* @param {Element} dom
* @param {EventListener} [handler]
* @param {boolean} [capture]
* @param {boolean} [passive]
* @returns {void}
*/
function event(event_name, dom, handler, capture, passive) {
var options = {
capture,
passive
};
var target_handler = create_event(event_name, dom, handler, options);
if (dom === document.body || dom === window || dom === document || dom instanceof HTMLMediaElement) teardown(() => {
dom.removeEventListener(event_name, target_handler, options);
});
}
/**
* @param {string} event_name
* @param {Element} element
* @param {EventListener} [handler]
* @returns {void}
*/
function delegated(event_name, element, handler) {
(element[event_symbol] ??= {})[event_name] = handler;
}
/**
* @param {Array<string>} events
* @returns {void}
*/
function delegate(events) {
for (var i = 0; i < events.length; i++) all_registered_events.add(events[i]);
for (var fn of root_event_handles) fn(events);
}
var last_propagated_event = null;
/**
* @this {EventTarget}
* @param {Event} event
* @returns {void}
*/
function handle_event_propagation(event) {
var handler_element = this;
var owner_document = handler_element.ownerDocument;
var event_name = event.type;
var path = event.composedPath?.() || [];
var current_target = path[0] || event.target;
last_propagated_event = event;
var path_idx = 0;
var handled_at = last_propagated_event === event && event[event_symbol];
if (handled_at) {
var at_idx = path.indexOf(handled_at);
if (at_idx !== -1 && (handler_element === document || handler_element === window)) {
event[event_symbol] = handler_element;
return;
}
var handler_idx = path.indexOf(handler_element);
if (handler_idx === -1) return;
if (at_idx <= handler_idx) path_idx = at_idx;
}
current_target = path[path_idx] || event.target;
if (current_target === handler_element) return;
define_property(event, "currentTarget", {
configurable: true,
get() {
return current_target || owner_document;
}
});
var previous_reaction = active_reaction;
var previous_effect = active_effect;
set_active_reaction(null);
set_active_effect(null);
try {
/**
* @type {unknown}
*/
var throw_error;
/**
* @type {unknown[]}
*/
var other_errors = [];
while (current_target !== null) {
/** @type {null | Element} */
var parent_element = current_target.assignedSlot || current_target.parentNode || current_target.host || null;
try {
var delegated = current_target[event_symbol]?.[event_name];
if (delegated != null && (!current_target.disabled || event.target === current_target)) delegated.call(current_target, event);
} catch (error) {
if (throw_error) other_errors.push(error);
else throw_error = error;
}
if (event.cancelBubble || parent_element === handler_element || parent_element === null) break;
current_target = parent_element;
}
if (throw_error) {
for (let error of other_errors) queueMicrotask(() => {
throw error;
});
throw throw_error;
}
} finally {
event[event_symbol] = handler_element;
delete event.currentTarget;
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/reconciler.js
var policy = globalThis?.window?.trustedTypes && /* @__PURE__ */ globalThis.window.trustedTypes.createPolicy("svelte-trusted-html", {
/** @param {string} html */
createHTML: (html) => {
return html;
} });
/** @param {string} html */
function create_trusted_html(html) {
return policy?.createHTML(html) ?? html;
}
/**
* @param {string} html
*/
function create_fragment_from_html(html) {
var elem = create_element("template");
elem.innerHTML = create_trusted_html(html.replaceAll("<!>", "\x3C!---->"));
return elem.content;
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/template.js
/** @import { Effect, EffectNodes, TemplateNode } from '#client' */
/** @import { TemplateStructure } from './types' */
/**
* @param {TemplateNode} start
* @param {TemplateNode | null} end
*/
function assign_nodes(start, end) {
var effect = active_effect;
if (effect.nodes === null) effect.nodes = {
start,
end,
a: null,
t: null
};
}
/**
* @param {string} content
* @param {number} flags
* @returns {() => Node | Node[]}
*/
/* @__NO_SIDE_EFFECTS__ */
function from_html(content, flags) {
var is_fragment = (flags & 1) !== 0;
var use_import_node = (flags & 2) !== 0;
/** @type {Node} */
var node;
/**
* Whether or not the first item is a text/element node. If not, we need to
* create an additional comment node to act as `effect.nodes.start`
*/
var has_start = !content.startsWith("<!>");
return () => {
if (hydrating) {
assign_nodes(hydrate_node, null);
return hydrate_node;
}
if (node === void 0) {
node = create_fragment_from_html(has_start ? content : "<!>" + content);
if (!is_fragment) node = /* @__PURE__ */ get_first_child(node);
}
var clone = use_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true);
if (is_fragment) {
var start = /* @__PURE__ */ get_first_child(clone);
var end = clone.lastChild;
assign_nodes(start, end);
} else assign_nodes(clone, clone);
return clone;
};
}
/**
* Don't mark this as side-effect-free, hydration needs to walk all nodes
* @param {any} value
*/
function text(value = "") {
if (!hydrating) {
var t = create_text(value + "");
assign_nodes(t, t);
return t;
}
var node = hydrate_node;
if (node.nodeType !== 3) {
node.before(node = create_text());
set_hydrate_node(node);
} else merge_text_nodes(node);
assign_nodes(node, node);
return node;
}
/**
* @returns {TemplateNode | DocumentFragment}
*/
function comment() {
if (hydrating) {
assign_nodes(hydrate_node, null);
return hydrate_node;
}
var frag = document.createDocumentFragment();
var start = document.createComment("");
var anchor = create_text();
frag.append(start, anchor);
assign_nodes(start, anchor);
return frag;
}
/**
* Assign the created (or in hydration mode, traversed) dom elements to the current block
* and insert the elements into the dom (in client mode).
* @param {Text | Comment | Element} anchor
* @param {DocumentFragment | Element} dom
*/
function append(anchor, dom) {
if (hydrating) {
var effect = active_effect;
if ((effect.f & 32768) === 0 || effect.nodes.end === null) effect.nodes.end = hydrate_node;
hydrate_next();
return;
}
if (anchor === null) return;
anchor.before(dom);
}
/**
* @param {Element} text
* @param {string} value
* @returns {void}
*/
function set_text(text, value) {
var str = value == null ? "" : typeof value === "object" ? `${value}` : value;
if (str !== (text.__t ??= text.nodeValue)) {
text.__t = str;
text.nodeValue = `${str}`;
}
}
/**
* Mounts a component to the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component.
* Transitions will play during the initial render unless the `intro` option is set to `false`.
*
* @template {Record<string, any>} Props
* @template {Record<string, any>} Exports
* @param {ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>} component
* @param {MountOptions<Props>} options
* @returns {Exports}
*/
function mount(component, options) {
return _mount(component, options);
}
/** @type {Map<EventTarget, Map<string, number>>} */
var listeners = /* @__PURE__ */ new Map();
/**
* @template {Record<string, any>} Exports
* @param {ComponentType<SvelteComponent<any>> | Component<any>} Component
* @param {MountOptions} options
* @returns {Exports}
*/
function _mount(Component, { target, anchor, props = {}, events, context, intro = true, transformError }) {
init_operations();
/** @type {Exports} */
var component = void 0;
var unmount = component_root(() => {
var anchor_node = anchor ?? target.appendChild(create_text());
boundary(anchor_node, { pending: () => {} }, (anchor_node) => {
push({});
var ctx = component_context;
if (context) ctx.c = context;
if (events)
/** @type {any} */ props.$$events = events;
if (hydrating) assign_nodes(anchor_node, null);
component = Component(anchor_node, props) || {};
if (hydrating) {
/** @type {Effect & { nodes: EffectNodes }} */ active_effect.nodes.end = hydrate_node;
if (hydrate_node === null || hydrate_node.nodeType !== 8 || hydrate_node.data !== "]") {
hydration_mismatch();
throw HYDRATION_ERROR;
}
}
pop();
}, transformError);
/** @type {Set<string>} */
var registered_events = /* @__PURE__ */ new Set();
/** @param {Array<string>} events */
var event_handle = (events) => {
for (var i = 0; i < events.length; i++) {
var event_name = events[i];
if (registered_events.has(event_name)) continue;
registered_events.add(event_name);
var passive = is_passive_event(event_name);
for (const node of [target, document]) {
var counts = listeners.get(node);
if (counts === void 0) {
counts = /* @__PURE__ */ new Map();
listeners.set(node, counts);
}
var count = counts.get(event_name);
if (count === void 0) {
node.addEventListener(event_name, handle_event_propagation, { passive });
counts.set(event_name, 1);
} else counts.set(event_name, count + 1);
}
}
};
event_handle(array_from(all_registered_events));
root_event_handles.add(event_handle);
return () => {
for (var event_name of registered_events) for (const node of [target, document]) {
var counts = listeners.get(node);
var count = counts.get(event_name);
if (--count == 0) {
node.removeEventListener(event_name, handle_event_propagation);
counts.delete(event_name);
if (counts.size === 0) listeners.delete(node);
} else counts.set(event_name, count);
}
root_event_handles.delete(event_handle);
if (anchor_node !== anchor) anchor_node.parentNode?.removeChild(anchor_node);
};
});
mounted_components.set(component, unmount);
return component;
}
/**
* References of the components that were mounted or hydrated.
* Uses a `WeakMap` to avoid memory leaks.
*/
var mounted_components = /* @__PURE__ */ new WeakMap();
//#endregion
//#region node_modules/svelte/src/internal/client/dom/blocks/branches.js
/** @import { Effect, TemplateNode } from '#client' */
/**
* @typedef {{ effect: Effect, fragment: DocumentFragment }} Branch
*/
/**
* @template Key
*/
var BranchManager = class {
/** @type {TemplateNode} */
anchor;
/** @type {Map<Batch, Key>} */
#batches = /* @__PURE__ */ new Map();
/**
* Map of keys to effects that are currently rendered in the DOM.
* These effects are visible and actively part of the document tree.
* Example:
* ```
* {#if condition}
* foo
* {:else}
* bar
* {/if}
* ```
* Can result in the entries `true->Effect` and `false->Effect`
* @type {Map<Key, Effect>}
*/
#onscreen = /* @__PURE__ */ new Map();
/**
* Similar to #onscreen with respect to the keys, but contains branches that are not yet
* in the DOM, because their insertion is deferred.
* @type {Map<Key, Branch>}
*/
#offscreen = /* @__PURE__ */ new Map();
/**
* Keys of effects that are currently outroing
* @type {Set<Key>}
*/
#outroing = /* @__PURE__ */ new Set();
/**
* Whether to pause (i.e. outro) on change, or destroy immediately.
* This is necessary for `<svelte:element>`
*/
#transition = true;
/**
* @param {TemplateNode} anchor
* @param {boolean} transition
*/
constructor(anchor, transition = true) {
this.anchor = anchor;
this.#transition = transition;
}
/**
* @param {Batch} batch
*/
#commit = (batch) => {
if (!this.#batches.has(batch)) return;
var key = this.#batches.get(batch);
var onscreen = this.#onscreen.get(key);
if (onscreen) {
resume_effect(onscreen);
this.#outroing.delete(key);
} else {
var offscreen = this.#offscreen.get(key);
if (offscreen) {
this.#onscreen.set(key, offscreen.effect);
this.#offscreen.delete(key);
/** @type {TemplateNode} */ offscreen.fragment.lastChild.remove();
this.anchor.before(offscreen.fragment);
onscreen = offscreen.effect;
}
}
for (const [b, k] of this.#batches) {
this.#batches.delete(b);
if (b === batch) break;
const offscreen = this.#offscreen.get(k);
if (offscreen) {
destroy_effect(offscreen.effect);
this.#offscreen.delete(k);
}
}
for (const [k, effect] of this.#onscreen) {
if (k === key || this.#outroing.has(k)) continue;
const on_destroy = () => {
if (Array.from(this.#batches.values()).includes(k)) {
var fragment = document.createDocumentFragment();
move_effect(effect, fragment);
fragment.append(create_text());
this.#offscreen.set(k, {
effect,
fragment
});
} else destroy_effect(effect);
this.#outroing.delete(k);
this.#onscreen.delete(k);
};
if (this.#transition || !onscreen) {
this.#outroing.add(k);
pause_effect(effect, on_destroy, false);
} else on_destroy();
}
};
/**
* @param {Batch} batch
*/
#discard = (batch) => {
this.#batches.delete(batch);
const keys = Array.from(this.#batches.values());
for (const [k, branch] of this.#offscreen) if (!keys.includes(k)) {
destroy_effect(branch.effect);
this.#offscreen.delete(k);
}
};
/**
*
* @param {any} key
* @param {null | ((target: TemplateNode) => void)} fn
*/
ensure(key, fn) {
var batch = current_batch;
var defer = should_defer_append();
if (fn && !this.#onscreen.has(key) && !this.#offscreen.has(key)) if (defer) {
var fragment = document.createDocumentFragment();
var target = create_text();
fragment.append(target);
this.#offscreen.set(key, {
effect: branch(() => fn(target)),
fragment
});
} else this.#onscreen.set(key, branch(() => fn(this.anchor)));
this.#batches.set(batch, key);
if (defer) {
for (const [k, effect] of this.#onscreen) if (k === key) batch.unskip_effect(effect);
else batch.skip_effect(effect);
for (const [k, branch] of this.#offscreen) if (k === key) batch.unskip_effect(branch.effect);
else batch.skip_effect(branch.effect);
batch.oncommit(this.#commit);
batch.ondiscard(this.#discard);
} else {
if (hydrating) this.anchor = hydrate_node;
this.#commit(batch);
}
}
};
//#endregion
//#region node_modules/svelte/src/internal/client/dom/blocks/if.js
/** @import { TemplateNode } from '#client' */
/**
* @param {TemplateNode} node
* @param {(branch: (fn: (anchor: Node) => void, key?: number | false) => void) => void} fn
* @param {boolean} [elseif] True if this is an `{:else if ...}` block rather than an `{#if ...}`, as that affects which transitions are considered 'local'
* @returns {void}
*/
function if_block(node, fn, elseif = false) {
/** @type {TemplateNode | undefined} */
var marker;
if (hydrating) {
marker = hydrate_node;
hydrate_next();
}
var branches = new BranchManager(node);
var flags = elseif ? EFFECT_TRANSPARENT : 0;
/**
* @param {number | false} key
* @param {null | ((anchor: Node) => void)} fn
*/
function update_branch(key, fn) {
if (hydrating) {
var data = read_hydration_instruction(marker);
if (key !== parseInt(data.substring(1))) {
var anchor = skip_nodes();
set_hydrate_node(anchor);
branches.anchor = anchor;
set_hydrating(false);
branches.ensure(key, fn);
set_hydrating(true);
return;
}
}
branches.ensure(key, fn);
}
block(() => {
var has_branch = false;
fn((fn, key = 0) => {
has_branch = true;
update_branch(key, fn);
});
if (!has_branch) update_branch(-1, null);
}, flags);
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/blocks/each.js
/** @import { EachItem, EachOutroGroup, EachState, Effect, EffectNodes, MaybeSource, Source, TemplateNode, TransitionManager, Value } from '#client' */
/** @import { Batch } from '../../reactivity/batch.js'; */
/**
* @param {any} _
* @param {number} i
*/
function index(_, i) {
return i;
}
/**
* Pause multiple effects simultaneously, and coordinate their
* subsequent destruction. Used in each blocks
* @param {EachState} state
* @param {Effect[]} to_destroy
* @param {null | Node} controlled_anchor
*/
function pause_effects(state, to_destroy, controlled_anchor) {
/** @type {TransitionManager[]} */
var transitions = [];
var length = to_destroy.length;
/** @type {EachOutroGroup} */
var group;
var remaining = to_destroy.length;
for (var i = 0; i < length; i++) {
let effect = to_destroy[i];
pause_effect(effect, () => {
if (group) {
group.pending.delete(effect);
group.done.add(effect);
if (group.pending.size === 0) {
var groups = state.outrogroups;
destroy_effects(state, array_from(group.done));
groups.delete(group);
if (groups.size === 0) state.outrogroups = null;
}
} else remaining -= 1;
}, false);
}
if (remaining === 0) {
var fast_path = transitions.length === 0 && controlled_anchor !== null;
if (fast_path) {
var anchor = controlled_anchor;
var parent_node = anchor.parentNode;
clear_text_content(parent_node);
parent_node.append(anchor);
state.items.clear();
}
destroy_effects(state, to_destroy, !fast_path);
} else {
group = {
pending: new Set(to_destroy),
done: /* @__PURE__ */ new Set()
};
(state.outrogroups ??= /* @__PURE__ */ new Set()).add(group);
}
}
/**
* @param {EachState} state
* @param {Effect[]} to_destroy
* @param {boolean} remove_dom
*/
function destroy_effects(state, to_destroy, remove_dom = true) {
/** @type {Set<Effect> | undefined} */
var preserved_effects;
if (state.pending.size > 0) {
preserved_effects = /* @__PURE__ */ new Set();
for (const keys of state.pending.values()) for (const key of keys) preserved_effects.add(
/** @type {EachItem} */
state.items.get(key).e
);
}
for (var i = 0; i < to_destroy.length; i++) {
var e = to_destroy[i];
if (preserved_effects?.has(e)) {
e.f |= EFFECT_OFFSCREEN;
move_effect(e, document.createDocumentFragment());
} else destroy_effect(to_destroy[i], remove_dom);
}
}
/** @type {TemplateNode} */
var offscreen_anchor;
/**
* @template V
* @param {Element | Comment} node The next sibling node, or the parent node if this is a 'controlled' block
* @param {number} flags
* @param {() => V[]} get_collection
* @param {(value: V, index: number) => any} get_key
* @param {(anchor: Node, item: MaybeSource<V>, index: MaybeSource<number>) => void} render_fn
* @param {null | ((anchor: Node) => void)} fallback_fn
* @returns {void}
*/
function each(node, flags, get_collection, get_key, render_fn, fallback_fn = null) {
var anchor = node;
/** @type {Map<any, EachItem>} */
var items = /* @__PURE__ */ new Map();
if ((flags & 4) !== 0) {
var parent_node = node;
anchor = hydrating ? set_hydrate_node(/* @__PURE__ */ get_first_child(parent_node)) : parent_node.appendChild(create_text());
}
if (hydrating) hydrate_next();
/** @type {Effect | null} */
var fallback = null;
var each_array = /* @__PURE__ */ derived_safe_equal(() => {
var collection = get_collection();
return is_array(collection) ? collection : collection == null ? [] : array_from(collection);
});
/** @type {V[]} */
var array;
/** @type {Map<Batch, Set<any>>} */
var pending = /* @__PURE__ */ new Map();
var first_run = true;
/**
* @param {Batch} batch
*/
function commit(batch) {
if ((state.effect.f & 16384) !== 0) return;
state.pending.delete(batch);
state.fallback = fallback;
reconcile(state, array, anchor, flags, get_key);
if (fallback !== null) if (array.length === 0) if ((fallback.f & 33554432) === 0) resume_effect(fallback);
else {
fallback.f ^= EFFECT_OFFSCREEN;
move(fallback, null, anchor);
}
else pause_effect(fallback, () => {
fallback = null;
});
}
/**
* @param {Batch} batch
*/
function discard(batch) {
state.pending.delete(batch);
}
/** @type {EachState} */
var state = {
effect: block(() => {
array = get(each_array);
var length = array.length;
/** `true` if there was a hydration mismatch. Needs to be a `let` or else it isn't treeshaken out */
let mismatch = false;
if (hydrating) {
if (read_hydration_instruction(anchor) === "[!" !== (length === 0)) {
anchor = skip_nodes();
set_hydrate_node(anchor);
set_hydrating(false);
mismatch = true;
}
}
var keys = /* @__PURE__ */ new Set();
var batch = current_batch;
var defer = should_defer_append();
for (var index = 0; index < length; index += 1) {
if (hydrating && hydrate_node.nodeType === 8 && hydrate_node.data === "]") {
anchor = hydrate_node;
mismatch = true;
set_hydrating(false);
}
var value = array[index];
var key = get_key(value, index);
var item = first_run ? null : items.get(key);
if (item) {
if (item.v) internal_set(item.v, value);
if (item.i) internal_set(item.i, index);
if (defer) batch.unskip_effect(item.e);
} else {
item = create_item(items, first_run ? anchor : offscreen_anchor ??= create_text(), value, key, index, render_fn, flags, get_collection);
if (!first_run) item.e.f |= EFFECT_OFFSCREEN;
items.set(key, item);
}
keys.add(key);
}
if (length === 0 && fallback_fn && !fallback) if (first_run) fallback = branch(() => fallback_fn(anchor));
else {
fallback = branch(() => fallback_fn(offscreen_anchor ??= create_text()));
fallback.f |= EFFECT_OFFSCREEN;
}
if (length > keys.size) each_key_duplicate("", "", "");
if (hydrating && length > 0) set_hydrate_node(skip_nodes());
if (!first_run) {
pending.set(batch, keys);
if (defer) {
for (const [key, item] of items) if (!keys.has(key)) batch.skip_effect(item.e);
batch.oncommit(commit);
batch.ondiscard(discard);
} else commit(batch);
}
if (mismatch) set_hydrating(true);
get(each_array);
}),
flags,
items,
pending,
outrogroups: null,
fallback
};
first_run = false;
if (hydrating) anchor = hydrate_node;
}
/**
* Skip past any non-branch effects (which could be created with `createSubscriber`, for example) to find the next branch effect
* @param {Effect | null} effect
* @returns {Effect | null}
*/
function skip_to_branch(effect) {
while (effect !== null && (effect.f & 32) === 0) effect = effect.next;
return effect;
}
/**
* Add, remove, or reorder items output by an each block as its input changes
* @template V
* @param {EachState} state
* @param {Array<V>} array
* @param {Element | Comment | Text} anchor
* @param {number} flags
* @param {(value: V, index: number) => any} get_key
* @returns {void}
*/
function reconcile(state, array, anchor, flags, get_key) {
var is_animated = (flags & 8) !== 0;
var length = array.length;
var items = state.items;
var current = skip_to_branch(state.effect.first);
/** @type {undefined | Set<Effect>} */
var seen;
/** @type {Effect | null} */
var prev = null;
/** @type {undefined | Set<Effect>} */
var to_animate;
/** @type {Effect[]} */
var matched = [];
/** @type {Effect[]} */
var stashed = [];
/** @type {V} */
var value;
/** @type {any} */
var key;
/** @type {Effect | undefined} */
var effect;
/** @type {number} */
var i;
if (is_animated) for (i = 0; i < length; i += 1) {
value = array[i];
key = get_key(value, i);
effect = items.get(key).e;
if ((effect.f & 33554432) === 0) {
effect.nodes?.a?.measure();
(to_animate ??= /* @__PURE__ */ new Set()).add(effect);
}
}
for (i = 0; i < length; i += 1) {
value = array[i];
key = get_key(value, i);
effect = items.get(key).e;
if (state.outrogroups !== null) for (const group of state.outrogroups) {
group.pending.delete(effect);
group.done.delete(effect);
}
if ((effect.f & 8192) !== 0) {
resume_effect(effect);
if (is_animated) {
effect.nodes?.a?.unfix();
(to_animate ??= /* @__PURE__ */ new Set()).delete(effect);
}
}
if ((effect.f & 33554432) !== 0) {
effect.f ^= EFFECT_OFFSCREEN;
if (effect === current) move(effect, null, anchor);
else {
var next = prev ? prev.next : current;
if (effect === state.effect.last) state.effect.last = effect.prev;
if (effect.prev) effect.prev.next = effect.next;
if (effect.next) effect.next.prev = effect.prev;
link(state, prev, effect);
link(state, effect, next);
move(effect, next, anchor);
prev = effect;
matched = [];
stashed = [];
current = skip_to_branch(prev.next);
continue;
}
}
if (effect !== current) {
if (seen !== void 0 && seen.has(effect)) {
if (matched.length < stashed.length) {
var start = stashed[0];
var j;
prev = start.prev;
var a = matched[0];
var b = matched[matched.length - 1];
for (j = 0; j < matched.length; j += 1) move(matched[j], start, anchor);
for (j = 0; j < stashed.length; j += 1) seen.delete(stashed[j]);
link(state, a.prev, b.next);
link(state, prev, a);
link(state, b, start);
current = start;
prev = b;
i -= 1;
matched = [];
stashed = [];
} else {
seen.delete(effect);
move(effect, current, anchor);
link(state, effect.prev, effect.next);
link(state, effect, prev === null ? state.effect.first : prev.next);
link(state, prev, effect);
prev = effect;
}
continue;
}
matched = [];
stashed = [];
while (current !== null && current !== effect) {
(seen ??= /* @__PURE__ */ new Set()).add(current);
stashed.push(current);
current = skip_to_branch(current.next);
}
if (current === null) continue;
}
if ((effect.f & 33554432) === 0) matched.push(effect);
prev = effect;
current = skip_to_branch(effect.next);
}
if (state.outrogroups !== null) {
for (const group of state.outrogroups) if (group.pending.size === 0) {
destroy_effects(state, array_from(group.done));
state.outrogroups?.delete(group);
}
if (state.outrogroups.size === 0) state.outrogroups = null;
}
if (current !== null || seen !== void 0) {
/** @type {Effect[]} */
var to_destroy = [];
if (seen !== void 0) {
for (effect of seen) if ((effect.f & 8192) === 0) to_destroy.push(effect);
}
while (current !== null) {
if ((current.f & 8192) === 0 && current !== state.fallback) to_destroy.push(current);
current = skip_to_branch(current.next);
}
var destroy_length = to_destroy.length;
if (destroy_length > 0) {
var controlled_anchor = (flags & 4) !== 0 && length === 0 ? anchor : null;
if (is_animated) {
for (i = 0; i < destroy_length; i += 1) to_destroy[i].nodes?.a?.measure();
for (i = 0; i < destroy_length; i += 1) to_destroy[i].nodes?.a?.fix();
}
pause_effects(state, to_destroy, controlled_anchor);
}
}
if (is_animated) queue_micro_task(() => {
if (to_animate === void 0) return;
for (effect of to_animate) effect.nodes?.a?.apply();
});
}
/**
* @template V
* @param {Map<any, EachItem>} items
* @param {Node} anchor
* @param {V} value
* @param {unknown} key
* @param {number} index
* @param {(anchor: Node, item: V | Source<V>, index: number | Value<number>, collection: () => V[]) => void} render_fn
* @param {number} flags
* @param {() => V[]} get_collection
* @returns {EachItem}
*/
function create_item(items, anchor, value, key, index, render_fn, flags, get_collection) {
var v = (flags & 1) !== 0 ? (flags & 16) === 0 ? /* @__PURE__ */ mutable_source(value, false, false) : source(value) : null;
var i = (flags & 2) !== 0 ? source(index) : null;
return {
v,
i,
e: branch(() => {
render_fn(anchor, v ?? value, i ?? index, get_collection);
return () => {
items.delete(key);
};
})
};
}
/**
* @param {Effect} effect
* @param {Effect | null} next
* @param {Text | Element | Comment} anchor
*/
function move(effect, next, anchor) {
if (!effect.nodes) return;
var node = effect.nodes.start;
var end = effect.nodes.end;
var dest = next && (next.f & 33554432) === 0 ? next.nodes.start : anchor;
while (node !== null) {
var next_node = /* @__PURE__ */ get_next_sibling(node);
dest.before(node);
if (node === end) return;
node = next_node;
}
}
/**
* @param {EachState} state
* @param {Effect | null} prev
* @param {Effect | null} next
*/
function link(state, prev, next) {
if (prev === null) state.effect.first = next;
else prev.next = next;
if (next === null) state.effect.last = prev;
else next.prev = prev;
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/blocks/svelte-head.js
/** @import { TemplateNode } from '#client' */
/**
* @param {string} hash
* @param {(anchor: Node) => void} render_fn
* @returns {void}
*/
function head(hash, render_fn) {
let previous_hydrate_node = null;
let was_hydrating = hydrating;
/** @type {Comment | Text} */
var anchor;
if (hydrating) {
previous_hydrate_node = hydrate_node;
var head_anchor = /* @__PURE__ */ get_first_child(document.head);
while (head_anchor !== null && (head_anchor.nodeType !== 8 || head_anchor.data !== hash)) head_anchor = /* @__PURE__ */ get_next_sibling(head_anchor);
if (head_anchor === null) set_hydrating(false);
else {
var start = /* @__PURE__ */ get_next_sibling(head_anchor);
head_anchor.remove();
set_hydrate_node(start);
}
}
if (!hydrating) anchor = document.head.appendChild(create_text());
try {
block(() => render_fn(anchor), HEAD_EFFECT | EFFECT_PRESERVED);
} finally {
if (was_hydrating) {
set_hydrating(true);
set_hydrate_node(previous_hydrate_node);
}
}
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/elements/actions.js
/** @import { ActionPayload } from '#client' */
/**
* @template P
* @param {Element} dom
* @param {(dom: Element, value?: P) => ActionPayload<P>} action
* @param {() => P} [get_value]
* @returns {void}
*/
function action(dom, action, get_value) {
effect(() => {
var payload = untrack(() => action(dom, get_value?.()) || {});
if (get_value && payload?.update) {
var inited = false;
/** @type {P} */
var prev = {};
render_effect(() => {
var value = get_value();
deep_read_state(value);
if (inited && safe_not_equal(prev, value)) {
prev = value;
/** @type {Function} */ payload.update(value);
}
});
inited = true;
}
if (payload?.destroy) return () => payload.destroy();
});
}
//#endregion
//#region node_modules/svelte/src/internal/shared/attributes.js
var whitespace = [..." \n\r\f\xA0\v"];
/**
* @param {any} value
* @param {string | null} [hash]
* @param {Record<string, boolean>} [directives]
* @returns {string | null}
*/
function to_class(value, hash, directives) {
var classname = value == null ? "" : "" + value;
if (hash) classname = classname ? classname + " " + hash : hash;
if (directives) {
for (var key of Object.keys(directives)) if (directives[key]) classname = classname ? classname + " " + key : key;
else if (classname.length) {
var len = key.length;
var a = 0;
while ((a = classname.indexOf(key, a)) >= 0) {
var b = a + len;
if ((a === 0 || whitespace.includes(classname[a - 1])) && (b === classname.length || whitespace.includes(classname[b]))) classname = (a === 0 ? "" : classname.substring(0, a)) + classname.substring(b + 1);
else a = b;
}
}
}
return classname === "" ? null : classname;
}
/**
*
* @param {Record<string,any>} styles
* @param {boolean} important
*/
function append_styles(styles, important = false) {
var separator = important ? " !important;" : ";";
var css = "";
for (var key of Object.keys(styles)) {
var value = styles[key];
if (value != null && value !== "") css += " " + key + ": " + value + separator;
}
return css;
}
/**
* @param {string} name
* @returns {string}
*/
function to_css_name(name) {
if (name[0] !== "-" || name[1] !== "-") return name.toLowerCase();
return name;
}
/**
* @param {any} value
* @param {Record<string, any> | [Record<string, any>, Record<string, any>]} [styles]
* @returns {string | null}
*/
function to_style(value, styles) {
if (styles) {
var new_style = "";
/** @type {Record<string,any> | undefined} */
var normal_styles;
/** @type {Record<string,any> | undefined} */
var important_styles;
if (Array.isArray(styles)) {
normal_styles = styles[0];
important_styles = styles[1];
} else normal_styles = styles;
if (value) {
value = String(value).replaceAll(/\s*\/\*.*?\*\/\s*/g, "").trim();
/** @type {boolean | '"' | "'"} */
var in_str = false;
var in_apo = 0;
var in_comment = false;
var reserved_names = [];
if (normal_styles) reserved_names.push(...Object.keys(normal_styles).map(to_css_name));
if (important_styles) reserved_names.push(...Object.keys(important_styles).map(to_css_name));
var start_index = 0;
var name_index = -1;
const len = value.length;
for (var i = 0; i < len; i++) {
var c = value[i];
if (in_comment) {
if (c === "/" && value[i - 1] === "*") in_comment = false;
} else if (in_str) {
if (in_str === c) in_str = false;
} else if (c === "/" && value[i + 1] === "*") in_comment = true;
else if (c === "\"" || c === "'") in_str = c;
else if (c === "(") in_apo++;
else if (c === ")") in_apo--;
if (!in_comment && in_str === false && in_apo === 0) {
if (c === ":" && name_index === -1) name_index = i;
else if (c === ";" || i === len - 1) {
if (name_index !== -1) {
var name = to_css_name(value.substring(start_index, name_index).trim());
if (!reserved_names.includes(name)) {
if (c !== ";") i++;
var property = value.substring(start_index, i).trim();
new_style += " " + property + ";";
}
}
start_index = i + 1;
name_index = -1;
}
}
}
}
if (normal_styles) new_style += append_styles(normal_styles);
if (important_styles) new_style += append_styles(important_styles, true);
new_style = new_style.trim();
return new_style === "" ? null : new_style;
}
return value == null ? null : String(value);
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/elements/class.js
/**
* @param {Element} dom
* @param {boolean | number} is_html
* @param {string | null} value
* @param {string} [hash]
* @param {Record<string, any>} [prev_classes]
* @param {Record<string, any>} [next_classes]
* @returns {Record<string, boolean> | undefined}
*/
function set_class(dom, is_html, value, hash, prev_classes, next_classes) {
var prev = dom.__className;
if (hydrating || prev !== value || prev === void 0) {
var next_class_name = to_class(value, hash, next_classes);
if (!hydrating || next_class_name !== dom.getAttribute("class")) if (next_class_name == null) dom.removeAttribute("class");
else if (is_html) dom.className = next_class_name;
else dom.setAttribute("class", next_class_name);
dom.__className = value;
} else if (next_classes && prev_classes !== next_classes) for (var key in next_classes) {
var is_present = !!next_classes[key];
if (prev_classes == null || is_present !== !!prev_classes[key]) dom.classList.toggle(key, is_present);
}
return next_classes;
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/elements/style.js
/**
* @param {Element & ElementCSSInlineStyle} dom
* @param {Record<string, any>} prev
* @param {Record<string, any>} next
* @param {string} [priority]
*/
function update_styles(dom, prev = {}, next, priority) {
for (var key in next) {
var value = next[key];
if (prev[key] !== value) if (next[key] == null) dom.style.removeProperty(key);
else dom.style.setProperty(key, value, priority);
}
}
/**
* @param {Element & ElementCSSInlineStyle} dom
* @param {string | null} value
* @param {Record<string, any> | [Record<string, any>, Record<string, any>]} [prev_styles]
* @param {Record<string, any> | [Record<string, any>, Record<string, any>]} [next_styles]
*/
function set_style(dom, value, prev_styles, next_styles) {
var prev = dom.__style;
if (hydrating || prev !== value) {
var next_style_attr = to_style(value, next_styles);
if (!hydrating || next_style_attr !== dom.getAttribute("style")) if (next_style_attr == null) dom.removeAttribute("style");
else dom.style.cssText = next_style_attr;
dom.__style = value;
} else if (next_styles) if (Array.isArray(next_styles)) {
update_styles(dom, prev_styles?.[0], next_styles[0]);
update_styles(dom, prev_styles?.[1], next_styles[1], "important");
} else update_styles(dom, prev_styles, next_styles);
return next_styles;
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/elements/bindings/select.js
/**
* Selects the correct option(s) (depending on whether this is a multiple select)
* @template V
* @param {HTMLSelectElement} select
* @param {V} value
* @param {boolean} mounting
*/
function select_option(select, value, mounting = false) {
if (select.multiple) {
if (value == void 0) return;
if (!is_array(value)) return select_multiple_invalid_value();
for (var option of select.options) option.selected = value.includes(get_option_value(option));
return;
}
for (option of select.options) if (is(get_option_value(option), value)) {
option.selected = true;
return;
}
if (!mounting || value !== void 0) select.selectedIndex = -1;
}
/**
* Selects the correct option(s) if `value` is given,
* and then sets up a mutation observer to sync the
* current selection to the dom when it changes. Such
* changes could for example occur when options are
* inside an `#each` block.
* @param {HTMLSelectElement} select
*/
function init_select(select) {
var observer = new MutationObserver(() => {
select_option(select, select.__value);
});
observer.observe(select, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["value"]
});
teardown(() => {
observer.disconnect();
});
}
/**
* @param {HTMLSelectElement} select
* @param {() => unknown} get
* @param {(value: unknown) => void} set
* @returns {void}
*/
function bind_select_value(select, get, set = get) {
var batches = /* @__PURE__ */ new WeakSet();
var mounting = true;
listen_to_event_and_reset_event(select, "change", (is_reset) => {
var query = is_reset ? "[selected]" : ":checked";
/** @type {unknown} */
var value;
if (select.multiple) value = [].map.call(select.querySelectorAll(query), get_option_value);
else {
/** @type {HTMLOptionElement | null} */
var selected_option = select.querySelector(query) ?? select.querySelector("option:not([disabled])");
value = selected_option && get_option_value(selected_option);
}
set(value);
select.__value = value;
if (current_batch !== null) batches.add(current_batch);
});
effect(() => {
var value = get();
if (select === document.activeElement) {
var batch = async_mode_flag ? previous_batch : current_batch;
if (batches.has(batch)) return;
}
select_option(select, value, mounting);
if (mounting && value === void 0) {
/** @type {HTMLOptionElement | null} */
var selected_option = select.querySelector(":checked");
if (selected_option !== null) {
value = get_option_value(selected_option);
set(value);
}
}
select.__value = value;
mounting = false;
});
init_select(select);
}
/** @param {HTMLOptionElement} option */
function get_option_value(option) {
if ("__value" in option) return option.__value;
else return option.value;
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/elements/attributes.js
/** @import { Blocker, Effect } from '#client' */
var IS_CUSTOM_ELEMENT = Symbol("is custom element");
var IS_HTML = Symbol("is html");
var LINK_TAG = IS_XHTML ? "link" : "LINK";
var PROGRESS_TAG = IS_XHTML ? "progress" : "PROGRESS";
/**
* The value/checked attribute in the template actually corresponds to the defaultValue property, so we need
* to remove it upon hydration to avoid a bug when someone resets the form value.
* @param {HTMLInputElement} input
* @returns {void}
*/
function remove_input_defaults(input) {
if (!hydrating) return;
var already_removed = false;
var remove_defaults = () => {
if (already_removed) return;
already_removed = true;
if (input.hasAttribute("value")) {
var value = input.value;
set_attribute(input, "value", null);
input.value = value;
}
if (input.hasAttribute("checked")) {
var checked = input.checked;
set_attribute(input, "checked", null);
input.checked = checked;
}
};
input.__on_r = remove_defaults;
queue_micro_task(remove_defaults);
add_form_reset_listener();
}
/**
* @param {Element} element
* @param {any} value
*/
function set_value(element, value) {
var attributes = get_attributes(element);
if (attributes.value === (attributes.value = value ?? void 0) || element.value === value && (value !== 0 || element.nodeName !== PROGRESS_TAG)) return;
element.value = value ?? "";
}
/**
* @param {Element} element
* @param {string} attribute
* @param {string | null} value
* @param {boolean} [skip_warning]
*/
function set_attribute(element, attribute, value, skip_warning) {
var attributes = get_attributes(element);
if (hydrating) {
attributes[attribute] = element.getAttribute(attribute);
if (attribute === "src" || attribute === "srcset" || attribute === "href" && element.nodeName === LINK_TAG) {
if (!skip_warning);
return;
}
}
if (attributes[attribute] === (attributes[attribute] = value)) return;
if (attribute === "loading") element[LOADING_ATTR_SYMBOL] = value;
if (value == null) element.removeAttribute(attribute);
else if (typeof value !== "string" && get_setters(element).includes(attribute)) element[attribute] = value;
else element.setAttribute(attribute, value);
}
/**
*
* @param {Element} element
*/
function get_attributes(element) {
return element.__attributes ??= {
[IS_CUSTOM_ELEMENT]: element.nodeName.includes("-"),
[IS_HTML]: element.namespaceURI === NAMESPACE_HTML
};
}
/** @type {Map<string, string[]>} */
var setters_cache = /* @__PURE__ */ new Map();
/** @param {Element} element */
function get_setters(element) {
var cache_key = element.getAttribute("is") || element.nodeName;
var setters = setters_cache.get(cache_key);
if (setters) return setters;
setters_cache.set(cache_key, setters = []);
var descriptors;
var proto = element;
var element_proto = Element.prototype;
while (element_proto !== proto) {
descriptors = get_descriptors(proto);
for (var key in descriptors) if (descriptors[key].set) setters.push(key);
proto = get_prototype_of(proto);
}
return setters;
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/elements/bindings/input.js
/** @import { Batch } from '../../../reactivity/batch.js' */
/**
* @param {HTMLInputElement} input
* @param {() => unknown} get
* @param {(value: unknown) => void} set
* @returns {void}
*/
function bind_value(input, get, set = get) {
var batches = /* @__PURE__ */ new WeakSet();
listen_to_event_and_reset_event(input, "input", async (is_reset) => {
/** @type {any} */
var value = is_reset ? input.defaultValue : input.value;
value = is_numberlike_input(input) ? to_number(value) : value;
set(value);
if (current_batch !== null) batches.add(current_batch);
await tick();
if (value !== (value = get())) {
var start = input.selectionStart;
var end = input.selectionEnd;
var length = input.value.length;
input.value = value ?? "";
if (end !== null) {
var new_length = input.value.length;
if (start === end && end === length && new_length > length) {
input.selectionStart = new_length;
input.selectionEnd = new_length;
} else {
input.selectionStart = start;
input.selectionEnd = Math.min(end, new_length);
}
}
}
});
if (hydrating && input.defaultValue !== input.value || untrack(get) == null && input.value) {
set(is_numberlike_input(input) ? to_number(input.value) : input.value);
if (current_batch !== null) batches.add(current_batch);
}
render_effect(() => {
var value = get();
if (input === document.activeElement) {
var batch = async_mode_flag ? previous_batch : current_batch;
if (batches.has(batch)) return;
}
if (is_numberlike_input(input) && value === to_number(input.value)) return;
if (input.type === "date" && !value && !input.value) return;
if (value !== input.value) input.value = value ?? "";
});
}
/** @type {Set<HTMLInputElement[]>} */
var pending = /* @__PURE__ */ new Set();
/**
* @param {HTMLInputElement[]} inputs
* @param {null | [number]} group_index
* @param {HTMLInputElement} input
* @param {() => unknown} get
* @param {(value: unknown) => void} set
* @returns {void}
*/
function bind_group(inputs, group_index, input, get, set = get) {
var is_checkbox = input.getAttribute("type") === "checkbox";
var binding_group = inputs;
let hydration_mismatch = false;
if (group_index !== null) for (var index of group_index) binding_group = binding_group[index] ??= [];
binding_group.push(input);
listen_to_event_and_reset_event(input, "change", () => {
var value = input.__value;
if (is_checkbox) value = get_binding_group_value(binding_group, value, input.checked);
set(value);
}, () => set(is_checkbox ? [] : null));
render_effect(() => {
var value = get();
if (hydrating && input.defaultChecked !== input.checked) {
hydration_mismatch = true;
return;
}
if (is_checkbox) {
value = value || [];
input.checked = value.includes(input.__value);
} else input.checked = is(input.__value, value);
});
teardown(() => {
var index = binding_group.indexOf(input);
if (index !== -1) binding_group.splice(index, 1);
});
if (!pending.has(binding_group)) {
pending.add(binding_group);
queue_micro_task(() => {
binding_group.sort((a, b) => a.compareDocumentPosition(b) === 4 ? -1 : 1);
pending.delete(binding_group);
});
}
queue_micro_task(() => {
if (hydration_mismatch) {
var value;
if (is_checkbox) value = get_binding_group_value(binding_group, value, input.checked);
else value = binding_group.find((input) => input.checked)?.__value;
set(value);
}
});
}
/**
* @template V
* @param {Array<HTMLInputElement>} group
* @param {V} __value
* @param {boolean} checked
* @returns {V[]}
*/
function get_binding_group_value(group, __value, checked) {
/** @type {Set<V>} */
var value = /* @__PURE__ */ new Set();
for (var i = 0; i < group.length; i += 1) if (group[i].checked) value.add(group[i].__value);
if (!checked) value.delete(__value);
return Array.from(value);
}
/**
* @param {HTMLInputElement} input
*/
function is_numberlike_input(input) {
var type = input.type;
return type === "number" || type === "range";
}
/**
* @param {string} value
*/
function to_number(value) {
return value === "" ? null : +value;
}
//#endregion
//#region node_modules/svelte/src/internal/client/dom/legacy/lifecycle.js
/** @import { ComponentContextLegacy } from '#client' */
/**
* Legacy-mode only: Call `onMount` callbacks and set up `beforeUpdate`/`afterUpdate` effects
* @param {boolean} [immutable]
*/
function init(immutable = false) {
const context = component_context;
const callbacks = context.l.u;
if (!callbacks) return;
let props = () => deep_read_state(context.s);
if (immutable) {
let version = 0;
let prev = {};
const d = /* @__PURE__ */ derived(() => {
let changed = false;
const props = context.s;
for (const key in props) if (props[key] !== prev[key]) {
prev[key] = props[key];
changed = true;
}
if (changed) version++;
return version;
});
props = () => get(d);
}
if (callbacks.b.length) user_pre_effect(() => {
observe_all(context, props);
run_all(callbacks.b);
});
user_effect(() => {
const fns = untrack(() => callbacks.m.map(run));
return () => {
for (const fn of fns) if (typeof fn === "function") fn();
};
});
if (callbacks.a.length) user_effect(() => {
observe_all(context, props);
run_all(callbacks.a);
});
}
/**
* Invoke the getter of all signals associated with a component
* so they can be registered to the effect this function is called in.
* @param {ComponentContextLegacy} context
* @param {(() => void)} props
*/
function observe_all(context, props) {
if (context.l.s) for (const signal of context.l.s) get(signal);
props();
}
if (typeof HTMLElement === "function");
//#endregion
//#region node_modules/svelte/src/internal/disclose-version.js
if (typeof window !== "undefined") ((window.__svelte ??= {}).v ??= /* @__PURE__ */ new Set()).add("5");
//#endregion
//#region node_modules/svelte/src/internal/flags/legacy.js
enable_legacy_mode_flag();
//#endregion
//#region src/lib/stores/security.svelte.js
var DEFAULT_AUTO_LOCK_MINUTES = 5;
var autoLockTimer = null;
var autoLockMinutes = 5;
function startAutoLock(minutes = DEFAULT_AUTO_LOCK_MINUTES) {
autoLockMinutes = minutes;
resetAutoLock();
const events = [
"mousedown",
"keydown",
"scroll",
"touchstart"
];
const handler = () => resetAutoLock();
events.forEach((evt) => window.addEventListener(evt, handler, { passive: true }));
document.addEventListener("visibilitychange", handleVisibilityChange);
window.addEventListener("beforeunload", clearKeyOnExit);
window.__vaultCleanup = () => {
events.forEach((evt) => window.removeEventListener(evt, handler));
document.removeEventListener("visibilitychange", handleVisibilityChange);
window.removeEventListener("beforeunload", clearKeyOnExit);
if (autoLockTimer) clearTimeout(autoLockTimer);
};
}
/**
* Reset the auto-lock timer.
*/
function resetAutoLock() {
if (autoLockTimer) clearTimeout(autoLockTimer);
autoLockTimer = setTimeout(() => {
app$1.lockVault();
}, autoLockMinutes * 60 * 1e3);
}
/**
* Handle visibility change — lock when user switches away from tab.
*/
function handleVisibilityChange() {
if (document.hidden && app$1.isUnlocked) app$1.lockVault();
}
/**
* Clear the encryption key when the page is closing.
*/
function clearKeyOnExit() {
app$1.encryptionKey = null;
}
/**
* Stop auto-lock (e.g., when manually locking).
*/
function stopAutoLock() {
if (autoLockTimer) {
clearTimeout(autoLockTimer);
autoLockTimer = null;
}
}
//#endregion
//#region src/lib/stores/app.svelte.js
var AppStore = class {
#isUnlocked = /* @__PURE__ */ state(false);
get isUnlocked() {
return get(this.#isUnlocked);
}
set isUnlocked(value) {
set(this.#isUnlocked, value, true);
}
#encryptionKey = /* @__PURE__ */ state(null);
get encryptionKey() {
return get(this.#encryptionKey);
}
set encryptionKey(value) {
set(this.#encryptionKey, value, true);
}
#salt = /* @__PURE__ */ state(null);
get salt() {
return get(this.#salt);
}
set salt(value) {
set(this.#salt, value, true);
}
lockVault() {
stopAutoLock();
this.encryptionKey = null;
this.isUnlocked = false;
}
};
var app$1 = new AppStore();
//#endregion
//#region src/lib/models/schema.js
/**
* Data model definitions and factory functions.
*
* All IDs are generated with a simple ULID-like timestamp + random suffix
* to keep things sortable and collision-resistant without external deps.
*/
/**
* Generate a unique ID (timestamp-based, sortable).
* @returns {string}
*/
function generateId() {
const timestamp = Date.now().toString(36);
const randomBytes = new Uint8Array(4);
crypto.getRandomValues(randomBytes);
return `${timestamp}_${Array.from(randomBytes).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, 8)}`;
}
/**
* @typedef {Object} CredentialEntry
* @property {string} id - Unique identifier
* @property {string} title - Display name (e.g. "GitHub", "Gmail")
* @property {string} [username] - Login username or email (optional)
* @property {string} encryptedPassword - AES-GCM encrypted password blob (JSON string)
* @property {string} [url] - Website URL
* @property {string} [notes] - Free-form notes
* @property {string} [groupId] - Reference to a Group id (empty string = no group)
* @property {string[]} [tags] - Free-form tags
* @property {string} createdAt - ISO timestamp
* @property {string} updatedAt - ISO timestamp
*/
/**
* Create a new CredentialEntry.
*
* @param {Object} data
* @param {string} data.title
* @param {string} [data.username]
* @param {string} data.encryptedPassword - Must already be encrypted
* @param {string} [data.url]
* @param {string} [data.notes]
* @param {string} [data.groupId]
* @param {string[]} [data.tags]
* @returns {CredentialEntry}
*/
function createEntry(data) {
const now = (/* @__PURE__ */ new Date()).toISOString();
return {
id: generateId(),
title: data.title.trim(),
username: data.username?.trim() || "",
encryptedPassword: data.encryptedPassword,
url: data.url?.trim() || "",
notes: data.notes?.trim() || "",
groupId: data.groupId || "",
tags: data.tags || [],
createdAt: now,
updatedAt: now
};
}
/**
* Update an existing entry, preserving id and createdAt.
*
* @param {CredentialEntry} existing
* @param {Object} data - Fields to update
* @returns {CredentialEntry}
*/
function updateEntry$1(existing, data) {
return {
...existing,
title: data.title !== void 0 ? data.title.trim() : existing.title,
username: data.username !== void 0 ? data.username?.trim() || "" : existing.username,
encryptedPassword: data.encryptedPassword !== void 0 ? data.encryptedPassword : existing.encryptedPassword,
url: data.url !== void 0 ? data.url.trim() : existing.url,
notes: data.notes !== void 0 ? data.notes.trim() : existing.notes,
groupId: data.groupId !== void 0 ? data.groupId : existing.groupId,
tags: data.tags !== void 0 ? data.tags : existing.tags,
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
};
}
/**
* @typedef {Object} Group
* @property {string} id - Unique identifier
* @property {string} name - Display name
* @property {string} [color] - Hex color for UI accent
* @property {string} createdAt - ISO timestamp
*/
var GROUP_COLORS = [
"#6c63ff",
"#e5484d",
"#34d399",
"#fbbf24",
"#3b82f6",
"#ec4899",
"#8b5cf6",
"#14b8a6",
"#f97316",
"#06b6d4"
];
/**
* Create a new Group.
*
* @param {string} name
* @param {string} [color]
* @returns {Group}
*/
function createGroup(name, color) {
return {
id: generateId(),
name: name.trim(),
color: color || GROUP_COLORS[Math.floor(Math.random() * GROUP_COLORS.length)],
createdAt: (/* @__PURE__ */ new Date()).toISOString()
};
}
/**
* Validate a credential entry form submission.
*
* @param {Object} data
* @returns {{ valid: boolean, errors: string[] }}
*/
function validateEntry(data) {
const errors = [];
if (!data.title || !data.title.trim()) errors.push("Title is required");
if (!data.encryptedPassword) errors.push("Password is required");
return {
valid: errors.length === 0,
errors
};
}
/**
* Validate a group name.
*
* @param {string} name
* @returns {{ valid: boolean, errors: string[] }}
*/
function validateGroup(name) {
const errors = [];
if (!name || !name.trim()) errors.push("Group name is required");
else if (name.trim().length > 50) errors.push("Group name must be 50 characters or less");
return {
valid: errors.length === 0,
errors
};
}
//#endregion
//#region src/lib/crypto/crypto.js
/**
* Crypto module — Web Crypto API wrapper.
*
* Uses PBKDF2 for key derivation and AES-GCM for symmetric encryption.
* All operations are async and use the browser's native Web Crypto API.
*
* The derived encryption key is kept in memory only — never written to disk.
*/
var PBKDF2_ITERATIONS = 6e5;
var SALT_LENGTH = 16;
var IV_LENGTH = 12;
/**
* Generate a random salt.
* @returns {Uint8Array}
*/
function generateSalt() {
return crypto.getRandomValues(new Uint8Array(SALT_LENGTH));
}
/**
* Derive an AES-GCM encryption key from a master password and salt.
*
* @param {string} masterPassword
* @param {Uint8Array} salt
* @returns {Promise<CryptoKey>}
*/
async function deriveKey(masterPassword, salt) {
const keyMaterial = await crypto.subtle.importKey("raw", new TextEncoder().encode(masterPassword), "PBKDF2", false, ["deriveKey"]);
return crypto.subtle.deriveKey({
name: "PBKDF2",
salt,
iterations: PBKDF2_ITERATIONS,
hash: "SHA-256"
}, keyMaterial, {
name: "AES-GCM",
length: 256
}, false, ["encrypt", "decrypt"]);
}
/**
* Encrypt a plaintext string.
*
* @param {string} plaintext
* @param {CryptoKey} key
* @returns {Promise<string>} JSON string containing { iv, ciphertext }
* (salt is stored separately in the app store)
*/
async function encrypt(plaintext, key) {
const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
const encoded = new TextEncoder().encode(plaintext);
const ciphertext = await crypto.subtle.encrypt({
name: "AES-GCM",
iv
}, key, encoded);
return JSON.stringify({
iv: uint8ArrayToBase64(iv),
ciphertext: uint8ArrayToBase64(new Uint8Array(ciphertext))
});
}
/**
* Decrypt an encrypted blob back to plaintext.
*
* @param {string} encryptedJson - JSON string from encrypt()
* @param {CryptoKey} key
* @returns {Promise<string>}
*/
async function decrypt(encryptedJson, key) {
const { iv, ciphertext } = JSON.parse(encryptedJson);
const ciphertextBuffer = base64ToUint8Array$1(ciphertext);
const ivBuffer = base64ToUint8Array$1(iv);
const decrypted = await crypto.subtle.decrypt({
name: "AES-GCM",
iv: ivBuffer
}, key, ciphertextBuffer);
return new TextDecoder().decode(decrypted);
}
/**
* Verify that a master password is correct by attempting to decrypt a test payload.
*
* @param {string} masterPassword
* @param {Uint8Array} salt
* @param {string} testEncrypted - A known encrypted test string
* @param {string} testPlaintext - The expected plaintext
* @returns {Promise<boolean>}
*/
async function verifyPassword(masterPassword, salt, testEncrypted, testPlaintext) {
try {
return await decrypt(testEncrypted, await deriveKey(masterPassword, salt)) === testPlaintext;
} catch {
return false;
}
}
/**
* Create a test payload for password verification on first setup.
*
* @param {string} masterPassword
* @returns {Promise<{ salt: Uint8Array, testEncrypted: string }>}
*/
async function createTestPayload(masterPassword) {
const salt = generateSalt();
const key = await deriveKey(masterPassword, salt);
const testPlaintext = "vault_test_" + generateId();
return {
salt,
testEncrypted: await encrypt(testPlaintext, key),
testPlaintext
};
}
function uint8ArrayToBase64(buffer) {
const bytes = new Uint8Array(buffer);
let binary = "";
for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]);
return btoa(binary);
}
function base64ToUint8Array$1(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
return bytes;
}
/**
* Generate a random password.
*
* @param {Object} options
* @param {number} [options.length=16]
* @param {boolean} [options.uppercase=true]
* @param {boolean} [options.lowercase=true]
* @param {boolean} [options.digits=true]
* @param {boolean} [options.symbols=true]
* @param {string} [options.exclude='']
* @returns {string}
*/
function generatePassword({ length = 16, uppercase = true, lowercase = true, digits = true, symbols = true, exclude = "" } = {}) {
let charset = "";
if (uppercase) charset += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (lowercase) charset += "abcdefghijklmnopqrstuvwxyz";
if (digits) charset += "0123456789";
if (symbols) charset += "!@#$%^&*()_+-=[]{}|;:,.<>?";
if (exclude) {
const excludeSet = new Set(exclude.split(""));
charset = charset.split("").filter((c) => !excludeSet.has(c)).join("");
}
if (!charset) throw new Error("Password charset is empty — enable at least one character type");
const charsetLength = charset.length;
const maxValid = 256 - 256 % charsetLength;
const randomBytes = new Uint8Array(length * 2);
let password = "";
let byteIdx = 0;
while (password.length < length) {
if (byteIdx >= randomBytes.length) {
crypto.getRandomValues(randomBytes);
byteIdx = 0;
}
const byte = randomBytes[byteIdx++];
if (byte < maxValid) password += charset[byte % charsetLength];
}
return password;
}
//#endregion
//#region node_modules/idb/build/index.js
var instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
var idbProxyableTypes;
var cursorAdvanceMethods;
function getIdbProxyableTypes() {
return idbProxyableTypes || (idbProxyableTypes = [
IDBDatabase,
IDBObjectStore,
IDBIndex,
IDBCursor,
IDBTransaction
]);
}
function getCursorAdvanceMethods() {
return cursorAdvanceMethods || (cursorAdvanceMethods = [
IDBCursor.prototype.advance,
IDBCursor.prototype.continue,
IDBCursor.prototype.continuePrimaryKey
]);
}
var transactionDoneMap = /* @__PURE__ */ new WeakMap();
var transformCache = /* @__PURE__ */ new WeakMap();
var reverseTransformCache = /* @__PURE__ */ new WeakMap();
function promisifyRequest(request) {
const promise = new Promise((resolve, reject) => {
const unlisten = () => {
request.removeEventListener("success", success);
request.removeEventListener("error", error);
};
const success = () => {
resolve(wrap(request.result));
unlisten();
};
const error = () => {
reject(request.error);
unlisten();
};
request.addEventListener("success", success);
request.addEventListener("error", error);
});
reverseTransformCache.set(promise, request);
return promise;
}
function cacheDonePromiseForTransaction(tx) {
if (transactionDoneMap.has(tx)) return;
const done = new Promise((resolve, reject) => {
const unlisten = () => {
tx.removeEventListener("complete", complete);
tx.removeEventListener("error", error);
tx.removeEventListener("abort", error);
};
const complete = () => {
resolve();
unlisten();
};
const error = () => {
reject(tx.error || new DOMException("AbortError", "AbortError"));
unlisten();
};
tx.addEventListener("complete", complete);
tx.addEventListener("error", error);
tx.addEventListener("abort", error);
});
transactionDoneMap.set(tx, done);
}
var idbProxyTraps = {
get(target, prop, receiver) {
if (target instanceof IDBTransaction) {
if (prop === "done") return transactionDoneMap.get(target);
if (prop === "store") return receiver.objectStoreNames[1] ? void 0 : receiver.objectStore(receiver.objectStoreNames[0]);
}
return wrap(target[prop]);
},
set(target, prop, value) {
target[prop] = value;
return true;
},
has(target, prop) {
if (target instanceof IDBTransaction && (prop === "done" || prop === "store")) return true;
return prop in target;
}
};
function replaceTraps(callback) {
idbProxyTraps = callback(idbProxyTraps);
}
function wrapFunction(func) {
if (getCursorAdvanceMethods().includes(func)) return function(...args) {
func.apply(unwrap(this), args);
return wrap(this.request);
};
return function(...args) {
return wrap(func.apply(unwrap(this), args));
};
}
function transformCachableValue(value) {
if (typeof value === "function") return wrapFunction(value);
if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
return value;
}
function wrap(value) {
if (value instanceof IDBRequest) return promisifyRequest(value);
if (transformCache.has(value)) return transformCache.get(value);
const newValue = transformCachableValue(value);
if (newValue !== value) {
transformCache.set(value, newValue);
reverseTransformCache.set(newValue, value);
}
return newValue;
}
var unwrap = (value) => reverseTransformCache.get(value);
/**
* Open a database.
*
* @param name Name of the database.
* @param version Schema version.
* @param callbacks Additional callbacks.
*/
function openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {
const request = indexedDB.open(name, version);
const openPromise = wrap(request);
if (upgrade) request.addEventListener("upgradeneeded", (event) => {
upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
});
if (blocked) request.addEventListener("blocked", (event) => blocked(event.oldVersion, event.newVersion, event));
openPromise.then((db) => {
if (terminated) db.addEventListener("close", () => terminated());
if (blocking) db.addEventListener("versionchange", (event) => blocking(event.oldVersion, event.newVersion, event));
}).catch(() => {});
return openPromise;
}
var readMethods = [
"get",
"getKey",
"getAll",
"getAllKeys",
"count"
];
var writeMethods = [
"put",
"add",
"delete",
"clear"
];
var cachedMethods = /* @__PURE__ */ new Map();
function getMethod(target, prop) {
if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === "string")) return;
if (cachedMethods.get(prop)) return cachedMethods.get(prop);
const targetFuncName = prop.replace(/FromIndex$/, "");
const useIndex = prop !== targetFuncName;
const isWrite = writeMethods.includes(targetFuncName);
if (!(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) return;
const method = async function(storeName, ...args) {
const tx = this.transaction(storeName, isWrite ? "readwrite" : "readonly");
let target = tx.store;
if (useIndex) target = target.index(args.shift());
return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
};
cachedMethods.set(prop, method);
return method;
}
replaceTraps((oldTraps) => ({
...oldTraps,
get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
}));
var advanceMethodProps = [
"continue",
"continuePrimaryKey",
"advance"
];
var methodMap = {};
var advanceResults = /* @__PURE__ */ new WeakMap();
var ittrProxiedCursorToOriginalProxy = /* @__PURE__ */ new WeakMap();
var cursorIteratorTraps = { get(target, prop) {
if (!advanceMethodProps.includes(prop)) return target[prop];
let cachedFunc = methodMap[prop];
if (!cachedFunc) cachedFunc = methodMap[prop] = function(...args) {
advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
};
return cachedFunc;
} };
async function* iterate(...args) {
let cursor = this;
if (!(cursor instanceof IDBCursor)) cursor = await cursor.openCursor(...args);
if (!cursor) return;
cursor = cursor;
const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
reverseTransformCache.set(proxiedCursor, unwrap(cursor));
while (cursor) {
yield proxiedCursor;
cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
advanceResults.delete(proxiedCursor);
}
}
function isIteratorProp(target, prop) {
return prop === Symbol.asyncIterator && instanceOfAny(target, [
IDBIndex,
IDBObjectStore,
IDBCursor
]) || prop === "iterate" && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
}
replaceTraps((oldTraps) => ({
...oldTraps,
get(target, prop, receiver) {
if (isIteratorProp(target, prop)) return iterate;
return oldTraps.get(target, prop, receiver);
},
has(target, prop) {
return isIteratorProp(target, prop) || oldTraps.has(target, prop);
}
}));
//#endregion
//#region src/lib/storage/db.js
/**
* IndexedDB storage layer using the `idb` wrapper.
*
* Database: "password-vault"
* - Object store "entries": stores CredentialEntry objects
* - Object store "groups": stores Group objects
* - Object store "meta": stores app metadata (salt, test payload, version)
*
* All passwords are stored as encrypted blobs (encryptedPassword field).
* The encryption key is never stored — only the salt and a test payload
* for password verification.
*/
var DB_NAME = "password-vault";
var DB_VERSION = 1;
/**
* Open (or create) the database.
* @returns {Promise<IDBPDatabase>}
*/
async function getDb() {
return openDB(DB_NAME, DB_VERSION, { upgrade(db) {
if (!db.objectStoreNames.contains("entries")) {
const entryStore = db.createObjectStore("entries", { keyPath: "id" });
entryStore.createIndex("groupId", "groupId");
entryStore.createIndex("updatedAt", "updatedAt");
}
if (!db.objectStoreNames.contains("groups")) db.createObjectStore("groups", { keyPath: "id" });
if (!db.objectStoreNames.contains("meta")) db.createObjectStore("meta", { keyPath: "key" });
} });
}
/**
* Store the vault's salt and test payload (used for password verification).
*
* @param {Uint8Array} salt
* @param {string} testEncrypted
* @param {string} testPlaintext
*/
async function saveVaultMeta(salt, testEncrypted, testPlaintext) {
const tx = (await getDb()).transaction("meta", "readwrite");
let binary = "";
for (let i = 0; i < salt.byteLength; i++) binary += String.fromCharCode(salt[i]);
const saltBase64 = btoa(binary);
await tx.store.put({
key: "salt",
value: saltBase64
});
await tx.store.put({
key: "testEncrypted",
value: testEncrypted
});
await tx.store.put({
key: "testPlaintext",
value: testPlaintext
});
await tx.store.put({
key: "dbVersion",
value: DB_VERSION
});
await tx.done;
}
/**
* Load the vault's salt and test payload.
*
* @returns {Promise<{ salt: Uint8Array|null, testEncrypted: string|null, testPlaintext: string|null }>}
*/
async function loadVaultMeta() {
const store = (await getDb()).transaction("meta", "readonly").store;
const saltRow = await store.get("salt");
const testEncryptedRow = await store.get("testEncrypted");
const testPlaintextRow = await store.get("testPlaintext");
let salt = null;
if (saltRow?.value) {
const binary = atob(saltRow.value);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
salt = bytes;
}
return {
salt,
testEncrypted: testEncryptedRow?.value || null,
testPlaintext: testPlaintextRow?.value || null
};
}
/**
* Check if the vault has been initialized (has a salt stored).
* @returns {Promise<boolean>}
*/
async function isVaultInitialized() {
return (await loadVaultMeta()).salt !== null;
}
/**
* @typedef {import('../models/schema.js').Group} Group
*/
/**
* Add a group.
* @param {Group} group
* @returns {Promise<void>}
*/
async function addGroup(group) {
await (await getDb()).put("groups", group);
}
/**
* Update a group.
* @param {Group} group
* @returns {Promise<void>}
*/
async function updateGroup(group) {
await (await getDb()).put("groups", group);
}
/**
* Delete a group (does NOT delete associated entries — they become ungrouped).
* @param {string} groupId
* @returns {Promise<void>}
*/
async function deleteGroup(groupId) {
await (await getDb()).delete("groups", groupId);
}
/**
* Get all groups, sorted by creation date.
* @returns {Promise<Group[]>}
*/
async function getGroups() {
return (await (await getDb()).transaction("groups", "readonly").store.getAll()).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
}
/**
* @typedef {import('../models/schema.js').CredentialEntry} CredentialEntry
*/
/**
* Add an entry.
* @param {CredentialEntry} entry
* @returns {Promise<void>}
*/
async function addEntry(entry) {
await (await getDb()).put("entries", entry);
}
/**
* Update an entry.
* @param {CredentialEntry} entry
* @returns {Promise<void>}
*/
async function updateEntry(entry) {
await (await getDb()).put("entries", entry);
}
/**
* Delete an entry.
* @param {string} entryId
* @returns {Promise<void>}
*/
async function deleteEntry(entryId) {
await (await getDb()).delete("entries", entryId);
}
/**
* Get a single entry by ID.
* @param {string} entryId
* @returns {Promise<CredentialEntry | undefined>}
*/
async function getEntryById(entryId) {
return (await getDb()).get("entries", entryId);
}
/**
* Get all entries. Optionally filter by groupId.
* Results sorted by updatedAt descending (most recent first).
*
* @param {Object} [options]
* @param {string} [options.groupId] - Filter by group (empty string = ungrouped)
* @returns {Promise<CredentialEntry[]>}
*/
async function getEntries(options = {}) {
const db = await getDb();
let entries;
if (options.groupId !== void 0) entries = await db.transaction("entries").store.index("groupId").getAll(options.groupId);
else entries = await db.getAll("entries");
return entries.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
}
/**
* Search entries by query string (matches title, username, url, notes).
*
* @param {string} query
* @param {Object} [options]
* @param {string} [options.groupId]
* @returns {Promise<CredentialEntry[]>}
*/
async function searchEntries(query, options = {}) {
const entries = await getEntries(options);
const lower = query.toLowerCase();
return entries.filter((e) => e.title.toLowerCase().includes(lower) || e.username.toLowerCase().includes(lower) || e.url && e.url.toLowerCase().includes(lower) || e.notes && e.notes.toLowerCase().includes(lower));
}
/**
* Count entries per group.
* @returns {Promise<Map<string, number>>}
*/
async function getEntryCountsByGroup() {
const all = await (await getDb()).getAll("entries");
const counts = /* @__PURE__ */ new Map();
for (const entry of all) {
const gid = entry.groupId || "";
counts.set(gid, (counts.get(gid) || 0) + 1);
}
return counts;
}
/**
* Export all data (entries + groups + meta) as a JSON object.
* Entries remain encrypted with the source vault's key. The import function
* requires the source vault's master password to decrypt and re-encrypt
* entries under the target vault's key.
*
* @returns {Promise<Object>}
*/
async function exportAll() {
const db = await getDb();
const entries = await db.getAll("entries");
const groups = await db.getAll("groups");
const saltRow = await db.get("meta", "salt");
const testEncryptedRow = await db.get("meta", "testEncrypted");
const testPlaintextRow = await db.get("meta", "testPlaintext");
return {
version: DB_VERSION,
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
meta: {
salt: saltRow?.value || null,
testEncrypted: testEncryptedRow?.value || null,
testPlaintext: testPlaintextRow?.value || null
},
groups,
entries
};
}
/**
* Import data from a previously exported JSON object.
*
* Requires the source vault's master password to decrypt entries, then
* re-encrypts them under the target vault's current encryption key.
* The target vault's meta (salt, test payload) is never overwritten.
*
* @param {Object} data
* @param {'merge'|'replace'} mode - 'merge' adds to existing, 'replace' clears first
* @param {string} sourcePassword - Master password of the source vault
* @param {CryptoKey} targetKey - Current encryption key of the target vault
* @returns {Promise<{ imported: { entries: number, groups: number }, skipped: number }>}
*/
async function importAll(data, mode = "merge", sourcePassword = "", targetKey = null) {
if (!data || !Array.isArray(data.entries) || !Array.isArray(data.groups)) throw new Error("Invalid import data format");
let sourceKey = null;
if (data.meta?.salt && sourcePassword) sourceKey = await deriveKey(sourcePassword, base64ToUint8Array(data.meta.salt));
const db = await getDb();
if (mode === "replace") {
await db.clear("entries");
await db.clear("groups");
}
let skipped = 0;
let importedEntries = 0;
let importedGroups = 0;
for (const group of data.groups) try {
await db.put("groups", group);
importedGroups++;
} catch {
skipped++;
}
for (const entry of data.entries) try {
let reencryptedEntry = { ...entry };
if (sourceKey && targetKey && entry.encryptedPassword) reencryptedEntry.encryptedPassword = await encrypt(await decrypt(entry.encryptedPassword, sourceKey), targetKey);
else if (!sourceKey || !targetKey) {
console.warn("Skipping entry (missing source password or target key):", entry.title);
skipped++;
continue;
}
await db.put("entries", reencryptedEntry);
importedEntries++;
} catch (e) {
console.warn("Failed to import entry:", entry.title, e);
skipped++;
}
return {
imported: {
entries: importedEntries,
groups: importedGroups
},
skipped
};
}
//#endregion
//#region src/lib/autofocus.js
/**
* Action that autofocuses an element after mount when the condition is truthy.
* Uses a microtask to ensure the element is fully rendered.
*/
function autofocus(node, condition = true) {
if (condition) queueMicrotask(() => node.focus());
}
//#endregion
//#region src/components/LockScreen.svelte
var root_1$8 = /* @__PURE__ */ from_html(`<div class="error-banner svelte-7sq1ct" role="alert"> </div>`);
var root_2$6 = /* @__PURE__ */ from_html(`<div class="form-group"><label for="confirm-password">Confirm Password</label> <input id="confirm-password" type="password" placeholder="Confirm master password" autocomplete="new-password"/></div>`);
var root$7 = /* @__PURE__ */ from_html(`<div class="lock-screen svelte-7sq1ct"><div class="lock-card svelte-7sq1ct"><div class="lock-icon svelte-7sq1ct">🔐</div> <h1 class="svelte-7sq1ct">Password Vault</h1> <p class="subtitle svelte-7sq1ct"> </p> <!> <form class="lock-form svelte-7sq1ct"><div class="form-group"><label for="master-password">Master Password</label> <input id="master-password" type="password" placeholder="Enter master password" autocomplete="current-password"/></div> <!> <button type="submit" class="btn btn-primary w-full"> </button></form> <p class="hint svelte-7sq1ct"> </p></div></div>`);
function LockScreen($$anchor, $$props) {
push($$props, true);
let masterPassword = /* @__PURE__ */ state("");
let confirmPassword = /* @__PURE__ */ state("");
let error = /* @__PURE__ */ state("");
let loading = /* @__PURE__ */ state(false);
let isSetup = /* @__PURE__ */ state(false);
async function checkVault() {
set(isSetup, !await isVaultInitialized());
}
checkVault();
async function handleSubmit() {
set(error, "");
set(loading, true);
try {
if (get(isSetup)) {
if (!get(masterPassword) || get(masterPassword).length < 4) {
set(error, "Password must be at least 4 characters");
set(loading, false);
return;
}
if (get(masterPassword) !== get(confirmPassword)) {
set(error, "Passwords do not match");
set(loading, false);
return;
}
const { salt, testEncrypted, testPlaintext } = await createTestPayload(get(masterPassword));
app$1.salt = salt;
app$1.encryptionKey = await deriveKey(get(masterPassword), salt);
await saveVaultMeta(salt, testEncrypted, testPlaintext);
app$1.isUnlocked = true;
startAutoLock();
} else {
const meta = await loadVaultMeta();
if (!meta.salt || !meta.testEncrypted || !meta.testPlaintext) {
set(error, "Vault data corrupted");
set(loading, false);
return;
}
const key = await deriveKey(get(masterPassword), meta.salt);
if (!await verifyPassword(get(masterPassword), meta.salt, meta.testEncrypted, meta.testPlaintext)) {
set(error, "Incorrect password");
set(loading, false);
return;
}
app$1.salt = meta.salt;
app$1.encryptionKey = key;
app$1.isUnlocked = true;
startAutoLock();
}
} catch (e) {
console.error(e);
set(error, "An error occurred: " + e.message);
}
set(loading, false);
set(masterPassword, "");
set(confirmPassword, "");
}
var div = root$7();
var div_1 = child(div);
var p = sibling(child(div_1), 4);
var text = child(p, true);
reset(p);
var node = sibling(p, 2);
var consequent = ($$anchor) => {
var div_2 = root_1$8();
var text_1 = child(div_2, true);
reset(div_2);
template_effect(() => set_text(text_1, get(error)));
append($$anchor, div_2);
};
if_block(node, ($$render) => {
if (get(error)) $$render(consequent);
});
var form = sibling(node, 2);
var div_3 = child(form);
var input = sibling(child(div_3), 2);
remove_input_defaults(input);
effect(() => bind_value(input, () => get(masterPassword), ($$value) => set(masterPassword, $$value)));
action(input, ($$node) => autofocus?.($$node));
reset(div_3);
var node_1 = sibling(div_3, 2);
var consequent_1 = ($$anchor) => {
var div_4 = root_2$6();
var input_1 = sibling(child(div_4), 2);
remove_input_defaults(input_1);
reset(div_4);
template_effect(() => input_1.disabled = get(loading));
bind_value(input_1, () => get(confirmPassword), ($$value) => set(confirmPassword, $$value));
append($$anchor, div_4);
};
if_block(node_1, ($$render) => {
if (get(isSetup)) $$render(consequent_1);
});
var button = sibling(node_1, 2);
var text_2 = child(button, true);
reset(button);
reset(form);
var p_1 = sibling(form, 2);
var text_3 = child(p_1, true);
reset(p_1);
reset(div_1);
reset(div);
template_effect(() => {
set_text(text, get(isSetup) ? "Create your vault" : "Unlock your vault");
input.disabled = get(loading);
button.disabled = get(loading);
set_text(text_2, get(loading) ? "Processing..." : get(isSetup) ? "Create Vault" : "Unlock");
set_text(text_3, get(isSetup) ? "Your master password encrypts all data locally. It cannot be recovered if lost." : "Your data is encrypted with AES-256-GCM. Key is stored only in memory.");
});
event("submit", form, (e) => {
e.preventDefault();
handleSubmit();
});
append($$anchor, div);
pop();
}
//#endregion
//#region src/lib/stores/search.svelte.js
var SearchStore = class {
#query = /* @__PURE__ */ state("");
get query() {
return get(this.#query);
}
set query(value) {
set(this.#query, value, true);
}
#activeGroupId = /* @__PURE__ */ state("all");
get activeGroupId() {
return get(this.#activeGroupId);
}
set activeGroupId(value) {
set(this.#activeGroupId, value, true);
}
#refreshTrigger = /* @__PURE__ */ state(0);
get refreshTrigger() {
return get(this.#refreshTrigger);
}
set refreshTrigger(value) {
set(this.#refreshTrigger, value, true);
}
clear() {
this.query = "";
this.activeGroupId = "all";
}
/** Force subscribed components to re-fetch data. */
refresh() {
this.refreshTrigger++;
}
};
var search = new SearchStore();
//#endregion
//#region src/components/Sidebar.svelte
var root_1$7 = /* @__PURE__ */ from_html(`<div class="group-row svelte-181dlmc"><button><span class="group-color svelte-181dlmc"></span> <span class="group-name svelte-181dlmc"> </span></button> <div class="group-actions svelte-181dlmc"><button class="group-action-btn svelte-181dlmc" title="Edit group">✏️</button> <button class="group-action-btn svelte-181dlmc" title="Delete group">🗑</button></div></div>`);
var root_3$5 = /* @__PURE__ */ from_html(`<div class="error-banner svelte-181dlmc"> </div>`);
var root_4$5 = /* @__PURE__ */ from_html(`<button></button>`);
var root_2$5 = /* @__PURE__ */ from_html(`<div class="modal-overlay svelte-181dlmc" role="presentation"><div class="modal svelte-181dlmc" role="dialog" aria-modal="true" aria-label="Group settings" tabindex="-1"><h3 class="svelte-181dlmc"> </h3> <!> <div class="form-group"><label for="group-name">Group Name</label> <input id="group-name" type="text" placeholder="e.g. Work, Personal"/></div> <div class="form-group"><span class="field-label">Color</span> <div class="color-picker svelte-181dlmc"></div></div> <div class="modal-actions svelte-181dlmc"><button class="btn btn-primary"> </button> <button class="btn btn-ghost">Cancel</button></div></div></div>`);
var root_5$4 = /* @__PURE__ */ from_html(`<div class="modal-overlay svelte-181dlmc" role="presentation"><div class="modal svelte-181dlmc" role="dialog" aria-modal="true" aria-label="Delete group confirmation" tabindex="-1"><h3 class="svelte-181dlmc">Delete Group</h3> <p class="svelte-181dlmc">Delete "<strong> </strong>"? Entries in this group will become ungrouped.</p> <div class="modal-actions svelte-181dlmc"><button class="btn btn-danger">Yes, delete</button> <button class="btn btn-ghost">Cancel</button></div></div></div>`);
var root$6 = /* @__PURE__ */ from_html(`<div class="sidebar-content svelte-181dlmc"><div class="sidebar-header svelte-181dlmc"><h2 class="svelte-181dlmc">🔐 Vault</h2></div> <div class="search-box svelte-181dlmc"><input type="text" placeholder="Search entries..." class="svelte-181dlmc"/></div> <nav class="groups-nav svelte-181dlmc"><button><span class="group-icon svelte-181dlmc">📋</span> <span class="group-name svelte-181dlmc">All Entries</span></button> <!></nav> <div class="sidebar-footer svelte-181dlmc"><button class="btn btn-ghost btn-sm w-full">+ New Group</button></div> <!> <!></div>`);
function Sidebar($$anchor, $$props) {
push($$props, true);
let groups = /* @__PURE__ */ state(proxy([]));
let entryCounts = /* @__PURE__ */ state(proxy(/* @__PURE__ */ new Map()));
let showGroupForm = /* @__PURE__ */ state(false);
let editingGroupId = /* @__PURE__ */ state(null);
let groupName = /* @__PURE__ */ state("");
let groupColor = /* @__PURE__ */ state("#6c63ff");
let groupError = /* @__PURE__ */ state("");
let showDeleteGroupConfirm = /* @__PURE__ */ state(null);
let deletingGroup = /* @__PURE__ */ user_derived(() => get(groups).find((g) => g.id === get(showDeleteGroupConfirm)));
const GROUP_COLORS = [
"#6c63ff",
"#e5484d",
"#34d399",
"#fbbf24",
"#3b82f6",
"#ec4899",
"#8b5cf6",
"#14b8a6",
"#f97316",
"#06b6d4",
"#a855f7",
"#ef4444",
"#22c55e",
"#eab308",
"#6366f1"
];
async function loadData() {
const [g, counts] = await Promise.all([getGroups(), getEntryCountsByGroup()]);
set(groups, g, true);
set(entryCounts, counts, true);
}
user_effect(() => {
search.refreshTrigger;
loadData();
});
function openGroupForm(group = null) {
if (group) {
set(editingGroupId, group.id, true);
set(groupName, group.name, true);
set(groupColor, group.color || "#6c63ff", true);
} else {
set(editingGroupId, null);
set(groupName, "");
set(groupColor, GROUP_COLORS[Math.floor(Math.random() * GROUP_COLORS.length)], true);
}
set(groupError, "");
set(showGroupForm, true);
}
async function saveGroup() {
set(groupError, "");
const validation = validateGroup(get(groupName));
if (!validation.valid) {
set(groupError, validation.errors[0], true);
return;
}
try {
if (get(editingGroupId)) await updateGroup({
...get(groups).find((g) => g.id === get(editingGroupId)),
name: get(groupName).trim(),
color: get(groupColor)
});
else await addGroup(createGroup(get(groupName), get(groupColor)));
set(showGroupForm, false);
await loadData();
} catch (e) {
set(groupError, "Failed to save group: " + e.message);
}
}
async function confirmDeleteGroup(groupId) {
try {
await deleteGroup(groupId);
if (search.activeGroupId === groupId) search.activeGroupId = "all";
set(showDeleteGroupConfirm, null);
await loadData();
} catch (e) {
set(groupError, "Failed to delete group: " + e.message);
}
}
var div = root$6();
var div_1 = sibling(child(div), 2);
var input = child(div_1);
remove_input_defaults(input);
reset(div_1);
var nav = sibling(div_1, 2);
var button = child(nav);
each(sibling(button, 2), 17, () => get(groups), index, ($$anchor, group) => {
var div_2 = root_1$7();
var button_1 = child(div_2);
var span = child(button_1);
var span_1 = sibling(span, 2);
var text = child(span_1, true);
reset(span_1);
reset(button_1);
var div_3 = sibling(button_1, 2);
var button_2 = child(div_3);
var button_3 = sibling(button_2, 2);
reset(div_3);
reset(div_2);
template_effect(() => {
set_class(button_1, 1, `group-item ${search.activeGroupId === get(group).id ? "active" : ""}`, "svelte-181dlmc");
set_style(span, `background-color: ${(get(group).color || "#6c63ff") ?? ""}`);
set_text(text, get(group).name);
});
delegated("click", button_1, () => search.activeGroupId = get(group).id);
delegated("click", button_2, () => openGroupForm(get(group)));
delegated("click", button_3, () => set(showDeleteGroupConfirm, get(group).id, true));
append($$anchor, div_2);
});
reset(nav);
var div_4 = sibling(nav, 2);
var button_4 = child(div_4);
reset(div_4);
var node_1 = sibling(div_4, 2);
var consequent_1 = ($$anchor) => {
var div_5 = root_2$5();
var div_6 = child(div_5);
var h3 = child(div_6);
var text_1 = child(h3, true);
reset(h3);
var node_2 = sibling(h3, 2);
var consequent = ($$anchor) => {
var div_7 = root_3$5();
var text_2 = child(div_7, true);
reset(div_7);
template_effect(() => set_text(text_2, get(groupError)));
append($$anchor, div_7);
};
if_block(node_2, ($$render) => {
if (get(groupError)) $$render(consequent);
});
var div_8 = sibling(node_2, 2);
var input_1 = sibling(child(div_8), 2);
remove_input_defaults(input_1);
effect(() => bind_value(input_1, () => get(groupName), ($$value) => set(groupName, $$value)));
action(input_1, ($$node, $$action_arg) => autofocus?.($$node, $$action_arg), () => !get(editingGroupId));
reset(div_8);
var div_9 = sibling(div_8, 2);
var div_10 = sibling(child(div_9), 2);
each(div_10, 21, () => GROUP_COLORS, index, ($$anchor, color) => {
var button_5 = root_4$5();
template_effect(() => {
set_class(button_5, 1, `color-swatch ${get(groupColor) === get(color) ? "selected" : ""}`, "svelte-181dlmc");
set_style(button_5, `background-color: ${get(color) ?? ""}`);
set_attribute(button_5, "title", get(color));
});
delegated("click", button_5, () => set(groupColor, get(color), true));
append($$anchor, button_5);
});
reset(div_10);
reset(div_9);
var div_11 = sibling(div_9, 2);
var button_6 = child(div_11);
var text_3 = child(button_6, true);
reset(button_6);
var button_7 = sibling(button_6, 2);
reset(div_11);
reset(div_6);
reset(div_5);
template_effect(() => {
set_text(text_1, get(editingGroupId) ? "Edit Group" : "New Group");
set_text(text_3, get(editingGroupId) ? "Update" : "Create");
});
delegated("click", div_5, () => set(showGroupForm, false));
delegated("click", div_6, (e) => e.stopPropagation());
delegated("click", button_6, saveGroup);
delegated("click", button_7, () => set(showGroupForm, false));
append($$anchor, div_5);
};
if_block(node_1, ($$render) => {
if (get(showGroupForm)) $$render(consequent_1);
});
var node_3 = sibling(node_1, 2);
var consequent_2 = ($$anchor) => {
var div_12 = root_5$4();
var div_13 = child(div_12);
var p = sibling(child(div_13), 2);
var strong = sibling(child(p));
var text_4 = child(strong, true);
reset(strong);
next();
reset(p);
var div_14 = sibling(p, 2);
var button_8 = child(div_14);
var button_9 = sibling(button_8, 2);
reset(div_14);
reset(div_13);
reset(div_12);
template_effect(() => set_text(text_4, get(deletingGroup).name));
delegated("click", div_12, () => set(showDeleteGroupConfirm, null));
delegated("click", div_13, (e) => e.stopPropagation());
delegated("click", button_8, () => confirmDeleteGroup(get(deletingGroup).id));
delegated("click", button_9, () => set(showDeleteGroupConfirm, null));
append($$anchor, div_12);
};
if_block(node_3, ($$render) => {
if (get(deletingGroup)) $$render(consequent_2);
});
reset(div);
template_effect(() => {
set_value(input, search.query);
set_class(button, 1, `group-item ${search.activeGroupId === "all" ? "active" : ""}`, "svelte-181dlmc");
});
event("Input", input, (e) => search.query = e.target.value);
delegated("click", button, () => search.activeGroupId = "all");
delegated("click", button_4, () => openGroupForm(null));
append($$anchor, div);
pop();
}
delegate(["click"]);
//#endregion
//#region src/components/EntryList.svelte
var root_1$6 = /* @__PURE__ */ from_html(`<div class="loading svelte-13s7gu4">Loading entries...</div>`);
var root_2$4 = /* @__PURE__ */ from_html(`<div class="error-banner svelte-13s7gu4"> </div>`);
var root_4$4 = /* @__PURE__ */ from_html(`<button class="btn btn-primary mt-3">+ New Entry</button>`);
var root_3$4 = /* @__PURE__ */ from_html(`<div class="empty-state svelte-13s7gu4"><p class="empty-icon svelte-13s7gu4"> </p> <p class="empty-text svelte-13s7gu4"> </p> <p class="empty-hint svelte-13s7gu4"> </p> <!></div>`);
var root_6$4 = /* @__PURE__ */ from_html(`matching "<strong> </strong>"`, 1);
var root_7$2 = /* @__PURE__ */ from_html(`<tr class="entry-row svelte-13s7gu4"><td class="svelte-13s7gu4"><span class="entry-title svelte-13s7gu4"> </span></td><td class="svelte-13s7gu4"><span class="entry-username svelte-13s7gu4"> </span></td><td class="svelte-13s7gu4"><span class="entry-url truncate svelte-13s7gu4"> </span></td></tr>`);
var root_5$3 = /* @__PURE__ */ from_html(`<div class="results-info svelte-13s7gu4"><span class="text-sm text-muted"> <!></span></div> <table class="entries-table svelte-13s7gu4"><thead><tr><th class="svelte-13s7gu4">Title</th><th class="svelte-13s7gu4">Username</th><th class="svelte-13s7gu4">URL</th></tr></thead><tbody></tbody></table>`, 1);
var root$5 = /* @__PURE__ */ from_html(`<div class="entry-list"><!></div>`);
function EntryList($$anchor, $$props) {
push($$props, true);
let entries = /* @__PURE__ */ state(proxy([]));
let loading = /* @__PURE__ */ state(true);
let error = /* @__PURE__ */ state("");
let resultCount = /* @__PURE__ */ state(0);
async function loadEntries() {
set(loading, true);
set(error, "");
try {
const query = search.query.trim();
const groupId = search.activeGroupId;
if (query) set(entries, await searchEntries(query, groupId !== "all" ? { groupId } : {}), true);
else if (groupId !== "all") set(entries, await getEntries({ groupId }), true);
else set(entries, await getEntries(), true);
set(resultCount, get(entries).length, true);
} catch (e) {
set(error, "Failed to load entries: " + e.message);
}
set(loading, false);
}
user_effect(() => {
search.query;
search.activeGroupId;
search.refreshTrigger;
loadEntries();
});
var div = root$5();
var node = child(div);
var consequent = ($$anchor) => {
append($$anchor, root_1$6());
};
var consequent_1 = ($$anchor) => {
var div_2 = root_2$4();
var text = child(div_2, true);
reset(div_2);
template_effect(() => set_text(text, get(error)));
append($$anchor, div_2);
};
var consequent_3 = ($$anchor) => {
var div_3 = root_3$4();
var p = child(div_3);
var text_1 = child(p, true);
reset(p);
var p_1 = sibling(p, 2);
var text_2 = child(p_1, true);
reset(p_1);
var p_2 = sibling(p_1, 2);
var text_3 = child(p_2, true);
reset(p_2);
var node_1 = sibling(p_2, 2);
var consequent_2 = ($$anchor) => {
var button = root_4$4();
delegated("click", button, function(...$$args) {
$$props.onAdd?.apply(this, $$args);
});
append($$anchor, button);
};
if_block(node_1, ($$render) => {
if (!search.query) $$render(consequent_2);
});
reset(div_3);
template_effect(() => {
set_text(text_1, search.query ? "🔍" : "🔑");
set_text(text_2, search.query ? "No results found" : "No entries yet");
set_text(text_3, search.query ? "Try a different search term" : "Add your first login credential to get started");
});
append($$anchor, div_3);
};
var alternate = ($$anchor) => {
var fragment = root_5$3();
var div_4 = first_child(fragment);
var span = child(div_4);
var text_4 = child(span);
var node_2 = sibling(text_4);
var consequent_4 = ($$anchor) => {
var fragment_1 = root_6$4();
var strong = sibling(first_child(fragment_1));
var text_5 = child(strong, true);
reset(strong);
next();
template_effect(() => set_text(text_5, search.query));
append($$anchor, fragment_1);
};
if_block(node_2, ($$render) => {
if (search.query) $$render(consequent_4);
});
reset(span);
reset(div_4);
var table = sibling(div_4, 2);
var tbody = sibling(child(table));
each(tbody, 21, () => get(entries), (entry) => entry.id, ($$anchor, entry) => {
var tr = root_7$2();
var td = child(tr);
var span_1 = child(td);
var text_6 = child(span_1, true);
reset(span_1);
reset(td);
var td_1 = sibling(td);
var span_2 = child(td_1);
var text_7 = child(span_2, true);
reset(span_2);
reset(td_1);
var td_2 = sibling(td_1);
var span_3 = child(td_2);
var text_8 = child(span_3, true);
reset(span_3);
reset(td_2);
reset(tr);
template_effect(() => {
set_text(text_6, get(entry).title);
set_text(text_7, get(entry).username || "—");
set_text(text_8, get(entry).url || "—");
});
delegated("click", tr, () => $$props.onSelect(get(entry).id));
append($$anchor, tr);
});
reset(tbody);
reset(table);
template_effect(() => set_text(text_4, `${get(resultCount) ?? ""} entr${get(resultCount) === 1 ? "y" : "ies"} `));
append($$anchor, fragment);
};
if_block(node, ($$render) => {
if (get(loading)) $$render(consequent);
else if (get(error)) $$render(consequent_1, 1);
else if (get(entries).length === 0) $$render(consequent_3, 2);
else $$render(alternate, -1);
});
reset(div);
append($$anchor, div);
pop();
}
delegate(["click"]);
//#endregion
//#region src/components/EntryDetail.svelte
var root_1$5 = /* @__PURE__ */ from_html(`<div class="toast svelte-dssgjx"> </div>`);
var root_2$3 = /* @__PURE__ */ from_html(`<div class="loading svelte-dssgjx">Loading...</div>`);
var root_3$3 = /* @__PURE__ */ from_html(`<div class="error-banner svelte-dssgjx"> </div>`);
var root_4$3 = /* @__PURE__ */ from_html(`<div class="empty-state svelte-dssgjx">Entry not found</div>`);
var root_6$3 = /* @__PURE__ */ from_html(`<div class="detail-field"><span class="field-label svelte-dssgjx">Username</span> <div class="field-value svelte-dssgjx"><span> </span> <button class="btn btn-ghost btn-sm copy-btn svelte-dssgjx" title="Copy username">📋</button></div></div>`);
var root_7$1 = /* @__PURE__ */ from_html(`<div class="detail-field"><span class="field-label svelte-dssgjx">URL</span> <div class="field-value svelte-dssgjx"><a target="_blank" rel="noopener noreferrer" class="svelte-dssgjx"> </a> <button class="btn btn-ghost btn-sm copy-btn svelte-dssgjx" title="Copy URL">📋</button></div></div>`);
var root_8 = /* @__PURE__ */ from_html(`<div class="detail-field"><span class="field-label svelte-dssgjx">Notes</span> <div class="field-value notes svelte-dssgjx"> </div></div>`);
var root_9 = /* @__PURE__ */ from_html(`<div class="modal-overlay svelte-dssgjx" role="presentation"><div class="modal svelte-dssgjx" role="dialog" aria-modal="true" aria-label="Delete confirmation" tabindex="-1"><h3 class="svelte-dssgjx">Delete Entry</h3> <p class="svelte-dssgjx">Are you sure you want to delete "<strong> </strong>"? This cannot be undone.</p> <div class="modal-actions svelte-dssgjx"><button class="btn btn-danger"> </button> <button class="btn btn-ghost">Cancel</button></div></div></div>`);
var root_5$2 = /* @__PURE__ */ from_html(`<div class="detail-card svelte-dssgjx"><div class="detail-header svelte-dssgjx"><h2 class="svelte-dssgjx"> </h2> <div class="header-actions svelte-dssgjx"><button class="btn btn-ghost btn-sm">✏️ Edit</button> <button class="btn btn-danger btn-sm">🗑 Delete</button></div></div> <div class="detail-fields svelte-dssgjx"><!> <div class="detail-field"><span class="field-label svelte-dssgjx">Password</span> <div class="field-value svelte-dssgjx"><span> </span> <button class="btn btn-ghost btn-sm" title="Toggle visibility"> </button> <button class="btn btn-ghost btn-sm copy-btn svelte-dssgjx" title="Copy password">📋</button></div></div> <!> <!></div> <div class="detail-meta svelte-dssgjx"><span class="text-xs text-muted"> </span> <span class="text-xs text-muted"> </span></div></div> <!>`, 1);
var root$4 = /* @__PURE__ */ from_html(`<div class="entry-detail"><!> <!></div>`);
function EntryDetail($$anchor, $$props) {
push($$props, true);
let entry = /* @__PURE__ */ state(null);
let passwordVisible = /* @__PURE__ */ state(false);
let decryptedPassword = /* @__PURE__ */ state("");
let loading = /* @__PURE__ */ state(true);
let error = /* @__PURE__ */ state("");
let showDeleteConfirm = /* @__PURE__ */ state(false);
let deleting = /* @__PURE__ */ state(false);
let toast = /* @__PURE__ */ state("");
let toastTimer = null;
async function loadEntry() {
set(loading, true);
set(error, "");
try {
set(entry, await getEntryById($$props.entryId), true);
if (get(entry) && app$1.encryptionKey) set(decryptedPassword, await decrypt(get(entry).encryptedPassword, app$1.encryptionKey), true);
} catch (e) {
set(error, "Failed to load entry: " + e.message);
}
set(loading, false);
}
loadEntry();
function showToast(message) {
set(toast, message, true);
if (toastTimer) clearTimeout(toastTimer);
toastTimer = setTimeout(() => {
set(toast, "");
}, 3e3);
}
async function copyToClipboard(text, label) {
try {
await navigator.clipboard.writeText(text);
showToast(`${label} copied (auto-clear in 15s)`);
setTimeout(async () => {
try {
await navigator.clipboard.writeText("");
} catch {}
}, 15e3);
} catch (e) {
const textarea = document.createElement("textarea");
textarea.value = text;
textarea.style.position = "fixed";
textarea.style.opacity = "0";
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
showToast(`${label} copied`);
}
}
async function handleDelete() {
set(deleting, true);
try {
await deleteEntry($$props.entryId);
$$props.onBack();
} catch (e) {
set(error, "Failed to delete: " + e.message);
}
set(deleting, false);
set(showDeleteConfirm, false);
}
var div = root$4();
var node = child(div);
var consequent = ($$anchor) => {
var div_1 = root_1$5();
var text_1 = child(div_1, true);
reset(div_1);
template_effect(() => set_text(text_1, get(toast)));
append($$anchor, div_1);
};
if_block(node, ($$render) => {
if (get(toast)) $$render(consequent);
});
var node_1 = sibling(node, 2);
var consequent_1 = ($$anchor) => {
append($$anchor, root_2$3());
};
var consequent_2 = ($$anchor) => {
var div_3 = root_3$3();
var text_2 = child(div_3, true);
reset(div_3);
template_effect(() => set_text(text_2, get(error)));
append($$anchor, div_3);
};
var consequent_3 = ($$anchor) => {
append($$anchor, root_4$3());
};
var alternate = ($$anchor) => {
var fragment = root_5$2();
var div_5 = first_child(fragment);
var div_6 = child(div_5);
var h2 = child(div_6);
var text_3 = child(h2, true);
reset(h2);
var div_7 = sibling(h2, 2);
var button = child(div_7);
var button_1 = sibling(button, 2);
reset(div_7);
reset(div_6);
var div_8 = sibling(div_6, 2);
var node_2 = child(div_8);
var consequent_4 = ($$anchor) => {
var div_9 = root_6$3();
var div_10 = sibling(child(div_9), 2);
var span = child(div_10);
var text_4 = child(span, true);
reset(span);
var button_2 = sibling(span, 2);
reset(div_10);
reset(div_9);
template_effect(() => set_text(text_4, get(entry).username));
delegated("click", button_2, () => copyToClipboard(get(entry).username, "Username"));
append($$anchor, div_9);
};
if_block(node_2, ($$render) => {
if (get(entry).username) $$render(consequent_4);
});
var div_11 = sibling(node_2, 2);
var div_12 = sibling(child(div_11), 2);
var span_1 = child(div_12);
var text_5 = child(span_1, true);
reset(span_1);
var button_3 = sibling(span_1, 2);
var text_6 = child(button_3, true);
reset(button_3);
var button_4 = sibling(button_3, 2);
reset(div_12);
reset(div_11);
var node_3 = sibling(div_11, 2);
var consequent_5 = ($$anchor) => {
var div_13 = root_7$1();
var div_14 = sibling(child(div_13), 2);
var a = child(div_14);
var text_7 = child(a, true);
reset(a);
var button_5 = sibling(a, 2);
reset(div_14);
reset(div_13);
template_effect(() => {
set_attribute(a, "href", get(entry).url);
set_text(text_7, get(entry).url);
});
delegated("click", button_5, () => copyToClipboard(get(entry).url, "URL"));
append($$anchor, div_13);
};
if_block(node_3, ($$render) => {
if (get(entry).url) $$render(consequent_5);
});
var node_4 = sibling(node_3, 2);
var consequent_6 = ($$anchor) => {
var div_15 = root_8();
var div_16 = sibling(child(div_15), 2);
var text_8 = child(div_16, true);
reset(div_16);
reset(div_15);
template_effect(() => set_text(text_8, get(entry).notes));
append($$anchor, div_15);
};
if_block(node_4, ($$render) => {
if (get(entry).notes) $$render(consequent_6);
});
reset(div_8);
var div_17 = sibling(div_8, 2);
var span_2 = child(div_17);
var text_9 = child(span_2);
reset(span_2);
var span_3 = sibling(span_2, 2);
var text_10 = child(span_3);
reset(span_3);
reset(div_17);
reset(div_5);
var node_5 = sibling(div_5, 2);
var consequent_7 = ($$anchor) => {
var div_18 = root_9();
var div_19 = child(div_18);
var p = sibling(child(div_19), 2);
var strong = sibling(child(p));
var text_11 = child(strong, true);
reset(strong);
next();
reset(p);
var div_20 = sibling(p, 2);
var button_6 = child(div_20);
var text_12 = child(button_6, true);
reset(button_6);
var button_7 = sibling(button_6, 2);
reset(div_20);
reset(div_19);
reset(div_18);
template_effect(() => {
set_text(text_11, get(entry).title);
button_6.disabled = get(deleting);
set_text(text_12, get(deleting) ? "Deleting..." : "Yes, delete");
});
delegated("click", div_18, () => set(showDeleteConfirm, false));
delegated("click", div_19, (e) => e.stopPropagation());
delegated("click", button_6, handleDelete);
delegated("click", button_7, () => set(showDeleteConfirm, false));
append($$anchor, div_18);
};
if_block(node_5, ($$render) => {
if (get(showDeleteConfirm)) $$render(consequent_7);
});
template_effect(($0, $1) => {
set_text(text_3, get(entry).title);
set_text(text_5, get(passwordVisible) ? get(decryptedPassword) : "••••••••••••");
set_text(text_6, get(passwordVisible) ? "🙈" : "👁");
set_text(text_9, `Created: ${$0 ?? ""}`);
set_text(text_10, `Updated: ${$1 ?? ""}`);
}, [() => new Date(get(entry).createdAt).toLocaleString(), () => new Date(get(entry).updatedAt).toLocaleString()]);
delegated("click", button, () => $$props.onEdit(get(entry).id));
delegated("click", button_1, () => set(showDeleteConfirm, true));
delegated("click", button_3, () => set(passwordVisible, !get(passwordVisible)));
delegated("click", button_4, () => copyToClipboard(get(decryptedPassword), "Password"));
append($$anchor, fragment);
};
if_block(node_1, ($$render) => {
if (get(loading)) $$render(consequent_1);
else if (get(error)) $$render(consequent_2, 1);
else if (!get(entry)) $$render(consequent_3, 2);
else $$render(alternate, -1);
});
reset(div);
append($$anchor, div);
pop();
}
delegate(["click"]);
delegate(["click"]);
//#endregion
//#region src/components/EntryForm.svelte
var root_1$3 = /* @__PURE__ */ from_html(`<div class="loading svelte-pafazm">Loading...</div>`);
var root_3$2 = /* @__PURE__ */ from_html(`<div class="error-banner svelte-pafazm"> </div>`);
var root_5$1 = /* @__PURE__ */ from_html(`<div class="validation-error svelte-pafazm"> </div>`);
var root_4$2 = /* @__PURE__ */ from_html(`<div class="validation-errors svelte-pafazm"></div>`);
var root_6$2 = /* @__PURE__ */ from_html(`<option> </option>`);
var root_2$2 = /* @__PURE__ */ from_html(`<!> <form class="form-card svelte-pafazm"><!> <div class="form-group"><label for="title">Title *</label> <input id="title" type="text" placeholder="e.g. GitHub, Gmail"/></div> <div class="form-group"><label for="username">Username / Email</label> <input id="username" type="text" placeholder="username or email"/></div> <div class="form-group"><label for="password">Password *</label> <div class="password-input-group svelte-pafazm"><input id="password" placeholder="Password" class="svelte-pafazm"/> <button type="button" class="btn btn-ghost btn-sm" title="Toggle visibility"> </button> <button type="button" class="btn btn-ghost btn-sm" title="Generate password">🎲</button></div></div> <div class="form-group"><label for="url">URL</label> <input id="url" type="url" placeholder="https://example.com"/></div> <div class="form-group"><label for="group">Group</label> <select id="group"><option>No group</option><!></select></div> <div class="form-group"><label for="notes">Notes</label> <textarea id="notes" placeholder="Any additional notes..."></textarea></div> <div class="form-actions svelte-pafazm"><button type="submit" class="btn btn-primary"> </button> <button type="button" class="btn btn-ghost">Cancel</button></div></form>`, 1);
var root$2 = /* @__PURE__ */ from_html(`<div class="entry-form"><!></div>`);
function EntryForm($$anchor, $$props) {
push($$props, true);
let title = /* @__PURE__ */ state("");
let username = /* @__PURE__ */ state("");
let password = /* @__PURE__ */ state("");
let url = /* @__PURE__ */ state("");
let notes = /* @__PURE__ */ state("");
let groupId = /* @__PURE__ */ state("");
let passwordVisible = /* @__PURE__ */ state(false);
let groups = /* @__PURE__ */ state(proxy([]));
let loading = /* @__PURE__ */ state(true);
let error = /* @__PURE__ */ state("");
let saving = /* @__PURE__ */ state(false);
let isEdit = /* @__PURE__ */ state(false);
let formErrors = /* @__PURE__ */ state(proxy([]));
async function loadForm() {
set(loading, true);
try {
set(groups, await getGroups(), true);
if ($$props.entryId) {
set(isEdit, true);
const entry = await getEntryById($$props.entryId);
if (entry) {
set(title, entry.title, true);
set(username, entry.username, true);
set(password, await decrypt(entry.encryptedPassword, app$1.encryptionKey), true);
set(url, entry.url || "", true);
set(notes, entry.notes || "", true);
set(groupId, entry.groupId || "", true);
} else set(error, "Entry not found");
}
} catch (e) {
set(error, "Failed to load form: " + e.message);
}
set(loading, false);
}
loadForm();
async function handleSubmit() {
set(formErrors, [], true);
set(error, "");
set(saving, true);
try {
const validation = validateEntry({
title: get(title),
username: get(username),
encryptedPassword: get(password)
});
if (!validation.valid) {
set(formErrors, validation.errors, true);
set(saving, false);
return;
}
const encryptedPassword = await encrypt(get(password), app$1.encryptionKey);
if (get(isEdit)) await updateEntry(updateEntry$1(await getEntryById($$props.entryId), {
title: get(title),
username: get(username),
encryptedPassword,
url: get(url),
notes: get(notes),
groupId: get(groupId)
}));
else await addEntry(createEntry({
title: get(title),
username: get(username),
encryptedPassword,
url: get(url),
notes: get(notes),
groupId: get(groupId)
}));
$$props.onSave();
} catch (e) {
set(error, "Failed to save: " + e.message);
}
set(saving, false);
}
var div = root$2();
var node = child(div);
var consequent = ($$anchor) => {
append($$anchor, root_1$3());
};
var alternate = ($$anchor) => {
var fragment = root_2$2();
var node_1 = first_child(fragment);
var consequent_1 = ($$anchor) => {
var div_2 = root_3$2();
var text = child(div_2, true);
reset(div_2);
template_effect(() => set_text(text, get(error)));
append($$anchor, div_2);
};
if_block(node_1, ($$render) => {
if (get(error)) $$render(consequent_1);
});
var form = sibling(node_1, 2);
var node_2 = child(form);
var consequent_2 = ($$anchor) => {
var div_3 = root_4$2();
each(div_3, 21, () => get(formErrors), index, ($$anchor, err) => {
var div_4 = root_5$1();
var text_1 = child(div_4);
reset(div_4);
template_effect(() => set_text(text_1, `${get(err) ?? ""}`));
append($$anchor, div_4);
});
reset(div_3);
append($$anchor, div_3);
};
if_block(node_2, ($$render) => {
if (get(formErrors).length > 0) $$render(consequent_2);
});
var div_5 = sibling(node_2, 2);
var input = sibling(child(div_5), 2);
remove_input_defaults(input);
effect(() => bind_value(input, () => get(title), ($$value) => set(title, $$value)));
action(input, ($$node, $$action_arg) => autofocus?.($$node, $$action_arg), () => !get(isEdit));
reset(div_5);
var div_6 = sibling(div_5, 2);
var input_1 = sibling(child(div_6), 2);
remove_input_defaults(input_1);
reset(div_6);
var div_7 = sibling(div_6, 2);
var div_8 = sibling(child(div_7), 2);
var input_2 = child(div_8);
remove_input_defaults(input_2);
var button = sibling(input_2, 2);
var text_2 = child(button, true);
reset(button);
var button_1 = sibling(button, 2);
reset(div_8);
reset(div_7);
var div_9 = sibling(div_7, 2);
var input_3 = sibling(child(div_9), 2);
remove_input_defaults(input_3);
reset(div_9);
var div_10 = sibling(div_9, 2);
var select = sibling(child(div_10), 2);
var option = child(select);
option.value = option.__value = "";
each(sibling(option), 17, () => get(groups), index, ($$anchor, group) => {
var option_1 = root_6$2();
var text_3 = child(option_1, true);
reset(option_1);
var option_1_value = {};
template_effect(() => {
set_text(text_3, get(group).name);
if (option_1_value !== (option_1_value = get(group).id)) option_1.value = (option_1.__value = get(group).id) ?? "";
});
append($$anchor, option_1);
});
reset(select);
reset(div_10);
var div_11 = sibling(div_10, 2);
var textarea = sibling(child(div_11), 2);
remove_textarea_child(textarea);
reset(div_11);
var div_12 = sibling(div_11, 2);
var button_2 = child(div_12);
var text_4 = child(button_2, true);
reset(button_2);
var button_3 = sibling(button_2, 2);
reset(div_12);
reset(form);
template_effect(() => {
set_attribute(input_2, "type", get(passwordVisible) ? "text" : "password");
set_text(text_2, get(passwordVisible) ? "🙈" : "👁");
button_2.disabled = get(saving);
set_text(text_4, get(saving) ? "Saving..." : get(isEdit) ? "💾 Update" : " Create");
});
event("submit", form, (e) => {
e.preventDefault();
handleSubmit();
});
bind_value(input_1, () => get(username), ($$value) => set(username, $$value));
bind_value(input_2, () => get(password), ($$value) => set(password, $$value));
delegated("click", button, () => set(passwordVisible, !get(passwordVisible)));
delegated("click", button_1, () => set(password, generatePassword({ length: 16 }), true));
bind_value(input_3, () => get(url), ($$value) => set(url, $$value));
bind_select_value(select, () => get(groupId), ($$value) => set(groupId, $$value));
bind_value(textarea, () => get(notes), ($$value) => set(notes, $$value));
delegated("click", button_3, function(...$$args) {
$$props.onCancel?.apply(this, $$args);
});
append($$anchor, fragment);
};
if_block(node, ($$render) => {
if (get(loading)) $$render(consequent);
else $$render(alternate, -1);
});
reset(div);
append($$anchor, div);
pop();
}
delegate(["click"]);
//#endregion
//#region src/components/ImportExport.svelte
var root_1$2 = /* @__PURE__ */ from_html(`<div class="modal-overlay svelte-17di1i9" role="presentation"><div class="modal svelte-17di1i9" role="dialog" aria-modal="true" aria-label="Export vault" tabindex="-1"><h3 class="svelte-17di1i9">Export Vault</h3> <p class="svelte-17di1i9">All entries and groups will be exported. You'll need the source vault's master password when importing into another vault.</p> <div class="modal-actions svelte-17di1i9"><button class="btn btn-primary"> </button> <button class="btn btn-ghost">Cancel</button></div></div></div>`);
var root_3$1 = /* @__PURE__ */ from_html(`<div class="error-banner svelte-17di1i9"> </div>`);
var root_4$1 = /* @__PURE__ */ from_html(`<div class="success-banner svelte-17di1i9"> <!></div>`);
var root_6$1 = /* @__PURE__ */ from_html(`<p class="svelte-17di1i9">File loaded. Enter the <strong>source vault's master password</strong> to decrypt and re-encrypt entries under your current vault.</p> <div class="form-group svelte-17di1i9"><label for="source-password" class="file-label svelte-17di1i9">Source vault password</label> <input id="source-password" type="password" placeholder="Enter source vault password" autocomplete="current-password" class="svelte-17di1i9"/></div> <div class="import-mode svelte-17di1i9"><label class="radio-label svelte-17di1i9"><input type="radio" name="importMode" class="svelte-17di1i9"/> <span class="svelte-17di1i9">Merge — add to existing data</span></label> <label class="radio-label svelte-17di1i9"><input type="radio" name="importMode" class="svelte-17di1i9"/> <span class="svelte-17di1i9">Replace — clear all existing data first</span></label></div> <div class="modal-actions svelte-17di1i9"><button class="btn btn-primary"> </button> <button class="btn btn-ghost">Cancel</button></div>`, 1);
var root_7 = /* @__PURE__ */ from_html(`<p class="svelte-17di1i9">Select how to handle existing data:</p> <div class="import-mode svelte-17di1i9"><label class="radio-label svelte-17di1i9"><input type="radio" name="importMode" class="svelte-17di1i9"/> <span class="svelte-17di1i9">Merge — add to existing data</span></label> <label class="radio-label svelte-17di1i9"><input type="radio" name="importMode" class="svelte-17di1i9"/> <span class="svelte-17di1i9">Replace — clear all existing data first</span></label></div> <div class="form-group svelte-17di1i9"><label for="import-file" class="file-label svelte-17di1i9">Choose JSON file</label> <input id="import-file" type="file" accept=".json,application/json" class="svelte-17di1i9"/></div>`, 1);
var root_2$1 = /* @__PURE__ */ from_html(`<div class="modal-overlay svelte-17di1i9" role="presentation"><div class="modal svelte-17di1i9" role="dialog" aria-modal="true" aria-label="Import vault data" tabindex="-1"><h3 class="svelte-17di1i9">Import Vault Data</h3> <!> <!> <div class="modal-actions svelte-17di1i9"><button class="btn btn-ghost">Close</button></div></div></div>`);
var root$1 = /* @__PURE__ */ from_html(`<div class="import-export"><button class="btn btn-ghost btn-sm" title="Export">📤 Export</button> <button class="btn btn-ghost btn-sm" title="Import">📥 Import</button> <!> <!></div>`);
function ImportExport($$anchor, $$props) {
push($$props, true);
const binding_group = [];
let showExport = /* @__PURE__ */ state(false);
let showImport = /* @__PURE__ */ state(false);
let importMode = /* @__PURE__ */ state("merge");
let importResult = /* @__PURE__ */ state(null);
let importError = /* @__PURE__ */ state("");
let importing = /* @__PURE__ */ state(false);
let exportData = /* @__PURE__ */ state(null);
let exporting = /* @__PURE__ */ state(false);
let sourcePassword = /* @__PURE__ */ state("");
let parsedFileData = /* @__PURE__ */ state(null);
async function handleExport() {
set(exporting, true);
try {
set(exportData, await exportAll(), true);
const json = JSON.stringify(get(exportData), null, 2);
const blob = new Blob([json], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `password-vault-export-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.json`;
a.click();
URL.revokeObjectURL(url);
set(showExport, false);
} catch (e) {
set(importError, "Export failed: " + e.message);
}
set(exporting, false);
}
async function handleFileSelect(event) {
const file = event.target.files[0];
if (!file) return;
set(importError, "");
set(importResult, null);
set(sourcePassword, "");
try {
const text = await file.text();
const data = JSON.parse(text);
if (!data.entries || !data.groups) {
set(importError, "Invalid file format — missing entries or groups data");
return;
}
set(parsedFileData, data, true);
} catch (e) {
set(importError, "Failed to parse file: " + e.message);
}
event.target.value = "";
}
async function handleImportSubmit() {
if (!get(parsedFileData)) return;
if (!get(sourcePassword).trim()) {
set(importError, "Source vault password is required");
return;
}
set(importing, true);
set(importError, "");
set(importResult, null);
try {
set(importResult, await importAll(get(parsedFileData), get(importMode), get(sourcePassword), app$1.encryptionKey), true);
set(sourcePassword, "");
set(parsedFileData, null);
search.refresh();
} catch (e) {
set(importError, "Import failed: " + e.message);
}
set(importing, false);
}
var div = root$1();
var button = child(div);
var button_1 = sibling(button, 2);
var node = sibling(button_1, 2);
var consequent = ($$anchor) => {
var div_1 = root_1$2();
var div_2 = child(div_1);
var div_3 = sibling(child(div_2), 4);
var button_2 = child(div_3);
var text_1 = child(button_2, true);
reset(button_2);
var button_3 = sibling(button_2, 2);
reset(div_3);
reset(div_2);
reset(div_1);
template_effect(() => {
button_2.disabled = get(exporting);
set_text(text_1, get(exporting) ? "Exporting..." : "📤 Export JSON");
});
delegated("click", div_1, () => set(showExport, false));
delegated("click", div_2, (e) => e.stopPropagation());
delegated("click", button_2, handleExport);
delegated("click", button_3, () => set(showExport, false));
append($$anchor, div_1);
};
if_block(node, ($$render) => {
if (get(showExport)) $$render(consequent);
});
var node_1 = sibling(node, 2);
var consequent_5 = ($$anchor) => {
var div_4 = root_2$1();
var div_5 = child(div_4);
var node_2 = sibling(child(div_5), 2);
var consequent_1 = ($$anchor) => {
var div_6 = root_3$1();
var text_2 = child(div_6, true);
reset(div_6);
template_effect(() => set_text(text_2, get(importError)));
append($$anchor, div_6);
};
if_block(node_2, ($$render) => {
if (get(importError)) $$render(consequent_1);
});
var node_3 = sibling(node_2, 2);
var consequent_3 = ($$anchor) => {
var div_7 = root_4$1();
var text_3 = child(div_7);
var node_4 = sibling(text_3);
var consequent_2 = ($$anchor) => {
var text_4 = text();
template_effect(() => set_text(text_4, `(${get(importResult).skipped ?? ""} skipped)`));
append($$anchor, text_4);
};
if_block(node_4, ($$render) => {
if (get(importResult).skipped > 0) $$render(consequent_2);
});
reset(div_7);
template_effect(() => set_text(text_3, `✓ Imported ${get(importResult).imported.entries ?? ""} entries and ${get(importResult).imported.groups ?? ""} groups `));
append($$anchor, div_7);
};
var consequent_4 = ($$anchor) => {
var fragment_1 = root_6$1();
var div_8 = sibling(first_child(fragment_1), 2);
var input = sibling(child(div_8), 2);
remove_input_defaults(input);
reset(div_8);
var div_9 = sibling(div_8, 2);
var label = child(div_9);
var input_1 = child(label);
remove_input_defaults(input_1);
input_1.value = input_1.__value = "merge";
next(2);
reset(label);
var label_1 = sibling(label, 2);
var input_2 = child(label_1);
remove_input_defaults(input_2);
input_2.value = input_2.__value = "replace";
next(2);
reset(label_1);
reset(div_9);
var div_10 = sibling(div_9, 2);
var button_4 = child(div_10);
var text_5 = child(button_4, true);
reset(button_4);
var button_5 = sibling(button_4, 2);
reset(div_10);
template_effect(() => {
button_4.disabled = get(importing);
set_text(text_5, get(importing) ? "Importing..." : "📥 Import");
});
bind_value(input, () => get(sourcePassword), ($$value) => set(sourcePassword, $$value));
bind_group(binding_group, [], input_1, () => get(importMode), ($$value) => set(importMode, $$value));
bind_group(binding_group, [], input_2, () => get(importMode), ($$value) => set(importMode, $$value));
delegated("click", button_4, handleImportSubmit);
delegated("click", button_5, () => {
set(parsedFileData, null);
set(sourcePassword, "");
});
append($$anchor, fragment_1);
};
var alternate = ($$anchor) => {
var fragment_2 = root_7();
var div_11 = sibling(first_child(fragment_2), 2);
var label_2 = child(div_11);
var input_3 = child(label_2);
remove_input_defaults(input_3);
input_3.value = input_3.__value = "merge";
next(2);
reset(label_2);
var label_3 = sibling(label_2, 2);
var input_4 = child(label_3);
remove_input_defaults(input_4);
input_4.value = input_4.__value = "replace";
next(2);
reset(label_3);
reset(div_11);
var div_12 = sibling(div_11, 2);
var input_5 = sibling(child(div_12), 2);
reset(div_12);
template_effect(() => input_5.disabled = get(importing));
bind_group(binding_group, [], input_3, () => get(importMode), ($$value) => set(importMode, $$value));
bind_group(binding_group, [], input_4, () => get(importMode), ($$value) => set(importMode, $$value));
delegated("change", input_5, handleFileSelect);
append($$anchor, fragment_2);
};
if_block(node_3, ($$render) => {
if (get(importResult)) $$render(consequent_3);
else if (get(parsedFileData)) $$render(consequent_4, 1);
else $$render(alternate, -1);
});
var div_13 = sibling(node_3, 2);
var button_6 = child(div_13);
reset(div_13);
reset(div_5);
reset(div_4);
delegated("click", div_4, () => set(showImport, false));
delegated("click", div_5, (e) => e.stopPropagation());
delegated("click", button_6, () => {
set(showImport, false);
set(importResult, null);
set(importError, "");
});
append($$anchor, div_4);
};
if_block(node_1, ($$render) => {
if (get(showImport)) $$render(consequent_5);
});
reset(div);
delegated("click", button, () => set(showExport, true));
delegated("click", button_1, () => set(showImport, true));
append($$anchor, div);
pop();
}
delegate(["click", "change"]);
//#endregion
//#region src/components/MainLayout.svelte
var root_1$1 = /* @__PURE__ */ from_html(`<button class="sidebar-overlay svelte-1ybayt" aria-label="Close menu"></button>`);
var root_2 = /* @__PURE__ */ from_html(`<button class="btn btn-ghost btn-sm">← Back</button>`);
var root_3 = /* @__PURE__ */ from_html(`<h1 class="svelte-1ybayt">All Entries</h1>`);
var root_4 = /* @__PURE__ */ from_html(`<h1 class="svelte-1ybayt">Entry Details</h1>`);
var root_5 = /* @__PURE__ */ from_html(`<h1 class="svelte-1ybayt"> </h1>`);
var root_6 = /* @__PURE__ */ from_html(`<button class="btn btn-primary btn-sm">+ New Entry</button>`);
var root = /* @__PURE__ */ from_html(`<div class="app-shell svelte-1ybayt"><div class="mobile-header svelte-1ybayt"><button class="btn btn-ghost btn-sm">☰ Menu</button> <span class="mobile-title svelte-1ybayt">Password Vault</span> <button class="btn btn-ghost btn-sm" title="Lock">🔒</button></div> <!> <aside><!></aside> <main class="main-content svelte-1ybayt"><div class="top-bar svelte-1ybayt"><!> <div class="top-bar-title svelte-1ybayt"><!></div> <div class="top-bar-actions svelte-1ybayt"><!> <!> <button class="btn btn-ghost btn-sm" title="Lock vault">🔒</button></div></div> <div class="content-area svelte-1ybayt"><!></div></main></div>`);
function MainLayout($$anchor, $$props) {
push($$props, true);
let sidebarOpen = /* @__PURE__ */ state(false);
let viewMode = /* @__PURE__ */ state("list");
let selectedEntryId = /* @__PURE__ */ state(null);
function goList() {
set(viewMode, "list");
set(selectedEntryId, null);
set(sidebarOpen, false);
}
function goDetail(entryId) {
set(selectedEntryId, entryId, true);
set(viewMode, "detail");
set(sidebarOpen, false);
}
function goForm(entryId = null) {
set(selectedEntryId, entryId, true);
set(viewMode, "form");
set(sidebarOpen, false);
}
function handleBack() {
if (get(viewMode) === "form") goDetail(get(selectedEntryId));
else goList();
}
function handleLock() {
app$1.lockVault();
}
var div = root();
var div_1 = child(div);
var button = child(div_1);
var button_1 = sibling(button, 4);
reset(div_1);
var node = sibling(div_1, 2);
var consequent = ($$anchor) => {
var button_2 = root_1$1();
delegated("click", button_2, () => set(sidebarOpen, false));
append($$anchor, button_2);
};
if_block(node, ($$render) => {
if (get(sidebarOpen)) $$render(consequent);
});
var aside = sibling(node, 2);
Sidebar(child(aside), { $$events: {
back: handleBack,
goList
} });
reset(aside);
var main = sibling(aside, 2);
var div_2 = child(main);
var node_2 = child(div_2);
var consequent_1 = ($$anchor) => {
var button_3 = root_2();
delegated("click", button_3, handleBack);
append($$anchor, button_3);
};
if_block(node_2, ($$render) => {
if (get(viewMode) !== "list") $$render(consequent_1);
});
var div_3 = sibling(node_2, 2);
var node_3 = child(div_3);
var consequent_2 = ($$anchor) => {
append($$anchor, root_3());
};
var consequent_3 = ($$anchor) => {
append($$anchor, root_4());
};
var consequent_4 = ($$anchor) => {
var h1_2 = root_5();
var text = child(h1_2, true);
reset(h1_2);
template_effect(() => set_text(text, get(selectedEntryId) ? "Edit Entry" : "New Entry"));
append($$anchor, h1_2);
};
if_block(node_3, ($$render) => {
if (get(viewMode) === "list") $$render(consequent_2);
else if (get(viewMode) === "detail") $$render(consequent_3, 1);
else if (get(viewMode) === "form") $$render(consequent_4, 2);
});
reset(div_3);
var div_4 = sibling(div_3, 2);
var node_4 = child(div_4);
var consequent_5 = ($$anchor) => {
var button_4 = root_6();
delegated("click", button_4, () => goForm(null));
append($$anchor, button_4);
};
if_block(node_4, ($$render) => {
if (get(viewMode) === "list") $$render(consequent_5);
});
var node_5 = sibling(node_4, 2);
ImportExport(node_5, {});
var button_5 = sibling(node_5, 2);
reset(div_4);
reset(div_2);
var div_5 = sibling(div_2, 2);
var node_6 = child(div_5);
var consequent_6 = ($$anchor) => {
EntryList($$anchor, {
onSelect: goDetail,
onAdd: () => goForm(null)
});
};
var consequent_7 = ($$anchor) => {
EntryDetail($$anchor, {
get entryId() {
return get(selectedEntryId);
},
onEdit: () => goForm(get(selectedEntryId)),
onBack: goList
});
};
var consequent_8 = ($$anchor) => {
EntryForm($$anchor, {
get entryId() {
return get(selectedEntryId);
},
onSave: goList,
onCancel: handleBack
});
};
if_block(node_6, ($$render) => {
if (get(viewMode) === "list") $$render(consequent_6);
else if (get(viewMode) === "detail" && get(selectedEntryId)) $$render(consequent_7, 1);
else if (get(viewMode) === "form") $$render(consequent_8, 2);
});
reset(div_5);
reset(main);
reset(div);
template_effect(() => set_class(aside, 1, `sidebar ${get(sidebarOpen) ? "open" : ""}`, "svelte-1ybayt"));
delegated("click", button, () => set(sidebarOpen, !get(sidebarOpen)));
delegated("click", button_1, handleLock);
delegated("click", button_5, handleLock);
append($$anchor, div);
pop();
}
delegate(["click"]);
//#endregion
//#region src/App.svelte
var root_1 = /* @__PURE__ */ from_html(`<meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>`, 1);
function App($$anchor, $$props) {
push($$props, false);
init();
var fragment_1 = comment();
head("1n46o8q", ($$anchor) => {
var fragment = root_1();
next(2);
append($$anchor, fragment);
});
var node = first_child(fragment_1);
var consequent = ($$anchor) => {
MainLayout($$anchor, {});
};
var alternate = ($$anchor) => {
LockScreen($$anchor, {});
};
if_block(node, ($$render) => {
if (app$1.isUnlocked) $$render(consequent);
else $$render(alternate, -1);
});
append($$anchor, fragment_1);
pop();
}
mount(App, { target: document.getElementById("app") });
//#endregion</script>
<style rel="stylesheet" crossorigin>/* ===== CSS Reset & Base ===== */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--color-bg: #0f1117;
--color-surface: #1a1d27;
--color-surface-hover: #242836;
--color-border: #2e3345;
--color-text: #e4e6f0;
--color-text-muted: #8b8fa3;
--color-primary: #6c63ff;
--color-primary-hover: #5a52d9;
--color-danger: #e5484d;
--color-danger-hover: #c93a3f;
--color-success: #34d399;
--color-warning: #fbbf24;
--color-input-bg: #161822;
--color-sidebar: #13151d;
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
--transition: 150ms ease;
}
html {
font-size: 16px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background-color: var(--color-bg);
color: var(--color-text);
line-height: 1.5;
min-height: 100vh;
}
#app {
min-height: 100vh;
}
/* ===== Typography ===== */
h1 { font-size: 1.5rem; font-weight: 600; }
h2 { font-size: 1.25rem; font-weight: 600; }
h3 { font-size: 1.1rem; font-weight: 600; }
/* ===== Buttons ===== */
.btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 16px;
border: none;
border-radius: var(--radius-md);
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: background-color var(--transition), opacity var(--transition);
text-decoration: none;
white-space: nowrap;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.btn-primary {
background-color: var(--color-primary);
color: #fff;
}
.btn-primary:hover:not(:disabled) {
background-color: var(--color-primary-hover);
}
.btn-danger {
background-color: var(--color-danger);
color: #fff;
}
.btn-danger:hover:not(:disabled) {
background-color: var(--color-danger-hover);
}
.btn-ghost {
background: transparent;
color: var(--color-text-muted);
border: 1px solid var(--color-border);
}
.btn-ghost:hover:not(:disabled) {
background-color: var(--color-surface-hover);
color: var(--color-text);
}
.btn-sm {
padding: 4px 10px;
font-size: 0.8rem;
}
/* ===== Inputs ===== */
input[type="text"],
input[type="password"],
input[type="url"],
input[type="email"],
input[type="number"],
textarea,
select {
width: 100%;
padding: 10px 12px;
background-color: var(--color-input-bg);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text);
font-size: 0.875rem;
font-family: inherit;
transition: border-color var(--transition);
outline: none;
}
input:focus,
textarea:focus,
select:focus {
border-color: var(--color-primary);
}
input::placeholder,
textarea::placeholder {
color: var(--color-text-muted);
}
textarea {
resize: vertical;
min-height: 80px;
}
label {
display: block;
font-size: 0.8rem;
font-weight: 500;
color: var(--color-text-muted);
margin-bottom: 4px;
}
.form-group {
margin-bottom: 16px;
}
/* ===== Utility ===== */
.text-muted { color: var(--color-text-muted); }
.text-sm { font-size: 0.8rem; }
.text-xs { font-size: 0.75rem; }
.mt-1 { margin-top: 4px; }
.mt-2 { margin-top: 8px; }
.mt-3 { margin-top: 12px; }
.mt-4 { margin-top: 16px; }
.mb-2 { margin-bottom: 8px; }
.mb-4 { margin-bottom: 16px; }
.flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 4px; }
.gap-2 { gap: 8px; }
.gap-3 { gap: 12px; }
.gap-4 { gap: 16px; }
.w-full { width: 100%; }
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.lock-screen.svelte-7sq1ct {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 1rem;
}
.lock-card.svelte-7sq1ct {
width: 100%;
max-width: 400px;
padding: 2.5rem 2rem;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
box-shadow: var(--shadow);
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
}
.lock-icon.svelte-7sq1ct {
font-size: 3rem;
line-height: 1;
}
h1.svelte-7sq1ct {
font-size: 1.5rem;
text-align: center;
}
.subtitle.svelte-7sq1ct {
color: var(--color-text-muted);
font-size: 0.9rem;
text-align: center;
}
.lock-form.svelte-7sq1ct {
width: 100%;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.error-banner.svelte-7sq1ct {
width: 100%;
padding: 10px 14px;
background: rgba(229, 72, 77, 0.15);
border: 1px solid rgba(229, 72, 77, 0.4);
border-radius: var(--radius-md);
color: var(--color-danger);
font-size: 0.85rem;
text-align: center;
}
.hint.svelte-7sq1ct {
font-size: 0.75rem;
color: var(--color-text-muted);
text-align: center;
line-height: 1.4;
margin-top: 0.5rem;
}
.sidebar-content.svelte-181dlmc {
display: flex;
flex-direction: column;
height: 100%;
}
.sidebar-header.svelte-181dlmc {
padding: 16px;
border-bottom: 1px solid var(--color-border);
}
.sidebar-header.svelte-181dlmc h2:where(.svelte-181dlmc) {
font-size: 1rem;
font-weight: 600;
}
.search-box.svelte-181dlmc {
padding: 12px 16px;
}
.search-box.svelte-181dlmc input:where(.svelte-181dlmc) {
padding: 8px 10px;
font-size: 0.85rem;
}
.groups-nav.svelte-181dlmc {
flex: 1;
overflow-y: auto;
padding: 8px;
}
.group-row.svelte-181dlmc {
display: flex;
align-items: center;
}
.group-item.svelte-181dlmc {
display: flex;
align-items: center;
gap: 10px;
flex: 1;
min-width: 0;
padding: 8px 12px;
border: none;
border-radius: var(--radius-md);
background: transparent;
color: var(--color-text-muted);
font-size: 0.875rem;
cursor: pointer;
transition: background-color 150ms, color 150ms;
text-align: left;
}
.group-item.svelte-181dlmc:hover {
background: var(--color-surface-hover);
color: var(--color-text);
}
.group-item.active.svelte-181dlmc {
background: rgba(108, 99, 255, 0.15);
color: var(--color-primary);
}
.group-icon.svelte-181dlmc {
font-size: 1rem;
}
.group-color.svelte-181dlmc {
width: 10px;
height: 10px;
border-radius: 50%;
flex-shrink: 0;
}
.group-name.svelte-181dlmc {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.group-actions.svelte-181dlmc {
display: flex;
gap: 2px;
padding-right: 4px;
opacity: 0;
transition: opacity 150ms;
}
.group-row.svelte-181dlmc:hover .group-actions:where(.svelte-181dlmc) {
opacity: 1;
}
.group-action-btn.svelte-181dlmc {
background: none;
border: none;
cursor: pointer;
font-size: 0.75rem;
padding: 4px;
border-radius: var(--radius-sm);
transition: background-color 150ms;
}
.group-action-btn.svelte-181dlmc:hover {
background: var(--color-surface-hover);
}
.sidebar-footer.svelte-181dlmc {
padding: 12px 16px;
border-top: 1px solid var(--color-border);
}
/* Modal */
.modal-overlay.svelte-181dlmc {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 200;
padding: 1rem;
}
.modal.svelte-181dlmc {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: 24px;
max-width: 380px;
width: 100%;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
.modal.svelte-181dlmc h3:where(.svelte-181dlmc) {
margin-bottom: 16px;
}
.modal.svelte-181dlmc p:where(.svelte-181dlmc) {
color: var(--color-text-muted);
font-size: 0.9rem;
margin-bottom: 20px;
}
.modal-actions.svelte-181dlmc {
display: flex;
gap: 8px;
}
.error-banner.svelte-181dlmc {
padding: 8px 12px;
background: rgba(229, 72, 77, 0.15);
border: 1px solid rgba(229, 72, 77, 0.4);
border-radius: var(--radius-md);
color: var(--color-danger);
font-size: 0.85rem;
margin-bottom: 12px;
}
/* Color picker */
.color-picker.svelte-181dlmc {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.color-swatch.svelte-181dlmc {
width: 28px;
height: 28px;
border-radius: 50%;
border: 2px solid transparent;
cursor: pointer;
transition: transform 150ms, border-color 150ms;
}
.color-swatch.svelte-181dlmc:hover {
transform: scale(1.15);
}
.color-swatch.selected.svelte-181dlmc {
border-color: #fff;
transform: scale(1.15);
}
.loading.svelte-13s7gu4, .empty-state.svelte-13s7gu4 {
text-align: center;
padding: 3rem 1rem;
color: var(--color-text-muted);
}
.error-banner.svelte-13s7gu4 {
padding: 12px 16px;
background: rgba(229, 72, 77, 0.15);
border: 1px solid rgba(229, 72, 77, 0.4);
border-radius: var(--radius-md);
color: var(--color-danger);
font-size: 0.85rem;
}
.empty-icon.svelte-13s7gu4 {
font-size: 3rem;
margin-bottom: 0.5rem;
}
.empty-text.svelte-13s7gu4 {
font-size: 1.1rem;
font-weight: 500;
color: var(--color-text);
}
.empty-hint.svelte-13s7gu4 {
font-size: 0.85rem;
color: var(--color-text-muted);
}
.results-info.svelte-13s7gu4 {
padding: 8px 0;
margin-bottom: 8px;
}
.entries-table.svelte-13s7gu4 {
width: 100%;
border-collapse: collapse;
}
.entries-table.svelte-13s7gu4 th:where(.svelte-13s7gu4) {
text-align: left;
padding: 8px 12px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--color-text-muted);
border-bottom: 1px solid var(--color-border);
}
.entry-row.svelte-13s7gu4 {
cursor: pointer;
transition: background-color 150ms;
}
.entry-row.svelte-13s7gu4:hover {
background: var(--color-surface-hover);
}
.entry-row.svelte-13s7gu4 td:where(.svelte-13s7gu4) {
padding: 10px 12px;
font-size: 0.875rem;
border-bottom: 1px solid var(--color-border);
}
.entry-title.svelte-13s7gu4 {
font-weight: 500;
}
.entry-username.svelte-13s7gu4 {
color: var(--color-text-muted);
}
.entry-url.svelte-13s7gu4 {
color: var(--color-text-muted);
max-width: 200px;
}
@media (max-width: 600px) {
.entries-table.svelte-13s7gu4 th:where(.svelte-13s7gu4):nth-child(3),
.entry-row.svelte-13s7gu4 td:where(.svelte-13s7gu4):nth-child(3) {
display: none;
}
}
.loading.svelte-dssgjx, .empty-state.svelte-dssgjx {
text-align: center;
padding: 3rem;
color: var(--color-text-muted);
}
.error-banner.svelte-dssgjx {
padding: 12px 16px;
background: rgba(229, 72, 77, 0.15);
border: 1px solid rgba(229, 72, 77, 0.4);
border-radius: var(--radius-md);
color: var(--color-danger);
font-size: 0.85rem;
}
.toast.svelte-dssgjx {
position: fixed;
bottom: 20px;
right: 20px;
padding: 10px 16px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
font-size: 0.85rem;
color: var(--color-success);
box-shadow: var(--shadow);
z-index: 1000;
animation: svelte-dssgjx-slideIn 200ms ease;
}
@keyframes svelte-dssgjx-slideIn {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
.detail-card.svelte-dssgjx {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: 24px;
max-width: 600px;
}
.detail-header.svelte-dssgjx {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
padding-bottom: 16px;
border-bottom: 1px solid var(--color-border);
gap: 12px;
}
.detail-header.svelte-dssgjx h2:where(.svelte-dssgjx) {
font-size: 1.25rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.header-actions.svelte-dssgjx {
display: flex;
gap: 8px;
flex-shrink: 0;
}
.detail-fields.svelte-dssgjx {
display: flex;
flex-direction: column;
gap: 16px;
}
.field-label.svelte-dssgjx {
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--color-text-muted);
margin-bottom: 4px;
display: block;
}
.field-value.svelte-dssgjx {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.95rem;
word-break: break-all;
}
.field-value.notes.svelte-dssgjx {
white-space: pre-wrap;
}
.field-value.svelte-dssgjx a:where(.svelte-dssgjx) {
color: var(--color-primary);
text-decoration: none;
}
.field-value.svelte-dssgjx a:where(.svelte-dssgjx):hover {
text-decoration: underline;
}
.copy-btn.svelte-dssgjx {
flex-shrink: 0;
}
.detail-meta.svelte-dssgjx {
display: flex;
gap: 16px;
margin-top: 24px;
padding-top: 16px;
border-top: 1px solid var(--color-border);
}
/* Modal */
.modal-overlay.svelte-dssgjx {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 200;
padding: 1rem;
}
.modal.svelte-dssgjx {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: 24px;
max-width: 400px;
width: 100%;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
.modal.svelte-dssgjx h3:where(.svelte-dssgjx) {
margin-bottom: 12px;
}
.modal.svelte-dssgjx p:where(.svelte-dssgjx) {
color: var(--color-text-muted);
font-size: 0.9rem;
margin-bottom: 20px;
}
.modal-actions.svelte-dssgjx {
display: flex;
gap: 8px;
}
@media (max-width: 600px) {
.header-actions.svelte-dssgjx {
display: none;
}
}
.loading.svelte-pafazm {
text-align: center;
padding: 3rem;
color: var(--color-text-muted);
}
.error-banner.svelte-pafazm {
padding: 12px 16px;
background: rgba(229, 72, 77, 0.15);
border: 1px solid rgba(229, 72, 77, 0.4);
border-radius: var(--radius-md);
color: var(--color-danger);
font-size: 0.85rem;
margin-bottom: 16px;
}
.form-card.svelte-pafazm {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: 24px;
max-width: 500px;
}
.validation-errors.svelte-pafazm {
margin-bottom: 16px;
padding: 12px;
background: rgba(251, 191, 36, 0.1);
border: 1px solid rgba(251, 191, 36, 0.3);
border-radius: var(--radius-md);
}
.validation-error.svelte-pafazm {
font-size: 0.85rem;
color: var(--color-warning);
}
.password-input-group.svelte-pafazm {
display: flex;
gap: 8px;
}
.password-input-group.svelte-pafazm input:where(.svelte-pafazm) {
flex: 1;
}
.form-actions.svelte-pafazm {
display: flex;
gap: 8px;
margin-top: 20px;
}
.modal-overlay.svelte-17di1i9 {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 200;
padding: 1rem;
}
.modal.svelte-17di1i9 {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: 24px;
max-width: 420px;
width: 100%;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
.modal.svelte-17di1i9 h3:where(.svelte-17di1i9) {
margin-bottom: 12px;
}
.modal.svelte-17di1i9 p:where(.svelte-17di1i9) {
color: var(--color-text-muted);
font-size: 0.9rem;
margin-bottom: 16px;
}
.modal-actions.svelte-17di1i9 {
display: flex;
gap: 8px;
margin-top: 16px;
}
.error-banner.svelte-17di1i9 {
padding: 10px 14px;
background: rgba(229, 72, 77, 0.15);
border: 1px solid rgba(229, 72, 77, 0.4);
border-radius: var(--radius-md);
color: var(--color-danger);
font-size: 0.85rem;
margin-bottom: 12px;
}
.success-banner.svelte-17di1i9 {
padding: 10px 14px;
background: rgba(52, 211, 153, 0.15);
border: 1px solid rgba(52, 211, 153, 0.4);
border-radius: var(--radius-md);
color: var(--color-success);
font-size: 0.85rem;
margin-bottom: 12px;
}
.import-mode.svelte-17di1i9 {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 16px;
}
.radio-label.svelte-17di1i9 {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
cursor: pointer;
transition: border-color 150ms, background-color 150ms;
}
.radio-label.svelte-17di1i9:hover {
border-color: var(--color-primary);
background: var(--color-surface-hover);
}
.radio-label.svelte-17di1i9 input[type="radio"]:where(.svelte-17di1i9) {
accent-color: var(--color-primary);
cursor: pointer;
}
.radio-label.svelte-17di1i9 span:where(.svelte-17di1i9) {
font-size: 0.85rem;
}
.file-label.svelte-17di1i9 {
font-size: 0.8rem;
font-weight: 500;
color: var(--color-text-muted);
margin-bottom: 4px;
}
input[type="file"].svelte-17di1i9 {
font-size: 0.85rem;
padding: 8px;
}
.form-group.svelte-17di1i9 {
margin-bottom: 16px;
}
.form-group.svelte-17di1i9 input[type="password"]:where(.svelte-17di1i9) {
width: 100%;
padding: 8px 12px;
font-size: 0.85rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: var(--color-surface);
color: var(--color-text);
box-sizing: border-box;
}
.form-group.svelte-17di1i9 input[type="password"]:where(.svelte-17di1i9):focus {
outline: none;
border-color: var(--color-primary);
}
.app-shell.svelte-1ybayt {
display: flex;
min-height: 100vh;
}
/* Mobile header */
.mobile-header.svelte-1ybayt {
display: none;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
position: sticky;
top: 0;
z-index: 100;
}
.mobile-title.svelte-1ybayt {
font-weight: 600;
font-size: 0.95rem;
}
/* Sidebar */
.sidebar.svelte-1ybayt {
width: 260px;
min-width: 260px;
background: var(--color-sidebar);
border-right: 1px solid var(--color-border);
height: 100vh;
position: sticky;
top: 0;
overflow-y: auto;
display: flex;
flex-direction: column;
}
/* Main content */
.main-content.svelte-1ybayt {
flex: 1;
display: flex;
flex-direction: column;
min-width: 0;
}
.top-bar.svelte-1ybayt {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 20px;
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
position: sticky;
top: 0;
z-index: 10;
}
.top-bar-title.svelte-1ybayt {
flex: 1;
min-width: 0;
}
.top-bar-title.svelte-1ybayt h1:where(.svelte-1ybayt) {
font-size: 1.1rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.top-bar-actions.svelte-1ybayt {
display: flex;
gap: 8px;
align-items: center;
}
.content-area.svelte-1ybayt {
flex: 1;
padding: 20px;
overflow-y: auto;
}
/* Sidebar overlay (mobile) */
.sidebar-overlay.svelte-1ybayt {
display: none;
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 49;
border: none;
cursor: pointer;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
/* Responsive */
@media (max-width: 768px) {
.mobile-header.svelte-1ybayt {
display: flex;
}
.sidebar.svelte-1ybayt {
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: 50;
transform: translateX(-100%);
transition: transform 200ms ease;
}
.sidebar.open.svelte-1ybayt {
transform: translateX(0);
}
.sidebar-overlay.svelte-1ybayt {
display: block;
}
.content-area.svelte-1ybayt {
padding: 12px;
}
.top-bar.svelte-1ybayt {
padding: 10px 12px;
}
}
/*$vite$:1*/</style>
</head>
<body>
<div id="app"></div>
</body>
</html>