aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/assets/icons/alarm-fill.svg3
-rw-r--r--src/assets/icons/alarm.svg7
-rw-r--r--src/assets/icons/alt.svg3
-rw-r--r--src/assets/icons/app-indicator.svg4
-rw-r--r--src/assets/icons/app.svg3
-rw-r--r--src/assets/icons/archive-fill.svg3
-rw-r--r--src/assets/icons/archive.svg4
-rw-r--r--src/assets/icons/arrow-90deg-down.svg4
-rw-r--r--src/assets/icons/arrow-90deg-left.svg4
-rw-r--r--src/assets/icons/arrow-90deg-right.svg4
-rw-r--r--src/assets/icons/arrow-90deg-up.svg4
-rw-r--r--src/assets/icons/arrow-bar-down.svg4
-rw-r--r--src/assets/icons/arrow-bar-left.svg4
-rw-r--r--src/assets/icons/arrow-bar-right.svg4
-rw-r--r--src/assets/icons/arrow-bar-up.svg4
-rw-r--r--src/assets/icons/arrow-clockwise.svg4
-rw-r--r--src/assets/icons/arrow-counterclockwise.svg4
-rw-r--r--src/assets/icons/arrow-down-left.svg4
-rw-r--r--src/assets/icons/arrow-down-right.svg4
-rw-r--r--src/assets/icons/arrow-down-short.svg4
-rw-r--r--src/assets/icons/arrow-down.svg4
-rw-r--r--src/assets/icons/arrow-left-right.svg5
-rw-r--r--src/assets/icons/arrow-left-short.svg4
-rw-r--r--src/assets/icons/arrow-left.svg4
-rw-r--r--src/assets/icons/arrow-repeat.svg4
-rw-r--r--src/assets/icons/arrow-return-left.svg4
-rw-r--r--src/assets/icons/arrow-return-right.svg4
-rw-r--r--src/assets/icons/arrow-right-short.svg4
-rw-r--r--src/assets/icons/arrow-right.svg4
-rw-r--r--src/assets/icons/arrow-up-down.svg5
-rw-r--r--src/assets/icons/arrow-up-left.svg4
-rw-r--r--src/assets/icons/arrow-up-right.svg4
-rw-r--r--src/assets/icons/arrow-up-short.svg4
-rw-r--r--src/assets/icons/arrow-up.svg4
-rw-r--r--src/assets/icons/arrows-angle-contract.svg5
-rw-r--r--src/assets/icons/arrows-angle-expand.svg5
-rw-r--r--src/assets/icons/arrows-collapse.svg5
-rw-r--r--src/assets/icons/arrows-expand.svg5
-rw-r--r--src/assets/icons/arrows-fullscreen.svg7
-rw-r--r--src/assets/icons/arrows-move.svg7
-rw-r--r--src/assets/icons/aspect-ratio-fill.svg3
-rw-r--r--src/assets/icons/aspect-ratio.svg4
-rw-r--r--src/assets/icons/at.svg3
-rw-r--r--src/assets/icons/award-fill.svg4
-rw-r--r--src/assets/icons/award.svg4
-rw-r--r--src/assets/icons/backspace-fill.svg3
-rw-r--r--src/assets/icons/backspace-reverse-fill.svg3
-rw-r--r--src/assets/icons/backspace-reverse.svg5
-rw-r--r--src/assets/icons/backspace.svg5
-rw-r--r--src/assets/icons/bag-fill.svg3
-rw-r--r--src/assets/icons/bag.svg4
-rw-r--r--src/assets/icons/bar-chart-fill.svg5
-rw-r--r--src/assets/icons/bar-chart.svg3
-rw-r--r--src/assets/icons/battery-charging.svg5
-rw-r--r--src/assets/icons/battery-full.svg4
-rw-r--r--src/assets/icons/battery-half.svg4
-rw-r--r--src/assets/icons/battery.svg4
-rw-r--r--src/assets/icons/bell-fill.svg3
-rw-r--r--src/assets/icons/bell.svg4
-rw-r--r--src/assets/icons/blockquote-left.svg4
-rw-r--r--src/assets/icons/blockquote-right.svg4
-rw-r--r--src/assets/icons/book-half.svg4
-rw-r--r--src/assets/icons/book.svg4
-rw-r--r--src/assets/icons/bookmark-check.svg4
-rw-r--r--src/assets/icons/bookmark-dash.svg3
-rw-r--r--src/assets/icons/bookmark-fill.svg3
-rw-r--r--src/assets/icons/bookmark-plus.svg4
-rw-r--r--src/assets/icons/bookmark.svg3
-rw-r--r--src/assets/icons/bookmarks-fill.svg4
-rw-r--r--src/assets/icons/bookmarks.svg4
-rw-r--r--src/assets/icons/bootstrap-fill.svg3
-rw-r--r--src/assets/icons/bootstrap-reboot.svg3
-rw-r--r--src/assets/icons/bootstrap.svg4
-rw-r--r--src/assets/icons/bounding-box-circles.svg4
-rw-r--r--src/assets/icons/bounding-box.svg3
-rw-r--r--src/assets/icons/box-arrow-down-left.svg4
-rw-r--r--src/assets/icons/box-arrow-down-right.svg4
-rw-r--r--src/assets/icons/box-arrow-down.svg5
-rw-r--r--src/assets/icons/box-arrow-in-down-left.svg5
-rw-r--r--src/assets/icons/box-arrow-in-down-right.svg5
-rw-r--r--src/assets/icons/box-arrow-in-down.svg5
-rw-r--r--src/assets/icons/box-arrow-in-left.svg5
-rw-r--r--src/assets/icons/box-arrow-in-right.svg5
-rw-r--r--src/assets/icons/box-arrow-in-up-left.svg5
-rw-r--r--src/assets/icons/box-arrow-in-up-right.svg5
-rw-r--r--src/assets/icons/box-arrow-in-up.svg5
-rw-r--r--src/assets/icons/box-arrow-left.svg5
-rw-r--r--src/assets/icons/box-arrow-right.svg5
-rw-r--r--src/assets/icons/box-arrow-up-left.svg4
-rw-r--r--src/assets/icons/box-arrow-up-right.svg4
-rw-r--r--src/assets/icons/box-arrow-up.svg5
-rw-r--r--src/assets/icons/braces.svg3
-rw-r--r--src/assets/icons/briefcase-fill.svg4
-rw-r--r--src/assets/icons/briefcase.svg4
-rw-r--r--src/assets/icons/brightness-alt-high-fill.svg3
-rw-r--r--src/assets/icons/brightness-alt-high.svg3
-rw-r--r--src/assets/icons/brightness-alt-low-fill.svg4
-rw-r--r--src/assets/icons/brightness-alt-low.svg4
-rw-r--r--src/assets/icons/brightness-high-fill.svg4
-rw-r--r--src/assets/icons/brightness-high.svg3
-rw-r--r--src/assets/icons/brightness-low-fill.svg11
-rw-r--r--src/assets/icons/brightness-low.svg11
-rw-r--r--src/assets/icons/brush.svg4
-rw-r--r--src/assets/icons/bucket-fill.svg4
-rw-r--r--src/assets/icons/bucket.svg4
-rw-r--r--src/assets/icons/building.svg5
-rw-r--r--src/assets/icons/bullseye.svg6
-rw-r--r--src/assets/icons/calendar-fill.svg4
-rw-r--r--src/assets/icons/calendar.svg4
-rw-r--r--src/assets/icons/camera-video-fill.svg4
-rw-r--r--src/assets/icons/camera-video.svg4
-rw-r--r--src/assets/icons/camera.svg5
-rw-r--r--src/assets/icons/capslock-fill.svg3
-rw-r--r--src/assets/icons/capslock.svg3
-rw-r--r--src/assets/icons/card-checklist.svg4
-rw-r--r--src/assets/icons/card-heading.svg5
-rw-r--r--src/assets/icons/card-image.svg5
-rw-r--r--src/assets/icons/card-list.svg7
-rw-r--r--src/assets/icons/card-text.svg4
-rw-r--r--src/assets/icons/caret-down-fill.svg3
-rw-r--r--src/assets/icons/caret-down.svg3
-rw-r--r--src/assets/icons/caret-left-fill.svg3
-rw-r--r--src/assets/icons/caret-left.svg3
-rw-r--r--src/assets/icons/caret-right-fill.svg3
-rw-r--r--src/assets/icons/caret-right.svg3
-rw-r--r--src/assets/icons/caret-up-fill.svg3
-rw-r--r--src/assets/icons/caret-up.svg3
-rw-r--r--src/assets/icons/chat-dots-fill.svg3
-rw-r--r--src/assets/icons/chat-dots.svg4
-rw-r--r--src/assets/icons/chat-fill.svg3
-rw-r--r--src/assets/icons/chat-quote-fill.svg3
-rw-r--r--src/assets/icons/chat-quote.svg7
-rw-r--r--src/assets/icons/chat-square-dots-fill.svg3
-rw-r--r--src/assets/icons/chat-square-dots.svg4
-rw-r--r--src/assets/icons/chat-square-fill.svg3
-rw-r--r--src/assets/icons/chat-square-quote-fill.svg3
-rw-r--r--src/assets/icons/chat-square-quote.svg7
-rw-r--r--src/assets/icons/chat-square.svg3
-rw-r--r--src/assets/icons/chat.svg3
-rw-r--r--src/assets/icons/check-all.svg4
-rw-r--r--src/assets/icons/check-box.svg4
-rw-r--r--src/assets/icons/check-circle.svg4
-rw-r--r--src/assets/icons/check.svg3
-rw-r--r--src/assets/icons/chevron-bar-contract.svg3
-rw-r--r--src/assets/icons/chevron-bar-down.svg3
-rw-r--r--src/assets/icons/chevron-bar-expand.svg3
-rw-r--r--src/assets/icons/chevron-bar-left.svg3
-rw-r--r--src/assets/icons/chevron-bar-right.svg3
-rw-r--r--src/assets/icons/chevron-bar-up.svg3
-rw-r--r--src/assets/icons/chevron-compact-down.svg3
-rw-r--r--src/assets/icons/chevron-compact-left.svg3
-rw-r--r--src/assets/icons/chevron-compact-right.svg3
-rw-r--r--src/assets/icons/chevron-compact-up.svg3
-rw-r--r--src/assets/icons/chevron-contract.svg3
-rw-r--r--src/assets/icons/chevron-double-down.svg4
-rw-r--r--src/assets/icons/chevron-double-left.svg4
-rw-r--r--src/assets/icons/chevron-double-right.svg4
-rw-r--r--src/assets/icons/chevron-double-up.svg4
-rw-r--r--src/assets/icons/chevron-down.svg3
-rw-r--r--src/assets/icons/chevron-expand.svg3
-rw-r--r--src/assets/icons/chevron-left.svg3
-rw-r--r--src/assets/icons/chevron-right.svg3
-rw-r--r--src/assets/icons/chevron-up.svg3
-rw-r--r--src/assets/icons/circle-fill.svg3
-rw-r--r--src/assets/icons/circle-half.svg3
-rw-r--r--src/assets/icons/circle-square.svg4
-rw-r--r--src/assets/icons/circle.svg3
-rw-r--r--src/assets/icons/clipboard-data.svg5
-rw-r--r--src/assets/icons/clipboard.svg4
-rw-r--r--src/assets/icons/clock-fill.svg3
-rw-r--r--src/assets/icons/clock-history.svg5
-rw-r--r--src/assets/icons/clock.svg4
-rw-r--r--src/assets/icons/cloud-download.svg5
-rw-r--r--src/assets/icons/cloud-fill.svg3
-rw-r--r--src/assets/icons/cloud-upload.svg5
-rw-r--r--src/assets/icons/cloud.svg3
-rw-r--r--src/assets/icons/code-slash.svg3
-rw-r--r--src/assets/icons/code.svg3
-rw-r--r--src/assets/icons/collection-fill.svg4
-rw-r--r--src/assets/icons/collection-play-fill.svg3
-rw-r--r--src/assets/icons/collection-play.svg4
-rw-r--r--src/assets/icons/collection.svg3
-rw-r--r--src/assets/icons/columns-gap.svg3
-rw-r--r--src/assets/icons/columns.svg4
-rw-r--r--src/assets/icons/command.svg4
-rw-r--r--src/assets/icons/compass.svg4
-rw-r--r--src/assets/icons/cone-striped.svg4
-rw-r--r--src/assets/icons/cone.svg4
-rw-r--r--src/assets/icons/controller.svg5
-rw-r--r--src/assets/icons/credit-card.svg5
-rw-r--r--src/assets/icons/crop.svg4
-rw-r--r--src/assets/icons/cursor-fill.svg3
-rw-r--r--src/assets/icons/cursor-text.svg3
-rw-r--r--src/assets/icons/cursor.svg3
-rw-r--r--src/assets/icons/dash-circle-fill.svg3
-rw-r--r--src/assets/icons/dash-circle.svg4
-rw-r--r--src/assets/icons/dash-square-fill.svg3
-rw-r--r--src/assets/icons/dash-square.svg4
-rw-r--r--src/assets/icons/dash.svg3
-rw-r--r--src/assets/icons/diamond-fill.svg3
-rw-r--r--src/assets/icons/diamond-half.svg3
-rw-r--r--src/assets/icons/diamond.svg3
-rw-r--r--src/assets/icons/display-fill.svg5
-rw-r--r--src/assets/icons/display.svg4
-rw-r--r--src/assets/icons/dot.svg3
-rw-r--r--src/assets/icons/download.svg5
-rw-r--r--src/assets/icons/droplet-fill.svg3
-rw-r--r--src/assets/icons/droplet-half.svg5
-rw-r--r--src/assets/icons/droplet.svg4
-rw-r--r--src/assets/icons/egg-fill.svg3
-rw-r--r--src/assets/icons/egg-fried.svg4
-rw-r--r--src/assets/icons/egg.svg3
-rw-r--r--src/assets/icons/eject-fill.svg3
-rw-r--r--src/assets/icons/eject.svg3
-rw-r--r--src/assets/icons/envelope-fill.svg3
-rw-r--r--src/assets/icons/envelope-open-fill.svg3
-rw-r--r--src/assets/icons/envelope-open.svg5
-rw-r--r--src/assets/icons/envelope.svg5
-rw-r--r--src/assets/icons/exclamation-circle-fill.svg3
-rw-r--r--src/assets/icons/exclamation-circle.svg4
-rw-r--r--src/assets/icons/exclamation-diamond-fill.svg3
-rw-r--r--src/assets/icons/exclamation-diamond.svg4
-rw-r--r--src/assets/icons/exclamation-octagon-fill.svg3
-rw-r--r--src/assets/icons/exclamation-octagon.svg4
-rw-r--r--src/assets/icons/exclamation-square-fill.svg3
-rw-r--r--src/assets/icons/exclamation-square.svg4
-rw-r--r--src/assets/icons/exclamation-triangle-fill.svg3
-rw-r--r--src/assets/icons/exclamation-triangle.svg4
-rw-r--r--src/assets/icons/exclamation.svg3
-rw-r--r--src/assets/icons/exclude.svg3
-rw-r--r--src/assets/icons/eye-fill.svg4
-rw-r--r--src/assets/icons/eye-slash-fill.svg5
-rw-r--r--src/assets/icons/eye-slash.svg6
-rw-r--r--src/assets/icons/eye.svg4
-rw-r--r--src/assets/icons/file-arrow-down.svg5
-rw-r--r--src/assets/icons/file-arrow-up.svg5
-rw-r--r--src/assets/icons/file-break.svg4
-rw-r--r--src/assets/icons/file-check.svg4
-rw-r--r--src/assets/icons/file-code.svg4
-rw-r--r--src/assets/icons/file-diff.svg5
-rw-r--r--src/assets/icons/file-earmark-arrow-down.svg6
-rw-r--r--src/assets/icons/file-earmark-arrow-up.svg6
-rw-r--r--src/assets/icons/file-earmark-break.svg3
-rw-r--r--src/assets/icons/file-earmark-check.svg4
-rw-r--r--src/assets/icons/file-earmark-code.svg5
-rw-r--r--src/assets/icons/file-earmark-diff.svg6
-rw-r--r--src/assets/icons/file-earmark-minus.svg4
-rw-r--r--src/assets/icons/file-earmark-plus.svg5
-rw-r--r--src/assets/icons/file-earmark-ruled.svg6
-rw-r--r--src/assets/icons/file-earmark-spreadsheet.svg6
-rw-r--r--src/assets/icons/file-earmark-text.svg5
-rw-r--r--src/assets/icons/file-earmark-zip.svg6
-rw-r--r--src/assets/icons/file-earmark.svg4
-rw-r--r--src/assets/icons/file-minus.svg4
-rw-r--r--src/assets/icons/file-plus.svg5
-rw-r--r--src/assets/icons/file-post.svg5
-rw-r--r--src/assets/icons/file-richtext.svg4
-rw-r--r--src/assets/icons/file-ruled.svg4
-rw-r--r--src/assets/icons/file-spreadsheet.svg5
-rw-r--r--src/assets/icons/file-text.svg4
-rw-r--r--src/assets/icons/file-zip.svg5
-rw-r--r--src/assets/icons/file.svg3
-rw-r--r--src/assets/icons/files-alt.svg4
-rw-r--r--src/assets/icons/files.svg4
-rw-r--r--src/assets/icons/film.svg3
-rw-r--r--src/assets/icons/filter-left.svg3
-rw-r--r--src/assets/icons/filter-right.svg3
-rw-r--r--src/assets/icons/filter.svg3
-rw-r--r--src/assets/icons/flag-fill.svg4
-rw-r--r--src/assets/icons/flag.svg4
-rw-r--r--src/assets/icons/folder-check.svg4
-rw-r--r--src/assets/icons/folder-fill.svg3
-rw-r--r--src/assets/icons/folder-minus.svg4
-rw-r--r--src/assets/icons/folder-plus.svg5
-rw-r--r--src/assets/icons/folder-symlink-fill.svg3
-rw-r--r--src/assets/icons/folder-symlink.svg5
-rw-r--r--src/assets/icons/folder.svg4
-rw-r--r--src/assets/icons/fonts.svg3
-rw-r--r--src/assets/icons/forward-fill.svg3
-rw-r--r--src/assets/icons/forward.svg3
-rw-r--r--src/assets/icons/fullscreen-exit.svg3
-rw-r--r--src/assets/icons/fullscreen.svg3
-rw-r--r--src/assets/icons/funnel-fill.svg4
-rw-r--r--src/assets/icons/funnel.svg3
-rw-r--r--src/assets/icons/gear-fill.svg3
-rw-r--r--src/assets/icons/gear-wide-connected.svg4
-rw-r--r--src/assets/icons/gear-wide.svg3
-rw-r--r--src/assets/icons/gear.svg4
-rw-r--r--src/assets/icons/gem.svg3
-rw-r--r--src/assets/icons/geo-alt.svg3
-rw-r--r--src/assets/icons/geo.svg5
-rw-r--r--src/assets/icons/gift-fill.svg5
-rw-r--r--src/assets/icons/gift.svg5
-rw-r--r--src/assets/icons/graph-down.svg5
-rw-r--r--src/assets/icons/graph-up.svg5
-rw-r--r--src/assets/icons/grid-1x2-fill.svg3
-rw-r--r--src/assets/icons/grid-1x2.svg3
-rw-r--r--src/assets/icons/grid-3x2-gap-fill.svg3
-rw-r--r--src/assets/icons/grid-3x2-gap.svg3
-rw-r--r--src/assets/icons/grid-3x2.svg3
-rw-r--r--src/assets/icons/grid-3x3-gap-fill.svg3
-rw-r--r--src/assets/icons/grid-3x3-gap.svg3
-rw-r--r--src/assets/icons/grid-3x3.svg3
-rw-r--r--src/assets/icons/grid-fill.svg3
-rw-r--r--src/assets/icons/grid.svg3
-rw-r--r--src/assets/icons/hammer.svg4
-rw-r--r--src/assets/icons/hash.svg3
-rw-r--r--src/assets/icons/heart-fill.svg3
-rw-r--r--src/assets/icons/heart-half.svg4
-rw-r--r--src/assets/icons/heart.svg3
-rw-r--r--src/assets/icons/house-door-fill.svg4
-rw-r--r--src/assets/icons/house-door.svg4
-rw-r--r--src/assets/icons/house-fill.svg4
-rw-r--r--src/assets/icons/house.svg4
-rw-r--r--src/assets/icons/hr.svg4
-rw-r--r--src/assets/icons/image-alt.svg4
-rw-r--r--src/assets/icons/image-fill.svg3
-rw-r--r--src/assets/icons/image.svg5
-rw-r--r--src/assets/icons/images.svg5
-rw-r--r--src/assets/icons/inbox-fill.svg4
-rw-r--r--src/assets/icons/inbox.svg4
-rw-r--r--src/assets/icons/inboxes-fill.svg4
-rw-r--r--src/assets/icons/inboxes.svg4
-rw-r--r--src/assets/icons/info-circle-fill.svg3
-rw-r--r--src/assets/icons/info-circle.svg5
-rw-r--r--src/assets/icons/info-square-fill.svg3
-rw-r--r--src/assets/icons/info-square.svg5
-rw-r--r--src/assets/icons/info.svg4
-rw-r--r--src/assets/icons/intersect.svg5
-rw-r--r--src/assets/icons/justify-left.svg3
-rw-r--r--src/assets/icons/justify-right.svg3
-rw-r--r--src/assets/icons/justify.svg3
-rw-r--r--src/assets/icons/kanban-fill.svg3
-rw-r--r--src/assets/icons/kanban.svg6
-rw-r--r--src/assets/icons/laptop.svg4
-rw-r--r--src/assets/icons/layers-fill.svg4
-rw-r--r--src/assets/icons/layers-half.svg4
-rw-r--r--src/assets/icons/layers.svg4
-rw-r--r--src/assets/icons/layout-sidebar-inset-reverse.svg4
-rw-r--r--src/assets/icons/layout-sidebar-inset.svg4
-rw-r--r--src/assets/icons/layout-sidebar-reverse.svg4
-rw-r--r--src/assets/icons/layout-sidebar.svg4
-rw-r--r--src/assets/icons/layout-split.svg4
-rw-r--r--src/assets/icons/layout-text-sidebar-reverse.svg4
-rw-r--r--src/assets/icons/layout-text-sidebar.svg4
-rw-r--r--src/assets/icons/layout-text-window-reverse.svg4
-rw-r--r--src/assets/icons/layout-text-window.svg4
-rw-r--r--src/assets/icons/layout-three-columns.svg4
-rw-r--r--src/assets/icons/layout-wtf.svg3
-rw-r--r--src/assets/icons/life-preserver.svg5
-rw-r--r--src/assets/icons/lightning-fill.svg3
-rw-r--r--src/assets/icons/lightning.svg3
-rw-r--r--src/assets/icons/link-45deg.svg6
-rw-r--r--src/assets/icons/link.svg6
-rw-r--r--src/assets/icons/list-check.svg3
-rw-r--r--src/assets/icons/list-nested.svg3
-rw-r--r--src/assets/icons/list-ol.svg4
-rw-r--r--src/assets/icons/list-task.svg5
-rw-r--r--src/assets/icons/list-ul.svg3
-rw-r--r--src/assets/icons/list.svg3
-rw-r--r--src/assets/icons/lock-fill.svg4
-rw-r--r--src/assets/icons/lock.svg3
-rw-r--r--src/assets/icons/map.svg3
-rw-r--r--src/assets/icons/mic-fill.svg4
-rw-r--r--src/assets/icons/mic-mute-fill.svg4
-rw-r--r--src/assets/icons/mic-mute.svg4
-rw-r--r--src/assets/icons/mic.svg4
-rw-r--r--src/assets/icons/moon.svg3
-rw-r--r--src/assets/icons/music-note-beamed.svg5
-rw-r--r--src/assets/icons/music-note-list.svg6
-rw-r--r--src/assets/icons/music-note.svg5
-rw-r--r--src/assets/icons/music-player-fill.svg4
-rw-r--r--src/assets/icons/music-player.svg5
-rw-r--r--src/assets/icons/newspaper.svg5
-rw-r--r--src/assets/icons/octagon-fill.svg3
-rw-r--r--src/assets/icons/octagon-half.svg4
-rw-r--r--src/assets/icons/octagon.svg3
-rw-r--r--src/assets/icons/option.svg3
-rw-r--r--src/assets/icons/outlet.svg5
-rw-r--r--src/assets/icons/paperclip.svg3
-rw-r--r--src/assets/icons/pause-fill.svg3
-rw-r--r--src/assets/icons/pause.svg3
-rw-r--r--src/assets/icons/pen.svg5
-rw-r--r--src/assets/icons/pencil-square.svg4
-rw-r--r--src/assets/icons/pencil.svg4
-rw-r--r--src/assets/icons/pentagon-fill.svg3
-rw-r--r--src/assets/icons/pentagon-half.svg3
-rw-r--r--src/assets/icons/pentagon.svg3
-rw-r--r--src/assets/icons/people-circle.svg5
-rw-r--r--src/assets/icons/people-fill.svg3
-rw-r--r--src/assets/icons/people.svg3
-rw-r--r--src/assets/icons/person-bounding-box.svg4
-rw-r--r--src/assets/icons/person-check-fill.svg3
-rw-r--r--src/assets/icons/person-check.svg3
-rw-r--r--src/assets/icons/person-dash-fill.svg3
-rw-r--r--src/assets/icons/person-dash.svg3
-rw-r--r--src/assets/icons/person-fill.svg3
-rw-r--r--src/assets/icons/person-lines-fill.svg3
-rw-r--r--src/assets/icons/person-plus-fill.svg4
-rw-r--r--src/assets/icons/person-plus.svg4
-rw-r--r--src/assets/icons/person-square.svg4
-rw-r--r--src/assets/icons/person.svg3
-rw-r--r--src/assets/icons/phone-landscape.svg4
-rw-r--r--src/assets/icons/phone.svg4
-rw-r--r--src/assets/icons/pie-chart-fill.svg3
-rw-r--r--src/assets/icons/pie-chart.svg4
-rw-r--r--src/assets/icons/pip-fill.svg3
-rw-r--r--src/assets/icons/pip.svg4
-rw-r--r--src/assets/icons/play-fill.svg3
-rw-r--r--src/assets/icons/play.svg3
-rw-r--r--src/assets/icons/plug.svg4
-rw-r--r--src/assets/icons/plus-circle-fill.svg3
-rw-r--r--src/assets/icons/plus-circle.svg5
-rw-r--r--src/assets/icons/plus-square-fill.svg3
-rw-r--r--src/assets/icons/plus-square.svg5
-rw-r--r--src/assets/icons/plus.svg4
-rw-r--r--src/assets/icons/power.svg4
-rw-r--r--src/assets/icons/puzzle-fill.svg3
-rw-r--r--src/assets/icons/puzzle.svg3
-rw-r--r--src/assets/icons/question-circle-fill.svg3
-rw-r--r--src/assets/icons/question-circle.svg4
-rw-r--r--src/assets/icons/question-diamond-fill.svg3
-rw-r--r--src/assets/icons/question-diamond.svg4
-rw-r--r--src/assets/icons/question-octagon-fill.svg3
-rw-r--r--src/assets/icons/question-octagon.svg4
-rw-r--r--src/assets/icons/question-square-fill.svg3
-rw-r--r--src/assets/icons/question-square.svg4
-rw-r--r--src/assets/icons/question.svg3
-rw-r--r--src/assets/icons/reply-all-fill.svg4
-rw-r--r--src/assets/icons/reply-all.svg4
-rw-r--r--src/assets/icons/reply-fill.svg3
-rw-r--r--src/assets/icons/reply.svg3
-rw-r--r--src/assets/icons/screwdriver.svg3
-rw-r--r--src/assets/icons/search.svg4
-rw-r--r--src/assets/icons/server.svg6
-rw-r--r--src/assets/icons/shield-fill.svg3
-rw-r--r--src/assets/icons/shield-lock-fill.svg3
-rw-r--r--src/assets/icons/shield-lock.svg5
-rw-r--r--src/assets/icons/shield-shaded.svg4
-rw-r--r--src/assets/icons/shield.svg3
-rw-r--r--src/assets/icons/shift-fill.svg3
-rw-r--r--src/assets/icons/shift.svg3
-rw-r--r--src/assets/icons/shuffle.svg5
-rw-r--r--src/assets/icons/skip-backward-fill.svg5
-rw-r--r--src/assets/icons/skip-backward.svg3
-rw-r--r--src/assets/icons/skip-end-fill.svg4
-rw-r--r--src/assets/icons/skip-end.svg4
-rw-r--r--src/assets/icons/skip-forward-fill.svg5
-rw-r--r--src/assets/icons/skip-forward.svg3
-rw-r--r--src/assets/icons/skip-start-fill.svg4
-rw-r--r--src/assets/icons/skip-start.svg4
-rw-r--r--src/assets/icons/slash-circle-fill.svg3
-rw-r--r--src/assets/icons/slash-circle.svg4
-rw-r--r--src/assets/icons/slash-square-fill.svg3
-rw-r--r--src/assets/icons/slash-square.svg4
-rw-r--r--src/assets/icons/slash.svg3
-rw-r--r--src/assets/icons/sliders.svg5
-rw-r--r--src/assets/icons/soundwave.svg3
-rw-r--r--src/assets/icons/speaker.svg4
-rw-r--r--src/assets/icons/square-fill.svg3
-rw-r--r--src/assets/icons/square-half.svg3
-rw-r--r--src/assets/icons/square.svg3
-rw-r--r--src/assets/icons/star-fill.svg3
-rw-r--r--src/assets/icons/star-half.svg3
-rw-r--r--src/assets/icons/star.svg3
-rw-r--r--src/assets/icons/stop-fill.svg3
-rw-r--r--src/assets/icons/stop.svg3
-rw-r--r--src/assets/icons/stopwatch-fill.svg3
-rw-r--r--src/assets/icons/stopwatch.svg5
-rw-r--r--src/assets/icons/subtract.svg4
-rw-r--r--src/assets/icons/sun.svg4
-rw-r--r--src/assets/icons/table.svg7
-rw-r--r--src/assets/icons/tablet-landscape.svg4
-rw-r--r--src/assets/icons/tablet.svg4
-rw-r--r--src/assets/icons/tag-fill.svg3
-rw-r--r--src/assets/icons/tag.svg4
-rw-r--r--src/assets/icons/terminal-fill.svg3
-rw-r--r--src/assets/icons/terminal.svg4
-rw-r--r--src/assets/icons/text-center.svg3
-rw-r--r--src/assets/icons/text-indent-left.svg3
-rw-r--r--src/assets/icons/text-indent-right.svg3
-rw-r--r--src/assets/icons/text-left.svg3
-rw-r--r--src/assets/icons/text-right.svg3
-rw-r--r--src/assets/icons/textarea-t.svg5
-rw-r--r--src/assets/icons/textarea.svg4
-rw-r--r--src/assets/icons/three-dots-vertical.svg3
-rw-r--r--src/assets/icons/three-dots.svg3
-rw-r--r--src/assets/icons/toggle-off.svg3
-rw-r--r--src/assets/icons/toggle-on.svg3
-rw-r--r--src/assets/icons/toggles.svg4
-rw-r--r--src/assets/icons/tools.svg4
-rw-r--r--src/assets/icons/trash-fill.svg3
-rw-r--r--src/assets/icons/trash.svg4
-rw-r--r--src/assets/icons/trash2-fill.svg4
-rw-r--r--src/assets/icons/trash2.svg5
-rw-r--r--src/assets/icons/triangle-fill.svg3
-rw-r--r--src/assets/icons/triangle-half.svg3
-rw-r--r--src/assets/icons/triangle.svg3
-rw-r--r--src/assets/icons/trophy.svg6
-rw-r--r--src/assets/icons/tv-fill.svg3
-rw-r--r--src/assets/icons/tv.svg3
-rw-r--r--src/assets/icons/type-bold.svg3
-rw-r--r--src/assets/icons/type-h1.svg3
-rw-r--r--src/assets/icons/type-h2.svg3
-rw-r--r--src/assets/icons/type-h3.svg3
-rw-r--r--src/assets/icons/type-italic.svg3
-rw-r--r--src/assets/icons/type-strikethrough.svg4
-rw-r--r--src/assets/icons/type-underline.svg4
-rw-r--r--src/assets/icons/type.svg3
-rw-r--r--src/assets/icons/union.svg4
-rw-r--r--src/assets/icons/unlock-fill.svg4
-rw-r--r--src/assets/icons/unlock.svg3
-rw-r--r--src/assets/icons/upload.svg4
-rw-r--r--src/assets/icons/view-list.svg3
-rw-r--r--src/assets/icons/view-stacked.svg3
-rw-r--r--src/assets/icons/volume-down-fill.svg4
-rw-r--r--src/assets/icons/volume-down.svg4
-rw-r--r--src/assets/icons/volume-mute-fill.svg4
-rw-r--r--src/assets/icons/volume-mute.svg4
-rw-r--r--src/assets/icons/volume-up-fill.svg6
-rw-r--r--src/assets/icons/volume-up.svg6
-rw-r--r--src/assets/icons/vr.svg4
-rw-r--r--src/assets/icons/wallet.svg3
-rw-r--r--src/assets/icons/watch.svg5
-rw-r--r--src/assets/icons/wifi.svg5
-rw-r--r--src/assets/icons/window.svg5
-rw-r--r--src/assets/icons/wrench.svg3
-rw-r--r--src/assets/icons/x-circle-fill.svg3
-rw-r--r--src/assets/icons/x-circle.svg5
-rw-r--r--src/assets/icons/x-diamond-fill.svg3
-rw-r--r--src/assets/icons/x-diamond.svg5
-rw-r--r--src/assets/icons/x-octagon-fill.svg3
-rw-r--r--src/assets/icons/x-octagon.svg5
-rw-r--r--src/assets/icons/x-square-fill.svg3
-rw-r--r--src/assets/icons/x-square.svg5
-rw-r--r--src/assets/icons/x.svg4
-rw-r--r--src/index.html115
-rw-r--r--src/lib/bootstrap.css6
-rw-r--r--src/lib/bootstrap.js6
-rw-r--r--src/lib/liquid.js3651
-rw-r--r--src/lib/popper.js5
-rw-r--r--src/lib/pouchdb.js12245
-rw-r--r--src/lib/toaster.js146
-rw-r--r--src/scripts/index.js379
-rw-r--r--src/styles/index.css28
-rw-r--r--src/styles/index.scss30
-rw-r--r--src/styles/prepros.config908
547 files changed, 19591 insertions, 0 deletions
diff --git a/src/assets/icons/alarm-fill.svg b/src/assets/icons/alarm-fill.svg
new file mode 100644
index 0000000..fcd9e14
--- /dev/null
+++ b/src/assets/icons/alarm-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-alarm-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.5.5A.5.5 0 016 0h4a.5.5 0 010 1H9v1.07a7.002 7.002 0 013.537 12.26l.817.816a.5.5 0 01-.708.708l-.924-.925A6.967 6.967 0 018 16a6.967 6.967 0 01-3.722-1.07l-.924.924a.5.5 0 01-.708-.708l.817-.816A7.002 7.002 0 017 2.07V1H5.999a.5.5 0 01-.5-.5zM.86 5.387A2.5 2.5 0 114.387 1.86 8.035 8.035 0 00.86 5.387zM13.5 1c-.753 0-1.429.333-1.887.86a8.035 8.035 0 013.527 3.527A2.5 2.5 0 0013.5 1zm-5 4a.5.5 0 00-1 0v3.882l-1.447 2.894a.5.5 0 10.894.448l1.5-3A.5.5 0 008.5 9V5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/alarm.svg b/src/assets/icons/alarm.svg
new file mode 100644
index 0000000..0c2ce66
--- /dev/null
+++ b/src/assets/icons/alarm.svg
@@ -0,0 +1,7 @@
+<svg class="bi bi-alarm" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A6 6 0 108 3a6 6 0 000 12zm0 1A7 7 0 108 2a7 7 0 000 14z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 4.5a.5.5 0 01.5.5v4a.5.5 0 01-.053.224l-1.5 3a.5.5 0 11-.894-.448L7.5 8.882V5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path d="M.86 5.387A2.5 2.5 0 114.387 1.86 8.035 8.035 0 00.86 5.387zM11.613 1.86a2.5 2.5 0 113.527 3.527 8.035 8.035 0 00-3.527-3.527z"/>
+ <path fill-rule="evenodd" d="M11.646 14.146a.5.5 0 01.708 0l1 1a.5.5 0 01-.708.708l-1-1a.5.5 0 010-.708zm-7.292 0a.5.5 0 00-.708 0l-1 1a.5.5 0 00.708.708l1-1a.5.5 0 000-.708zM5.5.5A.5.5 0 016 0h4a.5.5 0 010 1H6a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path d="M7 1h2v2H7V1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/alt.svg b/src/assets/icons/alt.svg
new file mode 100644
index 0000000..a28dbe9
--- /dev/null
+++ b/src/assets/icons/alt.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-alt" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 13.5a.5.5 0 00.5.5h3.797a.5.5 0 00.439-.26L11 3h3.5a.5.5 0 000-1h-3.797a.5.5 0 00-.439.26L5 13H1.5a.5.5 0 00-.5.5zm10 0a.5.5 0 00.5.5h3a.5.5 0 000-1h-3a.5.5 0 00-.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/app-indicator.svg b/src/assets/icons/app-indicator.svg
new file mode 100644
index 0000000..89bc05c
--- /dev/null
+++ b/src/assets/icons/app-indicator.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-app-indicator" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.5 2A3.5 3.5 0 002 5.5v5A3.5 3.5 0 005.5 14h5a3.5 3.5 0 003.5-3.5V8a.5.5 0 011 0v2.5a4.5 4.5 0 01-4.5 4.5h-5A4.5 4.5 0 011 10.5v-5A4.5 4.5 0 015.5 1H8a.5.5 0 010 1H5.5z" clip-rule="evenodd"/>
+ <path d="M16 3a3 3 0 11-6 0 3 3 0 016 0z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/app.svg b/src/assets/icons/app.svg
new file mode 100644
index 0000000..2a5797d
--- /dev/null
+++ b/src/assets/icons/app.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-app" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11 2H5a3 3 0 00-3 3v6a3 3 0 003 3h6a3 3 0 003-3V5a3 3 0 00-3-3zM5 1a4 4 0 00-4 4v6a4 4 0 004 4h6a4 4 0 004-4V5a4 4 0 00-4-4H5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/archive-fill.svg b/src/assets/icons/archive-fill.svg
new file mode 100644
index 0000000..c5b33cd
--- /dev/null
+++ b/src/assets/icons/archive-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-archive-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12.643 15C13.979 15 15 13.845 15 12.5V5H1v7.5C1 13.845 2.021 15 3.357 15h9.286zM6 7a.5.5 0 000 1h4a.5.5 0 000-1H6zM.8 1a.8.8 0 00-.8.8V3a.8.8 0 00.8.8h14.4A.8.8 0 0016 3V1.8a.8.8 0 00-.8-.8H.8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/archive.svg b/src/assets/icons/archive.svg
new file mode 100644
index 0000000..3e08be6
--- /dev/null
+++ b/src/assets/icons/archive.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-archive" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 5v7.5c0 .864.642 1.5 1.357 1.5h9.286c.715 0 1.357-.636 1.357-1.5V5h1v7.5c0 1.345-1.021 2.5-2.357 2.5H3.357C2.021 15 1 13.845 1 12.5V5h1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.5 7.5A.5.5 0 016 7h4a.5.5 0 010 1H6a.5.5 0 01-.5-.5zM15 2H1v2h14V2zM1 1a1 1 0 00-1 1v2a1 1 0 001 1h14a1 1 0 001-1V2a1 1 0 00-1-1H1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-90deg-down.svg b/src/assets/icons/arrow-90deg-down.svg
new file mode 100644
index 0000000..b271455
--- /dev/null
+++ b/src/assets/icons/arrow-90deg-down.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-90deg-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.646 9.646a.5.5 0 01.708 0L6 12.293l2.646-2.647a.5.5 0 11.708.708l-3 3a.5.5 0 01-.708 0l-3-3a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6 13a.5.5 0 01-.5-.5V6A2.5 2.5 0 018 3.5h5.5a.5.5 0 010 1H8A1.5 1.5 0 006.5 6v6.5a.5.5 0 01-.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-90deg-left.svg b/src/assets/icons/arrow-90deg-left.svg
new file mode 100644
index 0000000..88be7f0
--- /dev/null
+++ b/src/assets/icons/arrow-90deg-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-90deg-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.104 2.396a.5.5 0 010 .708L3.457 5.75l2.647 2.646a.5.5 0 11-.708.708l-3-3a.5.5 0 010-.708l3-3a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.75 5.75a.5.5 0 01.5-.5h6.5a2.5 2.5 0 012.5 2.5v5.5a.5.5 0 01-1 0v-5.5a1.5 1.5 0 00-1.5-1.5h-6.5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-90deg-right.svg b/src/assets/icons/arrow-90deg-right.svg
new file mode 100644
index 0000000..df4aca9
--- /dev/null
+++ b/src/assets/icons/arrow-90deg-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-90deg-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.896 2.396a.5.5 0 000 .708l2.647 2.646-2.647 2.646a.5.5 0 10.708.708l3-3a.5.5 0 000-.708l-3-3a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13.25 5.75a.5.5 0 00-.5-.5h-6.5a2.5 2.5 0 00-2.5 2.5v5.5a.5.5 0 001 0v-5.5a1.5 1.5 0 011.5-1.5h6.5a.5.5 0 00.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-90deg-up.svg b/src/assets/icons/arrow-90deg-up.svg
new file mode 100644
index 0000000..d373696
--- /dev/null
+++ b/src/assets/icons/arrow-90deg-up.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-90deg-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.646 6.854a.5.5 0 00.708 0L6 4.207l2.646 2.647a.5.5 0 10.708-.708l-3-3a.5.5 0 00-.708 0l-3 3a.5.5 0 000 .708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6 3.5a.5.5 0 00-.5.5v6.5A2.5 2.5 0 008 13h5.5a.5.5 0 000-1H8a1.5 1.5 0 01-1.5-1.5V4a.5.5 0 00-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-bar-down.svg b/src/assets/icons/arrow-bar-down.svg
new file mode 100644
index 0000000..309073d
--- /dev/null
+++ b/src/assets/icons/arrow-bar-down.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-bar-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.354 10.146a.5.5 0 010 .708l-3 3a.5.5 0 01-.708 0l-3-3a.5.5 0 01.708-.708L8 12.793l2.646-2.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 6a.5.5 0 01.5.5V13a.5.5 0 01-1 0V6.5A.5.5 0 018 6zM2 3.5a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-bar-left.svg b/src/assets/icons/arrow-bar-left.svg
new file mode 100644
index 0000000..4c0cd90
--- /dev/null
+++ b/src/assets/icons/arrow-bar-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-bar-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.854 4.646a.5.5 0 00-.708 0l-3 3a.5.5 0 000 .708l3 3a.5.5 0 00.708-.708L3.207 8l2.647-2.646a.5.5 0 000-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10 8a.5.5 0 00-.5-.5H3a.5.5 0 000 1h6.5A.5.5 0 0010 8zm2.5 6a.5.5 0 01-.5-.5v-11a.5.5 0 011 0v11a.5.5 0 01-.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-bar-right.svg b/src/assets/icons/arrow-bar-right.svg
new file mode 100644
index 0000000..0e6bab7
--- /dev/null
+++ b/src/assets/icons/arrow-bar-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-bar-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M10.146 4.646a.5.5 0 01.708 0l3 3a.5.5 0 010 .708l-3 3a.5.5 0 01-.708-.708L12.793 8l-2.647-2.646a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6 8a.5.5 0 01.5-.5H13a.5.5 0 010 1H6.5A.5.5 0 016 8zm-2.5 6a.5.5 0 01-.5-.5v-11a.5.5 0 011 0v11a.5.5 0 01-.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-bar-up.svg b/src/assets/icons/arrow-bar-up.svg
new file mode 100644
index 0000000..f94da89
--- /dev/null
+++ b/src/assets/icons/arrow-bar-up.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-bar-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.354 5.854a.5.5 0 000-.708l-3-3a.5.5 0 00-.708 0l-3 3a.5.5 0 10.708.708L8 3.207l2.646 2.647a.5.5 0 00.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 10a.5.5 0 00.5-.5V3a.5.5 0 00-1 0v6.5a.5.5 0 00.5.5zm-4.8 1.6c0-.22.18-.4.4-.4h8.8a.4.4 0 010 .8H3.6a.4.4 0 01-.4-.4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-clockwise.svg b/src/assets/icons/arrow-clockwise.svg
new file mode 100644
index 0000000..868423b
--- /dev/null
+++ b/src/assets/icons/arrow-clockwise.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-clockwise" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.17 6.706a5 5 0 017.103-3.16.5.5 0 10.454-.892A6 6 0 1013.455 5.5a.5.5 0 00-.91.417 5 5 0 11-9.375.789z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8.147.146a.5.5 0 01.707 0l2.5 2.5a.5.5 0 010 .708l-2.5 2.5a.5.5 0 11-.707-.708L10.293 3 8.147.854a.5.5 0 010-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-counterclockwise.svg b/src/assets/icons/arrow-counterclockwise.svg
new file mode 100644
index 0000000..8e1a4dc
--- /dev/null
+++ b/src/assets/icons/arrow-counterclockwise.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-counterclockwise" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12.83 6.706a5 5 0 00-7.103-3.16.5.5 0 11-.454-.892A6 6 0 112.545 5.5a.5.5 0 11.91.417 5 5 0 109.375.789z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.854.146a.5.5 0 00-.708 0l-2.5 2.5a.5.5 0 000 .708l2.5 2.5a.5.5 0 10.708-.708L5.707 3 7.854.854a.5.5 0 000-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-down-left.svg b/src/assets/icons/arrow-down-left.svg
new file mode 100644
index 0000000..e3f6c44
--- /dev/null
+++ b/src/assets/icons/arrow-down-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-down-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3 7.5a.5.5 0 01.5.5v4.5H8a.5.5 0 010 1H3a.5.5 0 01-.5-.5V8a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M12.354 3.646a.5.5 0 010 .708l-9 9a.5.5 0 01-.708-.708l9-9a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-down-right.svg b/src/assets/icons/arrow-down-right.svg
new file mode 100644
index 0000000..1c28b33
--- /dev/null
+++ b/src/assets/icons/arrow-down-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-down-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 7.5a.5.5 0 01.5.5v5a.5.5 0 01-.5.5H7a.5.5 0 010-1h4.5V8a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.646 3.646a.5.5 0 01.708 0l9 9a.5.5 0 01-.708.708l-9-9a.5.5 0 010-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-down-short.svg b/src/assets/icons/arrow-down-short.svg
new file mode 100644
index 0000000..17f16f7
--- /dev/null
+++ b/src/assets/icons/arrow-down-short.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-down-short" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.646 7.646a.5.5 0 01.708 0L8 10.293l2.646-2.647a.5.5 0 01.708.708l-3 3a.5.5 0 01-.708 0l-3-3a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 4.5a.5.5 0 01.5.5v5a.5.5 0 01-1 0V5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-down.svg b/src/assets/icons/arrow-down.svg
new file mode 100644
index 0000000..584bce3
--- /dev/null
+++ b/src/assets/icons/arrow-down.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.646 9.646a.5.5 0 01.708 0L8 12.293l2.646-2.647a.5.5 0 01.708.708l-3 3a.5.5 0 01-.708 0l-3-3a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 2.5a.5.5 0 01.5.5v9a.5.5 0 01-1 0V3a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-left-right.svg b/src/assets/icons/arrow-left-right.svg
new file mode 100644
index 0000000..131f27e
--- /dev/null
+++ b/src/assets/icons/arrow-left-right.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-arrow-left-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M10.146 7.646a.5.5 0 01.708 0l3 3a.5.5 0 010 .708l-3 3a.5.5 0 01-.708-.708L12.793 11l-2.647-2.646a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2 11a.5.5 0 01.5-.5H13a.5.5 0 010 1H2.5A.5.5 0 012 11zm3.854-9.354a.5.5 0 010 .708L3.207 5l2.647 2.646a.5.5 0 11-.708.708l-3-3a.5.5 0 010-.708l3-3a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.5 5a.5.5 0 01.5-.5h10.5a.5.5 0 010 1H3a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-left-short.svg b/src/assets/icons/arrow-left-short.svg
new file mode 100644
index 0000000..ab0fe1e
--- /dev/null
+++ b/src/assets/icons/arrow-left-short.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-left-short" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.854 4.646a.5.5 0 010 .708L5.207 8l2.647 2.646a.5.5 0 01-.708.708l-3-3a.5.5 0 010-.708l3-3a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.5 8a.5.5 0 01.5-.5h6.5a.5.5 0 010 1H5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-left.svg b/src/assets/icons/arrow-left.svg
new file mode 100644
index 0000000..9663c94
--- /dev/null
+++ b/src/assets/icons/arrow-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.854 4.646a.5.5 0 010 .708L3.207 8l2.647 2.646a.5.5 0 01-.708.708l-3-3a.5.5 0 010-.708l3-3a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.5 8a.5.5 0 01.5-.5h10.5a.5.5 0 010 1H3a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-repeat.svg b/src/assets/icons/arrow-repeat.svg
new file mode 100644
index 0000000..0f22124
--- /dev/null
+++ b/src/assets/icons/arrow-repeat.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-repeat" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.854 7.146a.5.5 0 00-.708 0l-2 2a.5.5 0 10.708.708L2.5 8.207l1.646 1.647a.5.5 0 00.708-.708l-2-2zm13-1a.5.5 0 00-.708 0L13.5 7.793l-1.646-1.647a.5.5 0 00-.708.708l2 2a.5.5 0 00.708 0l2-2a.5.5 0 000-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 3a4.995 4.995 0 00-4.192 2.273.5.5 0 01-.837-.546A6 6 0 0114 8a.5.5 0 01-1.001 0 5 5 0 00-5-5zM2.5 7.5A.5.5 0 013 8a5 5 0 009.192 2.727.5.5 0 11.837.546A6 6 0 012 8a.5.5 0 01.501-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-return-left.svg b/src/assets/icons/arrow-return-left.svg
new file mode 100644
index 0000000..b60b6cf
--- /dev/null
+++ b/src/assets/icons/arrow-return-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-return-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.854 5.646a.5.5 0 010 .708L3.207 9l2.647 2.646a.5.5 0 01-.708.708l-3-3a.5.5 0 010-.708l3-3a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13.5 2.5a.5.5 0 01.5.5v4a2.5 2.5 0 01-2.5 2.5H3a.5.5 0 010-1h8.5A1.5 1.5 0 0013 7V3a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-return-right.svg b/src/assets/icons/arrow-return-right.svg
new file mode 100644
index 0000000..a2cfe90
--- /dev/null
+++ b/src/assets/icons/arrow-return-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-return-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M10.146 5.646a.5.5 0 01.708 0l3 3a.5.5 0 010 .708l-3 3a.5.5 0 01-.708-.708L12.793 9l-2.647-2.646a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M3 2.5a.5.5 0 00-.5.5v4A2.5 2.5 0 005 9.5h8.5a.5.5 0 000-1H5A1.5 1.5 0 013.5 7V3a.5.5 0 00-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-right-short.svg b/src/assets/icons/arrow-right-short.svg
new file mode 100644
index 0000000..6f1c547
--- /dev/null
+++ b/src/assets/icons/arrow-right-short.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-right-short" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.146 4.646a.5.5 0 01.708 0l3 3a.5.5 0 010 .708l-3 3a.5.5 0 01-.708-.708L10.793 8 8.146 5.354a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4 8a.5.5 0 01.5-.5H11a.5.5 0 010 1H4.5A.5.5 0 014 8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-right.svg b/src/assets/icons/arrow-right.svg
new file mode 100644
index 0000000..6e3d621
--- /dev/null
+++ b/src/assets/icons/arrow-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M10.146 4.646a.5.5 0 01.708 0l3 3a.5.5 0 010 .708l-3 3a.5.5 0 01-.708-.708L12.793 8l-2.647-2.646a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2 8a.5.5 0 01.5-.5H13a.5.5 0 010 1H2.5A.5.5 0 012 8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-up-down.svg b/src/assets/icons/arrow-up-down.svg
new file mode 100644
index 0000000..1f272ec
--- /dev/null
+++ b/src/assets/icons/arrow-up-down.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-arrow-up-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11 3.5a.5.5 0 01.5.5v9a.5.5 0 01-1 0V4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.646 2.646a.5.5 0 01.708 0l3 3a.5.5 0 01-.708.708L11 3.707 8.354 6.354a.5.5 0 11-.708-.708l3-3zm-9 7a.5.5 0 01.708 0L5 12.293l2.646-2.647a.5.5 0 11.708.708l-3 3a.5.5 0 01-.708 0l-3-3a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 2.5a.5.5 0 01.5.5v9a.5.5 0 01-1 0V3a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-up-left.svg b/src/assets/icons/arrow-up-left.svg
new file mode 100644
index 0000000..e0e2ae0
--- /dev/null
+++ b/src/assets/icons/arrow-up-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-up-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.5 4a.5.5 0 01.5-.5h5a.5.5 0 010 1H3.5V9a.5.5 0 01-1 0V4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.646 3.646a.5.5 0 01.708 0l9 9a.5.5 0 01-.708.708l-9-9a.5.5 0 010-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-up-right.svg b/src/assets/icons/arrow-up-right.svg
new file mode 100644
index 0000000..77153db
--- /dev/null
+++ b/src/assets/icons/arrow-up-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-up-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.5 4a.5.5 0 01.5-.5h5a.5.5 0 01.5.5v5a.5.5 0 01-1 0V4.5H7a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M12.354 3.646a.5.5 0 010 .708l-9 9a.5.5 0 01-.708-.708l9-9a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-up-short.svg b/src/assets/icons/arrow-up-short.svg
new file mode 100644
index 0000000..e798a35
--- /dev/null
+++ b/src/assets/icons/arrow-up-short.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-up-short" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 5.5a.5.5 0 01.5.5v5a.5.5 0 01-1 0V6a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.646 4.646a.5.5 0 01.708 0l3 3a.5.5 0 01-.708.708L8 5.707 5.354 8.354a.5.5 0 11-.708-.708l3-3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrow-up.svg b/src/assets/icons/arrow-up.svg
new file mode 100644
index 0000000..38501b3
--- /dev/null
+++ b/src/assets/icons/arrow-up.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-arrow-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 3.5a.5.5 0 01.5.5v9a.5.5 0 01-1 0V4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.646 2.646a.5.5 0 01.708 0l3 3a.5.5 0 01-.708.708L8 3.707 5.354 6.354a.5.5 0 11-.708-.708l3-3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrows-angle-contract.svg b/src/assets/icons/arrows-angle-contract.svg
new file mode 100644
index 0000000..a8d9444
--- /dev/null
+++ b/src/assets/icons/arrows-angle-contract.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-arrows-angle-contract" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.5 2.036a.5.5 0 01.5.5v3.5h3.5a.5.5 0 010 1h-4a.5.5 0 01-.5-.5v-4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M14.354 1.646a.5.5 0 010 .708l-4.5 4.5a.5.5 0 11-.708-.708l4.5-4.5a.5.5 0 01.708 0zm-7.5 7.5a.5.5 0 010 .708l-4.5 4.5a.5.5 0 01-.708-.708l4.5-4.5a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.036 9.5a.5.5 0 01.5-.5h4a.5.5 0 01.5.5v4a.5.5 0 01-1 0V10h-3.5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrows-angle-expand.svg b/src/assets/icons/arrows-angle-expand.svg
new file mode 100644
index 0000000..16c6c6c
--- /dev/null
+++ b/src/assets/icons/arrows-angle-expand.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-arrows-angle-expand" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 10.036a.5.5 0 01.5.5v3.5h3.5a.5.5 0 010 1h-4a.5.5 0 01-.5-.5v-4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6.354 9.646a.5.5 0 010 .708l-4.5 4.5a.5.5 0 01-.708-.708l4.5-4.5a.5.5 0 01.708 0zm8.5-8.5a.5.5 0 010 .708l-4.5 4.5a.5.5 0 01-.708-.708l4.5-4.5a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.036 1.5a.5.5 0 01.5-.5h4a.5.5 0 01.5.5v4a.5.5 0 11-1 0V2h-3.5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrows-collapse.svg b/src/assets/icons/arrows-collapse.svg
new file mode 100644
index 0000000..968303c
--- /dev/null
+++ b/src/assets/icons/arrows-collapse.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-arrows-collapse" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 8a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11A.5.5 0 012 8zm6-7a.5.5 0 01.5.5V6a.5.5 0 01-1 0V1.5A.5.5 0 018 1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.354 3.646a.5.5 0 010 .708l-2 2a.5.5 0 01-.708 0l-2-2a.5.5 0 11.708-.708L8 5.293l1.646-1.647a.5.5 0 01.708 0zM8 15a.5.5 0 00.5-.5V10a.5.5 0 00-1 0v4.5a.5.5 0 00.5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.354 12.354a.5.5 0 000-.708l-2-2a.5.5 0 00-.708 0l-2 2a.5.5 0 00.708.708L8 10.707l1.646 1.647a.5.5 0 00.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrows-expand.svg b/src/assets/icons/arrows-expand.svg
new file mode 100644
index 0000000..ef0238d
--- /dev/null
+++ b/src/assets/icons/arrows-expand.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-arrows-expand" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 8a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11A.5.5 0 012 8zm6-1.5a.5.5 0 00.5-.5V1.5a.5.5 0 00-1 0V6a.5.5 0 00.5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.354 3.854a.5.5 0 000-.708l-2-2a.5.5 0 00-.708 0l-2 2a.5.5 0 10.708.708L8 2.207l1.646 1.647a.5.5 0 00.708 0zM8 9.5a.5.5 0 01.5.5v4.5a.5.5 0 01-1 0V10a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.354 12.146a.5.5 0 010 .708l-2 2a.5.5 0 01-.708 0l-2-2a.5.5 0 01.708-.708L8 13.793l1.646-1.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrows-fullscreen.svg b/src/assets/icons/arrows-fullscreen.svg
new file mode 100644
index 0000000..5996c8c
--- /dev/null
+++ b/src/assets/icons/arrows-fullscreen.svg
@@ -0,0 +1,7 @@
+<svg class="bi bi-arrows-fullscreen" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.464 10.536a.5.5 0 01.5.5v3h3a.5.5 0 010 1h-3.5a.5.5 0 01-.5-.5v-3.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.964 10a.5.5 0 010 .707l-4.146 4.147a.5.5 0 01-.707-.708L5.257 10a.5.5 0 01.707 0zm8.854-8.854a.5.5 0 010 .708L10.672 6a.5.5 0 01-.708-.707l4.147-4.147a.5.5 0 01.707 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.5 1.5A.5.5 0 0111 1h3.5a.5.5 0 01.5.5V5a.5.5 0 01-1 0V2h-3a.5.5 0 01-.5-.5zm4 9a.5.5 0 00-.5.5v3h-3a.5.5 0 000 1h3.5a.5.5 0 00.5-.5V11a.5.5 0 00-.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10 9.964a.5.5 0 000 .708l4.146 4.146a.5.5 0 00.708-.707l-4.147-4.147a.5.5 0 00-.707 0zM1.182 1.146a.5.5 0 000 .708L5.328 6a.5.5 0 00.708-.707L1.889 1.146a.5.5 0 00-.707 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.5 1.5A.5.5 0 005 1H1.5a.5.5 0 00-.5.5V5a.5.5 0 001 0V2h3a.5.5 0 00.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/arrows-move.svg b/src/assets/icons/arrows-move.svg
new file mode 100644
index 0000000..634dfce
--- /dev/null
+++ b/src/assets/icons/arrows-move.svg
@@ -0,0 +1,7 @@
+<svg class="bi bi-arrows-move" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.5 8a.5.5 0 00-.5-.5H1.5a.5.5 0 000 1H6a.5.5 0 00.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M3.854 5.646a.5.5 0 00-.708 0l-2 2a.5.5 0 000 .708l2 2a.5.5 0 00.708-.708L2.207 8l1.647-1.646a.5.5 0 000-.708zM9.5 8a.5.5 0 01.5-.5h4.5a.5.5 0 010 1H10a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M12.146 5.646a.5.5 0 01.708 0l2 2a.5.5 0 010 .708l-2 2a.5.5 0 01-.708-.708L13.793 8l-1.647-1.646a.5.5 0 010-.708zM8 9.5a.5.5 0 00-.5.5v4.5a.5.5 0 001 0V10a.5.5 0 00-.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.646 12.146a.5.5 0 000 .708l2 2a.5.5 0 00.708 0l2-2a.5.5 0 00-.708-.708L8 13.793l-1.646-1.647a.5.5 0 00-.708 0zM8 6.5a.5.5 0 01-.5-.5V1.5a.5.5 0 011 0V6a.5.5 0 01-.5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.646 3.854a.5.5 0 010-.708l2-2a.5.5 0 01.708 0l2 2a.5.5 0 01-.708.708L8 2.207 6.354 3.854a.5.5 0 01-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/aspect-ratio-fill.svg b/src/assets/icons/aspect-ratio-fill.svg
new file mode 100644
index 0000000..49d5e08
--- /dev/null
+++ b/src/assets/icons/aspect-ratio-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-aspect-ratio-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 2A1.5 1.5 0 000 3.5v9A1.5 1.5 0 001.5 14h13a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 2h-13zm1 2a.5.5 0 00-.5.5v3a.5.5 0 001 0V5h2.5a.5.5 0 000-1h-3zm11 8a.5.5 0 00.5-.5v-3a.5.5 0 00-1 0V11h-2.5a.5.5 0 000 1h3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/aspect-ratio.svg b/src/assets/icons/aspect-ratio.svg
new file mode 100644
index 0000000..1442997
--- /dev/null
+++ b/src/assets/icons/aspect-ratio.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-aspect-ratio" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 3.5A1.5 1.5 0 011.5 2h13A1.5 1.5 0 0116 3.5v9a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 010 12.5v-9zM1.5 3a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h13a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5h-13z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2 4.5a.5.5 0 01.5-.5h3a.5.5 0 010 1H3v2.5a.5.5 0 01-1 0v-3zm12 7a.5.5 0 01-.5.5h-3a.5.5 0 010-1H13V8.5a.5.5 0 011 0v3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/at.svg b/src/assets/icons/at.svg
new file mode 100644
index 0000000..5447748
--- /dev/null
+++ b/src/assets/icons/at.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-at" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13.106 7.222c0-2.967-2.249-5.032-5.482-5.032-3.35 0-5.646 2.318-5.646 5.702 0 3.493 2.235 5.708 5.762 5.708.862 0 1.689-.123 2.304-.335v-.862c-.43.199-1.354.328-2.29.328-2.926 0-4.813-1.88-4.813-4.798 0-2.844 1.921-4.881 4.594-4.881 2.735 0 4.608 1.688 4.608 4.156 0 1.682-.554 2.769-1.416 2.769-.492 0-.772-.28-.772-.76V5.206H8.923v.834h-.11c-.266-.595-.881-.964-1.6-.964-1.4 0-2.378 1.162-2.378 2.823 0 1.737.957 2.906 2.379 2.906.8 0 1.415-.39 1.709-1.087h.11c.081.67.703 1.148 1.503 1.148 1.572 0 2.57-1.415 2.57-3.643zm-7.177.704c0-1.197.54-1.907 1.456-1.907.93 0 1.524.738 1.524 1.907S8.308 9.84 7.371 9.84c-.895 0-1.442-.725-1.442-1.914z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/award-fill.svg b/src/assets/icons/award-fill.svg
new file mode 100644
index 0000000..5bb4d14
--- /dev/null
+++ b/src/assets/icons/award-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-award-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8 0l1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864 8 0z"/>
+ <path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1 4 11.794z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/award.svg b/src/assets/icons/award.svg
new file mode 100644
index 0000000..7f64d0e
--- /dev/null
+++ b/src/assets/icons/award.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-award" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.669.864L8 0 6.331.864l-1.858.282-.842 1.68-1.337 1.32L2.6 6l-.306 1.854 1.337 1.32.842 1.68 1.858.282L8 12l1.669-.864 1.858-.282.842-1.68 1.337-1.32L13.4 6l.306-1.854-1.337-1.32-.842-1.68L9.669.864zm1.196 1.193l-1.51-.229L8 1.126l-1.355.702-1.51.229-.684 1.365-1.086 1.072L3.614 6l-.25 1.506 1.087 1.072.684 1.365 1.51.229L8 10.874l1.356-.702 1.509-.229.684-1.365 1.086-1.072L12.387 6l.248-1.506-1.086-1.072-.684-1.365z" clip-rule="evenodd"/>
+ <path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1 4 11.794z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/backspace-fill.svg b/src/assets/icons/backspace-fill.svg
new file mode 100644
index 0000000..84ffe18
--- /dev/null
+++ b/src/assets/icons/backspace-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-backspace-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M15.683 3a2 2 0 00-2-2h-7.08a2 2 0 00-1.519.698L.241 7.35a1 1 0 000 1.302l4.843 5.65A2 2 0 006.603 15h7.08a2 2 0 002-2V3zM5.829 5.854a.5.5 0 11.707-.708l2.147 2.147 2.146-2.147a.5.5 0 11.707.708L9.39 8l2.146 2.146a.5.5 0 01-.707.708L8.683 8.707l-2.147 2.147a.5.5 0 01-.707-.708L7.976 8 5.829 5.854z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/backspace-reverse-fill.svg b/src/assets/icons/backspace-reverse-fill.svg
new file mode 100644
index 0000000..5b18374
--- /dev/null
+++ b/src/assets/icons/backspace-reverse-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-backspace-reverse-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 3a2 2 0 012-2h7.08a2 2 0 011.519.698l4.843 5.651a1 1 0 010 1.302L10.6 14.3a2 2 0 01-1.52.7H2a2 2 0 01-2-2V3zm9.854 2.854a.5.5 0 00-.708-.708L7 7.293 4.854 5.146a.5.5 0 10-.708.708L6.293 8l-2.147 2.146a.5.5 0 00.708.708L7 8.707l2.146 2.147a.5.5 0 00.708-.708L7.707 8l2.147-2.146z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/backspace-reverse.svg b/src/assets/icons/backspace-reverse.svg
new file mode 100644
index 0000000..8e256c4
--- /dev/null
+++ b/src/assets/icons/backspace-reverse.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-backspace-reverse" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.08 2H2a1 1 0 00-1 1v10a1 1 0 001 1h7.08a1 1 0 00.76-.35L14.682 8 9.839 2.35A1 1 0 009.08 2zM2 1a2 2 0 00-2 2v10a2 2 0 002 2h7.08a2 2 0 001.519-.698l4.843-5.651a1 1 0 000-1.302L10.6 1.7A2 2 0 009.08 1H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M9.854 5.146a.5.5 0 010 .708l-5 5a.5.5 0 01-.708-.708l5-5a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.146 5.146a.5.5 0 000 .708l5 5a.5.5 0 00.708-.708l-5-5a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/backspace.svg b/src/assets/icons/backspace.svg
new file mode 100644
index 0000000..4d59aee
--- /dev/null
+++ b/src/assets/icons/backspace.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-backspace" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.603 2h7.08a1 1 0 011 1v10a1 1 0 01-1 1h-7.08a1 1 0 01-.76-.35L1 8l4.844-5.65A1 1 0 016.603 2zm7.08-1a2 2 0 012 2v10a2 2 0 01-2 2h-7.08a2 2 0 01-1.519-.698L.241 8.65a1 1 0 010-1.302L5.084 1.7A2 2 0 016.603 1h7.08z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.83 5.146a.5.5 0 000 .708l5 5a.5.5 0 00.707-.708l-5-5a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.537 5.146a.5.5 0 010 .708l-5 5a.5.5 0 01-.708-.708l5-5a.5.5 0 01.707 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bag-fill.svg b/src/assets/icons/bag-fill.svg
new file mode 100644
index 0000000..78f8b6a
--- /dev/null
+++ b/src/assets/icons/bag-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-bag-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M1 4h14v10a2 2 0 01-2 2H3a2 2 0 01-2-2V4zm7-2.5A2.5 2.5 0 005.5 4h-1a3.5 3.5 0 117 0h-1A2.5 2.5 0 008 1.5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bag.svg b/src/assets/icons/bag.svg
new file mode 100644
index 0000000..2b082fc
--- /dev/null
+++ b/src/assets/icons/bag.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bag" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 5H2v9a1 1 0 001 1h10a1 1 0 001-1V5zM1 4v10a2 2 0 002 2h10a2 2 0 002-2V4H1z" clip-rule="evenodd"/>
+ <path d="M8 1.5A2.5 2.5 0 005.5 4h-1a3.5 3.5 0 117 0h-1A2.5 2.5 0 008 1.5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bar-chart-fill.svg b/src/assets/icons/bar-chart-fill.svg
new file mode 100644
index 0000000..22ad287
--- /dev/null
+++ b/src/assets/icons/bar-chart-fill.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-bar-chart-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <rect width="4" height="5" x="1" y="10" rx="1"/>
+ <rect width="4" height="9" x="6" y="6" rx="1"/>
+ <rect width="4" height="14" x="11" y="1" rx="1"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bar-chart.svg b/src/assets/icons/bar-chart.svg
new file mode 100644
index 0000000..7dcc04b
--- /dev/null
+++ b/src/assets/icons/bar-chart.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-bar-chart" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 11H2v3h2v-3zm5-4H7v7h2V7zm5-5h-2v12h2V2zm-2-1a1 1 0 00-1 1v12a1 1 0 001 1h2a1 1 0 001-1V2a1 1 0 00-1-1h-2zM6 7a1 1 0 011-1h2a1 1 0 011 1v7a1 1 0 01-1 1H7a1 1 0 01-1-1V7zm-5 4a1 1 0 011-1h2a1 1 0 011 1v3a1 1 0 01-1 1H2a1 1 0 01-1-1v-3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/battery-charging.svg b/src/assets/icons/battery-charging.svg
new file mode 100644
index 0000000..f8257eb
--- /dev/null
+++ b/src/assets/icons/battery-charging.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-battery-charging" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M14.5 9.5a1.5 1.5 0 000-3v3z"/>
+ <path fill-rule="evenodd" d="M9.585 2.568a.5.5 0 01.226.58L8.677 6.832h1.99a.5.5 0 01.364.843l-5.334 5.667a.5.5 0 01-.842-.49L5.99 9.167H4a.5.5 0 01-.364-.843l5.333-5.667a.5.5 0 01.616-.09z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6.332 4H2a2 2 0 00-2 2v4a2 2 0 002 2h2.072l.307-1H2a1 1 0 01-1-1V6a1 1 0 011-1h3.391l.941-1zM4.45 6H2v4h1.313a1.5 1.5 0 01-.405-2.361L4.45 6zm.976 5l-.308 1H6.96l.21-.224h.001l.73-.776H6.53l-.085.09.028-.09H5.426zm1.354-1H5.733l.257-.833H4a.5.5 0 01-.364-.843l.793-.843L5.823 6h1.373L5.157 8.167h1.51a.5.5 0 01.478.647L6.78 10zm.69 0h1.374l1.394-1.482.793-.842a.5.5 0 00-.364-.843h-1.99L8.933 6H7.887l-.166.54-.199.646A.5.5 0 008 7.833h1.51L7.47 10zm.725-5H9.24l.308-1H7.706l-.942 1h1.374l.085-.09-.028.09zm2.4-1l-.308 1H12a1 1 0 011 1v4a1 1 0 01-1 1H9.276l-.942 1H12a2 2 0 002-2V6a2 2 0 00-2-2h-1.405zm-.378 6H12V8.02a1.499 1.499 0 01-.241.341L10.217 10zM12 6.646V6h-.646a1.5 1.5 0 01.646.646z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/battery-full.svg b/src/assets/icons/battery-full.svg
new file mode 100644
index 0000000..2c5fc90
--- /dev/null
+++ b/src/assets/icons/battery-full.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-battery-full" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 5H2a1 1 0 00-1 1v4a1 1 0 001 1h10a1 1 0 001-1V6a1 1 0 00-1-1zM2 4a2 2 0 00-2 2v4a2 2 0 002 2h10a2 2 0 002-2V6a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path d="M2 6h10v4H2V6zm12.5 3.5a1.5 1.5 0 000-3v3z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/battery-half.svg b/src/assets/icons/battery-half.svg
new file mode 100644
index 0000000..ee73730
--- /dev/null
+++ b/src/assets/icons/battery-half.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-battery-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 5H2a1 1 0 00-1 1v4a1 1 0 001 1h10a1 1 0 001-1V6a1 1 0 00-1-1zM2 4a2 2 0 00-2 2v4a2 2 0 002 2h10a2 2 0 002-2V6a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path d="M2 6h5v4H2V6zm12.5 3.5a1.5 1.5 0 000-3v3z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/battery.svg b/src/assets/icons/battery.svg
new file mode 100644
index 0000000..1b983e6
--- /dev/null
+++ b/src/assets/icons/battery.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-battery" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 5H2a1 1 0 00-1 1v4a1 1 0 001 1h10a1 1 0 001-1V6a1 1 0 00-1-1zM2 4a2 2 0 00-2 2v4a2 2 0 002 2h10a2 2 0 002-2V6a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path d="M14.5 9.5a1.5 1.5 0 000-3v3z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bell-fill.svg b/src/assets/icons/bell-fill.svg
new file mode 100644
index 0000000..db6068b
--- /dev/null
+++ b/src/assets/icons/bell-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-bell-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8 16a2 2 0 002-2H6a2 2 0 002 2zm.995-14.901a1 1 0 10-1.99 0A5.002 5.002 0 003 6c0 1.098-.5 6-2 7h14c-1.5-1-2-5.902-2-7 0-2.42-1.72-4.44-4.005-4.901z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bell.svg b/src/assets/icons/bell.svg
new file mode 100644
index 0000000..e40465b
--- /dev/null
+++ b/src/assets/icons/bell.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bell" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8 16a2 2 0 002-2H6a2 2 0 002 2z"/>
+ <path fill-rule="evenodd" d="M8 1.918l-.797.161A4.002 4.002 0 004 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4.002 4.002 0 00-3.203-3.92L8 1.917zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 111.99 0A5.002 5.002 0 0113 6c0 .88.32 4.2 1.22 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/blockquote-left.svg b/src/assets/icons/blockquote-left.svg
new file mode 100644
index 0000000..15aeff1
--- /dev/null
+++ b/src/assets/icons/blockquote-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-blockquote-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 3.5a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm5 3a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5zm-5 3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path d="M3.734 6.352a6.586 6.586 0 00-.445.275 1.94 1.94 0 00-.346.299 1.38 1.38 0 00-.252.369c-.058.129-.1.295-.123.498h.282c.242 0 .431.06.568.182.14.117.21.29.21.521a.697.697 0 01-.187.463c-.12.14-.289.21-.503.21-.336 0-.577-.108-.721-.327C2.072 8.619 2 8.328 2 7.969c0-.254.055-.485.164-.692.11-.21.242-.398.398-.562.16-.168.33-.31.51-.428.18-.117.33-.213.451-.287l.211.352zm2.168 0a6.588 6.588 0 00-.445.275 1.94 1.94 0 00-.346.299c-.113.12-.199.246-.257.375a1.75 1.75 0 00-.118.492h.282c.242 0 .431.06.568.182.14.117.21.29.21.521a.697.697 0 01-.187.463c-.12.14-.289.21-.504.21-.335 0-.576-.108-.72-.327-.145-.223-.217-.514-.217-.873 0-.254.055-.485.164-.692.11-.21.242-.398.398-.562.16-.168.33-.31.51-.428.18-.117.33-.213.451-.287l.211.352z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/blockquote-right.svg b/src/assets/icons/blockquote-right.svg
new file mode 100644
index 0000000..0510768
--- /dev/null
+++ b/src/assets/icons/blockquote-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-blockquote-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 3.5a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path d="M12.168 6.352c.184.105.332.197.445.275.114.074.229.174.346.299.11.117.193.24.252.369s.1.295.123.498h-.281c-.243 0-.432.06-.569.182-.14.117-.21.29-.21.521 0 .164.062.318.187.463.121.14.289.21.504.21.336 0 .576-.108.72-.327.145-.223.217-.514.217-.873 0-.254-.054-.485-.164-.692a2.436 2.436 0 00-.398-.562c-.16-.168-.33-.31-.51-.428-.18-.117-.33-.213-.451-.287l-.211.352zm-2.168 0c.184.105.332.197.445.275.114.074.229.174.346.299.113.12.2.246.258.375.055.125.094.289.117.492h-.281c-.242 0-.432.06-.569.182-.14.117-.21.29-.21.521 0 .164.062.318.187.463.121.14.289.21.504.21.336 0 .576-.108.72-.327.145-.223.217-.514.217-.873 0-.254-.054-.485-.164-.692a2.438 2.438 0 00-.398-.562c-.16-.168-.33-.31-.51-.428-.18-.117-.33-.213-.451-.287L10 6.352z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/book-half.svg b/src/assets/icons/book-half.svg
new file mode 100644
index 0000000..b6e2dd4
--- /dev/null
+++ b/src/assets/icons/book-half.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-book-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.214 1.072C4.813.752 6.916.71 8.354 2.146A.5.5 0 018.5 2.5v11a.5.5 0 01-.854.354c-.843-.844-2.115-1.059-3.47-.92-1.344.14-2.66.617-3.452 1.013A.5.5 0 010 13.5v-11a.5.5 0 01.276-.447L.5 2.5l-.224-.447.002-.001.004-.002.013-.006a5.017 5.017 0 01.22-.103 12.958 12.958 0 012.7-.869zM1 2.82v9.908c.846-.343 1.944-.672 3.074-.788 1.143-.118 2.387-.023 3.426.56V2.718c-1.063-.929-2.631-.956-4.09-.664A11.958 11.958 0 001 2.82z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M12.786 1.072C11.188.752 9.084.71 7.646 2.146A.5.5 0 007.5 2.5v11a.5.5 0 00.854.354c.843-.844 2.115-1.059 3.47-.92 1.344.14 2.66.617 3.452 1.013A.5.5 0 0016 13.5v-11a.5.5 0 00-.276-.447L15.5 2.5l.224-.447-.002-.001-.004-.002-.013-.006-.047-.023a12.582 12.582 0 00-.799-.34 12.96 12.96 0 00-2.073-.609z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/book.svg b/src/assets/icons/book.svg
new file mode 100644
index 0000000..d72eb2d
--- /dev/null
+++ b/src/assets/icons/book.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-book" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.214 1.072C4.813.752 6.916.71 8.354 2.146A.5.5 0 018.5 2.5v11a.5.5 0 01-.854.354c-.843-.844-2.115-1.059-3.47-.92-1.344.14-2.66.617-3.452 1.013A.5.5 0 010 13.5v-11a.5.5 0 01.276-.447L.5 2.5l-.224-.447.002-.001.004-.002.013-.006a5.017 5.017 0 01.22-.103 12.958 12.958 0 012.7-.869zM1 2.82v9.908c.846-.343 1.944-.672 3.074-.788 1.143-.118 2.387-.023 3.426.56V2.718c-1.063-.929-2.631-.956-4.09-.664A11.958 11.958 0 001 2.82z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M12.786 1.072C11.188.752 9.084.71 7.646 2.146A.5.5 0 007.5 2.5v11a.5.5 0 00.854.354c.843-.844 2.115-1.059 3.47-.92 1.344.14 2.66.617 3.452 1.013A.5.5 0 0016 13.5v-11a.5.5 0 00-.276-.447L15.5 2.5l.224-.447-.002-.001-.004-.002-.013-.006-.047-.023a12.582 12.582 0 00-.799-.34 12.96 12.96 0 00-2.073-.609zM15 2.82v9.908c-.846-.343-1.944-.672-3.074-.788-1.143-.118-2.387-.023-3.426.56V2.718c1.063-.929 2.631-.956 4.09-.664A11.956 11.956 0 0115 2.82z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bookmark-check.svg b/src/assets/icons/bookmark-check.svg
new file mode 100644
index 0000000..37c343c
--- /dev/null
+++ b/src/assets/icons/bookmark-check.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bookmark-check" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.5 2a.5.5 0 00-.5.5v11.066l4-2.667 4 2.667V8.5a.5.5 0 011 0v6.934l-5-3.333-5 3.333V2.5A1.5 1.5 0 014.5 1h4a.5.5 0 010 1h-4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M15.854 2.146a.5.5 0 010 .708l-3 3a.5.5 0 01-.708 0l-1.5-1.5a.5.5 0 01.708-.708L12.5 4.793l2.646-2.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bookmark-dash.svg b/src/assets/icons/bookmark-dash.svg
new file mode 100644
index 0000000..a7fb3f0
--- /dev/null
+++ b/src/assets/icons/bookmark-dash.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-bookmark-dash" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11 3.5a.5.5 0 01.5-.5h4a.5.5 0 010 1h-4a.5.5 0 01-.5-.5zM4.5 2a.5.5 0 00-.5.5v11.066l4-2.667 4 2.667V8.5a.5.5 0 011 0v6.934l-5-3.333-5 3.333V2.5A1.5 1.5 0 014.5 1h4a.5.5 0 010 1h-4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bookmark-fill.svg b/src/assets/icons/bookmark-fill.svg
new file mode 100644
index 0000000..a50703f
--- /dev/null
+++ b/src/assets/icons/bookmark-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-bookmark-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3 3a2 2 0 012-2h6a2 2 0 012 2v12l-5-3-5 3V3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bookmark-plus.svg b/src/assets/icons/bookmark-plus.svg
new file mode 100644
index 0000000..ae64b34
--- /dev/null
+++ b/src/assets/icons/bookmark-plus.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bookmark-plus" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.5 2a.5.5 0 00-.5.5v11.066l4-2.667 4 2.667V8.5a.5.5 0 011 0v6.934l-5-3.333-5 3.333V2.5A1.5 1.5 0 014.5 1h4a.5.5 0 010 1h-4zm9-1a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 010-1H13V1.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13 3.5a.5.5 0 01.5-.5h2a.5.5 0 010 1H14v1.5a.5.5 0 01-1 0v-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bookmark.svg b/src/assets/icons/bookmark.svg
new file mode 100644
index 0000000..fea465d
--- /dev/null
+++ b/src/assets/icons/bookmark.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-bookmark" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 12l5 3V3a2 2 0 00-2-2H5a2 2 0 00-2 2v12l5-3zm-4 1.234l4-2.4 4 2.4V3a1 1 0 00-1-1H5a1 1 0 00-1 1v10.234z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bookmarks-fill.svg b/src/assets/icons/bookmarks-fill.svg
new file mode 100644
index 0000000..6b303e6
--- /dev/null
+++ b/src/assets/icons/bookmarks-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bookmarks-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 4a2 2 0 012-2h6a2 2 0 012 2v12l-5-3-5 3V4z" clip-rule="evenodd"/>
+ <path d="M14 14l-1-.6V2a1 1 0 00-1-1H4.268A2 2 0 016 0h6a2 2 0 012 2v12z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bookmarks.svg b/src/assets/icons/bookmarks.svg
new file mode 100644
index 0000000..1a7e6e3
--- /dev/null
+++ b/src/assets/icons/bookmarks.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bookmarks" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7 13l5 3V4a2 2 0 00-2-2H4a2 2 0 00-2 2v12l5-3zm-4 1.234l4-2.4 4 2.4V4a1 1 0 00-1-1H4a1 1 0 00-1 1v10.234z" clip-rule="evenodd"/>
+ <path d="M14 14l-1-.6V2a1 1 0 00-1-1H4.268A2 2 0 016 0h6a2 2 0 012 2v12z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bootstrap-fill.svg b/src/assets/icons/bootstrap-fill.svg
new file mode 100644
index 0000000..cce7595
--- /dev/null
+++ b/src/assets/icons/bootstrap-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-bootstrap-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.002 0a4 4 0 00-4 4v8a4 4 0 004 4h8a4 4 0 004-4V4a4 4 0 00-4-4h-8zm1.06 12h3.475c1.804 0 2.888-.908 2.888-2.396 0-1.102-.761-1.916-1.904-2.034v-.1c.832-.14 1.482-.93 1.482-1.816 0-1.3-.955-2.11-2.542-2.11H5.062V12zm1.313-4.875V4.658h1.78c.973 0 1.542.457 1.542 1.237 0 .802-.604 1.23-1.764 1.23H6.375zm0 3.762h1.898c1.184 0 1.81-.48 1.81-1.377 0-.885-.65-1.348-1.886-1.348H6.375v2.725z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bootstrap-reboot.svg b/src/assets/icons/bootstrap-reboot.svg
new file mode 100644
index 0000000..b77463d
--- /dev/null
+++ b/src/assets/icons/bootstrap-reboot.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-bootstrap-reboot" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.161 8a6.84 6.84 0 106.842-6.84.58.58 0 010-1.16 8 8 0 11-6.556 3.412l-.663-.577a.58.58 0 01.227-.997l2.52-.69a.58.58 0 01.728.633l-.332 2.592a.58.58 0 01-.956.364l-.643-.56A6.812 6.812 0 001.16 8zm5.48-.079V5.277h1.57c.881 0 1.416.499 1.416 1.32 0 .84-.504 1.324-1.386 1.324h-1.6zm0 3.75V8.843h1.57l1.498 2.828h1.314L9.377 8.665c.897-.3 1.427-1.106 1.427-2.1 0-1.37-.943-2.246-2.456-2.246H5.5v7.352h1.141z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bootstrap.svg b/src/assets/icons/bootstrap.svg
new file mode 100644
index 0000000..d12006e
--- /dev/null
+++ b/src/assets/icons/bootstrap.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bootstrap" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 1H4a3 3 0 00-3 3v8a3 3 0 003 3h8a3 3 0 003-3V4a3 3 0 00-3-3zM4 0a4 4 0 00-4 4v8a4 4 0 004 4h8a4 4 0 004-4V4a4 4 0 00-4-4H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8.537 12H5.062V3.545h3.399c1.587 0 2.543.809 2.543 2.11 0 .884-.65 1.675-1.483 1.816v.1c1.143.117 1.904.931 1.904 2.033 0 1.488-1.084 2.396-2.888 2.396zM6.375 4.658v2.467h1.558c1.16 0 1.764-.428 1.764-1.23 0-.78-.569-1.237-1.541-1.237H6.375zm1.898 6.229H6.375V8.162h1.822c1.236 0 1.887.463 1.887 1.348 0 .896-.627 1.377-1.811 1.377z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bounding-box-circles.svg b/src/assets/icons/bounding-box-circles.svg
new file mode 100644
index 0000000..f79e1e2
--- /dev/null
+++ b/src/assets/icons/bounding-box-circles.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bounding-box-circles" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12.5 2h-9V1h9v1zm-10 1.5v9h-1v-9h1zm11 9v-9h1v9h-1zM3.5 14h9v1h-9v-1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M14 3a1 1 0 100-2 1 1 0 000 2zm0 1a2 2 0 100-4 2 2 0 000 4zm0 11a1 1 0 100-2 1 1 0 000 2zm0 1a2 2 0 100-4 2 2 0 000 4zM2 3a1 1 0 100-2 1 1 0 000 2zm0 1a2 2 0 100-4 2 2 0 000 4zm0 11a1 1 0 100-2 1 1 0 000 2zm0 1a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bounding-box.svg b/src/assets/icons/bounding-box.svg
new file mode 100644
index 0000000..cb3983c
--- /dev/null
+++ b/src/assets/icons/bounding-box.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-bounding-box" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5 2V0H0v5h2v6H0v5h5v-2h6v2h5v-5h-2V5h2V0h-5v2H5zm6 1H5v2H3v6h2v2h6v-2h2V5h-2V3zm1-2v3h3V1h-3zm3 11h-3v3h3v-3zM4 15v-3H1v3h3zM1 4h3V1H1v3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-down-left.svg b/src/assets/icons/box-arrow-down-left.svg
new file mode 100644
index 0000000..bd7269d
--- /dev/null
+++ b/src/assets/icons/box-arrow-down-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-box-arrow-down-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13 1.5A1.5 1.5 0 0114.5 3v8a1.5 1.5 0 01-1.5 1.5H9a.5.5 0 010-1h4a.5.5 0 00.5-.5V3a.5.5 0 00-.5-.5H5a.5.5 0 00-.5.5v4a.5.5 0 01-1 0V3A1.5 1.5 0 015 1.5h8zm-11 7a.5.5 0 00-.5.5v5a.5.5 0 00.5.5h5a.5.5 0 000-1H2.5V9a.5.5 0 00-.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.646 14.354a.5.5 0 00.708 0l8-8a.5.5 0 00-.708-.708l-8 8a.5.5 0 000 .708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-down-right.svg b/src/assets/icons/box-arrow-down-right.svg
new file mode 100644
index 0000000..888cb99
--- /dev/null
+++ b/src/assets/icons/box-arrow-down-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-box-arrow-down-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3 1.5A1.5 1.5 0 001.5 3v8A1.5 1.5 0 003 12.5h4a.5.5 0 000-1H3a.5.5 0 01-.5-.5V3a.5.5 0 01.5-.5h8a.5.5 0 01.5.5v4a.5.5 0 001 0V3A1.5 1.5 0 0011 1.5H3zm11 7a.5.5 0 01.5.5v5a.5.5 0 01-.5.5H9a.5.5 0 010-1h4.5V9a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M14.354 14.354a.5.5 0 01-.708 0l-8-8a.5.5 0 11.708-.708l8 8a.5.5 0 010 .708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-down.svg b/src/assets/icons/box-arrow-down.svg
new file mode 100644
index 0000000..c78183f
--- /dev/null
+++ b/src/assets/icons/box-arrow-down.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.646 11.646a.5.5 0 01.708 0L8 14.293l2.646-2.647a.5.5 0 01.708.708l-3 3a.5.5 0 01-.708 0l-3-3a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 4.5a.5.5 0 01.5.5v9a.5.5 0 01-1 0V5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.5 2A1.5 1.5 0 014 .5h8A1.5 1.5 0 0113.5 2v7a1.5 1.5 0 01-1.5 1.5h-1.5a.5.5 0 010-1H12a.5.5 0 00.5-.5V2a.5.5 0 00-.5-.5H4a.5.5 0 00-.5.5v7a.5.5 0 00.5.5h1.5a.5.5 0 010 1H4A1.5 1.5 0 012.5 9V2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-in-down-left.svg b/src/assets/icons/box-arrow-in-down-left.svg
new file mode 100644
index 0000000..712b91a
--- /dev/null
+++ b/src/assets/icons/box-arrow-in-down-left.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-in-down-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 13A1.5 1.5 0 003 14.5h10a1.5 1.5 0 001.5-1.5V8a.5.5 0 00-1 0v5a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5V3a.5.5 0 01.5-.5h4a.5.5 0 000-1H3A1.5 1.5 0 001.5 3v10z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.5 10a.5.5 0 01-.5.5H6a.5.5 0 01-.5-.5V5a.5.5 0 011 0v4.5H11a.5.5 0 01.5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.646 10.354a.5.5 0 010-.708l8-8a.5.5 0 01.708.708l-8 8a.5.5 0 01-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-in-down-right.svg b/src/assets/icons/box-arrow-in-down-right.svg
new file mode 100644
index 0000000..8229839
--- /dev/null
+++ b/src/assets/icons/box-arrow-in-down-right.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-in-down-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 13a1.5 1.5 0 01-1.5 1.5H3A1.5 1.5 0 011.5 13V8a.5.5 0 011 0v5a.5.5 0 00.5.5h10a.5.5 0 00.5-.5V3a.5.5 0 00-.5-.5H9a.5.5 0 010-1h4A1.5 1.5 0 0114.5 3v10z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.5 10a.5.5 0 00.5.5h5a.5.5 0 00.5-.5V5a.5.5 0 00-1 0v4.5H5a.5.5 0 00-.5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.354 10.354a.5.5 0 000-.708l-8-8a.5.5 0 10-.708.708l8 8a.5.5 0 00.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-in-down.svg b/src/assets/icons/box-arrow-in-down.svg
new file mode 100644
index 0000000..35b8f72
--- /dev/null
+++ b/src/assets/icons/box-arrow-in-down.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-in-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.646 8.146a.5.5 0 01.708 0L8 10.793l2.646-2.647a.5.5 0 01.708.708l-3 3a.5.5 0 01-.708 0l-3-3a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 1a.5.5 0 01.5.5v9a.5.5 0 01-1 0v-9A.5.5 0 018 1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.5 13.5A1.5 1.5 0 003 15h10a1.5 1.5 0 001.5-1.5v-8A1.5 1.5 0 0013 4h-1.5a.5.5 0 000 1H13a.5.5 0 01.5.5v8a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5v-8A.5.5 0 013 5h1.5a.5.5 0 000-1H3a1.5 1.5 0 00-1.5 1.5v8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-in-left.svg b/src/assets/icons/box-arrow-in-left.svg
new file mode 100644
index 0000000..e98bf1d
--- /dev/null
+++ b/src/assets/icons/box-arrow-in-left.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-in-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.854 11.354a.5.5 0 000-.708L5.207 8l2.647-2.646a.5.5 0 10-.708-.708l-3 3a.5.5 0 000 .708l3 3a.5.5 0 00.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M15 8a.5.5 0 00-.5-.5h-9a.5.5 0 000 1h9A.5.5 0 0015 8z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.5 14.5A1.5 1.5 0 011 13V3a1.5 1.5 0 011.5-1.5h8A1.5 1.5 0 0112 3v1.5a.5.5 0 01-1 0V3a.5.5 0 00-.5-.5h-8A.5.5 0 002 3v10a.5.5 0 00.5.5h8a.5.5 0 00.5-.5v-1.5a.5.5 0 011 0V13a1.5 1.5 0 01-1.5 1.5h-8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-in-right.svg b/src/assets/icons/box-arrow-in-right.svg
new file mode 100644
index 0000000..76f5aae
--- /dev/null
+++ b/src/assets/icons/box-arrow-in-right.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-in-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.146 11.354a.5.5 0 010-.708L10.793 8 8.146 5.354a.5.5 0 11.708-.708l3 3a.5.5 0 010 .708l-3 3a.5.5 0 01-.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1 8a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9A.5.5 0 011 8z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13.5 14.5A1.5 1.5 0 0015 13V3a1.5 1.5 0 00-1.5-1.5h-8A1.5 1.5 0 004 3v1.5a.5.5 0 001 0V3a.5.5 0 01.5-.5h8a.5.5 0 01.5.5v10a.5.5 0 01-.5.5h-8A.5.5 0 015 13v-1.5a.5.5 0 00-1 0V13a1.5 1.5 0 001.5 1.5h8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-in-up-left.svg b/src/assets/icons/box-arrow-in-up-left.svg
new file mode 100644
index 0000000..d1e57a0
--- /dev/null
+++ b/src/assets/icons/box-arrow-in-up-left.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-in-up-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 3A1.5 1.5 0 013 1.5h10A1.5 1.5 0 0114.5 3v5a.5.5 0 01-1 0V3a.5.5 0 00-.5-.5H3a.5.5 0 00-.5.5v10a.5.5 0 00.5.5h4a.5.5 0 010 1H3A1.5 1.5 0 011.5 13V3z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.5 6a.5.5 0 00-.5-.5H6a.5.5 0 00-.5.5v5a.5.5 0 001 0V6.5H11a.5.5 0 00.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.646 5.646a.5.5 0 000 .708l8 8a.5.5 0 00.708-.708l-8-8a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-in-up-right.svg b/src/assets/icons/box-arrow-in-up-right.svg
new file mode 100644
index 0000000..f07b7b9
--- /dev/null
+++ b/src/assets/icons/box-arrow-in-up-right.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-in-up-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 3A1.5 1.5 0 0013 1.5H3A1.5 1.5 0 001.5 3v5a.5.5 0 001 0V3a.5.5 0 01.5-.5h10a.5.5 0 01.5.5v10a.5.5 0 01-.5.5H9a.5.5 0 000 1h4a1.5 1.5 0 001.5-1.5V3z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.5 6a.5.5 0 01.5-.5h5a.5.5 0 01.5.5v5a.5.5 0 01-1 0V6.5H5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.354 5.646a.5.5 0 010 .708l-8 8a.5.5 0 01-.708-.708l8-8a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-in-up.svg b/src/assets/icons/box-arrow-in-up.svg
new file mode 100644
index 0000000..7a6b463
--- /dev/null
+++ b/src/assets/icons/box-arrow-in-up.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-in-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.646 7.854a.5.5 0 00.708 0L8 5.207l2.646 2.647a.5.5 0 00.708-.708l-3-3a.5.5 0 00-.708 0l-3 3a.5.5 0 000 .708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 15a.5.5 0 00.5-.5v-9a.5.5 0 00-1 0v9a.5.5 0 00.5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.5 2.5A1.5 1.5 0 013 1h10a1.5 1.5 0 011.5 1.5v8A1.5 1.5 0 0113 12h-1.5a.5.5 0 010-1H13a.5.5 0 00.5-.5v-8A.5.5 0 0013 2H3a.5.5 0 00-.5.5v8a.5.5 0 00.5.5h1.5a.5.5 0 010 1H3a1.5 1.5 0 01-1.5-1.5v-8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-left.svg b/src/assets/icons/box-arrow-left.svg
new file mode 100644
index 0000000..ad91021
--- /dev/null
+++ b/src/assets/icons/box-arrow-left.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.354 11.354a.5.5 0 000-.708L1.707 8l2.647-2.646a.5.5 0 10-.708-.708l-3 3a.5.5 0 000 .708l3 3a.5.5 0 00.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.5 8a.5.5 0 00-.5-.5H2a.5.5 0 000 1h9a.5.5 0 00.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M14 13.5a1.5 1.5 0 001.5-1.5V4A1.5 1.5 0 0014 2.5H7A1.5 1.5 0 005.5 4v1.5a.5.5 0 001 0V4a.5.5 0 01.5-.5h7a.5.5 0 01.5.5v8a.5.5 0 01-.5.5H7a.5.5 0 01-.5-.5v-1.5a.5.5 0 00-1 0V12A1.5 1.5 0 007 13.5h7z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-right.svg b/src/assets/icons/box-arrow-right.svg
new file mode 100644
index 0000000..9b03763
--- /dev/null
+++ b/src/assets/icons/box-arrow-right.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.646 11.354a.5.5 0 010-.708L14.293 8l-2.647-2.646a.5.5 0 01.708-.708l3 3a.5.5 0 010 .708l-3 3a.5.5 0 01-.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.5 8a.5.5 0 01.5-.5h9a.5.5 0 010 1H5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2 13.5A1.5 1.5 0 01.5 12V4A1.5 1.5 0 012 2.5h7A1.5 1.5 0 0110.5 4v1.5a.5.5 0 01-1 0V4a.5.5 0 00-.5-.5H2a.5.5 0 00-.5.5v8a.5.5 0 00.5.5h7a.5.5 0 00.5-.5v-1.5a.5.5 0 011 0V12A1.5 1.5 0 019 13.5H2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-up-left.svg b/src/assets/icons/box-arrow-up-left.svg
new file mode 100644
index 0000000..6da272a
--- /dev/null
+++ b/src/assets/icons/box-arrow-up-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-box-arrow-up-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 13a1.5 1.5 0 01-1.5 1.5H5A1.5 1.5 0 013.5 13V9a.5.5 0 011 0v4a.5.5 0 00.5.5h8a.5.5 0 00.5-.5V5a.5.5 0 00-.5-.5H9a.5.5 0 010-1h4A1.5 1.5 0 0114.5 5v8zm-7-11a.5.5 0 00-.5-.5H2a.5.5 0 00-.5.5v5a.5.5 0 001 0V2.5H7a.5.5 0 00.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.646 1.646a.5.5 0 000 .708l8 8a.5.5 0 00.708-.708l-8-8a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-up-right.svg b/src/assets/icons/box-arrow-up-right.svg
new file mode 100644
index 0000000..1004af8
--- /dev/null
+++ b/src/assets/icons/box-arrow-up-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-box-arrow-up-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 13A1.5 1.5 0 003 14.5h8a1.5 1.5 0 001.5-1.5V9a.5.5 0 00-1 0v4a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5V5a.5.5 0 01.5-.5h4a.5.5 0 000-1H3A1.5 1.5 0 001.5 5v8zm7-11a.5.5 0 01.5-.5h5a.5.5 0 01.5.5v5a.5.5 0 01-1 0V2.5H9a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M14.354 1.646a.5.5 0 010 .708l-8 8a.5.5 0 01-.708-.708l8-8a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/box-arrow-up.svg b/src/assets/icons/box-arrow-up.svg
new file mode 100644
index 0000000..c400e0d
--- /dev/null
+++ b/src/assets/icons/box-arrow-up.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-box-arrow-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.646 4.354a.5.5 0 00.708 0L8 1.707l2.646 2.647a.5.5 0 00.708-.708l-3-3a.5.5 0 00-.708 0l-3 3a.5.5 0 000 .708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 11.5a.5.5 0 00.5-.5V2a.5.5 0 00-1 0v9a.5.5 0 00.5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.5 14A1.5 1.5 0 004 15.5h8a1.5 1.5 0 001.5-1.5V7A1.5 1.5 0 0012 5.5h-1.5a.5.5 0 000 1H12a.5.5 0 01.5.5v7a.5.5 0 01-.5.5H4a.5.5 0 01-.5-.5V7a.5.5 0 01.5-.5h1.5a.5.5 0 000-1H4A1.5 1.5 0 002.5 7v7z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/braces.svg b/src/assets/icons/braces.svg
new file mode 100644
index 0000000..6cd3710
--- /dev/null
+++ b/src/assets/icons/braces.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-braces" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M2.114 8.063V7.9c1.005-.102 1.497-.615 1.497-1.6V4.503c0-1.094.39-1.538 1.354-1.538h.273V2h-.376C3.25 2 2.49 2.759 2.49 4.352v1.524c0 1.094-.376 1.456-1.49 1.456v1.299c1.114 0 1.49.362 1.49 1.456v1.524c0 1.593.759 2.352 2.372 2.352h.376v-.964h-.273c-.964 0-1.354-.444-1.354-1.538V9.663c0-.984-.492-1.497-1.497-1.6zM13.886 7.9v.163c-1.005.103-1.497.616-1.497 1.6v1.798c0 1.094-.39 1.538-1.354 1.538h-.273v.964h.376c1.613 0 2.372-.759 2.372-2.352v-1.524c0-1.094.376-1.456 1.49-1.456V7.332c-1.114 0-1.49-.362-1.49-1.456V4.352C13.51 2.759 12.75 2 11.138 2h-.376v.964h.273c.964 0 1.354.444 1.354 1.538V6.3c0 .984.492 1.497 1.497 1.6z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/briefcase-fill.svg b/src/assets/icons/briefcase-fill.svg
new file mode 100644
index 0000000..12295dd
--- /dev/null
+++ b/src/assets/icons/briefcase-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-briefcase-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 12.5A1.5 1.5 0 001.5 14h13a1.5 1.5 0 001.5-1.5V6.85L8.129 8.947a.5.5 0 01-.258 0L0 6.85v5.65z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M0 4.5A1.5 1.5 0 011.5 3h13A1.5 1.5 0 0116 4.5v1.384l-7.614 2.03a1.5 1.5 0 01-.772 0L0 5.884V4.5zm5-2A1.5 1.5 0 016.5 1h3A1.5 1.5 0 0111 2.5V3h-1v-.5a.5.5 0 00-.5-.5h-3a.5.5 0 00-.5.5V3H5v-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/briefcase.svg b/src/assets/icons/briefcase.svg
new file mode 100644
index 0000000..755c65b
--- /dev/null
+++ b/src/assets/icons/briefcase.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-briefcase" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 12.5A1.5 1.5 0 001.5 14h13a1.5 1.5 0 001.5-1.5v-6h-1v6a.5.5 0 01-.5.5h-13a.5.5 0 01-.5-.5v-6H0v6z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M0 4.5A1.5 1.5 0 011.5 3h13A1.5 1.5 0 0116 4.5v2.384l-7.614 2.03a1.5 1.5 0 01-.772 0L0 6.884V4.5zM1.5 4a.5.5 0 00-.5.5v1.616l6.871 1.832a.5.5 0 00.258 0L15 6.116V4.5a.5.5 0 00-.5-.5h-13zM5 2.5A1.5 1.5 0 016.5 1h3A1.5 1.5 0 0111 2.5V3h-1v-.5a.5.5 0 00-.5-.5h-3a.5.5 0 00-.5.5V3H5v-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/brightness-alt-high-fill.svg b/src/assets/icons/brightness-alt-high-fill.svg
new file mode 100644
index 0000000..08a7f1c
--- /dev/null
+++ b/src/assets/icons/brightness-alt-high-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-brightness-alt-high-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 11a4 4 0 118 0 .5.5 0 01-.5.5h-7A.5.5 0 014 11zm4-8a.5.5 0 01.5.5v2a.5.5 0 01-1 0v-2A.5.5 0 018 3zm8 8a.5.5 0 01-.5.5h-2a.5.5 0 010-1h2a.5.5 0 01.5.5zM3 11a.5.5 0 01-.5.5h-2a.5.5 0 010-1h2a.5.5 0 01.5.5zm10.657-5.657a.5.5 0 010 .707l-1.414 1.414a.5.5 0 11-.707-.707l1.414-1.414a.5.5 0 01.707 0zM4.464 7.464a.5.5 0 01-.707 0L2.343 6.05a.5.5 0 01.707-.707l1.414 1.414a.5.5 0 010 .707z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/brightness-alt-high.svg b/src/assets/icons/brightness-alt-high.svg
new file mode 100644
index 0000000..9a9159c
--- /dev/null
+++ b/src/assets/icons/brightness-alt-high.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-brightness-alt-high" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.041 10.5h5.918a3 3 0 00-5.918 0zM4 11a4 4 0 118 0 .5.5 0 01-.5.5h-7A.5.5 0 014 11zm4-8a.5.5 0 01.5.5v2a.5.5 0 01-1 0v-2A.5.5 0 018 3zm8 8a.5.5 0 01-.5.5h-2a.5.5 0 010-1h2a.5.5 0 01.5.5zM3 11a.5.5 0 01-.5.5h-2a.5.5 0 010-1h2a.5.5 0 01.5.5zm10.657-5.657a.5.5 0 010 .707l-1.414 1.414a.5.5 0 11-.707-.707l1.414-1.414a.5.5 0 01.707 0zM4.464 7.464a.5.5 0 01-.707 0L2.343 6.05a.5.5 0 01.707-.707l1.414 1.414a.5.5 0 010 .707z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/brightness-alt-low-fill.svg b/src/assets/icons/brightness-alt-low-fill.svg
new file mode 100644
index 0000000..92a71e5
--- /dev/null
+++ b/src/assets/icons/brightness-alt-low-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-brightness-alt-low-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8.5 5.5a.5.5 0 11-1 0 .5.5 0 011 0zm5 6a.5.5 0 110-1 .5.5 0 010 1zm-11 0a.5.5 0 110-1 .5.5 0 010 1zm9.743-4.036a.5.5 0 11-.707-.707.5.5 0 01.707.707zm-8.486 0a.5.5 0 11.707-.707.5.5 0 01-.707.707z"/>
+ <path fill-rule="evenodd" d="M4 11a4 4 0 118 0 .5.5 0 01-.5.5h-7A.5.5 0 014 11z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/brightness-alt-low.svg b/src/assets/icons/brightness-alt-low.svg
new file mode 100644
index 0000000..26422c5
--- /dev/null
+++ b/src/assets/icons/brightness-alt-low.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-brightness-alt-low" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8.5 5.5a.5.5 0 11-1 0 .5.5 0 011 0zm5 6a.5.5 0 110-1 .5.5 0 010 1zm-11 0a.5.5 0 110-1 .5.5 0 010 1zm9.743-4.036a.5.5 0 11-.707-.707.5.5 0 01.707.707zm-8.486 0a.5.5 0 11.707-.707.5.5 0 01-.707.707z"/>
+ <path fill-rule="evenodd" d="M5.041 10.5h5.918a3 3 0 00-5.918 0zM4 11a4 4 0 118 0 .5.5 0 01-.5.5h-7A.5.5 0 014 11z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/brightness-high-fill.svg b/src/assets/icons/brightness-high-fill.svg
new file mode 100644
index 0000000..214640c
--- /dev/null
+++ b/src/assets/icons/brightness-high-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-brightness-high-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="8" cy="8" r="4"/>
+ <path fill-rule="evenodd" d="M8 0a.5.5 0 01.5.5v2a.5.5 0 01-1 0v-2A.5.5 0 018 0zm0 13a.5.5 0 01.5.5v2a.5.5 0 01-1 0v-2A.5.5 0 018 13zm8-5a.5.5 0 01-.5.5h-2a.5.5 0 010-1h2a.5.5 0 01.5.5zM3 8a.5.5 0 01-.5.5h-2a.5.5 0 010-1h2A.5.5 0 013 8zm10.657-5.657a.5.5 0 010 .707l-1.414 1.415a.5.5 0 11-.707-.708l1.414-1.414a.5.5 0 01.707 0zm-9.193 9.193a.5.5 0 010 .707L3.05 13.657a.5.5 0 01-.707-.707l1.414-1.414a.5.5 0 01.707 0zm9.193 2.121a.5.5 0 01-.707 0l-1.414-1.414a.5.5 0 01.707-.707l1.414 1.414a.5.5 0 010 .707zM4.464 4.465a.5.5 0 01-.707 0L2.343 3.05a.5.5 0 01.707-.707l1.414 1.414a.5.5 0 010 .708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/brightness-high.svg b/src/assets/icons/brightness-high.svg
new file mode 100644
index 0000000..fe4517f
--- /dev/null
+++ b/src/assets/icons/brightness-high.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-brightness-high" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 11a3 3 0 100-6 3 3 0 000 6zm0 1a4 4 0 100-8 4 4 0 000 8zM8 0a.5.5 0 01.5.5v2a.5.5 0 01-1 0v-2A.5.5 0 018 0zm0 13a.5.5 0 01.5.5v2a.5.5 0 01-1 0v-2A.5.5 0 018 13zm8-5a.5.5 0 01-.5.5h-2a.5.5 0 010-1h2a.5.5 0 01.5.5zM3 8a.5.5 0 01-.5.5h-2a.5.5 0 010-1h2A.5.5 0 013 8zm10.657-5.657a.5.5 0 010 .707l-1.414 1.415a.5.5 0 11-.707-.708l1.414-1.414a.5.5 0 01.707 0zm-9.193 9.193a.5.5 0 010 .707L3.05 13.657a.5.5 0 01-.707-.707l1.414-1.414a.5.5 0 01.707 0zm9.193 2.121a.5.5 0 01-.707 0l-1.414-1.414a.5.5 0 01.707-.707l1.414 1.414a.5.5 0 010 .707zM4.464 4.465a.5.5 0 01-.707 0L2.343 3.05a.5.5 0 11.707-.707l1.414 1.414a.5.5 0 010 .708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/brightness-low-fill.svg b/src/assets/icons/brightness-low-fill.svg
new file mode 100644
index 0000000..54c3002
--- /dev/null
+++ b/src/assets/icons/brightness-low-fill.svg
@@ -0,0 +1,11 @@
+<svg class="bi bi-brightness-low-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="8" cy="8" r="4"/>
+ <circle cx="8" cy="2.5" r=".5"/>
+ <circle cx="8" cy="13.5" r=".5"/>
+ <circle cx="13.5" cy="8" r=".5" transform="rotate(90 13.5 8)"/>
+ <circle cx="2.5" cy="8" r=".5" transform="rotate(90 2.5 8)"/>
+ <circle cx="11.889" cy="4.111" r=".5" transform="rotate(45 11.89 4.11)"/>
+ <circle cx="4.111" cy="11.889" r=".5" transform="rotate(45 4.11 11.89)"/>
+ <circle cx="11.889" cy="11.889" r=".5" transform="rotate(135 11.89 11.889)"/>
+ <circle cx="4.111" cy="4.111" r=".5" transform="rotate(135 4.11 4.11)"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/brightness-low.svg b/src/assets/icons/brightness-low.svg
new file mode 100644
index 0000000..ca49799
--- /dev/null
+++ b/src/assets/icons/brightness-low.svg
@@ -0,0 +1,11 @@
+<svg class="bi bi-brightness-low" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 11a3 3 0 100-6 3 3 0 000 6zm0 1a4 4 0 100-8 4 4 0 000 8z" clip-rule="evenodd"/>
+ <circle cx="8" cy="2.5" r=".5"/>
+ <circle cx="8" cy="13.5" r=".5"/>
+ <circle cx="13.5" cy="8" r=".5" transform="rotate(90 13.5 8)"/>
+ <circle cx="2.5" cy="8" r=".5" transform="rotate(90 2.5 8)"/>
+ <circle cx="11.889" cy="4.111" r=".5" transform="rotate(45 11.89 4.11)"/>
+ <circle cx="4.111" cy="11.889" r=".5" transform="rotate(45 4.11 11.89)"/>
+ <circle cx="11.889" cy="11.889" r=".5" transform="rotate(135 11.89 11.889)"/>
+ <circle cx="4.111" cy="4.111" r=".5" transform="rotate(135 4.11 4.11)"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/brush.svg b/src/assets/icons/brush.svg
new file mode 100644
index 0000000..8717fa9
--- /dev/null
+++ b/src/assets/icons/brush.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-brush" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M15.213 1.018a.572.572 0 01.756.05.57.57 0 01.057.746C15.085 3.082 12.044 7.107 9.6 9.55c-.71.71-1.42 1.243-1.952 1.596-.508.339-1.167.234-1.599-.197-.416-.416-.53-1.047-.212-1.543.346-.542.887-1.273 1.642-1.977 2.521-2.35 6.476-5.44 7.734-6.411z"/>
+ <path d="M7 12a2 2 0 01-2 2c-1 0-2 0-3.5-.5s.5-1 1-1.5 1.395-2 2.5-2a2 2 0 012 2z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bucket-fill.svg b/src/assets/icons/bucket-fill.svg
new file mode 100644
index 0000000..391d0d2
--- /dev/null
+++ b/src/assets/icons/bucket-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bucket-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 1.5A4.5 4.5 0 003.5 6h-1a5.5 5.5 0 1111 0h-1A4.5 4.5 0 008 1.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.61 5.687A.5.5 0 012 5.5h12a.5.5 0 01.488.608l-1.826 8.217a1.5 1.5 0 01-1.464 1.175H4.802a1.5 1.5 0 01-1.464-1.175L1.512 6.108a.5.5 0 01.098-.42z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bucket.svg b/src/assets/icons/bucket.svg
new file mode 100644
index 0000000..ca8576d
--- /dev/null
+++ b/src/assets/icons/bucket.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-bucket" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 1.5A4.5 4.5 0 003.5 6h-1a5.5 5.5 0 1111 0h-1A4.5 4.5 0 008 1.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.61 5.687A.5.5 0 012 5.5h12a.5.5 0 01.488.608l-1.826 8.217a1.5 1.5 0 01-1.464 1.175H4.802a1.5 1.5 0 01-1.464-1.175L1.512 6.108a.5.5 0 01.098-.42zm1.013.813l1.691 7.608a.5.5 0 00.488.392h6.396a.5.5 0 00.488-.392l1.69-7.608H2.624z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/building.svg b/src/assets/icons/building.svg
new file mode 100644
index 0000000..6ae302f
--- /dev/null
+++ b/src/assets/icons/building.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-building" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M15.285.089A.5.5 0 0115.5.5v15a.5.5 0 01-.5.5h-3a.5.5 0 01-.5-.5V14h-1v1.5a.5.5 0 01-.5.5H1a.5.5 0 01-.5-.5v-6a.5.5 0 01.418-.493l5.582-.93V3.5a.5.5 0 01.324-.468l8-3a.5.5 0 01.46.057zM7.5 3.846V8.5a.5.5 0 01-.418.493l-5.582.93V15h8v-1.5a.5.5 0 01.5-.5h2a.5.5 0 01.5.5V15h2V1.222l-7 2.624z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6.5 15.5v-7h1v7h-1z" clip-rule="evenodd"/>
+ <path d="M2.5 11h1v1h-1v-1zm2 0h1v1h-1v-1zm-2 2h1v1h-1v-1zm2 0h1v1h-1v-1zm6-10h1v1h-1V3zm2 0h1v1h-1V3zm-4 2h1v1h-1V5zm2 0h1v1h-1V5zm2 0h1v1h-1V5zm-2 2h1v1h-1V7zm2 0h1v1h-1V7zm-4 0h1v1h-1V7zm0 2h1v1h-1V9zm2 0h1v1h-1V9zm2 0h1v1h-1V9zm-4 2h1v1h-1v-1zm2 0h1v1h-1v-1zm2 0h1v1h-1v-1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/bullseye.svg b/src/assets/icons/bullseye.svg
new file mode 100644
index 0000000..d0d00a8
--- /dev/null
+++ b/src/assets/icons/bullseye.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-bullseye" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 13A5 5 0 108 3a5 5 0 000 10zm0 1A6 6 0 108 2a6 6 0 000 12z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 11a3 3 0 100-6 3 3 0 000 6zm0 1a4 4 0 100-8 4 4 0 000 8z" clip-rule="evenodd"/>
+ <path d="M9.5 8a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/calendar-fill.svg b/src/assets/icons/calendar-fill.svg
new file mode 100644
index 0000000..de5037a
--- /dev/null
+++ b/src/assets/icons/calendar-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-calendar-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M0 2a2 2 0 012-2h12a2 2 0 012 2H0z"/>
+ <path fill-rule="evenodd" d="M0 3h16v11a2 2 0 01-2 2H2a2 2 0 01-2-2V3zm6.5 4a1 1 0 100-2 1 1 0 000 2zm4-1a1 1 0 11-2 0 1 1 0 012 0zm2 1a1 1 0 100-2 1 1 0 000 2zm-8 2a1 1 0 11-2 0 1 1 0 012 0zm2 1a1 1 0 100-2 1 1 0 000 2zm4-1a1 1 0 11-2 0 1 1 0 012 0zm2 1a1 1 0 100-2 1 1 0 000 2zm-8 2a1 1 0 11-2 0 1 1 0 012 0zm2 1a1 1 0 100-2 1 1 0 000 2zm4-1a1 1 0 11-2 0 1 1 0 012 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/calendar.svg b/src/assets/icons/calendar.svg
new file mode 100644
index 0000000..3f745ac
--- /dev/null
+++ b/src/assets/icons/calendar.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-calendar" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 0H2a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2zM1 3.857C1 3.384 1.448 3 2 3h12c.552 0 1 .384 1 .857v10.286c0 .473-.448.857-1 .857H2c-.552 0-1-.384-1-.857V3.857z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6.5 7a1 1 0 100-2 1 1 0 000 2zm3 0a1 1 0 100-2 1 1 0 000 2zm3 0a1 1 0 100-2 1 1 0 000 2zm-9 3a1 1 0 100-2 1 1 0 000 2zm3 0a1 1 0 100-2 1 1 0 000 2zm3 0a1 1 0 100-2 1 1 0 000 2zm3 0a1 1 0 100-2 1 1 0 000 2zm-9 3a1 1 0 100-2 1 1 0 000 2zm3 0a1 1 0 100-2 1 1 0 000 2zm3 0a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/camera-video-fill.svg b/src/assets/icons/camera-video-fill.svg
new file mode 100644
index 0000000..001c9cf
--- /dev/null
+++ b/src/assets/icons/camera-video-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-camera-video-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M2.667 3h6.666C10.253 3 11 3.746 11 4.667v6.666c0 .92-.746 1.667-1.667 1.667H2.667C1.747 13 1 12.254 1 11.333V4.667C1 3.747 1.746 3 2.667 3z"/>
+ <path d="M7.404 8.697l6.363 3.692c.54.313 1.233-.066 1.233-.697V4.308c0-.63-.693-1.01-1.233-.696L7.404 7.304a.802.802 0 000 1.393z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/camera-video.svg b/src/assets/icons/camera-video.svg
new file mode 100644
index 0000000..5e3da5f
--- /dev/null
+++ b/src/assets/icons/camera-video.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-camera-video" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.667 3.5c-.645 0-1.167.522-1.167 1.167v6.666c0 .645.522 1.167 1.167 1.167h6.666c.645 0 1.167-.522 1.167-1.167V4.667c0-.645-.522-1.167-1.167-1.167H2.667zM.5 4.667C.5 3.47 1.47 2.5 2.667 2.5h6.666c1.197 0 2.167.97 2.167 2.167v6.666c0 1.197-.97 2.167-2.167 2.167H2.667A2.167 2.167 0 01.5 11.333V4.667z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.25 5.65l2.768-1.605a.318.318 0 01.482.263v7.384c0 .228-.26.393-.482.264l-2.767-1.605-.502.865 2.767 1.605c.859.498 1.984-.095 1.984-1.129V4.308c0-1.033-1.125-1.626-1.984-1.128L10.75 4.785l.502.865z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/camera.svg b/src/assets/icons/camera.svg
new file mode 100644
index 0000000..fab165a
--- /dev/null
+++ b/src/assets/icons/camera.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-camera" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9 5C7.343 5 5 6.343 5 8a4 4 0 014-4v1z"/>
+ <path fill-rule="evenodd" d="M14.333 3h-2.015A5.97 5.97 0 009 2a5.972 5.972 0 00-3.318 1H1.667C.747 3 0 3.746 0 4.667v6.666C0 12.253.746 13 1.667 13h4.015c.95.632 2.091 1 3.318 1a5.973 5.973 0 003.318-1h2.015c.92 0 1.667-.746 1.667-1.667V4.667C16 3.747 15.254 3 14.333 3zM1.5 5a.5.5 0 100-1 .5.5 0 000 1zM9 13A5 5 0 109 3a5 5 0 000 10z" clip-rule="evenodd"/>
+ <path d="M2 3a1 1 0 011-1h1a1 1 0 010 2H3a1 1 0 01-1-1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/capslock-fill.svg b/src/assets/icons/capslock-fill.svg
new file mode 100644
index 0000000..ffa8dbc
--- /dev/null
+++ b/src/assets/icons/capslock-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-capslock-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.27 1.047a1 1 0 011.46 0l6.345 6.77c.6.638.146 1.683-.73 1.683H11.5v1a1 1 0 01-1 1h-5a1 1 0 01-1-1v-1H1.654C.78 9.5.326 8.455.924 7.816L7.27 1.047zM4.5 13.5a1 1 0 011-1h5a1 1 0 011 1v1a1 1 0 01-1 1h-5a1 1 0 01-1-1v-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/capslock.svg b/src/assets/icons/capslock.svg
new file mode 100644
index 0000000..c8c5896
--- /dev/null
+++ b/src/assets/icons/capslock.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-capslock" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.27 1.047a1 1 0 011.46 0l6.345 6.77c.6.638.146 1.683-.73 1.683H11.5v1a1 1 0 01-1 1h-5a1 1 0 01-1-1v-1H1.654C.78 9.5.326 8.455.924 7.816L7.27 1.047zM14.346 8.5L8 1.731 1.654 8.5H4.5a1 1 0 011 1v1h5v-1a1 1 0 011-1h2.846zm-9.846 5a1 1 0 011-1h5a1 1 0 011 1v1a1 1 0 01-1 1h-5a1 1 0 01-1-1v-1zm6 0h-5v1h5v-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/card-checklist.svg b/src/assets/icons/card-checklist.svg
new file mode 100644
index 0000000..9824848
--- /dev/null
+++ b/src/assets/icons/card-checklist.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-card-checklist" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 3h-13a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h13a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5zm-13-1A1.5 1.5 0 000 3.5v9A1.5 1.5 0 001.5 14h13a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 2h-13z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7 5.5a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5zm-1.496-.854a.5.5 0 010 .708l-1.5 1.5a.5.5 0 01-.708 0l-.5-.5a.5.5 0 11.708-.708l.146.147 1.146-1.147a.5.5 0 01.708 0zM7 9.5a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5zm-1.496-.854a.5.5 0 010 .708l-1.5 1.5a.5.5 0 01-.708 0l-.5-.5a.5.5 0 01.708-.708l.146.147 1.146-1.147a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/card-heading.svg b/src/assets/icons/card-heading.svg
new file mode 100644
index 0000000..bbbe5fe
--- /dev/null
+++ b/src/assets/icons/card-heading.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-card-heading" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 3h-13a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h13a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5zm-13-1A1.5 1.5 0 000 3.5v9A1.5 1.5 0 001.5 14h13a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 2h-13z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M3 8.5a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zm0 2a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path d="M3 5.5a.5.5 0 01.5-.5h9a.5.5 0 01.5.5v1a.5.5 0 01-.5.5h-9a.5.5 0 01-.5-.5v-1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/card-image.svg b/src/assets/icons/card-image.svg
new file mode 100644
index 0000000..ab1cf54
--- /dev/null
+++ b/src/assets/icons/card-image.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-card-image" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 3h-13a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h13a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5zm-13-1A1.5 1.5 0 000 3.5v9A1.5 1.5 0 001.5 14h13a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 2h-13z" clip-rule="evenodd"/>
+ <path d="M10.648 7.646a.5.5 0 01.577-.093L15.002 9.5V13h-14v-1l2.646-2.354a.5.5 0 01.63-.062l2.66 1.773 3.71-3.71z"/>
+ <path fill-rule="evenodd" d="M4.502 7a1.5 1.5 0 100-3 1.5 1.5 0 000 3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/card-list.svg b/src/assets/icons/card-list.svg
new file mode 100644
index 0000000..e882859
--- /dev/null
+++ b/src/assets/icons/card-list.svg
@@ -0,0 +1,7 @@
+<svg class="bi bi-card-list" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 3h-13a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h13a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5zm-13-1A1.5 1.5 0 000 3.5v9A1.5 1.5 0 001.5 14h13a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 2h-13z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 8a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7A.5.5 0 015 8zm0-2.5a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm0 5a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <circle cx="3.5" cy="5.5" r=".5"/>
+ <circle cx="3.5" cy="8" r=".5"/>
+ <circle cx="3.5" cy="10.5" r=".5"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/card-text.svg b/src/assets/icons/card-text.svg
new file mode 100644
index 0000000..cccc74b
--- /dev/null
+++ b/src/assets/icons/card-text.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-card-text" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 3h-13a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h13a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5zm-13-1A1.5 1.5 0 000 3.5v9A1.5 1.5 0 001.5 14h13a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 2h-13z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M3 5.5a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zM3 8a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9A.5.5 0 013 8zm0 2.5a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/caret-down-fill.svg b/src/assets/icons/caret-down-fill.svg
new file mode 100644
index 0000000..bd235f9
--- /dev/null
+++ b/src/assets/icons/caret-down-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-caret-down-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 01.753 1.659l-4.796 5.48a1 1 0 01-1.506 0z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/caret-down.svg b/src/assets/icons/caret-down.svg
new file mode 100644
index 0000000..1a5a00d
--- /dev/null
+++ b/src/assets/icons/caret-down.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-caret-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.204 5L8 10.481 12.796 5H3.204zm-.753.659l4.796 5.48a1 1 0 001.506 0l4.796-5.48c.566-.647.106-1.659-.753-1.659H3.204a1 1 0 00-.753 1.659z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/caret-left-fill.svg b/src/assets/icons/caret-left-fill.svg
new file mode 100644
index 0000000..b5376b5
--- /dev/null
+++ b/src/assets/icons/caret-left-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-caret-left-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M3.86 8.753l5.482 4.796c.646.566 1.658.106 1.658-.753V3.204a1 1 0 00-1.659-.753l-5.48 4.796a1 1 0 000 1.506z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/caret-left.svg b/src/assets/icons/caret-left.svg
new file mode 100644
index 0000000..c368eb2
--- /dev/null
+++ b/src/assets/icons/caret-left.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-caret-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M10 12.796L4.519 8 10 3.204v9.592zm-.659.753l-5.48-4.796a1 1 0 010-1.506l5.48-4.796A1 1 0 0111 3.204v9.592a1 1 0 01-1.659.753z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/caret-right-fill.svg b/src/assets/icons/caret-right-fill.svg
new file mode 100644
index 0000000..59f9b4a
--- /dev/null
+++ b/src/assets/icons/caret-right-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-caret-right-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12.14 8.753l-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 011.659-.753l5.48 4.796a1 1 0 010 1.506z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/caret-right.svg b/src/assets/icons/caret-right.svg
new file mode 100644
index 0000000..363f3cb
--- /dev/null
+++ b/src/assets/icons/caret-right.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-caret-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6 12.796L11.481 8 6 3.204v9.592zm.659.753l5.48-4.796a1 1 0 000-1.506L6.66 2.451C6.011 1.885 5 2.345 5 3.204v9.592a1 1 0 001.659.753z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/caret-up-fill.svg b/src/assets/icons/caret-up-fill.svg
new file mode 100644
index 0000000..eb93a4c
--- /dev/null
+++ b/src/assets/icons/caret-up-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-caret-up-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M7.247 4.86l-4.796 5.481c-.566.647-.106 1.659.753 1.659h9.592a1 1 0 00.753-1.659l-4.796-5.48a1 1 0 00-1.506 0z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/caret-up.svg b/src/assets/icons/caret-up.svg
new file mode 100644
index 0000000..a617980
--- /dev/null
+++ b/src/assets/icons/caret-up.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-caret-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.204 11L8 5.519 12.796 11H3.204zm-.753-.659l4.796-5.48a1 1 0 011.506 0l4.796 5.48c.566.647.106 1.659-.753 1.659H3.204a1 1 0 01-.753-1.659z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-dots-fill.svg b/src/assets/icons/chat-dots-fill.svg
new file mode 100644
index 0000000..aad68c4
--- /dev/null
+++ b/src/assets/icons/chat-dots-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chat-dots-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8c0 3.866-3.582 7-8 7a9.06 9.06 0 01-2.347-.306c-.584.296-1.925.864-4.181 1.234-.2.032-.352-.176-.273-.362.354-.836.674-1.95.77-2.966C.744 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7zM5 8a1 1 0 11-2 0 1 1 0 012 0zm4 0a1 1 0 11-2 0 1 1 0 012 0zm3 1a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-dots.svg b/src/assets/icons/chat-dots.svg
new file mode 100644
index 0000000..bdbd7d4
--- /dev/null
+++ b/src/assets/icons/chat-dots.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-chat-dots" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.678 11.894a1 1 0 01.287.801 10.97 10.97 0 01-.398 2c1.395-.323 2.247-.697 2.634-.893a1 1 0 01.71-.074A8.06 8.06 0 008 14c3.996 0 7-2.807 7-6 0-3.192-3.004-6-7-6S1 4.808 1 8c0 1.468.617 2.83 1.678 3.894zm-.493 3.905a21.682 21.682 0 01-.713.129c-.2.032-.352-.176-.273-.362a9.68 9.68 0 00.244-.637l.003-.01c.248-.72.45-1.548.524-2.319C.743 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7-3.582 7-8 7a9.06 9.06 0 01-2.347-.306c-.52.263-1.639.742-3.468 1.105z" clip-rule="evenodd"/>
+ <path d="M5 8a1 1 0 11-2 0 1 1 0 012 0zm4 0a1 1 0 11-2 0 1 1 0 012 0zm4 0a1 1 0 11-2 0 1 1 0 012 0z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-fill.svg b/src/assets/icons/chat-fill.svg
new file mode 100644
index 0000000..608e4a9
--- /dev/null
+++ b/src/assets/icons/chat-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chat-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8 15c4.418 0 8-3.134 8-7s-3.582-7-8-7-8 3.134-8 7c0 1.76.743 3.37 1.97 4.6-.097 1.016-.417 2.13-.771 2.966-.079.186.074.394.273.362 2.256-.37 3.597-.938 4.18-1.234A9.06 9.06 0 008 15z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-quote-fill.svg b/src/assets/icons/chat-quote-fill.svg
new file mode 100644
index 0000000..169d51b
--- /dev/null
+++ b/src/assets/icons/chat-quote-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chat-quote-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8c0 3.866-3.582 7-8 7a9.06 9.06 0 01-2.347-.306c-.584.296-1.925.864-4.181 1.234-.2.032-.352-.176-.273-.362.354-.836.674-1.95.77-2.966C.744 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7zM7.194 6.766c.087.124.163.26.227.401.428.948.393 2.377-.942 3.706a.446.446 0 01-.612.01.405.405 0 01-.011-.59c.419-.416.672-.831.809-1.22-.269.165-.588.26-.93.26C4.775 9.333 4 8.587 4 7.667 4 6.747 4.776 6 5.734 6c.271 0 .528.06.756.166l.008.004c.169.07.327.182.469.324.085.083.161.174.227.272zM11 9.073c-.269.165-.588.26-.93.26-.958 0-1.735-.746-1.735-1.666 0-.92.777-1.667 1.734-1.667.271 0 .528.06.756.166l.008.004c.17.07.327.182.469.324.085.083.161.174.227.272.087.124.164.26.228.401.428.948.392 2.377-.942 3.706a.446.446 0 01-.613.01.405.405 0 01-.011-.59c.42-.416.672-.831.81-1.22z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-quote.svg b/src/assets/icons/chat-quote.svg
new file mode 100644
index 0000000..d204e12
--- /dev/null
+++ b/src/assets/icons/chat-quote.svg
@@ -0,0 +1,7 @@
+<svg class="bi bi-chat-quote" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.678 11.894a1 1 0 01.287.801 10.97 10.97 0 01-.398 2c1.395-.323 2.247-.697 2.634-.893a1 1 0 01.71-.074A8.06 8.06 0 008 14c3.996 0 7-2.807 7-6 0-3.192-3.004-6-7-6S1 4.808 1 8c0 1.468.617 2.83 1.678 3.894zm-.493 3.905a21.682 21.682 0 01-.713.129c-.2.032-.352-.176-.273-.362a9.68 9.68 0 00.244-.637l.003-.01c.248-.72.45-1.548.524-2.319C.743 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7-3.582 7-8 7a9.06 9.06 0 01-2.347-.306c-.52.263-1.639.742-3.468 1.105z" clip-rule="evenodd"/>
+ <path d="M7.468 7.667c0 .92-.776 1.666-1.734 1.666S4 8.587 4 7.667C4 6.747 4.776 6 5.734 6s1.734.746 1.734 1.667z"/>
+ <path fill-rule="evenodd" d="M6.157 6.936a.438.438 0 01-.56.293.413.413 0 01-.274-.527c.08-.23.23-.44.477-.546a.891.891 0 01.698.014c.387.16.72.545.923.997.428.948.393 2.377-.942 3.706a.446.446 0 01-.612.01.405.405 0 01-.011-.59c1.093-1.087 1.058-2.158.77-2.794-.152-.336-.354-.514-.47-.563zm-.035-.012h-.001.001z" clip-rule="evenodd"/>
+ <path d="M11.803 7.667c0 .92-.776 1.666-1.734 1.666-.957 0-1.734-.746-1.734-1.666 0-.92.777-1.667 1.734-1.667.958 0 1.734.746 1.734 1.667z"/>
+ <path fill-rule="evenodd" d="M10.492 6.936a.438.438 0 01-.56.293.413.413 0 01-.274-.527c.08-.23.23-.44.477-.546a.891.891 0 01.698.014c.387.16.72.545.924.997.428.948.392 2.377-.942 3.706a.446.446 0 01-.613.01.405.405 0 01-.011-.59c1.093-1.087 1.058-2.158.77-2.794-.152-.336-.354-.514-.469-.563zm-.034-.012h-.002.002z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-square-dots-fill.svg b/src/assets/icons/chat-square-dots-fill.svg
new file mode 100644
index 0000000..1102580
--- /dev/null
+++ b/src/assets/icons/chat-square-dots-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chat-square-dots-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 2a2 2 0 012-2h12a2 2 0 012 2v8a2 2 0 01-2 2h-2.5a1 1 0 00-.8.4l-1.9 2.533a1 1 0 01-1.6 0L5.3 12.4a1 1 0 00-.8-.4H2a2 2 0 01-2-2V2zm5 4a1 1 0 11-2 0 1 1 0 012 0zm4 0a1 1 0 11-2 0 1 1 0 012 0zm3 1a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-square-dots.svg b/src/assets/icons/chat-square-dots.svg
new file mode 100644
index 0000000..3659f7f
--- /dev/null
+++ b/src/assets/icons/chat-square-dots.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-chat-square-dots" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v8a1 1 0 001 1h2.5a2 2 0 011.6.8L8 14.333 9.9 11.8a2 2 0 011.6-.8H14a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v8a2 2 0 002 2h2.5a1 1 0 01.8.4l1.9 2.533a1 1 0 001.6 0l1.9-2.533a1 1 0 01.8-.4H14a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path d="M5 6a1 1 0 11-2 0 1 1 0 012 0zm4 0a1 1 0 11-2 0 1 1 0 012 0zm4 0a1 1 0 11-2 0 1 1 0 012 0z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-square-fill.svg b/src/assets/icons/chat-square-fill.svg
new file mode 100644
index 0000000..a78271d
--- /dev/null
+++ b/src/assets/icons/chat-square-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chat-square-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 0a2 2 0 00-2 2v8a2 2 0 002 2h2.5a1 1 0 01.8.4l1.9 2.533a1 1 0 001.6 0l1.9-2.533a1 1 0 01.8-.4H14a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-square-quote-fill.svg b/src/assets/icons/chat-square-quote-fill.svg
new file mode 100644
index 0000000..54ce71b
--- /dev/null
+++ b/src/assets/icons/chat-square-quote-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chat-square-quote-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 2a2 2 0 012-2h12a2 2 0 012 2v8a2 2 0 01-2 2h-2.5a1 1 0 00-.8.4l-1.9 2.533a1 1 0 01-1.6 0L5.3 12.4a1 1 0 00-.8-.4H2a2 2 0 01-2-2V2zm7.194 2.766c.087.124.163.26.227.401.428.948.393 2.377-.942 3.706a.446.446 0 01-.612.01.405.405 0 01-.011-.59c.419-.416.672-.831.809-1.22-.269.165-.588.26-.93.26C4.775 7.333 4 6.587 4 5.667 4 4.747 4.776 4 5.734 4c.271 0 .528.06.756.166l.008.004c.169.07.327.182.469.324.085.083.161.174.227.272zM11 7.073c-.269.165-.588.26-.93.26-.958 0-1.735-.746-1.735-1.666 0-.92.777-1.667 1.734-1.667.271 0 .528.06.756.166l.008.004c.17.07.327.182.469.324.085.083.161.174.227.272.087.124.164.26.228.401.428.948.392 2.377-.942 3.706a.446.446 0 01-.613.01.405.405 0 01-.011-.59c.42-.416.672-.831.81-1.22z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-square-quote.svg b/src/assets/icons/chat-square-quote.svg
new file mode 100644
index 0000000..7674d28
--- /dev/null
+++ b/src/assets/icons/chat-square-quote.svg
@@ -0,0 +1,7 @@
+<svg class="bi bi-chat-square-quote" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v8a1 1 0 001 1h2.5a2 2 0 011.6.8L8 14.333 9.9 11.8a2 2 0 011.6-.8H14a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v8a2 2 0 002 2h2.5a1 1 0 01.8.4l1.9 2.533a1 1 0 001.6 0l1.9-2.533a1 1 0 01.8-.4H14a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path d="M7.468 5.667c0 .92-.776 1.666-1.734 1.666S4 6.587 4 5.667C4 4.747 4.776 4 5.734 4s1.734.746 1.734 1.667z"/>
+ <path fill-rule="evenodd" d="M6.157 4.936a.438.438 0 01-.56.293.413.413 0 01-.274-.527c.08-.23.23-.44.477-.546a.891.891 0 01.698.014c.387.16.72.545.923.997.428.948.393 2.377-.942 3.706a.446.446 0 01-.612.01.405.405 0 01-.011-.59c1.093-1.087 1.058-2.158.77-2.794-.152-.336-.354-.514-.47-.563z" clip-rule="evenodd"/>
+ <path d="M11.803 5.667c0 .92-.776 1.666-1.734 1.666-.957 0-1.734-.746-1.734-1.666 0-.92.777-1.667 1.734-1.667.958 0 1.734.746 1.734 1.667z"/>
+ <path fill-rule="evenodd" d="M10.492 4.936a.438.438 0 01-.56.293.413.413 0 01-.274-.527c.08-.23.23-.44.477-.546a.891.891 0 01.698.014c.387.16.72.545.924.997.428.948.392 2.377-.942 3.706a.446.446 0 01-.613.01.405.405 0 01-.011-.59c1.093-1.087 1.058-2.158.77-2.794-.152-.336-.354-.514-.469-.563z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat-square.svg b/src/assets/icons/chat-square.svg
new file mode 100644
index 0000000..1757b06
--- /dev/null
+++ b/src/assets/icons/chat-square.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chat-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v8a1 1 0 001 1h2.5a2 2 0 011.6.8L8 14.333 9.9 11.8a2 2 0 011.6-.8H14a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v8a2 2 0 002 2h2.5a1 1 0 01.8.4l1.9 2.533a1 1 0 001.6 0l1.9-2.533a1 1 0 01.8-.4H14a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chat.svg b/src/assets/icons/chat.svg
new file mode 100644
index 0000000..9748c1f
--- /dev/null
+++ b/src/assets/icons/chat.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chat" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.678 11.894a1 1 0 01.287.801 10.97 10.97 0 01-.398 2c1.395-.323 2.247-.697 2.634-.893a1 1 0 01.71-.074A8.06 8.06 0 008 14c3.996 0 7-2.807 7-6 0-3.192-3.004-6-7-6S1 4.808 1 8c0 1.468.617 2.83 1.678 3.894zm-.493 3.905a21.682 21.682 0 01-.713.129c-.2.032-.352-.176-.273-.362a9.68 9.68 0 00.244-.637l.003-.01c.248-.72.45-1.548.524-2.319C.743 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7-3.582 7-8 7a9.06 9.06 0 01-2.347-.306c-.52.263-1.639.742-3.468 1.105z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/check-all.svg b/src/assets/icons/check-all.svg
new file mode 100644
index 0000000..29b9297
--- /dev/null
+++ b/src/assets/icons/check-all.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-check-all" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12.354 3.646a.5.5 0 010 .708l-7 7a.5.5 0 01-.708 0l-3.5-3.5a.5.5 0 11.708-.708L5 10.293l6.646-6.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path d="M6.25 8.043l-.896-.897a.5.5 0 10-.708.708l.897.896.707-.707zm1 2.414l.896.897a.5.5 0 00.708 0l7-7a.5.5 0 00-.708-.708L8.5 10.293l-.543-.543-.707.707z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/check-box.svg b/src/assets/icons/check-box.svg
new file mode 100644
index 0000000..f0aa4a8
--- /dev/null
+++ b/src/assets/icons/check-box.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-check-box" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M15.354 2.646a.5.5 0 010 .708l-7 7a.5.5 0 01-.708 0l-3-3a.5.5 0 11.708-.708L8 9.293l6.646-6.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.5 13A1.5 1.5 0 003 14.5h10a1.5 1.5 0 001.5-1.5V8a.5.5 0 00-1 0v5a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5V3a.5.5 0 01.5-.5h8a.5.5 0 000-1H3A1.5 1.5 0 001.5 3v10z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/check-circle.svg b/src/assets/icons/check-circle.svg
new file mode 100644
index 0000000..c2c3361
--- /dev/null
+++ b/src/assets/icons/check-circle.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-check-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M15.354 2.646a.5.5 0 010 .708l-7 7a.5.5 0 01-.708 0l-3-3a.5.5 0 11.708-.708L8 9.293l6.646-6.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 2.5A5.5 5.5 0 1013.5 8a.5.5 0 011 0 6.5 6.5 0 11-3.25-5.63.5.5 0 11-.5.865A5.472 5.472 0 008 2.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/check.svg b/src/assets/icons/check.svg
new file mode 100644
index 0000000..8324a62
--- /dev/null
+++ b/src/assets/icons/check.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-check" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13.854 3.646a.5.5 0 010 .708l-7 7a.5.5 0 01-.708 0l-3.5-3.5a.5.5 0 11.708-.708L6.5 10.293l6.646-6.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-bar-contract.svg b/src/assets/icons/chevron-bar-contract.svg
new file mode 100644
index 0000000..eabdfaf
--- /dev/null
+++ b/src/assets/icons/chevron-bar-contract.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-bar-contract" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.646 14.854a.5.5 0 00.708 0L8 11.207l3.646 3.647a.5.5 0 00.708-.708l-4-4a.5.5 0 00-.708 0l-4 4a.5.5 0 000 .708zm0-13.708a.5.5 0 01.708 0L8 4.793l3.646-3.647a.5.5 0 01.708.708l-4 4a.5.5 0 01-.708 0l-4-4a.5.5 0 010-.708zM1 8a.5.5 0 01.5-.5h13a.5.5 0 010 1h-13A.5.5 0 011 8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-bar-down.svg b/src/assets/icons/chevron-bar-down.svg
new file mode 100644
index 0000000..39f8bef
--- /dev/null
+++ b/src/assets/icons/chevron-bar-down.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-bar-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.646 4.146a.5.5 0 01.708 0L8 7.793l3.646-3.647a.5.5 0 01.708.708l-4 4a.5.5 0 01-.708 0l-4-4a.5.5 0 010-.708zM1 11.5a.5.5 0 01.5-.5h13a.5.5 0 010 1h-13a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-bar-expand.svg b/src/assets/icons/chevron-bar-expand.svg
new file mode 100644
index 0000000..2fe79d4
--- /dev/null
+++ b/src/assets/icons/chevron-bar-expand.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-bar-expand" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.646 10.146a.5.5 0 01.708 0L8 13.793l3.646-3.647a.5.5 0 01.708.708l-4 4a.5.5 0 01-.708 0l-4-4a.5.5 0 010-.708zm0-4.292a.5.5 0 00.708 0L8 2.207l3.646 3.647a.5.5 0 00.708-.708l-4-4a.5.5 0 00-.708 0l-4 4a.5.5 0 000 .708zM1 8a.5.5 0 01.5-.5h13a.5.5 0 010 1h-13A.5.5 0 011 8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-bar-left.svg b/src/assets/icons/chevron-bar-left.svg
new file mode 100644
index 0000000..0069916
--- /dev/null
+++ b/src/assets/icons/chevron-bar-left.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-bar-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.854 3.646a.5.5 0 010 .708L8.207 8l3.647 3.646a.5.5 0 01-.708.708l-4-4a.5.5 0 010-.708l4-4a.5.5 0 01.708 0zM4.5 1a.5.5 0 00-.5.5v13a.5.5 0 001 0v-13a.5.5 0 00-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-bar-right.svg b/src/assets/icons/chevron-bar-right.svg
new file mode 100644
index 0000000..f33d86b
--- /dev/null
+++ b/src/assets/icons/chevron-bar-right.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-bar-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.146 3.646a.5.5 0 000 .708L7.793 8l-3.647 3.646a.5.5 0 00.708.708l4-4a.5.5 0 000-.708l-4-4a.5.5 0 00-.708 0zM11.5 1a.5.5 0 01.5.5v13a.5.5 0 01-1 0v-13a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-bar-up.svg b/src/assets/icons/chevron-bar-up.svg
new file mode 100644
index 0000000..8b653b0
--- /dev/null
+++ b/src/assets/icons/chevron-bar-up.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-bar-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.646 11.854a.5.5 0 00.708 0L8 8.207l3.646 3.647a.5.5 0 00.708-.708l-4-4a.5.5 0 00-.708 0l-4 4a.5.5 0 000 .708zM2.4 5.2c0 .22.18.4.4.4h10.4a.4.4 0 000-.8H2.8a.4.4 0 00-.4.4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-compact-down.svg b/src/assets/icons/chevron-compact-down.svg
new file mode 100644
index 0000000..d7eb34f
--- /dev/null
+++ b/src/assets/icons/chevron-compact-down.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-compact-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.553 6.776a.5.5 0 01.67-.223L8 9.44l5.776-2.888a.5.5 0 11.448.894l-6 3a.5.5 0 01-.448 0l-6-3a.5.5 0 01-.223-.67z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-compact-left.svg b/src/assets/icons/chevron-compact-left.svg
new file mode 100644
index 0000000..d84410b
--- /dev/null
+++ b/src/assets/icons/chevron-compact-left.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-compact-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.224 1.553a.5.5 0 01.223.67L6.56 8l2.888 5.776a.5.5 0 11-.894.448l-3-6a.5.5 0 010-.448l3-6a.5.5 0 01.67-.223z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-compact-right.svg b/src/assets/icons/chevron-compact-right.svg
new file mode 100644
index 0000000..a54f61a
--- /dev/null
+++ b/src/assets/icons/chevron-compact-right.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-compact-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.776 1.553a.5.5 0 01.671.223l3 6a.5.5 0 010 .448l-3 6a.5.5 0 11-.894-.448L9.44 8 6.553 2.224a.5.5 0 01.223-.671z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-compact-up.svg b/src/assets/icons/chevron-compact-up.svg
new file mode 100644
index 0000000..64d347a
--- /dev/null
+++ b/src/assets/icons/chevron-compact-up.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-compact-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.776 5.553a.5.5 0 01.448 0l6 3a.5.5 0 11-.448.894L8 6.56 2.224 9.447a.5.5 0 11-.448-.894l6-3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-contract.svg b/src/assets/icons/chevron-contract.svg
new file mode 100644
index 0000000..0adf235
--- /dev/null
+++ b/src/assets/icons/chevron-contract.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-contract" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.646 13.854a.5.5 0 00.708 0L8 10.207l3.646 3.647a.5.5 0 00.708-.708l-4-4a.5.5 0 00-.708 0l-4 4a.5.5 0 000 .708zm0-11.708a.5.5 0 01.708 0L8 5.793l3.646-3.647a.5.5 0 01.708.708l-4 4a.5.5 0 01-.708 0l-4-4a.5.5 0 010-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-double-down.svg b/src/assets/icons/chevron-double-down.svg
new file mode 100644
index 0000000..70a4de6
--- /dev/null
+++ b/src/assets/icons/chevron-double-down.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-chevron-double-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.646 6.646a.5.5 0 01.708 0L8 12.293l5.646-5.647a.5.5 0 01.708.708l-6 6a.5.5 0 01-.708 0l-6-6a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.646 2.646a.5.5 0 01.708 0L8 8.293l5.646-5.647a.5.5 0 01.708.708l-6 6a.5.5 0 01-.708 0l-6-6a.5.5 0 010-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-double-left.svg b/src/assets/icons/chevron-double-left.svg
new file mode 100644
index 0000000..06d5d59
--- /dev/null
+++ b/src/assets/icons/chevron-double-left.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-chevron-double-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.354 1.646a.5.5 0 010 .708L2.707 8l5.647 5.646a.5.5 0 01-.708.708l-6-6a.5.5 0 010-.708l6-6a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M12.354 1.646a.5.5 0 010 .708L6.707 8l5.647 5.646a.5.5 0 01-.708.708l-6-6a.5.5 0 010-.708l6-6a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-double-right.svg b/src/assets/icons/chevron-double-right.svg
new file mode 100644
index 0000000..59434fc
--- /dev/null
+++ b/src/assets/icons/chevron-double-right.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-chevron-double-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.646 1.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L9.293 8 3.646 2.354a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.646 1.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L13.293 8 7.646 2.354a.5.5 0 010-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-double-up.svg b/src/assets/icons/chevron-double-up.svg
new file mode 100644
index 0000000..55004a4
--- /dev/null
+++ b/src/assets/icons/chevron-double-up.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-chevron-double-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.646 2.646a.5.5 0 01.708 0l6 6a.5.5 0 01-.708.708L8 3.707 2.354 9.354a.5.5 0 11-.708-.708l6-6z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.646 6.646a.5.5 0 01.708 0l6 6a.5.5 0 01-.708.708L8 7.707l-5.646 5.647a.5.5 0 01-.708-.708l6-6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-down.svg b/src/assets/icons/chevron-down.svg
new file mode 100644
index 0000000..ff9110c
--- /dev/null
+++ b/src/assets/icons/chevron-down.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 01.708 0L8 10.293l5.646-5.647a.5.5 0 01.708.708l-6 6a.5.5 0 01-.708 0l-6-6a.5.5 0 010-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-expand.svg b/src/assets/icons/chevron-expand.svg
new file mode 100644
index 0000000..9b56541
--- /dev/null
+++ b/src/assets/icons/chevron-expand.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-expand" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.646 9.146a.5.5 0 01.708 0L8 12.793l3.646-3.647a.5.5 0 01.708.708l-4 4a.5.5 0 01-.708 0l-4-4a.5.5 0 010-.708zm0-2.292a.5.5 0 00.708 0L8 3.207l3.646 3.647a.5.5 0 00.708-.708l-4-4a.5.5 0 00-.708 0l-4 4a.5.5 0 000 .708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-left.svg b/src/assets/icons/chevron-left.svg
new file mode 100644
index 0000000..a3e6c73
--- /dev/null
+++ b/src/assets/icons/chevron-left.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 010 .708L5.707 8l5.647 5.646a.5.5 0 01-.708.708l-6-6a.5.5 0 010-.708l6-6a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-right.svg b/src/assets/icons/chevron-right.svg
new file mode 100644
index 0000000..d077952
--- /dev/null
+++ b/src/assets/icons/chevron-right.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L10.293 8 4.646 2.354a.5.5 0 010-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/chevron-up.svg b/src/assets/icons/chevron-up.svg
new file mode 100644
index 0000000..6f361f6
--- /dev/null
+++ b/src/assets/icons/chevron-up.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-chevron-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.646 4.646a.5.5 0 01.708 0l6 6a.5.5 0 01-.708.708L8 5.707l-5.646 5.647a.5.5 0 01-.708-.708l6-6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/circle-fill.svg b/src/assets/icons/circle-fill.svg
new file mode 100644
index 0000000..64d438e
--- /dev/null
+++ b/src/assets/icons/circle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-circle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="8" cy="8" r="8"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/circle-half.svg b/src/assets/icons/circle-half.svg
new file mode 100644
index 0000000..8fceb64
--- /dev/null
+++ b/src/assets/icons/circle-half.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-circle-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15V1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/circle-square.svg b/src/assets/icons/circle-square.svg
new file mode 100644
index 0000000..7f0c2e8
--- /dev/null
+++ b/src/assets/icons/circle-square.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-circle-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M0 6a6 6 0 1112 0A6 6 0 010 6z"/>
+ <path d="M12.93 5h1.57a.5.5 0 01.5.5v9a.5.5 0 01-.5.5h-9a.5.5 0 01-.5-.5v-1.57a6.953 6.953 0 01-1-.22v1.79A1.5 1.5 0 005.5 16h9a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 4h-1.79c.097.324.17.658.22 1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/circle.svg b/src/assets/icons/circle.svg
new file mode 100644
index 0000000..3bdddd7
--- /dev/null
+++ b/src/assets/icons/circle.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/clipboard-data.svg b/src/assets/icons/clipboard-data.svg
new file mode 100644
index 0000000..62a25dd
--- /dev/null
+++ b/src/assets/icons/clipboard-data.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-clipboard-data" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1.5H3a2 2 0 00-2 2V14a2 2 0 002 2h10a2 2 0 002-2V3.5a2 2 0 00-2-2h-1v1h1a1 1 0 011 1V14a1 1 0 01-1 1H3a1 1 0 01-1-1V3.5a1 1 0 011-1h1v-1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M9.5 1h-3a.5.5 0 00-.5.5v1a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-1a.5.5 0 00-.5-.5zm-3-1A1.5 1.5 0 005 1.5v1A1.5 1.5 0 006.5 4h3A1.5 1.5 0 0011 2.5v-1A1.5 1.5 0 009.5 0h-3z" clip-rule="evenodd"/>
+ <path d="M4 11a1 1 0 112 0v1a1 1 0 11-2 0v-1zm6-4a1 1 0 112 0v5a1 1 0 11-2 0V7zM7 9a1 1 0 012 0v3a1 1 0 11-2 0V9z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/clipboard.svg b/src/assets/icons/clipboard.svg
new file mode 100644
index 0000000..f0915d5
--- /dev/null
+++ b/src/assets/icons/clipboard.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-clipboard" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1.5H3a2 2 0 00-2 2V14a2 2 0 002 2h10a2 2 0 002-2V3.5a2 2 0 00-2-2h-1v1h1a1 1 0 011 1V14a1 1 0 01-1 1H3a1 1 0 01-1-1V3.5a1 1 0 011-1h1v-1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M9.5 1h-3a.5.5 0 00-.5.5v1a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-1a.5.5 0 00-.5-.5zm-3-1A1.5 1.5 0 005 1.5v1A1.5 1.5 0 006.5 4h3A1.5 1.5 0 0011 2.5v-1A1.5 1.5 0 009.5 0h-3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/clock-fill.svg b/src/assets/icons/clock-fill.svg
new file mode 100644
index 0000000..1d9b817
--- /dev/null
+++ b/src/assets/icons/clock-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-clock-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8A8 8 0 110 8a8 8 0 0116 0zM8 3.5a.5.5 0 00-1 0V9a.5.5 0 00.252.434l3.5 2a.5.5 0 00.496-.868L8 8.71V3.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/clock-history.svg b/src/assets/icons/clock-history.svg
new file mode 100644
index 0000000..66523a5
--- /dev/null
+++ b/src/assets/icons/clock-history.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-clock-history" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.515 1.019A7 7 0 008 1V0a8 8 0 01.589.022l-.074.997zm2.004.45a7.003 7.003 0 00-.985-.299l.219-.976c.383.086.76.2 1.126.342l-.36.933zm1.37.71a7.01 7.01 0 00-.439-.27l.493-.87a8.025 8.025 0 01.979.654l-.615.789a6.996 6.996 0 00-.418-.302zm1.834 1.79a6.99 6.99 0 00-.653-.796l.724-.69c.27.285.52.59.747.91l-.818.576zm.744 1.352a7.08 7.08 0 00-.214-.468l.893-.45a7.976 7.976 0 01.45 1.088l-.95.313a7.023 7.023 0 00-.179-.483zm.53 2.507a6.991 6.991 0 00-.1-1.025l.985-.17c.067.386.106.778.116 1.17l-1 .025zm-.131 1.538c.033-.17.06-.339.081-.51l.993.123a7.957 7.957 0 01-.23 1.155l-.964-.267c.046-.165.086-.332.12-.501zm-.952 2.379c.184-.29.346-.594.486-.908l.914.405c-.16.36-.345.706-.555 1.038l-.845-.535zm-.964 1.205c.122-.122.239-.248.35-.378l.758.653a8.073 8.073 0 01-.401.432l-.707-.707z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 1a7 7 0 104.95 11.95l.707.707A8.001 8.001 0 118 0v1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.5 3a.5.5 0 01.5.5v5.21l3.248 1.856a.5.5 0 01-.496.868l-3.5-2A.5.5 0 017 9V3.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/clock.svg b/src/assets/icons/clock.svg
new file mode 100644
index 0000000..95cc436
--- /dev/null
+++ b/src/assets/icons/clock.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-clock" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm8-7A8 8 0 110 8a8 8 0 0116 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.5 3a.5.5 0 01.5.5v5.21l3.248 1.856a.5.5 0 01-.496.868l-3.5-2A.5.5 0 017 9V3.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/cloud-download.svg b/src/assets/icons/cloud-download.svg
new file mode 100644
index 0000000..4525b01
--- /dev/null
+++ b/src/assets/icons/cloud-download.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-cloud-download" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4.887 5.2l-.964-.165A2.5 2.5 0 103.5 10H6v1H3.5a3.5 3.5 0 11.59-6.95 5.002 5.002 0 119.804 1.98A2.501 2.501 0 0113.5 11H10v-1h3.5a1.5 1.5 0 00.237-2.981L12.7 6.854l.216-1.028a4 4 0 10-7.843-1.587l-.185.96z"/>
+ <path fill-rule="evenodd" d="M5 12.5a.5.5 0 01.707 0L8 14.793l2.293-2.293a.5.5 0 11.707.707l-2.646 2.646a.5.5 0 01-.708 0L5 13.207a.5.5 0 010-.707z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 6a.5.5 0 01.5.5v8a.5.5 0 01-1 0v-8A.5.5 0 018 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/cloud-fill.svg b/src/assets/icons/cloud-fill.svg
new file mode 100644
index 0000000..20a1c4a
--- /dev/null
+++ b/src/assets/icons/cloud-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-cloud-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.5 13a3.5 3.5 0 11.59-6.95 5.002 5.002 0 119.804 1.98A2.5 2.5 0 0113.5 13h-10z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/cloud-upload.svg b/src/assets/icons/cloud-upload.svg
new file mode 100644
index 0000000..847df99
--- /dev/null
+++ b/src/assets/icons/cloud-upload.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-cloud-upload" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4.887 6.2l-.964-.165A2.5 2.5 0 103.5 11H6v1H3.5a3.5 3.5 0 11.59-6.95 5.002 5.002 0 119.804 1.98A2.501 2.501 0 0113.5 12H10v-1h3.5a1.5 1.5 0 00.237-2.981L12.7 7.854l.216-1.028a4 4 0 10-7.843-1.587l-.185.96z"/>
+ <path fill-rule="evenodd" d="M5 8.854a.5.5 0 00.707 0L8 6.56l2.293 2.293A.5.5 0 1011 8.146L8.354 5.5a.5.5 0 00-.708 0L5 8.146a.5.5 0 000 .708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 6a.5.5 0 01.5.5v8a.5.5 0 01-1 0v-8A.5.5 0 018 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/cloud.svg b/src/assets/icons/cloud.svg
new file mode 100644
index 0000000..5373e3c
--- /dev/null
+++ b/src/assets/icons/cloud.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-cloud" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.887 7.2l-.964-.165A2.5 2.5 0 103.5 12h10a1.5 1.5 0 00.237-2.981L12.7 8.854l.216-1.028a4 4 0 10-7.843-1.587l-.185.96zm9.084.341a5 5 0 00-9.88-1.492A3.5 3.5 0 103.5 13h9.999a2.5 2.5 0 00.394-4.968c.033-.16.06-.324.077-.49z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/code-slash.svg b/src/assets/icons/code-slash.svg
new file mode 100644
index 0000000..e30e502
--- /dev/null
+++ b/src/assets/icons/code-slash.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-code-slash" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.854 4.146a.5.5 0 010 .708L1.707 8l3.147 3.146a.5.5 0 01-.708.708l-3.5-3.5a.5.5 0 010-.708l3.5-3.5a.5.5 0 01.708 0zm6.292 0a.5.5 0 000 .708L14.293 8l-3.147 3.146a.5.5 0 00.708.708l3.5-3.5a.5.5 0 000-.708l-3.5-3.5a.5.5 0 00-.708 0zm-.999-3.124a.5.5 0 01.33.625l-4 13a.5.5 0 01-.955-.294l4-13a.5.5 0 01.625-.33z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/code.svg b/src/assets/icons/code.svg
new file mode 100644
index 0000000..b96f7cb
--- /dev/null
+++ b/src/assets/icons/code.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-code" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.854 4.146a.5.5 0 010 .708L2.707 8l3.147 3.146a.5.5 0 01-.708.708l-3.5-3.5a.5.5 0 010-.708l3.5-3.5a.5.5 0 01.708 0zm4.292 0a.5.5 0 000 .708L13.293 8l-3.147 3.146a.5.5 0 00.708.708l3.5-3.5a.5.5 0 000-.708l-3.5-3.5a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/collection-fill.svg b/src/assets/icons/collection-fill.svg
new file mode 100644
index 0000000..a923727
--- /dev/null
+++ b/src/assets/icons/collection-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-collection-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <rect width="16" height="10" rx="1.5" transform="matrix(1 0 0 -1 0 14.5)"/>
+ <path fill-rule="evenodd" d="M2 3a.5.5 0 00.5.5h11a.5.5 0 000-1h-11A.5.5 0 002 3zm2-2a.5.5 0 00.5.5h7a.5.5 0 000-1h-7A.5.5 0 004 1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/collection-play-fill.svg b/src/assets/icons/collection-play-fill.svg
new file mode 100644
index 0000000..cc0faa2
--- /dev/null
+++ b/src/assets/icons/collection-play-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-collection-play-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 14.5A1.5 1.5 0 010 13V6a1.5 1.5 0 011.5-1.5h13A1.5 1.5 0 0116 6v7a1.5 1.5 0 01-1.5 1.5h-13zm5.265-7.924A.5.5 0 006 7v5a.5.5 0 00.765.424l4-2.5a.5.5 0 000-.848l-4-2.5zM2 3a.5.5 0 00.5.5h11a.5.5 0 000-1h-11A.5.5 0 002 3zm2-2a.5.5 0 00.5.5h7a.5.5 0 000-1h-7A.5.5 0 004 1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/collection-play.svg b/src/assets/icons/collection-play.svg
new file mode 100644
index 0000000..a936daf
--- /dev/null
+++ b/src/assets/icons/collection-play.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-collection-play" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 13.5h-13A.5.5 0 011 13V6a.5.5 0 01.5-.5h13a.5.5 0 01.5.5v7a.5.5 0 01-.5.5zm-13 1A1.5 1.5 0 010 13V6a1.5 1.5 0 011.5-1.5h13A1.5 1.5 0 0116 6v7a1.5 1.5 0 01-1.5 1.5h-13zM2 3a.5.5 0 00.5.5h11a.5.5 0 000-1h-11A.5.5 0 002 3zm2-2a.5.5 0 00.5.5h7a.5.5 0 000-1h-7A.5.5 0 004 1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6.258 6.563a.5.5 0 01.507.013l4 2.5a.5.5 0 010 .848l-4 2.5A.5.5 0 016 12V7a.5.5 0 01.258-.437z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/collection.svg b/src/assets/icons/collection.svg
new file mode 100644
index 0000000..0b6b6c3
--- /dev/null
+++ b/src/assets/icons/collection.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-collection" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.5 13.5h-13A.5.5 0 011 13V6a.5.5 0 01.5-.5h13a.5.5 0 01.5.5v7a.5.5 0 01-.5.5zm-13 1A1.5 1.5 0 010 13V6a1.5 1.5 0 011.5-1.5h13A1.5 1.5 0 0116 6v7a1.5 1.5 0 01-1.5 1.5h-13zM2 3a.5.5 0 00.5.5h11a.5.5 0 000-1h-11A.5.5 0 002 3zm2-2a.5.5 0 00.5.5h7a.5.5 0 000-1h-7A.5.5 0 004 1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/columns-gap.svg b/src/assets/icons/columns-gap.svg
new file mode 100644
index 0000000..af50540
--- /dev/null
+++ b/src/assets/icons/columns-gap.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-columns-gap" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6 1H1v3h5V1zM1 0a1 1 0 00-1 1v3a1 1 0 001 1h5a1 1 0 001-1V1a1 1 0 00-1-1H1zm14 12h-5v3h5v-3zm-5-1a1 1 0 00-1 1v3a1 1 0 001 1h5a1 1 0 001-1v-3a1 1 0 00-1-1h-5zM6 8H1v7h5V8zM1 7a1 1 0 00-1 1v7a1 1 0 001 1h5a1 1 0 001-1V8a1 1 0 00-1-1H1zm14-6h-5v7h5V1zm-5-1a1 1 0 00-1 1v7a1 1 0 001 1h5a1 1 0 001-1V1a1 1 0 00-1-1h-5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/columns.svg b/src/assets/icons/columns.svg
new file mode 100644
index 0000000..40235ad
--- /dev/null
+++ b/src/assets/icons/columns.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-columns" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M15 2H1v12h14V2zM1 1a1 1 0 00-1 1v12a1 1 0 001 1h14a1 1 0 001-1V2a1 1 0 00-1-1H1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.5 14V2h1v12h-1zm0-8H1V5h6.5v1zm7.5 5H8.5v-1H15v1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/command.svg b/src/assets/icons/command.svg
new file mode 100644
index 0000000..1061e4b
--- /dev/null
+++ b/src/assets/icons/command.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-command" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 3.5A1.5 1.5 0 003.5 5H5V3.5a1.5 1.5 0 10-3 0zM6 6V3.5A2.5 2.5 0 103.5 6H6zm8-2.5A1.5 1.5 0 0112.5 5H11V3.5a1.5 1.5 0 013 0zM10 6V3.5A2.5 2.5 0 1112.5 6H10zm-8 6.5A1.5 1.5 0 013.5 11H5v1.5a1.5 1.5 0 01-3 0zM6 10v2.5A2.5 2.5 0 113.5 10H6zm8 2.5a1.5 1.5 0 00-1.5-1.5H11v1.5a1.5 1.5 0 003 0zM10 10v2.5a2.5 2.5 0 102.5-2.5H10z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10 6H6v4h4V6zM5 5v6h6V5H5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/compass.svg b/src/assets/icons/compass.svg
new file mode 100644
index 0000000..6e793fb
--- /dev/null
+++ b/src/assets/icons/compass.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-compass" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15.016a6.5 6.5 0 100-13 6.5 6.5 0 000 13zm0 1a7.5 7.5 0 100-15 7.5 7.5 0 000 15z" clip-rule="evenodd"/>
+ <path d="M6 1a1 1 0 011-1h2a1 1 0 010 2H7a1 1 0 01-1-1zm.94 6.44l4.95-2.83-2.83 4.95-4.95 2.83 2.83-4.95z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/cone-striped.svg b/src/assets/icons/cone-striped.svg
new file mode 100644
index 0000000..2e1f4d9
--- /dev/null
+++ b/src/assets/icons/cone-striped.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-cone-striped" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.879 11.015a.5.5 0 01.242 0l6 1.5a.5.5 0 01.037.96l-6 2a.499.499 0 01-.316 0l-6-2a.5.5 0 01.037-.96l6-1.5z" clip-rule="evenodd"/>
+ <path d="M11.885 12.538l-.72-2.877C10.303 9.873 9.201 10 8 10s-2.303-.127-3.165-.339l-.72 2.877c-.073.292-.002.6.256.756C4.86 13.589 5.916 14 8 14s3.14-.411 3.63-.706c.257-.155.328-.464.255-.756zM9.97 4.88l.953 3.811C10.159 8.878 9.14 9 8 9c-1.14 0-2.159-.122-2.923-.309L6.03 4.88C6.635 4.957 7.3 5 8 5s1.365-.043 1.97-.12zm-.245-.978L8.97.88C8.718-.13 7.282-.13 7.03.88L6.275 3.9C6.8 3.965 7.382 4 8 4c.618 0 1.2-.036 1.725-.098z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/cone.svg b/src/assets/icons/cone.svg
new file mode 100644
index 0000000..bba9fe2
--- /dev/null
+++ b/src/assets/icons/cone.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-cone" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M7.03 1.88c.252-1.01 1.688-1.01 1.94 0L12 14H4L7.03 1.88z"/>
+ <path fill-rule="evenodd" d="M1.5 14a.5.5 0 01.5-.5h12a.5.5 0 010 1H2a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/controller.svg b/src/assets/icons/controller.svg
new file mode 100644
index 0000000..0dcd450
--- /dev/null
+++ b/src/assets/icons/controller.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-controller" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.119 2.693c.904.19 1.75.495 2.235.98.407.408.779 1.05 1.094 1.772.32.733.599 1.591.805 2.466.206.875.34 1.78.364 2.606.024.815-.059 1.602-.328 2.21a1.42 1.42 0 01-1.445.83c-.636-.067-1.115-.394-1.513-.773a11.307 11.307 0 01-.739-.809c-.126-.147-.25-.291-.368-.422-.728-.804-1.597-1.527-3.224-1.527-1.627 0-2.496.723-3.224 1.527-.119.131-.242.275-.368.422-.243.283-.494.576-.739.81-.398.378-.877.705-1.513.772a1.42 1.42 0 01-1.445-.83c-.27-.608-.352-1.395-.329-2.21.024-.826.16-1.73.365-2.606.206-.875.486-1.733.805-2.466.315-.722.687-1.364 1.094-1.772.486-.485 1.331-.79 2.235-.98.932-.196 2.03-.292 3.119-.292 1.089 0 2.187.096 3.119.292zm-6.032.979c-.877.185-1.469.443-1.733.708-.276.276-.587.783-.885 1.465a13.748 13.748 0 00-.748 2.295 12.351 12.351 0 00-.339 2.406c-.022.755.062 1.368.243 1.776a.42.42 0 00.426.24c.327-.034.61-.199.929-.502.212-.202.4-.423.615-.674.133-.156.276-.323.44-.505C4.861 9.97 5.978 9.026 8 9.026s3.139.943 3.965 1.855c.164.182.307.35.44.505.214.25.403.472.615.674.318.303.601.468.929.503a.42.42 0 00.426-.241c.18-.408.265-1.02.243-1.776a12.354 12.354 0 00-.339-2.406 13.753 13.753 0 00-.748-2.295c-.298-.682-.61-1.19-.885-1.465-.264-.265-.856-.523-1.733-.708-.85-.179-1.877-.27-2.913-.27-1.036 0-2.063.091-2.913.27z" clip-rule="evenodd"/>
+ <path d="M11.5 6.026a.5.5 0 11-1 0 .5.5 0 011 0zm-1 1a.5.5 0 11-1 0 .5.5 0 011 0zm2 0a.5.5 0 11-1 0 .5.5 0 011 0zm-1 1a.5.5 0 11-1 0 .5.5 0 011 0zm-7-2.5h1v3h-1v-3z"/>
+ <path d="M3.5 6.526h3v1h-3v-1zM3.051 3.26a.5.5 0 01.354-.613l1.932-.518a.5.5 0 01.258.966l-1.932.518a.5.5 0 01-.612-.354zm9.976 0a.5.5 0 00-.353-.613l-1.932-.518a.5.5 0 10-.259.966l1.932.518a.5.5 0 00.612-.354z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/credit-card.svg b/src/assets/icons/credit-card.svg
new file mode 100644
index 0000000..c61b1fa
--- /dev/null
+++ b/src/assets/icons/credit-card.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-credit-card" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 3H2a1 1 0 00-1 1v8a1 1 0 001 1h12a1 1 0 001-1V4a1 1 0 00-1-1zM2 2a2 2 0 00-2 2v8a2 2 0 002 2h12a2 2 0 002-2V4a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <rect width="3" height="3" x="2" y="9" rx="1"/>
+ <path d="M1 5h14v2H1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/crop.svg b/src/assets/icons/crop.svg
new file mode 100644
index 0000000..e477746
--- /dev/null
+++ b/src/assets/icons/crop.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-crop" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.5.5A.5.5 0 014 1v13h13a.5.5 0 010 1H3.5a.5.5 0 01-.5-.5V1a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M.5 3.5A.5.5 0 011 3h2.5a.5.5 0 010 1H1a.5.5 0 01-.5-.5zm5.5 0a.5.5 0 01.5-.5h8a.5.5 0 01.5.5v8a.5.5 0 01-1 0V4H6.5a.5.5 0 01-.5-.5zM14.5 14a.5.5 0 01.5.5V17a.5.5 0 01-1 0v-2.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/cursor-fill.svg b/src/assets/icons/cursor-fill.svg
new file mode 100644
index 0000000..25d58ba
--- /dev/null
+++ b/src/assets/icons/cursor-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-cursor-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.082 2.182a.5.5 0 01.103.557L8.528 15.467a.5.5 0 01-.917-.007L5.57 10.694.803 8.652a.5.5 0 01-.006-.916l12.728-5.657a.5.5 0 01.556.103z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/cursor-text.svg b/src/assets/icons/cursor-text.svg
new file mode 100644
index 0000000..584f0c8
--- /dev/null
+++ b/src/assets/icons/cursor-text.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-cursor-text" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5 2a.5.5 0 01.5-.5c.862 0 1.573.287 2.06.566.174.099.321.198.44.286.119-.088.266-.187.44-.286A4.165 4.165 0 0110.5 1.5a.5.5 0 010 1c-.638 0-1.177.213-1.564.434a3.49 3.49 0 00-.436.294V7.5H9a.5.5 0 010 1h-.5v4.272c.1.08.248.187.436.294.387.221.926.434 1.564.434a.5.5 0 010 1 4.165 4.165 0 01-2.06-.566A4.561 4.561 0 018 13.65a4.561 4.561 0 01-.44.285 4.165 4.165 0 01-2.06.566.5.5 0 010-1c.638 0 1.177-.213 1.564-.434.188-.107.335-.214.436-.294V8.5H7a.5.5 0 010-1h.5V3.228a3.49 3.49 0 00-.436-.294A3.166 3.166 0 005.5 2.5.5.5 0 015 2zm3.352 1.355zm-.704 9.29z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/cursor.svg b/src/assets/icons/cursor.svg
new file mode 100644
index 0000000..e5157bb
--- /dev/null
+++ b/src/assets/icons/cursor.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-cursor" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.082 2.182a.5.5 0 01.103.557L8.528 15.467a.5.5 0 01-.917-.007L5.57 10.694.803 8.652a.5.5 0 01-.006-.916l12.728-5.657a.5.5 0 01.556.103zM2.25 8.184l3.897 1.67a.5.5 0 01.262.263l1.67 3.897L12.743 3.52 2.25 8.184z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/dash-circle-fill.svg b/src/assets/icons/dash-circle-fill.svg
new file mode 100644
index 0000000..b1fc6a1
--- /dev/null
+++ b/src/assets/icons/dash-circle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-dash-circle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8A8 8 0 110 8a8 8 0 0116 0zM4 7.5a.5.5 0 000 1h8a.5.5 0 000-1H4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/dash-circle.svg b/src/assets/icons/dash-circle.svg
new file mode 100644
index 0000000..849622b
--- /dev/null
+++ b/src/assets/icons/dash-circle.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-dash-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M3.5 8a.5.5 0 01.5-.5h8a.5.5 0 010 1H4a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/dash-square-fill.svg b/src/assets/icons/dash-square-fill.svg
new file mode 100644
index 0000000..212baff
--- /dev/null
+++ b/src/assets/icons/dash-square-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-dash-square-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2zm2 7.5a.5.5 0 000 1h8a.5.5 0 000-1H4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/dash-square.svg b/src/assets/icons/dash-square.svg
new file mode 100644
index 0000000..b1a6ac5
--- /dev/null
+++ b/src/assets/icons/dash-square.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-dash-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M3.5 8a.5.5 0 01.5-.5h8a.5.5 0 010 1H4a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/dash.svg b/src/assets/icons/dash.svg
new file mode 100644
index 0000000..a7da2d9
--- /dev/null
+++ b/src/assets/icons/dash.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-dash" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.5 8a.5.5 0 01.5-.5h8a.5.5 0 010 1H4a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/diamond-fill.svg b/src/assets/icons/diamond-fill.svg
new file mode 100644
index 0000000..8867838
--- /dev/null
+++ b/src/assets/icons/diamond-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-diamond-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.95.435c.58-.58 1.52-.58 2.1 0l6.515 6.516c.58.58.58 1.519 0 2.098L9.05 15.565c-.58.58-1.519.58-2.098 0L.435 9.05a1.482 1.482 0 010-2.098L6.95.435z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/diamond-half.svg b/src/assets/icons/diamond-half.svg
new file mode 100644
index 0000000..54eab14
--- /dev/null
+++ b/src/assets/icons/diamond-half.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-diamond-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.95.435c.58-.58 1.52-.58 2.1 0l6.515 6.516c.58.58.58 1.519 0 2.098L9.05 15.565c-.58.58-1.519.58-2.098 0L.435 9.05a1.482 1.482 0 010-2.098L6.95.435zM8 .989a.493.493 0 00-.35.145L1.134 7.65a.495.495 0 000 .7l6.516 6.516a.493.493 0 00.35.145V.989z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/diamond.svg b/src/assets/icons/diamond.svg
new file mode 100644
index 0000000..aac7bdc
--- /dev/null
+++ b/src/assets/icons/diamond.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-diamond" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.95.435c.58-.58 1.52-.58 2.1 0l6.515 6.516c.58.58.58 1.519 0 2.098L9.05 15.565c-.58.58-1.519.58-2.098 0L.435 9.05a1.482 1.482 0 010-2.098L6.95.435zm1.4.7a.495.495 0 00-.7 0L1.134 7.65a.495.495 0 000 .7l6.516 6.516a.495.495 0 00.7 0l6.516-6.516a.495.495 0 000-.7L8.35 1.134z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/display-fill.svg b/src/assets/icons/display-fill.svg
new file mode 100644
index 0000000..ac42259
--- /dev/null
+++ b/src/assets/icons/display-fill.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-display-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5.75 13.5c.167-.333.25-.833.25-1.5h4c0 .667.083 1.167.25 1.5H11a.5.5 0 010 1H5a.5.5 0 010-1h.75z"/>
+ <path fill-rule="evenodd" d="M13.991 3H2c-.325 0-.502.078-.602.145a.758.758 0 00-.254.302A1.46 1.46 0 001 4.01V10c0 .325.078.502.145.602.07.105.17.188.302.254a1.464 1.464 0 00.538.143L2.01 11H14c.325 0 .502-.078.602-.145a.758.758 0 00.254-.302 1.464 1.464 0 00.143-.538L15 9.99V4c0-.325-.078-.502-.145-.602a.757.757 0 00-.302-.254A1.46 1.46 0 0013.99 3zM14 2H2C0 2 0 4 0 4v6c0 2 2 2 2 2h12c2 0 2-2 2-2V4c0-2-2-2-2-2z" clip-rule="evenodd"/>
+ <path d="M2 4h12v6H2z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/display.svg b/src/assets/icons/display.svg
new file mode 100644
index 0000000..24cb922
--- /dev/null
+++ b/src/assets/icons/display.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-display" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5.75 13.5c.167-.333.25-.833.25-1.5h4c0 .667.083 1.167.25 1.5H11a.5.5 0 010 1H5a.5.5 0 010-1h.75z"/>
+ <path fill-rule="evenodd" d="M13.991 3H2c-.325 0-.502.078-.602.145a.758.758 0 00-.254.302A1.46 1.46 0 001 4.01V10c0 .325.078.502.145.602.07.105.17.188.302.254a1.464 1.464 0 00.538.143L2.01 11H14c.325 0 .502-.078.602-.145a.758.758 0 00.254-.302 1.464 1.464 0 00.143-.538L15 9.99V4c0-.325-.078-.502-.145-.602a.757.757 0 00-.302-.254A1.46 1.46 0 0013.99 3zM14 2H2C0 2 0 4 0 4v6c0 2 2 2 2 2h12c2 0 2-2 2-2V4c0-2-2-2-2-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/dot.svg b/src/assets/icons/dot.svg
new file mode 100644
index 0000000..0aa7441
--- /dev/null
+++ b/src/assets/icons/dot.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-dot" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 9.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/download.svg b/src/assets/icons/download.svg
new file mode 100644
index 0000000..5a9710c
--- /dev/null
+++ b/src/assets/icons/download.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-download" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.5 8a.5.5 0 01.5.5V12a1 1 0 001 1h12a1 1 0 001-1V8.5a.5.5 0 011 0V12a2 2 0 01-2 2H2a2 2 0 01-2-2V8.5A.5.5 0 01.5 8z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 7.5a.5.5 0 01.707 0L8 9.793 10.293 7.5a.5.5 0 11.707.707l-2.646 2.647a.5.5 0 01-.708 0L5 8.207A.5.5 0 015 7.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 1a.5.5 0 01.5.5v8a.5.5 0 01-1 0v-8A.5.5 0 018 1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/droplet-fill.svg b/src/assets/icons/droplet-fill.svg
new file mode 100644
index 0000000..705a34f
--- /dev/null
+++ b/src/assets/icons/droplet-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-droplet-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 16a6 6 0 006-6c0-1.655-1.122-2.904-2.432-4.362C10.254 4.176 8.75 2.503 8 0c0 0-6 5.686-6 10a6 6 0 006 6zM6.646 4.646c-.376.377-1.272 1.489-2.093 3.13l.894.448c.78-1.559 1.616-2.58 1.907-2.87l-.708-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/droplet-half.svg b/src/assets/icons/droplet-half.svg
new file mode 100644
index 0000000..4f962d9
--- /dev/null
+++ b/src/assets/icons/droplet-half.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-droplet-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.21.8C7.69.295 8 0 8 0c.109.363.234.708.371 1.038.812 1.946 2.073 3.35 3.197 4.6C12.878 7.096 14 8.345 14 10a6 6 0 01-12 0C2 6.668 5.58 2.517 7.21.8zm.413 1.021A31.25 31.25 0 005.794 3.99c-.726.95-1.436 2.008-1.96 3.07C3.304 8.133 3 9.138 3 10a5 5 0 0010 0c0-1.201-.796-2.157-2.181-3.7l-.03-.032C9.75 5.11 8.5 3.72 7.623 1.82z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.553 7.776c.82-1.641 1.717-2.753 2.093-3.13l.708.708c-.29.29-1.128 1.311-1.907 2.87l-.894-.448z" clip-rule="evenodd"/>
+ <path d="M14 10a6 6 0 01-12 0s2.5 2.5 6.5.5S14 10 14 10z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/droplet.svg b/src/assets/icons/droplet.svg
new file mode 100644
index 0000000..ba7cc2b
--- /dev/null
+++ b/src/assets/icons/droplet.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-droplet" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.21.8C7.69.295 8 0 8 0c.109.363.234.708.371 1.038.812 1.946 2.073 3.35 3.197 4.6C12.878 7.096 14 8.345 14 10a6 6 0 01-12 0C2 6.668 5.58 2.517 7.21.8zm.413 1.021A31.25 31.25 0 005.794 3.99c-.726.95-1.436 2.008-1.96 3.07C3.304 8.133 3 9.138 3 10a5 5 0 0010 0c0-1.201-.796-2.157-2.181-3.7l-.03-.032C9.75 5.11 8.5 3.72 7.623 1.82z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.553 7.776c.82-1.641 1.717-2.753 2.093-3.13l.708.708c-.29.29-1.128 1.311-1.907 2.87l-.894-.448z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/egg-fill.svg b/src/assets/icons/egg-fill.svg
new file mode 100644
index 0000000..889e7c4
--- /dev/null
+++ b/src/assets/icons/egg-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-egg-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M14 10a6 6 0 01-12 0C2 5.686 5 0 8 0s6 5.686 6 10z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/egg-fried.svg b/src/assets/icons/egg-fried.svg
new file mode 100644
index 0000000..dce48c3
--- /dev/null
+++ b/src/assets/icons/egg-fried.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-egg-fried" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13.665 6.113a1 1 0 01-.667-.977L13 5a4 4 0 00-6.483-3.136 1 1 0 01-.8.2 4 4 0 00-3.693 6.61 1 1 0 01.2 1 4 4 0 006.67 4.087 1 1 0 011.262-.152 2.5 2.5 0 003.715-2.905 1 1 0 01.341-1.113 2.001 2.001 0 00-.547-3.478zM14 5c0 .057 0 .113-.003.17a3.001 3.001 0 01.822 5.216 3.5 3.5 0 01-5.201 4.065 5 5 0 01-8.336-5.109A5 5 0 015.896 1.08 5 5 0 0114 5z" clip-rule="evenodd"/>
+ <circle cx="8" cy="8" r="3"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/egg.svg b/src/assets/icons/egg.svg
new file mode 100644
index 0000000..25a6040
--- /dev/null
+++ b/src/assets/icons/egg.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-egg" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15a5 5 0 005-5c0-1.956-.69-4.286-1.742-6.12-.524-.913-1.112-1.658-1.704-2.164C8.956 1.206 8.428 1 8 1c-.428 0-.956.206-1.554.716-.592.506-1.18 1.251-1.704 2.164C3.69 5.714 3 8.044 3 10a5 5 0 005 5zm0 1a6 6 0 006-6c0-4.314-3-10-6-10S2 5.686 2 10a6 6 0 006 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/eject-fill.svg b/src/assets/icons/eject-fill.svg
new file mode 100644
index 0000000..fc58e80
--- /dev/null
+++ b/src/assets/icons/eject-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-eject-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.27 1.047a1 1 0 011.46 0l6.345 6.77c.6.638.146 1.683-.73 1.683H1.656C.78 9.5.326 8.455.926 7.816L7.27 1.047zM.5 11.5a1 1 0 011-1h13a1 1 0 011 1v1a1 1 0 01-1 1h-13a1 1 0 01-1-1v-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/eject.svg b/src/assets/icons/eject.svg
new file mode 100644
index 0000000..1522584
--- /dev/null
+++ b/src/assets/icons/eject.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-eject" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.27 1.047a1 1 0 011.46 0l6.345 6.77c.6.638.146 1.683-.73 1.683H1.656C.78 9.5.326 8.455.926 7.816L7.27 1.047zM14.346 8.5L8 1.731 1.654 8.5h12.692zM.5 11.5a1 1 0 011-1h13a1 1 0 011 1v1a1 1 0 01-1 1h-13a1 1 0 01-1-1v-1zm14 0h-13v1h13v-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/envelope-fill.svg b/src/assets/icons/envelope-fill.svg
new file mode 100644
index 0000000..4e7f7af
--- /dev/null
+++ b/src/assets/icons/envelope-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-envelope-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M.05 3.555L8 8.414l7.95-4.859A2 2 0 0014 2H2A2 2 0 00.05 3.555zM16 4.697l-5.875 3.59L16 11.743V4.697zm-.168 8.108L9.157 8.879 8 9.586l-1.157-.707-6.675 3.926A2 2 0 002 14h12a2 2 0 001.832-1.195zM0 11.743l5.875-3.456L0 4.697v7.046z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/envelope-open-fill.svg b/src/assets/icons/envelope-open-fill.svg
new file mode 100644
index 0000000..a014b1e
--- /dev/null
+++ b/src/assets/icons/envelope-open-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-envelope-open-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.941.435a2 2 0 00-1.882 0l-6 3.2A2 2 0 000 5.4v.125l8 4.889 8-4.889V5.4a2 2 0 00-1.059-1.765l-6-3.2zM16 6.697l-5.875 3.59L16 13.743V6.697zm-.168 8.108L9.246 10.93l-.089-.052-.896.548-.261.159-.26-.16-.897-.547-.09.052-6.585 3.874A2 2 0 002 16h12a2 2 0 001.832-1.195zM0 13.743l5.875-3.456L0 6.697v7.046z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/envelope-open.svg b/src/assets/icons/envelope-open.svg
new file mode 100644
index 0000000..f352948
--- /dev/null
+++ b/src/assets/icons/envelope-open.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-envelope-open" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.243 6.929l.514-.858L8 10.417l7.243-4.346.514.858L8 11.583.243 6.93z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.184 10.68L.752 14.432l-.504-.864L6.68 9.816l.504.864zm1.632 0l6.432 3.752.504-.864L9.32 9.816l-.504.864z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8.47 1.318a1 1 0 00-.94 0l-6 3.2A1 1 0 001 5.4V14a1 1 0 001 1h12a1 1 0 001-1V5.4a1 1 0 00-.53-.882l-6-3.2zM7.06.435a2 2 0 011.882 0l6 3.2A2 2 0 0116 5.4V14a2 2 0 01-2 2H2a2 2 0 01-2-2V5.4a2 2 0 011.059-1.765l6-3.2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/envelope.svg b/src/assets/icons/envelope.svg
new file mode 100644
index 0000000..d8902d2
--- /dev/null
+++ b/src/assets/icons/envelope.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-envelope" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 3H2a1 1 0 00-1 1v8a1 1 0 001 1h12a1 1 0 001-1V4a1 1 0 00-1-1zM2 2a2 2 0 00-2 2v8a2 2 0 002 2h12a2 2 0 002-2V4a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M.071 4.243a.5.5 0 01.686-.172L8 8.417l7.243-4.346a.5.5 0 01.514.858L8 9.583.243 4.93a.5.5 0 01-.172-.686z" clip-rule="evenodd"/>
+ <path d="M6.752 8.932l.432-.252-.504-.864-.432.252.504.864zm-6 3.5l6-3.5-.504-.864-6 3.5.504.864zm8.496-3.5l-.432-.252.504-.864.432.252-.504.864zm6 3.5l-6-3.5.504-.864 6 3.5-.504.864z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-circle-fill.svg b/src/assets/icons/exclamation-circle-fill.svg
new file mode 100644
index 0000000..273b02e
--- /dev/null
+++ b/src/assets/icons/exclamation-circle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-exclamation-circle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8A8 8 0 110 8a8 8 0 0116 0zM8 4a.905.905 0 00-.9.995l.35 3.507a.552.552 0 001.1 0l.35-3.507A.905.905 0 008 4zm.002 6a1 1 0 100 2 1 1 0 000-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-circle.svg b/src/assets/icons/exclamation-circle.svg
new file mode 100644
index 0000000..9f1993e
--- /dev/null
+++ b/src/assets/icons/exclamation-circle.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-exclamation-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+ <path d="M7.002 11a1 1 0 112 0 1 1 0 01-2 0zM7.1 4.995a.905.905 0 111.8 0l-.35 3.507a.552.552 0 01-1.1 0L7.1 4.995z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-diamond-fill.svg b/src/assets/icons/exclamation-diamond-fill.svg
new file mode 100644
index 0000000..e97027e
--- /dev/null
+++ b/src/assets/icons/exclamation-diamond-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-exclamation-diamond-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.05.435c-.58-.58-1.52-.58-2.1 0L.436 6.95c-.58.58-.58 1.519 0 2.098l6.516 6.516c.58.58 1.519.58 2.098 0l6.516-6.516c.58-.58.58-1.519 0-2.098L9.05.435zM8 4a.905.905 0 00-.9.995l.35 3.507a.552.552 0 001.1 0l.35-3.507A.905.905 0 008 4zm.002 6a1 1 0 100 2 1 1 0 000-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-diamond.svg b/src/assets/icons/exclamation-diamond.svg
new file mode 100644
index 0000000..96e6430
--- /dev/null
+++ b/src/assets/icons/exclamation-diamond.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-exclamation-diamond" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.95.435c.58-.58 1.52-.58 2.1 0l6.515 6.516c.58.58.58 1.519 0 2.098L9.05 15.565c-.58.58-1.519.58-2.098 0L.435 9.05a1.482 1.482 0 010-2.098L6.95.435zm1.4.7a.495.495 0 00-.7 0L1.134 7.65a.495.495 0 000 .7l6.516 6.516a.495.495 0 00.7 0l6.516-6.516a.495.495 0 000-.7L8.35 1.134z" clip-rule="evenodd"/>
+ <path d="M7.002 11a1 1 0 112 0 1 1 0 01-2 0zM7.1 4.995a.905.905 0 111.8 0l-.35 3.507a.552.552 0 01-1.1 0L7.1 4.995z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-octagon-fill.svg b/src/assets/icons/exclamation-octagon-fill.svg
new file mode 100644
index 0000000..76ae5a6
--- /dev/null
+++ b/src/assets/icons/exclamation-octagon-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-exclamation-octagon-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.46.146A.5.5 0 0011.107 0H4.893a.5.5 0 00-.353.146L.146 4.54A.5.5 0 000 4.893v6.214a.5.5 0 00.146.353l4.394 4.394a.5.5 0 00.353.146h6.214a.5.5 0 00.353-.146l4.394-4.394a.5.5 0 00.146-.353V4.893a.5.5 0 00-.146-.353L11.46.146zM8 4a.905.905 0 00-.9.995l.35 3.507a.552.552 0 001.1 0l.35-3.507A.905.905 0 008 4zm.002 6a1 1 0 100 2 1 1 0 000-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-octagon.svg b/src/assets/icons/exclamation-octagon.svg
new file mode 100644
index 0000000..527d792
--- /dev/null
+++ b/src/assets/icons/exclamation-octagon.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-exclamation-octagon" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.54.146A.5.5 0 014.893 0h6.214a.5.5 0 01.353.146l4.394 4.394a.5.5 0 01.146.353v6.214a.5.5 0 01-.146.353l-4.394 4.394a.5.5 0 01-.353.146H4.893a.5.5 0 01-.353-.146L.146 11.46A.5.5 0 010 11.107V4.893a.5.5 0 01.146-.353L4.54.146zM5.1 1L1 5.1v5.8L5.1 15h5.8l4.1-4.1V5.1L10.9 1H5.1z" clip-rule="evenodd"/>
+ <path d="M7.002 11a1 1 0 112 0 1 1 0 01-2 0zM7.1 4.995a.905.905 0 111.8 0l-.35 3.507a.552.552 0 01-1.1 0L7.1 4.995z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-square-fill.svg b/src/assets/icons/exclamation-square-fill.svg
new file mode 100644
index 0000000..98f3b73
--- /dev/null
+++ b/src/assets/icons/exclamation-square-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-exclamation-square-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2zm6 4a.905.905 0 00-.9.995l.35 3.507a.552.552 0 001.1 0l.35-3.507A.905.905 0 008 4zm.002 6a1 1 0 100 2 1 1 0 000-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-square.svg b/src/assets/icons/exclamation-square.svg
new file mode 100644
index 0000000..bf50dc7
--- /dev/null
+++ b/src/assets/icons/exclamation-square.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-exclamation-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path d="M7.002 11a1 1 0 112 0 1 1 0 01-2 0zM7.1 4.995a.905.905 0 111.8 0l-.35 3.507a.552.552 0 01-1.1 0L7.1 4.995z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-triangle-fill.svg b/src/assets/icons/exclamation-triangle-fill.svg
new file mode 100644
index 0000000..4c57f81
--- /dev/null
+++ b/src/assets/icons/exclamation-triangle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-exclamation-triangle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.982 1.566a1.13 1.13 0 00-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5a.905.905 0 00-.9.995l.35 3.507a.552.552 0 001.1 0l.35-3.507A.905.905 0 008 5zm.002 6a1 1 0 100 2 1 1 0 000-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation-triangle.svg b/src/assets/icons/exclamation-triangle.svg
new file mode 100644
index 0000000..5128e3c
--- /dev/null
+++ b/src/assets/icons/exclamation-triangle.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-exclamation-triangle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.938 2.016a.146.146 0 00-.054.057L1.027 13.74a.176.176 0 00-.002.183c.016.03.037.05.054.06.015.01.034.017.066.017h13.713a.12.12 0 00.066-.017.163.163 0 00.055-.06.176.176 0 00-.003-.183L8.12 2.073a.146.146 0 00-.054-.057A.13.13 0 008.002 2a.13.13 0 00-.064.016zm1.044-.45a1.13 1.13 0 00-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566z" clip-rule="evenodd"/>
+ <path d="M7.002 12a1 1 0 112 0 1 1 0 01-2 0zM7.1 5.995a.905.905 0 111.8 0l-.35 3.507a.552.552 0 01-1.1 0L7.1 5.995z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclamation.svg b/src/assets/icons/exclamation.svg
new file mode 100644
index 0000000..769a427
--- /dev/null
+++ b/src/assets/icons/exclamation.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-exclamation" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M7.002 11a1 1 0 112 0 1 1 0 01-2 0zM7.1 4.995a.905.905 0 111.8 0l-.35 3.507a.552.552 0 01-1.1 0L7.1 4.995z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/exclude.svg b/src/assets/icons/exclude.svg
new file mode 100644
index 0000000..977fbb9
--- /dev/null
+++ b/src/assets/icons/exclude.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-exclude" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 0A1.5 1.5 0 000 1.5v9A1.5 1.5 0 001.5 12H4v2.5A1.5 1.5 0 005.5 16h9a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 4H12V1.5A1.5 1.5 0 0010.5 0h-9zM12 4H5.5A1.5 1.5 0 004 5.5V12h6.5a1.5 1.5 0 001.5-1.5V4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/eye-fill.svg b/src/assets/icons/eye-fill.svg
new file mode 100644
index 0000000..db5a3bb
--- /dev/null
+++ b/src/assets/icons/eye-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-eye-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M10.5 8a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z"/>
+ <path fill-rule="evenodd" d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 100-7 3.5 3.5 0 000 7z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/eye-slash-fill.svg b/src/assets/icons/eye-slash-fill.svg
new file mode 100644
index 0000000..f3d9343
--- /dev/null
+++ b/src/assets/icons/eye-slash-fill.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-eye-slash-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M10.79 12.912l-1.614-1.615a3.5 3.5 0 01-4.474-4.474l-2.06-2.06C.938 6.278 0 8 0 8s3 5.5 8 5.5a7.029 7.029 0 002.79-.588zM5.21 3.088A7.028 7.028 0 018 2.5c5 0 8 5.5 8 5.5s-.939 1.721-2.641 3.238l-2.062-2.062a3.5 3.5 0 00-4.474-4.474L5.21 3.089z"/>
+ <path d="M5.525 7.646a2.5 2.5 0 002.829 2.829l-2.83-2.829zm4.95.708l-2.829-2.83a2.5 2.5 0 012.829 2.829z"/>
+ <path fill-rule="evenodd" d="M13.646 14.354l-12-12 .708-.708 12 12-.708.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/eye-slash.svg b/src/assets/icons/eye-slash.svg
new file mode 100644
index 0000000..ec21559
--- /dev/null
+++ b/src/assets/icons/eye-slash.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-eye-slash" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 00-2.79.588l.77.771A5.944 5.944 0 018 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0114.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z"/>
+ <path d="M11.297 9.176a3.5 3.5 0 00-4.474-4.474l.823.823a2.5 2.5 0 012.829 2.829l.822.822zm-2.943 1.299l.822.822a3.5 3.5 0 01-4.474-4.474l.823.823a2.5 2.5 0 002.829 2.829z"/>
+ <path d="M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 001.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 018 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709z"/>
+ <path fill-rule="evenodd" d="M13.646 14.354l-12-12 .708-.708 12 12-.708.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/eye.svg b/src/assets/icons/eye.svg
new file mode 100644
index 0000000..b05e64d
--- /dev/null
+++ b/src/assets/icons/eye.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-eye" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.134 13.134 0 001.66 2.043C4.12 11.332 5.88 12.5 8 12.5c2.12 0 3.879-1.168 5.168-2.457A13.134 13.134 0 0014.828 8a13.133 13.133 0 00-1.66-2.043C11.879 4.668 10.119 3.5 8 3.5c-2.12 0-3.879 1.168-5.168 2.457A13.133 13.133 0 001.172 8z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 5.5a2.5 2.5 0 100 5 2.5 2.5 0 000-5zM4.5 8a3.5 3.5 0 117 0 3.5 3.5 0 01-7 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-arrow-down.svg b/src/assets/icons/file-arrow-down.svg
new file mode 100644
index 0000000..3443b53
--- /dev/null
+++ b/src/assets/icons/file-arrow-down.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-arrow-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.646 8.146a.5.5 0 01.708 0L8 10.793l2.646-2.647a.5.5 0 01.708.708l-3 3a.5.5 0 01-.708 0l-3-3a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 4a.5.5 0 01.5.5v6a.5.5 0 01-1 0v-6A.5.5 0 018 4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-arrow-up.svg b/src/assets/icons/file-arrow-up.svg
new file mode 100644
index 0000000..2480730
--- /dev/null
+++ b/src/assets/icons/file-arrow-up.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-arrow-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.646 7.854a.5.5 0 00.708 0L8 5.207l2.646 2.647a.5.5 0 00.708-.708l-3-3a.5.5 0 00-.708 0l-3 3a.5.5 0 000 .708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 12a.5.5 0 00.5-.5v-6a.5.5 0 00-1 0v6a.5.5 0 00.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-break.svg b/src/assets/icons/file-break.svg
new file mode 100644
index 0000000..62c6668
--- /dev/null
+++ b/src/assets/icons/file-break.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-break" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 10.5a.5.5 0 01.5-.5h15a.5.5 0 010 1H.5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path d="M12 1H4a2 2 0 00-2 2v6h1V3a1 1 0 011-1h8a1 1 0 011 1v6h1V3a2 2 0 00-2-2zm2 11h-1v1a1 1 0 01-1 1H4a1 1 0 01-1-1v-1H2v1a2 2 0 002 2h8a2 2 0 002-2v-1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-check.svg b/src/assets/icons/file-check.svg
new file mode 100644
index 0000000..4cbab14
--- /dev/null
+++ b/src/assets/icons/file-check.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-check" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9 1H4a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V8h-1v5a1 1 0 01-1 1H4a1 1 0 01-1-1V3a1 1 0 011-1h5V1z"/>
+ <path fill-rule="evenodd" d="M15.854 2.146a.5.5 0 010 .708l-3 3a.5.5 0 01-.708 0l-1.5-1.5a.5.5 0 01.708-.708L12.5 4.793l2.646-2.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-code.svg b/src/assets/icons/file-code.svg
new file mode 100644
index 0000000..870f0f9
--- /dev/null
+++ b/src/assets/icons/file-code.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-code" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8.646 5.646a.5.5 0 01.708 0l2 2a.5.5 0 010 .708l-2 2a.5.5 0 01-.708-.708L10.293 8 8.646 6.354a.5.5 0 010-.708zm-1.292 0a.5.5 0 00-.708 0l-2 2a.5.5 0 000 .708l2 2a.5.5 0 00.708-.708L5.707 8l1.647-1.646a.5.5 0 000-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-diff.svg b/src/assets/icons/file-diff.svg
new file mode 100644
index 0000000..60ad916
--- /dev/null
+++ b/src/assets/icons/file-diff.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-diff" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.5 10.5A.5.5 0 016 10h4a.5.5 0 010 1H6a.5.5 0 01-.5-.5zM8 4a.5.5 0 01.5.5v4a.5.5 0 01-1 0v-4A.5.5 0 018 4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.5 6.5A.5.5 0 016 6h4a.5.5 0 010 1H6a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-arrow-down.svg b/src/assets/icons/file-earmark-arrow-down.svg
new file mode 100644
index 0000000..1874ab0
--- /dev/null
+++ b/src/assets/icons/file-earmark-arrow-down.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-file-earmark-arrow-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 1h5v1H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6h1v7a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2z"/>
+ <path d="M9 4.5V1l5 5h-3.5A1.5 1.5 0 019 4.5z"/>
+ <path fill-rule="evenodd" d="M5.646 9.146a.5.5 0 01.708 0L8 10.793l1.646-1.647a.5.5 0 01.708.708l-2 2a.5.5 0 01-.708 0l-2-2a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 6a.5.5 0 01.5.5v4a.5.5 0 01-1 0v-4A.5.5 0 018 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-arrow-up.svg b/src/assets/icons/file-earmark-arrow-up.svg
new file mode 100644
index 0000000..309acdd
--- /dev/null
+++ b/src/assets/icons/file-earmark-arrow-up.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-file-earmark-arrow-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 1h5v1H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6h1v7a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2z"/>
+ <path d="M9 4.5V1l5 5h-3.5A1.5 1.5 0 019 4.5z"/>
+ <path fill-rule="evenodd" d="M5.646 8.854a.5.5 0 00.708 0L8 7.207l1.646 1.647a.5.5 0 00.708-.708l-2-2a.5.5 0 00-.708 0l-2 2a.5.5 0 000 .708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 12a.5.5 0 00.5-.5v-4a.5.5 0 00-1 0v4a.5.5 0 00.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-break.svg b/src/assets/icons/file-earmark-break.svg
new file mode 100644
index 0000000..cae6dfe
--- /dev/null
+++ b/src/assets/icons/file-earmark-break.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-file-earmark-break" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9 1H4a2 2 0 00-2 2v6h1V3a1 1 0 011-1h5v2.5A1.5 1.5 0 0010.5 6H13v3h1V6L9 1zm5 11h-1v1a1 1 0 01-1 1H4a1 1 0 01-1-1v-1H2v1a2 2 0 002 2h8a2 2 0 002-2v-1zM0 10.5a.5.5 0 01.5-.5h15a.5.5 0 010 1H.5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-check.svg b/src/assets/icons/file-earmark-check.svg
new file mode 100644
index 0000000..dd12f16
--- /dev/null
+++ b/src/assets/icons/file-earmark-check.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-earmark-check" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9 1H4a2 2 0 00-2 2v10a2 2 0 002 2h5v-1H4a1 1 0 01-1-1V3a1 1 0 011-1h5v2.5A1.5 1.5 0 0010.5 6H13v2h1V6L9 1z"/>
+ <path fill-rule="evenodd" d="M15.854 10.146a.5.5 0 010 .708l-3 3a.5.5 0 01-.708 0l-1.5-1.5a.5.5 0 01.708-.708l1.146 1.147 2.646-2.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-code.svg b/src/assets/icons/file-earmark-code.svg
new file mode 100644
index 0000000..e61faa4
--- /dev/null
+++ b/src/assets/icons/file-earmark-code.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-earmark-code" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 1h5v1H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6h1v7a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2z"/>
+ <path d="M9 4.5V1l5 5h-3.5A1.5 1.5 0 019 4.5z"/>
+ <path fill-rule="evenodd" d="M8.646 6.646a.5.5 0 01.708 0l2 2a.5.5 0 010 .708l-2 2a.5.5 0 01-.708-.708L10.293 9 8.646 7.354a.5.5 0 010-.708zm-1.292 0a.5.5 0 00-.708 0l-2 2a.5.5 0 000 .708l2 2a.5.5 0 00.708-.708L5.707 9l1.647-1.646a.5.5 0 000-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-diff.svg b/src/assets/icons/file-earmark-diff.svg
new file mode 100644
index 0000000..dcb2071
--- /dev/null
+++ b/src/assets/icons/file-earmark-diff.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-file-earmark-diff" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 1h5v1H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6h1v7a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2z"/>
+ <path d="M9 4.5V1l5 5h-3.5A1.5 1.5 0 019 4.5z"/>
+ <path fill-rule="evenodd" d="M5.5 11.5A.5.5 0 016 11h4a.5.5 0 010 1H6a.5.5 0 01-.5-.5zM8 5a.5.5 0 01.5.5v4a.5.5 0 01-1 0v-4A.5.5 0 018 5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.5 7.5A.5.5 0 016 7h4a.5.5 0 010 1H6a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-minus.svg b/src/assets/icons/file-earmark-minus.svg
new file mode 100644
index 0000000..ed031e4
--- /dev/null
+++ b/src/assets/icons/file-earmark-minus.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-earmark-minus" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9 1H4a2 2 0 00-2 2v10a2 2 0 002 2h5v-1H4a1 1 0 01-1-1V3a1 1 0 011-1h5v2.5A1.5 1.5 0 0010.5 6H13v2h1V6L9 1z"/>
+ <path fill-rule="evenodd" d="M11 11.5a.5.5 0 01.5-.5h4a.5.5 0 010 1h-4a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-plus.svg b/src/assets/icons/file-earmark-plus.svg
new file mode 100644
index 0000000..f87bd32
--- /dev/null
+++ b/src/assets/icons/file-earmark-plus.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-earmark-plus" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9 1H4a2 2 0 00-2 2v10a2 2 0 002 2h5v-1H4a1 1 0 01-1-1V3a1 1 0 011-1h5v2.5A1.5 1.5 0 0010.5 6H13v2h1V6L9 1z"/>
+ <path fill-rule="evenodd" d="M13.5 10a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 010-1H13v-1.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13 12.5a.5.5 0 01.5-.5h2a.5.5 0 010 1H14v1.5a.5.5 0 01-1 0v-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-ruled.svg b/src/assets/icons/file-earmark-ruled.svg
new file mode 100644
index 0000000..dcecf94
--- /dev/null
+++ b/src/assets/icons/file-earmark-ruled.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-file-earmark-ruled" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13 9H3V8h10v1zm0 3H3v-1h10v1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 14V9h1v5H5z" clip-rule="evenodd"/>
+ <path d="M4 1h5v1H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6h1v7a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2z"/>
+ <path d="M9 4.5V1l5 5h-3.5A1.5 1.5 0 019 4.5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-spreadsheet.svg b/src/assets/icons/file-earmark-spreadsheet.svg
new file mode 100644
index 0000000..d5a4c9c
--- /dev/null
+++ b/src/assets/icons/file-earmark-spreadsheet.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-file-earmark-spreadsheet" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13 9H3V8h10v1zm0 3H3v-1h10v1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 14V9h1v5H5zm4 0V9h1v5H9z" clip-rule="evenodd"/>
+ <path d="M4 1h5v1H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6h1v7a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2z"/>
+ <path d="M9 4.5V1l5 5h-3.5A1.5 1.5 0 019 4.5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-text.svg b/src/assets/icons/file-earmark-text.svg
new file mode 100644
index 0000000..0443fce
--- /dev/null
+++ b/src/assets/icons/file-earmark-text.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-earmark-text" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 1h5v1H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6h1v7a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2z"/>
+ <path d="M9 4.5V1l5 5h-3.5A1.5 1.5 0 019 4.5z"/>
+ <path fill-rule="evenodd" d="M5 11.5a.5.5 0 01.5-.5h2a.5.5 0 010 1h-2a.5.5 0 01-.5-.5zm0-2a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5zm0-2a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark-zip.svg b/src/assets/icons/file-earmark-zip.svg
new file mode 100644
index 0000000..320822e
--- /dev/null
+++ b/src/assets/icons/file-earmark-zip.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-file-earmark-zip" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 1h5v1H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6h1v7a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2z"/>
+ <path d="M9 4.5V1l5 5h-3.5A1.5 1.5 0 019 4.5z"/>
+ <path fill-rule="evenodd" d="M5 8.5a1 1 0 011-1h1a1 1 0 011 1v.938l.4 1.599a1 1 0 01-.416 1.074l-.93.62a1 1 0 01-1.11 0l-.929-.62a1 1 0 01-.415-1.074L5 9.438V8.5zm2 0H6v.938a1 1 0 01-.03.243l-.4 1.598.93.62.929-.62-.4-1.598A1 1 0 017 9.438V8.5z" clip-rule="evenodd"/>
+ <path d="M6 2h1.5v1H6zM5 3h1.5v1H5zm1 1h1.5v1H6zM5 5h1.5v1H5zm1 1h1.5v1H6V6z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-earmark.svg b/src/assets/icons/file-earmark.svg
new file mode 100644
index 0000000..15f9b6f
--- /dev/null
+++ b/src/assets/icons/file-earmark.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-earmark" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 1h5v1H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6h1v7a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2z"/>
+ <path d="M9 4.5V1l5 5h-3.5A1.5 1.5 0 019 4.5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-minus.svg b/src/assets/icons/file-minus.svg
new file mode 100644
index 0000000..db80115
--- /dev/null
+++ b/src/assets/icons/file-minus.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-minus" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9 1H4a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V8h-1v5a1 1 0 01-1 1H4a1 1 0 01-1-1V3a1 1 0 011-1h5V1z"/>
+ <path fill-rule="evenodd" d="M11 3.5a.5.5 0 01.5-.5h4a.5.5 0 010 1h-4a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-plus.svg b/src/assets/icons/file-plus.svg
new file mode 100644
index 0000000..a471b7c
--- /dev/null
+++ b/src/assets/icons/file-plus.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-plus" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9 1H4a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V8h-1v5a1 1 0 01-1 1H4a1 1 0 01-1-1V3a1 1 0 011-1h5V1z"/>
+ <path fill-rule="evenodd" d="M13.5 1a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 010-1H13V1.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13 3.5a.5.5 0 01.5-.5h2a.5.5 0 010 1H14v1.5a.5.5 0 01-1 0v-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-post.svg b/src/assets/icons/file-post.svg
new file mode 100644
index 0000000..f444884
--- /dev/null
+++ b/src/assets/icons/file-post.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-post" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path d="M4 5.5a.5.5 0 01.5-.5h7a.5.5 0 01.5.5v7a.5.5 0 01-.5.5h-7a.5.5 0 01-.5-.5v-7z"/>
+ <path fill-rule="evenodd" d="M4 3.5a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-richtext.svg b/src/assets/icons/file-richtext.svg
new file mode 100644
index 0000000..c16928f
--- /dev/null
+++ b/src/assets/icons/file-richtext.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-richtext" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.5 11.5A.5.5 0 015 11h3a.5.5 0 010 1H5a.5.5 0 01-.5-.5zm0-2A.5.5 0 015 9h6a.5.5 0 010 1H5a.5.5 0 01-.5-.5zm1.639-3.708l1.33.886 1.854-1.855a.25.25 0 01.289-.047l1.888.974V7.5a.5.5 0 01-.5.5H5a.5.5 0 01-.5-.5V7s1.54-1.274 1.639-1.208zM6.25 5a.75.75 0 100-1.5.75.75 0 000 1.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-ruled.svg b/src/assets/icons/file-ruled.svg
new file mode 100644
index 0000000..7dbeadf
--- /dev/null
+++ b/src/assets/icons/file-ruled.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-ruled" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path stroke="#000" d="M3 5.5h10m-10 3h10m-10 3h10M5.5 6v8"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-spreadsheet.svg b/src/assets/icons/file-spreadsheet.svg
new file mode 100644
index 0000000..82ca266
--- /dev/null
+++ b/src/assets/icons/file-spreadsheet.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-spreadsheet" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13 6H3V5h10v1zm0 3H3V8h10v1zm0 3H3v-1h10v1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 14V6h1v8H5zm4 0V6h1v8H9z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-text.svg b/src/assets/icons/file-text.svg
new file mode 100644
index 0000000..9de4fc6
--- /dev/null
+++ b/src/assets/icons/file-text.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-file-text" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.5 10.5A.5.5 0 015 10h3a.5.5 0 010 1H5a.5.5 0 01-.5-.5zm0-2A.5.5 0 015 8h6a.5.5 0 010 1H5a.5.5 0 01-.5-.5zm0-2A.5.5 0 015 6h6a.5.5 0 010 1H5a.5.5 0 01-.5-.5zm0-2A.5.5 0 015 4h6a.5.5 0 010 1H5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file-zip.svg b/src/assets/icons/file-zip.svg
new file mode 100644
index 0000000..918ca89
--- /dev/null
+++ b/src/assets/icons/file-zip.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-file-zip" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6.5 8.5a1 1 0 011-1h1a1 1 0 011 1v.938l.4 1.599a1 1 0 01-.416 1.074l-.93.62a1 1 0 01-1.109 0l-.93-.62a1 1 0 01-.415-1.074l.4-1.599V8.5zm2 0h-1v.938a1 1 0 01-.03.243l-.4 1.598.93.62.93-.62-.4-1.598a1 1 0 01-.03-.243V8.5z" clip-rule="evenodd"/>
+ <path d="M7.5 2H9v1H7.5zm-1 1H8v1H6.5zm1 1H9v1H7.5zm-1 1H8v1H6.5zm1 1H9v1H7.5V6z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/file.svg b/src/assets/icons/file.svg
new file mode 100644
index 0000000..cae1795
--- /dev/null
+++ b/src/assets/icons/file.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-file" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 1h8a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/files-alt.svg b/src/assets/icons/files-alt.svg
new file mode 100644
index 0000000..dded2f3
--- /dev/null
+++ b/src/assets/icons/files-alt.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-files-alt" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3 1h8a2 2 0 012 2v10a2 2 0 01-2 2H3a2 2 0 01-2-2V3a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V3a1 1 0 00-1-1H3z" clip-rule="evenodd"/>
+ <path d="M13 4V3a2 2 0 012 2v6a2 2 0 01-2 2v-1a1 1 0 001-1V5a1 1 0 00-1-1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/files.svg b/src/assets/icons/files.svg
new file mode 100644
index 0000000..988a257
--- /dev/null
+++ b/src/assets/icons/files.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-files" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3 2h8a2 2 0 012 2v10a2 2 0 01-2 2H3a2 2 0 01-2-2V4a2 2 0 012-2zm0 1a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V4a1 1 0 00-1-1H3z" clip-rule="evenodd"/>
+ <path d="M5 0h8a2 2 0 012 2v10a2 2 0 01-2 2v-1a1 1 0 001-1V2a1 1 0 00-1-1H5a1 1 0 00-1 1H3a2 2 0 012-2z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/film.svg b/src/assets/icons/film.svg
new file mode 100644
index 0000000..5d6c8e2
--- /dev/null
+++ b/src/assets/icons/film.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-film" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 1a1 1 0 011-1h14a1 1 0 011 1v14a1 1 0 01-1 1H1a1 1 0 01-1-1V1zm4 0h8v6H4V1zm8 8H4v6h8V9zM1 1h2v2H1V1zm2 3H1v2h2V4zM1 7h2v2H1V7zm2 3H1v2h2v-2zm-2 3h2v2H1v-2zM15 1h-2v2h2V1zm-2 3h2v2h-2V4zm2 3h-2v2h2V7zm-2 3h2v2h-2v-2zm2 3h-2v2h2v-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/filter-left.svg b/src/assets/icons/filter-left.svg
new file mode 100644
index 0000000..489f48d
--- /dev/null
+++ b/src/assets/icons/filter-left.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-filter-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 10.5a.5.5 0 01.5-.5h3a.5.5 0 010 1h-3a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/filter-right.svg b/src/assets/icons/filter-right.svg
new file mode 100644
index 0000000..df2b1bd
--- /dev/null
+++ b/src/assets/icons/filter-right.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-filter-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 10.5a.5.5 0 00-.5-.5h-3a.5.5 0 000 1h3a.5.5 0 00.5-.5zm0-3a.5.5 0 00-.5-.5h-7a.5.5 0 000 1h7a.5.5 0 00.5-.5zm0-3a.5.5 0 00-.5-.5h-11a.5.5 0 000 1h11a.5.5 0 00.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/filter.svg b/src/assets/icons/filter.svg
new file mode 100644
index 0000000..f772792
--- /dev/null
+++ b/src/assets/icons/filter.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-filter" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6 10.5a.5.5 0 01.5-.5h3a.5.5 0 010 1h-3a.5.5 0 01-.5-.5zm-2-3a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm-2-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/flag-fill.svg b/src/assets/icons/flag-fill.svg
new file mode 100644
index 0000000..ddf9835
--- /dev/null
+++ b/src/assets/icons/flag-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-flag-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.5 1a.5.5 0 01.5.5v13a.5.5 0 01-1 0v-13a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M3.762 2.558C4.735 1.909 5.348 1.5 6.5 1.5c.653 0 1.139.325 1.495.562l.032.022c.391.26.646.416.973.416.168 0 .356-.042.587-.126a8.89 8.89 0 00.593-.25c.058-.027.117-.053.18-.08.57-.255 1.278-.544 2.14-.544a.5.5 0 01.5.5v6a.5.5 0 01-.5.5c-.638 0-1.18.21-1.734.457l-.159.07c-.22.1-.453.205-.678.287A2.719 2.719 0 019 9.5c-.653 0-1.139-.325-1.495-.562l-.032-.022c-.391-.26-.646-.416-.973-.416-.833 0-1.218.246-2.223.916A.5.5 0 013.5 9V3a.5.5 0 01.223-.416l.04-.026z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/flag.svg b/src/assets/icons/flag.svg
new file mode 100644
index 0000000..f474db1
--- /dev/null
+++ b/src/assets/icons/flag.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-flag" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.5 1a.5.5 0 01.5.5v13a.5.5 0 01-1 0v-13a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M3.762 2.558C4.735 1.909 5.348 1.5 6.5 1.5c.653 0 1.139.325 1.495.562l.032.022c.391.26.646.416.973.416.168 0 .356-.042.587-.126a8.89 8.89 0 00.593-.25c.058-.027.117-.053.18-.08.57-.255 1.278-.544 2.14-.544a.5.5 0 01.5.5v6a.5.5 0 01-.5.5c-.638 0-1.18.21-1.734.457l-.159.07c-.22.1-.453.205-.678.287A2.719 2.719 0 019 9.5c-.653 0-1.139-.325-1.495-.562l-.032-.022c-.391-.26-.646-.416-.973-.416-.833 0-1.218.246-2.223.916a.5.5 0 11-.515-.858C4.735 7.909 5.348 7.5 6.5 7.5c.653 0 1.139.325 1.495.562l.032.022c.391.26.646.416.973.416.168 0 .356-.042.587-.126.187-.068.376-.153.593-.25.058-.027.117-.053.18-.08.456-.204 1-.43 1.64-.512V2.543c-.433.074-.83.234-1.234.414l-.159.07c-.22.1-.453.205-.678.287A2.719 2.719 0 019 3.5c-.653 0-1.139-.325-1.495-.562l-.032-.022c-.391-.26-.646-.416-.973-.416-.833 0-1.218.246-2.223.916a.5.5 0 01-.554-.832l.04-.026z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/folder-check.svg b/src/assets/icons/folder-check.svg
new file mode 100644
index 0000000..28af2e5
--- /dev/null
+++ b/src/assets/icons/folder-check.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-folder-check" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.828 4H2.19a1 1 0 00-.996 1.09l.637 7a1 1 0 00.995.91H9v1H2.826a2 2 0 01-1.991-1.819l-.637-7a1.99 1.99 0 01.342-1.31L.5 3a2 2 0 012-2h3.672a2 2 0 011.414.586l.828.828A2 2 0 009.828 3h3.982a2 2 0 011.992 2.181L15.546 8H14.54l.265-2.91A1 1 0 0013.81 4H9.828zm-2.95-1.707L7.587 3H2.19c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 011-.98h3.672a1 1 0 01.707.293z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M15.854 10.146a.5.5 0 010 .708l-3 3a.5.5 0 01-.708 0l-1.5-1.5a.5.5 0 01.708-.708l1.146 1.147 2.646-2.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/folder-fill.svg b/src/assets/icons/folder-fill.svg
new file mode 100644
index 0000000..b1fa80a
--- /dev/null
+++ b/src/assets/icons/folder-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-folder-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.828 3h3.982a2 2 0 011.992 2.181l-.637 7A2 2 0 0113.174 14H2.826a2 2 0 01-1.991-1.819l-.637-7a1.99 1.99 0 01.342-1.31L.5 3a2 2 0 012-2h3.672a2 2 0 011.414.586l.828.828A2 2 0 009.828 3zm-8.322.12C1.72 3.042 1.95 3 2.19 3h5.396l-.707-.707A1 1 0 006.172 2H2.5a1 1 0 00-1 .981l.006.139z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/folder-minus.svg b/src/assets/icons/folder-minus.svg
new file mode 100644
index 0000000..8a9b039
--- /dev/null
+++ b/src/assets/icons/folder-minus.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-folder-minus" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.828 4H2.19a1 1 0 00-.996 1.09l.637 7a1 1 0 00.995.91H9v1H2.826a2 2 0 01-1.991-1.819l-.637-7a1.99 1.99 0 01.342-1.31L.5 3a2 2 0 012-2h3.672a2 2 0 011.414.586l.828.828A2 2 0 009.828 3h3.982a2 2 0 011.992 2.181L15.546 8H14.54l.265-2.91A1 1 0 0013.81 4H9.828zm-2.95-1.707L7.587 3H2.19c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 011-.98h3.672a1 1 0 01.707.293z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11 11.5a.5.5 0 01.5-.5h4a.5.5 0 010 1h-4a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/folder-plus.svg b/src/assets/icons/folder-plus.svg
new file mode 100644
index 0000000..2b81d0a
--- /dev/null
+++ b/src/assets/icons/folder-plus.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-folder-plus" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.828 4H2.19a1 1 0 00-.996 1.09l.637 7a1 1 0 00.995.91H9v1H2.826a2 2 0 01-1.991-1.819l-.637-7a1.99 1.99 0 01.342-1.31L.5 3a2 2 0 012-2h3.672a2 2 0 011.414.586l.828.828A2 2 0 009.828 3h3.982a2 2 0 011.992 2.181L15.546 8H14.54l.265-2.91A1 1 0 0013.81 4H9.828zm-2.95-1.707L7.587 3H2.19c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 011-.98h3.672a1 1 0 01.707.293z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13.5 10a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 010-1H13v-1.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13 12.5a.5.5 0 01.5-.5h2a.5.5 0 010 1H14v1.5a.5.5 0 01-1 0v-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/folder-symlink-fill.svg b/src/assets/icons/folder-symlink-fill.svg
new file mode 100644
index 0000000..c2b5b12
--- /dev/null
+++ b/src/assets/icons/folder-symlink-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-folder-symlink-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13.81 3H9.828a2 2 0 01-1.414-.586l-.828-.828A2 2 0 006.172 1H2.5a2 2 0 00-2 2l.04.87a1.99 1.99 0 00-.342 1.311l.637 7A2 2 0 002.826 14h10.348a2 2 0 001.991-1.819l.637-7A2 2 0 0013.81 3zM2.19 3c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 011-.98h3.672a1 1 0 01.707.293L7.586 3H2.19zm9.608 5.271l-3.182 1.97c-.27.166-.616-.036-.616-.372V9.1s-2.571-.3-4 2.4c.571-4.8 3.143-4.8 4-4.8v-.769c0-.336.346-.538.616-.371l3.182 1.969c.27.166.27.576 0 .742z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/folder-symlink.svg b/src/assets/icons/folder-symlink.svg
new file mode 100644
index 0000000..862eb91
--- /dev/null
+++ b/src/assets/icons/folder-symlink.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-folder-symlink" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9.828 4a3 3 0 01-2.12-.879l-.83-.828A1 1 0 006.173 2H2.5a1 1 0 00-1 .981L1.546 4h-1L.5 3a2 2 0 012-2h3.672a2 2 0 011.414.586l.828.828A2 2 0 009.828 3v1z"/>
+ <path fill-rule="evenodd" d="M13.81 4H2.19a1 1 0 00-.996 1.09l.637 7a1 1 0 00.995.91h10.348a1 1 0 00.995-.91l.637-7A1 1 0 0013.81 4zM2.19 3A2 2 0 00.198 5.181l.637 7A2 2 0 002.826 14h10.348a2 2 0 001.991-1.819l.637-7A2 2 0 0013.81 3H2.19z" clip-rule="evenodd"/>
+ <path d="M8.616 10.24l3.182-1.969a.443.443 0 000-.742l-3.182-1.97c-.27-.166-.616.036-.616.372V6.7c-.857 0-3.429 0-4 4.8 1.429-2.7 4-2.4 4-2.4v.769c0 .336.346.538.616.371z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/folder.svg b/src/assets/icons/folder.svg
new file mode 100644
index 0000000..870ec7f
--- /dev/null
+++ b/src/assets/icons/folder.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-folder" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9.828 4a3 3 0 01-2.12-.879l-.83-.828A1 1 0 006.173 2H2.5a1 1 0 00-1 .981L1.546 4h-1L.5 3a2 2 0 012-2h3.672a2 2 0 011.414.586l.828.828A2 2 0 009.828 3v1z"/>
+ <path fill-rule="evenodd" d="M13.81 4H2.19a1 1 0 00-.996 1.09l.637 7a1 1 0 00.995.91h10.348a1 1 0 00.995-.91l.637-7A1 1 0 0013.81 4zM2.19 3A2 2 0 00.198 5.181l.637 7A2 2 0 002.826 14h10.348a2 2 0 001.991-1.819l.637-7A2 2 0 0013.81 3H2.19z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/fonts.svg b/src/assets/icons/fonts.svg
new file mode 100644
index 0000000..43177e0
--- /dev/null
+++ b/src/assets/icons/fonts.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-fonts" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12.258 3H3.747l-.082 2.46h.479c.26-1.544.758-1.783 2.693-1.845l.424-.013v7.827c0 .663-.144.82-1.3.923v.52h4.082v-.52c-1.162-.103-1.306-.26-1.306-.923V3.602l.43.013c1.935.062 2.434.301 2.694 1.846h.479L12.258 3z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/forward-fill.svg b/src/assets/icons/forward-fill.svg
new file mode 100644
index 0000000..c19f820
--- /dev/null
+++ b/src/assets/icons/forward-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-forward-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9.77 12.11l4.012-2.953a.647.647 0 000-1.114L9.771 5.09a.644.644 0 00-.971.557V6.65H2v3.9h6.8v1.003c0 .505.545.808.97.557z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/forward.svg b/src/assets/icons/forward.svg
new file mode 100644
index 0000000..02d9bcf
--- /dev/null
+++ b/src/assets/icons/forward.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-forward" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.502 5.513a.144.144 0 00-.202.134V6.65a.5.5 0 01-.5.5H2.5v2.9h6.3a.5.5 0 01.5.5v1.003c0 .108.11.176.202.134l3.984-2.933a.51.51 0 01.042-.028.147.147 0 000-.252.51.51 0 01-.042-.028L9.502 5.513zM8.3 5.647a1.144 1.144 0 011.767-.96l3.994 2.94a1.147 1.147 0 010 1.946l-3.994 2.94a1.144 1.144 0 01-1.767-.96v-.503H2a.5.5 0 01-.5-.5v-3.9a.5.5 0 01.5-.5h6.3v-.503z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/fullscreen-exit.svg b/src/assets/icons/fullscreen-exit.svg
new file mode 100644
index 0000000..41b07eb
--- /dev/null
+++ b/src/assets/icons/fullscreen-exit.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-fullscreen-exit" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.5 0a.5.5 0 01.5.5v4A1.5 1.5 0 014.5 6h-4a.5.5 0 010-1h4a.5.5 0 00.5-.5v-4a.5.5 0 01.5-.5zm5 0a.5.5 0 01.5.5v4a.5.5 0 00.5.5h4a.5.5 0 010 1h-4A1.5 1.5 0 0110 4.5v-4a.5.5 0 01.5-.5zM0 10.5a.5.5 0 01.5-.5h4A1.5 1.5 0 016 11.5v4a.5.5 0 01-1 0v-4a.5.5 0 00-.5-.5h-4a.5.5 0 01-.5-.5zm10 1a1.5 1.5 0 011.5-1.5h4a.5.5 0 010 1h-4a.5.5 0 00-.5.5v4a.5.5 0 01-1 0v-4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/fullscreen.svg b/src/assets/icons/fullscreen.svg
new file mode 100644
index 0000000..4f2a828
--- /dev/null
+++ b/src/assets/icons/fullscreen.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-fullscreen" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 1a.5.5 0 00-.5.5v4a.5.5 0 01-1 0v-4A1.5 1.5 0 011.5 0h4a.5.5 0 010 1h-4zM10 .5a.5.5 0 01.5-.5h4A1.5 1.5 0 0116 1.5v4a.5.5 0 01-1 0v-4a.5.5 0 00-.5-.5h-4a.5.5 0 01-.5-.5zM.5 10a.5.5 0 01.5.5v4a.5.5 0 00.5.5h4a.5.5 0 010 1h-4A1.5 1.5 0 010 14.5v-4a.5.5 0 01.5-.5zm15 0a.5.5 0 01.5.5v4a1.5 1.5 0 01-1.5 1.5h-4a.5.5 0 010-1h4a.5.5 0 00.5-.5v-4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/funnel-fill.svg b/src/assets/icons/funnel-fill.svg
new file mode 100644
index 0000000..ec8ac82
--- /dev/null
+++ b/src/assets/icons/funnel-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-funnel-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M2 3.5v-2h12v2l-4.5 5v5l-3 1v-6L2 3.5z"/>
+ <path fill-rule="evenodd" d="M1.5 1.5A.5.5 0 012 1h12a.5.5 0 01.5.5v2a.5.5 0 01-.128.334L10 8.692V13.5a.5.5 0 01-.342.474l-3 1A.5.5 0 016 14.5V8.692L1.628 3.834A.5.5 0 011.5 3.5v-2zm1 .5v1.308l4.372 4.858A.5.5 0 017 8.5v5.306l2-.666V8.5a.5.5 0 01.128-.334L13.5 3.308V2h-11z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/funnel.svg b/src/assets/icons/funnel.svg
new file mode 100644
index 0000000..eed2196
--- /dev/null
+++ b/src/assets/icons/funnel.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-funnel" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 1.5A.5.5 0 012 1h12a.5.5 0 01.5.5v2a.5.5 0 01-.128.334L10 8.692V13.5a.5.5 0 01-.342.474l-3 1A.5.5 0 016 14.5V8.692L1.628 3.834A.5.5 0 011.5 3.5v-2zm1 .5v1.308l4.372 4.858A.5.5 0 017 8.5v5.306l2-.666V8.5a.5.5 0 01.128-.334L13.5 3.308V2h-11z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/gear-fill.svg b/src/assets/icons/gear-fill.svg
new file mode 100644
index 0000000..105835c
--- /dev/null
+++ b/src/assets/icons/gear-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-gear-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 01-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 01.872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 012.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 012.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 01.872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 01-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 01-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 100-5.86 2.929 2.929 0 000 5.858z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/gear-wide-connected.svg b/src/assets/icons/gear-wide-connected.svg
new file mode 100644
index 0000000..62a088a
--- /dev/null
+++ b/src/assets/icons/gear-wide-connected.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-gear-wide-connected" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.928 1.723c-.243-.97-1.62-.97-1.863 0l-.072.286a.96.96 0 01-1.622.435l-.204-.212c-.695-.718-1.889-.03-1.614.932l.08.283a.96.96 0 01-1.186 1.187l-.283-.081c-.961-.275-1.65.919-.932 1.614l.212.204a.96.96 0 01-.435 1.622l-.286.072c-.97.242-.97 1.62 0 1.863l.286.071a.96.96 0 01.435 1.622l-.212.205c-.718.695-.03 1.888.932 1.613l.283-.08a.96.96 0 011.187 1.187l-.081.283c-.275.96.919 1.65 1.614.931l.204-.211a.96.96 0 011.622.434l.072.286c.242.97 1.62.97 1.863 0l.071-.286a.96.96 0 011.622-.434l.205.212c.695.718 1.888.029 1.613-.932l-.08-.283a.96.96 0 011.187-1.188l.283.081c.96.275 1.65-.918.931-1.613l-.211-.205A.96.96 0 0115.983 10l.286-.071c.97-.243.97-1.62 0-1.863l-.286-.072a.96.96 0 01-.434-1.622l.212-.204c.718-.695.029-1.889-.932-1.614l-.283.08a.96.96 0 01-1.188-1.186l.081-.283c.275-.961-.918-1.65-1.613-.932l-.205.212A.96.96 0 0110 2.009l-.071-.286zm-.932 12.27a4.998 4.998 0 100-9.994 4.998 4.998 0 000 9.995z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8.372 8.996L5.598 5.298l.8-.6 2.848 3.798h4.748v1H9.246l-2.849 3.798-.8-.6 2.775-3.698z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/gear-wide.svg b/src/assets/icons/gear-wide.svg
new file mode 100644
index 0000000..e08e4d5
--- /dev/null
+++ b/src/assets/icons/gear-wide.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-gear-wide" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.928 1.723c-.243-.97-1.62-.97-1.863 0l-.072.286a.96.96 0 01-1.622.435l-.204-.212c-.695-.718-1.889-.03-1.614.932l.08.283a.96.96 0 01-1.186 1.187l-.283-.081c-.961-.275-1.65.919-.932 1.614l.212.204a.96.96 0 01-.435 1.622l-.286.072c-.97.242-.97 1.62 0 1.863l.286.071a.96.96 0 01.435 1.622l-.212.205c-.718.695-.03 1.888.932 1.613l.283-.08a.96.96 0 011.187 1.187l-.081.283c-.275.96.919 1.65 1.614.931l.204-.211a.96.96 0 011.622.434l.072.286c.242.97 1.62.97 1.863 0l.071-.286a.96.96 0 011.622-.434l.205.212c.695.718 1.888.029 1.613-.932l-.08-.283a.96.96 0 011.187-1.188l.283.081c.96.275 1.65-.918.931-1.613l-.211-.205A.96.96 0 0115.983 10l.286-.071c.97-.243.97-1.62 0-1.863l-.286-.072a.96.96 0 01-.434-1.622l.212-.204c.718-.695.029-1.889-.932-1.614l-.283.08a.96.96 0 01-1.188-1.186l.081-.283c.275-.961-.918-1.65-1.613-.932l-.205.212A.96.96 0 0110 2.009l-.071-.286zm-.932 12.27a4.998 4.998 0 100-9.994 4.998 4.998 0 000 9.995z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/gear.svg b/src/assets/icons/gear.svg
new file mode 100644
index 0000000..30dab5f
--- /dev/null
+++ b/src/assets/icons/gear.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-gear" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.837 1.626c-.246-.835-1.428-.835-1.674 0l-.094.319A1.873 1.873 0 014.377 3.06l-.292-.16c-.764-.415-1.6.42-1.184 1.185l.159.292a1.873 1.873 0 01-1.115 2.692l-.319.094c-.835.246-.835 1.428 0 1.674l.319.094a1.873 1.873 0 011.115 2.693l-.16.291c-.415.764.42 1.6 1.185 1.184l.292-.159a1.873 1.873 0 012.692 1.116l.094.318c.246.835 1.428.835 1.674 0l.094-.319a1.873 1.873 0 012.693-1.115l.291.16c.764.415 1.6-.42 1.184-1.185l-.159-.291a1.873 1.873 0 011.116-2.693l.318-.094c.835-.246.835-1.428 0-1.674l-.319-.094a1.873 1.873 0 01-1.115-2.692l.16-.292c.415-.764-.42-1.6-1.185-1.184l-.291.159A1.873 1.873 0 018.93 1.945l-.094-.319zm-2.633-.283c.527-1.79 3.065-1.79 3.592 0l.094.319a.873.873 0 001.255.52l.292-.16c1.64-.892 3.434.901 2.54 2.541l-.159.292a.873.873 0 00.52 1.255l.319.094c1.79.527 1.79 3.065 0 3.592l-.319.094a.873.873 0 00-.52 1.255l.16.292c.893 1.64-.902 3.434-2.541 2.54l-.292-.159a.873.873 0 00-1.255.52l-.094.319c-.527 1.79-3.065 1.79-3.592 0l-.094-.319a.873.873 0 00-1.255-.52l-.292.16c-1.64.893-3.433-.902-2.54-2.541l.159-.292a.873.873 0 00-.52-1.255l-.319-.094c-1.79-.527-1.79-3.065 0-3.592l.319-.094a.873.873 0 00.52-1.255l-.16-.292c-.892-1.64.902-3.433 2.541-2.54l.292.159a.873.873 0 001.255-.52l.094-.319z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 5.754a2.246 2.246 0 100 4.492 2.246 2.246 0 000-4.492zM4.754 8a3.246 3.246 0 116.492 0 3.246 3.246 0 01-6.492 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/gem.svg b/src/assets/icons/gem.svg
new file mode 100644
index 0000000..c762ad7
--- /dev/null
+++ b/src/assets/icons/gem.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-gem" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.1.7a.5.5 0 01.4-.2h9a.5.5 0 01.4.2l2.976 3.974c.149.185.156.45.01.644L8.4 15.3a.5.5 0 01-.8 0L.1 5.3a.5.5 0 010-.6l3-4zm11.386 3.785l-1.806-2.41-.776 2.413 2.582-.003zm-3.633.004l.961-2.989H4.186l.963 2.995 5.704-.006zM5.47 5.495l5.062-.005L8 13.366 5.47 5.495zm-1.371-.999l-.78-2.422-1.818 2.425 2.598-.003zM1.499 5.5l2.92-.003 2.193 6.82L1.5 5.5zm7.889 6.817l2.194-6.828 2.929-.003-5.123 6.831z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/geo-alt.svg b/src/assets/icons/geo-alt.svg
new file mode 100644
index 0000000..6d3b58d
--- /dev/null
+++ b/src/assets/icons/geo-alt.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-geo-alt" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 16s6-5.686 6-10A6 6 0 002 6c0 4.314 6 10 6 10zm0-7a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/geo.svg b/src/assets/icons/geo.svg
new file mode 100644
index 0000000..4e567be
--- /dev/null
+++ b/src/assets/icons/geo.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-geo" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M11 4a3 3 0 11-6 0 3 3 0 016 0z"/>
+ <path d="M7.5 4h1v9a.5.5 0 01-1 0V4z"/>
+ <path fill-rule="evenodd" d="M6.489 12.095a.5.5 0 01-.383.594c-.565.123-1.003.292-1.286.472-.302.192-.32.321-.32.339 0 .013.005.085.146.21.14.124.372.26.701.382.655.246 1.593.408 2.653.408s1.998-.162 2.653-.408c.329-.123.56-.258.701-.382.14-.125.146-.197.146-.21 0-.018-.018-.147-.32-.339-.283-.18-.721-.35-1.286-.472a.5.5 0 11.212-.977c.63.137 1.193.34 1.61.606.4.253.784.645.784 1.182 0 .402-.219.724-.483.958-.264.235-.618.423-1.013.57-.793.298-1.855.472-3.004.472s-2.21-.174-3.004-.471c-.395-.148-.749-.336-1.013-.571-.264-.234-.483-.556-.483-.958 0-.537.384-.929.783-1.182.418-.266.98-.47 1.611-.606a.5.5 0 01.595.383z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/gift-fill.svg b/src/assets/icons/gift-fill.svg
new file mode 100644
index 0000000..825dd05
--- /dev/null
+++ b/src/assets/icons/gift-fill.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-gift-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M10 1a1.5 1.5 0 00-1.5 1.5c0 .098.033.16.12.227.103.081.272.15.49.2A3.44 3.44 0 009.96 3h.015L10 2.999l.025.002h.014A2.569 2.569 0 0010.293 3c.17-.006.387-.026.598-.073.217-.048.386-.118.49-.199.086-.066.119-.13.119-.227A1.5 1.5 0 0010 1zm0 3h-.006a3.535 3.535 0 01-.326 0 4.435 4.435 0 01-.777-.097c-.283-.063-.614-.175-.885-.385A1.255 1.255 0 017.5 2.5a2.5 2.5 0 015 0c0 .454-.217.793-.506 1.017-.27.21-.602.322-.885.385a4.434 4.434 0 01-1.104.099H10z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6 1a1.5 1.5 0 00-1.5 1.5c0 .098.033.16.12.227.103.081.272.15.49.2A3.44 3.44 0 005.96 3h.015L6 2.999l.025.002h.014l.053.001a3.869 3.869 0 00.799-.076c.217-.048.386-.118.49-.199.086-.066.119-.13.119-.227A1.5 1.5 0 006 1zm0 3h-.006a3.535 3.535 0 01-.326 0 4.435 4.435 0 01-.777-.097c-.283-.063-.614-.175-.885-.385A1.255 1.255 0 013.5 2.5a2.5 2.5 0 015 0c0 .454-.217.793-.506 1.017-.27.21-.602.322-.885.385a4.435 4.435 0 01-1.103.099H6zm9 10.5V7H8.5v9h5a1.5 1.5 0 001.5-1.5zM7.5 16h-5A1.5 1.5 0 011 14.5V7h6.5v9z" clip-rule="evenodd"/>
+ <path d="M0 4a1 1 0 011-1h14a1 1 0 011 1v1a1 1 0 01-1 1H1a1 1 0 01-1-1V4z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/gift.svg b/src/assets/icons/gift.svg
new file mode 100644
index 0000000..58e0d83
--- /dev/null
+++ b/src/assets/icons/gift.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-gift" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 6v8.5a.5.5 0 00.5.5h11a.5.5 0 00.5-.5V6h1v8.5a1.5 1.5 0 01-1.5 1.5h-11A1.5 1.5 0 011 14.5V6h1zm8-5a1.5 1.5 0 00-1.5 1.5c0 .098.033.16.12.227.103.081.272.15.49.2A3.44 3.44 0 009.96 3h.015L10 2.999l.025.002h.014A2.569 2.569 0 0010.293 3c.17-.006.387-.026.598-.073.217-.048.386-.118.49-.199.086-.066.119-.13.119-.227A1.5 1.5 0 0010 1zm0 3h-.006a3.535 3.535 0 01-.326 0 4.435 4.435 0 01-.777-.097c-.283-.063-.614-.175-.885-.385A1.255 1.255 0 017.5 2.5a2.5 2.5 0 015 0c0 .454-.217.793-.506 1.017-.27.21-.602.322-.885.385a4.434 4.434 0 01-1.104.099H10z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6 1a1.5 1.5 0 00-1.5 1.5c0 .098.033.16.12.227.103.081.272.15.49.2A3.44 3.44 0 005.96 3h.015L6 2.999l.025.002h.014l.053.001a3.869 3.869 0 00.799-.076c.217-.048.386-.118.49-.199.086-.066.119-.13.119-.227A1.5 1.5 0 006 1zm0 3h-.006a3.535 3.535 0 01-.326 0 4.435 4.435 0 01-.777-.097c-.283-.063-.614-.175-.885-.385A1.255 1.255 0 013.5 2.5a2.5 2.5 0 015 0c0 .454-.217.793-.506 1.017-.27.21-.602.322-.885.385a4.435 4.435 0 01-1.103.099H6zm1.5 12V6h1v10h-1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M15 4H1v1h14V4zM1 3a1 1 0 00-1 1v1a1 1 0 001 1h14a1 1 0 001-1V4a1 1 0 00-1-1H1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/graph-down.svg b/src/assets/icons/graph-down.svg
new file mode 100644
index 0000000..33c6c68
--- /dev/null
+++ b/src/assets/icons/graph-down.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-graph-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M0 0h1v16H0V0zm1 15h15v1H1v-1z"/>
+ <path fill-rule="evenodd" d="M14.39 9.041l-4.349-5.436L7 6.646 3.354 3l-.708.707L7 8.061l2.959-2.959 3.65 4.564.781-.625z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10 9.854a.5.5 0 00.5.5h4a.5.5 0 00.5-.5v-4a.5.5 0 00-1 0v3.5h-3.5a.5.5 0 00-.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/graph-up.svg b/src/assets/icons/graph-up.svg
new file mode 100644
index 0000000..c93f022
--- /dev/null
+++ b/src/assets/icons/graph-up.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-graph-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M0 0h1v16H0V0zm1 15h15v1H1v-1z"/>
+ <path fill-rule="evenodd" d="M14.39 4.312L10.041 9.75 7 6.707l-3.646 3.647-.708-.708L7 5.293 9.959 8.25l3.65-4.563.781.624z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10 3.5a.5.5 0 01.5-.5h4a.5.5 0 01.5.5v4a.5.5 0 01-1 0V4h-3.5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid-1x2-fill.svg b/src/assets/icons/grid-1x2-fill.svg
new file mode 100644
index 0000000..cd00243
--- /dev/null
+++ b/src/assets/icons/grid-1x2-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid-1x2-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M0 1a1 1 0 011-1h5a1 1 0 011 1v14a1 1 0 01-1 1H1a1 1 0 01-1-1V1zm9 0a1 1 0 011-1h5a1 1 0 011 1v5a1 1 0 01-1 1h-5a1 1 0 01-1-1V1zm0 9a1 1 0 011-1h5a1 1 0 011 1v5a1 1 0 01-1 1h-5a1 1 0 01-1-1v-5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid-1x2.svg b/src/assets/icons/grid-1x2.svg
new file mode 100644
index 0000000..b76e6d4
--- /dev/null
+++ b/src/assets/icons/grid-1x2.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid-1x2" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6 1H1v14h5V1zm9 0h-5v5h5V1zm0 9h-5v5h5v-5zM0 1a1 1 0 011-1h5a1 1 0 011 1v14a1 1 0 01-1 1H1a1 1 0 01-1-1V1zm9 0a1 1 0 011-1h5a1 1 0 011 1v5a1 1 0 01-1 1h-5a1 1 0 01-1-1V1zm1 8a1 1 0 00-1 1v5a1 1 0 001 1h5a1 1 0 001-1v-5a1 1 0 00-1-1h-5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid-3x2-gap-fill.svg b/src/assets/icons/grid-3x2-gap-fill.svg
new file mode 100644
index 0000000..968571c
--- /dev/null
+++ b/src/assets/icons/grid-3x2-gap-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid-3x2-gap-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M1 4a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H2a1 1 0 01-1-1V4zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H7a1 1 0 01-1-1V4zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V4zM1 9a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H2a1 1 0 01-1-1V9zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H7a1 1 0 01-1-1V9zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V9z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid-3x2-gap.svg b/src/assets/icons/grid-3x2-gap.svg
new file mode 100644
index 0000000..16137a7
--- /dev/null
+++ b/src/assets/icons/grid-3x2-gap.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid-3x2-gap" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path stroke="#000" d="M1.5 4a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H2a.5.5 0 01-.5-.5V4zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H7a.5.5 0 01-.5-.5V4zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 01-.5-.5V4zm-10 5a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H2a.5.5 0 01-.5-.5V9zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H7a.5.5 0 01-.5-.5V9zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 01-.5-.5V9z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid-3x2.svg b/src/assets/icons/grid-3x2.svg
new file mode 100644
index 0000000..f464348
--- /dev/null
+++ b/src/assets/icons/grid-3x2.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid-3x2" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 3.5A1.5 1.5 0 011.5 2h13A1.5 1.5 0 0116 3.5v8a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 010 11.5v-8zM1.5 3a.5.5 0 00-.5.5V7h4V3H1.5zM5 8H1v3.5a.5.5 0 00.5.5H5V8zm1 0h4v4H6V8zm4-1H6V3h4v4zm1 1v4h3.5a.5.5 0 00.5-.5V8h-4zm0-1V3h3.5a.5.5 0 01.5.5V7h-4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid-3x3-gap-fill.svg b/src/assets/icons/grid-3x3-gap-fill.svg
new file mode 100644
index 0000000..d7d317e
--- /dev/null
+++ b/src/assets/icons/grid-3x3-gap-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid-3x3-gap-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M1 2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H2a1 1 0 01-1-1V2zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H7a1 1 0 01-1-1V2zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V2zM1 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H2a1 1 0 01-1-1V7zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H7a1 1 0 01-1-1V7zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V7zM1 12a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H2a1 1 0 01-1-1v-2zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H7a1 1 0 01-1-1v-2zm5 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid-3x3-gap.svg b/src/assets/icons/grid-3x3-gap.svg
new file mode 100644
index 0000000..cca056e
--- /dev/null
+++ b/src/assets/icons/grid-3x3-gap.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid-3x3-gap" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path stroke="#000" d="M1.5 2a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H2a.5.5 0 01-.5-.5V2zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H7a.5.5 0 01-.5-.5V2zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 01-.5-.5V2zm-10 5a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H2a.5.5 0 01-.5-.5V7zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H7a.5.5 0 01-.5-.5V7zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 01-.5-.5V7zm-10 5a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H2a.5.5 0 01-.5-.5v-2zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5H7a.5.5 0 01-.5-.5v-2zm5 0a.5.5 0 01.5-.5h2a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 01-.5-.5v-2z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid-3x3.svg b/src/assets/icons/grid-3x3.svg
new file mode 100644
index 0000000..3489375
--- /dev/null
+++ b/src/assets/icons/grid-3x3.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid-3x3" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 1.5A1.5 1.5 0 011.5 0h13A1.5 1.5 0 0116 1.5v13a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 010 14.5v-13zM1.5 1a.5.5 0 00-.5.5V5h4V1H1.5zM5 6H1v4h4V6zm1 4V6h4v4H6zm-1 1H1v3.5a.5.5 0 00.5.5H5v-4zm1 0h4v4H6v-4zm5 0v4h3.5a.5.5 0 00.5-.5V11h-4zm0-1h4V6h-4v4zm0-5h4V1.5a.5.5 0 00-.5-.5H11v4zm-1 0H6V1h4v4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid-fill.svg b/src/assets/icons/grid-fill.svg
new file mode 100644
index 0000000..d16ce49
--- /dev/null
+++ b/src/assets/icons/grid-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 2.5A1.5 1.5 0 012.5 1h3A1.5 1.5 0 017 2.5v3A1.5 1.5 0 015.5 7h-3A1.5 1.5 0 011 5.5v-3zm8 0A1.5 1.5 0 0110.5 1h3A1.5 1.5 0 0115 2.5v3A1.5 1.5 0 0113.5 7h-3A1.5 1.5 0 019 5.5v-3zm-8 8A1.5 1.5 0 012.5 9h3A1.5 1.5 0 017 10.5v3A1.5 1.5 0 015.5 15h-3A1.5 1.5 0 011 13.5v-3zm8 0A1.5 1.5 0 0110.5 9h3a1.5 1.5 0 011.5 1.5v3a1.5 1.5 0 01-1.5 1.5h-3A1.5 1.5 0 019 13.5v-3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/grid.svg b/src/assets/icons/grid.svg
new file mode 100644
index 0000000..b17258d
--- /dev/null
+++ b/src/assets/icons/grid.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-grid" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 2.5A1.5 1.5 0 012.5 1h3A1.5 1.5 0 017 2.5v3A1.5 1.5 0 015.5 7h-3A1.5 1.5 0 011 5.5v-3zM2.5 2a.5.5 0 00-.5.5v3a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-3a.5.5 0 00-.5-.5h-3zm6.5.5A1.5 1.5 0 0110.5 1h3A1.5 1.5 0 0115 2.5v3A1.5 1.5 0 0113.5 7h-3A1.5 1.5 0 019 5.5v-3zm1.5-.5a.5.5 0 00-.5.5v3a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-3a.5.5 0 00-.5-.5h-3zM1 10.5A1.5 1.5 0 012.5 9h3A1.5 1.5 0 017 10.5v3A1.5 1.5 0 015.5 15h-3A1.5 1.5 0 011 13.5v-3zm1.5-.5a.5.5 0 00-.5.5v3a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-3a.5.5 0 00-.5-.5h-3zm6.5.5A1.5 1.5 0 0110.5 9h3a1.5 1.5 0 011.5 1.5v3a1.5 1.5 0 01-1.5 1.5h-3A1.5 1.5 0 019 13.5v-3zm1.5-.5a.5.5 0 00-.5.5v3a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-3a.5.5 0 00-.5-.5h-3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/hammer.svg b/src/assets/icons/hammer.svg
new file mode 100644
index 0000000..d4da16b
--- /dev/null
+++ b/src/assets/icons/hammer.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-hammer" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9.812 1.952a.5.5 0 01-.312.89c-1.671 0-2.852.596-3.616 1.185L4.857 5.073V6.21a.5.5 0 01-.146.354L3.425 7.853a.5.5 0 01-.708 0L.146 5.274a.5.5 0 010-.706l1.286-1.29a.5.5 0 01.354-.146H2.84C4.505 1.228 6.216.862 7.557 1.04a5.009 5.009 0 012.077.782l.178.129z"/>
+ <path fill-rule="evenodd" d="M6.012 3.5a.5.5 0 01.359.165l9.146 8.646A.5.5 0 0115.5 13L14 14.5a.5.5 0 01-.756-.056L4.598 5.297a.5.5 0 01.048-.65l1-1a.5.5 0 01.366-.147z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/hash.svg b/src/assets/icons/hash.svg
new file mode 100644
index 0000000..d1b6243
--- /dev/null
+++ b/src/assets/icons/hash.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-hash" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8.39 12.648a1.32 1.32 0 00-.015.18c0 .305.21.508.5.508.266 0 .492-.172.555-.477l.554-2.703h1.204c.421 0 .617-.234.617-.547 0-.312-.188-.53-.617-.53h-.985l.516-2.524h1.265c.43 0 .618-.227.618-.547 0-.313-.188-.524-.618-.524h-1.046l.476-2.304a1.06 1.06 0 00.016-.164.51.51 0 00-.516-.516.54.54 0 00-.539.43l-.523 2.554H7.617l.477-2.304c.008-.04.015-.118.015-.164a.512.512 0 00-.523-.516.539.539 0 00-.531.43L6.53 5.484H5.414c-.43 0-.617.22-.617.532 0 .312.187.539.617.539h.906l-.515 2.523H4.609c-.421 0-.609.219-.609.531 0 .313.188.547.61.547h.976l-.516 2.492c-.008.04-.015.125-.015.18 0 .305.21.508.5.508.265 0 .492-.172.554-.477l.555-2.703h2.242l-.515 2.492zm-1-6.109h2.266l-.515 2.563H6.859l.532-2.563z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/heart-fill.svg b/src/assets/icons/heart-fill.svg
new file mode 100644
index 0000000..2f7ac5a
--- /dev/null
+++ b/src/assets/icons/heart-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-heart-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/heart-half.svg b/src/assets/icons/heart-half.svg
new file mode 100644
index 0000000..adf019d
--- /dev/null
+++ b/src/assets/icons/heart-half.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-heart-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 1.314C3.562-3.248-7.534 4.735 8 15V1.314z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 2.748l-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 01.176-.17C12.72-3.042 23.333 4.867 8 15z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/heart.svg b/src/assets/icons/heart.svg
new file mode 100644
index 0000000..4cccc44
--- /dev/null
+++ b/src/assets/icons/heart.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-heart" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 2.748l-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 01.176-.17C12.72-3.042 23.333 4.867 8 15z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/house-door-fill.svg b/src/assets/icons/house-door-fill.svg
new file mode 100644
index 0000000..405fc69
--- /dev/null
+++ b/src/assets/icons/house-door-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-house-door-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M6.5 10.995V14.5a.5.5 0 01-.5.5H2a.5.5 0 01-.5-.5v-7a.5.5 0 01.146-.354l6-6a.5.5 0 01.708 0l6 6a.5.5 0 01.146.354v7a.5.5 0 01-.5.5h-4a.5.5 0 01-.5-.5V11c0-.25-.25-.5-.5-.5H7c-.25 0-.5.25-.5.495z"/>
+ <path fill-rule="evenodd" d="M13 2.5V6l-2-2V2.5a.5.5 0 01.5-.5h1a.5.5 0 01.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/house-door.svg b/src/assets/icons/house-door.svg
new file mode 100644
index 0000000..e58dc5f
--- /dev/null
+++ b/src/assets/icons/house-door.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-house-door" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.646 1.146a.5.5 0 01.708 0l6 6a.5.5 0 01.146.354v7a.5.5 0 01-.5.5H9.5a.5.5 0 01-.5-.5v-4H7v4a.5.5 0 01-.5.5H2a.5.5 0 01-.5-.5v-7a.5.5 0 01.146-.354l6-6zM2.5 7.707V14H6v-4a.5.5 0 01.5-.5h3a.5.5 0 01.5.5v4h3.5V7.707L8 2.207l-5.5 5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13 2.5V6l-2-2V2.5a.5.5 0 01.5-.5h1a.5.5 0 01.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/house-fill.svg b/src/assets/icons/house-fill.svg
new file mode 100644
index 0000000..d5dee82
--- /dev/null
+++ b/src/assets/icons/house-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-house-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 3.293l6 6V13.5a1.5 1.5 0 01-1.5 1.5h-9A1.5 1.5 0 012 13.5V9.293l6-6zm5-.793V6l-2-2V2.5a.5.5 0 01.5-.5h1a.5.5 0 01.5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.293 1.5a1 1 0 011.414 0l6.647 6.646a.5.5 0 01-.708.708L8 2.207 1.354 8.854a.5.5 0 11-.708-.708L7.293 1.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/house.svg b/src/assets/icons/house.svg
new file mode 100644
index 0000000..8351f6c
--- /dev/null
+++ b/src/assets/icons/house.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-house" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 13.5V7h1v6.5a.5.5 0 00.5.5h9a.5.5 0 00.5-.5V7h1v6.5a1.5 1.5 0 01-1.5 1.5h-9A1.5 1.5 0 012 13.5zm11-11V6l-2-2V2.5a.5.5 0 01.5-.5h1a.5.5 0 01.5.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.293 1.5a1 1 0 011.414 0l6.647 6.646a.5.5 0 01-.708.708L8 2.207 1.354 8.854a.5.5 0 11-.708-.708L7.293 1.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/hr.svg b/src/assets/icons/hr.svg
new file mode 100644
index 0000000..a579270
--- /dev/null
+++ b/src/assets/icons/hr.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-hr" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 8a.5.5 0 01.5-.5h15a.5.5 0 010 1H.5A.5.5 0 010 8z" clip-rule="evenodd"/>
+ <path d="M4 3h8a1 1 0 011 1v2.5h1V4a2 2 0 00-2-2H4a2 2 0 00-2 2v2.5h1V4a1 1 0 011-1zM3 9.5H2V12a2 2 0 002 2h8a2 2 0 002-2V9.5h-1V12a1 1 0 01-1 1H4a1 1 0 01-1-1V9.5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/image-alt.svg b/src/assets/icons/image-alt.svg
new file mode 100644
index 0000000..c043a0c
--- /dev/null
+++ b/src/assets/icons/image-alt.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-image-alt" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M10.648 6.646a.5.5 0 01.577-.093l4.777 3.947V15a1 1 0 01-1 1h-14a1 1 0 01-1-1v-2l3.646-4.354a.5.5 0 01.63-.062l2.66 2.773 3.71-4.71z"/>
+ <path fill-rule="evenodd" d="M4.5 5a2.5 2.5 0 100-5 2.5 2.5 0 000 5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/image-fill.svg b/src/assets/icons/image-fill.svg
new file mode 100644
index 0000000..8fb6db8
--- /dev/null
+++ b/src/assets/icons/image-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-image-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.002 3a2 2 0 012-2h12a2 2 0 012 2v10a2 2 0 01-2 2h-12a2 2 0 01-2-2V3zm1 9l2.646-2.354a.5.5 0 01.63-.062l2.66 1.773 3.71-3.71a.5.5 0 01.577-.094L15.002 9.5V13a1 1 0 01-1 1h-12a1 1 0 01-1-1v-1zm5-6.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/image.svg b/src/assets/icons/image.svg
new file mode 100644
index 0000000..b04a925
--- /dev/null
+++ b/src/assets/icons/image.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-image" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.002 2h-12a1 1 0 00-1 1v10a1 1 0 001 1h12a1 1 0 001-1V3a1 1 0 00-1-1zm-12-1a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V3a2 2 0 00-2-2h-12z" clip-rule="evenodd"/>
+ <path d="M10.648 7.646a.5.5 0 01.577-.093L15.002 9.5V14h-14v-2l2.646-2.354a.5.5 0 01.63-.062l2.66 1.773 3.71-3.71z"/>
+ <path fill-rule="evenodd" d="M4.502 7a1.5 1.5 0 100-3 1.5 1.5 0 000 3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/images.svg b/src/assets/icons/images.svg
new file mode 100644
index 0000000..3b30bc2
--- /dev/null
+++ b/src/assets/icons/images.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-images" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12.002 4h-10a1 1 0 00-1 1v8a1 1 0 001 1h10a1 1 0 001-1V5a1 1 0 00-1-1zm-10-1a2 2 0 00-2 2v8a2 2 0 002 2h10a2 2 0 002-2V5a2 2 0 00-2-2h-10z" clip-rule="evenodd"/>
+ <path d="M10.648 8.646a.5.5 0 01.577-.093l1.777 1.947V14h-12v-1l2.646-2.354a.5.5 0 01.63-.062l2.66 1.773 3.71-3.71z"/>
+ <path fill-rule="evenodd" d="M4.502 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM4 2h10a1 1 0 011 1v8a1 1 0 01-1 1v1a2 2 0 002-2V3a2 2 0 00-2-2H4a2 2 0 00-2 2h1a1 1 0 011-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/inbox-fill.svg b/src/assets/icons/inbox-fill.svg
new file mode 100644
index 0000000..db0c289
--- /dev/null
+++ b/src/assets/icons/inbox-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-inbox-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.81 4.063A1.5 1.5 0 014.98 3.5h6.04a1.5 1.5 0 011.17.563l3.7 4.625a.5.5 0 01-.78.624l-3.7-4.624a.5.5 0 00-.39-.188H4.98a.5.5 0 00-.39.188L.89 9.312a.5.5 0 11-.78-.624l3.7-4.625z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M.125 8.67A.5.5 0 01.5 8.5h5A.5.5 0 016 9c0 .828.625 2 2 2s2-1.172 2-2a.5.5 0 01.5-.5h5a.5.5 0 01.496.562l-.39 3.124a1.5 1.5 0 01-1.489 1.314H1.883a1.5 1.5 0 01-1.489-1.314l-.39-3.124a.5.5 0 01.121-.393z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/inbox.svg b/src/assets/icons/inbox.svg
new file mode 100644
index 0000000..272c235
--- /dev/null
+++ b/src/assets/icons/inbox.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-inbox" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.81 4.063A1.5 1.5 0 014.98 3.5h6.04a1.5 1.5 0 011.17.563l3.7 4.625a.5.5 0 01-.78.624l-3.7-4.624a.5.5 0 00-.39-.188H4.98a.5.5 0 00-.39.188L.89 9.312a.5.5 0 11-.78-.624l3.7-4.625z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M.125 8.67A.5.5 0 01.5 8.5H6a.5.5 0 01.5.5 1.5 1.5 0 003 0 .5.5 0 01.5-.5h5.5a.5.5 0 01.496.562l-.39 3.124a1.5 1.5 0 01-1.489 1.314H1.883a1.5 1.5 0 01-1.489-1.314l-.39-3.124a.5.5 0 01.121-.393zm.941.83l.32 2.562a.5.5 0 00.497.438h12.234a.5.5 0 00.496-.438l.32-2.562H10.45a2.5 2.5 0 01-4.9 0H1.066z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/inboxes-fill.svg b/src/assets/icons/inboxes-fill.svg
new file mode 100644
index 0000000..c78baa2
--- /dev/null
+++ b/src/assets/icons/inboxes-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-inboxes-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.125 11.17A.5.5 0 01.5 11H6a.5.5 0 01.5.5 1.5 1.5 0 003 0 .5.5 0 01.5-.5h5.5a.5.5 0 01.496.562l-.39 3.124A1.5 1.5 0 0114.117 16H1.883a1.5 1.5 0 01-1.489-1.314l-.39-3.124a.5.5 0 01.121-.393zM3.81.563A1.5 1.5 0 014.98 0h6.04a1.5 1.5 0 011.17.563l3.7 4.625a.5.5 0 01-.78.624l-3.7-4.624A.5.5 0 0011.02 1H4.98a.5.5 0 00-.39.188L.89 5.812a.5.5 0 11-.78-.624L3.81.563z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M.125 5.17A.5.5 0 01.5 5H6a.5.5 0 01.5.5 1.5 1.5 0 003 0A.5.5 0 0110 5h5.5a.5.5 0 01.496.562l-.39 3.124A1.5 1.5 0 0114.117 10H1.883A1.5 1.5 0 01.394 8.686l-.39-3.124a.5.5 0 01.121-.393z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/inboxes.svg b/src/assets/icons/inboxes.svg
new file mode 100644
index 0000000..efb8f7f
--- /dev/null
+++ b/src/assets/icons/inboxes.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-inboxes" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.125 11.17A.5.5 0 01.5 11H6a.5.5 0 01.5.5 1.5 1.5 0 003 0 .5.5 0 01.5-.5h5.5a.5.5 0 01.496.562l-.39 3.124A1.5 1.5 0 0114.117 16H1.883a1.5 1.5 0 01-1.489-1.314l-.39-3.124a.5.5 0 01.121-.393zm.941.83l.32 2.562a.5.5 0 00.497.438h12.234a.5.5 0 00.496-.438l.32-2.562H10.45a2.5 2.5 0 01-4.9 0H1.066zM3.81.563A1.5 1.5 0 014.98 0h6.04a1.5 1.5 0 011.17.563l3.7 4.625a.5.5 0 01-.78.624l-3.7-4.624A.5.5 0 0011.02 1H4.98a.5.5 0 00-.39.188L.89 5.812a.5.5 0 11-.78-.624L3.81.563z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M.125 5.17A.5.5 0 01.5 5H6a.5.5 0 01.5.5 1.5 1.5 0 003 0A.5.5 0 0110 5h5.5a.5.5 0 01.496.562l-.39 3.124A1.5 1.5 0 0114.117 10H1.883A1.5 1.5 0 01.394 8.686l-.39-3.124a.5.5 0 01.121-.393zm.941.83l.32 2.562A.5.5 0 001.884 9h12.234a.5.5 0 00.496-.438L14.933 6H10.45a2.5 2.5 0 01-4.9 0H1.066z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/info-circle-fill.svg b/src/assets/icons/info-circle-fill.svg
new file mode 100644
index 0000000..19c4fad
--- /dev/null
+++ b/src/assets/icons/info-circle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-info-circle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 16A8 8 0 108 0a8 8 0 000 16zm.93-9.412l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM8 5.5a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/info-circle.svg b/src/assets/icons/info-circle.svg
new file mode 100644
index 0000000..2f0405a
--- /dev/null
+++ b/src/assets/icons/info-circle.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-info-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+ <path d="M8.93 6.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588z"/>
+ <circle cx="8" cy="4.5" r="1"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/info-square-fill.svg b/src/assets/icons/info-square-fill.svg
new file mode 100644
index 0000000..65f554a
--- /dev/null
+++ b/src/assets/icons/info-square-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-info-square-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 2a2 2 0 012-2h12a2 2 0 012 2v12a2 2 0 01-2 2H2a2 2 0 01-2-2V2zm8.93 4.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM8 5.5a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/info-square.svg b/src/assets/icons/info-square.svg
new file mode 100644
index 0000000..9a446c7
--- /dev/null
+++ b/src/assets/icons/info-square.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-info-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path d="M8.93 6.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588z"/>
+ <circle cx="8" cy="4.5" r="1"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/info.svg b/src/assets/icons/info.svg
new file mode 100644
index 0000000..2bebd27
--- /dev/null
+++ b/src/assets/icons/info.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-info" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8.93 6.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588z"/>
+ <circle cx="8" cy="4.5" r="1"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/intersect.svg b/src/assets/icons/intersect.svg
new file mode 100644
index 0000000..355c7e2
--- /dev/null
+++ b/src/assets/icons/intersect.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-intersect" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 4v6.5a1.5 1.5 0 01-1.5 1.5H4V5.5A1.5 1.5 0 015.5 4H12z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M14.5 5h-9a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h9a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5zm-9-1A1.5 1.5 0 004 5.5v9A1.5 1.5 0 005.5 16h9a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 4h-9z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.5 1h-9a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h9a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5zm-9-1A1.5 1.5 0 000 1.5v9A1.5 1.5 0 001.5 12h9a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0010.5 0h-9z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/justify-left.svg b/src/assets/icons/justify-left.svg
new file mode 100644
index 0000000..2405fba
--- /dev/null
+++ b/src/assets/icons/justify-left.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-justify-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 12.5a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/justify-right.svg b/src/assets/icons/justify-right.svg
new file mode 100644
index 0000000..c134df6
--- /dev/null
+++ b/src/assets/icons/justify-right.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-justify-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6 12.5a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm-4-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/justify.svg b/src/assets/icons/justify.svg
new file mode 100644
index 0000000..ff5620d
--- /dev/null
+++ b/src/assets/icons/justify.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-justify" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 12.5a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/kanban-fill.svg b/src/assets/icons/kanban-fill.svg
new file mode 100644
index 0000000..4e7e586
--- /dev/null
+++ b/src/assets/icons/kanban-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-kanban-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.5 0a2 2 0 00-2 2v12a2 2 0 002 2h11a2 2 0 002-2V2a2 2 0 00-2-2h-11zm5 2a1 1 0 00-1 1v3a1 1 0 001 1h1a1 1 0 001-1V3a1 1 0 00-1-1h-1zm-5 1a1 1 0 011-1h1a1 1 0 011 1v7a1 1 0 01-1 1h-1a1 1 0 01-1-1V3zm9-1a1 1 0 00-1 1v10a1 1 0 001 1h1a1 1 0 001-1V3a1 1 0 00-1-1h-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/kanban.svg b/src/assets/icons/kanban.svg
new file mode 100644
index 0000000..347de4d
--- /dev/null
+++ b/src/assets/icons/kanban.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-kanban" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13.5 1h-11a1 1 0 00-1 1v12a1 1 0 001 1h11a1 1 0 001-1V2a1 1 0 00-1-1zm-11-1a2 2 0 00-2 2v12a2 2 0 002 2h11a2 2 0 002-2V2a2 2 0 00-2-2h-11z" clip-rule="evenodd"/>
+ <rect width="3" height="5" x="6.5" y="2" rx="1"/>
+ <rect width="3" height="9" x="2.5" y="2" rx="1"/>
+ <rect width="3" height="12" x="10.5" y="2" rx="1"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/laptop.svg b/src/assets/icons/laptop.svg
new file mode 100644
index 0000000..53efe73
--- /dev/null
+++ b/src/assets/icons/laptop.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-laptop" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13.5 3h-11a.5.5 0 00-.5.5V11h12V3.5a.5.5 0 00-.5-.5zm-11-1A1.5 1.5 0 001 3.5V12h14V3.5A1.5 1.5 0 0013.5 2h-11z" clip-rule="evenodd"/>
+ <path d="M0 12h16v.5a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 010 12.5V12z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layers-fill.svg b/src/assets/icons/layers-fill.svg
new file mode 100644
index 0000000..1708e4c
--- /dev/null
+++ b/src/assets/icons/layers-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layers-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.765 1.559a.5.5 0 01.47 0l7.5 4a.5.5 0 010 .882l-7.5 4a.5.5 0 01-.47 0l-7.5-4a.5.5 0 010-.882l7.5-4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.125 8.567l-1.86.992a.5.5 0 000 .882l7.5 4a.5.5 0 00.47 0l7.5-4a.5.5 0 000-.882l-1.86-.992-5.17 2.756a1.5 1.5 0 01-1.41 0l.418-.785-.419.785-5.169-2.756z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layers-half.svg b/src/assets/icons/layers-half.svg
new file mode 100644
index 0000000..98076b1
--- /dev/null
+++ b/src/assets/icons/layers-half.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layers-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.188 8L.264 9.559a.5.5 0 000 .882l7.5 4a.5.5 0 00.47 0l7.5-4a.5.5 0 000-.882L12.813 8l-4.578 2.441a.5.5 0 01-.47 0L3.188 8z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.765 1.559a.5.5 0 01.47 0l7.5 4a.5.5 0 010 .882l-7.5 4a.5.5 0 01-.47 0l-7.5-4a.5.5 0 010-.882l7.5-4zM1.563 6L8 9.433 14.438 6 8 2.567 1.562 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layers.svg b/src/assets/icons/layers.svg
new file mode 100644
index 0000000..e40dd82
--- /dev/null
+++ b/src/assets/icons/layers.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layers" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.188 8L.264 9.559a.5.5 0 000 .882l7.5 4a.5.5 0 00.47 0l7.5-4a.5.5 0 000-.882L12.813 8l-1.063.567L14.438 10 8 13.433 1.562 10 4.25 8.567 3.187 8z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.765 1.559a.5.5 0 01.47 0l7.5 4a.5.5 0 010 .882l-7.5 4a.5.5 0 01-.47 0l-7.5-4a.5.5 0 010-.882l7.5-4zM1.563 6L8 9.433 14.438 6 8 2.567 1.562 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-sidebar-inset-reverse.svg b/src/assets/icons/layout-sidebar-inset-reverse.svg
new file mode 100644
index 0000000..34d99a2
--- /dev/null
+++ b/src/assets/icons/layout-sidebar-inset-reverse.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-sidebar-inset-reverse" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 2h12a1 1 0 011 1v10a1 1 0 01-1 1H2a1 1 0 01-1-1V3a1 1 0 011-1zm12-1a2 2 0 012 2v10a2 2 0 01-2 2H2a2 2 0 01-2-2V3a2 2 0 012-2h12z" clip-rule="evenodd"/>
+ <path d="M13 4a1 1 0 00-1-1h-2a1 1 0 00-1 1v8a1 1 0 001 1h2a1 1 0 001-1V4z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-sidebar-inset.svg b/src/assets/icons/layout-sidebar-inset.svg
new file mode 100644
index 0000000..155771d
--- /dev/null
+++ b/src/assets/icons/layout-sidebar-inset.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-sidebar-inset" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 2H2a1 1 0 00-1 1v10a1 1 0 001 1h12a1 1 0 001-1V3a1 1 0 00-1-1zM2 1a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V3a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path d="M3 4a1 1 0 011-1h2a1 1 0 011 1v8a1 1 0 01-1 1H4a1 1 0 01-1-1V4z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-sidebar-reverse.svg b/src/assets/icons/layout-sidebar-reverse.svg
new file mode 100644
index 0000000..08e2b2d
--- /dev/null
+++ b/src/assets/icons/layout-sidebar-reverse.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-sidebar-reverse" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 2H2a1 1 0 00-1 1v10a1 1 0 001 1h12a1 1 0 001-1V3a1 1 0 00-1-1zM2 1a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V3a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11 14V2h1v12h-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-sidebar.svg b/src/assets/icons/layout-sidebar.svg
new file mode 100644
index 0000000..b6337f1
--- /dev/null
+++ b/src/assets/icons/layout-sidebar.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-sidebar" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 2H2a1 1 0 00-1 1v10a1 1 0 001 1h12a1 1 0 001-1V3a1 1 0 00-1-1zM2 1a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V3a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4 14V2h1v12H4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-split.svg b/src/assets/icons/layout-split.svg
new file mode 100644
index 0000000..3a43f75
--- /dev/null
+++ b/src/assets/icons/layout-split.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-split" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 2H2a1 1 0 00-1 1v10a1 1 0 001 1h12a1 1 0 001-1V3a1 1 0 00-1-1zM2 1a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V3a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.5 14V2h1v12h-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-text-sidebar-reverse.svg b/src/assets/icons/layout-text-sidebar-reverse.svg
new file mode 100644
index 0000000..45203eb
--- /dev/null
+++ b/src/assets/icons/layout-text-sidebar-reverse.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-text-sidebar-reverse" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 1h12a1 1 0 011 1v12a1 1 0 01-1 1H2a1 1 0 01-1-1V2a1 1 0 011-1zm12-1a2 2 0 012 2v12a2 2 0 01-2 2H2a2 2 0 01-2-2V2a2 2 0 012-2h12z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 15V1H4v14h1zm8-11.5a.5.5 0 00-.5-.5h-5a.5.5 0 000 1h5a.5.5 0 00.5-.5zm0 3a.5.5 0 00-.5-.5h-5a.5.5 0 000 1h5a.5.5 0 00.5-.5zm0 3a.5.5 0 00-.5-.5h-5a.5.5 0 000 1h5a.5.5 0 00.5-.5zm0 3a.5.5 0 00-.5-.5h-5a.5.5 0 000 1h5a.5.5 0 00.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-text-sidebar.svg b/src/assets/icons/layout-text-sidebar.svg
new file mode 100644
index 0000000..cc2b25e
--- /dev/null
+++ b/src/assets/icons/layout-text-sidebar.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-text-sidebar" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11 15V1h1v14h-1zM3 3.5a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-text-window-reverse.svg b/src/assets/icons/layout-text-window-reverse.svg
new file mode 100644
index 0000000..c4613d9
--- /dev/null
+++ b/src/assets/icons/layout-text-window-reverse.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-text-window-reverse" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 1h12a1 1 0 011 1v12a1 1 0 01-1 1H2a1 1 0 01-1-1V2a1 1 0 011-1zm12-1a2 2 0 012 2v12a2 2 0 01-2 2H2a2 2 0 01-2-2V2a2 2 0 012-2h12z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 15V4H4v11h1zM.5 4h15V3H.5v1zM13 6.5a.5.5 0 00-.5-.5h-5a.5.5 0 000 1h5a.5.5 0 00.5-.5zm0 3a.5.5 0 00-.5-.5h-5a.5.5 0 000 1h5a.5.5 0 00.5-.5zm0 3a.5.5 0 00-.5-.5h-5a.5.5 0 000 1h5a.5.5 0 00.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-text-window.svg b/src/assets/icons/layout-text-window.svg
new file mode 100644
index 0000000..6476795
--- /dev/null
+++ b/src/assets/icons/layout-text-window.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-text-window" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11 15V4h1v11h-1zm4.5-11H.5V3h15v1zM3 6.5a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h5a.5.5 0 010 1h-5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-three-columns.svg b/src/assets/icons/layout-three-columns.svg
new file mode 100644
index 0000000..adf8425
--- /dev/null
+++ b/src/assets/icons/layout-three-columns.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-layout-three-columns" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 2.5A1.5 1.5 0 011.5 1h13A1.5 1.5 0 0116 2.5v11a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 010 13.5v-11zM1.5 2a.5.5 0 00-.5.5v11a.5.5 0 00.5.5h13a.5.5 0 00.5-.5v-11a.5.5 0 00-.5-.5h-13z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 15V1h1v14H5zm5 0V1h1v14h-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/layout-wtf.svg b/src/assets/icons/layout-wtf.svg
new file mode 100644
index 0000000..2701121
--- /dev/null
+++ b/src/assets/icons/layout-wtf.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-layout-wtf" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5 1H1v8h4V1zM1 0a1 1 0 00-1 1v8a1 1 0 001 1h4a1 1 0 001-1V1a1 1 0 00-1-1H1zm13 2H9v5h5V2zM9 1a1 1 0 00-1 1v5a1 1 0 001 1h5a1 1 0 001-1V2a1 1 0 00-1-1H9zM5 13H3v2h2v-2zm-2-1a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1H3zm12-1H9v2h6v-2zm-6-1a1 1 0 00-1 1v2a1 1 0 001 1h6a1 1 0 001-1v-2a1 1 0 00-1-1H9z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/life-preserver.svg b/src/assets/icons/life-preserver.svg
new file mode 100644
index 0000000..6173bdf
--- /dev/null
+++ b/src/assets/icons/life-preserver.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-life-preserver" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 11a3 3 0 100-6 3 3 0 000 6zm0 1a4 4 0 100-8 4 4 0 000 8z" clip-rule="evenodd"/>
+ <path d="M11.642 6.343L15 5v6l-3.358-1.343A3.99 3.99 0 0012 8a3.99 3.99 0 00-.358-1.657zM9.657 4.358L11 1H5l1.343 3.358A3.985 3.985 0 018 4c.59 0 1.152.128 1.657.358zM4.358 6.343L1 5v6l3.358-1.343A3.985 3.985 0 014 8c0-.59.128-1.152.358-1.657zm1.985 5.299L5 15h6l-1.343-3.358A3.984 3.984 0 018 12a3.99 3.99 0 01-1.657-.358z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/lightning-fill.svg b/src/assets/icons/lightning-fill.svg
new file mode 100644
index 0000000..ed66628
--- /dev/null
+++ b/src/assets/icons/lightning-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-lightning-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.251.068a.5.5 0 01.227.58L9.677 6.5H13a.5.5 0 01.364.843l-8 8.5a.5.5 0 01-.842-.49L6.323 9.5H3a.5.5 0 01-.364-.843l8-8.5a.5.5 0 01.615-.09z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/lightning.svg b/src/assets/icons/lightning.svg
new file mode 100644
index 0000000..f9266af
--- /dev/null
+++ b/src/assets/icons/lightning.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-lightning" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.251.068a.5.5 0 01.227.58L9.677 6.5H13a.5.5 0 01.364.843l-8 8.5a.5.5 0 01-.842-.49L6.323 9.5H3a.5.5 0 01-.364-.843l8-8.5a.5.5 0 01.615-.09zM4.157 8.5H7a.5.5 0 01.478.647L6.11 13.59l5.732-6.09H9a.5.5 0 01-.478-.647L9.89 2.41 4.157 8.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/link-45deg.svg b/src/assets/icons/link-45deg.svg
new file mode 100644
index 0000000..5bfda63
--- /dev/null
+++ b/src/assets/icons/link-45deg.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-link-45deg" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4.715 6.542L3.343 7.914a3 3 0 104.243 4.243l1.828-1.829A3 3 0 008.586 5.5L8 6.086a1.001 1.001 0 00-.154.199 2 2 0 01.861 3.337L6.88 11.45a2 2 0 11-2.83-2.83l.793-.792a4.018 4.018 0 01-.128-1.287z"/>
+ <path d="M5.712 6.96l.167-.167a1.99 1.99 0 01.896-.518 1.99 1.99 0 01.518-.896l.167-.167A3.004 3.004 0 006 5.499c-.22.46-.316.963-.288 1.46z"/>
+ <path d="M6.586 4.672A3 3 0 007.414 9.5l.775-.776a2 2 0 01-.896-3.346L9.12 3.55a2 2 0 012.83 2.83l-.793.792c.112.42.155.855.128 1.287l1.372-1.372a3 3 0 00-4.243-4.243L6.586 4.672z"/>
+ <path d="M10 9.5a2.99 2.99 0 00.288-1.46l-.167.167a1.99 1.99 0 01-.896.518 1.99 1.99 0 01-.518.896l-.167.167A3.004 3.004 0 0010 9.501z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/link.svg b/src/assets/icons/link.svg
new file mode 100644
index 0000000..0ed8293
--- /dev/null
+++ b/src/assets/icons/link.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-link" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M6.354 5.5H4a3 3 0 000 6h3a3 3 0 002.83-4H9c-.086 0-.17.01-.25.031A2 2 0 017 10.5H4a2 2 0 110-4h1.535c.218-.376.495-.714.82-1z"/>
+ <path d="M6.764 6.5H7c.364 0 .706.097 1 .268A1.99 1.99 0 019 6.5h.236A3.004 3.004 0 008 5.67a3 3 0 00-1.236.83z"/>
+ <path d="M9 5.5a3 3 0 00-2.83 4h1.098A2 2 0 019 6.5h3a2 2 0 110 4h-1.535a4.02 4.02 0 01-.82 1H12a3 3 0 100-6H9z"/>
+ <path d="M8 11.33a3.01 3.01 0 001.236-.83H9a1.99 1.99 0 01-1-.268 1.99 1.99 0 01-1 .268h-.236c.332.371.756.66 1.236.83z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/list-check.svg b/src/assets/icons/list-check.svg
new file mode 100644
index 0000000..59b8cd0
--- /dev/null
+++ b/src/assets/icons/list-check.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-list-check" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5 11.5a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zm0-4a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zm0-4a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zM3.854 2.146a.5.5 0 010 .708l-1.5 1.5a.5.5 0 01-.708 0l-.5-.5a.5.5 0 11.708-.708L2 3.293l1.146-1.147a.5.5 0 01.708 0zm0 4a.5.5 0 010 .708l-1.5 1.5a.5.5 0 01-.708 0l-.5-.5a.5.5 0 11.708-.708L2 7.293l1.146-1.147a.5.5 0 01.708 0zm0 4a.5.5 0 010 .708l-1.5 1.5a.5.5 0 01-.708 0l-.5-.5a.5.5 0 01.708-.708l.146.147 1.146-1.147a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/list-nested.svg b/src/assets/icons/list-nested.svg
new file mode 100644
index 0000000..cdb5799
--- /dev/null
+++ b/src/assets/icons/list-nested.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-list-nested" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.5 11.5A.5.5 0 015 11h10a.5.5 0 010 1H5a.5.5 0 01-.5-.5zm-2-4A.5.5 0 013 7h10a.5.5 0 010 1H3a.5.5 0 01-.5-.5zm-2-4A.5.5 0 011 3h10a.5.5 0 010 1H1a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/list-ol.svg b/src/assets/icons/list-ol.svg
new file mode 100644
index 0000000..e7dd072
--- /dev/null
+++ b/src/assets/icons/list-ol.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-list-ol" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5 11.5a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zm0-4a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zm0-4a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path d="M1.713 11.865v-.474H2c.217 0 .363-.137.363-.317 0-.185-.158-.31-.361-.31-.223 0-.367.152-.373.31h-.59c.016-.467.373-.787.986-.787.588-.002.954.291.957.703a.595.595 0 01-.492.594v.033a.615.615 0 01.569.631c.003.533-.502.8-1.051.8-.656 0-1-.37-1.008-.794h.582c.008.178.186.306.422.309.254 0 .424-.145.422-.35-.002-.195-.155-.348-.414-.348h-.3zm-.004-4.699h-.604v-.035c0-.408.295-.844.958-.844.583 0 .96.326.96.756 0 .389-.257.617-.476.848l-.537.572v.03h1.054V9H1.143v-.395l.957-.99c.138-.142.293-.304.293-.508 0-.18-.147-.32-.342-.32a.33.33 0 00-.342.338v.041zM2.564 5h-.635V2.924h-.031l-.598.42v-.567l.629-.443h.635V5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/list-task.svg b/src/assets/icons/list-task.svg
new file mode 100644
index 0000000..2585227
--- /dev/null
+++ b/src/assets/icons/list-task.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-list-task" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 2.5a.5.5 0 00-.5.5v1a.5.5 0 00.5.5h1a.5.5 0 00.5-.5V3a.5.5 0 00-.5-.5H2zM3 3H2v1h1V3z" clip-rule="evenodd"/>
+ <path d="M5 3.5a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zM5.5 7a.5.5 0 000 1h9a.5.5 0 000-1h-9zm0 4a.5.5 0 000 1h9a.5.5 0 000-1h-9z"/>
+ <path fill-rule="evenodd" d="M1.5 7a.5.5 0 01.5-.5h1a.5.5 0 01.5.5v1a.5.5 0 01-.5.5H2a.5.5 0 01-.5-.5V7zM2 7h1v1H2V7zm0 3.5a.5.5 0 00-.5.5v1a.5.5 0 00.5.5h1a.5.5 0 00.5-.5v-1a.5.5 0 00-.5-.5H2zm1 .5H2v1h1v-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/list-ul.svg b/src/assets/icons/list-ul.svg
new file mode 100644
index 0000000..afbfc7f
--- /dev/null
+++ b/src/assets/icons/list-ul.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-list-ul" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5 11.5a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zm0-4a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zm0-4a.5.5 0 01.5-.5h9a.5.5 0 010 1h-9a.5.5 0 01-.5-.5zm-3 1a1 1 0 100-2 1 1 0 000 2zm0 4a1 1 0 100-2 1 1 0 000 2zm0 4a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/list.svg b/src/assets/icons/list.svg
new file mode 100644
index 0000000..8b8f4d4
--- /dev/null
+++ b/src/assets/icons/list.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-list" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.5 11.5A.5.5 0 013 11h10a.5.5 0 010 1H3a.5.5 0 01-.5-.5zm0-4A.5.5 0 013 7h10a.5.5 0 010 1H3a.5.5 0 01-.5-.5zm0-4A.5.5 0 013 3h10a.5.5 0 010 1H3a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/lock-fill.svg b/src/assets/icons/lock-fill.svg
new file mode 100644
index 0000000..3501f31
--- /dev/null
+++ b/src/assets/icons/lock-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-lock-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <rect width="11" height="9" x="2.5" y="7" rx="2"/>
+ <path fill-rule="evenodd" d="M4.5 4a3.5 3.5 0 117 0v3h-1V4a2.5 2.5 0 00-5 0v3h-1V4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/lock.svg b/src/assets/icons/lock.svg
new file mode 100644
index 0000000..8cb3776
--- /dev/null
+++ b/src/assets/icons/lock.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-lock" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.5 8h-7a1 1 0 00-1 1v5a1 1 0 001 1h7a1 1 0 001-1V9a1 1 0 00-1-1zm-7-1a2 2 0 00-2 2v5a2 2 0 002 2h7a2 2 0 002-2V9a2 2 0 00-2-2h-7zm0-3a3.5 3.5 0 117 0v3h-1V4a2.5 2.5 0 00-5 0v3h-1V4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/map.svg b/src/assets/icons/map.svg
new file mode 100644
index 0000000..73a9932
--- /dev/null
+++ b/src/assets/icons/map.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-map" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M15.817.613A.5.5 0 0116 1v13a.5.5 0 01-.402.49l-5 1a.502.502 0 01-.196 0L5.5 14.51l-4.902.98A.5.5 0 010 15V2a.5.5 0 01.402-.49l5-1a.5.5 0 01.196 0l4.902.98 4.902-.98a.5.5 0 01.415.103zM10 2.41l-4-.8v11.98l4 .8V2.41zm1 11.98l4-.8V1.61l-4 .8v11.98zm-6-.8V1.61l-4 .8v11.98l4-.8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/mic-fill.svg b/src/assets/icons/mic-fill.svg
new file mode 100644
index 0000000..2abf899
--- /dev/null
+++ b/src/assets/icons/mic-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-mic-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5 3a3 3 0 016 0v5a3 3 0 01-6 0V3z"/>
+ <path fill-rule="evenodd" d="M3.5 6.5A.5.5 0 014 7v1a4 4 0 008 0V7a.5.5 0 011 0v1a5 5 0 01-4.5 4.975V15h3a.5.5 0 010 1h-7a.5.5 0 010-1h3v-2.025A5 5 0 013 8V7a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/mic-mute-fill.svg b/src/assets/icons/mic-mute-fill.svg
new file mode 100644
index 0000000..79fb6ce
--- /dev/null
+++ b/src/assets/icons/mic-mute-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-mic-mute-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12.734 9.613A4.995 4.995 0 0013 8V7a.5.5 0 00-1 0v1c0 .274-.027.54-.08.799l.814.814zm-2.522 1.72A4 4 0 014 8V7a.5.5 0 00-1 0v1a5 5 0 004.5 4.975V15h-3a.5.5 0 000 1h7a.5.5 0 000-1h-3v-2.025a4.973 4.973 0 002.43-.923l-.718-.719zM11 7.88V3a3 3 0 00-5.842-.963L11 7.879zM5 6.12l4.486 4.486A3 3 0 015 8V6.121z" clip-rule="evenodd"/>
+ <path stroke="#000" d="M2 1l12 12"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/mic-mute.svg b/src/assets/icons/mic-mute.svg
new file mode 100644
index 0000000..931362f
--- /dev/null
+++ b/src/assets/icons/mic-mute.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-mic-mute" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12.734 9.613A4.995 4.995 0 0013 8V7a.5.5 0 00-1 0v1c0 .274-.027.54-.08.799l.814.814zm-2.522 1.72A4 4 0 014 8V7a.5.5 0 00-1 0v1a5 5 0 004.5 4.975V15h-3a.5.5 0 000 1h7a.5.5 0 000-1h-3v-2.025a4.973 4.973 0 002.43-.923l-.718-.719zM11 7.88V3a3 3 0 00-5.842-.963l.845.845A2 2 0 0110 3v3.879l1 1zM8.738 9.86l.748.748A3 3 0 015 8V6.121l1 1V8a2 2 0 002.738 1.86z" clip-rule="evenodd"/>
+ <path stroke="#000" d="M2 1l12 12"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/mic.svg b/src/assets/icons/mic.svg
new file mode 100644
index 0000000..af2583d
--- /dev/null
+++ b/src/assets/icons/mic.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-mic" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.5 6.5A.5.5 0 014 7v1a4 4 0 008 0V7a.5.5 0 011 0v1a5 5 0 01-4.5 4.975V15h3a.5.5 0 010 1h-7a.5.5 0 010-1h3v-2.025A5 5 0 013 8V7a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10 8V3a2 2 0 10-4 0v5a2 2 0 104 0zM8 0a3 3 0 00-3 3v5a3 3 0 006 0V3a3 3 0 00-3-3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/moon.svg b/src/assets/icons/moon.svg
new file mode 100644
index 0000000..af7f0e0
--- /dev/null
+++ b/src/assets/icons/moon.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-moon" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14.53 10.53a7 7 0 01-9.058-9.058A7.003 7.003 0 008 15a7.002 7.002 0 006.53-4.47z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/music-note-beamed.svg b/src/assets/icons/music-note-beamed.svg
new file mode 100644
index 0000000..a074a68
--- /dev/null
+++ b/src/assets/icons/music-note-beamed.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-music-note-beamed" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M6 13c0 1.105-1.12 2-2.5 2S1 14.105 1 13c0-1.104 1.12-2 2.5-2s2.5.896 2.5 2zm9-2c0 1.105-1.12 2-2.5 2s-2.5-.895-2.5-2 1.12-2 2.5-2 2.5.895 2.5 2z"/>
+ <path fill-rule="evenodd" d="M14 11V2h1v9h-1zM6 3v10H5V3h1z" clip-rule="evenodd"/>
+ <path d="M5 2.905a1 1 0 01.9-.995l8-.8a1 1 0 011.1.995V3L5 4V2.905z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/music-note-list.svg b/src/assets/icons/music-note-list.svg
new file mode 100644
index 0000000..5abe83e
--- /dev/null
+++ b/src/assets/icons/music-note-list.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-music-note-list" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12 13c0 1.105-1.12 2-2.5 2S7 14.105 7 13s1.12-2 2.5-2 2.5.895 2.5 2z"/>
+ <path fill-rule="evenodd" d="M12 3v10h-1V3h1z" clip-rule="evenodd"/>
+ <path d="M11 2.82a1 1 0 01.804-.98l3-.6A1 1 0 0116 2.22V4l-5 1V2.82z"/>
+ <path fill-rule="evenodd" d="M0 11.5a.5.5 0 01.5-.5H4a.5.5 0 010 1H.5a.5.5 0 01-.5-.5zm0-4A.5.5 0 01.5 7H8a.5.5 0 010 1H.5a.5.5 0 01-.5-.5zm0-4A.5.5 0 01.5 3H8a.5.5 0 010 1H.5a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/music-note.svg b/src/assets/icons/music-note.svg
new file mode 100644
index 0000000..c197303
--- /dev/null
+++ b/src/assets/icons/music-note.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-music-note" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9 13c0 1.105-1.12 2-2.5 2S4 14.105 4 13s1.12-2 2.5-2 2.5.895 2.5 2z"/>
+ <path fill-rule="evenodd" d="M9 3v10H8V3h1z" clip-rule="evenodd"/>
+ <path d="M8 2.82a1 1 0 01.804-.98l3-.6A1 1 0 0113 2.22V4L8 5V2.82z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/music-player-fill.svg b/src/assets/icons/music-player-fill.svg
new file mode 100644
index 0000000..801c934
--- /dev/null
+++ b/src/assets/icons/music-player-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-music-player-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 2a2 2 0 012-2h8a2 2 0 012 2v12a2 2 0 01-2 2H4a2 2 0 01-2-2V2zm2 1a1 1 0 011-1h6a1 1 0 011 1v2.5a1 1 0 01-1 1H5a1 1 0 01-1-1V3zm7 8a3 3 0 11-6 0 3 3 0 016 0z" clip-rule="evenodd"/>
+ <circle cx="8" cy="11" r="1"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/music-player.svg b/src/assets/icons/music-player.svg
new file mode 100644
index 0000000..a259eb4
--- /dev/null
+++ b/src/assets/icons/music-player.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-music-player" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 1H4a1 1 0 00-1 1v12a1 1 0 001 1h8a1 1 0 001-1V2a1 1 0 00-1-1zM4 0a2 2 0 00-2 2v12a2 2 0 002 2h8a2 2 0 002-2V2a2 2 0 00-2-2H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11 3H5v3h6V3zM5 2a1 1 0 00-1 1v3a1 1 0 001 1h6a1 1 0 001-1V3a1 1 0 00-1-1H5zm3 11a2 2 0 100-4 2 2 0 000 4zm3-2a3 3 0 11-6 0 3 3 0 016 0z" clip-rule="evenodd"/>
+ <circle cx="8" cy="11" r="1"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/newspaper.svg b/src/assets/icons/newspaper.svg
new file mode 100644
index 0000000..da8b9f7
--- /dev/null
+++ b/src/assets/icons/newspaper.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-newspaper" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 2A1.5 1.5 0 011.5.5h11A1.5 1.5 0 0114 2v12a1.5 1.5 0 01-1.5 1.5h-11A1.5 1.5 0 010 14V2zm1.5-.5A.5.5 0 001 2v12a.5.5 0 00.5.5h11a.5.5 0 00.5-.5V2a.5.5 0 00-.5-.5h-11z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M15.5 3a.5.5 0 01.5.5V14a1.5 1.5 0 01-1.5 1.5h-3v-1h3a.5.5 0 00.5-.5V3.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path d="M2 3h10v2H2V3zm0 3h4v3H2V6zm0 4h4v1H2v-1zm0 2h4v1H2v-1zm5-6h2v1H7V6zm3 0h2v1h-2V6zM7 8h2v1H7V8zm3 0h2v1h-2V8zm-3 2h2v1H7v-1zm3 0h2v1h-2v-1zm-3 2h2v1H7v-1zm3 0h2v1h-2v-1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/octagon-fill.svg b/src/assets/icons/octagon-fill.svg
new file mode 100644
index 0000000..2b1d109
--- /dev/null
+++ b/src/assets/icons/octagon-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-octagon-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M11.107 0a.5.5 0 01.353.146l4.394 4.394a.5.5 0 01.146.353v6.214a.5.5 0 01-.146.353l-4.394 4.394a.5.5 0 01-.353.146H4.893a.5.5 0 01-.353-.146L.146 11.46A.5.5 0 010 11.107V4.893a.5.5 0 01.146-.353L4.54.146A.5.5 0 014.893 0h6.214z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/octagon-half.svg b/src/assets/icons/octagon-half.svg
new file mode 100644
index 0000000..ab629e5
--- /dev/null
+++ b/src/assets/icons/octagon-half.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-octagon-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4.893 16h3.214V0H4.893a.5.5 0 00-.353.146L.146 4.54A.5.5 0 000 4.893v6.214a.5.5 0 00.146.353l4.394 4.394a.5.5 0 00.353.146z"/>
+ <path fill-rule="evenodd" d="M4.54.146A.5.5 0 014.893 0h6.214a.5.5 0 01.353.146l4.394 4.394a.5.5 0 01.146.353v6.214a.5.5 0 01-.146.353l-4.394 4.394a.5.5 0 01-.353.146H4.893a.5.5 0 01-.353-.146L.146 11.46A.5.5 0 010 11.107V4.893a.5.5 0 01.146-.353L4.54.146zM5.1 1L1 5.1v5.8L5.1 15h5.8l4.1-4.1V5.1L10.9 1H5.1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/octagon.svg b/src/assets/icons/octagon.svg
new file mode 100644
index 0000000..3f44d7a
--- /dev/null
+++ b/src/assets/icons/octagon.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-octagon" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.54.146A.5.5 0 014.893 0h6.214a.5.5 0 01.353.146l4.394 4.394a.5.5 0 01.146.353v6.214a.5.5 0 01-.146.353l-4.394 4.394a.5.5 0 01-.353.146H4.893a.5.5 0 01-.353-.146L.146 11.46A.5.5 0 010 11.107V4.893a.5.5 0 01.146-.353L4.54.146zM5.1 1L1 5.1v5.8L5.1 15h5.8l4.1-4.1V5.1L10.9 1H5.1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/option.svg b/src/assets/icons/option.svg
new file mode 100644
index 0000000..3e9ca0e
--- /dev/null
+++ b/src/assets/icons/option.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-option" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 2.5a.5.5 0 01.5-.5h3.797a.5.5 0 01.439.26L11 13h3.5a.5.5 0 010 1h-3.797a.5.5 0 01-.439-.26L5 3H1.5a.5.5 0 01-.5-.5zm10 0a.5.5 0 01.5-.5h3a.5.5 0 010 1h-3a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/outlet.svg b/src/assets/icons/outlet.svg
new file mode 100644
index 0000000..c3a9349
--- /dev/null
+++ b/src/assets/icons/outlet.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-outlet" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.34 2.994c.275-.338.68-.494 1.074-.494h7.172c.393 0 .798.156 1.074.494.578.708 1.84 2.534 1.84 5.006 0 2.472-1.262 4.297-1.84 5.006-.276.338-.68.494-1.074.494H4.414c-.394 0-.799-.156-1.074-.494C2.762 12.297 1.5 10.472 1.5 8c0-2.472 1.262-4.297 1.84-5.006zm1.074.506a.376.376 0 00-.299.126C3.599 4.259 2.5 5.863 2.5 8c0 2.137 1.099 3.74 1.615 4.374.06.073.163.126.3.126h7.17c.137 0 .24-.053.3-.126.516-.633 1.615-2.237 1.615-4.374 0-2.137-1.099-3.74-1.615-4.374a.376.376 0 00-.3-.126h-7.17z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6 5.5a.5.5 0 01.5.5v1.5a.5.5 0 01-1 0V6a.5.5 0 01.5-.5zm4 0a.5.5 0 01.5.5v1.5a.5.5 0 01-1 0V6a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path d="M7 10v1h2v-1a1 1 0 00-2 0z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/paperclip.svg b/src/assets/icons/paperclip.svg
new file mode 100644
index 0000000..14716ad
--- /dev/null
+++ b/src/assets/icons/paperclip.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-paperclip" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.5 3a2.5 2.5 0 015 0v9a1.5 1.5 0 01-3 0V5a.5.5 0 011 0v7a.5.5 0 001 0V3a1.5 1.5 0 10-3 0v9a2.5 2.5 0 005 0V5a.5.5 0 011 0v7a3.5 3.5 0 11-7 0V3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pause-fill.svg b/src/assets/icons/pause-fill.svg
new file mode 100644
index 0000000..a8e02e0
--- /dev/null
+++ b/src/assets/icons/pause-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-pause-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5.5 3.5A1.5 1.5 0 017 5v6a1.5 1.5 0 01-3 0V5a1.5 1.5 0 011.5-1.5zm5 0A1.5 1.5 0 0112 5v6a1.5 1.5 0 01-3 0V5a1.5 1.5 0 011.5-1.5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pause.svg b/src/assets/icons/pause.svg
new file mode 100644
index 0000000..d46ba35
--- /dev/null
+++ b/src/assets/icons/pause.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-pause" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6 3.5a.5.5 0 01.5.5v8a.5.5 0 01-1 0V4a.5.5 0 01.5-.5zm4 0a.5.5 0 01.5.5v8a.5.5 0 01-1 0V4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pen.svg b/src/assets/icons/pen.svg
new file mode 100644
index 0000000..16fbd30
--- /dev/null
+++ b/src/assets/icons/pen.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-pen" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.707 13.707a1 1 0 01-.39.242l-3 1a1 1 0 01-1.266-1.265l1-3a1 1 0 01.242-.391L10.086 2.5a2 2 0 012.828 0l.586.586a2 2 0 010 2.828l-7.793 7.793zM3 11l7.793-7.793a1 1 0 011.414 0l.586.586a1 1 0 010 1.414L5 13l-3 1 1-3z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M9.854 2.56a.5.5 0 00-.708 0L5.854 5.855a.5.5 0 01-.708-.708L8.44 1.854a1.5 1.5 0 012.122 0l.293.292a.5.5 0 01-.707.708l-.293-.293z" clip-rule="evenodd"/>
+ <path d="M13.293 1.207a1 1 0 011.414 0l.03.03a1 1 0 01.03 1.383L13.5 4 12 2.5l1.293-1.293z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pencil-square.svg b/src/assets/icons/pencil-square.svg
new file mode 100644
index 0000000..15bd3a5
--- /dev/null
+++ b/src/assets/icons/pencil-square.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-pencil-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M15.502 1.94a.5.5 0 010 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 01.707 0l1.293 1.293zm-1.75 2.456l-2-2L4.939 9.21a.5.5 0 00-.121.196l-.805 2.414a.25.25 0 00.316.316l2.414-.805a.5.5 0 00.196-.12l6.813-6.814z"/>
+ <path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 002.5 15h11a1.5 1.5 0 001.5-1.5v-6a.5.5 0 00-1 0v6a.5.5 0 01-.5.5h-11a.5.5 0 01-.5-.5v-11a.5.5 0 01.5-.5H9a.5.5 0 000-1H2.5A1.5 1.5 0 001 2.5v11z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pencil.svg b/src/assets/icons/pencil.svg
new file mode 100644
index 0000000..cba81d4
--- /dev/null
+++ b/src/assets/icons/pencil.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-pencil" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.293 1.293a1 1 0 011.414 0l2 2a1 1 0 010 1.414l-9 9a1 1 0 01-.39.242l-3 1a1 1 0 01-1.266-1.265l1-3a1 1 0 01.242-.391l9-9zM12 2l2 2-9 9-3 1 1-3 9-9z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M12.146 6.354l-2.5-2.5.708-.708 2.5 2.5-.707.708zM3 10v.5a.5.5 0 00.5.5H4v.5a.5.5 0 00.5.5H5v.5a.5.5 0 00.5.5H6v-1.5a.5.5 0 00-.5-.5H5v-.5a.5.5 0 00-.5-.5H3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pentagon-fill.svg b/src/assets/icons/pentagon-fill.svg
new file mode 100644
index 0000000..0a609be
--- /dev/null
+++ b/src/assets/icons/pentagon-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-pentagon-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8 0l8 6.5-3 9.5H3L0 6.5 8 0z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pentagon-half.svg b/src/assets/icons/pentagon-half.svg
new file mode 100644
index 0000000..0f3ba39
--- /dev/null
+++ b/src/assets/icons/pentagon-half.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-pentagon-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 1.288V15h4.267l2.575-8.153L8 1.288zM16 6.5L8 0 0 6.5 3 16h10l3-9.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pentagon.svg b/src/assets/icons/pentagon.svg
new file mode 100644
index 0000000..483fb3d
--- /dev/null
+++ b/src/assets/icons/pentagon.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-pentagon" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 1.288l-6.842 5.56L3.733 15h8.534l2.575-8.153L8 1.288zM16 6.5L8 0 0 6.5 3 16h10l3-9.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/people-circle.svg b/src/assets/icons/people-circle.svg
new file mode 100644
index 0000000..0ac6882
--- /dev/null
+++ b/src/assets/icons/people-circle.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-people-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M13.468 12.37C12.758 11.226 11.195 10 8 10s-4.757 1.225-5.468 2.37A6.987 6.987 0 008 15a6.987 6.987 0 005.468-2.63z"/>
+ <path fill-rule="evenodd" d="M8 9a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 1a7 7 0 100 14A7 7 0 008 1zM0 8a8 8 0 1116 0A8 8 0 010 8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/people-fill.svg b/src/assets/icons/people-fill.svg
new file mode 100644
index 0000000..9c2f611
--- /dev/null
+++ b/src/assets/icons/people-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-people-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7 14s-1 0-1-1 1-4 5-4 5 3 5 4-1 1-1 1H7zm4-6a3 3 0 100-6 3 3 0 000 6zm-5.784 6A2.238 2.238 0 015 13c0-1.355.68-2.75 1.936-3.72A6.325 6.325 0 005 9c-4 0-5 3-5 4s1 1 1 1h4.216zM4.5 8a2.5 2.5 0 100-5 2.5 2.5 0 000 5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/people.svg b/src/assets/icons/people.svg
new file mode 100644
index 0000000..3f63e9f
--- /dev/null
+++ b/src/assets/icons/people.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-people" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M15 14s1 0 1-1-1-4-5-4-5 3-5 4 1 1 1 1h8zm-7.995-.944v-.002.002zM7.022 13h7.956a.274.274 0 00.014-.002l.008-.002c-.002-.264-.167-1.03-.76-1.72C13.688 10.629 12.718 10 11 10c-1.717 0-2.687.63-3.24 1.276-.593.69-.759 1.457-.76 1.72a1.05 1.05 0 00.022.004zm7.973.056v-.002.002zM11 7a2 2 0 100-4 2 2 0 000 4zm3-2a3 3 0 11-6 0 3 3 0 016 0zM6.936 9.28a5.88 5.88 0 00-1.23-.247A7.35 7.35 0 005 9c-4 0-5 3-5 4 0 .667.333 1 1 1h4.216A2.238 2.238 0 015 13c0-1.01.377-2.042 1.09-2.904.243-.294.526-.569.846-.816zM4.92 10c-1.668.02-2.615.64-3.16 1.276C1.163 11.97 1 12.739 1 13h3c0-1.045.323-2.086.92-3zM1.5 5.5a3 3 0 116 0 3 3 0 01-6 0zm3-2a2 2 0 100 4 2 2 0 000-4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-bounding-box.svg b/src/assets/icons/person-bounding-box.svg
new file mode 100644
index 0000000..3d7797f
--- /dev/null
+++ b/src/assets/icons/person-bounding-box.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-person-bounding-box" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 1a.5.5 0 00-.5.5v3a.5.5 0 01-1 0v-3A1.5 1.5 0 011.5 0h3a.5.5 0 010 1h-3zM11 .5a.5.5 0 01.5-.5h3A1.5 1.5 0 0116 1.5v3a.5.5 0 01-1 0v-3a.5.5 0 00-.5-.5h-3a.5.5 0 01-.5-.5zM.5 11a.5.5 0 01.5.5v3a.5.5 0 00.5.5h3a.5.5 0 010 1h-3A1.5 1.5 0 010 14.5v-3a.5.5 0 01.5-.5zm15 0a.5.5 0 01.5.5v3a1.5 1.5 0 01-1.5 1.5h-3a.5.5 0 010-1h3a.5.5 0 00.5-.5v-3a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-check-fill.svg b/src/assets/icons/person-check-fill.svg
new file mode 100644
index 0000000..65bde47
--- /dev/null
+++ b/src/assets/icons/person-check-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-person-check-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H1zm5-6a3 3 0 100-6 3 3 0 000 6zm9.854-2.854a.5.5 0 010 .708l-3 3a.5.5 0 01-.708 0l-1.5-1.5a.5.5 0 01.708-.708L12.5 7.793l2.646-2.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-check.svg b/src/assets/icons/person-check.svg
new file mode 100644
index 0000000..44d4f87
--- /dev/null
+++ b/src/assets/icons/person-check.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-person-check" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11 14s1 0 1-1-1-4-6-4-6 3-6 4 1 1 1 1h10zm-9.995-.944v-.002.002zM1.022 13h9.956a.274.274 0 00.014-.002l.008-.002c-.001-.246-.154-.986-.832-1.664C9.516 10.68 8.289 10 6 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664a1.05 1.05 0 00.022.004zm9.974.056v-.002.002zM6 7a2 2 0 100-4 2 2 0 000 4zm3-2a3 3 0 11-6 0 3 3 0 016 0zm6.854.146a.5.5 0 010 .708l-3 3a.5.5 0 01-.708 0l-1.5-1.5a.5.5 0 01.708-.708L12.5 7.793l2.646-2.647a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-dash-fill.svg b/src/assets/icons/person-dash-fill.svg
new file mode 100644
index 0000000..57198c6
--- /dev/null
+++ b/src/assets/icons/person-dash-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-person-dash-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H1zm5-6a3 3 0 100-6 3 3 0 000 6zm5-.5a.5.5 0 01.5-.5h4a.5.5 0 010 1h-4a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-dash.svg b/src/assets/icons/person-dash.svg
new file mode 100644
index 0000000..ea853c0
--- /dev/null
+++ b/src/assets/icons/person-dash.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-person-dash" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11 14s1 0 1-1-1-4-6-4-6 3-6 4 1 1 1 1h10zm-9.995-.944v-.002.002zM1.022 13h9.956a.274.274 0 00.014-.002l.008-.002c-.001-.246-.154-.986-.832-1.664C9.516 10.68 8.289 10 6 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664a1.05 1.05 0 00.022.004zm9.974.056v-.002.002zM6 7a2 2 0 100-4 2 2 0 000 4zm3-2a3 3 0 11-6 0 3 3 0 016 0zm2 2.5a.5.5 0 01.5-.5h4a.5.5 0 010 1h-4a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-fill.svg b/src/assets/icons/person-fill.svg
new file mode 100644
index 0000000..6f8af40
--- /dev/null
+++ b/src/assets/icons/person-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-person-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-lines-fill.svg b/src/assets/icons/person-lines-fill.svg
new file mode 100644
index 0000000..7c13fc8
--- /dev/null
+++ b/src/assets/icons/person-lines-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-person-lines-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H1zm5-6a3 3 0 100-6 3 3 0 000 6zm7 1.5a.5.5 0 01.5-.5h2a.5.5 0 010 1h-2a.5.5 0 01-.5-.5zm-2-3a.5.5 0 01.5-.5h4a.5.5 0 010 1h-4a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h4a.5.5 0 010 1h-4a.5.5 0 01-.5-.5zm2 9a.5.5 0 01.5-.5h2a.5.5 0 010 1h-2a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-plus-fill.svg b/src/assets/icons/person-plus-fill.svg
new file mode 100644
index 0000000..d1fa7e4
--- /dev/null
+++ b/src/assets/icons/person-plus-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-person-plus-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H1zm5-6a3 3 0 100-6 3 3 0 000 6zm7.5-3a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 010-1H13V5.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13 7.5a.5.5 0 01.5-.5h2a.5.5 0 010 1H14v1.5a.5.5 0 01-1 0v-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-plus.svg b/src/assets/icons/person-plus.svg
new file mode 100644
index 0000000..d26a4f2
--- /dev/null
+++ b/src/assets/icons/person-plus.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-person-plus" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11 14s1 0 1-1-1-4-6-4-6 3-6 4 1 1 1 1h10zm-9.995-.944v-.002.002zM1.022 13h9.956a.274.274 0 00.014-.002l.008-.002c-.001-.246-.154-.986-.832-1.664C9.516 10.68 8.289 10 6 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664a1.05 1.05 0 00.022.004zm9.974.056v-.002.002zM6 7a2 2 0 100-4 2 2 0 000 4zm3-2a3 3 0 11-6 0 3 3 0 016 0zm4.5 0a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 010-1H13V5.5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M13 7.5a.5.5 0 01.5-.5h2a.5.5 0 010 1H14v1.5a.5.5 0 01-1 0v-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person-square.svg b/src/assets/icons/person-square.svg
new file mode 100644
index 0000000..8388c2c
--- /dev/null
+++ b/src/assets/icons/person-square.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-person-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2 15v-1c0-1 1-4 6-4s6 3 6 4v1H2zm6-6a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/person.svg b/src/assets/icons/person.svg
new file mode 100644
index 0000000..d1d66bb
--- /dev/null
+++ b/src/assets/icons/person.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-person" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M13 14s1 0 1-1-1-4-6-4-6 3-6 4 1 1 1 1h10zm-9.995-.944v-.002.002zM3.022 13h9.956a.274.274 0 00.014-.002l.008-.002c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664a1.05 1.05 0 00.022.004zm9.974.056v-.002.002zM8 7a2 2 0 100-4 2 2 0 000 4zm3-2a3 3 0 11-6 0 3 3 0 016 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/phone-landscape.svg b/src/assets/icons/phone-landscape.svg
new file mode 100644
index 0000000..094f70a
--- /dev/null
+++ b/src/assets/icons/phone-landscape.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-phone-landscape" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 4.5v6a1 1 0 001 1h12a1 1 0 001-1v-6a1 1 0 00-1-1H2a1 1 0 00-1 1zm-1 6a2 2 0 002 2h12a2 2 0 002-2v-6a2 2 0 00-2-2H2a2 2 0 00-2 2v6z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M14 7.5a1 1 0 10-2 0 1 1 0 002 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/phone.svg b/src/assets/icons/phone.svg
new file mode 100644
index 0000000..a69c320
--- /dev/null
+++ b/src/assets/icons/phone.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-phone" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11 1H5a1 1 0 00-1 1v12a1 1 0 001 1h6a1 1 0 001-1V2a1 1 0 00-1-1zM5 0a2 2 0 00-2 2v12a2 2 0 002 2h6a2 2 0 002-2V2a2 2 0 00-2-2H5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 14a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pie-chart-fill.svg b/src/assets/icons/pie-chart-fill.svg
new file mode 100644
index 0000000..9dc2899
--- /dev/null
+++ b/src/assets/icons/pie-chart-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-pie-chart-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M15.985 8.5H8.207l-5.5 5.5a8 8 0 0013.277-5.5zM2 13.292A8 8 0 017.5.015v7.778l-5.5 5.5zM8.5.015V7.5h7.485A8.001 8.001 0 008.5.015z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pie-chart.svg b/src/assets/icons/pie-chart.svg
new file mode 100644
index 0000000..29964a2
--- /dev/null
+++ b/src/assets/icons/pie-chart.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-pie-chart" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.5 7.793V1h1v6.5H15v1H8.207l-4.853 4.854-.708-.708L7.5 7.793z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pip-fill.svg b/src/assets/icons/pip-fill.svg
new file mode 100644
index 0000000..29c216c
--- /dev/null
+++ b/src/assets/icons/pip-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-pip-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 2A1.5 1.5 0 000 3.5v9A1.5 1.5 0 001.5 14h13a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 2h-13zm7 6a.5.5 0 00-.5.5v3a.5.5 0 00.5.5h5a.5.5 0 00.5-.5v-3a.5.5 0 00-.5-.5h-5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/pip.svg b/src/assets/icons/pip.svg
new file mode 100644
index 0000000..45e4ee0
--- /dev/null
+++ b/src/assets/icons/pip.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-pip" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 3.5A1.5 1.5 0 011.5 2h13A1.5 1.5 0 0116 3.5v9a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 010 12.5v-9zM1.5 3a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h13a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5h-13z" clip-rule="evenodd"/>
+ <path d="M8 8.5a.5.5 0 01.5-.5h5a.5.5 0 01.5.5v3a.5.5 0 01-.5.5h-5a.5.5 0 01-.5-.5v-3z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/play-fill.svg b/src/assets/icons/play-fill.svg
new file mode 100644
index 0000000..1fe86bb
--- /dev/null
+++ b/src/assets/icons/play-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-play-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M11.596 8.697l-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 010 1.393z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/play.svg b/src/assets/icons/play.svg
new file mode 100644
index 0000000..4c81880
--- /dev/null
+++ b/src/assets/icons/play.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-play" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M10.804 8L5 4.633v6.734L10.804 8zm.792-.696a.802.802 0 010 1.392l-6.363 3.692C4.713 12.69 4 12.345 4 11.692V4.308c0-.653.713-.998 1.233-.696l6.363 3.692z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/plug.svg b/src/assets/icons/plug.svg
new file mode 100644
index 0000000..37dca62
--- /dev/null
+++ b/src/assets/icons/plug.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-plug" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 5h8v3a4 4 0 01-8 0V5z"/>
+ <path fill-rule="evenodd" d="M6 1.5a.5.5 0 01.5.5v3a.5.5 0 01-1 0V2a.5.5 0 01.5-.5zm4 0a.5.5 0 01.5.5v3a.5.5 0 01-1 0V2a.5.5 0 01.5-.5zM7.115 13.651c.256-.511.385-1.408.385-2.651h1c0 1.257-.121 2.36-.49 3.099-.191.381-.47.707-.87.877-.401.17-.845.15-1.298-.002-.961-.32-1.534-.175-1.851.046-.33.23-.491.615-.491.98h-1c0-.635.278-1.353.918-1.8.653-.456 1.58-.561 2.74-.174.297.099.478.078.592.03.115-.05.244-.161.365-.405z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/plus-circle-fill.svg b/src/assets/icons/plus-circle-fill.svg
new file mode 100644
index 0000000..29f87c2
--- /dev/null
+++ b/src/assets/icons/plus-circle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-plus-circle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8A8 8 0 110 8a8 8 0 0116 0zM8.5 4a.5.5 0 00-1 0v3.5H4a.5.5 0 000 1h3.5V12a.5.5 0 001 0V8.5H12a.5.5 0 000-1H8.5V4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/plus-circle.svg b/src/assets/icons/plus-circle.svg
new file mode 100644
index 0000000..1401699
--- /dev/null
+++ b/src/assets/icons/plus-circle.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-plus-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 3.5a.5.5 0 01.5.5v4a.5.5 0 01-.5.5H4a.5.5 0 010-1h3.5V4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.5 8a.5.5 0 01.5-.5h4a.5.5 0 010 1H8.5V12a.5.5 0 01-1 0V8z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/plus-square-fill.svg b/src/assets/icons/plus-square-fill.svg
new file mode 100644
index 0000000..9f4aaeb
--- /dev/null
+++ b/src/assets/icons/plus-square-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-plus-square-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2zm6.5 4a.5.5 0 00-1 0v3.5H4a.5.5 0 000 1h3.5V12a.5.5 0 001 0V8.5H12a.5.5 0 000-1H8.5V4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/plus-square.svg b/src/assets/icons/plus-square.svg
new file mode 100644
index 0000000..3eb747b
--- /dev/null
+++ b/src/assets/icons/plus-square.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-plus-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 3.5a.5.5 0 01.5.5v4a.5.5 0 01-.5.5H4a.5.5 0 010-1h3.5V4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.5 8a.5.5 0 01.5-.5h4a.5.5 0 010 1H8.5V12a.5.5 0 01-1 0V8z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/plus.svg b/src/assets/icons/plus.svg
new file mode 100644
index 0000000..42f32bc
--- /dev/null
+++ b/src/assets/icons/plus.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-plus" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 3.5a.5.5 0 01.5.5v4a.5.5 0 01-.5.5H4a.5.5 0 010-1h3.5V4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.5 8a.5.5 0 01.5-.5h4a.5.5 0 010 1H8.5V12a.5.5 0 01-1 0V8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/power.svg b/src/assets/icons/power.svg
new file mode 100644
index 0000000..0eb5968
--- /dev/null
+++ b/src/assets/icons/power.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-power" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.578 4.437a5 5 0 104.922.044l.5-.866a6 6 0 11-5.908-.053l.486.875z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.5 8V1h1v7h-1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/puzzle-fill.svg b/src/assets/icons/puzzle-fill.svg
new file mode 100644
index 0000000..aa96c45
--- /dev/null
+++ b/src/assets/icons/puzzle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-puzzle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.112 3.645A1.5 1.5 0 014.605 2H7a.5.5 0 01.5.5v.382c0 .696-.497 1.182-.872 1.469a.459.459 0 00-.115.118.113.113 0 00-.012.025L6.5 4.5v.003l.003.01c.004.01.014.028.036.053a.86.86 0 00.27.194C7.09 4.9 7.51 5 8 5c.492 0 .912-.1 1.19-.24a.86.86 0 00.271-.194.213.213 0 00.036-.054l.003-.01v-.008a.112.112 0 00-.012-.025.459.459 0 00-.115-.118c-.375-.287-.872-.773-.872-1.469V2.5A.5.5 0 019 2h2.395a1.5 1.5 0 011.493 1.645L12.645 6.5h.237c.195 0 .42-.147.675-.48.21-.274.528-.52.943-.52.568 0 .947.447 1.154.862C15.877 6.807 16 7.387 16 8s-.123 1.193-.346 1.638c-.207.415-.586.862-1.154.862-.415 0-.733-.246-.943-.52-.255-.333-.48-.48-.675-.48h-.237l.243 2.855A1.5 1.5 0 0111.395 14H9a.5.5 0 01-.5-.5v-.382c0-.696.497-1.182.872-1.469a.459.459 0 00.115-.118.113.113 0 00.012-.025L9.5 11.5v-.003l-.003-.01a.214.214 0 00-.036-.053.859.859 0 00-.27-.194C8.91 11.1 8.49 11 8 11c-.491 0-.912.1-1.19.24a.859.859 0 00-.271.194.214.214 0 00-.036.054l-.003.01v.002l.001.006a.113.113 0 00.012.025c.016.027.05.068.115.118.375.287.872.773.872 1.469v.382a.5.5 0 01-.5.5H4.605a1.5 1.5 0 01-1.493-1.645L3.356 9.5h-.238c-.195 0-.42.147-.675.48-.21.274-.528.52-.943.52-.568 0-.947-.447-1.154-.862C.123 9.193 0 8.613 0 8s.123-1.193.346-1.638C.553 5.947.932 5.5 1.5 5.5c.415 0 .733.246.943.52.255.333.48.48.675.48h.238l-.244-2.855z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/puzzle.svg b/src/assets/icons/puzzle.svg
new file mode 100644
index 0000000..1e8674b
--- /dev/null
+++ b/src/assets/icons/puzzle.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-puzzle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4.605 2.5V2v.5zM3.61 3.6l.498-.043V3.55l-.498.05zM7 2.5h.5A.5.5 0 007 2v.5zm-.676 1.454l.304.397-.304-.397zm3.352 0l-.304.397.304-.397zM9 2.5V2a.5.5 0 00-.5.5H9zm3.39 1.1l-.498-.05v.007l.498.043zM12.1 7l-.498-.043a.5.5 0 00.498.543V7zm1.854-.676l.397.304-.397-.304zm0 3.352l.397-.304-.397.304zM12.1 9v-.5a.5.5 0 00-.498.542L12.1 9zm.29 3.4l-.498.043v.007l.498-.05zM9 13.5h-.5a.5.5 0 00.5.5v-.5zm.676-1.454l-.304-.397.304.397zm-3.352 0l.304-.397-.304.397zM7 13.5v.5a.5.5 0 00.5-.5H7zm-2.395 0V13v.5zm-.995-1.1l.498.05v-.007L3.61 12.4zM3.9 9l.498.042A.5.5 0 003.9 8.5V9zm-1.854.676l-.397-.304.397.304zm0-3.352l-.397.304.397-.304zM3.9 7v.5a.5.5 0 00.498-.543L3.9 7zm.705-5a1.5 1.5 0 00-1.493 1.65l.995-.1A.5.5 0 014.605 3V2zM7 2H4.605v1H7V2zm.5.882V2.5h-1v.382h1zm-.872 1.469c.375-.287.872-.773.872-1.469h-1c0 .195-.147.42-.48.675l.608.794zM6.5 4.5l.001-.006a.113.113 0 01.012-.025.459.459 0 01.115-.118l-.608-.794c-.274.21-.52.528-.52.943h1zM8 5c-.491 0-.912-.1-1.19-.24a.86.86 0 01-.271-.194.213.213 0 01-.039-.063V4.5h-1c0 .568.447.947.862 1.154C6.807 5.877 7.387 6 8 6V5zm1.5-.5v.003a.213.213 0 01-.039.064.86.86 0 01-.27.193C8.91 4.9 8.49 5 8 5v1c.613 0 1.193-.123 1.638-.346.415-.207.862-.586.862-1.154h-1zm-.128-.15c.065.05.099.092.115.119.008.013.01.021.012.025L9.5 4.5h1c0-.415-.246-.733-.52-.943l-.608.794zM8.5 2.883c0 .696.497 1.182.872 1.469l.608-.794c-.333-.255-.48-.48-.48-.675h-1zm0-.382v.382h1V2.5h-1zm2.895-.5H9v1h2.395V2zm1.493 1.65A1.5 1.5 0 0011.395 2v1a.5.5 0 01.498.55l.995.1zm-.29 3.392l.29-3.4-.996-.085-.29 3.4.996.085zm.284-.542H12.1v1h.782v-1zm.675-.48c-.255.333-.48.48-.675.48v1c.696 0 1.182-.497 1.469-.872l-.794-.608zm.943-.52c-.415 0-.733.246-.943.52l.794.608a.459.459 0 01.118-.115.113.113 0 01.025-.012L14.5 6.5v-1zM16 8c0-.613-.123-1.193-.346-1.638-.207-.415-.586-.862-1.154-.862v1h.003l.01.003a.237.237 0 01.053.036.86.86 0 01.194.27c.14.28.24.7.24 1.191h1zm-1.5 2.5c.568 0 .947-.447 1.154-.862C15.877 9.193 16 8.613 16 8h-1c0 .491-.1.912-.24 1.19a.86.86 0 01-.194.271.214.214 0 01-.063.039H14.5v1zm-.943-.52c.21.274.528.52.943.52v-1l-.006-.001a.113.113 0 01-.025-.012.458.458 0 01-.118-.115l-.794.608zm-.675-.48c.195 0 .42.147.675.48l.794-.608c-.287-.375-.773-.872-1.469-.872v1zm-.782 0h.782v-1H12.1v1zm.788 2.858l-.29-3.4-.996.084.29 3.401.996-.085zM11.395 14a1.5 1.5 0 001.493-1.65l-.995.1a.5.5 0 01-.498.55v1zM9 14h2.395v-1H9v1zm.5-.5v-.382h-1v.382h1zm0-.382c0-.195.147-.42.48-.675l-.608-.794c-.375.287-.872.773-.872 1.469h1zm.48-.675c.274-.21.52-.528.52-.943h-1l-.001.006a.113.113 0 01-.012.025.459.459 0 01-.115.118l.608.794zm.52-.943c0-.568-.447-.947-.862-1.154C9.193 10.123 8.613 10 8 10v1c.492 0 .912.1 1.19.24.14.07.226.14.271.194a.214.214 0 01.039.063v.003h1zM8 10c-.613 0-1.193.123-1.638.346-.415.207-.862.586-.862 1.154h1v-.003l.003-.01a.214.214 0 01.036-.053.859.859 0 01.27-.194C7.09 11.1 7.51 11 8 11v-1zm-2.5 1.5c0 .415.246.733.52.943l.608-.794a.459.459 0 01-.115-.118.113.113 0 01-.012-.025L6.5 11.5h-1zm.52.943c.333.255.48.48.48.675h1c0-.696-.497-1.182-.872-1.469l-.608.794zm.48.675v.382h1v-.382h-1zM4.605 14H7v-1H4.605v1zm-1.493-1.65A1.5 1.5 0 004.605 14v-1a.5.5 0 01-.498-.55l-.995-.1zm.29-3.393l-.29 3.401.996.085.29-3.4-.996-.086zm-.284.543H3.9v-1h-.782v1zm-.675.48c.255-.333.48-.48.675-.48v-1c-.696 0-1.182.497-1.469.872l.794.608zm-.943.52c.415 0 .733-.246.943-.52l-.794-.608a.459.459 0 01-.118.115.112.112 0 01-.025.012L1.5 9.5v1zM0 8c0 .613.123 1.193.346 1.638.207.415.586.862 1.154.862v-1h-.003a.213.213 0 01-.064-.039.86.86 0 01-.193-.27C1.1 8.91 1 8.49 1 8H0zm1.5-2.5c-.568 0-.947.447-1.154.862C.123 6.807 0 7.387 0 8h1c0-.492.1-.912.24-1.19a.86.86 0 01.194-.271.213.213 0 01.063-.039H1.5v-1zm.943.52c-.21-.274-.528-.52-.943-.52v1l.006.001a.112.112 0 01.025.012c.027.016.068.05.118.115l.794-.608zm.675.48c-.195 0-.42-.147-.675-.48l-.794.608c.287.375.773.872 1.469.872v-1zm.782 0h-.782v1H3.9v-1zm-.788-2.858l.29 3.4.996-.085-.29-3.4-.996.085z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/question-circle-fill.svg b/src/assets/icons/question-circle-fill.svg
new file mode 100644
index 0000000..68e83f3
--- /dev/null
+++ b/src/assets/icons/question-circle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-question-circle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8A8 8 0 110 8a8 8 0 0116 0zM6.57 6.033H5.25C5.22 4.147 6.68 3.5 8.006 3.5c1.397 0 2.673.73 2.673 2.24 0 1.08-.635 1.594-1.244 2.057-.737.559-1.01.768-1.01 1.486v.355H7.117l-.007-.463c-.038-.927.495-1.498 1.168-1.987.59-.444.965-.736.965-1.371 0-.825-.628-1.168-1.314-1.168-.901 0-1.358.603-1.358 1.384zm1.251 6.443c-.584 0-1.009-.394-1.009-.927 0-.552.425-.94 1.01-.94.609 0 1.028.388 1.028.94 0 .533-.42.927-1.029.927z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/question-circle.svg b/src/assets/icons/question-circle.svg
new file mode 100644
index 0000000..088bb8c
--- /dev/null
+++ b/src/assets/icons/question-circle.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-question-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+ <path d="M5.25 6.033h1.32c0-.781.458-1.384 1.36-1.384.685 0 1.313.343 1.313 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.007.463h1.307v-.355c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.326 0-2.786.647-2.754 2.533zm1.562 5.516c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/question-diamond-fill.svg b/src/assets/icons/question-diamond-fill.svg
new file mode 100644
index 0000000..a5682eb
--- /dev/null
+++ b/src/assets/icons/question-diamond-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-question-diamond-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.05.435c-.58-.58-1.52-.58-2.1 0L.436 6.95c-.58.58-.58 1.519 0 2.098l6.516 6.516c.58.58 1.519.58 2.098 0l6.516-6.516c.58-.58.58-1.519 0-2.098L9.05.435zM6.57 6.033H5.25C5.22 4.147 6.68 3.5 8.006 3.5c1.397 0 2.673.73 2.673 2.24 0 1.08-.635 1.594-1.244 2.057-.737.559-1.01.768-1.01 1.486v.355H7.117l-.007-.463c-.038-.927.495-1.498 1.168-1.987.59-.444.965-.736.965-1.371 0-.825-.628-1.168-1.314-1.168-.901 0-1.358.603-1.358 1.384zm1.251 6.443c-.584 0-1.009-.394-1.009-.927 0-.552.425-.94 1.01-.94.609 0 1.028.388 1.028.94 0 .533-.42.927-1.029.927z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/question-diamond.svg b/src/assets/icons/question-diamond.svg
new file mode 100644
index 0000000..1864cc0
--- /dev/null
+++ b/src/assets/icons/question-diamond.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-question-diamond" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.95.435c.58-.58 1.52-.58 2.1 0l6.515 6.516c.58.58.58 1.519 0 2.098L9.05 15.565c-.58.58-1.519.58-2.098 0L.435 9.05a1.482 1.482 0 010-2.098L6.95.435zm1.4.7a.495.495 0 00-.7 0L1.134 7.65a.495.495 0 000 .7l6.516 6.516a.495.495 0 00.7 0l6.516-6.516a.495.495 0 000-.7L8.35 1.134z" clip-rule="evenodd"/>
+ <path d="M5.25 6.033h1.32c0-.781.458-1.384 1.36-1.384.685 0 1.313.343 1.313 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.007.463h1.307v-.355c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.326 0-2.786.647-2.754 2.533zm1.562 5.516c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/question-octagon-fill.svg b/src/assets/icons/question-octagon-fill.svg
new file mode 100644
index 0000000..9372b4f
--- /dev/null
+++ b/src/assets/icons/question-octagon-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-question-octagon-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.46.146A.5.5 0 0011.107 0H4.893a.5.5 0 00-.353.146L.146 4.54A.5.5 0 000 4.893v6.214a.5.5 0 00.146.353l4.394 4.394a.5.5 0 00.353.146h6.214a.5.5 0 00.353-.146l4.394-4.394a.5.5 0 00.146-.353V4.893a.5.5 0 00-.146-.353L11.46.146zM6.57 6.033H5.25C5.22 4.147 6.68 3.5 8.006 3.5c1.397 0 2.673.73 2.673 2.24 0 1.08-.635 1.594-1.244 2.057-.737.559-1.01.768-1.01 1.486v.355H7.117l-.007-.463c-.038-.927.495-1.498 1.168-1.987.59-.444.965-.736.965-1.371 0-.825-.628-1.168-1.314-1.168-.901 0-1.358.603-1.358 1.384zm1.251 6.443c-.584 0-1.009-.394-1.009-.927 0-.552.425-.94 1.01-.94.609 0 1.028.388 1.028.94 0 .533-.42.927-1.029.927z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/question-octagon.svg b/src/assets/icons/question-octagon.svg
new file mode 100644
index 0000000..d538136
--- /dev/null
+++ b/src/assets/icons/question-octagon.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-question-octagon" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.54.146A.5.5 0 014.893 0h6.214a.5.5 0 01.353.146l4.394 4.394a.5.5 0 01.146.353v6.214a.5.5 0 01-.146.353l-4.394 4.394a.5.5 0 01-.353.146H4.893a.5.5 0 01-.353-.146L.146 11.46A.5.5 0 010 11.107V4.893a.5.5 0 01.146-.353L4.54.146zM5.1 1L1 5.1v5.8L5.1 15h5.8l4.1-4.1V5.1L10.9 1H5.1z" clip-rule="evenodd"/>
+ <path d="M5.25 6.033h1.32c0-.781.458-1.384 1.36-1.384.685 0 1.313.343 1.313 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.007.463h1.307v-.355c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.326 0-2.786.647-2.754 2.533zm1.562 5.516c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/question-square-fill.svg b/src/assets/icons/question-square-fill.svg
new file mode 100644
index 0000000..d79e7c4
--- /dev/null
+++ b/src/assets/icons/question-square-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-question-square-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2zm4.57 6.033H5.25C5.22 4.147 6.68 3.5 8.006 3.5c1.397 0 2.673.73 2.673 2.24 0 1.08-.635 1.594-1.244 2.057-.737.559-1.01.768-1.01 1.486v.355H7.117l-.007-.463c-.038-.927.495-1.498 1.168-1.987.59-.444.965-.736.965-1.371 0-.825-.628-1.168-1.314-1.168-.901 0-1.358.603-1.358 1.384zm1.251 6.443c-.584 0-1.009-.394-1.009-.927 0-.552.425-.94 1.01-.94.609 0 1.028.388 1.028.94 0 .533-.42.927-1.029.927z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/question-square.svg b/src/assets/icons/question-square.svg
new file mode 100644
index 0000000..148baf0
--- /dev/null
+++ b/src/assets/icons/question-square.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-question-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path d="M5.25 6.033h1.32c0-.781.458-1.384 1.36-1.384.685 0 1.313.343 1.313 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.007.463h1.307v-.355c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.326 0-2.786.647-2.754 2.533zm1.562 5.516c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/question.svg b/src/assets/icons/question.svg
new file mode 100644
index 0000000..c14d18f
--- /dev/null
+++ b/src/assets/icons/question.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-question" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5.25 6.033h1.32c0-.781.458-1.384 1.36-1.384.685 0 1.313.343 1.313 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.007.463h1.307v-.355c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.326 0-2.786.647-2.754 2.533zm1.562 5.516c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/reply-all-fill.svg b/src/assets/icons/reply-all-fill.svg
new file mode 100644
index 0000000..d604c5c
--- /dev/null
+++ b/src/assets/icons/reply-all-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-reply-all-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8.079 11.9l4.568-3.281a.719.719 0 000-1.238L8.079 4.1A.716.716 0 007 4.719V6c-1.5 0-6 0-7 8 2.5-4.5 7-4 7-4v1.281c0 .56.606.898 1.079.62z"/>
+ <path fill-rule="evenodd" d="M10.868 4.293a.5.5 0 01.7-.106l3.993 2.94a1.147 1.147 0 010 1.946l-3.994 2.94a.5.5 0 01-.593-.805l4.012-2.954a.493.493 0 01.042-.028.147.147 0 000-.252.496.496 0 01-.042-.028l-4.012-2.954a.5.5 0 01-.106-.699z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/reply-all.svg b/src/assets/icons/reply-all.svg
new file mode 100644
index 0000000..ab43a5d
--- /dev/null
+++ b/src/assets/icons/reply-all.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-reply-all" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.002 5.013a.144.144 0 00-.202.134V6.3a.5.5 0 01-.5.5c-.667 0-2.013.005-3.3.822-.984.624-1.99 1.76-2.595 3.876C2.425 10.515 3.59 9.982 4.61 9.7a8.741 8.741 0 011.921-.306 7.403 7.403 0 01.798.008h.013l.005.001h.001L7.3 9.9l.05-.498a.5.5 0 01.45.498v1.153c0 .108.11.176.202.134l3.984-2.933a.494.494 0 01.042-.028.147.147 0 000-.252.494.494 0 01-.042-.028L8.002 5.013zM6.8 10.386a7.745 7.745 0 00-1.923.277c-1.326.368-2.896 1.201-3.94 3.08a.5.5 0 01-.933-.305c.464-3.71 1.886-5.662 3.46-6.66 1.245-.79 2.527-.942 3.336-.971v-.66a1.144 1.144 0 011.767-.96l3.994 2.94a1.147 1.147 0 010 1.946l-3.994 2.94a1.144 1.144 0 01-1.767-.96v-.667z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.868 4.293a.5.5 0 01.7-.106l3.993 2.94a1.147 1.147 0 010 1.946l-3.994 2.94a.5.5 0 01-.593-.805l4.012-2.954a.493.493 0 01.042-.028.147.147 0 000-.252.496.496 0 01-.042-.028l-4.012-2.954a.5.5 0 01-.106-.699z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/reply-fill.svg b/src/assets/icons/reply-fill.svg
new file mode 100644
index 0000000..771ecae
--- /dev/null
+++ b/src/assets/icons/reply-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-reply-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9.079 11.9l4.568-3.281a.719.719 0 000-1.238L9.079 4.1A.716.716 0 008 4.719V6c-1.5 0-6 0-7 8 2.5-4.5 7-4 7-4v1.281c0 .56.606.898 1.079.62z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/reply.svg b/src/assets/icons/reply.svg
new file mode 100644
index 0000000..a0aa84c
--- /dev/null
+++ b/src/assets/icons/reply.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-reply" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.502 5.013a.144.144 0 00-.202.134V6.3a.5.5 0 01-.5.5c-.667 0-2.013.005-3.3.822-.984.624-1.99 1.76-2.595 3.876C3.925 10.515 5.09 9.982 6.11 9.7a8.741 8.741 0 011.921-.306 7.403 7.403 0 01.798.008h.013l.005.001h.001L8.8 9.9l.05-.498a.5.5 0 01.45.498v1.153c0 .108.11.176.202.134l3.984-2.933a.494.494 0 01.042-.028.147.147 0 000-.252.494.494 0 01-.042-.028L9.502 5.013zM8.3 10.386a7.745 7.745 0 00-1.923.277c-1.326.368-2.896 1.201-3.94 3.08a.5.5 0 01-.933-.305c.464-3.71 1.886-5.662 3.46-6.66 1.245-.79 2.527-.942 3.336-.971v-.66a1.144 1.144 0 011.767-.96l3.994 2.94a1.147 1.147 0 010 1.946l-3.994 2.94a1.144 1.144 0 01-1.767-.96v-.667z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/screwdriver.svg b/src/assets/icons/screwdriver.svg
new file mode 100644
index 0000000..e54f112
--- /dev/null
+++ b/src/assets/icons/screwdriver.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-screwdriver" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 1l1-1 3.081 2.2a1 1 0 01.419.815v.07a1 1 0 00.293.708L10.5 9.5l.914-.305a1 1 0 011.023.242l3.356 3.356a1 1 0 010 1.414l-1.586 1.586a1 1 0 01-1.414 0l-3.356-3.356a1 1 0 01-.242-1.023L9.5 10.5 3.793 4.793a1 1 0 00-.707-.293h-.071a1 1 0 01-.814-.419L0 1zm11.354 9.646a.5.5 0 00-.708.708l3 3a.5.5 0 00.708-.708l-3-3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/search.svg b/src/assets/icons/search.svg
new file mode 100644
index 0000000..3c8e902
--- /dev/null
+++ b/src/assets/icons/search.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-search" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M10.442 10.442a1 1 0 011.415 0l3.85 3.85a1 1 0 01-1.414 1.415l-3.85-3.85a1 1 0 010-1.415z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6.5 12a5.5 5.5 0 100-11 5.5 5.5 0 000 11zM13 6.5a6.5 6.5 0 11-13 0 6.5 6.5 0 0113 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/server.svg b/src/assets/icons/server.svg
new file mode 100644
index 0000000..5c48cc6
--- /dev/null
+++ b/src/assets/icons/server.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-server" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M13 2c0-1.105-2.239-2-5-2S3 .895 3 2s2.239 2 5 2 5-.895 5-2z"/>
+ <path d="M13 3.75c-.322.24-.698.435-1.093.593C10.857 4.763 9.475 5 8 5s-2.857-.237-3.907-.657A4.881 4.881 0 013 3.75V6c0 1.105 2.239 2 5 2s5-.895 5-2V3.75z"/>
+ <path d="M13 7.75c-.322.24-.698.435-1.093.593C10.857 8.763 9.475 9 8 9s-2.857-.237-3.907-.657A4.881 4.881 0 013 7.75V10c0 1.105 2.239 2 5 2s5-.895 5-2V7.75z"/>
+ <path d="M13 11.75c-.322.24-.698.435-1.093.593-1.05.42-2.432.657-3.907.657s-2.857-.237-3.907-.657A4.883 4.883 0 013 11.75V14c0 1.105 2.239 2 5 2s5-.895 5-2v-2.25z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/shield-fill.svg b/src/assets/icons/shield-fill.svg
new file mode 100644
index 0000000..37b86ee
--- /dev/null
+++ b/src/assets/icons/shield-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-shield-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.187 1.025C6.23.749 7.337.5 8 .5c.662 0 1.77.249 2.813.525a61.09 61.09 0 012.772.815c.528.168.926.623 1.003 1.184.573 4.197-.756 7.307-2.367 9.365a11.191 11.191 0 01-2.418 2.3 6.942 6.942 0 01-1.007.586c-.27.124-.558.225-.796.225s-.526-.101-.796-.225a6.908 6.908 0 01-1.007-.586 11.192 11.192 0 01-2.417-2.3C2.167 10.331.839 7.221 1.412 3.024A1.454 1.454 0 012.415 1.84a61.11 61.11 0 012.772-.815z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/shield-lock-fill.svg b/src/assets/icons/shield-lock-fill.svg
new file mode 100644
index 0000000..fbef815
--- /dev/null
+++ b/src/assets/icons/shield-lock-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-shield-lock-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.187 1.025C6.23.749 7.337.5 8 .5c.662 0 1.77.249 2.813.525a61.09 61.09 0 012.772.815c.528.168.926.623 1.003 1.184.573 4.197-.756 7.307-2.367 9.365a11.191 11.191 0 01-2.418 2.3 6.942 6.942 0 01-1.007.586c-.27.124-.558.225-.796.225s-.526-.101-.796-.225a6.908 6.908 0 01-1.007-.586 11.192 11.192 0 01-2.417-2.3C2.167 10.331.839 7.221 1.412 3.024A1.454 1.454 0 012.415 1.84a61.11 61.11 0 012.772-.815zm3.328 6.884a1.5 1.5 0 10-1.06-.011.5.5 0 00-.044.136l-.333 2a.5.5 0 00.493.582h.835a.5.5 0 00.493-.585l-.347-2a.5.5 0 00-.037-.122z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/shield-lock.svg b/src/assets/icons/shield-lock.svg
new file mode 100644
index 0000000..f55d18e
--- /dev/null
+++ b/src/assets/icons/shield-lock.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-shield-lock" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.443 1.991a60.17 60.17 0 00-2.725.802.454.454 0 00-.315.366C1.87 7.056 3.1 9.9 4.567 11.773c.736.94 1.533 1.636 2.197 2.093.333.228.626.394.857.5.116.053.21.089.282.11A.73.73 0 008 14.5c.007-.001.038-.005.097-.023.072-.022.166-.058.282-.111.23-.106.525-.272.857-.5a10.197 10.197 0 002.197-2.093C12.9 9.9 14.13 7.056 13.597 3.159a.454.454 0 00-.315-.366c-.626-.2-1.682-.526-2.725-.802C9.491 1.71 8.51 1.5 8 1.5c-.51 0-1.49.21-2.557.491zm-.256-.966C6.23.749 7.337.5 8 .5c.662 0 1.77.249 2.813.525a61.09 61.09 0 012.772.815c.528.168.926.623 1.003 1.184.573 4.197-.756 7.307-2.367 9.365a11.191 11.191 0 01-2.418 2.3 6.942 6.942 0 01-1.007.586c-.27.124-.558.225-.796.225s-.526-.101-.796-.225a6.908 6.908 0 01-1.007-.586 11.192 11.192 0 01-2.417-2.3C2.167 10.331.839 7.221 1.412 3.024A1.454 1.454 0 012.415 1.84a61.11 61.11 0 012.772-.815z" clip-rule="evenodd"/>
+ <path d="M9.5 6.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"/>
+ <path d="M7.411 8.034a.5.5 0 01.493-.417h.156a.5.5 0 01.492.414l.347 2a.5.5 0 01-.493.585h-.835a.5.5 0 01-.493-.582l.333-2z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/shield-shaded.svg b/src/assets/icons/shield-shaded.svg
new file mode 100644
index 0000000..c165f8a
--- /dev/null
+++ b/src/assets/icons/shield-shaded.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-shield-shaded" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.443 1.991a60.17 60.17 0 00-2.725.802.454.454 0 00-.315.366C1.87 7.056 3.1 9.9 4.567 11.773c.736.94 1.533 1.636 2.197 2.093.333.228.626.394.857.5.116.053.21.089.282.11A.73.73 0 008 14.5c.007-.001.038-.005.097-.023.072-.022.166-.058.282-.111.23-.106.525-.272.857-.5a10.197 10.197 0 002.197-2.093C12.9 9.9 14.13 7.056 13.597 3.159a.454.454 0 00-.315-.366c-.626-.2-1.682-.526-2.725-.802C9.491 1.71 8.51 1.5 8 1.5c-.51 0-1.49.21-2.557.491zm-.256-.966C6.23.749 7.337.5 8 .5c.662 0 1.77.249 2.813.525a61.09 61.09 0 012.772.815c.528.168.926.623 1.003 1.184.573 4.197-.756 7.307-2.367 9.365a11.191 11.191 0 01-2.418 2.3 6.942 6.942 0 01-1.007.586c-.27.124-.558.225-.796.225s-.526-.101-.796-.225a6.908 6.908 0 01-1.007-.586 11.192 11.192 0 01-2.417-2.3C2.167 10.331.839 7.221 1.412 3.024A1.454 1.454 0 012.415 1.84a61.11 61.11 0 012.772-.815z" clip-rule="evenodd"/>
+ <path d="M8 2.25c.909 0 3.188.685 4.254 1.022a.94.94 0 01.656.773c.814 6.424-4.13 9.452-4.91 9.452V2.25z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/shield.svg b/src/assets/icons/shield.svg
new file mode 100644
index 0000000..8eb8067
--- /dev/null
+++ b/src/assets/icons/shield.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-shield" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.443 1.991a60.17 60.17 0 00-2.725.802.454.454 0 00-.315.366C1.87 7.056 3.1 9.9 4.567 11.773c.736.94 1.533 1.636 2.197 2.093.333.228.626.394.857.5.116.053.21.089.282.11A.73.73 0 008 14.5c.007-.001.038-.005.097-.023.072-.022.166-.058.282-.111.23-.106.525-.272.857-.5a10.197 10.197 0 002.197-2.093C12.9 9.9 14.13 7.056 13.597 3.159a.454.454 0 00-.315-.366c-.626-.2-1.682-.526-2.725-.802C9.491 1.71 8.51 1.5 8 1.5c-.51 0-1.49.21-2.557.491zm-.256-.966C6.23.749 7.337.5 8 .5c.662 0 1.77.249 2.813.525a61.09 61.09 0 012.772.815c.528.168.926.623 1.003 1.184.573 4.197-.756 7.307-2.367 9.365a11.191 11.191 0 01-2.418 2.3 6.942 6.942 0 01-1.007.586c-.27.124-.558.225-.796.225s-.526-.101-.796-.225a6.908 6.908 0 01-1.007-.586 11.192 11.192 0 01-2.417-2.3C2.167 10.331.839 7.221 1.412 3.024A1.454 1.454 0 012.415 1.84a61.11 61.11 0 012.772-.815z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/shift-fill.svg b/src/assets/icons/shift-fill.svg
new file mode 100644
index 0000000..27eeabf
--- /dev/null
+++ b/src/assets/icons/shift-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-shift-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.27 2.047a1 1 0 011.46 0l6.345 6.77c.6.638.146 1.683-.73 1.683H11.5v3a1 1 0 01-1 1h-5a1 1 0 01-1-1v-3H1.654C.78 10.5.326 9.455.924 8.816L7.27 2.047z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/shift.svg b/src/assets/icons/shift.svg
new file mode 100644
index 0000000..f83e962
--- /dev/null
+++ b/src/assets/icons/shift.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-shift" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.27 2.047a1 1 0 011.46 0l6.345 6.77c.6.638.146 1.683-.73 1.683H11.5v3a1 1 0 01-1 1h-5a1 1 0 01-1-1v-3H1.654C.78 10.5.326 9.455.924 8.816L7.27 2.047zM14.346 9.5L8 2.731 1.654 9.5H4.5a1 1 0 011 1v3h5v-3a1 1 0 011-1h2.846z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/shuffle.svg b/src/assets/icons/shuffle.svg
new file mode 100644
index 0000000..26c3edf
--- /dev/null
+++ b/src/assets/icons/shuffle.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-shuffle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12.646 1.146a.5.5 0 01.708 0l2.5 2.5a.5.5 0 010 .708l-2.5 2.5a.5.5 0 01-.708-.708L14.793 4l-2.147-2.146a.5.5 0 010-.708zm0 8a.5.5 0 01.708 0l2.5 2.5a.5.5 0 010 .708l-2.5 2.5a.5.5 0 01-.708-.708L14.793 12l-2.147-2.146a.5.5 0 010-.708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M0 4a.5.5 0 01.5-.5h2c3.053 0 4.564 2.258 5.856 4.226l.08.123c.636.97 1.224 1.865 1.932 2.539.718.682 1.538 1.112 2.632 1.112h2a.5.5 0 010 1h-2c-1.406 0-2.461-.57-3.321-1.388-.795-.755-1.441-1.742-2.055-2.679l-.105-.159C6.186 6.242 4.947 4.5 2.5 4.5h-2A.5.5 0 010 4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M0 12a.5.5 0 00.5.5h2c3.053 0 4.564-2.258 5.856-4.226l.08-.123c.636-.97 1.224-1.865 1.932-2.539C11.086 4.93 11.906 4.5 13 4.5h2a.5.5 0 000-1h-2c-1.406 0-2.461.57-3.321 1.388-.795.755-1.441 1.742-2.055 2.679l-.105.159C6.186 9.758 4.947 11.5 2.5 11.5h-2a.5.5 0 00-.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/skip-backward-fill.svg b/src/assets/icons/skip-backward-fill.svg
new file mode 100644
index 0000000..9fe8e24
--- /dev/null
+++ b/src/assets/icons/skip-backward-fill.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-skip-backward-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.5 3.5A.5.5 0 000 4v8a.5.5 0 001 0V4a.5.5 0 00-.5-.5z" clip-rule="evenodd"/>
+ <path d="M.904 8.697l6.363 3.692c.54.313 1.233-.066 1.233-.697V4.308c0-.63-.692-1.01-1.233-.696L.904 7.304a.802.802 0 000 1.393z"/>
+ <path d="M8.404 8.697l6.363 3.692c.54.313 1.233-.066 1.233-.697V4.308c0-.63-.693-1.01-1.233-.696L8.404 7.304a.802.802 0 000 1.393z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/skip-backward.svg b/src/assets/icons/skip-backward.svg
new file mode 100644
index 0000000..1ce8fe8
--- /dev/null
+++ b/src/assets/icons/skip-backward.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-skip-backward" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.5 3.5A.5.5 0 011 4v3.248l6.267-3.636c.52-.302 1.233.043 1.233.696v2.94l6.267-3.636c.52-.302 1.233.043 1.233.696v7.384c0 .653-.713.998-1.233.696L8.5 8.752v2.94c0 .653-.713.998-1.233.696L1 8.752V12a.5.5 0 01-1 0V4a.5.5 0 01.5-.5zm7 1.133L1.696 8 7.5 11.367V4.633zm7.5 0L9.196 8 15 11.367V4.633z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/skip-end-fill.svg b/src/assets/icons/skip-end-fill.svg
new file mode 100644
index 0000000..5e53762
--- /dev/null
+++ b/src/assets/icons/skip-end-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-skip-end-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 3.5a.5.5 0 01.5.5v8a.5.5 0 01-1 0V4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path d="M11.596 8.697l-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 010 1.393z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/skip-end.svg b/src/assets/icons/skip-end.svg
new file mode 100644
index 0000000..bf5835d
--- /dev/null
+++ b/src/assets/icons/skip-end.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-skip-end" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 3.5a.5.5 0 01.5.5v8a.5.5 0 01-1 0V4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M10.804 8L5 4.633v6.734L10.804 8zm.792-.696a.802.802 0 010 1.392l-6.363 3.692C4.713 12.69 4 12.345 4 11.692V4.308c0-.653.713-.998 1.233-.696l6.363 3.692z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/skip-forward-fill.svg b/src/assets/icons/skip-forward-fill.svg
new file mode 100644
index 0000000..0f5a014
--- /dev/null
+++ b/src/assets/icons/skip-forward-fill.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-skip-forward-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M15.5 3.5a.5.5 0 01.5.5v8a.5.5 0 01-1 0V4a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+ <path d="M7.596 8.697l-6.363 3.692C.693 12.702 0 12.322 0 11.692V4.308c0-.63.693-1.01 1.233-.696l6.363 3.692a.802.802 0 010 1.393z"/>
+ <path d="M15.096 8.697l-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.693-1.01 1.233-.696l6.363 3.692a.802.802 0 010 1.393z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/skip-forward.svg b/src/assets/icons/skip-forward.svg
new file mode 100644
index 0000000..7e131bf
--- /dev/null
+++ b/src/assets/icons/skip-forward.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-skip-forward" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M15.5 3.5a.5.5 0 01.5.5v8a.5.5 0 01-1 0V8.752l-6.267 3.636c-.52.302-1.233-.043-1.233-.696v-2.94l-6.267 3.636C.713 12.69 0 12.345 0 11.692V4.308c0-.653.713-.998 1.233-.696L7.5 7.248v-2.94c0-.653.713-.998 1.233-.696L15 7.248V4a.5.5 0 01.5-.5zM1 4.633v6.734L6.804 8 1 4.633zm7.5 0v6.734L14.304 8 8.5 4.633z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/skip-start-fill.svg b/src/assets/icons/skip-start-fill.svg
new file mode 100644
index 0000000..39062e1
--- /dev/null
+++ b/src/assets/icons/skip-start-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-skip-start-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.5 3.5A.5.5 0 004 4v8a.5.5 0 001 0V4a.5.5 0 00-.5-.5z" clip-rule="evenodd"/>
+ <path d="M4.903 8.697l6.364 3.692c.54.313 1.232-.066 1.232-.697V4.308c0-.63-.692-1.01-1.232-.696L4.903 7.304a.802.802 0 000 1.393z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/skip-start.svg b/src/assets/icons/skip-start.svg
new file mode 100644
index 0000000..a9e58bc
--- /dev/null
+++ b/src/assets/icons/skip-start.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-skip-start" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.5 3.5A.5.5 0 004 4v8a.5.5 0 001 0V4a.5.5 0 00-.5-.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5.696 8L11.5 4.633v6.734L5.696 8zm-.792-.696a.802.802 0 000 1.392l6.363 3.692c.52.302 1.233-.043 1.233-.696V4.308c0-.653-.713-.998-1.233-.696L4.904 7.304z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/slash-circle-fill.svg b/src/assets/icons/slash-circle-fill.svg
new file mode 100644
index 0000000..171514e
--- /dev/null
+++ b/src/assets/icons/slash-circle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-slash-circle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8A8 8 0 110 8a8 8 0 0116 0zm-4.146-3.146a.5.5 0 00-.708-.708l-7 7a.5.5 0 00.708.708l7-7z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/slash-circle.svg b/src/assets/icons/slash-circle.svg
new file mode 100644
index 0000000..82f92ef
--- /dev/null
+++ b/src/assets/icons/slash-circle.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-slash-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/slash-square-fill.svg b/src/assets/icons/slash-square-fill.svg
new file mode 100644
index 0000000..8e334a4
--- /dev/null
+++ b/src/assets/icons/slash-square-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-slash-square-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2zm9.854 4.854a.5.5 0 00-.708-.708l-7 7a.5.5 0 00.708.708l7-7z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/slash-square.svg b/src/assets/icons/slash-square.svg
new file mode 100644
index 0000000..0471b14
--- /dev/null
+++ b/src/assets/icons/slash-square.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-slash-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/slash.svg b/src/assets/icons/slash.svg
new file mode 100644
index 0000000..df26e8d
--- /dev/null
+++ b/src/assets/icons/slash.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-slash" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/sliders.svg b/src/assets/icons/sliders.svg
new file mode 100644
index 0000000..9fe265e
--- /dev/null
+++ b/src/assets/icons/sliders.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-sliders" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M0 0h16v16H0z"/>
+ <path fill-rule="evenodd" d="M14 3.5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zM11.5 5a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM7 8.5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zM4.5 10a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm9.5 3.5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zM11.5 15a1.5 1.5 0 100-3 1.5 1.5 0 000 3z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M9.5 4H0V3h9.5v1zM16 4h-2.5V3H16v1zM9.5 14H0v-1h9.5v1zm6.5 0h-2.5v-1H16v1zM6.5 9H16V8H6.5v1zM0 9h2.5V8H0v1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/soundwave.svg b/src/assets/icons/soundwave.svg
new file mode 100644
index 0000000..f119cac
--- /dev/null
+++ b/src/assets/icons/soundwave.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-soundwave" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path stroke="#000" stroke-linecap="round" d="M2.5 7v2m12-2v2m-2-3v4m-8-4v4m4-7.5v11m-2-9v7m4-7v7"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/speaker.svg b/src/assets/icons/speaker.svg
new file mode 100644
index 0000000..19570d3
--- /dev/null
+++ b/src/assets/icons/speaker.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-speaker" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M9 4a1 1 0 11-2 0 1 1 0 012 0zm-2.5 6.5a1.5 1.5 0 113 0 1.5 1.5 0 01-3 0z"/>
+ <path fill-rule="evenodd" d="M4 0a2 2 0 00-2 2v12a2 2 0 002 2h8a2 2 0 002-2V2a2 2 0 00-2-2H4zm6 4a2 2 0 11-4 0 2 2 0 014 0zM8 7a3.5 3.5 0 100 7 3.5 3.5 0 000-7z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/square-fill.svg b/src/assets/icons/square-fill.svg
new file mode 100644
index 0000000..d04fc18
--- /dev/null
+++ b/src/assets/icons/square-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-square-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <rect width="16" height="16" rx="2"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/square-half.svg b/src/assets/icons/square-half.svg
new file mode 100644
index 0000000..7058c5a
--- /dev/null
+++ b/src/assets/icons/square-half.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-square-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 1H2a1 1 0 00-1 1v12a1 1 0 001 1h6V1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/square.svg b/src/assets/icons/square.svg
new file mode 100644
index 0000000..4c40def
--- /dev/null
+++ b/src/assets/icons/square.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/star-fill.svg b/src/assets/icons/star-fill.svg
new file mode 100644
index 0000000..4bebff6
--- /dev/null
+++ b/src/assets/icons/star-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-star-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/star-half.svg b/src/assets/icons/star-half.svg
new file mode 100644
index 0000000..5f8896d
--- /dev/null
+++ b/src/assets/icons/star-half.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-star-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.354 5.119L7.538.792A.516.516 0 018 .5c.183 0 .366.097.465.292l2.184 4.327 4.898.696A.537.537 0 0116 6.32a.55.55 0 01-.17.445l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256a.519.519 0 01-.146.05c-.341.06-.668-.254-.6-.642l.83-4.73L.173 6.765a.55.55 0 01-.171-.403.59.59 0 01.084-.302.513.513 0 01.37-.245l4.898-.696zM8 12.027c.08 0 .16.018.232.056l3.686 1.894-.694-3.957a.564.564 0 01.163-.505l2.906-2.77-4.052-.576a.525.525 0 01-.393-.288L8.002 2.223 8 2.226v9.8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/star.svg b/src/assets/icons/star.svg
new file mode 100644
index 0000000..7e97a10
--- /dev/null
+++ b/src/assets/icons/star.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-star" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.523-3.356c.329-.314.158-.888-.283-.95l-4.898-.696L8.465.792a.513.513 0 00-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356-.83 4.73zm4.905-2.767l-3.686 1.894.694-3.957a.565.565 0 00-.163-.505L1.71 6.745l4.052-.576a.525.525 0 00.393-.288l1.847-3.658 1.846 3.658a.525.525 0 00.393.288l4.052.575-2.906 2.77a.564.564 0 00-.163.506l.694 3.957-3.686-1.894a.503.503 0 00-.461 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/stop-fill.svg b/src/assets/icons/stop-fill.svg
new file mode 100644
index 0000000..bbc00dc
--- /dev/null
+++ b/src/assets/icons/stop-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-stop-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5 3.5h6A1.5 1.5 0 0112.5 5v6a1.5 1.5 0 01-1.5 1.5H5A1.5 1.5 0 013.5 11V5A1.5 1.5 0 015 3.5z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/stop.svg b/src/assets/icons/stop.svg
new file mode 100644
index 0000000..b1887ee
--- /dev/null
+++ b/src/assets/icons/stop.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-stop" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.5 5A1.5 1.5 0 015 3.5h6A1.5 1.5 0 0112.5 5v6a1.5 1.5 0 01-1.5 1.5H5A1.5 1.5 0 013.5 11V5zM5 4.5a.5.5 0 00-.5.5v6a.5.5 0 00.5.5h6a.5.5 0 00.5-.5V5a.5.5 0 00-.5-.5H5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/stopwatch-fill.svg b/src/assets/icons/stopwatch-fill.svg
new file mode 100644
index 0000000..bf2f7ea
--- /dev/null
+++ b/src/assets/icons/stopwatch-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-stopwatch-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5.5.5A.5.5 0 016 0h4a.5.5 0 010 1H9v1.07A7.002 7.002 0 018 16 7 7 0 017 2.07V1H6a.5.5 0 01-.5-.5zm3 4.5a.5.5 0 00-1 0v3.5h-3a.5.5 0 000 1H8a.5.5 0 00.5-.5V5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/stopwatch.svg b/src/assets/icons/stopwatch.svg
new file mode 100644
index 0000000..652d60e
--- /dev/null
+++ b/src/assets/icons/stopwatch.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-stopwatch" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A6 6 0 108 3a6 6 0 000 12zm0 1A7 7 0 108 2a7 7 0 000 14z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 4.5a.5.5 0 01.5.5v4a.5.5 0 01-.5.5H4.5a.5.5 0 010-1h3V5a.5.5 0 01.5-.5zM5.5.5A.5.5 0 016 0h4a.5.5 0 010 1H6a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+ <path d="M7 1h2v2H7V1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/subtract.svg b/src/assets/icons/subtract.svg
new file mode 100644
index 0000000..bf18e96
--- /dev/null
+++ b/src/assets/icons/subtract.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-subtract" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 12v2.5A1.5 1.5 0 005.5 16h9a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0014.5 4H12v6.5a1.5 1.5 0 01-1.5 1.5H4z"/>
+ <path fill-rule="evenodd" d="M10.5 1h-9a.5.5 0 00-.5.5v9a.5.5 0 00.5.5h9a.5.5 0 00.5-.5v-9a.5.5 0 00-.5-.5zm-9-1A1.5 1.5 0 000 1.5v9A1.5 1.5 0 001.5 12h9a1.5 1.5 0 001.5-1.5v-9A1.5 1.5 0 0010.5 0h-9z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/sun.svg b/src/assets/icons/sun.svg
new file mode 100644
index 0000000..da87463
--- /dev/null
+++ b/src/assets/icons/sun.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-sun" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M3.5 8a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0z"/>
+ <path fill-rule="evenodd" d="M8.202.28a.25.25 0 00-.404 0l-.91 1.255a.25.25 0 01-.334.067L5.232.79a.25.25 0 00-.374.155l-.36 1.508a.25.25 0 01-.282.19l-1.532-.245a.25.25 0 00-.286.286l.244 1.532a.25.25 0 01-.189.282l-1.509.36a.25.25 0 00-.154.374l.812 1.322a.25.25 0 01-.067.333l-1.256.91a.25.25 0 000 .405l1.256.91a.25.25 0 01.067.334L.79 10.768a.25.25 0 00.154.374l1.51.36a.25.25 0 01.188.282l-.244 1.532a.25.25 0 00.286.286l1.532-.244a.25.25 0 01.282.189l.36 1.508a.25.25 0 00.374.155l1.322-.812a.25.25 0 01.333.067l.91 1.256a.25.25 0 00.405 0l.91-1.256a.25.25 0 01.334-.067l1.322.812a.25.25 0 00.374-.155l.36-1.508a.25.25 0 01.282-.19l1.532.245a.25.25 0 00.286-.286l-.244-1.532a.25.25 0 01.189-.282l1.508-.36a.25.25 0 00.155-.374l-.812-1.322a.25.25 0 01.067-.333l1.256-.91a.25.25 0 000-.405l-1.256-.91a.25.25 0 01-.067-.334l.812-1.322a.25.25 0 00-.155-.374l-1.508-.36a.25.25 0 01-.19-.282l.245-1.532a.25.25 0 00-.286-.286l-1.532.244a.25.25 0 01-.282-.189l-.36-1.508a.25.25 0 00-.374-.155l-1.322.812a.25.25 0 01-.333-.067L8.203.28zM8 2.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/table.svg b/src/assets/icons/table.svg
new file mode 100644
index 0000000..c095bb1
--- /dev/null
+++ b/src/assets/icons/table.svg
@@ -0,0 +1,7 @@
+<svg class="bi bi-table" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M15 4H1V3h14v1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M5 15.5v-14h1v14H5zm5 0v-14h1v14h-1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M15 8H1V7h14v1zm0 4H1v-1h14v1z" clip-rule="evenodd"/>
+ <path d="M0 2a2 2 0 012-2h12a2 2 0 012 2v2H0V2z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/tablet-landscape.svg b/src/assets/icons/tablet-landscape.svg
new file mode 100644
index 0000000..7a37894
--- /dev/null
+++ b/src/assets/icons/tablet-landscape.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-tablet-landscape" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1 4v8a1 1 0 001 1h12a1 1 0 001-1V4a1 1 0 00-1-1H2a1 1 0 00-1 1zm-1 8a2 2 0 002 2h12a2 2 0 002-2V4a2 2 0 00-2-2H2a2 2 0 00-2 2v8z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M14 8a1 1 0 10-2 0 1 1 0 002 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/tablet.svg b/src/assets/icons/tablet.svg
new file mode 100644
index 0000000..57e5a2e
--- /dev/null
+++ b/src/assets/icons/tablet.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-tablet" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M12 1H4a1 1 0 00-1 1v12a1 1 0 001 1h8a1 1 0 001-1V2a1 1 0 00-1-1zM4 0a2 2 0 00-2 2v12a2 2 0 002 2h8a2 2 0 002-2V2a2 2 0 00-2-2H4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 14a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/tag-fill.svg b/src/assets/icons/tag-fill.svg
new file mode 100644
index 0000000..11f5a40
--- /dev/null
+++ b/src/assets/icons/tag-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-tag-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 1a1 1 0 00-1 1v4.586a1 1 0 00.293.707l7 7a1 1 0 001.414 0l4.586-4.586a1 1 0 000-1.414l-7-7A1 1 0 006.586 1H2zm4 3.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/tag.svg b/src/assets/icons/tag.svg
new file mode 100644
index 0000000..4b37963
--- /dev/null
+++ b/src/assets/icons/tag.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-tag" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.5 2A1.5 1.5 0 012 .5h4.586a1.5 1.5 0 011.06.44l7 7a1.5 1.5 0 010 2.12l-4.585 4.586a1.5 1.5 0 01-2.122 0l-7-7A1.5 1.5 0 01.5 6.586V2zM2 1.5a.5.5 0 00-.5.5v4.586a.5.5 0 00.146.353l7 7a.5.5 0 00.708 0l4.585-4.585a.5.5 0 000-.708l-7-7a.5.5 0 00-.353-.146H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M2.5 4.5a2 2 0 114 0 2 2 0 01-4 0zm2-1a1 1 0 100 2 1 1 0 000-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/terminal-fill.svg b/src/assets/icons/terminal-fill.svg
new file mode 100644
index 0000000..fd015fb
--- /dev/null
+++ b/src/assets/icons/terminal-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-terminal-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 3a2 2 0 012-2h12a2 2 0 012 2v10a2 2 0 01-2 2H2a2 2 0 01-2-2V3zm9.5 5.5h-3a.5.5 0 000 1h3a.5.5 0 000-1zm-6.354-.354L4.793 6.5 3.146 4.854a.5.5 0 11.708-.708l2 2a.5.5 0 010 .708l-2 2a.5.5 0 01-.708-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/terminal.svg b/src/assets/icons/terminal.svg
new file mode 100644
index 0000000..5bfb77a
--- /dev/null
+++ b/src/assets/icons/terminal.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-terminal" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 2H2a1 1 0 00-1 1v10a1 1 0 001 1h12a1 1 0 001-1V3a1 1 0 00-1-1zM2 1a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V3a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M6 9a.5.5 0 01.5-.5h3a.5.5 0 010 1h-3A.5.5 0 016 9zM3.146 4.146a.5.5 0 01.708 0l2 2a.5.5 0 010 .708l-2 2a.5.5 0 11-.708-.708L4.793 6.5 3.146 4.854a.5.5 0 010-.708z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/text-center.svg b/src/assets/icons/text-center.svg
new file mode 100644
index 0000000..354e91a
--- /dev/null
+++ b/src/assets/icons/text-center.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-text-center" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 12.5a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm-2-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm2-3a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm-2-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/text-indent-left.svg b/src/assets/icons/text-indent-left.svg
new file mode 100644
index 0000000..7d56946
--- /dev/null
+++ b/src/assets/icons/text-indent-left.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-text-indent-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 3.5a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm.646 2.146a.5.5 0 01.708 0l2 2a.5.5 0 010 .708l-2 2a.5.5 0 01-.708-.708L4.293 8 2.646 6.354a.5.5 0 010-.708zM7 6.5a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5zm-5 3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/text-indent-right.svg b/src/assets/icons/text-indent-right.svg
new file mode 100644
index 0000000..630a92b
--- /dev/null
+++ b/src/assets/icons/text-indent-right.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-text-indent-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 3.5a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm10.646 2.146a.5.5 0 01.708.708L11.707 8l1.647 1.646a.5.5 0 01-.708.708l-2-2a.5.5 0 010-.708l2-2zM2 6.5a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h6a.5.5 0 010 1h-6a.5.5 0 01-.5-.5zm0 3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/text-left.svg b/src/assets/icons/text-left.svg
new file mode 100644
index 0000000..d121222
--- /dev/null
+++ b/src/assets/icons/text-left.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-text-left" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 12.5a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm0-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/text-right.svg b/src/assets/icons/text-right.svg
new file mode 100644
index 0000000..0d8b5a1
--- /dev/null
+++ b/src/assets/icons/text-right.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-text-right" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6 12.5a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm-4-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5zm4-3a.5.5 0 01.5-.5h7a.5.5 0 010 1h-7a.5.5 0 01-.5-.5zm-4-3a.5.5 0 01.5-.5h11a.5.5 0 010 1h-11a.5.5 0 01-.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/textarea-t.svg b/src/assets/icons/textarea-t.svg
new file mode 100644
index 0000000..73ee98d
--- /dev/null
+++ b/src/assets/icons/textarea-t.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-textarea-t" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 9a1 1 0 100-2 1 1 0 000 2zm0 1a2 2 0 100-4 2 2 0 000 4zM2 9a1 1 0 100-2 1 1 0 000 2zm0 1a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.5 2.5A1.5 1.5 0 013 1h10a1.5 1.5 0 011.5 1.5v4h-1v-4A.5.5 0 0013 2H3a.5.5 0 00-.5.5v4h-1v-4zm1 7v4a.5.5 0 00.5.5h10a.5.5 0 00.5-.5v-4h1v4A1.5 1.5 0 0113 15H3a1.5 1.5 0 01-1.5-1.5v-4h1z" clip-rule="evenodd"/>
+ <path d="M11.434 4H4.566L4.5 5.994h.386c.21-1.252.612-1.446 2.173-1.495l.343-.011v6.343c0 .537-.116.665-1.049.748V12h3.294v-.421c-.938-.083-1.054-.21-1.054-.748V4.488l.348.01c1.56.05 1.963.244 2.173 1.496h.386L11.434 4z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/textarea.svg b/src/assets/icons/textarea.svg
new file mode 100644
index 0000000..90f4fd0
--- /dev/null
+++ b/src/assets/icons/textarea.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-textarea" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 9a1 1 0 100-2 1 1 0 000 2zm0 1a2 2 0 100-4 2 2 0 000 4zM2 9a1 1 0 100-2 1 1 0 000 2zm0 1a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M1.5 2.5A1.5 1.5 0 013 1h10a1.5 1.5 0 011.5 1.5v4h-1v-4A.5.5 0 0013 2H3a.5.5 0 00-.5.5v4h-1v-4zm1 7v4a.5.5 0 00.5.5h10a.5.5 0 00.5-.5v-4h1v4A1.5 1.5 0 0113 15H3a1.5 1.5 0 01-1.5-1.5v-4h1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/three-dots-vertical.svg b/src/assets/icons/three-dots-vertical.svg
new file mode 100644
index 0000000..6c3c0af
--- /dev/null
+++ b/src/assets/icons/three-dots-vertical.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-three-dots-vertical" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/three-dots.svg b/src/assets/icons/three-dots.svg
new file mode 100644
index 0000000..6832611
--- /dev/null
+++ b/src/assets/icons/three-dots.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-three-dots" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3 9.5a1.5 1.5 0 110-3 1.5 1.5 0 010 3zm5 0a1.5 1.5 0 110-3 1.5 1.5 0 010 3zm5 0a1.5 1.5 0 110-3 1.5 1.5 0 010 3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/toggle-off.svg b/src/assets/icons/toggle-off.svg
new file mode 100644
index 0000000..f0c980d
--- /dev/null
+++ b/src/assets/icons/toggle-off.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-toggle-off" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11 4a4 4 0 010 8H8a4.992 4.992 0 002-4 4.992 4.992 0 00-2-4h3zm-6 8a4 4 0 110-8 4 4 0 010 8zM0 8a5 5 0 005 5h6a5 5 0 000-10H5a5 5 0 00-5 5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/toggle-on.svg b/src/assets/icons/toggle-on.svg
new file mode 100644
index 0000000..950ce6e
--- /dev/null
+++ b/src/assets/icons/toggle-on.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-toggle-on" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M5 3a5 5 0 000 10h6a5 5 0 000-10H5zm6 9a4 4 0 100-8 4 4 0 000 8z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/toggles.svg b/src/assets/icons/toggles.svg
new file mode 100644
index 0000000..0143460
--- /dev/null
+++ b/src/assets/icons/toggles.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-toggles" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.5 1h-7a2.5 2.5 0 000 5h7a2.5 2.5 0 000-5zm-7-1a3.5 3.5 0 100 7h7a3.5 3.5 0 100-7h-7zm0 9a3.5 3.5 0 100 7h7a3.5 3.5 0 100-7h-7zm7 6a2.5 2.5 0 100-5 2.5 2.5 0 000 5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 3.5a3.5 3.5 0 11-7 0 3.5 3.5 0 017 0zM4.5 6a2.5 2.5 0 100-5 2.5 2.5 0 000 5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/tools.svg b/src/assets/icons/tools.svg
new file mode 100644
index 0000000..bd149dc
--- /dev/null
+++ b/src/assets/icons/tools.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-tools" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M0 1l1-1 3.081 2.2a1 1 0 01.419.815v.07a1 1 0 00.293.708L10.5 9.5l.914-.305a1 1 0 011.023.242l3.356 3.356a1 1 0 010 1.414l-1.586 1.586a1 1 0 01-1.414 0l-3.356-3.356a1 1 0 01-.242-1.023L9.5 10.5 3.793 4.793a1 1 0 00-.707-.293h-.071a1 1 0 01-.814-.419L0 1zm11.354 9.646a.5.5 0 00-.708.708l3 3a.5.5 0 00.708-.708l-3-3z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M15.898 2.223a3.003 3.003 0 01-3.679 3.674L5.878 12.15a3 3 0 11-2.027-2.027l6.252-6.341A3 3 0 0113.778.1l-2.142 2.142L12 4l1.757.364 2.141-2.141zm-13.37 9.019L3.001 11l.471.242.529.026.287.445.445.287.026.529L5 13l-.242.471-.026.529-.445.287-.287.445-.529.026L3 15l-.471-.242L2 14.732l-.287-.445L1.268 14l-.026-.529L1 13l.242-.471.026-.529.445-.287.287-.445.529-.026z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/trash-fill.svg b/src/assets/icons/trash-fill.svg
new file mode 100644
index 0000000..d59714f
--- /dev/null
+++ b/src/assets/icons/trash-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-trash-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.5 1a1 1 0 00-1 1v1a1 1 0 001 1H3v9a2 2 0 002 2h6a2 2 0 002-2V4h.5a1 1 0 001-1V2a1 1 0 00-1-1H10a1 1 0 00-1-1H7a1 1 0 00-1 1H2.5zm3 4a.5.5 0 01.5.5v7a.5.5 0 01-1 0v-7a.5.5 0 01.5-.5zM8 5a.5.5 0 01.5.5v7a.5.5 0 01-1 0v-7A.5.5 0 018 5zm3 .5a.5.5 0 00-1 0v7a.5.5 0 001 0v-7z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/trash.svg b/src/assets/icons/trash.svg
new file mode 100644
index 0000000..148707e
--- /dev/null
+++ b/src/assets/icons/trash.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-trash" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5.5 5.5A.5.5 0 016 6v6a.5.5 0 01-1 0V6a.5.5 0 01.5-.5zm2.5 0a.5.5 0 01.5.5v6a.5.5 0 01-1 0V6a.5.5 0 01.5-.5zm3 .5a.5.5 0 00-1 0v6a.5.5 0 001 0V6z"/>
+ <path fill-rule="evenodd" d="M14.5 3a1 1 0 01-1 1H13v9a2 2 0 01-2 2H5a2 2 0 01-2-2V4h-.5a1 1 0 01-1-1V2a1 1 0 011-1H6a1 1 0 011-1h2a1 1 0 011 1h3.5a1 1 0 011 1v1zM4.118 4L4 4.059V13a1 1 0 001 1h6a1 1 0 001-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/trash2-fill.svg b/src/assets/icons/trash2-fill.svg
new file mode 100644
index 0000000..91720ae
--- /dev/null
+++ b/src/assets/icons/trash2-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-trash2-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M2.037 3.225l1.684 10.104A2 2 0 005.694 15h4.612a2 2 0 001.973-1.671l1.684-10.104C13.627 4.224 11.085 5 8 5c-3.086 0-5.627-.776-5.963-1.775z"/>
+ <path fill-rule="evenodd" d="M12.9 3c-.18-.14-.497-.307-.974-.466C10.967 2.214 9.58 2 8 2s-2.968.215-3.926.534c-.477.16-.795.327-.975.466.18.14.498.307.975.466C5.032 3.786 6.42 4 8 4s2.967-.215 3.926-.534c.477-.16.795-.327.975-.466zM8 5c3.314 0 6-.895 6-2s-2.686-2-6-2-6 .895-6 2 2.686 2 6 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/trash2.svg b/src/assets/icons/trash2.svg
new file mode 100644
index 0000000..3f10bac
--- /dev/null
+++ b/src/assets/icons/trash2.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-trash2" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3.18 4l1.528 9.164a1 1 0 00.986.836h4.612a1 1 0 00.986-.836L12.82 4H3.18zm.541 9.329A2 2 0 005.694 15h4.612a2 2 0 001.973-1.671L14 3H2l1.721 10.329z" clip-rule="evenodd"/>
+ <path d="M14 3c0 1.105-2.686 2-6 2s-6-.895-6-2 2.686-2 6-2 6 .895 6 2z"/>
+ <path fill-rule="evenodd" d="M12.9 3c-.18-.14-.497-.307-.974-.466C10.967 2.214 9.58 2 8 2s-2.968.215-3.926.534c-.477.16-.795.327-.975.466.18.14.498.307.975.466C5.032 3.786 6.42 4 8 4s2.967-.215 3.926-.534c.477-.16.795-.327.975-.466zM8 5c3.314 0 6-.895 6-2s-2.686-2-6-2-6 .895-6 2 2.686 2 6 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/triangle-fill.svg b/src/assets/icons/triangle-fill.svg
new file mode 100644
index 0000000..340f78a
--- /dev/null
+++ b/src/assets/icons/triangle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-triangle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.022 1.566a1.13 1.13 0 011.96 0l6.857 11.667c.457.778-.092 1.767-.98 1.767H1.144c-.889 0-1.437-.99-.98-1.767L7.022 1.566z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/triangle-half.svg b/src/assets/icons/triangle-half.svg
new file mode 100644
index 0000000..7a57956
--- /dev/null
+++ b/src/assets/icons/triangle-half.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-triangle-half" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.938 2.016a.146.146 0 00-.054.057L1.027 13.74a.176.176 0 00-.002.183c.016.03.037.05.054.06.015.01.034.017.066.017l6.857-.017V2a.13.13 0 00-.064.016zm1.044-.45a1.13 1.13 0 00-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/triangle.svg b/src/assets/icons/triangle.svg
new file mode 100644
index 0000000..584dcb5
--- /dev/null
+++ b/src/assets/icons/triangle.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-triangle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M7.938 2.016a.146.146 0 00-.054.057L1.027 13.74a.176.176 0 00-.002.183c.016.03.037.05.054.06.015.01.034.017.066.017h13.713a.12.12 0 00.066-.017.163.163 0 00.055-.06.176.176 0 00-.003-.183L8.12 2.073a.146.146 0 00-.054-.057A.13.13 0 008.002 2a.13.13 0 00-.064.016zm1.044-.45a1.13 1.13 0 00-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/trophy.svg b/src/assets/icons/trophy.svg
new file mode 100644
index 0000000..f4d39af
--- /dev/null
+++ b/src/assets/icons/trophy.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-trophy" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M3 1h10c-.495 3.467-.5 10-5 10S3.495 4.467 3 1zm0 15a1 1 0 011-1h8a1 1 0 011 1H3zm2-1a1 1 0 011-1h4a1 1 0 011 1H5z"/>
+ <path fill-rule="evenodd" d="M12.5 3a2 2 0 100 4 2 2 0 000-4zm-3 2a3 3 0 116 0 3 3 0 01-6 0zm-6-2a2 2 0 100 4 2 2 0 000-4zm-3 2a3 3 0 116 0 3 3 0 01-6 0z" clip-rule="evenodd"/>
+ <path d="M7 10h2v4H7v-4z"/>
+ <path d="M10 11c0 .552-.895 1-2 1s-2-.448-2-1 .895-1 2-1 2 .448 2 1z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/tv-fill.svg b/src/assets/icons/tv-fill.svg
new file mode 100644
index 0000000..d795769
--- /dev/null
+++ b/src/assets/icons/tv-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-tv-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.5 13.5A.5.5 0 013 13h10a.5.5 0 010 1H3a.5.5 0 01-.5-.5zM2 2h12s2 0 2 2v6s0 2-2 2H2s-2 0-2-2V4s0-2 2-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/tv.svg b/src/assets/icons/tv.svg
new file mode 100644
index 0000000..3ee75d5
--- /dev/null
+++ b/src/assets/icons/tv.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-tv" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2.5 13.5A.5.5 0 013 13h10a.5.5 0 010 1H3a.5.5 0 01-.5-.5zM13.991 3H2c-.325 0-.502.078-.602.145a.758.758 0 00-.254.302A1.46 1.46 0 001 4.01V10c0 .325.078.502.145.602.07.105.17.188.302.254a1.464 1.464 0 00.538.143L2.01 11H14c.325 0 .502-.078.602-.145a.758.758 0 00.254-.302 1.464 1.464 0 00.143-.538L15 9.99V4c0-.325-.078-.502-.145-.602a.757.757 0 00-.302-.254A1.46 1.46 0 0013.99 3zM14 2H2C0 2 0 4 0 4v6c0 2 2 2 2 2h12c2 0 2-2 2-2V4c0-2-2-2-2-2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/type-bold.svg b/src/assets/icons/type-bold.svg
new file mode 100644
index 0000000..7114746
--- /dev/null
+++ b/src/assets/icons/type-bold.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-type-bold" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8.21 13c2.106 0 3.412-1.087 3.412-2.823 0-1.306-.984-2.283-2.324-2.386v-.055a2.176 2.176 0 001.852-2.14c0-1.51-1.162-2.46-3.014-2.46H3.843V13H8.21zM5.908 4.674h1.696c.963 0 1.517.451 1.517 1.244 0 .834-.629 1.32-1.73 1.32H5.908V4.673zm0 6.788V8.598h1.73c1.217 0 1.88.492 1.88 1.415 0 .943-.643 1.449-1.832 1.449H5.907z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/type-h1.svg b/src/assets/icons/type-h1.svg
new file mode 100644
index 0000000..694c503
--- /dev/null
+++ b/src/assets/icons/type-h1.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-type-h1" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8.637 13V3.669H7.379V7.62H2.758V3.67H1.5V13h1.258V8.728h4.62V13h1.259zm5.329 0V3.669h-1.244L10.5 5.316v1.265l2.16-1.565h.062V13h1.244z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/type-h2.svg b/src/assets/icons/type-h2.svg
new file mode 100644
index 0000000..7837598
--- /dev/null
+++ b/src/assets/icons/type-h2.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-type-h2" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M7.638 13V3.669H6.38V7.62H1.759V3.67H.5V13h1.258V8.728h4.62V13h1.259zm3.022-6.733v-.048c0-.889.63-1.668 1.716-1.668.957 0 1.675.608 1.675 1.572 0 .855-.554 1.504-1.067 2.085l-3.513 3.999V13H15.5v-1.094h-4.245v-.075l2.481-2.844c.875-.998 1.586-1.784 1.586-2.953 0-1.463-1.155-2.556-2.919-2.556-1.941 0-2.966 1.326-2.966 2.74v.049h1.223z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/type-h3.svg b/src/assets/icons/type-h3.svg
new file mode 100644
index 0000000..f4f3754
--- /dev/null
+++ b/src/assets/icons/type-h3.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-type-h3" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M7.637 13V3.669H6.379V7.62H1.758V3.67H.5V13h1.258V8.728h4.62V13h1.259zm3.625-4.272h1.018c1.142 0 1.935.67 1.949 1.674.013 1.005-.78 1.737-2.01 1.73-1.08-.007-1.853-.588-1.935-1.32H9.108c.069 1.327 1.224 2.386 3.083 2.386 1.935 0 3.343-1.155 3.309-2.789-.027-1.51-1.251-2.16-2.037-2.249v-.068c.704-.123 1.764-.91 1.723-2.229-.035-1.353-1.176-2.4-2.954-2.385-1.873.006-2.857 1.162-2.898 2.358h1.196c.062-.69.711-1.299 1.696-1.299.998 0 1.695.622 1.695 1.525.007.922-.718 1.592-1.695 1.592h-.964v1.074z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/type-italic.svg b/src/assets/icons/type-italic.svg
new file mode 100644
index 0000000..c5c3b50
--- /dev/null
+++ b/src/assets/icons/type-italic.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-type-italic" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M7.991 11.674L9.53 4.455c.123-.595.246-.71 1.347-.807l.11-.52H7.211l-.11.52c1.06.096 1.128.212 1.005.807L6.57 11.674c-.123.595-.246.71-1.346.806l-.11.52h3.774l.11-.52c-1.06-.095-1.129-.211-1.006-.806z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/type-strikethrough.svg b/src/assets/icons/type-strikethrough.svg
new file mode 100644
index 0000000..bb9e82b
--- /dev/null
+++ b/src/assets/icons/type-strikethrough.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-type-strikethrough" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8.527 13.164c-2.153 0-3.589-1.107-3.705-2.81h1.23c.144 1.06 1.129 1.703 2.544 1.703 1.34 0 2.31-.705 2.31-1.675 0-.827-.547-1.374-1.914-1.675L8.046 8.5h3.45c.468.437.675.994.675 1.697 0 1.826-1.436 2.967-3.644 2.967zM6.602 6.5H5.167a2.776 2.776 0 01-.099-.76c0-1.627 1.436-2.768 3.48-2.768 1.969 0 3.39 1.175 3.445 2.85h-1.23c-.11-1.08-.964-1.743-2.25-1.743-1.23 0-2.18.602-2.18 1.607 0 .31.083.581.27.814z"/>
+ <path fill-rule="evenodd" d="M15 8.5H1v-1h14v1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/type-underline.svg b/src/assets/icons/type-underline.svg
new file mode 100644
index 0000000..8bf1174
--- /dev/null
+++ b/src/assets/icons/type-underline.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-type-underline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5.313 3.136h-1.23V9.54c0 2.105 1.47 3.623 3.917 3.623s3.917-1.518 3.917-3.623V3.136h-1.23v6.323c0 1.49-.978 2.57-2.687 2.57-1.709 0-2.687-1.08-2.687-2.57V3.136z"/>
+ <path fill-rule="evenodd" d="M12.5 15h-9v-1h9v1z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/type.svg b/src/assets/icons/type.svg
new file mode 100644
index 0000000..22aafb4
--- /dev/null
+++ b/src/assets/icons/type.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-type" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M2.244 13.081l.943-2.803H6.66l.944 2.803H8.86L5.54 3.75H4.322L1 13.081h1.244zm2.7-7.923L6.34 9.314H3.51l1.4-4.156h.034zm9.146 7.027h.035v.896h1.128V8.125c0-1.51-1.114-2.345-2.646-2.345-1.736 0-2.59.916-2.666 2.174h1.108c.068-.718.595-1.19 1.517-1.19.971 0 1.518.52 1.518 1.464v.731H12.19c-1.647.007-2.522.8-2.522 2.058 0 1.319.957 2.18 2.345 2.18 1.06 0 1.716-.43 2.078-1.011zm-1.763.035c-.752 0-1.456-.397-1.456-1.244 0-.65.424-1.115 1.408-1.115h1.805v.834c0 .896-.752 1.525-1.757 1.525z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/union.svg b/src/assets/icons/union.svg
new file mode 100644
index 0000000..9d037c8
--- /dev/null
+++ b/src/assets/icons/union.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-union" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 5.5A1.5 1.5 0 015.5 4h9A1.5 1.5 0 0116 5.5v9a1.5 1.5 0 01-1.5 1.5h-9A1.5 1.5 0 014 14.5v-9z"/>
+ <path d="M0 1.5A1.5 1.5 0 011.5 0h9A1.5 1.5 0 0112 1.5v9a1.5 1.5 0 01-1.5 1.5h-9A1.5 1.5 0 010 10.5v-9z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/unlock-fill.svg b/src/assets/icons/unlock-fill.svg
new file mode 100644
index 0000000..c48ae8c
--- /dev/null
+++ b/src/assets/icons/unlock-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-unlock-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M.5 9a2 2 0 012-2h7a2 2 0 012 2v5a2 2 0 01-2 2h-7a2 2 0 01-2-2V9z"/>
+ <path fill-rule="evenodd" d="M8.5 4a3.5 3.5 0 117 0v3h-1V4a2.5 2.5 0 00-5 0v3h-1V4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/unlock.svg b/src/assets/icons/unlock.svg
new file mode 100644
index 0000000..fa99b7d
--- /dev/null
+++ b/src/assets/icons/unlock.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-unlock" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.655 8H2.333c-.264 0-.398.068-.471.121a.73.73 0 00-.224.296 1.626 1.626 0 00-.138.59V14c0 .342.076.531.14.635.064.106.151.18.256.237a1.122 1.122 0 00.436.127l.013.001h7.322c.264 0 .398-.068.471-.121a.73.73 0 00.224-.296 1.627 1.627 0 00.138-.59V9c0-.342-.076-.531-.14-.635a.658.658 0 00-.255-.237A1.122 1.122 0 009.655 8zm.012-1H2.333C.5 7 .5 9 .5 9v5c0 2 1.833 2 1.833 2h7.334c1.833 0 1.833-2 1.833-2V9c0-2-1.833-2-1.833-2zM8.5 4a3.5 3.5 0 117 0v3h-1V4a2.5 2.5 0 00-5 0v3h-1V4z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/upload.svg b/src/assets/icons/upload.svg
new file mode 100644
index 0000000..69707b7
--- /dev/null
+++ b/src/assets/icons/upload.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-upload" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.5 8a.5.5 0 01.5.5V12a1 1 0 001 1h12a1 1 0 001-1V8.5a.5.5 0 011 0V12a2 2 0 01-2 2H2a2 2 0 01-2-2V8.5A.5.5 0 01.5 8zM5 4.854a.5.5 0 00.707 0L8 2.56l2.293 2.293A.5.5 0 1011 4.146L8.354 1.5a.5.5 0 00-.708 0L5 4.146a.5.5 0 000 .708z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 2a.5.5 0 01.5.5v8a.5.5 0 01-1 0v-8A.5.5 0 018 2z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/view-list.svg b/src/assets/icons/view-list.svg
new file mode 100644
index 0000000..7b5f998
--- /dev/null
+++ b/src/assets/icons/view-list.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-view-list" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3 4.5h10a2 2 0 012 2v3a2 2 0 01-2 2H3a2 2 0 01-2-2v-3a2 2 0 012-2zm0 1a1 1 0 00-1 1v3a1 1 0 001 1h10a1 1 0 001-1v-3a1 1 0 00-1-1H3zM1 2a.5.5 0 01.5-.5h13a.5.5 0 010 1h-13A.5.5 0 011 2zm0 12a.5.5 0 01.5-.5h13a.5.5 0 010 1h-13A.5.5 0 011 14z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/view-stacked.svg b/src/assets/icons/view-stacked.svg
new file mode 100644
index 0000000..18eedcc
--- /dev/null
+++ b/src/assets/icons/view-stacked.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-view-stacked" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M3 0h10a2 2 0 012 2v3a2 2 0 01-2 2H3a2 2 0 01-2-2V2a2 2 0 012-2zm0 1a1 1 0 00-1 1v3a1 1 0 001 1h10a1 1 0 001-1V2a1 1 0 00-1-1H3zm0 8h10a2 2 0 012 2v3a2 2 0 01-2 2H3a2 2 0 01-2-2v-3a2 2 0 012-2zm0 1a1 1 0 00-1 1v3a1 1 0 001 1h10a1 1 0 001-1v-3a1 1 0 00-1-1H3z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/volume-down-fill.svg b/src/assets/icons/volume-down-fill.svg
new file mode 100644
index 0000000..ae3acb6
--- /dev/null
+++ b/src/assets/icons/volume-down-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-volume-down-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.717 3.55A.5.5 0 019 4v8a.5.5 0 01-.812.39L5.825 10.5H3.5A.5.5 0 013 10V6a.5.5 0 01.5-.5h2.325l2.363-1.89a.5.5 0 01.529-.06z" clip-rule="evenodd"/>
+ <path d="M10.707 11.182A4.486 4.486 0 0012.025 8a4.486 4.486 0 00-1.318-3.182L10 5.525A3.489 3.489 0 0111.025 8c0 .966-.392 1.841-1.025 2.475l.707.707z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/volume-down.svg b/src/assets/icons/volume-down.svg
new file mode 100644
index 0000000..36e6cbe
--- /dev/null
+++ b/src/assets/icons/volume-down.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-volume-down" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8.717 3.55A.5.5 0 019 4v8a.5.5 0 01-.812.39L5.825 10.5H3.5A.5.5 0 013 10V6a.5.5 0 01.5-.5h2.325l2.363-1.89a.5.5 0 01.529-.06zM8 5.04L6.312 6.39A.5.5 0 016 6.5H4v3h2a.5.5 0 01.312.11L8 10.96V5.04z" clip-rule="evenodd"/>
+ <path d="M10.707 11.182A4.486 4.486 0 0012.025 8a4.486 4.486 0 00-1.318-3.182L10 5.525A3.489 3.489 0 0111.025 8c0 .966-.392 1.841-1.025 2.475l.707.707z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/volume-mute-fill.svg b/src/assets/icons/volume-mute-fill.svg
new file mode 100644
index 0000000..2835557
--- /dev/null
+++ b/src/assets/icons/volume-mute-fill.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-volume-mute-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.717 3.55A.5.5 0 017 4v8a.5.5 0 01-.812.39L3.825 10.5H1.5A.5.5 0 011 10V6a.5.5 0 01.5-.5h2.325l2.363-1.89a.5.5 0 01.529-.06zm7.137 1.596a.5.5 0 010 .708l-4 4a.5.5 0 01-.708-.708l4-4a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M9.146 5.146a.5.5 0 000 .708l4 4a.5.5 0 00.708-.708l-4-4a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/volume-mute.svg b/src/assets/icons/volume-mute.svg
new file mode 100644
index 0000000..0979661
--- /dev/null
+++ b/src/assets/icons/volume-mute.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-volume-mute" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.717 3.55A.5.5 0 017 4v8a.5.5 0 01-.812.39L3.825 10.5H1.5A.5.5 0 011 10V6a.5.5 0 01.5-.5h2.325l2.363-1.89a.5.5 0 01.529-.06zM6 5.04L4.312 6.39A.5.5 0 014 6.5H2v3h2a.5.5 0 01.312.11L6 10.96V5.04zm7.854.606a.5.5 0 010 .708l-4 4a.5.5 0 01-.708-.708l4-4a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M9.146 5.646a.5.5 0 000 .708l4 4a.5.5 0 00.708-.708l-4-4a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/volume-up-fill.svg b/src/assets/icons/volume-up-fill.svg
new file mode 100644
index 0000000..3cba3af
--- /dev/null
+++ b/src/assets/icons/volume-up-fill.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-volume-up-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M11.536 14.01A8.473 8.473 0 0014.026 8a8.473 8.473 0 00-2.49-6.01l-.708.707A7.476 7.476 0 0113.025 8c0 2.071-.84 3.946-2.197 5.303l.708.707z"/>
+ <path d="M10.121 12.596A6.48 6.48 0 0012.025 8a6.48 6.48 0 00-1.904-4.596l-.707.707A5.483 5.483 0 0111.025 8a5.483 5.483 0 01-1.61 3.89l.706.706z"/>
+ <path d="M8.707 11.182A4.486 4.486 0 0010.025 8a4.486 4.486 0 00-1.318-3.182L8 5.525A3.489 3.489 0 019.025 8 3.49 3.49 0 018 10.475l.707.707z"/>
+ <path fill-rule="evenodd" d="M6.717 3.55A.5.5 0 017 4v8a.5.5 0 01-.812.39L3.825 10.5H1.5A.5.5 0 011 10V6a.5.5 0 01.5-.5h2.325l2.363-1.89a.5.5 0 01.529-.06z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/volume-up.svg b/src/assets/icons/volume-up.svg
new file mode 100644
index 0000000..0f02793
--- /dev/null
+++ b/src/assets/icons/volume-up.svg
@@ -0,0 +1,6 @@
+<svg class="bi bi-volume-up" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.717 3.55A.5.5 0 017 4v8a.5.5 0 01-.812.39L3.825 10.5H1.5A.5.5 0 011 10V6a.5.5 0 01.5-.5h2.325l2.363-1.89a.5.5 0 01.529-.06zM6 5.04L4.312 6.39A.5.5 0 014 6.5H2v3h2a.5.5 0 01.312.11L6 10.96V5.04z" clip-rule="evenodd"/>
+ <path d="M11.536 14.01A8.473 8.473 0 0014.026 8a8.473 8.473 0 00-2.49-6.01l-.708.707A7.476 7.476 0 0113.025 8c0 2.071-.84 3.946-2.197 5.303l.708.707z"/>
+ <path d="M10.121 12.596A6.48 6.48 0 0012.025 8a6.48 6.48 0 00-1.904-4.596l-.707.707A5.483 5.483 0 0111.025 8a5.483 5.483 0 01-1.61 3.89l.706.706z"/>
+ <path d="M8.707 11.182A4.486 4.486 0 0010.025 8a4.486 4.486 0 00-1.318-3.182L8 5.525A3.489 3.489 0 019.025 8 3.49 3.49 0 018 10.475l.707.707z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/vr.svg b/src/assets/icons/vr.svg
new file mode 100644
index 0000000..c739100
--- /dev/null
+++ b/src/assets/icons/vr.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-vr" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path d="M3 12V4a1 1 0 011-1h2.5V2H4a2 2 0 00-2 2v8a2 2 0 002 2h2.5v-1H4a1 1 0 01-1-1zm6.5 1v1H12a2 2 0 002-2V4a2 2 0 00-2-2H9.5v1H12a1 1 0 011 1v8a1 1 0 01-1 1H9.5z"/>
+ <path fill-rule="evenodd" d="M8 16a.5.5 0 01-.5-.5V.5a.5.5 0 011 0v15a.5.5 0 01-.5.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/wallet.svg b/src/assets/icons/wallet.svg
new file mode 100644
index 0000000..2a9e4fe
--- /dev/null
+++ b/src/assets/icons/wallet.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-wallet" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M1.5 3a.5.5 0 00-.5.5v2h5a.5.5 0 01.5.5c0 .253.08.644.306.958.207.288.557.542 1.194.542.637 0 .987-.254 1.194-.542.226-.314.306-.705.306-.958a.5.5 0 01.5-.5h5v-2a.5.5 0 00-.5-.5h-13zM15 6.5h-4.551a2.678 2.678 0 01-.443 1.042C9.613 8.088 8.963 8.5 8 8.5c-.963 0-1.613-.412-2.006-.958A2.679 2.679 0 015.551 6.5H1v6a.5.5 0 00.5.5h13a.5.5 0 00.5-.5v-6zm-15-3A1.5 1.5 0 011.5 2h13A1.5 1.5 0 0116 3.5v9a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 010 12.5v-9z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/watch.svg b/src/assets/icons/watch.svg
new file mode 100644
index 0000000..dce965f
--- /dev/null
+++ b/src/assets/icons/watch.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-watch" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4 14.333v-1.86A5.985 5.985 0 012 8c0-1.777.772-3.374 2-4.472V1.667C4 .747 4.746 0 5.667 0h4.666C11.253 0 12 .746 12 1.667v1.86A5.985 5.985 0 0114 8a5.985 5.985 0 01-2 4.472v1.861c0 .92-.746 1.667-1.667 1.667H5.667C4.747 16 4 15.254 4 14.333zM13 8A5 5 0 103 8a5 5 0 0010 0z" clip-rule="evenodd"/>
+ <rect width="1" height="2" x="13.5" y="7" rx=".5"/>
+ <path fill-rule="evenodd" d="M8 4.5a.5.5 0 01.5.5v3a.5.5 0 01-.5.5H6a.5.5 0 010-1h1.5V5a.5.5 0 01.5-.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/wifi.svg b/src/assets/icons/wifi.svg
new file mode 100644
index 0000000..0de16ca
--- /dev/null
+++ b/src/assets/icons/wifi.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-wifi" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.858 11.858A1.991 1.991 0 018 11.5c.425 0 .818.132 1.142.358L8 13l-1.142-1.142z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M7.731 12.024l.269.269.269-.269a1.507 1.507 0 00-.538 0zm-1.159-.576A2.49 2.49 0 018 11c.53 0 1.023.165 1.428.448a.5.5 0 01.068.763l-1.142 1.143a.5.5 0 01-.708 0L6.504 12.21a.5.5 0 01.354-.853v.5l-.286-.41zM8 9.5a4.478 4.478 0 00-2.7.9.5.5 0 01-.6-.8c.919-.69 2.062-1.1 3.3-1.1s2.381.41 3.3 1.1a.5.5 0 01-.6.8A4.478 4.478 0 008 9.5zm0-3c-1.833 0-3.51.657-4.814 1.748a.5.5 0 01-.642-.766A8.468 8.468 0 018 5.5c2.076 0 3.98.745 5.456 1.982a.5.5 0 11-.642.766A7.468 7.468 0 008 6.5z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M8 3.5c-2.657 0-5.082.986-6.932 2.613a.5.5 0 11-.66-.75A11.458 11.458 0 018 2.5c2.91 0 5.567 1.081 7.592 2.862a.5.5 0 11-.66.751A10.458 10.458 0 008 3.5z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/window.svg b/src/assets/icons/window.svg
new file mode 100644
index 0000000..3c7ddbe
--- /dev/null
+++ b/src/assets/icons/window.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-window" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 2H2a1 1 0 00-1 1v10a1 1 0 001 1h12a1 1 0 001-1V3a1 1 0 00-1-1zM2 1a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V3a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M15 6H1V5h14v1z" clip-rule="evenodd"/>
+ <path d="M3 3.5a.5.5 0 11-1 0 .5.5 0 011 0zm1.5 0a.5.5 0 11-1 0 .5.5 0 011 0zm1.5 0a.5.5 0 11-1 0 .5.5 0 011 0z"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/wrench.svg b/src/assets/icons/wrench.svg
new file mode 100644
index 0000000..e110a38
--- /dev/null
+++ b/src/assets/icons/wrench.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-wrench" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M.102 2.223A3.004 3.004 0 003.78 5.897l6.341 6.252A3.003 3.003 0 0013 16a3 3 0 10-.851-5.878L5.897 3.781A3.004 3.004 0 002.223.1l2.141 2.142L4 4l-1.757.364L.102 2.223zm13.37 9.019L13 11l-.471.242-.529.026-.287.445-.445.287-.026.529L11 13l.242.471.026.529.445.287.287.445.529.026L13 15l.471-.242.529-.026.287-.445.445-.287.026-.529L15 13l-.242-.471-.026-.529-.445-.287-.287-.445-.529-.026z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/x-circle-fill.svg b/src/assets/icons/x-circle-fill.svg
new file mode 100644
index 0000000..345e203
--- /dev/null
+++ b/src/assets/icons/x-circle-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-x-circle-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M16 8A8 8 0 110 8a8 8 0 0116 0zm-4.146-3.146a.5.5 0 00-.708-.708L8 7.293 4.854 4.146a.5.5 0 10-.708.708L7.293 8l-3.147 3.146a.5.5 0 00.708.708L8 8.707l3.146 3.147a.5.5 0 00.708-.708L8.707 8l3.147-3.146z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/x-circle.svg b/src/assets/icons/x-circle.svg
new file mode 100644
index 0000000..01c72e4
--- /dev/null
+++ b/src/assets/icons/x-circle.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-x-circle" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M8 15A7 7 0 108 1a7 7 0 000 14zm0 1A8 8 0 108 0a8 8 0 000 16z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.146 4.146a.5.5 0 000 .708l7 7a.5.5 0 00.708-.708l-7-7a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/x-diamond-fill.svg b/src/assets/icons/x-diamond-fill.svg
new file mode 100644
index 0000000..9627000
--- /dev/null
+++ b/src/assets/icons/x-diamond-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-x-diamond-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M9.05.435c-.58-.58-1.52-.58-2.1 0L4.047 3.339 8 7.293l3.954-3.954L9.049.435zm3.61 3.611L8.708 8l3.954 3.954 2.904-2.905c.58-.58.58-1.519 0-2.098l-2.904-2.905zm-.706 8.615L8 8.707l-3.954 3.954 2.905 2.904c.58.58 1.519.58 2.098 0l2.905-2.904zm-8.615-.707L7.293 8 3.339 4.046.435 6.951c-.58.58-.58 1.519 0 2.098l2.904 2.905z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/x-diamond.svg b/src/assets/icons/x-diamond.svg
new file mode 100644
index 0000000..0d2748b
--- /dev/null
+++ b/src/assets/icons/x-diamond.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-x-diamond" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M6.95.435c.58-.58 1.52-.58 2.1 0l6.515 6.516c.58.58.58 1.519 0 2.098L9.05 15.565c-.58.58-1.519.58-2.098 0L.435 9.05a1.482 1.482 0 010-2.098L6.95.435zm1.4.7a.495.495 0 00-.7 0L1.134 7.65a.495.495 0 000 .7l6.516 6.516a.495.495 0 00.7 0l6.516-6.516a.495.495 0 000-.7L8.35 1.134z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.146 4.146a.5.5 0 000 .708l7 7a.5.5 0 00.708-.708l-7-7a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/x-octagon-fill.svg b/src/assets/icons/x-octagon-fill.svg
new file mode 100644
index 0000000..3789abf
--- /dev/null
+++ b/src/assets/icons/x-octagon-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-x-octagon-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.46.146A.5.5 0 0011.107 0H4.893a.5.5 0 00-.353.146L.146 4.54A.5.5 0 000 4.893v6.214a.5.5 0 00.146.353l4.394 4.394a.5.5 0 00.353.146h6.214a.5.5 0 00.353-.146l4.394-4.394a.5.5 0 00.146-.353V4.893a.5.5 0 00-.146-.353L11.46.146zm.394 4.708a.5.5 0 00-.708-.708L8 7.293 4.854 4.146a.5.5 0 10-.708.708L7.293 8l-3.147 3.146a.5.5 0 00.708.708L8 8.707l3.146 3.147a.5.5 0 00.708-.708L8.707 8l3.147-3.146z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/x-octagon.svg b/src/assets/icons/x-octagon.svg
new file mode 100644
index 0000000..135654b
--- /dev/null
+++ b/src/assets/icons/x-octagon.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-x-octagon" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M4.54.146A.5.5 0 014.893 0h6.214a.5.5 0 01.353.146l4.394 4.394a.5.5 0 01.146.353v6.214a.5.5 0 01-.146.353l-4.394 4.394a.5.5 0 01-.353.146H4.893a.5.5 0 01-.353-.146L.146 11.46A.5.5 0 010 11.107V4.893a.5.5 0 01.146-.353L4.54.146zM5.1 1L1 5.1v5.8L5.1 15h5.8l4.1-4.1V5.1L10.9 1H5.1z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.146 4.146a.5.5 0 000 .708l7 7a.5.5 0 00.708-.708l-7-7a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/x-square-fill.svg b/src/assets/icons/x-square-fill.svg
new file mode 100644
index 0000000..762573f
--- /dev/null
+++ b/src/assets/icons/x-square-fill.svg
@@ -0,0 +1,3 @@
+<svg class="bi bi-x-square-fill" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2zm9.854 4.854a.5.5 0 00-.708-.708L8 7.293 4.854 4.146a.5.5 0 10-.708.708L7.293 8l-3.147 3.146a.5.5 0 00.708.708L8 8.707l3.146 3.147a.5.5 0 00.708-.708L8.707 8l3.147-3.146z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/x-square.svg b/src/assets/icons/x-square.svg
new file mode 100644
index 0000000..255ba18
--- /dev/null
+++ b/src/assets/icons/x-square.svg
@@ -0,0 +1,5 @@
+<svg class="bi bi-x-square" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.146 4.146a.5.5 0 000 .708l7 7a.5.5 0 00.708-.708l-7-7a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/assets/icons/x.svg b/src/assets/icons/x.svg
new file mode 100644
index 0000000..b92947d
--- /dev/null
+++ b/src/assets/icons/x.svg
@@ -0,0 +1,4 @@
+<svg class="bi bi-x" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/>
+ <path fill-rule="evenodd" d="M4.146 4.146a.5.5 0 000 .708l7 7a.5.5 0 00.708-.708l-7-7a.5.5 0 00-.708 0z" clip-rule="evenodd"/>
+</svg> \ No newline at end of file
diff --git a/src/index.html b/src/index.html
new file mode 100644
index 0000000..deeb427
--- /dev/null
+++ b/src/index.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <!-- https://twbs-bootstrap.netlify.app/ -->
+ <link rel="stylesheet" href="lib/bootstrap.css">
+ <link rel="stylesheet" href="styles/index.css">
+ <title>Start</title>
+</head>
+
+<body>
+
+ <main class="container">
+ <form id="search-form" action="http://localhost:8888/search" method="POST" class="mt-5" autocomplete="off">
+ <input type="text" name="q" class="form-control form-control-lg w-75 mx-auto shadow-sm" id="search-input"
+ autofocus>
+ </form>
+ <div class="mx-auto mt-5">
+ <div class="row">
+ <ul class="nav justify-content-end">
+ <li class="nav-item">
+ <div class="dropdown">
+ <span class="btn dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
+ <img src="assets/icons/option.svg" width="32" height="32">
+ </span>
+ <ul class="dropdown-menu">
+ <li class="dropdown-item" id="open-new-card-modal-button" type="button">Legg til kort
+ </li>
+ <li class="dropdown-item" id="open-import-pins-modal-button" type="button">Importer fra
+ Pinboard</li>
+ <li>
+ <hr class="dropdown-divider">
+ </li>
+ <li class="dropdown-item" id="open-options-modal-button" type="button">Innstillinger
+ </li>
+ </ul>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div class="row py-5" id="cards">
+ </div>
+ </div>
+ </main>
+
+ <input type="file" class="form-control" accept="application/json" id="file" style="display:none">
+
+ <!-- MODALS -->
+ <div class="modal" id="card-modal" tabindex="-1">
+ <div class="modal-dialog modal-lg modal-dialog-scrollable">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title"></h5>
+ </div>
+ <div class="modal-body">
+ <input type="text" class="form-control" placeholder="Tittel" id="card-name">
+ <div id="card-links" class="d-flex flex-column mt-3">
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-primary" id="save-card-button">Lagre</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!--Settings-->
+ <div class="modal" id="options-modal" tabindex="-1">
+ <div class="modal-dialog modal-lg modal-dialog-scrollable">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title">Innstillinger</h5>
+ </div>
+ <div class="modal-body">
+ <div class="mb-3">
+ <ul class="nav nav-pills nav-fill">
+ <li class="nav-item">
+ <span class="nav-link active" type="button">Generelt</span>
+ </li>
+ <li class="nav-item">
+ <span class="nav-link" type="button">Status</span>
+ </li>
+ </ul>
+ </div>
+ <form action="#" onsubmit="return false" id="options-form">
+ <div class="mb-3">
+ <label for="couch-url" class="form-label">CouchDB url</label>
+ <input type="text" class="form-control" id="couch-url">
+ </div>
+ <div class="mb-3">
+ <div class="form-check">
+ <input class="form-check-input" type="checkbox" value="" id="open-cards-in-new-tab">
+ <label class="form-check-label" for="open-cards-in-new-tab">
+ Ă…pne lenker i en ny fane
+ </label>
+ </div>
+ </div>
+ </form>
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-primary" id="save-options-button">Lagre</button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <script src="lib/bootstrap.js"></script>
+ <script src="lib/pouchdb.js"></script>
+ <script src="lib/toaster.js"></script>
+ <script src="scripts/index.js"></script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/src/lib/bootstrap.css b/src/lib/bootstrap.css
new file mode 100644
index 0000000..a44ed29
--- /dev/null
+++ b/src/lib/bootstrap.css
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v5.0.0-alpha1 (https://getbootstrap.com/)
+ * Copyright 2011-2020 The Bootstrap Authors
+ * Copyright 2011-2020 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#28a745;--bs-teal:#20c997;--bs-cyan:#17a2b8;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#28a745;--bs-info:#17a2b8;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#343a40;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}body{margin:0;font-family:var(--bs-font-sans-serif);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#024dbc}a:not([href]),a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em;-ms-overflow-style:scrollbar}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit;white-space:normal}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.container{width:100%;padding-right:1rem;padding-left:1rem;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}@media (min-width:1400px){.container{max-width:1320px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{width:100%;padding-right:1rem;padding-left:1rem;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x)/ -2);margin-left:calc(var(--bs-gutter-x)/ -2)}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x)/ 2);padding-left:calc(var(--bs-gutter-x)/ 2);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%;min-width:0}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.333333%}.col-2{flex:0 0 auto;width:16.666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.333333%}.col-5{flex:0 0 auto;width:41.666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.333333%}.col-8{flex:0 0 auto;width:66.666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.333333%}.col-11{flex:0 0 auto;width:91.666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%;min-width:0}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.333333%}.col-sm-2{flex:0 0 auto;width:16.666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.333333%}.col-sm-5{flex:0 0 auto;width:41.666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.333333%}.col-sm-8{flex:0 0 auto;width:66.666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.333333%}.col-sm-11{flex:0 0 auto;width:91.666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%;min-width:0}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.333333%}.col-md-2{flex:0 0 auto;width:16.666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.333333%}.col-md-5{flex:0 0 auto;width:41.666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.333333%}.col-md-8{flex:0 0 auto;width:66.666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.333333%}.col-md-11{flex:0 0 auto;width:91.666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%;min-width:0}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.333333%}.col-lg-2{flex:0 0 auto;width:16.666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.333333%}.col-lg-5{flex:0 0 auto;width:41.666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.333333%}.col-lg-8{flex:0 0 auto;width:66.666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.333333%}.col-lg-11{flex:0 0 auto;width:91.666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%;min-width:0}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.333333%}.col-xl-2{flex:0 0 auto;width:16.666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.333333%}.col-xl-5{flex:0 0 auto;width:41.666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.333333%}.col-xl-8{flex:0 0 auto;width:66.666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.333333%}.col-xl-11{flex:0 0 auto;width:91.666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%;min-width:0}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.333333%}.col-xxl-2{flex:0 0 auto;width:16.666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.333333%}.col-xxl-5{flex:0 0 auto;width:41.666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.333333%}.col-xxl-8{flex:0 0 auto;width:66.666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.333333%}.col-xxl-11{flex:0 0 auto;width:91.666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.333333%}.offset-xxl-2{margin-left:16.666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.333333%}.offset-xxl-5{margin-left:41.666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.333333%}.offset-xxl-8{margin-left:66.666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.333333%}.offset-xxl-11{margin-left:91.666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-bg:transparent;--bs-table-accent-bg:transparent;--bs-table-striped-color:#212529;--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:#212529;--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:#212529;--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#212529;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem;background-color:var(--bs-table-bg);background-image:linear-gradient(var(--bs-table-accent-bg),var(--bs-table-accent-bg));border-bottom-width:1px}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:last-child)>:last-child>*{border-bottom-color:currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-striped>tbody>tr:nth-of-type(odd){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg:#bbd6fe;--bs-table-striped-bg:#b3cdf3;--bs-table-striped-color:#212529;--bs-table-active-bg:#acc4e9;--bs-table-active-color:#212529;--bs-table-hover-bg:#afc9ee;--bs-table-hover-color:#212529;color:#212529;border-color:#acc4e9}.table-secondary{--bs-table-bg:#d6d8db;--bs-table-striped-bg:#cdcfd2;--bs-table-striped-color:#212529;--bs-table-active-bg:#c4c6c9;--bs-table-active-color:#212529;--bs-table-hover-bg:#c8cbce;--bs-table-hover-color:#212529;color:#212529;border-color:#c4c6c9}.table-success{--bs-table-bg:#c3e6cb;--bs-table-striped-bg:#bbdcc3;--bs-table-striped-color:#212529;--bs-table-active-bg:#b3d3bb;--bs-table-active-color:#212529;--bs-table-hover-bg:#b7d8bf;--bs-table-hover-color:#212529;color:#212529;border-color:#b3d3bb}.table-info{--bs-table-bg:#bee5eb;--bs-table-striped-bg:#b6dbe1;--bs-table-striped-color:#212529;--bs-table-active-bg:#aed2d8;--bs-table-active-color:#212529;--bs-table-hover-bg:#b2d7dc;--bs-table-hover-color:#212529;color:#212529;border-color:#aed2d8}.table-warning{--bs-table-bg:#ffeeba;--bs-table-striped-bg:#f4e4b3;--bs-table-striped-color:#212529;--bs-table-active-bg:#e9daac;--bs-table-active-color:#212529;--bs-table-hover-bg:#eedfaf;--bs-table-hover-color:#212529;color:#212529;border-color:#e9daac}.table-danger{--bs-table-bg:#f5c6cb;--bs-table-striped-bg:#eabec3;--bs-table-striped-color:#212529;--bs-table-active-bg:#e0b6bb;--bs-table-active-color:#212529;--bs-table-hover-bg:#e5babf;--bs-table-hover-color:#212529;color:#212529;border-color:#e0b6bb}.table-light{--bs-table-bg:#f8f9fa;--bs-table-striped-bg:#edeef0;--bs-table-striped-color:#212529;--bs-table-active-bg:#e3e4e5;--bs-table-active-color:#212529;--bs-table-hover-bg:#e8e9ea;--bs-table-hover-color:#212529;color:#212529;border-color:#e3e4e5}.table-dark{--bs-table-bg:#343a40;--bs-table-striped-bg:#3e444a;--bs-table-striped-color:#fff;--bs-table-active-bg:#484e53;--bs-table-active-color:#fff;--bs-table-hover-bg:#43494e;--bs-table-hover-color:#fff;color:#fff;border-color:#484e53}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#6c757d}.form-control{display:block;width:100%;min-height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control:focus{color:#495057;background-color:#fff;border-color:#8bbafe;outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-color{max-width:3rem;padding:.375rem}.form-control-color::-moz-color-swatch{border-radius:.25rem}.form-control-color::-webkit-color-swatch{border-radius:.25rem}.form-select{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-select:focus{border-color:#8bbafe;outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.form-select:focus::-ms-value{color:#495057;background-color:#fff}.form-select[multiple],.form-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.form-select:disabled{color:#6c757d;background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.form-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.form-check{display:block;min-height:1.5rem;padding-left:1.75em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.75em}.form-check-input{width:1.25em;height:1.25em;margin-top:.125em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;transition:background-color .15s ease-in-out,background-position .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-check-input{transition:none}}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{-webkit-filter:brightness(90%);filter:brightness(90%)}.form-check-input:focus{border-color:#8bbafe;outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;-webkit-filter:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2380bdff'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.form-file{--bs-form-file-height:calc(1.5em + 0.75rem + 2px);position:relative}.form-file-input{position:relative;z-index:2;width:100%;height:var(--bs-form-file-height);margin:0;opacity:0}.form-file-input:focus-within~.form-file-label{border-color:#8bbafe;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.form-file-input:disabled~.form-file-label .form-file-text,.form-file-input[disabled]~.form-file-label .form-file-text{background-color:#e9ecef}.form-file-label{position:absolute;top:0;right:0;left:0;z-index:1;display:flex;height:var(--bs-form-file-height);border-color:#ced4da;border-radius:.25rem}.form-file-text{display:block;flex-grow:1;padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;border-color:inherit;border-style:solid;border-width:1px;border-top-left-radius:inherit;border-bottom-left-radius:inherit}.form-file-button{display:block;flex-shrink:0;padding:.375rem .75rem;margin-left:-1px;line-height:1.5;color:#495057;background-color:#e9ecef;border-color:inherit;border-style:solid;border-width:1px;border-top-right-radius:inherit;border-bottom-right-radius:inherit}.form-file-sm{--bs-form-file-height:calc(1.5em + 0.5rem + 2px);font-size:.875rem}.form-file-sm .form-file-button,.form-file-sm .form-file-text{padding:.25rem .5rem}.form-file-lg{--bs-form-file-height:calc(1.5em + 1rem + 2px);font-size:1.25rem}.form-file-lg .form-file-button,.form-file-lg .form-file-text{padding:.5rem 1rem}.form-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(13,110,253,.25)}.form-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#bed8fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#bed8fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#0d6efd;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-ms-thumb{-ms-transition:none;transition:none}}.form-range::-ms-thumb:active{background-color:#bed8fe}.form-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.form-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.form-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-range:disabled::-ms-thumb{background-color:#adb5bd}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-file,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-file .form-file-input:focus~.form-file-label,.input-group>.form-select:focus{z-index:3}.input-group>.form-file>.form-file-input:focus{z-index:4}.input-group>.form-file:not(:last-child)>.form-file-label{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.form-file:not(:first-child)>.form-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-lg>.form-control{min-height:calc(1.5em + 1rem + 2px)}.input-group-lg>.form-select{height:calc(1.5em + 1rem + 2px)}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.input-group-sm>.form-control{min-height:calc(1.5em + .5rem + 2px)}.input-group-sm>.form-select{height:calc(1.5em + .5rem + 2px)}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:1.75rem}.input-group>.dropdown-toggle:nth-last-child(n+3),.input-group>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 1.75rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#28a745}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#34ce57}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.form-file-input.is-valid~.form-file-label,.was-validated .form-file-input:valid~.form-file-label{border-color:#28a745}.form-file-input.is-valid:focus~.form-file-label,.was-validated .form-file-input:valid:focus~.form-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 1.75rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#e4606d}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.form-file-input.is-invalid~.form-file-label,.was-validated .form-file-input:invalid~.form-file-label{border-color:#dc3545}.form-file-input.is-invalid:focus~.form-file-label,.was-validated .form-file-input:invalid:focus~.form-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-primary:hover{color:#fff;background-color:#025ce2;border-color:#0257d5}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#025ce2;border-color:#0257d5;box-shadow:0 0 0 .2rem rgba(49,132,253,.5)}.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0257d5;border-color:#0252c9}.btn-primary.active:focus,.btn-primary:active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(49,132,253,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary.active:focus,.btn-secondary:active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success.active:focus,.btn-success:active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info.active:focus,.btn-info:active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning.active:focus,.btn-warning:active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger.active:focus,.btn-danger:active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.active,.btn-light:active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light.active:focus,.btn-light:active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.active,.btn-dark:active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark.active:focus,.btn-dark:active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-primary{color:#0d6efd;border-color:#0d6efd}.btn-outline-primary:hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(13,110,253,.5)}.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show,.btn-outline-primary:active{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus,.btn-outline-primary:active:focus{box-shadow:0 0 0 .2rem rgba(13,110,253,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#0d6efd;background-color:transparent}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show,.btn-outline-secondary:active{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus,.btn-outline-secondary:active:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show,.btn-outline-success:active{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus,.btn-outline-success:active:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show,.btn-outline-info:active{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus,.btn-outline-info:active:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show,.btn-outline-warning:active{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus,.btn-outline-warning:active:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show,.btn-outline-danger:active{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus,.btn-outline-danger:active:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show,.btn-outline-light:active{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus,.btn-outline-light:active:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show,.btn-outline-dark:active{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus,.btn-outline-dark:active:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-link{font-weight:400;color:#0d6efd;text-decoration:underline}.btn-link:hover{color:#024dbc}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-left{right:auto;left:0}.dropdown-menu-xxl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#212529;text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#0d6efd}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#0d6efd}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{align-items:center;width:100%}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem;transition:box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .2rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important}.navbar-expand-sm .navbar-toggler{display:none}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-collapse{display:flex!important}.navbar-expand-md .navbar-toggler{display:none}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-collapse{display:flex!important}.navbar-expand-lg .navbar-toggler{display:none}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-collapse{display:flex!important}.navbar-expand-xl .navbar-toggler{display:none}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-collapse{display:flex!important}.navbar-expand-xxl .navbar-toggler{display:none}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-collapse{display:flex!important}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.55)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.55)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.55);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.55)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-body{flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.5rem 1rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.5rem;margin-bottom:-.5rem;margin-left:-.5rem;border-bottom:0}.card-header-pills{margin-right:-.5rem;margin-left:-.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.5rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#0d6efd;text-decoration:none;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#024dbc;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;background-color:#fff;border-color:#dee2e6}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .5em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3.5rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:1rem 1rem;color:inherit}.alert-primary{color:#073984;background-color:#cfe2ff;border-color:#bbd6fe}.alert-primary .alert-link{color:#042454}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#0d6efd;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.5rem 1rem;text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#073984;background-color:#bbd6fe}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#073984;background-color:#a2c7fe}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#073984;border-color:#073984}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{font-size:calc(1.275rem + .3vw);font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}@media (min-width:1200px){.close{font-size:1.5rem}}.close:hover{color:#000;text-decoration:none}.close:focus,.close:hover{opacity:.75}.close.disabled,.close:disabled{pointer-events:none}button.close{padding:0;background-color:transparent;border:0}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .tooltip-arrow,.bs-tooltip-right .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .tooltip-arrow::before,.bs-tooltip-right .tooltip-arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .tooltip-arrow,.bs-tooltip-left .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .tooltip-arrow::before,.bs-tooltip-left .tooltip-arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.popover-arrow,.bs-popover-right>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.popover-arrow::before,.bs-popover-right>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.popover-arrow::after,.bs-popover-right>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.popover-arrow,.bs-popover-left>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.popover-arrow::before,.bs-popover-left>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.popover-arrow::after,.bs-popover-left>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#0d6efd}.link-primary:focus,.link-primary:hover{color:#024dbc}.link-secondary{color:#6c757d}.link-secondary:focus,.link-secondary:hover{color:#494f54}.link-success{color:#28a745}.link-success:focus,.link-success:hover{color:#19692c}.link-info{color:#17a2b8}.link-info:focus,.link-info:hover{color:#0f6674}.link-warning{color:#ffc107}.link-warning:focus,.link-warning:hover{color:#ba8b00}.link-danger{color:#dc3545}.link-danger:focus,.link-danger:hover{color:#a71d2a}.link-light{color:#f8f9fa}.link-light:focus,.link-light:hover{color:#cbd3da}.link-dark{color:#343a40}.link-dark:focus,.link-dark:hover{color:#121416}.embed-responsive{position:relative;width:100%}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;width:100%;height:100%}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only,.sr-only-focusable:not(:focus){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.border{border:1px solid #dee2e6!important}.border-0{border:0!important}.border-top{border-top:1px solid #dee2e6!important}.border-top-0{border-top:0!important}.border-right{border-right:1px solid #dee2e6!important}.border-right-0{border-right:0!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-bottom-0{border-bottom:0!important}.border-left{border-left:1px solid #dee2e6!important}.border-left-0{border-left:0!important}.border-primary{border-color:#0d6efd!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.mr-0{margin-right:0!important}.mr-1{margin-right:.25rem!important}.mr-2{margin-right:.5rem!important}.mr-3{margin-right:1rem!important}.mr-4{margin-right:1.5rem!important}.mr-5{margin-right:3rem!important}.mr-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ml-0{margin-left:0!important}.ml-1{margin-left:.25rem!important}.ml-2{margin-left:.5rem!important}.ml-3{margin-left:1rem!important}.ml-4{margin-left:1.5rem!important}.ml-5{margin-left:3rem!important}.ml-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pr-0{padding-right:0!important}.pr-1{padding-right:.25rem!important}.pr-2{padding-right:.5rem!important}.pr-3{padding-right:1rem!important}.pr-4{padding-right:1.5rem!important}.pr-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.pl-0{padding-left:0!important}.pl-1{padding-left:.25rem!important}.pl-2{padding-left:.5rem!important}.pl-3{padding-left:1rem!important}.pl-4{padding-left:1.5rem!important}.pl-5{padding-left:3rem!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-primary{color:#0d6efd!important}.text-secondary{color:#6c757d!important}.text-success{color:#28a745!important}.text-info{color:#17a2b8!important}.text-warning{color:#ffc107!important}.text-danger{color:#dc3545!important}.text-light{color:#f8f9fa!important}.text-dark{color:#343a40!important}.text-white{color:#fff!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-reset{color:inherit!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.bg-primary{background-color:#0d6efd!important}.bg-secondary{background-color:#6c757d!important}.bg-success{background-color:#28a745!important}.bg-info{background-color:#17a2b8!important}.bg-warning{background-color:#ffc107!important}.bg-danger{background-color:#dc3545!important}.bg-light{background-color:#f8f9fa!important}.bg-dark{background-color:#343a40!important}.bg-body{background-color:#fff!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.font-italic{font-style:italic!important}.font-normal{font-style:normal!important}.text-break{word-wrap:break-word!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:.25rem!important}.rounded-sm{border-radius:.2rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-bottom-left-radius:.25rem!important;border-top-left-radius:.25rem!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.mr-sm-0{margin-right:0!important}.mr-sm-1{margin-right:.25rem!important}.mr-sm-2{margin-right:.5rem!important}.mr-sm-3{margin-right:1rem!important}.mr-sm-4{margin-right:1.5rem!important}.mr-sm-5{margin-right:3rem!important}.mr-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ml-sm-0{margin-left:0!important}.ml-sm-1{margin-left:.25rem!important}.ml-sm-2{margin-left:.5rem!important}.ml-sm-3{margin-left:1rem!important}.ml-sm-4{margin-left:1.5rem!important}.ml-sm-5{margin-left:3rem!important}.ml-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pr-sm-0{padding-right:0!important}.pr-sm-1{padding-right:.25rem!important}.pr-sm-2{padding-right:.5rem!important}.pr-sm-3{padding-right:1rem!important}.pr-sm-4{padding-right:1.5rem!important}.pr-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.pl-sm-0{padding-left:0!important}.pl-sm-1{padding-left:.25rem!important}.pl-sm-2{padding-left:.5rem!important}.pl-sm-3{padding-left:1rem!important}.pl-sm-4{padding-left:1.5rem!important}.pl-sm-5{padding-left:3rem!important}.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.mr-md-0{margin-right:0!important}.mr-md-1{margin-right:.25rem!important}.mr-md-2{margin-right:.5rem!important}.mr-md-3{margin-right:1rem!important}.mr-md-4{margin-right:1.5rem!important}.mr-md-5{margin-right:3rem!important}.mr-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ml-md-0{margin-left:0!important}.ml-md-1{margin-left:.25rem!important}.ml-md-2{margin-left:.5rem!important}.ml-md-3{margin-left:1rem!important}.ml-md-4{margin-left:1.5rem!important}.ml-md-5{margin-left:3rem!important}.ml-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pr-md-0{padding-right:0!important}.pr-md-1{padding-right:.25rem!important}.pr-md-2{padding-right:.5rem!important}.pr-md-3{padding-right:1rem!important}.pr-md-4{padding-right:1.5rem!important}.pr-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.pl-md-0{padding-left:0!important}.pl-md-1{padding-left:.25rem!important}.pl-md-2{padding-left:.5rem!important}.pl-md-3{padding-left:1rem!important}.pl-md-4{padding-left:1.5rem!important}.pl-md-5{padding-left:3rem!important}.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.mr-lg-0{margin-right:0!important}.mr-lg-1{margin-right:.25rem!important}.mr-lg-2{margin-right:.5rem!important}.mr-lg-3{margin-right:1rem!important}.mr-lg-4{margin-right:1.5rem!important}.mr-lg-5{margin-right:3rem!important}.mr-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ml-lg-0{margin-left:0!important}.ml-lg-1{margin-left:.25rem!important}.ml-lg-2{margin-left:.5rem!important}.ml-lg-3{margin-left:1rem!important}.ml-lg-4{margin-left:1.5rem!important}.ml-lg-5{margin-left:3rem!important}.ml-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pr-lg-0{padding-right:0!important}.pr-lg-1{padding-right:.25rem!important}.pr-lg-2{padding-right:.5rem!important}.pr-lg-3{padding-right:1rem!important}.pr-lg-4{padding-right:1.5rem!important}.pr-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.pl-lg-0{padding-left:0!important}.pl-lg-1{padding-left:.25rem!important}.pl-lg-2{padding-left:.5rem!important}.pl-lg-3{padding-left:1rem!important}.pl-lg-4{padding-left:1.5rem!important}.pl-lg-5{padding-left:3rem!important}.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.mr-xl-0{margin-right:0!important}.mr-xl-1{margin-right:.25rem!important}.mr-xl-2{margin-right:.5rem!important}.mr-xl-3{margin-right:1rem!important}.mr-xl-4{margin-right:1.5rem!important}.mr-xl-5{margin-right:3rem!important}.mr-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ml-xl-0{margin-left:0!important}.ml-xl-1{margin-left:.25rem!important}.ml-xl-2{margin-left:.5rem!important}.ml-xl-3{margin-left:1rem!important}.ml-xl-4{margin-left:1.5rem!important}.ml-xl-5{margin-left:3rem!important}.ml-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pr-xl-0{padding-right:0!important}.pr-xl-1{padding-right:.25rem!important}.pr-xl-2{padding-right:.5rem!important}.pr-xl-3{padding-right:1rem!important}.pr-xl-4{padding-right:1.5rem!important}.pr-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.pl-xl-0{padding-left:0!important}.pl-xl-1{padding-left:.25rem!important}.pl-xl-2{padding-left:.5rem!important}.pl-xl-3{padding-left:1rem!important}.pl-xl-4{padding-left:1.5rem!important}.pl-xl-5{padding-left:3rem!important}.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-left{float:left!important}.float-xxl-right{float:right!important}.float-xxl-none{float:none!important}.d-xxl-none{display:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.mr-xxl-0{margin-right:0!important}.mr-xxl-1{margin-right:.25rem!important}.mr-xxl-2{margin-right:.5rem!important}.mr-xxl-3{margin-right:1rem!important}.mr-xxl-4{margin-right:1.5rem!important}.mr-xxl-5{margin-right:3rem!important}.mr-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ml-xxl-0{margin-left:0!important}.ml-xxl-1{margin-left:.25rem!important}.ml-xxl-2{margin-left:.5rem!important}.ml-xxl-3{margin-left:1rem!important}.ml-xxl-4{margin-left:1.5rem!important}.ml-xxl-5{margin-left:3rem!important}.ml-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pr-xxl-0{padding-right:0!important}.pr-xxl-1{padding-right:.25rem!important}.pr-xxl-2{padding-right:.5rem!important}.pr-xxl-3{padding-right:1rem!important}.pr-xxl-4{padding-right:1.5rem!important}.pr-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.pl-xxl-0{padding-left:0!important}.pl-xxl-1{padding-left:.25rem!important}.pl-xxl-2{padding-left:.5rem!important}.pl-xxl-3{padding-left:1rem!important}.pl-xxl-4{padding-left:1.5rem!important}.pl-xxl-5{padding-left:3rem!important}.text-xxl-left{text-align:left!important}.text-xxl-right{text-align:right!important}.text-xxl-center{text-align:center!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}
diff --git a/src/lib/bootstrap.js b/src/lib/bootstrap.js
new file mode 100644
index 0000000..d2e2cf4
--- /dev/null
+++ b/src/lib/bootstrap.js
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v5.0.0-alpha1 (https://getbootstrap.com/)
+ * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).bootstrap=e()}(this,(function(){"use strict";function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function e(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function o(t){for(var e=1;e<arguments.length;e++){var o=null!=arguments[e]?arguments[e]:{};e%2?i(Object(o),!0).forEach((function(e){n(t,e,o[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):i(Object(o)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))}))}return t}var r,s,a,l,c=function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},u=function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():null}return e},f=function(t){var e=u(t);return e&&document.querySelector(e)?e:null},d=function(t){var e=u(t);return e?document.querySelector(e):null},h=function(t){if(!t)return 0;var e=window.getComputedStyle(t),n=e.transitionDuration,i=e.transitionDelay,o=parseFloat(n),r=parseFloat(i);return o||r?(n=n.split(",")[0],i=i.split(",")[0],1e3*(parseFloat(n)+parseFloat(i))):0},p=function(t){t.dispatchEvent(new Event("transitionend"))},g=function(t){return(t[0]||t).nodeType},m=function(t,e){var n=!1,i=e+5;t.addEventListener("transitionend",(function e(){n=!0,t.removeEventListener("transitionend",e)})),setTimeout((function(){n||p(t)}),i)},v=function(t,e,n){Object.keys(n).forEach((function(i){var o,r=n[i],s=e[i],a=s&&g(s)?"element":null==(o=s)?""+o:{}.toString.call(o).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(r).test(a))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+a+'" but expected type "'+r+'".')}))},_=function(t){if(!t)return!1;if(t.style&&t.parentNode&&t.parentNode.style){var e=getComputedStyle(t),n=getComputedStyle(t.parentNode);return"none"!==e.display&&"none"!==n.display&&"hidden"!==e.visibility}return!1},b=function(){return function(){}},y=function(t){return t.offsetHeight},w=function(){var t=window.jQuery;return t&&!document.body.hasAttribute("data-no-jquery")?t:null},E=(r={},s=1,{set:function(t,e,n){void 0===t.key&&(t.key={key:e,id:s},s++),r[t.key.id]=n},get:function(t,e){if(!t||void 0===t.key)return null;var n=t.key;return n.key===e?r[n.id]:null},delete:function(t,e){if(void 0!==t.key){var n=t.key;n.key===e&&(delete r[n.id],delete t.key)}}}),T=function(t,e,n){E.set(t,e,n)},L=function(t,e){return E.get(t,e)},k=function(t,e){E.delete(t,e)},O=Element.prototype.querySelectorAll,C=Element.prototype.querySelector,A=(a=new CustomEvent("Bootstrap",{cancelable:!0}),(l=document.createElement("div")).addEventListener("Bootstrap",(function(){return null})),a.preventDefault(),l.dispatchEvent(a),a.defaultPrevented),D=/:scope\b/;(function(){var t=document.createElement("div");try{t.querySelectorAll(":scope *")}catch(t){return!1}return!0})()||(O=function(t){if(!D.test(t))return this.querySelectorAll(t);var e=Boolean(this.id);e||(this.id=c("scope"));var n=null;try{t=t.replace(D,"#"+this.id),n=this.querySelectorAll(t)}finally{e||this.removeAttribute("id")}return n},C=function(t){if(!D.test(t))return this.querySelector(t);var e=O.call(this,t);return void 0!==e[0]?e[0]:null});var S=w(),x=/[^.]*(?=\..*)\.|.*/,N=/\..*/,I=/::\d+$/,j={},P=1,M={mouseenter:"mouseover",mouseleave:"mouseout"},H=["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"];function B(t,e){return e&&e+"::"+P++||t.uidEvent||P++}function R(t){var e=B(t);return t.uidEvent=e,j[e]=j[e]||{},j[e]}function F(t,e,n){void 0===n&&(n=null);for(var i=Object.keys(t),o=0,r=i.length;o<r;o++){var s=t[i[o]];if(s.originalHandler===e&&s.delegationSelector===n)return s}return null}function W(t,e,n){var i="string"==typeof e,o=i?n:e,r=t.replace(N,""),s=M[r];return s&&(r=s),H.indexOf(r)>-1||(r=t),[i,o,r]}function U(t,e,n,i,o){if("string"==typeof e&&t){n||(n=i,i=null);var r=W(e,n,i),s=r[0],a=r[1],l=r[2],c=R(t),u=c[l]||(c[l]={}),f=F(u,a,s?n:null);if(f)f.oneOff=f.oneOff&&o;else{var d=B(a,e.replace(x,"")),h=s?function(t,e,n){return function i(o){for(var r=t.querySelectorAll(e),s=o.target;s&&s!==this;s=s.parentNode)for(var a=r.length;a--;)if(r[a]===s)return i.oneOff&&V.off(t,o.type,n),n.apply(s,[o]);return null}}(t,n,i):function(t,e){return function n(i){return n.oneOff&&V.off(t,i.type,e),e.apply(t,[i])}}(t,n);h.delegationSelector=s?n:null,h.originalHandler=a,h.oneOff=o,h.uidEvent=d,u[d]=h,t.addEventListener(l,h,s)}}}function Q(t,e,n,i,o){var r=F(e[n],i,o);r&&(t.removeEventListener(n,r,Boolean(o)),delete e[n][r.uidEvent])}var V={on:function(t,e,n,i){U(t,e,n,i,!1)},one:function(t,e,n,i){U(t,e,n,i,!0)},off:function(t,e,n,i){if("string"==typeof e&&t){var o=W(e,n,i),r=o[0],s=o[1],a=o[2],l=a!==e,c=R(t),u="."===e.charAt(0);if(void 0===s){u&&Object.keys(c).forEach((function(n){!function(t,e,n,i){var o=e[n]||{};Object.keys(o).forEach((function(r){if(r.indexOf(i)>-1){var s=o[r];Q(t,e,n,s.originalHandler,s.delegationSelector)}}))}(t,c,n,e.slice(1))}));var f=c[a]||{};Object.keys(f).forEach((function(n){var i=n.replace(I,"");if(!l||e.indexOf(i)>-1){var o=f[n];Q(t,c,a,o.originalHandler,o.delegationSelector)}}))}else{if(!c||!c[a])return;Q(t,c,a,s,r?n:null)}}},trigger:function(t,e,n){if("string"!=typeof e||!t)return null;var i,o=e.replace(N,""),r=e!==o,s=H.indexOf(o)>-1,a=!0,l=!0,c=!1,u=null;return r&&S&&(i=S.Event(e,n),S(t).trigger(i),a=!i.isPropagationStopped(),l=!i.isImmediatePropagationStopped(),c=i.isDefaultPrevented()),s?(u=document.createEvent("HTMLEvents")).initEvent(o,a,!0):u=new CustomEvent(e,{bubbles:a,cancelable:!0}),void 0!==n&&Object.keys(n).forEach((function(t){Object.defineProperty(u,t,{get:function(){return n[t]}})})),c&&(u.preventDefault(),A||Object.defineProperty(u,"defaultPrevented",{get:function(){return!0}})),l&&t.dispatchEvent(u),u.defaultPrevented&&void 0!==i&&i.preventDefault(),u}},q="alert",Y=function(){function t(t){this._element=t,this._element&&T(t,"bs.alert",this)}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t));var n=this._triggerCloseEvent(e);null===n||n.defaultPrevented||this._removeElement(e)},n.dispose=function(){k(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){return d(t)||t.closest(".alert")},n._triggerCloseEvent=function(t){return V.trigger(t,"close.bs.alert")},n._removeElement=function(t){var e=this;if(t.classList.remove("show"),t.classList.contains("fade")){var n=h(t);V.one(t,"transitionend",(function(){return e._destroyElement(t)})),m(t,n)}else this._destroyElement(t)},n._destroyElement=function(t){t.parentNode&&t.parentNode.removeChild(t),V.trigger(t,"closed.bs.alert")},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.alert");n||(n=new t(this)),"close"===e&&n[e](this)}))},t.handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},t.getInstance=function(t){return L(t,"bs.alert")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}}]),t}();V.on(document,"click.bs.alert.data-api",'[data-dismiss="alert"]',Y.handleDismiss(new Y));var z=w();if(z){var K=z.fn[q];z.fn[q]=Y.jQueryInterface,z.fn[q].Constructor=Y,z.fn[q].noConflict=function(){return z.fn[q]=K,Y.jQueryInterface}}var X={matches:function(t,e){return t.matches(e)},find:function(t,e){var n;return void 0===e&&(e=document.documentElement),(n=[]).concat.apply(n,O.call(e,t))},findOne:function(t,e){return void 0===e&&(e=document.documentElement),C.call(e,t)},children:function(t,e){var n,i=(n=[]).concat.apply(n,t.children);return i.filter((function(t){return t.matches(e)}))},parents:function(t,e){for(var n=[],i=t.parentNode;i&&i.nodeType===Node.ELEMENT_NODE&&3!==i.nodeType;)this.matches(i,e)&&n.push(i),i=i.parentNode;return n},prev:function(t,e){for(var n=t.previousElementSibling;n;){if(n.matches(e))return[n];n=n.previousElementSibling}return[]},next:function(t,e){for(var n=t.nextElementSibling;n;){if(this.matches(n,e))return[n];n=n.nextElementSibling}return[]}},G=function(){function t(t){this._element=t,T(t,"bs.button",this)}var n=t.prototype;return n.toggle=function(){var t=!0,e=!0,n=this._element.closest('[data-toggle="buttons"]');if(n){var i=X.findOne('input:not([type="hidden"])',this._element);if(i&&"radio"===i.type){if(i.checked&&this._element.classList.contains("active"))t=!1;else{var o=X.findOne(".active",n);o&&o.classList.remove("active")}if(t){if(i.hasAttribute("disabled")||n.hasAttribute("disabled")||i.classList.contains("disabled")||n.classList.contains("disabled"))return;i.checked=!this._element.classList.contains("active"),V.trigger(i,"change")}i.focus(),e=!1}}e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&this._element.classList.toggle("active")},n.dispose=function(){k(this._element,"bs.button"),this._element=null},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.button");n||(n=new t(this)),"toggle"===e&&n[e]()}))},t.getInstance=function(t){return L(t,"bs.button")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}}]),t}();V.on(document,"click.bs.button.data-api",'[data-toggle^="button"]',(function(t){t.preventDefault();var e=t.target.closest(".btn"),n=L(e,"bs.button");n||(n=new G(e)),n.toggle()})),V.on(document,"focus.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target.closest(".btn");e&&e.classList.add("focus")})),V.on(document,"blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target.closest(".btn");e&&e.classList.remove("focus")}));var $=w();if($){var Z=$.fn.button;$.fn.button=G.jQueryInterface,$.fn.button.Constructor=G,$.fn.button.noConflict=function(){return $.fn.button=Z,G.jQueryInterface}}function J(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function tt(t){return t.replace(/[A-Z]/g,(function(t){return"-"+t.toLowerCase()}))}var et={setDataAttribute:function(t,e,n){t.setAttribute("data-"+tt(e),n)},removeDataAttribute:function(t,e){t.removeAttribute("data-"+tt(e))},getDataAttributes:function(t){if(!t)return{};var e=o({},t.dataset);return Object.keys(e).forEach((function(t){e[t]=J(e[t])})),e},getDataAttribute:function(t,e){return J(t.getAttribute("data-"+tt(e)))},offset:function(t){var e=t.getBoundingClientRect();return{top:e.top+document.body.scrollTop,left:e.left+document.body.scrollLeft}},position:function(t){return{top:t.offsetTop,left:t.offsetLeft}},toggleClass:function(t,e){t&&(t.classList.contains(e)?t.classList.remove(e):t.classList.add(e))}},nt="carousel",it=".bs.carousel",ot={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},rt={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},st={TOUCH:"touch",PEN:"pen"},at=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=X.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners(),T(t,"bs.carousel",this)}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&_(this._element)&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),X.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(p(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var e=this;this._activeElement=X.findOne(".active.carousel-item",this._element);var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)V.one(this._element,"slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?"next":"prev";this._slide(i,this._items[t])}},n.dispose=function(){V.off(this._element,it),k(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=o(o({},ot),t),v(nt,t,rt),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&V.on(this._element,"keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&(V.on(this._element,"mouseenter.bs.carousel",(function(e){return t.pause(e)})),V.on(this._element,"mouseleave.bs.carousel",(function(e){return t.cycle(e)}))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this,e=function(e){t._pointerEvent&&st[e.pointerType.toUpperCase()]?t.touchStartX=e.clientX:t._pointerEvent||(t.touchStartX=e.touches[0].clientX)},n=function(e){t._pointerEvent&&st[e.pointerType.toUpperCase()]&&(t.touchDeltaX=e.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};X.find(".carousel-item img",this._element).forEach((function(t){V.on(t,"dragstart.bs.carousel",(function(t){return t.preventDefault()}))})),this._pointerEvent?(V.on(this._element,"pointerdown.bs.carousel",(function(t){return e(t)})),V.on(this._element,"pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(V.on(this._element,"touchstart.bs.carousel",(function(t){return e(t)})),V.on(this._element,"touchmove.bs.carousel",(function(e){return function(e){e.touches&&e.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.touches[0].clientX-t.touchStartX}(e)})),V.on(this._element,"touchend.bs.carousel",(function(t){return n(t)})))},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.key){case"ArrowLeft":t.preventDefault(),this.prev();break;case"ArrowRight":t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?X.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},n._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(X.findOne(".active.carousel-item",this._element));return V.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n})},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){for(var e=X.find(".active",this._indicatorsElement),n=0;n<e.length;n++)e[n].classList.remove("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&i.classList.add("active")}},n._slide=function(t,e){var n,i,o,r=this,s=X.findOne(".active.carousel-item",this._element),a=this._getItemIndex(s),l=e||s&&this._getItemByDirection(t,s),c=this._getItemIndex(l),u=Boolean(this._interval);if("next"===t?(n="carousel-item-left",i="carousel-item-next",o="left"):(n="carousel-item-right",i="carousel-item-prev",o="right"),l&&l.classList.contains("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(l,o).defaultPrevented&&s&&l){if(this._isSliding=!0,u&&this.pause(),this._setActiveIndicatorElement(l),this._element.classList.contains("slide")){l.classList.add(i),y(l),s.classList.add(n),l.classList.add(n);var f=parseInt(l.getAttribute("data-interval"),10);f?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=f):this._config.interval=this._config.defaultInterval||this._config.interval;var d=h(s);V.one(s,"transitionend",(function(){l.classList.remove(n,i),l.classList.add("active"),s.classList.remove("active",i,n),r._isSliding=!1,setTimeout((function(){V.trigger(r._element,"slid.bs.carousel",{relatedTarget:l,direction:o,from:a,to:c})}),0)})),m(s,d)}else s.classList.remove("active"),l.classList.add("active"),this._isSliding=!1,V.trigger(this._element,"slid.bs.carousel",{relatedTarget:l,direction:o,from:a,to:c});u&&this.cycle()}},t.carouselInterface=function(e,n){var i=L(e,"bs.carousel"),r=o(o({},ot),et.getDataAttributes(e));"object"==typeof n&&(r=o(o({},r),n));var s="string"==typeof n?n:r.slide;if(i||(i=new t(e,r)),"number"==typeof n)i.to(n);else if("string"==typeof s){if(void 0===i[s])throw new TypeError('No method named "'+s+'"');i[s]()}else r.interval&&r.ride&&(i.pause(),i.cycle())},t.jQueryInterface=function(e){return this.each((function(){t.carouselInterface(this,e)}))},t.dataApiClickHandler=function(e){var n=d(this);if(n&&n.classList.contains("carousel")){var i=o(o({},et.getDataAttributes(n)),et.getDataAttributes(this)),r=this.getAttribute("data-slide-to");r&&(i.interval=!1),t.carouselInterface(n,i),r&&L(n,"bs.carousel").to(r),e.preventDefault()}},t.getInstance=function(t){return L(t,"bs.carousel")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return ot}}]),t}();V.on(document,"click.bs.carousel.data-api","[data-slide], [data-slide-to]",at.dataApiClickHandler),V.on(window,"load.bs.carousel.data-api",(function(){for(var t=X.find('[data-ride="carousel"]'),e=0,n=t.length;e<n;e++)at.carouselInterface(t[e],L(t[e],"bs.carousel"))}));var lt=w();if(lt){var ct=lt.fn[nt];lt.fn[nt]=at.jQueryInterface,lt.fn[nt].Constructor=at,lt.fn[nt].noConflict=function(){return lt.fn[nt]=ct,at.jQueryInterface}}var ut="collapse",ft={toggle:!0,parent:""},dt={toggle:"boolean",parent:"(string|element)"},ht=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=X.find('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]');for(var n=X.find('[data-toggle="collapse"]'),i=0,o=n.length;i<o;i++){var r=n[i],s=f(r),a=X.find(s).filter((function(e){return e===t}));null!==s&&a.length&&(this._selector=s,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle(),T(t,"bs.collapse",this)}var n=t.prototype;return n.toggle=function(){this._element.classList.contains("show")?this.hide():this.show()},n.show=function(){var e=this;if(!this._isTransitioning&&!this._element.classList.contains("show")){var n,i;this._parent&&0===(n=X.find(".show, .collapsing",this._parent).filter((function(t){return"string"==typeof e._config.parent?t.getAttribute("data-parent")===e._config.parent:t.classList.contains("collapse")}))).length&&(n=null);var o=X.findOne(this._selector);if(n){var r=n.filter((function(t){return o!==t}));if((i=r[0]?L(r[0],"bs.collapse"):null)&&i._isTransitioning)return}if(!V.trigger(this._element,"show.bs.collapse").defaultPrevented){n&&n.forEach((function(e){o!==e&&t.collapseInterface(e,"hide"),i||T(e,"bs.collapse",null)}));var s=this._getDimension();this._element.classList.remove("collapse"),this._element.classList.add("collapsing"),this._element.style[s]=0,this._triggerArray.length&&this._triggerArray.forEach((function(t){t.classList.remove("collapsed"),t.setAttribute("aria-expanded",!0)})),this.setTransitioning(!0);var a="scroll"+(s[0].toUpperCase()+s.slice(1)),l=h(this._element);V.one(this._element,"transitionend",(function(){e._element.classList.remove("collapsing"),e._element.classList.add("collapse","show"),e._element.style[s]="",e.setTransitioning(!1),V.trigger(e._element,"shown.bs.collapse")})),m(this._element,l),this._element.style[s]=this._element[a]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&this._element.classList.contains("show")&&!V.trigger(this._element,"hide.bs.collapse").defaultPrevented){var e=this._getDimension();this._element.style[e]=this._element.getBoundingClientRect()[e]+"px",y(this._element),this._element.classList.add("collapsing"),this._element.classList.remove("collapse","show");var n=this._triggerArray.length;if(n>0)for(var i=0;i<n;i++){var o=this._triggerArray[i],r=d(o);r&&!r.classList.contains("show")&&(o.classList.add("collapsed"),o.setAttribute("aria-expanded",!1))}this.setTransitioning(!0);this._element.style[e]="";var s=h(this._element);V.one(this._element,"transitionend",(function(){t.setTransitioning(!1),t._element.classList.remove("collapsing"),t._element.classList.add("collapse"),V.trigger(t._element,"hidden.bs.collapse")})),m(this._element,s)}},n.setTransitioning=function(t){this._isTransitioning=t},n.dispose=function(){k(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(t){return(t=o(o({},ft),t)).toggle=Boolean(t.toggle),v(ut,t,dt),t},n._getDimension=function(){return this._element.classList.contains("width")?"width":"height"},n._getParent=function(){var t=this,e=this._config.parent;g(e)?void 0===e.jquery&&void 0===e[0]||(e=e[0]):e=X.findOne(e);var n='[data-toggle="collapse"][data-parent="'+e+'"]';return X.find(n,e).forEach((function(e){var n=d(e);t._addAriaAndCollapsedClass(n,[e])})),e},n._addAriaAndCollapsedClass=function(t,e){if(t){var n=t.classList.contains("show");e.length&&e.forEach((function(t){n?t.classList.remove("collapsed"):t.classList.add("collapsed"),t.setAttribute("aria-expanded",n)}))}},t.collapseInterface=function(e,n){var i=L(e,"bs.collapse"),r=o(o(o({},ft),et.getDataAttributes(e)),"object"==typeof n&&n?n:{});if(!i&&r.toggle&&"string"==typeof n&&/show|hide/.test(n)&&(r.toggle=!1),i||(i=new t(e,r)),"string"==typeof n){if(void 0===i[n])throw new TypeError('No method named "'+n+'"');i[n]()}},t.jQueryInterface=function(e){return this.each((function(){t.collapseInterface(this,e)}))},t.getInstance=function(t){return L(t,"bs.collapse")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return ft}}]),t}();V.on(document,"click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.target.tagName&&t.preventDefault();var e=et.getDataAttributes(this),n=f(this);X.find(n).forEach((function(t){var n,i=L(t,"bs.collapse");i?(null===i._parent&&"string"==typeof e.parent&&(i._config.parent=e.parent,i._parent=i._getParent()),n="toggle"):n=e,ht.collapseInterface(t,n)}))}));var pt=w();if(pt){var gt=pt.fn[ut];pt.fn[ut]=ht.jQueryInterface,pt.fn[ut].Constructor=ht,pt.fn[ut].noConflict=function(){return pt.fn[ut]=gt,ht.jQueryInterface}}var mt="undefined"!=typeof window&&"undefined"!=typeof document&&"undefined"!=typeof navigator,vt=function(){for(var t=["Edge","Trident","Firefox"],e=0;e<t.length;e+=1)if(mt&&navigator.userAgent.indexOf(t[e])>=0)return 1;return 0}();var _t=mt&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),vt))}};function bt(t){return t&&"[object Function]"==={}.toString.call(t)}function yt(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function wt(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function Et(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=yt(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:Et(wt(t))}function Tt(t){return t&&t.referenceNode?t.referenceNode:t}var Lt=mt&&!(!window.MSInputMethodContext||!document.documentMode),kt=mt&&/MSIE 10/.test(navigator.userAgent);function Ot(t){return 11===t?Lt:10===t?kt:Lt||kt}function Ct(t){if(!t)return document.documentElement;for(var e=Ot(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===yt(n,"position")?Ct(n):n:t?t.ownerDocument.documentElement:document.documentElement}function At(t){return null!==t.parentNode?At(t.parentNode):t}function Dt(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var s=r.commonAncestorContainer;if(t!==s&&e!==s||i.contains(o))return function(t){var e=t.nodeName;return"BODY"!==e&&("HTML"===e||Ct(t.firstElementChild)===t)}(s)?s:Ct(s);var a=At(t);return a.host?Dt(a.host,e):Dt(t,At(e).host)}function St(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function xt(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=St(e,"top"),o=St(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function Nt(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"],10)+parseFloat(t["border"+i+"Width"],10)}function It(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],Ot(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function jt(t){var e=t.body,n=t.documentElement,i=Ot(10)&&getComputedStyle(n);return{height:It("Height",e,n,i),width:It("Width",e,n,i)}}var Pt=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},Mt=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),Ht=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t},Bt=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t};function Rt(t){return Bt({},t,{right:t.left+t.width,bottom:t.top+t.height})}function Ft(t){var e={};try{if(Ot(10)){e=t.getBoundingClientRect();var n=St(t,"top"),i=St(t,"left");e.top+=n,e.left+=i,e.bottom+=n,e.right+=i}else e=t.getBoundingClientRect()}catch(t){}var o={left:e.left,top:e.top,width:e.right-e.left,height:e.bottom-e.top},r="HTML"===t.nodeName?jt(t.ownerDocument):{},s=r.width||t.clientWidth||o.width,a=r.height||t.clientHeight||o.height,l=t.offsetWidth-s,c=t.offsetHeight-a;if(l||c){var u=yt(t);l-=Nt(u,"x"),c-=Nt(u,"y"),o.width-=l,o.height-=c}return Rt(o)}function Wt(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=Ot(10),o="HTML"===e.nodeName,r=Ft(t),s=Ft(e),a=Et(t),l=yt(e),c=parseFloat(l.borderTopWidth,10),u=parseFloat(l.borderLeftWidth,10);n&&o&&(s.top=Math.max(s.top,0),s.left=Math.max(s.left,0));var f=Rt({top:r.top-s.top-c,left:r.left-s.left-u,width:r.width,height:r.height});if(f.marginTop=0,f.marginLeft=0,!i&&o){var d=parseFloat(l.marginTop,10),h=parseFloat(l.marginLeft,10);f.top-=c-d,f.bottom-=c-d,f.left-=u-h,f.right-=u-h,f.marginTop=d,f.marginLeft=h}return(i&&!n?e.contains(a):e===a&&"BODY"!==a.nodeName)&&(f=xt(f,e)),f}function Ut(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=Wt(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),s=e?0:St(n),a=e?0:St(n,"left"),l={top:s-i.top+i.marginTop,left:a-i.left+i.marginLeft,width:o,height:r};return Rt(l)}function Qt(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===yt(t,"position"))return!0;var n=wt(t);return!!n&&Qt(n)}function Vt(t){if(!t||!t.parentElement||Ot())return document.documentElement;for(var e=t.parentElement;e&&"none"===yt(e,"transform");)e=e.parentElement;return e||document.documentElement}function qt(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},s=o?Vt(t):Dt(t,Tt(e));if("viewport"===i)r=Ut(s,o);else{var a=void 0;"scrollParent"===i?"BODY"===(a=Et(wt(e))).nodeName&&(a=t.ownerDocument.documentElement):a="window"===i?t.ownerDocument.documentElement:i;var l=Wt(a,s,o);if("HTML"!==a.nodeName||Qt(s))r=l;else{var c=jt(t.ownerDocument),u=c.height,f=c.width;r.top+=l.top-l.marginTop,r.bottom=u+l.top,r.left+=l.left-l.marginLeft,r.right=f+l.left}}var d="number"==typeof(n=n||0);return r.left+=d?n:n.left||0,r.top+=d?n:n.top||0,r.right-=d?n:n.right||0,r.bottom-=d?n:n.bottom||0,r}function Yt(t){return t.width*t.height}function zt(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var s=qt(n,i,r,o),a={top:{width:s.width,height:e.top-s.top},right:{width:s.right-e.right,height:s.height},bottom:{width:s.width,height:s.bottom-e.bottom},left:{width:e.left-s.left,height:s.height}},l=Object.keys(a).map((function(t){return Bt({key:t},a[t],{area:Yt(a[t])})})).sort((function(t,e){return e.area-t.area})),c=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),u=c.length>0?c[0].key:l[0].key,f=t.split("-")[1];return u+(f?"-"+f:"")}function Kt(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?Vt(e):Dt(e,Tt(n));return Wt(n,o,i)}function Xt(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function Gt(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function $t(t,e,n){n=n.split("-")[0];var i=Xt(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),s=r?"top":"left",a=r?"left":"top",l=r?"height":"width",c=r?"width":"height";return o[s]=e[s]+e[l]/2-i[l]/2,o[a]=n===a?e[a]-i[c]:e[Gt(a)],o}function Zt(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function Jt(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=Zt(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&bt(n)&&(e.offsets.popper=Rt(e.offsets.popper),e.offsets.reference=Rt(e.offsets.reference),e=n(e,t))})),e}function te(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=Kt(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=zt(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=$t(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=Jt(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function ee(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function ne(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i<e.length;i++){var o=e[i],r=o?""+o+n:t;if(void 0!==document.body.style[r])return r}return null}function ie(){return this.state.isDestroyed=!0,ee(this.modifiers,"applyStyle")&&(this.popper.removeAttribute("x-placement"),this.popper.style.position="",this.popper.style.top="",this.popper.style.left="",this.popper.style.right="",this.popper.style.bottom="",this.popper.style.willChange="",this.popper.style[ne("transform")]=""),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function oe(t){var e=t.ownerDocument;return e?e.defaultView:window}function re(t,e,n,i){n.updateBound=i,oe(t).addEventListener("resize",n.updateBound,{passive:!0});var o=Et(t);return function t(e,n,i,o){var r="BODY"===e.nodeName,s=r?e.ownerDocument.defaultView:e;s.addEventListener(n,i,{passive:!0}),r||t(Et(s.parentNode),n,i,o),o.push(s)}(o,"scroll",n.updateBound,n.scrollParents),n.scrollElement=o,n.eventsEnabled=!0,n}function se(){this.state.eventsEnabled||(this.state=re(this.reference,this.options,this.state,this.scheduleUpdate))}function ae(){var t,e;this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=(t=this.reference,e=this.state,oe(t).removeEventListener("resize",e.updateBound),e.scrollParents.forEach((function(t){t.removeEventListener("scroll",e.updateBound)})),e.updateBound=null,e.scrollParents=[],e.scrollElement=null,e.eventsEnabled=!1,e))}function le(t){return""!==t&&!isNaN(parseFloat(t))&&isFinite(t)}function ce(t,e){Object.keys(e).forEach((function(n){var i="";-1!==["width","height","top","right","bottom","left"].indexOf(n)&&le(e[n])&&(i="px"),t.style[n]=e[n]+i}))}var ue=mt&&/Firefox/i.test(navigator.userAgent);function fe(t,e,n){var i=Zt(t,(function(t){return t.name===e})),o=!!i&&t.some((function(t){return t.name===n&&t.enabled&&t.order<i.order}));if(!o){var r="`"+e+"`",s="`"+n+"`";console.warn(s+" modifier is required by "+r+" modifier in order to work, be sure to include it before "+r+"!")}return o}var de=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],he=de.slice(3);function pe(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=he.indexOf(t),i=he.slice(n+1).concat(he.slice(0,n));return e?i.reverse():i}var ge="flip",me="clockwise",ve="counterclockwise";function _e(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),s=t.split(/(\+|\-)/).map((function(t){return t.trim()})),a=s.indexOf(Zt(s,(function(t){return-1!==t.search(/,|\s/)})));s[a]&&-1===s[a].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,c=-1!==a?[s.slice(0,a).concat([s[a].split(l)[0]]),[s[a].split(l)[1]].concat(s.slice(a+1))]:[s];return(c=c.map((function(t,i){var o=(1===i?!r:r)?"height":"width",s=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,s=!0,t):s?(t[t.length-1]+=e,s=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],s=o[2];if(!r)return t;if(0===s.indexOf("%")){var a=void 0;switch(s){case"%p":a=n;break;case"%":case"%r":default:a=i}return Rt(a)[e]/100*r}if("vh"===s||"vw"===s){return("vh"===s?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r}return r}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){le(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var be={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,s=o.popper,a=-1!==["bottom","top"].indexOf(n),l=a?"left":"top",c=a?"width":"height",u={start:Ht({},l,r[l]),end:Ht({},l,r[l]+r[c]-s[c])};t.offsets.popper=Bt({},s,u[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,o=t.offsets,r=o.popper,s=o.reference,a=i.split("-")[0],l=void 0;return l=le(+n)?[+n,0]:_e(n,r,s,a),"left"===a?(r.top+=l[0],r.left-=l[1]):"right"===a?(r.top+=l[0],r.left+=l[1]):"top"===a?(r.left+=l[0],r.top-=l[1]):"bottom"===a&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||Ct(t.instance.popper);t.instance.reference===n&&(n=Ct(n));var i=ne("transform"),o=t.instance.popper.style,r=o.top,s=o.left,a=o[i];o.top="",o.left="",o[i]="";var l=qt(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=s,o[i]=a,e.boundaries=l;var c=e.priority,u=t.offsets.popper,f={primary:function(t){var n=u[t];return u[t]<l[t]&&!e.escapeWithReference&&(n=Math.max(u[t],l[t])),Ht({},t,n)},secondary:function(t){var n="right"===t?"left":"top",i=u[n];return u[t]>l[t]&&!e.escapeWithReference&&(i=Math.min(u[n],l[t]-("right"===t?u.width:u.height))),Ht({},n,i)}};return c.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";u=Bt({},u,f[e](t))})),t.offsets.popper=u,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,s=-1!==["top","bottom"].indexOf(o),a=s?"right":"bottom",l=s?"left":"top",c=s?"width":"height";return n[a]<r(i[l])&&(t.offsets.popper[l]=r(i[l])-n[c]),n[l]>r(i[a])&&(t.offsets.popper[l]=r(i[a])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!fe(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,s=r.popper,a=r.reference,l=-1!==["left","right"].indexOf(o),c=l?"height":"width",u=l?"Top":"Left",f=u.toLowerCase(),d=l?"left":"top",h=l?"bottom":"right",p=Xt(i)[c];a[h]-p<s[f]&&(t.offsets.popper[f]-=s[f]-(a[h]-p)),a[f]+p>s[h]&&(t.offsets.popper[f]+=a[f]+p-s[h]),t.offsets.popper=Rt(t.offsets.popper);var g=a[f]+a[c]/2-p/2,m=yt(t.instance.popper),v=parseFloat(m["margin"+u],10),_=parseFloat(m["border"+u+"Width"],10),b=g-t.offsets.popper[f]-v-_;return b=Math.max(Math.min(s[c]-p,b),0),t.arrowElement=i,t.offsets.arrow=(Ht(n={},f,Math.round(b)),Ht(n,d,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(ee(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=qt(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=Gt(i),r=t.placement.split("-")[1]||"",s=[];switch(e.behavior){case ge:s=[i,o];break;case me:s=pe(i);break;case ve:s=pe(i,!0);break;default:s=e.behavior}return s.forEach((function(a,l){if(i!==a||s.length===l+1)return t;i=t.placement.split("-")[0],o=Gt(i);var c=t.offsets.popper,u=t.offsets.reference,f=Math.floor,d="left"===i&&f(c.right)>f(u.left)||"right"===i&&f(c.left)<f(u.right)||"top"===i&&f(c.bottom)>f(u.top)||"bottom"===i&&f(c.top)<f(u.bottom),h=f(c.left)<f(n.left),p=f(c.right)>f(n.right),g=f(c.top)<f(n.top),m=f(c.bottom)>f(n.bottom),v="left"===i&&h||"right"===i&&p||"top"===i&&g||"bottom"===i&&m,_=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(_&&"start"===r&&h||_&&"end"===r&&p||!_&&"start"===r&&g||!_&&"end"===r&&m),y=!!e.flipVariationsByContent&&(_&&"start"===r&&p||_&&"end"===r&&h||!_&&"start"===r&&m||!_&&"end"===r&&g),w=b||y;(d||v||w)&&(t.flipped=!0,(d||v)&&(i=s[l+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=Bt({},t.offsets.popper,$t(t.instance.popper,t.offsets.reference,t.placement)),t=Jt(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,s=-1!==["left","right"].indexOf(n),a=-1===["top","left"].indexOf(n);return o[s?"left":"top"]=r[n]-(a?o[s?"width":"height"]:0),t.placement=Gt(e),t.offsets.popper=Rt(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!fe(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=Zt(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottom<n.top||e.left>n.right||e.top>n.bottom||e.right<n.left){if(!0===t.hide)return t;t.hide=!0,t.attributes["x-out-of-boundaries"]=""}else{if(!1===t.hide)return t;t.hide=!1,t.attributes["x-out-of-boundaries"]=!1}return t}},computeStyle:{order:850,enabled:!0,fn:function(t,e){var n=e.x,i=e.y,o=t.offsets.popper,r=Zt(t.instance.modifiers,(function(t){return"applyStyle"===t.name})).gpuAcceleration;void 0!==r&&console.warn("WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!");var s=void 0!==r?r:e.gpuAcceleration,a=Ct(t.instance.popper),l=Ft(a),c={position:o.position},u=function(t,e){var n=t.offsets,i=n.popper,o=n.reference,r=Math.round,s=Math.floor,a=function(t){return t},l=r(o.width),c=r(i.width),u=-1!==["left","right"].indexOf(t.placement),f=-1!==t.placement.indexOf("-"),d=e?u||f||l%2==c%2?r:s:a,h=e?r:a;return{left:d(l%2==1&&c%2==1&&!f&&e?i.left-1:i.left),top:h(i.top),bottom:h(i.bottom),right:d(i.right)}}(t,window.devicePixelRatio<2||!ue),f="bottom"===n?"top":"bottom",d="right"===i?"left":"right",h=ne("transform"),p=void 0,g=void 0;if(g="bottom"===f?"HTML"===a.nodeName?-a.clientHeight+u.bottom:-l.height+u.bottom:u.top,p="right"===d?"HTML"===a.nodeName?-a.clientWidth+u.right:-l.width+u.right:u.left,s&&h)c[h]="translate3d("+p+"px, "+g+"px, 0)",c[f]=0,c[d]=0,c.willChange="transform";else{var m="bottom"===f?-1:1,v="right"===d?-1:1;c[f]=g*m,c[d]=p*v,c.willChange=f+", "+d}var _={"x-placement":t.placement};return t.attributes=Bt({},_,t.attributes),t.styles=Bt({},c,t.styles),t.arrowStyles=Bt({},t.offsets.arrow,t.arrowStyles),t},gpuAcceleration:!0,x:"bottom",y:"right"},applyStyle:{order:900,enabled:!0,fn:function(t){return ce(t.instance.popper,t.styles),function(t,e){Object.keys(e).forEach((function(n){!1!==e[n]?t.setAttribute(n,e[n]):t.removeAttribute(n)}))}(t.instance.popper,t.attributes),t.arrowElement&&Object.keys(t.arrowStyles).length&&ce(t.arrowElement,t.arrowStyles),t},onLoad:function(t,e,n,i,o){var r=Kt(o,e,t,n.positionFixed),s=zt(n.placement,r,e,t,n.modifiers.flip.boundariesElement,n.modifiers.flip.padding);return e.setAttribute("x-placement",s),ce(e,{position:n.positionFixed?"fixed":"absolute"}),n},gpuAcceleration:void 0}}},ye=function(){function t(e,n){var i=this,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};Pt(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=_t(this.update.bind(this)),this.options=Bt({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(Bt({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){i.options.modifiers[e]=Bt({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return Bt({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&bt(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return Mt(t,[{key:"update",value:function(){return te.call(this)}},{key:"destroy",value:function(){return ie.call(this)}},{key:"enableEventListeners",value:function(){return se.call(this)}},{key:"disableEventListeners",value:function(){return ae.call(this)}}]),t}();ye.Utils=("undefined"!=typeof window?window:global).PopperUtils,ye.placements=de,ye.Defaults=be;var we="dropdown",Ee=new RegExp("ArrowUp|ArrowDown|Escape"),Te={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},Le={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},ke=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners(),T(t,"bs.dropdown",this)}var n=t.prototype;return n.toggle=function(){if(!this._element.disabled&&!this._element.classList.contains("disabled")){var e=this._element.classList.contains("show");t.clearMenus(),e||this.show()}},n.show=function(){if(!(this._element.disabled||this._element.classList.contains("disabled")||this._menu.classList.contains("show"))){var e=t.getParentFromElement(this._element),n={relatedTarget:this._element};if(!V.trigger(this._element,"show.bs.dropdown",n).defaultPrevented){if(!this._inNavbar){if(void 0===ye)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org)");var i=this._element;"parent"===this._config.reference?i=e:g(this._config.reference)&&(i=this._config.reference,void 0!==this._config.reference.jquery&&(i=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e.classList.add("position-static"),this._popper=new ye(i,this._menu,this._getPopperConfig())}var o;if("ontouchstart"in document.documentElement&&!e.closest(".navbar-nav"))(o=[]).concat.apply(o,document.body.children).forEach((function(t){return V.on(t,"mouseover",null,(function(){}))}));this._element.focus(),this._element.setAttribute("aria-expanded",!0),et.toggleClass(this._menu,"show"),et.toggleClass(this._element,"show"),V.trigger(e,"shown.bs.dropdown",n)}}},n.hide=function(){if(!this._element.disabled&&!this._element.classList.contains("disabled")&&this._menu.classList.contains("show")){var e=t.getParentFromElement(this._element),n={relatedTarget:this._element};V.trigger(e,"hide.bs.dropdown",n).defaultPrevented||(this._popper&&this._popper.destroy(),et.toggleClass(this._menu,"show"),et.toggleClass(this._element,"show"),V.trigger(e,"hidden.bs.dropdown",n))}},n.dispose=function(){k(this._element,"bs.dropdown"),V.off(this._element,".bs.dropdown"),this._element=null,this._menu=null,this._popper&&(this._popper.destroy(),this._popper=null)},n.update=function(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.scheduleUpdate()},n._addEventListeners=function(){var t=this;V.on(this._element,"click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},n._getConfig=function(t){return t=o(o(o({},this.constructor.Default),et.getDataAttributes(this._element)),t),v(we,t,this.constructor.DefaultType),t},n._getMenuElement=function(){return X.next(this._element,".dropdown-menu")[0]},n._getPlacement=function(){var t=this._element.parentNode,e="bottom-start";return t.classList.contains("dropup")?(e="top-start",this._menu.classList.contains("dropdown-menu-right")&&(e="top-end")):t.classList.contains("dropright")?e="right-start":t.classList.contains("dropleft")?e="left-start":this._menu.classList.contains("dropdown-menu-right")&&(e="bottom-end"),e},n._detectNavbar=function(){return Boolean(this._element.closest(".navbar"))},n._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=o(o({},e.offsets),t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},n._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),o(o({},t),this._config.popperConfig)},t.dropdownInterface=function(e,n){var i=L(e,"bs.dropdown");if(i||(i=new t(e,"object"==typeof n?n:null)),"string"==typeof n){if(void 0===i[n])throw new TypeError('No method named "'+n+'"');i[n]()}},t.jQueryInterface=function(e){return this.each((function(){t.dropdownInterface(this,e)}))},t.clearMenus=function(e){if(!e||2!==e.button&&("keyup"!==e.type||"Tab"===e.key))for(var n=X.find('[data-toggle="dropdown"]'),i=0,o=n.length;i<o;i++){var r=t.getParentFromElement(n[i]),s=L(n[i],"bs.dropdown"),a={relatedTarget:n[i]};if(e&&"click"===e.type&&(a.clickEvent=e),s){var l=s._menu;if(n[i].classList.contains("show"))if(!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&"Tab"===e.key)&&l.contains(e.target)))if(!V.trigger(r,"hide.bs.dropdown",a).defaultPrevented){var c;if("ontouchstart"in document.documentElement)(c=[]).concat.apply(c,document.body.children).forEach((function(t){return V.off(t,"mouseover",null,(function(){}))}));n[i].setAttribute("aria-expanded","false"),s._popper&&s._popper.destroy(),l.classList.remove("show"),n[i].classList.remove("show"),V.trigger(r,"hidden.bs.dropdown",a)}}}},t.getParentFromElement=function(t){return d(t)||t.parentNode},t.dataApiKeydownHandler=function(e){if(!(/input|textarea/i.test(e.target.tagName)?"Space"===e.key||"Escape"!==e.key&&("ArrowDown"!==e.key&&"ArrowUp"!==e.key||e.target.closest(".dropdown-menu")):!Ee.test(e.key))&&(e.preventDefault(),e.stopPropagation(),!this.disabled&&!this.classList.contains("disabled"))){var n=t.getParentFromElement(this),i=this.classList.contains("show");if("Escape"===e.key)return(this.matches('[data-toggle="dropdown"]')?this:X.prev(this,'[data-toggle="dropdown"]')[0]).focus(),void t.clearMenus();if(i&&"Space"!==e.key){var o=X.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",n).filter(_);if(o.length){var r=o.indexOf(e.target);"ArrowUp"===e.key&&r>0&&r--,"ArrowDown"===e.key&&r<o.length-1&&r++,o[r=-1===r?0:r].focus()}}else t.clearMenus()}},t.getInstance=function(t){return L(t,"bs.dropdown")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return Te}},{key:"DefaultType",get:function(){return Le}}]),t}();V.on(document,"keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',ke.dataApiKeydownHandler),V.on(document,"keydown.bs.dropdown.data-api",".dropdown-menu",ke.dataApiKeydownHandler),V.on(document,"click.bs.dropdown.data-api",ke.clearMenus),V.on(document,"keyup.bs.dropdown.data-api",ke.clearMenus),V.on(document,"click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),ke.dropdownInterface(this,"toggle")})),V.on(document,"click.bs.dropdown.data-api",".dropdown form",(function(t){return t.stopPropagation()}));var Oe=w();if(Oe){var Ce=Oe.fn[we];Oe.fn[we]=ke.jQueryInterface,Oe.fn[we].Constructor=ke,Oe.fn[we].noConflict=function(){return Oe.fn[we]=Ce,ke.jQueryInterface}}var Ae={backdrop:!0,keyboard:!0,focus:!0,show:!0},De={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},Se=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=X.findOne(".modal-dialog",t),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0,T(t,"bs.modal",this)}var n=t.prototype;return n.toggle=function(t){return this._isShown?this.hide():this.show(t)},n.show=function(t){var e=this;if(!this._isShown&&!this._isTransitioning){this._element.classList.contains("fade")&&(this._isTransitioning=!0);var n=V.trigger(this._element,"show.bs.modal",{relatedTarget:t});this._isShown||n.defaultPrevented||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),V.on(this._element,"click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return e.hide(t)})),V.on(this._dialog,"mousedown.dismiss.bs.modal",(function(){V.one(e._element,"mouseup.dismiss.bs.modal",(function(t){t.target===e._element&&(e._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return e._showElement(t)})))}},n.hide=function(t){var e=this;if((t&&t.preventDefault(),this._isShown&&!this._isTransitioning)&&!V.trigger(this._element,"hide.bs.modal").defaultPrevented){this._isShown=!1;var n=this._element.classList.contains("fade");if(n&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),V.off(document,"focusin.bs.modal"),this._element.classList.remove("show"),V.off(this._element,"click.dismiss.bs.modal"),V.off(this._dialog,"mousedown.dismiss.bs.modal"),n){var i=h(this._element);V.one(this._element,"transitionend",(function(t){return e._hideModal(t)})),m(this._element,i)}else this._hideModal()}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return V.off(t,".bs.modal")})),V.off(document,"focusin.bs.modal"),k(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(t){return t=o(o({},Ae),t),v("modal",t,De),t},n._showElement=function(t){var e=this,n=this._element.classList.contains("fade"),i=X.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.scrollTop=0,i&&(i.scrollTop=0),n&&y(this._element),this._element.classList.add("show"),this._config.focus&&this._enforceFocus();var o=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,V.trigger(e._element,"shown.bs.modal",{relatedTarget:t})};if(n){var r=h(this._dialog);V.one(this._dialog,"transitionend",o),m(this._dialog,r)}else o()},n._enforceFocus=function(){var t=this;V.off(document,"focusin.bs.modal"),V.on(document,"focusin.bs.modal",(function(e){document===e.target||t._element===e.target||t._element.contains(e.target)||t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?V.on(this._element,"keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&"Escape"===e.key?(e.preventDefault(),t.hide()):t._config.keyboard||"Escape"!==e.key||t._triggerBackdropTransition()})):V.off(this._element,"keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?V.on(window,"resize.bs.modal",(function(){return t._adjustDialog()})):V.off(window,"resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._isTransitioning=!1,this._showBackdrop((function(){document.body.classList.remove("modal-open"),t._resetAdjustments(),t._resetScrollbar(),V.trigger(t._element,"hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop.parentNode.removeChild(this._backdrop),this._backdrop=null},n._showBackdrop=function(t){var e=this,n=this._element.classList.contains("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),document.body.appendChild(this._backdrop),V.on(this._element,"click.dismiss.bs.modal",(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&e._triggerBackdropTransition()})),n&&y(this._backdrop),this._backdrop.classList.add("show"),!n)return void t();var i=h(this._backdrop);V.one(this._backdrop,"transitionend",t),m(this._backdrop,i)}else if(!this._isShown&&this._backdrop){this._backdrop.classList.remove("show");var o=function(){e._removeBackdrop(),t()};if(this._element.classList.contains("fade")){var r=h(this._backdrop);V.one(this._backdrop,"transitionend",o),m(this._backdrop,r)}else o()}else t()},n._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){if(V.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;this._element.classList.add("modal-static");var e=h(this._element);V.one(this._element,"transitionend",(function(){t._element.classList.remove("modal-static")})),m(this._element,e),this._element.focus()}else this.hide()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect(),e=t.left,n=t.right;this._isBodyOverflowing=Math.floor(e+n)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){X.find(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top").forEach((function(e){var n=e.style.paddingRight,i=window.getComputedStyle(e)["padding-right"];et.setDataAttribute(e,"padding-right",n),e.style.paddingRight=parseFloat(i)+t._scrollbarWidth+"px"})),X.find(".sticky-top").forEach((function(e){var n=e.style.marginRight,i=window.getComputedStyle(e)["margin-right"];et.setDataAttribute(e,"margin-right",n),e.style.marginRight=parseFloat(i)-t._scrollbarWidth+"px"}));var e=document.body.style.paddingRight,n=window.getComputedStyle(document.body)["padding-right"];et.setDataAttribute(document.body,"padding-right",e),document.body.style.paddingRight=parseFloat(n)+this._scrollbarWidth+"px"}document.body.classList.add("modal-open")},n._resetScrollbar=function(){X.find(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top").forEach((function(t){var e=et.getDataAttribute(t,"padding-right");void 0!==e&&(et.removeDataAttribute(t,"padding-right"),t.style.paddingRight=e)})),X.find(".sticky-top").forEach((function(t){var e=et.getDataAttribute(t,"margin-right");void 0!==e&&(et.removeDataAttribute(t,"margin-right"),t.style.marginRight=e)}));var t=et.getDataAttribute(document.body,"padding-right");void 0===t?document.body.style.paddingRight="":(et.removeDataAttribute(document.body,"padding-right"),document.body.style.paddingRight=t)},n._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t.jQueryInterface=function(e,n){return this.each((function(){var i=L(this,"bs.modal"),r=o(o(o({},Ae),et.getDataAttributes(this)),"object"==typeof e&&e?e:{});if(i||(i=new t(this,r)),"string"==typeof e){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e](n)}else r.show&&i.show(n)}))},t.getInstance=function(t){return L(t,"bs.modal")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return Ae}}]),t}();V.on(document,"click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var e=this,n=d(this);"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault(),V.one(n,"show.bs.modal",(function(t){t.defaultPrevented||V.one(n,"hidden.bs.modal",(function(){_(e)&&e.focus()}))}));var i=L(n,"bs.modal");if(!i){var r=o(o({},et.getDataAttributes(n)),et.getDataAttributes(this));i=new Se(n,r)}i.show(this)}));var xe=w();if(xe){var Ne=xe.fn.modal;xe.fn.modal=Se.jQueryInterface,xe.fn.modal.Constructor=Se,xe.fn.modal.noConflict=function(){return xe.fn.modal=Ne,Se.jQueryInterface}}var Ie=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],je=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,Pe=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Me={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]};function He(t,e,n){var i;if(!t.length)return t;if(n&&"function"==typeof n)return n(t);for(var o=(new window.DOMParser).parseFromString(t,"text/html"),r=Object.keys(e),s=(i=[]).concat.apply(i,o.body.querySelectorAll("*")),a=function(t,n){var i,o=s[t],a=o.nodeName.toLowerCase();if(-1===r.indexOf(a))return o.parentNode.removeChild(o),"continue";var l=(i=[]).concat.apply(i,o.attributes),c=[].concat(e["*"]||[],e[a]||[]);l.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===Ie.indexOf(n)||(je.test(t.nodeValue)||Pe.test(t.nodeValue));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,r=i.length;o<r;o++)if(i[o].test(n))return!0;return!1})(t,c)||o.removeAttribute(t.nodeName)}))},l=0,c=s.length;l<c;l++)a(l);return o.body.innerHTML}var Be="tooltip",Re=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Fe=["sanitize","whiteList","sanitizeFn"],We={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},Ue={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Qe={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Me,popperConfig:null},Ve={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},qe=function(){function t(t,e){if(void 0===ye)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners(),T(t,this.constructor.DATA_KEY,this)}var n=t.prototype;return n.enable=function(){this._isEnabled=!0},n.disable=function(){this._isEnabled=!1},n.toggleEnabled=function(){this._isEnabled=!this._isEnabled},n.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=L(t.target,e);n||(n=new this.constructor(t.target,this._getDelegateConfig()),T(t.target,e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}},n.dispose=function(){clearTimeout(this._timeout),k(this.element,this.constructor.DATA_KEY),V.off(this.element,this.constructor.EVENT_KEY),V.off(this.element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.parentNode.removeChild(this.tip),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},n.show=function(){var t=this;if("none"===this.element.style.display)throw new Error("Please use show on visible elements");if(this.isWithContent()&&this._isEnabled){var e=V.trigger(this.element,this.constructor.Event.SHOW),n=function t(e){if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){var n=e.getRootNode();return n instanceof ShadowRoot?n:null}return e instanceof ShadowRoot?e:e.parentNode?t(e.parentNode):null}(this.element),i=null===n?this.element.ownerDocument.documentElement.contains(this.element):n.contains(this.element);if(e.defaultPrevented||!i)return;var o=this.getTipElement(),r=c(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&o.classList.add("fade");var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this._addAttachmentClass(a);var l,u=this._getContainer();if(T(o,this.constructor.DATA_KEY,this),this.element.ownerDocument.documentElement.contains(this.tip)||u.appendChild(o),V.trigger(this.element,this.constructor.Event.INSERTED),this._popper=new ye(this.element,o,this._getPopperConfig(a)),o.classList.add("show"),"ontouchstart"in document.documentElement)(l=[]).concat.apply(l,document.body.children).forEach((function(t){V.on(t,"mouseover",(function(){}))}));var f=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,V.trigger(t.element,t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(this.tip.classList.contains("fade")){var d=h(this.tip);V.one(this.tip,"transitionend",f),m(this.tip,d)}else f()}},n.hide=function(){var t=this,e=this.getTipElement(),n=function(){"show"!==t._hoverState&&e.parentNode&&e.parentNode.removeChild(e),t._cleanTipClass(),t.element.removeAttribute("aria-describedby"),V.trigger(t.element,t.constructor.Event.HIDDEN),t._popper.destroy()};if(!V.trigger(this.element,this.constructor.Event.HIDE).defaultPrevented){var i;if(e.classList.remove("show"),"ontouchstart"in document.documentElement)(i=[]).concat.apply(i,document.body.children).forEach((function(t){return V.off(t,"mouseover",b)}));if(this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this.tip.classList.contains("fade")){var o=h(e);V.one(e,"transitionend",n),m(e,o)}else n();this._hoverState=""}},n.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},n.isWithContent=function(){return Boolean(this.getTitle())},n.getTipElement=function(){if(this.tip)return this.tip;var t=document.createElement("div");return t.innerHTML=this.config.template,this.tip=t.children[0],this.tip},n.setContent=function(){var t=this.getTipElement();this.setElementContent(X.findOne(".tooltip-inner",t),this.getTitle()),t.classList.remove("fade","show")},n.setElementContent=function(t,e){if(null!==t)return"object"==typeof e&&g(e)?(e.jquery&&(e=e[0]),void(this.config.html?e.parentNode!==t&&(t.innerHTML="",t.appendChild(e)):t.textContent=e.textContent)):void(this.config.html?(this.config.sanitize&&(e=He(e,this.config.whiteList,this.config.sanitizeFn)),t.innerHTML=e):t.textContent=e)},n.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},n._getPopperConfig=function(t){var e=this;return o(o({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:"."+this.constructor.NAME+"-arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),this.config.popperConfig)},n._addAttachmentClass=function(t){this.getTipElement().classList.add("bs-tooltip-"+t)},n._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=o(o({},e.offsets),t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},n._getContainer=function(){return!1===this.config.container?document.body:g(this.config.container)?this.config.container:X.findOne(this.config.container)},n._getAttachment=function(t){return Ue[t.toUpperCase()]},n._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)V.on(t.element,t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;V.on(t.element,n,t.config.selector,(function(e){return t._enter(e)})),V.on(t.element,i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},V.on(this.element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=o(o({},this.config),{},{trigger:"manual",selector:""}):this._fixTitle()},n._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},n._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||L(t.target,n))||(e=new this.constructor(t.target,this._getDelegateConfig()),T(t.target,n,e)),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},n._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||L(t.target,n))||(e=new this.constructor(t.target,this._getDelegateConfig()),T(t.target,n,e)),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},n._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},n._getConfig=function(t){var e=et.getDataAttributes(this.element);return Object.keys(e).forEach((function(t){-1!==Fe.indexOf(t)&&delete e[t]})),t&&"object"==typeof t.container&&t.container.jquery&&(t.container=t.container[0]),"number"==typeof(t=o(o(o({},this.constructor.Default),e),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),v(Be,t,this.constructor.DefaultType),t.sanitize&&(t.template=He(t.template,t.whiteList,t.sanitizeFn)),t},n._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},n._cleanTipClass=function(){var t=this.getTipElement(),e=t.getAttribute("class").match(Re);null!==e&&e.length>0&&e.map((function(t){return t.trim()})).forEach((function(e){return t.classList.remove(e)}))},n._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(t.placement))},n._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(t.classList.remove("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.tooltip"),i="object"==typeof e&&e;if((n||!/dispose|hide/.test(e))&&(n||(n=new t(this,i)),"string"==typeof e)){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t.getInstance=function(t){return L(t,"bs.tooltip")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return Qe}},{key:"NAME",get:function(){return Be}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Ve}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return We}}]),t}(),Ye=w();if(Ye){var ze=Ye.fn[Be];Ye.fn[Be]=qe.jQueryInterface,Ye.fn[Be].Constructor=qe,Ye.fn[Be].noConflict=function(){return Ye.fn[Be]=ze,qe.jQueryInterface}}var Ke="popover",Xe=new RegExp("(^|\\s)bs-popover\\S+","g"),Ge=o(o({},qe.Default),{},{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),$e=o(o({},qe.DefaultType),{},{content:"(string|element|function)"}),Ze={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Je=function(t){var n,i;function o(){return t.apply(this,arguments)||this}i=t,(n=o).prototype=Object.create(i.prototype),n.prototype.constructor=n,n.__proto__=i;var r=o.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.setContent=function(){var t=this.getTipElement();this.setElementContent(X.findOne(".popover-header",t),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(X.findOne(".popover-body",t),e),t.classList.remove("fade","show")},r._addAttachmentClass=function(t){this.getTipElement().classList.add("bs-popover-"+t)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=this.getTipElement(),e=t.getAttribute("class").match(Xe);null!==e&&e.length>0&&e.map((function(t){return t.trim()})).forEach((function(e){return t.classList.remove(e)}))},o.jQueryInterface=function(t){return this.each((function(){var e=L(this,"bs.popover"),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new o(this,n),T(this,"bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},o.getInstance=function(t){return L(t,"bs.popover")},e(o,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return Ge}},{key:"NAME",get:function(){return Ke}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return Ze}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return $e}}]),o}(qe),tn=w();if(tn){var en=tn.fn[Ke];tn.fn[Ke]=Je.jQueryInterface,tn.fn[Ke].Constructor=Je,tn.fn[Ke].noConflict=function(){return tn.fn[Ke]=en,Je.jQueryInterface}}var nn="scrollspy",on={offset:10,method:"auto",target:""},rn={offset:"number",method:"string",target:"(string|element)"},sn=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,V.on(this._scrollElement,"scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process(),T(t,"bs.scrollspy",this)}var n=t.prototype;return n.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,i="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),X.find(this._selector).map((function(t){var e,o=f(t);if(o&&(e=X.findOne(o)),e){var r=e.getBoundingClientRect();if(r.width||r.height)return[et[n](e).top+i,o]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){k(this._element,"bs.scrollspy"),V.off(this._scrollElement,".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=o(o({},on),"object"==typeof t&&t?t:{})).target){var e=t.target.id;e||(e=c(nn),t.target.id=e),t.target="#"+e}return v(nn,t,rn),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&(void 0===this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},n._activate=function(t){this._activeTarget=t,this._clear();var e=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),n=X.findOne(e.join(","));n.classList.contains("dropdown-item")?(X.findOne(".dropdown-toggle",n.closest(".dropdown")).classList.add("active"),n.classList.add("active")):(n.classList.add("active"),X.parents(n,".nav, .list-group").forEach((function(t){X.prev(t,".nav-link, .list-group-item").forEach((function(t){return t.classList.add("active")})),X.prev(t,".nav-item").forEach((function(t){X.children(t,".nav-link").forEach((function(t){return t.classList.add("active")}))}))}))),V.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})},n._clear=function(){X.find(this._selector).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.scrollspy");if(n||(n=new t(this,"object"==typeof e&&e)),"string"==typeof e){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t.getInstance=function(t){return L(t,"bs.scrollspy")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return on}}]),t}();V.on(window,"load.bs.scrollspy.data-api",(function(){X.find('[data-spy="scroll"]').forEach((function(t){return new sn(t,et.getDataAttributes(t))}))}));var an=w();if(an){var ln=an.fn[nn];an.fn[nn]=sn.jQueryInterface,an.fn[nn].Constructor=sn,an.fn[nn].noConflict=function(){return an.fn[nn]=ln,sn.jQueryInterface}}var cn=function(){function t(t){this._element=t,T(this._element,"bs.tab",this)}var n=t.prototype;return n.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains("active")||this._element.classList.contains("disabled"))){var e,n=d(this._element),i=this._element.closest(".nav, .list-group");if(i){var o="UL"===i.nodeName||"OL"===i.nodeName?":scope > li > .active":".active";e=(e=X.find(o,i))[e.length-1]}var r=null;if(e&&(r=V.trigger(e,"hide.bs.tab",{relatedTarget:this._element})),!(V.trigger(this._element,"show.bs.tab",{relatedTarget:e}).defaultPrevented||null!==r&&r.defaultPrevented)){this._activate(this._element,i);var s=function(){V.trigger(e,"hidden.bs.tab",{relatedTarget:t._element}),V.trigger(t._element,"shown.bs.tab",{relatedTarget:e})};n?this._activate(n,n.parentNode,s):s()}}},n.dispose=function(){k(this._element,"bs.tab"),this._element=null},n._activate=function(t,e,n){var i=this,o=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?X.children(e,".active"):X.find(":scope > li > .active",e))[0],r=n&&o&&o.classList.contains("fade"),s=function(){return i._transitionComplete(t,o,n)};if(o&&r){var a=h(o);o.classList.remove("show"),V.one(o,"transitionend",s),m(o,a)}else s()},n._transitionComplete=function(t,e,n){if(e){e.classList.remove("active");var i=X.findOne(":scope > .dropdown-menu .active",e.parentNode);i&&i.classList.remove("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}(t.classList.add("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),y(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&t.parentNode.classList.contains("dropdown-menu"))&&(t.closest(".dropdown")&&X.find(".dropdown-toggle").forEach((function(t){return t.classList.add("active")})),t.setAttribute("aria-expanded",!0));n&&n()},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.tab")||new t(this);if("string"==typeof e){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t.getInstance=function(t){return L(t,"bs.tab")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}}]),t}();V.on(document,"click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),(L(this,"bs.tab")||new cn(this)).show()}));var un=w();if(un){var fn=un.fn.tab;un.fn.tab=cn.jQueryInterface,un.fn.tab.Constructor=cn,un.fn.tab.noConflict=function(){return un.fn.tab=fn,cn.jQueryInterface}}var dn={animation:"boolean",autohide:"boolean",delay:"number"},hn={animation:!0,autohide:!0,delay:500},pn=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners(),T(t,"bs.toast",this)}var n=t.prototype;return n.show=function(){var t=this;if(!V.trigger(this._element,"show.bs.toast").defaultPrevented){this._config.animation&&this._element.classList.add("fade");var e=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),V.trigger(t._element,"shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),y(this._element),this._element.classList.add("showing"),this._config.animation){var n=h(this._element);V.one(this._element,"transitionend",e),m(this._element,n)}else e()}},n.hide=function(){var t=this;if(this._element.classList.contains("show")&&!V.trigger(this._element,"hide.bs.toast").defaultPrevented){var e=function(){t._element.classList.add("hide"),V.trigger(t._element,"hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=h(this._element);V.one(this._element,"transitionend",e),m(this._element,n)}else e()}},n.dispose=function(){clearTimeout(this._timeout),this._timeout=null,this._element.classList.contains("show")&&this._element.classList.remove("show"),V.off(this._element,"click.dismiss.bs.toast"),k(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=o(o(o({},hn),et.getDataAttributes(this._element)),"object"==typeof t&&t?t:{}),v("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;V.on(this._element,"click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.toast");if(n||(n=new t(this,"object"==typeof e&&e)),"string"==typeof e){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e](this)}}))},t.getInstance=function(t){return L(t,"bs.toast")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"DefaultType",get:function(){return dn}},{key:"Default",get:function(){return hn}}]),t}(),gn=w();if(gn){var mn=gn.fn.toast;gn.fn.toast=pn.jQueryInterface,gn.fn.toast.Constructor=pn,gn.fn.toast.noConflict=function(){return gn.fn.toast=mn,pn.jQueryInterface}}return{Alert:Y,Button:G,Carousel:at,Collapse:ht,Dropdown:ke,Modal:Se,Popover:Je,ScrollSpy:sn,Tab:cn,Toast:pn,Tooltip:qe}}));
diff --git a/src/lib/liquid.js b/src/lib/liquid.js
new file mode 100644
index 0000000..118b044
--- /dev/null
+++ b/src/lib/liquid.js
@@ -0,0 +1,3651 @@
+/*
+ * liquidjs@9.11.10, https://github.com/harttle/liquidjs
+ * (c) 2016-2020 harttle
+ * Released under the MIT License.
+ */
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (global = global || self, factory(global.liquidjs = {}));
+}(this, function (exports) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ function __awaiter(thisArg, _arguments, P, generator) {
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+ }
+
+ function __generator(thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (_) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+ }
+
+ function __values(o) {
+ var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+ if (m) return m.call(o);
+ return {
+ next: function () {
+ if (o && i >= o.length) o = void 0;
+ return { value: o && o[i++], done: !o };
+ }
+ };
+ }
+
+ function __read(o, n) {
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
+ if (!m) return o;
+ var i = m.call(o), r, ar = [], e;
+ try {
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
+ }
+ catch (error) { e = { error: error }; }
+ finally {
+ try {
+ if (r && !r.done && (m = i["return"])) m.call(i);
+ }
+ finally { if (e) throw e.error; }
+ }
+ return ar;
+ }
+
+ function __spread() {
+ for (var ar = [], i = 0; i < arguments.length; i++)
+ ar = ar.concat(__read(arguments[i]));
+ return ar;
+ }
+
+ var Drop = /** @class */ (function () {
+ function Drop() {
+ }
+ Drop.prototype.valueOf = function () {
+ return undefined;
+ };
+ Drop.prototype.liquidMethodMissing = function (key) {
+ return undefined;
+ };
+ return Drop;
+ }());
+
+ var toStr = Object.prototype.toString;
+ var toLowerCase = String.prototype.toLowerCase;
+ /*
+ * Checks if value is classified as a String primitive or object.
+ * @param {any} value The value to check.
+ * @return {Boolean} Returns true if value is a string, else false.
+ */
+ function isString(value) {
+ return toStr.call(value) === '[object String]';
+ }
+ function isFunction(value) {
+ return typeof value === 'function';
+ }
+ function stringify(value) {
+ value = toValue(value);
+ return isNil(value) ? '' : String(value);
+ }
+ function toValue(value) {
+ return value instanceof Drop ? value.valueOf() : value;
+ }
+ function isNumber(value) {
+ return typeof value === 'number';
+ }
+ function toLiquid(value) {
+ if (value && isFunction(value.toLiquid))
+ return toLiquid(value.toLiquid());
+ return value;
+ }
+ function isNil(value) {
+ return value === null || value === undefined;
+ }
+ function isArray(value) {
+ // be compatible with IE 8
+ return toStr.call(value) === '[object Array]';
+ }
+ /*
+ * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property.
+ * The iteratee is invoked with three arguments: (value, key, object).
+ * Iteratee functions may exit iteration early by explicitly returning false.
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Object} Returns object.
+ */
+ function forOwn(object, iteratee) {
+ object = object || {};
+ for (var k in object) {
+ if (object.hasOwnProperty(k)) {
+ if (iteratee(object[k], k, object) === false)
+ break;
+ }
+ }
+ return object;
+ }
+ function last(arr) {
+ return arr[arr.length - 1];
+ }
+ /*
+ * Checks if value is the language type of Object.
+ * (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))
+ * @param {any} value The value to check.
+ * @return {Boolean} Returns true if value is an object, else false.
+ */
+ function isObject(value) {
+ var type = typeof value;
+ return value !== null && (type === 'object' || type === 'function');
+ }
+ function range(start, stop, step) {
+ if (step === void 0) { step = 1; }
+ var arr = [];
+ for (var i = start; i < stop; i += step) {
+ arr.push(i);
+ }
+ return arr;
+ }
+ function padStart(str, length, ch) {
+ if (ch === void 0) { ch = ' '; }
+ return pad(str, length, ch, function (str, ch) { return ch + str; });
+ }
+ function padEnd(str, length, ch) {
+ if (ch === void 0) { ch = ' '; }
+ return pad(str, length, ch, function (str, ch) { return str + ch; });
+ }
+ function pad(str, length, ch, add) {
+ str = String(str);
+ var n = length - str.length;
+ while (n-- > 0)
+ str = add(str, ch);
+ return str;
+ }
+ function identify(val) {
+ return val;
+ }
+ function snakeCase(str) {
+ return str.replace(/(\w?)([A-Z])/g, function (_, a, b) { return (a ? a + '_' : '') + b.toLowerCase(); });
+ }
+ function changeCase(str) {
+ var hasLowerCase = __spread(str).some(function (ch) { return ch >= 'a' && ch <= 'z'; });
+ return hasLowerCase ? str.toUpperCase() : str.toLowerCase();
+ }
+ function ellipsis(str, N) {
+ return str.length > N ? str.substr(0, N - 3) + '...' : str;
+ }
+ // compare string in case-insensitive way, undefined values to the tail
+ function caseInsensitiveCompare(a, b) {
+ if (a == null && b == null)
+ return 0;
+ if (a == null)
+ return 1;
+ if (b == null)
+ return -1;
+ a = toLowerCase.call(a);
+ b = toLowerCase.call(b);
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+ }
+
+ var Node = /** @class */ (function () {
+ function Node(key, value, next, prev) {
+ this.key = key;
+ this.value = value;
+ this.next = next;
+ this.prev = prev;
+ }
+ return Node;
+ }());
+ var LRU = /** @class */ (function () {
+ function LRU(limit, size) {
+ if (size === void 0) { size = 0; }
+ this.limit = limit;
+ this.size = size;
+ this.cache = {};
+ this.head = new Node('HEAD', null, null, null);
+ this.tail = new Node('TAIL', null, null, null);
+ this.head.next = this.tail;
+ this.tail.prev = this.head;
+ }
+ LRU.prototype.write = function (key, value) {
+ if (this.cache[key]) {
+ this.cache[key].value = value;
+ }
+ else {
+ var node = new Node(key, value, this.head.next, this.head);
+ this.head.next.prev = node;
+ this.head.next = node;
+ this.cache[key] = node;
+ this.size++;
+ this.ensureLimit();
+ }
+ };
+ LRU.prototype.read = function (key) {
+ if (!this.cache[key])
+ return;
+ var value = this.cache[key].value;
+ this.remove(key);
+ this.write(key, value);
+ return value;
+ };
+ LRU.prototype.remove = function (key) {
+ var node = this.cache[key];
+ node.prev.next = node.next;
+ node.next.prev = node.prev;
+ delete this.cache[key];
+ this.size--;
+ };
+ LRU.prototype.clear = function () {
+ this.head.next = this.tail;
+ this.tail.prev = this.head;
+ this.size = 0;
+ this.cache = {};
+ };
+ LRU.prototype.ensureLimit = function () {
+ if (this.size > this.limit)
+ this.remove(this.tail.prev.key);
+ };
+ return LRU;
+ }());
+
+ var defaultOptions = {
+ root: ['.'],
+ cache: undefined,
+ extname: '',
+ dynamicPartials: true,
+ trimTagRight: false,
+ trimTagLeft: false,
+ trimOutputRight: false,
+ trimOutputLeft: false,
+ greedy: true,
+ tagDelimiterLeft: '{%',
+ tagDelimiterRight: '%}',
+ outputDelimiterLeft: '{{',
+ outputDelimiterRight: '}}',
+ strictFilters: false,
+ strictVariables: false,
+ globals: {}
+ };
+ function normalize(options) {
+ options = options || {};
+ if (options.hasOwnProperty('root')) {
+ options.root = normalizeStringArray(options.root);
+ }
+ if (options.hasOwnProperty('cache')) {
+ var cache = void 0;
+ if (typeof options.cache === 'number')
+ cache = options.cache > 0 ? new LRU(options.cache) : undefined;
+ else if (typeof options.cache === 'object')
+ cache = options.cache;
+ else
+ cache = options.cache ? new LRU(1024) : undefined;
+ options.cache = cache;
+ }
+ return options;
+ }
+ function applyDefault(options) {
+ return __assign({}, defaultOptions, options);
+ }
+ function normalizeStringArray(value) {
+ if (isArray(value))
+ return value;
+ if (isString(value))
+ return [value];
+ return [];
+ }
+
+ var Context = /** @class */ (function () {
+ function Context(env, opts, sync) {
+ if (env === void 0) { env = {}; }
+ if (opts === void 0) { opts = defaultOptions; }
+ if (sync === void 0) { sync = false; }
+ this.scopes = [{}];
+ this.registers = {};
+ this.sync = sync;
+ this.opts = opts;
+ this.globals = opts.globals;
+ this.environments = env;
+ }
+ Context.prototype.getRegister = function (key, defaultValue) {
+ if (defaultValue === void 0) { defaultValue = {}; }
+ return (this.registers[key] = this.registers[key] || defaultValue);
+ };
+ Context.prototype.setRegister = function (key, value) {
+ return (this.registers[key] = value);
+ };
+ Context.prototype.saveRegister = function () {
+ var _this = this;
+ var keys = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ keys[_i] = arguments[_i];
+ }
+ return keys.map(function (key) { return [key, _this.getRegister(key)]; });
+ };
+ Context.prototype.restoreRegister = function (keyValues) {
+ var _this = this;
+ return keyValues.forEach(function (_a) {
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
+ return _this.setRegister(key, value);
+ });
+ };
+ Context.prototype.getAll = function () {
+ return __spread([this.globals, this.environments], this.scopes).reduce(function (ctx, val) { return __assign(ctx, val); }, {});
+ };
+ Context.prototype.get = function (paths) {
+ var scope = this.findScope(paths[0]);
+ return this.getFromScope(scope, paths);
+ };
+ Context.prototype.getFromScope = function (scope, paths) {
+ var _this = this;
+ if (typeof paths === 'string')
+ paths = paths.split('.');
+ return paths.reduce(function (scope, path) {
+ scope = readProperty(scope, path);
+ if (isNil(scope) && _this.opts.strictVariables) {
+ throw new TypeError("undefined variable: " + path);
+ }
+ return scope;
+ }, scope);
+ };
+ Context.prototype.push = function (ctx) {
+ return this.scopes.push(ctx);
+ };
+ Context.prototype.pop = function () {
+ return this.scopes.pop();
+ };
+ Context.prototype.bottom = function () {
+ return this.scopes[0];
+ };
+ Context.prototype.findScope = function (key) {
+ for (var i = this.scopes.length - 1; i >= 0; i--) {
+ var candidate = this.scopes[i];
+ if (key in candidate)
+ return candidate;
+ }
+ if (key in this.environments)
+ return this.environments;
+ return this.globals;
+ };
+ return Context;
+ }());
+ function readProperty(obj, key) {
+ if (isNil(obj))
+ return obj;
+ obj = toLiquid(obj);
+ if (obj instanceof Drop) {
+ if (isFunction(obj[key]))
+ return obj[key]();
+ if (obj.hasOwnProperty(key))
+ return obj[key];
+ return obj.liquidMethodMissing(key);
+ }
+ if (key === 'size')
+ return readSize(obj);
+ if (key === 'first')
+ return readFirst(obj);
+ if (key === 'last')
+ return readLast(obj);
+ return obj[key];
+ }
+ function readFirst(obj) {
+ if (isArray(obj))
+ return obj[0];
+ return obj['first'];
+ }
+ function readLast(obj) {
+ if (isArray(obj))
+ return obj[obj.length - 1];
+ return obj['last'];
+ }
+ function readSize(obj) {
+ if (isArray(obj) || isString(obj))
+ return obj.length;
+ return obj['size'];
+ }
+
+ function domResolve(root, path) {
+ var base = document.createElement('base');
+ base.href = root;
+ var head = document.getElementsByTagName('head')[0];
+ head.insertBefore(base, head.firstChild);
+ var a = document.createElement('a');
+ a.href = path;
+ var resolved = a.href;
+ head.removeChild(base);
+ return resolved;
+ }
+ function resolve(root, filepath, ext) {
+ if (root.length && last(root) !== '/')
+ root += '/';
+ var url = domResolve(root, filepath);
+ return url.replace(/^(\w+:\/\/[^/]+)(\/[^?]+)/, function (str, origin, path) {
+ var last = path.split('/').pop();
+ if (/\.\w+$/.test(last))
+ return str;
+ return origin + path + ext;
+ });
+ }
+ function readFile(url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, new Promise(function (resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function () {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ resolve(xhr.responseText);
+ }
+ else {
+ reject(new Error(xhr.statusText));
+ }
+ };
+ xhr.onerror = function () {
+ reject(new Error('An error occurred whilst receiving the response.'));
+ };
+ xhr.open('GET', url);
+ xhr.send();
+ })];
+ });
+ });
+ }
+ function readFileSync(url) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url, false);
+ xhr.send();
+ if (xhr.status < 200 || xhr.status >= 300) {
+ throw new Error(xhr.statusText);
+ }
+ return xhr.responseText;
+ }
+ function exists(filepath) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, true];
+ });
+ });
+ }
+ function existsSync(filepath) {
+ return true;
+ }
+
+ var fs = /*#__PURE__*/Object.freeze({
+ resolve: resolve,
+ readFile: readFile,
+ readFileSync: readFileSync,
+ exists: exists,
+ existsSync: existsSync
+ });
+
+ var TokenKind;
+ (function (TokenKind) {
+ TokenKind[TokenKind["Number"] = 1] = "Number";
+ TokenKind[TokenKind["Literal"] = 2] = "Literal";
+ TokenKind[TokenKind["Tag"] = 4] = "Tag";
+ TokenKind[TokenKind["Output"] = 8] = "Output";
+ TokenKind[TokenKind["HTML"] = 16] = "HTML";
+ TokenKind[TokenKind["Filter"] = 32] = "Filter";
+ TokenKind[TokenKind["Hash"] = 64] = "Hash";
+ TokenKind[TokenKind["PropertyAccess"] = 128] = "PropertyAccess";
+ TokenKind[TokenKind["Word"] = 256] = "Word";
+ TokenKind[TokenKind["Range"] = 512] = "Range";
+ TokenKind[TokenKind["Quoted"] = 1024] = "Quoted";
+ TokenKind[TokenKind["Operator"] = 2048] = "Operator";
+ TokenKind[TokenKind["Delimited"] = 12] = "Delimited";
+ })(TokenKind || (TokenKind = {}));
+
+ function isDelimitedToken(val) {
+ return !!(getKind(val) & TokenKind.Delimited);
+ }
+ function isOperatorToken(val) {
+ return getKind(val) === TokenKind.Operator;
+ }
+ function isHTMLToken(val) {
+ return getKind(val) === TokenKind.HTML;
+ }
+ function isOutputToken(val) {
+ return getKind(val) === TokenKind.Output;
+ }
+ function isTagToken(val) {
+ return getKind(val) === TokenKind.Tag;
+ }
+ function isQuotedToken(val) {
+ return getKind(val) === TokenKind.Quoted;
+ }
+ function isLiteralToken(val) {
+ return getKind(val) === TokenKind.Literal;
+ }
+ function isNumberToken(val) {
+ return getKind(val) === TokenKind.Number;
+ }
+ function isPropertyAccessToken(val) {
+ return getKind(val) === TokenKind.PropertyAccess;
+ }
+ function isWordToken(val) {
+ return getKind(val) === TokenKind.Word;
+ }
+ function isRangeToken(val) {
+ return getKind(val) === TokenKind.Range;
+ }
+ function getKind(val) {
+ return val ? val.kind : -1;
+ }
+
+ var typeGuards = /*#__PURE__*/Object.freeze({
+ isDelimitedToken: isDelimitedToken,
+ isOperatorToken: isOperatorToken,
+ isHTMLToken: isHTMLToken,
+ isOutputToken: isOutputToken,
+ isTagToken: isTagToken,
+ isQuotedToken: isQuotedToken,
+ isLiteralToken: isLiteralToken,
+ isNumberToken: isNumberToken,
+ isPropertyAccessToken: isPropertyAccessToken,
+ isWordToken: isWordToken,
+ isRangeToken: isRangeToken
+ });
+
+ // **DO NOT CHANGE THIS FILE**
+ //
+ // This file is generated by bin/character-gen.js
+ // bitmask character types to boost performance
+ var TYPES = [0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 4, 4, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 8, 0, 0, 0, 0, 8, 0, 0, 0, 64, 0, 65, 0, 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 0, 0, 2, 2, 2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];
+ var VARIABLE = 1;
+ var BLANK = 4;
+ var QUOTE = 8;
+ var INLINE_BLANK = 16;
+ var NUMBER = 32;
+ var SIGN = 64;
+ TYPES[160] = TYPES[5760] = TYPES[6158] = TYPES[8192] = TYPES[8193] = TYPES[8194] = TYPES[8195] = TYPES[8196] = TYPES[8197] = TYPES[8198] = TYPES[8199] = TYPES[8200] = TYPES[8201] = TYPES[8202] = TYPES[8232] = TYPES[8233] = TYPES[8239] = TYPES[8287] = TYPES[12288] = BLANK;
+
+ function whiteSpaceCtrl(tokens, options) {
+ options = __assign({ greedy: true }, options);
+ var inRaw = false;
+ for (var i = 0; i < tokens.length; i++) {
+ var token = tokens[i];
+ if (!isDelimitedToken(token))
+ continue;
+ if (!inRaw && token.trimLeft) {
+ trimLeft(tokens[i - 1], options.greedy);
+ }
+ if (isTagToken(token)) {
+ if (token.name === 'raw')
+ inRaw = true;
+ else if (token.name === 'endraw')
+ inRaw = false;
+ }
+ if (!inRaw && token.trimRight) {
+ trimRight(tokens[i + 1], options.greedy);
+ }
+ }
+ }
+ function trimLeft(token, greedy) {
+ if (!token || !isHTMLToken(token))
+ return;
+ var mask = greedy ? BLANK : INLINE_BLANK;
+ while (TYPES[token.input.charCodeAt(token.end - 1 - token.trimRight)] & mask)
+ token.trimRight++;
+ }
+ function trimRight(token, greedy) {
+ if (!token || !isHTMLToken(token))
+ return;
+ var mask = greedy ? BLANK : INLINE_BLANK;
+ while (TYPES[token.input.charCodeAt(token.begin + token.trimLeft)] & mask)
+ token.trimLeft++;
+ if (token.input.charAt(token.begin + token.trimLeft) === '\n')
+ token.trimLeft++;
+ }
+
+ var Token = /** @class */ (function () {
+ function Token(kind, input, begin, end, file) {
+ this.kind = kind;
+ this.input = input;
+ this.begin = begin;
+ this.end = end;
+ this.file = file;
+ }
+ Token.prototype.getText = function () {
+ return this.input.slice(this.begin, this.end);
+ };
+ Token.prototype.getPosition = function () {
+ var _a = __read([1, 1], 2), row = _a[0], col = _a[1];
+ for (var i = 0; i < this.begin; i++) {
+ if (this.input[i] === '\n') {
+ row++;
+ col = 1;
+ }
+ else
+ col++;
+ }
+ return [row, col];
+ };
+ Token.prototype.size = function () {
+ return this.end - this.begin;
+ };
+ return Token;
+ }());
+
+ var NumberToken = /** @class */ (function (_super) {
+ __extends(NumberToken, _super);
+ function NumberToken(whole, decimal) {
+ var _this = _super.call(this, TokenKind.Number, whole.input, whole.begin, decimal ? decimal.end : whole.end, whole.file) || this;
+ _this.whole = whole;
+ _this.decimal = decimal;
+ return _this;
+ }
+ return NumberToken;
+ }(Token));
+
+ // a word can be an identifier, a number, a keyword or a single-word-literal
+ var WordToken = /** @class */ (function (_super) {
+ __extends(WordToken, _super);
+ function WordToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Word, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.content = _this.getText();
+ return _this;
+ }
+ WordToken.prototype.isNumber = function (allowSign) {
+ if (allowSign === void 0) { allowSign = false; }
+ var begin = allowSign && TYPES[this.input.charCodeAt(this.begin)] & SIGN
+ ? this.begin + 1
+ : this.begin;
+ for (var i = begin; i < this.end; i++) {
+ if (!(TYPES[this.input.charCodeAt(i)] & NUMBER))
+ return false;
+ }
+ return true;
+ };
+ return WordToken;
+ }(Token));
+
+ var EmptyDrop = /** @class */ (function (_super) {
+ __extends(EmptyDrop, _super);
+ function EmptyDrop() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ EmptyDrop.prototype.equals = function (value) {
+ if (isString(value) || isArray(value))
+ return value.length === 0;
+ if (isObject(value))
+ return Object.keys(value).length === 0;
+ return false;
+ };
+ EmptyDrop.prototype.gt = function () {
+ return false;
+ };
+ EmptyDrop.prototype.geq = function () {
+ return false;
+ };
+ EmptyDrop.prototype.lt = function () {
+ return false;
+ };
+ EmptyDrop.prototype.leq = function () {
+ return false;
+ };
+ EmptyDrop.prototype.valueOf = function () {
+ return '';
+ };
+ return EmptyDrop;
+ }(Drop));
+
+ var BlankDrop = /** @class */ (function (_super) {
+ __extends(BlankDrop, _super);
+ function BlankDrop() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ BlankDrop.prototype.equals = function (value) {
+ if (value === false)
+ return true;
+ if (isNil(toValue(value)))
+ return true;
+ if (isString(value))
+ return /^\s*$/.test(value);
+ return _super.prototype.equals.call(this, value);
+ };
+ return BlankDrop;
+ }(EmptyDrop));
+
+ var NullDrop = /** @class */ (function (_super) {
+ __extends(NullDrop, _super);
+ function NullDrop() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ NullDrop.prototype.equals = function (value) {
+ return isNil(toValue(value)) || value instanceof BlankDrop;
+ };
+ NullDrop.prototype.gt = function () {
+ return false;
+ };
+ NullDrop.prototype.geq = function () {
+ return false;
+ };
+ NullDrop.prototype.lt = function () {
+ return false;
+ };
+ NullDrop.prototype.leq = function () {
+ return false;
+ };
+ NullDrop.prototype.valueOf = function () {
+ return null;
+ };
+ return NullDrop;
+ }(Drop));
+
+ var literalValues = {
+ 'true': true,
+ 'false': false,
+ 'nil': new NullDrop(),
+ 'null': new NullDrop(),
+ 'empty': new EmptyDrop(),
+ 'blank': new BlankDrop()
+ };
+
+ var LiteralToken = /** @class */ (function (_super) {
+ __extends(LiteralToken, _super);
+ function LiteralToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Literal, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.literal = _this.getText();
+ return _this;
+ }
+ return LiteralToken;
+ }(Token));
+
+ var precedence = {
+ '==': 1,
+ '!=': 1,
+ '>': 1,
+ '<': 1,
+ '>=': 1,
+ '<=': 1,
+ 'contains': 1,
+ 'and': 0,
+ 'or': 0
+ };
+ var OperatorToken = /** @class */ (function (_super) {
+ __extends(OperatorToken, _super);
+ function OperatorToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Operator, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.operator = _this.getText();
+ return _this;
+ }
+ OperatorToken.prototype.getPrecedence = function () {
+ return precedence[this.getText()];
+ };
+ return OperatorToken;
+ }(Token));
+
+ var PropertyAccessToken = /** @class */ (function (_super) {
+ __extends(PropertyAccessToken, _super);
+ function PropertyAccessToken(variable, props, end) {
+ var _this = _super.call(this, TokenKind.PropertyAccess, variable.input, variable.begin, end, variable.file) || this;
+ _this.variable = variable;
+ _this.props = props;
+ return _this;
+ }
+ return PropertyAccessToken;
+ }(Token));
+
+ var LiquidError = /** @class */ (function (_super) {
+ __extends(LiquidError, _super);
+ function LiquidError(err, token) {
+ var _this = _super.call(this, err.message) || this;
+ _this.originalError = err;
+ _this.token = token;
+ return _this;
+ }
+ LiquidError.prototype.update = function () {
+ var err = this.originalError;
+ var context = mkContext(this.token);
+ this.message = mkMessage(err.message, this.token);
+ this.stack = this.message + '\n' + context +
+ '\n' + this.stack + '\nFrom ' + err.stack;
+ };
+ return LiquidError;
+ }(Error));
+ var TokenizationError = /** @class */ (function (_super) {
+ __extends(TokenizationError, _super);
+ function TokenizationError(message, token) {
+ var _this = _super.call(this, new Error(message), token) || this;
+ _this.name = 'TokenizationError';
+ _super.prototype.update.call(_this);
+ return _this;
+ }
+ return TokenizationError;
+ }(LiquidError));
+ var ParseError = /** @class */ (function (_super) {
+ __extends(ParseError, _super);
+ function ParseError(err, token) {
+ var _this = _super.call(this, err, token) || this;
+ _this.name = 'ParseError';
+ _this.message = err.message;
+ _super.prototype.update.call(_this);
+ return _this;
+ }
+ return ParseError;
+ }(LiquidError));
+ var RenderError = /** @class */ (function (_super) {
+ __extends(RenderError, _super);
+ function RenderError(err, tpl) {
+ var _this = _super.call(this, err, tpl.token) || this;
+ _this.name = 'RenderError';
+ _this.message = err.message;
+ _super.prototype.update.call(_this);
+ return _this;
+ }
+ RenderError.is = function (obj) {
+ return obj instanceof RenderError;
+ };
+ return RenderError;
+ }(LiquidError));
+ var AssertionError = /** @class */ (function (_super) {
+ __extends(AssertionError, _super);
+ function AssertionError(message) {
+ var _this = _super.call(this, message) || this;
+ _this.name = 'AssertionError';
+ _this.message = message + '';
+ return _this;
+ }
+ return AssertionError;
+ }(Error));
+ function mkContext(token) {
+ var _a = __read(token.getPosition(), 1), line = _a[0];
+ var lines = token.input.split('\n');
+ var begin = Math.max(line - 2, 1);
+ var end = Math.min(line + 3, lines.length);
+ var context = range(begin, end + 1)
+ .map(function (lineNumber) {
+ var indicator = (lineNumber === line) ? '>> ' : ' ';
+ var num = padStart(String(lineNumber), String(end).length);
+ var text = lines[lineNumber - 1];
+ return "" + indicator + num + "| " + text;
+ })
+ .join('\n');
+ return context;
+ }
+ function mkMessage(msg, token) {
+ if (token.file)
+ msg += ", file:" + token.file;
+ var _a = __read(token.getPosition(), 2), line = _a[0], col = _a[1];
+ msg += ", line:" + line + ", col:" + col;
+ return msg;
+ }
+
+ function assert(predicate, message) {
+ if (!predicate) {
+ var msg = message ? message() : "expect " + predicate + " to be true";
+ throw new AssertionError(msg);
+ }
+ }
+
+ var FilterToken = /** @class */ (function (_super) {
+ __extends(FilterToken, _super);
+ function FilterToken(name, args, input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Filter, input, begin, end, file) || this;
+ _this.name = name;
+ _this.args = args;
+ return _this;
+ }
+ return FilterToken;
+ }(Token));
+
+ var HashToken = /** @class */ (function (_super) {
+ __extends(HashToken, _super);
+ function HashToken(input, begin, end, name, value, file) {
+ var _this = _super.call(this, TokenKind.Hash, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.name = name;
+ _this.value = value;
+ _this.file = file;
+ return _this;
+ }
+ return HashToken;
+ }(Token));
+
+ var QuotedToken = /** @class */ (function (_super) {
+ __extends(QuotedToken, _super);
+ function QuotedToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Quoted, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ return _this;
+ }
+ return QuotedToken;
+ }(Token));
+
+ var HTMLToken = /** @class */ (function (_super) {
+ __extends(HTMLToken, _super);
+ function HTMLToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.HTML, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.trimLeft = 0;
+ _this.trimRight = 0;
+ return _this;
+ }
+ HTMLToken.prototype.getContent = function () {
+ return this.input.slice(this.begin + this.trimLeft, this.end - this.trimRight);
+ };
+ return HTMLToken;
+ }(Token));
+
+ var DelimitedToken = /** @class */ (function (_super) {
+ __extends(DelimitedToken, _super);
+ function DelimitedToken(kind, content, input, begin, end, trimLeft, trimRight, file) {
+ var _this = _super.call(this, kind, input, begin, end, file) || this;
+ _this.trimLeft = false;
+ _this.trimRight = false;
+ _this.content = _this.getText();
+ var tl = content[0] === '-';
+ var tr = last(content) === '-';
+ _this.content = content
+ .slice(tl ? 1 : 0, tr ? -1 : content.length)
+ .trim();
+ _this.trimLeft = tl || trimLeft;
+ _this.trimRight = tr || trimRight;
+ return _this;
+ }
+ return DelimitedToken;
+ }(Token));
+
+ var TagToken = /** @class */ (function (_super) {
+ __extends(TagToken, _super);
+ function TagToken(input, begin, end, options, file) {
+ var _this = this;
+ var trimTagLeft = options.trimTagLeft, trimTagRight = options.trimTagRight, tagDelimiterLeft = options.tagDelimiterLeft, tagDelimiterRight = options.tagDelimiterRight;
+ var value = input.slice(begin + tagDelimiterLeft.length, end - tagDelimiterRight.length);
+ _this = _super.call(this, TokenKind.Tag, value, input, begin, end, trimTagLeft, trimTagRight, file) || this;
+ var nameEnd = 0;
+ while (TYPES[_this.content.charCodeAt(nameEnd)] & VARIABLE)
+ nameEnd++;
+ _this.name = _this.content.slice(0, nameEnd);
+ if (!_this.name)
+ throw new TokenizationError("illegal tag syntax", _this);
+ var argsBegin = nameEnd;
+ while (TYPES[_this.content.charCodeAt(argsBegin)] & BLANK)
+ argsBegin++;
+ _this.args = _this.content.slice(argsBegin);
+ return _this;
+ }
+ return TagToken;
+ }(DelimitedToken));
+
+ var RangeToken = /** @class */ (function (_super) {
+ __extends(RangeToken, _super);
+ function RangeToken(input, begin, end, lhs, rhs, file) {
+ var _this = _super.call(this, TokenKind.Range, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.lhs = lhs;
+ _this.rhs = rhs;
+ _this.file = file;
+ return _this;
+ }
+ return RangeToken;
+ }(Token));
+
+ var OutputToken = /** @class */ (function (_super) {
+ __extends(OutputToken, _super);
+ function OutputToken(input, begin, end, options, file) {
+ var _this = this;
+ var trimOutputLeft = options.trimOutputLeft, trimOutputRight = options.trimOutputRight, outputDelimiterLeft = options.outputDelimiterLeft, outputDelimiterRight = options.outputDelimiterRight;
+ var value = input.slice(begin + outputDelimiterLeft.length, end - outputDelimiterRight.length);
+ _this = _super.call(this, TokenKind.Output, value, input, begin, end, trimOutputLeft, trimOutputRight, file) || this;
+ return _this;
+ }
+ return OutputToken;
+ }(DelimitedToken));
+
+ var trie = {
+ a: { n: { d: { end: true, needBoundary: true } } },
+ o: { r: { end: true, needBoundary: true } },
+ c: { o: { n: { t: { a: { i: { n: { s: { end: true, needBoundary: true } } } } } } } },
+ '=': { '=': { end: true } },
+ '!': { '=': { end: true } },
+ '>': { end: true, '=': { end: true } },
+ '<': { end: true, '=': { end: true } }
+ };
+ function matchOperator(str, begin, end) {
+ if (end === void 0) { end = str.length; }
+ var node = trie;
+ var i = begin;
+ var info;
+ while (node[str[i]] && i < end) {
+ node = node[str[i++]];
+ if (node['end'])
+ info = node;
+ }
+ if (!info)
+ return -1;
+ if (info['needBoundary'] && str.charCodeAt(i) & VARIABLE)
+ return -1;
+ return i;
+ }
+
+ var Tokenizer = /** @class */ (function () {
+ function Tokenizer(input, file) {
+ if (file === void 0) { file = ''; }
+ this.input = input;
+ this.file = file;
+ this.p = 0;
+ this.N = input.length;
+ }
+ Tokenizer.prototype.readExpression = function () {
+ var operand, operator, operand_1;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ operand = this.readValue();
+ if (!operand)
+ return [2 /*return*/];
+ return [4 /*yield*/, operand];
+ case 1:
+ _a.sent();
+ _a.label = 2;
+ case 2:
+ if (!(this.p < this.N)) return [3 /*break*/, 5];
+ operator = this.readOperator();
+ if (!operator)
+ return [2 /*return*/];
+ operand_1 = this.readValue();
+ if (!operand_1)
+ return [2 /*return*/];
+ return [4 /*yield*/, operator];
+ case 3:
+ _a.sent();
+ return [4 /*yield*/, operand_1];
+ case 4:
+ _a.sent();
+ return [3 /*break*/, 2];
+ case 5: return [2 /*return*/];
+ }
+ });
+ };
+ Tokenizer.prototype.readOperator = function () {
+ this.skipBlank();
+ var end = matchOperator(this.input, this.p, this.p + 8);
+ if (end === -1)
+ return;
+ return new OperatorToken(this.input, this.p, (this.p = end), this.file);
+ };
+ Tokenizer.prototype.readFilters = function () {
+ var filters = [];
+ while (true) {
+ var filter = this.readFilter();
+ if (!filter)
+ return filters;
+ filters.push(filter);
+ }
+ };
+ Tokenizer.prototype.readFilter = function () {
+ var _this = this;
+ this.skipBlank();
+ if (this.end())
+ return null;
+ assert(this.peek() === '|', function () { return "unexpected token at " + _this.snapshot(); });
+ this.p++;
+ var begin = this.p;
+ var name = this.readWord();
+ if (!name.size())
+ return null;
+ var args = [];
+ this.skipBlank();
+ if (this.peek() === ':') {
+ do {
+ ++this.p;
+ var arg = this.readFilterArg();
+ arg && args.push(arg);
+ while (this.p < this.N && this.peek() !== ',' && this.peek() !== '|')
+ ++this.p;
+ } while (this.peek() === ',');
+ }
+ return new FilterToken(name.getText(), args, this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readFilterArg = function () {
+ var key = this.readValue();
+ if (!key)
+ return;
+ this.skipBlank();
+ if (this.peek() !== ':')
+ return key;
+ ++this.p;
+ var value = this.readValue();
+ return [key.getText(), value];
+ };
+ Tokenizer.prototype.readTopLevelTokens = function (options) {
+ if (options === void 0) { options = defaultOptions; }
+ var tokens = [];
+ while (this.p < this.N) {
+ var token = this.readTopLevelToken(options);
+ tokens.push(token);
+ }
+ whiteSpaceCtrl(tokens, options);
+ return tokens;
+ };
+ Tokenizer.prototype.readTopLevelToken = function (options) {
+ var tagDelimiterLeft = options.tagDelimiterLeft, outputDelimiterLeft = options.outputDelimiterLeft;
+ if (this.matchWord(tagDelimiterLeft))
+ return this.readTagToken(options);
+ if (this.matchWord(outputDelimiterLeft))
+ return this.readOutputToken(options);
+ return this.readHTMLToken(options);
+ };
+ Tokenizer.prototype.readHTMLToken = function (options) {
+ var begin = this.p;
+ while (this.p < this.N) {
+ var tagDelimiterLeft = options.tagDelimiterLeft, outputDelimiterLeft = options.outputDelimiterLeft;
+ if (this.matchWord(tagDelimiterLeft))
+ break;
+ if (this.matchWord(outputDelimiterLeft))
+ break;
+ ++this.p;
+ }
+ return new HTMLToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readTagToken = function (options) {
+ var _a = this, file = _a.file, input = _a.input;
+ var tagDelimiterRight = options.tagDelimiterRight;
+ var begin = this.p;
+ if (this.readTo(tagDelimiterRight) === -1) {
+ this.mkError("tag " + this.snapshot(begin) + " not closed", begin);
+ }
+ return new TagToken(input, begin, this.p, options, file);
+ };
+ Tokenizer.prototype.readOutputToken = function (options) {
+ var _a = this, file = _a.file, input = _a.input;
+ var outputDelimiterRight = options.outputDelimiterRight;
+ var begin = this.p;
+ if (this.readTo(outputDelimiterRight) === -1) {
+ this.mkError("output " + this.snapshot(begin) + " not closed", begin);
+ }
+ return new OutputToken(input, begin, this.p, options, file);
+ };
+ Tokenizer.prototype.mkError = function (msg, begin) {
+ throw new TokenizationError(msg, new WordToken(this.input, begin, this.N, this.file));
+ };
+ Tokenizer.prototype.snapshot = function (begin) {
+ if (begin === void 0) { begin = this.p; }
+ return JSON.stringify(ellipsis(this.input.slice(begin), 16));
+ };
+ Tokenizer.prototype.readWord = function () {
+ this.skipBlank();
+ var begin = this.p;
+ while (this.peekType() & VARIABLE)
+ ++this.p;
+ return new WordToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readHashes = function () {
+ var hashes = [];
+ while (true) {
+ var hash = this.readHash();
+ if (!hash)
+ return hashes;
+ hashes.push(hash);
+ }
+ };
+ Tokenizer.prototype.readHash = function () {
+ this.skipBlank();
+ if (this.peek() === ',')
+ ++this.p;
+ var begin = this.p;
+ var name = this.readWord();
+ if (!name.size())
+ return;
+ var value;
+ this.skipBlank();
+ if (this.peek() === ':') {
+ ++this.p;
+ value = this.readValue();
+ }
+ return new HashToken(this.input, begin, this.p, name, value, this.file);
+ };
+ Tokenizer.prototype.remaining = function () {
+ return this.input.slice(this.p);
+ };
+ Tokenizer.prototype.advance = function (i) {
+ if (i === void 0) { i = 1; }
+ this.p += i;
+ };
+ Tokenizer.prototype.end = function () {
+ return this.p >= this.N;
+ };
+ Tokenizer.prototype.readTo = function (end) {
+ while (this.p < this.N) {
+ ++this.p;
+ if (this.reverseMatchWord(end))
+ return this.p;
+ }
+ return -1;
+ };
+ Tokenizer.prototype.readValue = function () {
+ var value = this.readQuoted() || this.readRange();
+ if (value)
+ return value;
+ var variable = this.readWord();
+ if (!variable.size())
+ return;
+ var isNumber = variable.isNumber(true);
+ var props = [];
+ while (true) {
+ if (this.peek() === '[') {
+ isNumber = false;
+ this.p++;
+ var prop = this.readValue() || new WordToken(this.input, this.p, this.p, this.file);
+ this.readTo(']');
+ props.push(prop);
+ }
+ else if (this.peek() === '.' && this.peek(1) !== '.') { // skip range syntax
+ this.p++;
+ var prop = this.readWord();
+ if (!prop.size())
+ break;
+ if (!prop.isNumber())
+ isNumber = false;
+ props.push(prop);
+ }
+ else
+ break;
+ }
+ if (!props.length && literalValues.hasOwnProperty(variable.content)) {
+ return new LiteralToken(this.input, variable.begin, variable.end, this.file);
+ }
+ if (isNumber)
+ return new NumberToken(variable, props[0]);
+ return new PropertyAccessToken(variable, props, this.p);
+ };
+ Tokenizer.prototype.readRange = function () {
+ this.skipBlank();
+ var begin = this.p;
+ if (this.peek() !== '(')
+ return;
+ ++this.p;
+ var lhs = this.readValueOrThrow();
+ this.p += 2;
+ var rhs = this.readValueOrThrow();
+ ++this.p;
+ return new RangeToken(this.input, begin, this.p, lhs, rhs, this.file);
+ };
+ Tokenizer.prototype.readValueOrThrow = function () {
+ var _this = this;
+ var value = this.readValue();
+ assert(value, function () { return "unexpected token " + _this.snapshot() + ", value expected"; });
+ return value;
+ };
+ Tokenizer.prototype.readQuoted = function () {
+ this.skipBlank();
+ var begin = this.p;
+ if (!(this.peekType() & QUOTE))
+ return;
+ ++this.p;
+ var escaped = false;
+ while (this.p < this.N) {
+ ++this.p;
+ if (this.input[this.p - 1] === this.input[begin] && !escaped)
+ break;
+ if (escaped)
+ escaped = false;
+ else if (this.input[this.p - 1] === '\\')
+ escaped = true;
+ }
+ return new QuotedToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readFileName = function () {
+ var begin = this.p;
+ while (!(this.peekType() & BLANK) && this.peek() !== ',' && this.p < this.N)
+ this.p++;
+ return new WordToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.matchWord = function (word) {
+ for (var i = 0; i < word.length; i++) {
+ if (word[i] !== this.input[this.p + i])
+ return false;
+ }
+ return true;
+ };
+ Tokenizer.prototype.reverseMatchWord = function (word) {
+ for (var i = 0; i < word.length; i++) {
+ if (word[word.length - 1 - i] !== this.input[this.p - 1 - i])
+ return false;
+ }
+ return true;
+ };
+ Tokenizer.prototype.peekType = function (n) {
+ if (n === void 0) { n = 0; }
+ return TYPES[this.input.charCodeAt(this.p + n)];
+ };
+ Tokenizer.prototype.peek = function (n) {
+ if (n === void 0) { n = 0; }
+ return this.input[this.p + n];
+ };
+ Tokenizer.prototype.skipBlank = function () {
+ while (this.peekType() & BLANK)
+ ++this.p;
+ };
+ return Tokenizer;
+ }());
+
+ var Emitter = /** @class */ (function () {
+ function Emitter() {
+ this.html = '';
+ this.break = false;
+ this.continue = false;
+ }
+ Emitter.prototype.write = function (html) {
+ this.html += html;
+ };
+ return Emitter;
+ }());
+
+ var Render = /** @class */ (function () {
+ function Render() {
+ }
+ Render.prototype.renderTemplates = function (templates, ctx, emitter) {
+ var templates_1, templates_1_1, tpl, html, e_1, err, e_2_1;
+ var e_2, _a;
+ if (emitter === void 0) { emitter = new Emitter(); }
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ _b.trys.push([0, 7, 8, 9]);
+ templates_1 = __values(templates), templates_1_1 = templates_1.next();
+ _b.label = 1;
+ case 1:
+ if (!!templates_1_1.done) return [3 /*break*/, 6];
+ tpl = templates_1_1.value;
+ _b.label = 2;
+ case 2:
+ _b.trys.push([2, 4, , 5]);
+ return [4 /*yield*/, tpl.render(ctx, emitter)];
+ case 3:
+ html = _b.sent();
+ html && emitter.write(html);
+ if (emitter.break || emitter.continue)
+ return [3 /*break*/, 6];
+ return [3 /*break*/, 5];
+ case 4:
+ e_1 = _b.sent();
+ err = RenderError.is(e_1) ? e_1 : new RenderError(e_1, tpl);
+ throw err;
+ case 5:
+ templates_1_1 = templates_1.next();
+ return [3 /*break*/, 1];
+ case 6: return [3 /*break*/, 9];
+ case 7:
+ e_2_1 = _b.sent();
+ e_2 = { error: e_2_1 };
+ return [3 /*break*/, 9];
+ case 8:
+ try {
+ if (templates_1_1 && !templates_1_1.done && (_a = templates_1.return)) _a.call(templates_1);
+ }
+ finally { if (e_2) throw e_2.error; }
+ return [7 /*endfinally*/];
+ case 9: return [2 /*return*/, emitter.html];
+ }
+ });
+ };
+ return Render;
+ }());
+
+ var ParseStream = /** @class */ (function () {
+ function ParseStream(tokens, parseToken) {
+ this.handlers = {};
+ this.stopRequested = false;
+ this.tokens = tokens;
+ this.parseToken = parseToken;
+ }
+ ParseStream.prototype.on = function (name, cb) {
+ this.handlers[name] = cb;
+ return this;
+ };
+ ParseStream.prototype.trigger = function (event, arg) {
+ var h = this.handlers[event];
+ return h ? (h(arg), true) : false;
+ };
+ ParseStream.prototype.start = function () {
+ this.trigger('start');
+ var token;
+ while (!this.stopRequested && (token = this.tokens.shift())) {
+ if (this.trigger('token', token))
+ continue;
+ if (isTagToken(token) && this.trigger("tag:" + token.name, token)) {
+ continue;
+ }
+ var template = this.parseToken(token, this.tokens);
+ this.trigger('template', template);
+ }
+ if (!this.stopRequested)
+ this.trigger('end');
+ return this;
+ };
+ ParseStream.prototype.stop = function () {
+ this.stopRequested = true;
+ return this;
+ };
+ return ParseStream;
+ }());
+
+ var TemplateImpl = /** @class */ (function () {
+ function TemplateImpl(token) {
+ this.token = token;
+ }
+ return TemplateImpl;
+ }());
+
+ var rHex = /[\da-fA-F]/;
+ var rOct = /[0-7]/;
+ var escapeChar = {
+ b: '\b',
+ f: '\f',
+ n: '\n',
+ r: '\r',
+ t: '\t',
+ v: '\x0B'
+ };
+ function hexVal(c) {
+ var code = c.charCodeAt(0);
+ if (code >= 97)
+ return code - 87;
+ if (code >= 65)
+ return code - 55;
+ return code - 48;
+ }
+ function parseStringLiteral(str) {
+ var ret = '';
+ for (var i = 1; i < str.length - 1; i++) {
+ if (str[i] !== '\\') {
+ ret += str[i];
+ continue;
+ }
+ if (escapeChar[str[i + 1]] !== undefined) {
+ ret += escapeChar[str[++i]];
+ }
+ else if (str[i + 1] === 'u') {
+ var val = 0;
+ var j = i + 2;
+ while (j <= i + 5 && rHex.test(str[j])) {
+ val = val * 16 + hexVal(str[j++]);
+ }
+ i = j - 1;
+ ret += String.fromCharCode(val);
+ }
+ else if (!rOct.test(str[i + 1])) {
+ ret += str[++i];
+ }
+ else {
+ var j = i + 1;
+ var val = 0;
+ while (j <= i + 3 && rOct.test(str[j])) {
+ val = val * 8 + hexVal(str[j++]);
+ }
+ i = j - 1;
+ ret += String.fromCharCode(val);
+ }
+ }
+ return ret;
+ }
+
+ function isComparable(arg) {
+ return arg && isFunction(arg.equals);
+ }
+
+ function isTruthy(val) {
+ return !isFalsy(val);
+ }
+ function isFalsy(val) {
+ return val === false || undefined === val || val === null;
+ }
+
+ var operatorImpls = {
+ '==': function (l, r) {
+ if (isComparable(l))
+ return l.equals(r);
+ if (isComparable(r))
+ return r.equals(l);
+ return l === r;
+ },
+ '!=': function (l, r) {
+ if (isComparable(l))
+ return !l.equals(r);
+ if (isComparable(r))
+ return !r.equals(l);
+ return l !== r;
+ },
+ '>': function (l, r) {
+ if (isComparable(l))
+ return l.gt(r);
+ if (isComparable(r))
+ return r.lt(l);
+ return l > r;
+ },
+ '<': function (l, r) {
+ if (isComparable(l))
+ return l.lt(r);
+ if (isComparable(r))
+ return r.gt(l);
+ return l < r;
+ },
+ '>=': function (l, r) {
+ if (isComparable(l))
+ return l.geq(r);
+ if (isComparable(r))
+ return r.leq(l);
+ return l >= r;
+ },
+ '<=': function (l, r) {
+ if (isComparable(l))
+ return l.leq(r);
+ if (isComparable(r))
+ return r.geq(l);
+ return l <= r;
+ },
+ 'contains': function (l, r) {
+ return l && isFunction(l.indexOf) ? l.indexOf(r) > -1 : false;
+ },
+ 'and': function (l, r) { return isTruthy(l) && isTruthy(r); },
+ 'or': function (l, r) { return isTruthy(l) || isTruthy(r); }
+ };
+
+ var Expression = /** @class */ (function () {
+ function Expression(str) {
+ this.operands = [];
+ var tokenizer = new Tokenizer(str);
+ this.postfix = toPostfix(tokenizer.readExpression());
+ }
+ Expression.prototype.evaluate = function (ctx) {
+ var e_1, _a;
+ try {
+ for (var _b = __values(this.postfix), _c = _b.next(); !_c.done; _c = _b.next()) {
+ var token = _c.value;
+ if (isOperatorToken(token)) {
+ var r = this.operands.pop();
+ var l = this.operands.pop();
+ var result = evalOperatorToken(token, l, r);
+ this.operands.push(result);
+ }
+ else {
+ this.operands.push(evalToken(token, ctx));
+ }
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ return this.operands[0];
+ };
+ Expression.prototype.value = function (ctx) {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toValue(this.evaluate(ctx))];
+ });
+ };
+ return Expression;
+ }());
+ function evalToken(token, ctx) {
+ assert(ctx, function () { return 'unable to evaluate: context not defined'; });
+ if (isPropertyAccessToken(token)) {
+ var variable = token.variable.getText();
+ var props = token.props.map(function (prop) { return evalToken(prop, ctx); });
+ return ctx.get(__spread([variable], props));
+ }
+ if (isRangeToken(token))
+ return evalRangeToken(token, ctx);
+ if (isLiteralToken(token))
+ return evalLiteralToken(token);
+ if (isNumberToken(token))
+ return evalNumberToken(token);
+ if (isWordToken(token))
+ return token.getText();
+ if (isQuotedToken(token))
+ return evalQuotedToken(token);
+ }
+ function evalNumberToken(token) {
+ var str = token.whole.content + '.' + (token.decimal ? token.decimal.content : '');
+ return Number(str);
+ }
+ function evalQuotedToken(token) {
+ return parseStringLiteral(token.getText());
+ }
+ function evalOperatorToken(token, lhs, rhs) {
+ var impl = operatorImpls[token.operator];
+ return impl(lhs, rhs);
+ }
+ function evalLiteralToken(token) {
+ return literalValues[token.literal];
+ }
+ function evalRangeToken(token, ctx) {
+ var low = evalToken(token.lhs, ctx);
+ var high = evalToken(token.rhs, ctx);
+ return range(+low, +high + 1);
+ }
+ function toPostfix(tokens) {
+ var ops, tokens_1, tokens_1_1, token, e_2_1;
+ var e_2, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ ops = [];
+ _b.label = 1;
+ case 1:
+ _b.trys.push([1, 10, 11, 12]);
+ tokens_1 = __values(tokens), tokens_1_1 = tokens_1.next();
+ _b.label = 2;
+ case 2:
+ if (!!tokens_1_1.done) return [3 /*break*/, 9];
+ token = tokens_1_1.value;
+ if (!isOperatorToken(token)) return [3 /*break*/, 6];
+ _b.label = 3;
+ case 3:
+ if (!(ops.length && ops[ops.length - 1].getPrecedence() > token.getPrecedence())) return [3 /*break*/, 5];
+ return [4 /*yield*/, ops.pop()];
+ case 4:
+ _b.sent();
+ return [3 /*break*/, 3];
+ case 5:
+ ops.push(token);
+ return [3 /*break*/, 8];
+ case 6: return [4 /*yield*/, token];
+ case 7:
+ _b.sent();
+ _b.label = 8;
+ case 8:
+ tokens_1_1 = tokens_1.next();
+ return [3 /*break*/, 2];
+ case 9: return [3 /*break*/, 12];
+ case 10:
+ e_2_1 = _b.sent();
+ e_2 = { error: e_2_1 };
+ return [3 /*break*/, 12];
+ case 11:
+ try {
+ if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
+ }
+ finally { if (e_2) throw e_2.error; }
+ return [7 /*endfinally*/];
+ case 12:
+ if (!ops.length) return [3 /*break*/, 14];
+ return [4 /*yield*/, ops.pop()];
+ case 13:
+ _b.sent();
+ return [3 /*break*/, 12];
+ case 14: return [2 /*return*/];
+ }
+ });
+ }
+
+ /**
+ * Key-Value Pairs Representing Tag Arguments
+ * Example:
+ * For the markup `, foo:'bar', coo:2 reversed %}`,
+ * hash['foo'] === 'bar'
+ * hash['coo'] === 2
+ * hash['reversed'] === undefined
+ */
+ var Hash = /** @class */ (function () {
+ function Hash(markup) {
+ var e_1, _a;
+ this.hash = {};
+ var tokenizer = new Tokenizer(markup);
+ try {
+ for (var _b = __values(tokenizer.readHashes()), _c = _b.next(); !_c.done; _c = _b.next()) {
+ var hash = _c.value;
+ this.hash[hash.name.content] = hash.value;
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ }
+ Hash.prototype.render = function (ctx) {
+ var hash, _a, _b, key;
+ var e_2, _c;
+ return __generator(this, function (_d) {
+ hash = {};
+ try {
+ for (_a = __values(Object.keys(this.hash)), _b = _a.next(); !_b.done; _b = _a.next()) {
+ key = _b.value;
+ hash[key] = evalToken(this.hash[key], ctx);
+ }
+ }
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
+ finally {
+ try {
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+ }
+ finally { if (e_2) throw e_2.error; }
+ }
+ return [2 /*return*/, hash];
+ });
+ };
+ return Hash;
+ }());
+
+ var Tag = /** @class */ (function (_super) {
+ __extends(Tag, _super);
+ function Tag(token, tokens, liquid) {
+ var _this = _super.call(this, token) || this;
+ _this.name = token.name;
+ var impl = liquid.tags.get(token.name);
+ _this.impl = Object.create(impl);
+ _this.impl.liquid = liquid;
+ if (_this.impl.parse) {
+ _this.impl.parse(token, tokens);
+ }
+ return _this;
+ }
+ Tag.prototype.render = function (ctx, emitter) {
+ var hash, impl;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, new Hash(this.token.args).render(ctx)];
+ case 1:
+ hash = _a.sent();
+ impl = this.impl;
+ if (!isFunction(impl.render)) return [3 /*break*/, 3];
+ return [4 /*yield*/, impl.render(ctx, emitter, hash)];
+ case 2: return [2 /*return*/, _a.sent()];
+ case 3: return [2 /*return*/];
+ }
+ });
+ };
+ Tag.impls = {};
+ return Tag;
+ }(TemplateImpl));
+
+ function isKeyValuePair(arr) {
+ return isArray(arr);
+ }
+
+ var Filter = /** @class */ (function () {
+ function Filter(name, impl, args) {
+ this.name = name;
+ this.impl = impl || identify;
+ this.args = args;
+ }
+ Filter.prototype.render = function (value, context) {
+ var argv, _a, _b, arg, _c, _d, _e, _f, _g, e_1_1;
+ var e_1, _h;
+ return __generator(this, function (_j) {
+ switch (_j.label) {
+ case 0:
+ argv = [];
+ _j.label = 1;
+ case 1:
+ _j.trys.push([1, 8, 9, 10]);
+ _a = __values(this.args), _b = _a.next();
+ _j.label = 2;
+ case 2:
+ if (!!_b.done) return [3 /*break*/, 7];
+ arg = _b.value;
+ if (!isKeyValuePair(arg)) return [3 /*break*/, 4];
+ _d = (_c = argv).push;
+ _e = [arg[0]];
+ return [4 /*yield*/, evalToken(arg[1], context)];
+ case 3:
+ _d.apply(_c, [_e.concat([_j.sent()])]);
+ return [3 /*break*/, 6];
+ case 4:
+ _g = (_f = argv).push;
+ return [4 /*yield*/, evalToken(arg, context)];
+ case 5:
+ _g.apply(_f, [_j.sent()]);
+ _j.label = 6;
+ case 6:
+ _b = _a.next();
+ return [3 /*break*/, 2];
+ case 7: return [3 /*break*/, 10];
+ case 8:
+ e_1_1 = _j.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 10];
+ case 9:
+ try {
+ if (_b && !_b.done && (_h = _a.return)) _h.call(_a);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 10: return [2 /*return*/, this.impl.apply({ context: context }, __spread([value], argv))];
+ }
+ });
+ };
+ return Filter;
+ }());
+
+ var Value = /** @class */ (function () {
+ /**
+ * @param str the value to be valuated, eg.: "foobar" | truncate: 3
+ */
+ function Value(str, filterMap) {
+ var _this = this;
+ this.filterMap = filterMap;
+ this.filters = [];
+ var tokenizer = new Tokenizer(str);
+ this.initial = tokenizer.readValue();
+ this.filters = tokenizer.readFilters().map(function (_a) {
+ var name = _a.name, args = _a.args;
+ return new Filter(name, _this.filterMap.get(name), args);
+ });
+ }
+ Value.prototype.value = function (ctx) {
+ var val, _a, _b, filter, e_1_1;
+ var e_1, _c;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0: return [4 /*yield*/, evalToken(this.initial, ctx)];
+ case 1:
+ val = _d.sent();
+ _d.label = 2;
+ case 2:
+ _d.trys.push([2, 7, 8, 9]);
+ _a = __values(this.filters), _b = _a.next();
+ _d.label = 3;
+ case 3:
+ if (!!_b.done) return [3 /*break*/, 6];
+ filter = _b.value;
+ return [4 /*yield*/, filter.render(val, ctx)];
+ case 4:
+ val = _d.sent();
+ _d.label = 5;
+ case 5:
+ _b = _a.next();
+ return [3 /*break*/, 3];
+ case 6: return [3 /*break*/, 9];
+ case 7:
+ e_1_1 = _d.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 9];
+ case 8:
+ try {
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 9: return [2 /*return*/, val];
+ }
+ });
+ };
+ return Value;
+ }());
+
+ var Output = /** @class */ (function (_super) {
+ __extends(Output, _super);
+ function Output(token, filters) {
+ var _this = _super.call(this, token) || this;
+ _this.value = new Value(token.content, filters);
+ return _this;
+ }
+ Output.prototype.render = function (ctx, emitter) {
+ var val;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, this.value.value(ctx)];
+ case 1:
+ val = _a.sent();
+ emitter.write(stringify(toValue(val)));
+ return [2 /*return*/];
+ }
+ });
+ };
+ return Output;
+ }(TemplateImpl));
+
+ var HTML = /** @class */ (function (_super) {
+ __extends(HTML, _super);
+ function HTML(token) {
+ var _this = _super.call(this, token) || this;
+ _this.str = token.getContent();
+ return _this;
+ }
+ HTML.prototype.render = function (ctx, emitter) {
+ return __generator(this, function (_a) {
+ emitter.write(this.str);
+ return [2 /*return*/];
+ });
+ };
+ return HTML;
+ }(TemplateImpl));
+
+ var Parser = /** @class */ (function () {
+ function Parser(liquid) {
+ this.liquid = liquid;
+ }
+ Parser.prototype.parse = function (tokens) {
+ var token;
+ var templates = [];
+ while ((token = tokens.shift())) {
+ templates.push(this.parseToken(token, tokens));
+ }
+ return templates;
+ };
+ Parser.prototype.parseToken = function (token, remainTokens) {
+ try {
+ if (isTagToken(token)) {
+ return new Tag(token, remainTokens, this.liquid);
+ }
+ if (isOutputToken(token)) {
+ return new Output(token, this.liquid.filters);
+ }
+ return new HTML(token);
+ }
+ catch (e) {
+ throw new ParseError(e, token);
+ }
+ };
+ Parser.prototype.parseStream = function (tokens) {
+ var _this = this;
+ return new ParseStream(tokens, function (token, tokens) { return _this.parseToken(token, tokens); });
+ };
+ return Parser;
+ }());
+
+ var assign = {
+ parse: function (token) {
+ var tokenizer = new Tokenizer(token.args);
+ this.key = tokenizer.readWord().content;
+ tokenizer.skipBlank();
+ assert(tokenizer.peek() === '=', function () { return "illegal token " + token.getText(); });
+ tokenizer.advance();
+ this.value = tokenizer.remaining();
+ },
+ render: function (ctx) {
+ var _a, _b;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ _a = ctx.bottom();
+ _b = this.key;
+ return [4 /*yield*/, this.liquid._evalValue(this.value, ctx)];
+ case 1:
+ _a[_b] = _c.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ function toEnumerable(val) {
+ if (isArray(val))
+ return val;
+ if (isString(val) && val.length > 0)
+ return [val];
+ if (isObject(val))
+ return Object.keys(val).map(function (key) { return [key, val[key]]; });
+ return [];
+ }
+ function toArray(val) {
+ if (isArray(val))
+ return val;
+ return [val];
+ }
+
+ var ForloopDrop = /** @class */ (function (_super) {
+ __extends(ForloopDrop, _super);
+ function ForloopDrop(length) {
+ var _this = _super.call(this) || this;
+ _this.i = 0;
+ _this.length = length;
+ return _this;
+ }
+ ForloopDrop.prototype.next = function () {
+ this.i++;
+ };
+ ForloopDrop.prototype.index0 = function () {
+ return this.i;
+ };
+ ForloopDrop.prototype.index = function () {
+ return this.i + 1;
+ };
+ ForloopDrop.prototype.first = function () {
+ return this.i === 0;
+ };
+ ForloopDrop.prototype.last = function () {
+ return this.i === this.length - 1;
+ };
+ ForloopDrop.prototype.rindex = function () {
+ return this.length - this.i;
+ };
+ ForloopDrop.prototype.rindex0 = function () {
+ return this.length - this.i - 1;
+ };
+ ForloopDrop.prototype.valueOf = function () {
+ return JSON.stringify(this);
+ };
+ return ForloopDrop;
+ }(Drop));
+
+ var For = {
+ type: 'block',
+ parse: function (token, remainTokens) {
+ var _this = this;
+ var toknenizer = new Tokenizer(token.args);
+ var variable = toknenizer.readWord();
+ var inStr = toknenizer.readWord();
+ var collection = toknenizer.readValue();
+ assert(variable.size() && inStr.content === 'in' && collection, function () { return "illegal tag: " + token.getText(); });
+ this.variable = variable.content;
+ this.collection = collection;
+ this.hash = new Hash(toknenizer.remaining());
+ this.templates = [];
+ this.elseTemplates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () { return (p = _this.templates); })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endfor', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + token.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, collection, hash, offset, limit, scope, collection_1, collection_1_1, item, e_1_1;
+ var e_1, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ r = this.liquid.renderer;
+ collection = toEnumerable(evalToken(this.collection, ctx));
+ if (!!collection.length) return [3 /*break*/, 2];
+ return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
+ case 1:
+ _b.sent();
+ return [2 /*return*/];
+ case 2: return [4 /*yield*/, this.hash.render(ctx)];
+ case 3:
+ hash = _b.sent();
+ offset = hash.offset || 0;
+ limit = (hash.limit === undefined) ? collection.length : hash.limit;
+ collection = collection.slice(offset, offset + limit);
+ if ('reversed' in hash)
+ collection.reverse();
+ scope = { forloop: new ForloopDrop(collection.length) };
+ ctx.push(scope);
+ _b.label = 4;
+ case 4:
+ _b.trys.push([4, 9, 10, 11]);
+ collection_1 = __values(collection), collection_1_1 = collection_1.next();
+ _b.label = 5;
+ case 5:
+ if (!!collection_1_1.done) return [3 /*break*/, 8];
+ item = collection_1_1.value;
+ scope[this.variable] = item;
+ return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
+ case 6:
+ _b.sent();
+ if (emitter.break) {
+ emitter.break = false;
+ return [3 /*break*/, 8];
+ }
+ emitter.continue = false;
+ scope.forloop.next();
+ _b.label = 7;
+ case 7:
+ collection_1_1 = collection_1.next();
+ return [3 /*break*/, 5];
+ case 8: return [3 /*break*/, 11];
+ case 9:
+ e_1_1 = _b.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 11];
+ case 10:
+ try {
+ if (collection_1_1 && !collection_1_1.done && (_a = collection_1.return)) _a.call(collection_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 11:
+ ctx.pop();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var capture = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ var tokenizer = new Tokenizer(tagToken.args);
+ this.variable = tokenizer.readWord().content;
+ assert(this.variable, function () { return tagToken.args + " not valid identifier"; });
+ this.templates = [];
+ var stream = this.liquid.parser.parseStream(remainTokens);
+ stream.on('tag:endcapture', function () { return stream.stop(); })
+ .on('template', function (tpl) { return _this.templates.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx) {
+ var r, html;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ r = this.liquid.renderer;
+ return [4 /*yield*/, r.renderTemplates(this.templates, ctx)];
+ case 1:
+ html = _a.sent();
+ ctx.bottom()[this.variable] = html;
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var Case = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.cond = tagToken.args;
+ this.cases = [];
+ this.elseTemplates = [];
+ var p = [];
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('tag:when', function (token) {
+ _this.cases.push({
+ val: token.args,
+ templates: p = []
+ });
+ })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endcase', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, cond, i, branch, val;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ r = this.liquid.renderer;
+ return [4 /*yield*/, new Expression(this.cond).value(ctx)];
+ case 1:
+ cond = _a.sent();
+ i = 0;
+ _a.label = 2;
+ case 2:
+ if (!(i < this.cases.length)) return [3 /*break*/, 6];
+ branch = this.cases[i];
+ return [4 /*yield*/, new Expression(branch.val).value(ctx)];
+ case 3:
+ val = _a.sent();
+ if (!(val === cond)) return [3 /*break*/, 5];
+ return [4 /*yield*/, r.renderTemplates(branch.templates, ctx, emitter)];
+ case 4:
+ _a.sent();
+ return [2 /*return*/];
+ case 5:
+ i++;
+ return [3 /*break*/, 2];
+ case 6: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
+ case 7:
+ _a.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var comment = {
+ parse: function (tagToken, remainTokens) {
+ var stream = this.liquid.parser.parseStream(remainTokens);
+ stream
+ .on('token', function (token) {
+ if (token.name === 'endcomment')
+ stream.stop();
+ })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ }
+ };
+
+ var BlockMode;
+ (function (BlockMode) {
+ /* store rendered html into blocks */
+ BlockMode[BlockMode["OUTPUT"] = 0] = "OUTPUT";
+ /* output rendered html directly */
+ BlockMode[BlockMode["STORE"] = 1] = "STORE";
+ })(BlockMode || (BlockMode = {}));
+ var BlockMode$1 = BlockMode;
+
+ var include = {
+ parse: function (token) {
+ var args = token.args;
+ var tokenizer = new Tokenizer(args);
+ this.file = this.liquid.options.dynamicPartials
+ ? tokenizer.readValue()
+ : tokenizer.readFileName();
+ assert(this.file, function () { return "illegal argument \"" + token.args + "\""; });
+ var begin = tokenizer.p;
+ var withStr = tokenizer.readWord();
+ if (withStr.content === 'with') {
+ tokenizer.skipBlank();
+ if (tokenizer.peek() !== ':') {
+ this.withVar = tokenizer.readValue();
+ }
+ else
+ tokenizer.p = begin;
+ }
+ else
+ tokenizer.p = begin;
+ this.hash = new Hash(tokenizer.remaining());
+ },
+ render: function (ctx, emitter) {
+ var _a, liquid, hash, withVar, file, renderer, filepath, _b, _c, saved, scope, templates;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ _a = this, liquid = _a.liquid, hash = _a.hash, withVar = _a.withVar, file = _a.file;
+ renderer = liquid.renderer;
+ if (!ctx.opts.dynamicPartials) return [3 /*break*/, 5];
+ if (!isQuotedToken(file)) return [3 /*break*/, 2];
+ return [4 /*yield*/, renderer.renderTemplates(liquid.parse(evalQuotedToken(file)), ctx)];
+ case 1:
+ _c = _d.sent();
+ return [3 /*break*/, 4];
+ case 2: return [4 /*yield*/, evalToken(file, ctx)];
+ case 3:
+ _c = _d.sent();
+ _d.label = 4;
+ case 4:
+ _b = (_c);
+ return [3 /*break*/, 6];
+ case 5:
+ _b = file.getText();
+ _d.label = 6;
+ case 6:
+ filepath = _b;
+ assert(filepath, function () { return "illegal filename \"" + file.getText() + "\":\"" + filepath + "\""; });
+ saved = ctx.saveRegister('blocks', 'blockMode');
+ ctx.setRegister('blocks', {});
+ ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
+ return [4 /*yield*/, hash.render(ctx)];
+ case 7:
+ scope = _d.sent();
+ if (withVar)
+ scope[filepath] = evalToken(withVar, ctx);
+ return [4 /*yield*/, liquid._parseFile(filepath, ctx.opts, ctx.sync)];
+ case 8:
+ templates = _d.sent();
+ ctx.push(scope);
+ return [4 /*yield*/, renderer.renderTemplates(templates, ctx, emitter)];
+ case 9:
+ _d.sent();
+ ctx.pop();
+ ctx.restoreRegister(saved);
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var render = {
+ parse: function (token) {
+ var args = token.args;
+ var tokenizer = new Tokenizer(args);
+ this.file = this.liquid.options.dynamicPartials
+ ? tokenizer.readValue()
+ : tokenizer.readFileName();
+ assert(this.file, function () { return "illegal argument \"" + token.args + "\""; });
+ while (!tokenizer.end()) {
+ tokenizer.skipBlank();
+ var begin = tokenizer.p;
+ var keyword = tokenizer.readWord();
+ if (keyword.content === 'with' || keyword.content === 'for') {
+ tokenizer.skipBlank();
+ if (tokenizer.peek() !== ':') {
+ var value = tokenizer.readValue();
+ if (value) {
+ var beforeAs = tokenizer.p;
+ var asStr = tokenizer.readWord();
+ var alias = void 0;
+ if (asStr.content === 'as')
+ alias = tokenizer.readWord();
+ else
+ tokenizer.p = beforeAs;
+ this[keyword.content] = { value: value, alias: alias && alias.content };
+ tokenizer.skipBlank();
+ if (tokenizer.peek() === ',')
+ tokenizer.advance();
+ continue;
+ }
+ }
+ }
+ tokenizer.p = begin;
+ break;
+ }
+ this.hash = new Hash(tokenizer.remaining());
+ },
+ render: function (ctx, emitter) {
+ var _a, liquid, file, hash, renderer, filepath, _b, _c, childCtx, scope, _d, value, alias, _e, value, alias, collection, collection_1, collection_1_1, item, templates, e_1_1, templates;
+ var e_1, _f;
+ return __generator(this, function (_g) {
+ switch (_g.label) {
+ case 0:
+ _a = this, liquid = _a.liquid, file = _a.file, hash = _a.hash;
+ renderer = liquid.renderer;
+ if (!ctx.opts.dynamicPartials) return [3 /*break*/, 4];
+ if (!isQuotedToken(file)) return [3 /*break*/, 2];
+ return [4 /*yield*/, renderer.renderTemplates(liquid.parse(evalQuotedToken(file)), ctx)];
+ case 1:
+ _c = _g.sent();
+ return [3 /*break*/, 3];
+ case 2:
+ _c = evalToken(file, ctx);
+ _g.label = 3;
+ case 3:
+ _b = (_c);
+ return [3 /*break*/, 5];
+ case 4:
+ _b = file.getText();
+ _g.label = 5;
+ case 5:
+ filepath = _b;
+ assert(filepath, function () { return "illegal filename \"" + file.getText() + "\":\"" + filepath + "\""; });
+ childCtx = new Context({}, ctx.opts, ctx.sync);
+ return [4 /*yield*/, hash.render(ctx)];
+ case 6:
+ scope = _g.sent();
+ if (this['with']) {
+ _d = this['with'], value = _d.value, alias = _d.alias;
+ scope[alias || filepath] = evalToken(value, ctx);
+ }
+ childCtx.push(scope);
+ if (!this['for']) return [3 /*break*/, 16];
+ _e = this['for'], value = _e.value, alias = _e.alias;
+ collection = evalToken(value, ctx);
+ collection = toEnumerable(collection);
+ scope['forloop'] = new ForloopDrop(collection.length);
+ _g.label = 7;
+ case 7:
+ _g.trys.push([7, 13, 14, 15]);
+ collection_1 = __values(collection), collection_1_1 = collection_1.next();
+ _g.label = 8;
+ case 8:
+ if (!!collection_1_1.done) return [3 /*break*/, 12];
+ item = collection_1_1.value;
+ scope[alias] = item;
+ return [4 /*yield*/, liquid._parseFile(filepath, childCtx.opts, childCtx.sync)];
+ case 9:
+ templates = _g.sent();
+ return [4 /*yield*/, renderer.renderTemplates(templates, childCtx, emitter)];
+ case 10:
+ _g.sent();
+ scope.forloop.next();
+ _g.label = 11;
+ case 11:
+ collection_1_1 = collection_1.next();
+ return [3 /*break*/, 8];
+ case 12: return [3 /*break*/, 15];
+ case 13:
+ e_1_1 = _g.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 15];
+ case 14:
+ try {
+ if (collection_1_1 && !collection_1_1.done && (_f = collection_1.return)) _f.call(collection_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 15: return [3 /*break*/, 19];
+ case 16: return [4 /*yield*/, liquid._parseFile(filepath, childCtx.opts, childCtx.sync)];
+ case 17:
+ templates = _g.sent();
+ return [4 /*yield*/, renderer.renderTemplates(templates, childCtx, emitter)];
+ case 18:
+ _g.sent();
+ _g.label = 19;
+ case 19: return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var decrement = {
+ parse: function (token) {
+ var tokenizer = new Tokenizer(token.args);
+ this.variable = tokenizer.readWord().content;
+ },
+ render: function (context, emitter) {
+ var scope = context.environments;
+ if (!isNumber(scope[this.variable])) {
+ scope[this.variable] = 0;
+ }
+ emitter.write(stringify(--scope[this.variable]));
+ }
+ };
+
+ var cycle = {
+ parse: function (tagToken) {
+ var tokenizer = new Tokenizer(tagToken.args);
+ var group = tokenizer.readValue();
+ tokenizer.skipBlank();
+ this.candidates = [];
+ if (group) {
+ if (tokenizer.peek() === ':') {
+ this.group = group;
+ tokenizer.advance();
+ }
+ else
+ this.candidates.push(group);
+ }
+ while (!tokenizer.end()) {
+ var value = tokenizer.readValue();
+ if (value)
+ this.candidates.push(value);
+ tokenizer.readTo(',');
+ }
+ assert(this.candidates.length, function () { return "empty candidates: " + tagToken.getText(); });
+ },
+ render: function (ctx, emitter) {
+ var group = evalToken(this.group, ctx);
+ var fingerprint = "cycle:" + group + ":" + this.candidates.join(',');
+ var groups = ctx.getRegister('cycle');
+ var idx = groups[fingerprint];
+ if (idx === undefined) {
+ idx = groups[fingerprint] = 0;
+ }
+ var candidate = this.candidates[idx];
+ idx = (idx + 1) % this.candidates.length;
+ groups[fingerprint] = idx;
+ var html = evalToken(candidate, ctx);
+ emitter.write(html);
+ }
+ };
+
+ var If = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.branches = [];
+ this.elseTemplates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () { return _this.branches.push({
+ cond: tagToken.args,
+ templates: (p = [])
+ }); })
+ .on('tag:elsif', function (token) {
+ _this.branches.push({
+ cond: token.args,
+ templates: p = []
+ });
+ })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endif', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, _a, _b, branch, cond, e_1_1;
+ var e_1, _c;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ r = this.liquid.renderer;
+ _d.label = 1;
+ case 1:
+ _d.trys.push([1, 7, 8, 9]);
+ _a = __values(this.branches), _b = _a.next();
+ _d.label = 2;
+ case 2:
+ if (!!_b.done) return [3 /*break*/, 6];
+ branch = _b.value;
+ return [4 /*yield*/, new Expression(branch.cond).value(ctx)];
+ case 3:
+ cond = _d.sent();
+ if (!isTruthy(cond)) return [3 /*break*/, 5];
+ return [4 /*yield*/, r.renderTemplates(branch.templates, ctx, emitter)];
+ case 4:
+ _d.sent();
+ return [2 /*return*/];
+ case 5:
+ _b = _a.next();
+ return [3 /*break*/, 2];
+ case 6: return [3 /*break*/, 9];
+ case 7:
+ e_1_1 = _d.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 9];
+ case 8:
+ try {
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 9: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
+ case 10:
+ _d.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var increment = {
+ parse: function (token) {
+ var tokenizer = new Tokenizer(token.args);
+ this.variable = tokenizer.readWord().content;
+ },
+ render: function (context, emitter) {
+ var scope = context.environments;
+ if (!isNumber(scope[this.variable])) {
+ scope[this.variable] = 0;
+ }
+ var val = scope[this.variable];
+ scope[this.variable]++;
+ emitter.write(stringify(val));
+ }
+ };
+
+ var layout = {
+ parse: function (token, remainTokens) {
+ var tokenizer = new Tokenizer(token.args);
+ var file = this.liquid.options.dynamicPartials ? tokenizer.readValue() : tokenizer.readFileName();
+ assert(file, function () { return "illegal argument \"" + token.args + "\""; });
+ this.file = file;
+ this.hash = new Hash(tokenizer.remaining());
+ this.tpls = this.liquid.parser.parse(remainTokens);
+ },
+ render: function (ctx, emitter) {
+ var _a, liquid, hash, file, renderer, filepath, _b, _c, blocks, html, templates, _d, _e, partial;
+ return __generator(this, function (_f) {
+ switch (_f.label) {
+ case 0:
+ _a = this, liquid = _a.liquid, hash = _a.hash, file = _a.file;
+ renderer = liquid.renderer;
+ if (!ctx.opts.dynamicPartials) return [3 /*break*/, 4];
+ if (!isQuotedToken(file)) return [3 /*break*/, 2];
+ return [4 /*yield*/, renderer.renderTemplates(liquid.parse(evalQuotedToken(file)), ctx)];
+ case 1:
+ _c = _f.sent();
+ return [3 /*break*/, 3];
+ case 2:
+ _c = evalToken(this.file, ctx);
+ _f.label = 3;
+ case 3:
+ _b = (_c);
+ return [3 /*break*/, 5];
+ case 4:
+ _b = file.getText();
+ _f.label = 5;
+ case 5:
+ filepath = _b;
+ assert(filepath, function () { return "illegal filename \"" + file.getText() + "\":\"" + filepath + "\""; });
+ // render the remaining tokens immediately
+ ctx.setRegister('blockMode', BlockMode$1.STORE);
+ blocks = ctx.getRegister('blocks');
+ return [4 /*yield*/, renderer.renderTemplates(this.tpls, ctx)];
+ case 6:
+ html = _f.sent();
+ if (blocks[''] === undefined)
+ blocks[''] = html;
+ return [4 /*yield*/, liquid._parseFile(filepath, ctx.opts, ctx.sync)];
+ case 7:
+ templates = _f.sent();
+ _e = (_d = ctx).push;
+ return [4 /*yield*/, hash.render(ctx)];
+ case 8:
+ _e.apply(_d, [_f.sent()]);
+ ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
+ return [4 /*yield*/, renderer.renderTemplates(templates, ctx)];
+ case 9:
+ partial = _f.sent();
+ ctx.pop();
+ emitter.write(partial);
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var block = {
+ parse: function (token, remainTokens) {
+ var _this = this;
+ var match = /\w+/.exec(token.args);
+ this.block = match ? match[0] : '';
+ this.tpls = [];
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('tag:endblock', function () { return stream.stop(); })
+ .on('template', function (tpl) { return _this.tpls.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + token.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var blocks, childDefined, r, html, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ blocks = ctx.getRegister('blocks');
+ childDefined = blocks[this.block];
+ r = this.liquid.renderer;
+ if (!(childDefined !== undefined)) return [3 /*break*/, 1];
+ _a = childDefined;
+ return [3 /*break*/, 3];
+ case 1: return [4 /*yield*/, r.renderTemplates(this.tpls, ctx)];
+ case 2:
+ _a = _b.sent();
+ _b.label = 3;
+ case 3:
+ html = _a;
+ if (ctx.getRegister('blockMode', BlockMode$1.OUTPUT) === BlockMode$1.STORE) {
+ blocks[this.block] = html;
+ return [2 /*return*/];
+ }
+ emitter.write(html);
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var raw = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.tokens = [];
+ var stream = this.liquid.parser.parseStream(remainTokens);
+ stream
+ .on('token', function (token) {
+ if (token.name === 'endraw')
+ stream.stop();
+ else
+ _this.tokens.push(token);
+ })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function () {
+ return this.tokens.map(function (token) { return token.getText(); }).join('');
+ }
+ };
+
+ var TablerowloopDrop = /** @class */ (function (_super) {
+ __extends(TablerowloopDrop, _super);
+ function TablerowloopDrop(length, cols) {
+ var _this = _super.call(this, length) || this;
+ _this.length = length;
+ _this.cols = cols;
+ return _this;
+ }
+ TablerowloopDrop.prototype.row = function () {
+ return Math.floor(this.i / this.cols) + 1;
+ };
+ TablerowloopDrop.prototype.col0 = function () {
+ return (this.i % this.cols);
+ };
+ TablerowloopDrop.prototype.col = function () {
+ return this.col0() + 1;
+ };
+ TablerowloopDrop.prototype.col_first = function () {
+ return this.col0() === 0;
+ };
+ TablerowloopDrop.prototype.col_last = function () {
+ return this.col() === this.cols;
+ };
+ return TablerowloopDrop;
+ }(ForloopDrop));
+
+ var tablerow = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ var tokenizer = new Tokenizer(tagToken.args);
+ this.variable = tokenizer.readWord();
+ tokenizer.skipBlank();
+ var tmp = tokenizer.readWord();
+ assert(tmp && tmp.content === 'in', function () { return "illegal tag: " + tagToken.getText(); });
+ this.collection = tokenizer.readValue();
+ this.hash = new Hash(tokenizer.remaining());
+ this.templates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () { return (p = _this.templates); })
+ .on('tag:endtablerow', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var collection, hash, offset, limit, cols, r, tablerowloop, scope, idx;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ collection = toEnumerable(evalToken(this.collection, ctx));
+ return [4 /*yield*/, this.hash.render(ctx)];
+ case 1:
+ hash = _a.sent();
+ offset = hash.offset || 0;
+ limit = (hash.limit === undefined) ? collection.length : hash.limit;
+ collection = collection.slice(offset, offset + limit);
+ cols = hash.cols || collection.length;
+ r = this.liquid.renderer;
+ tablerowloop = new TablerowloopDrop(collection.length, cols);
+ scope = { tablerowloop: tablerowloop };
+ ctx.push(scope);
+ idx = 0;
+ _a.label = 2;
+ case 2:
+ if (!(idx < collection.length)) return [3 /*break*/, 5];
+ scope[this.variable.content] = collection[idx];
+ if (tablerowloop.col0() === 0) {
+ if (tablerowloop.row() !== 1)
+ emitter.write('</tr>');
+ emitter.write("<tr class=\"row" + tablerowloop.row() + "\">");
+ }
+ emitter.write("<td class=\"col" + tablerowloop.col() + "\">");
+ return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
+ case 3:
+ _a.sent();
+ emitter.write('</td>');
+ _a.label = 4;
+ case 4:
+ idx++, tablerowloop.next();
+ return [3 /*break*/, 2];
+ case 5:
+ if (collection.length)
+ emitter.write('</tr>');
+ ctx.pop();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var unless = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.templates = [];
+ this.elseTemplates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () {
+ p = _this.templates;
+ _this.cond = tagToken.args;
+ })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endunless', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, cond;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ r = this.liquid.renderer;
+ return [4 /*yield*/, new Expression(this.cond).value(ctx)];
+ case 1:
+ cond = _a.sent();
+ return [4 /*yield*/, (isFalsy(cond)
+ ? r.renderTemplates(this.templates, ctx, emitter)
+ : r.renderTemplates(this.elseTemplates, ctx, emitter))];
+ case 2:
+ _a.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var Break = {
+ render: function (ctx, emitter) {
+ emitter.break = true;
+ }
+ };
+
+ var Continue = {
+ render: function (ctx, emitter) {
+ emitter.continue = true;
+ }
+ };
+
+ var tags = {
+ assign: assign, 'for': For, capture: capture, 'case': Case, comment: comment, include: include, render: render, decrement: decrement, increment: increment, cycle: cycle, 'if': If, layout: layout, block: block, raw: raw, tablerow: tablerow, unless: unless, 'break': Break, 'continue': Continue
+ };
+
+ var escapeMap = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&#34;',
+ "'": '&#39;'
+ };
+ var unescapeMap = {
+ '&amp;': '&',
+ '&lt;': '<',
+ '&gt;': '>',
+ '&#34;': '"',
+ '&#39;': "'"
+ };
+ function escape(str) {
+ return stringify(str).replace(/&|<|>|"|'/g, function (m) { return escapeMap[m]; });
+ }
+ function unescape(str) {
+ return String(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) { return unescapeMap[m]; });
+ }
+ function escapeOnce(str) {
+ return escape(unescape(str));
+ }
+ function newlineToBr(v) {
+ return v.replace(/\n/g, '<br/>');
+ }
+ function stripHtml(v) {
+ return v.replace(/<script.*?<\/script>|<!--.*?-->|<style.*?<\/style>|<.*?>/g, '');
+ }
+
+ var abs = Math.abs;
+ var atLeast = Math.max;
+ var atMost = Math.min;
+ var ceil = Math.ceil;
+ var dividedBy = function (v, arg) { return v / arg; };
+ var floor = Math.floor;
+ var minus = function (v, arg) { return v - arg; };
+ var modulo = function (v, arg) { return v % arg; };
+ var times = function (v, arg) { return v * arg; };
+ function round(v, arg) {
+ if (arg === void 0) { arg = 0; }
+ var amp = Math.pow(10, arg);
+ return Math.round(v * amp) / amp;
+ }
+ function plus(v, arg) {
+ return Number(v) + Number(arg);
+ }
+ function sortNatural(input, property) {
+ if (!input || !input.sort)
+ return [];
+ if (property !== undefined) {
+ return __spread(input).sort(function (lhs, rhs) { return caseInsensitiveCompare(lhs[property], rhs[property]); });
+ }
+ return __spread(input).sort(caseInsensitiveCompare);
+ }
+
+ var urlDecode = function (x) { return x.split('+').map(decodeURIComponent).join(' '); };
+ var urlEncode = function (x) { return x.split(' ').map(encodeURIComponent).join('+'); };
+
+ var join = function (v, arg) { return v.join(arg === undefined ? ' ' : arg); };
+ var last$1 = function (v) { return isArray(v) ? last(v) : ''; };
+ var first = function (v) { return isArray(v) ? v[0] : ''; };
+ var reverse = function (v) { return __spread(v).reverse(); };
+ var sort = function (v, arg) { return v.sort(arg); };
+ var size = function (v) { return (v && v.length) || 0; };
+ function map(arr, arg) {
+ return toArray(arr).map(function (v) { return v[arg]; });
+ }
+ function concat(v, arg) {
+ return toArray(v).concat(arg);
+ }
+ function slice(v, begin, length) {
+ if (length === void 0) { length = 1; }
+ begin = begin < 0 ? v.length + begin : begin;
+ return v.slice(begin, begin + length);
+ }
+ function where(arr, property, expected) {
+ var _this = this;
+ return toArray(arr).filter(function (obj) {
+ var value = _this.context.getFromScope(obj, String(property).split('.'));
+ return expected === undefined ? isTruthy(value) : value === expected;
+ });
+ }
+ function uniq(arr) {
+ var u = {};
+ return (arr || []).filter(function (val) {
+ if (u.hasOwnProperty(String(val)))
+ return false;
+ u[String(val)] = true;
+ return true;
+ });
+ }
+
+ var rFormat = /%([-_0^#:]+)?(\d+)?([EO])?(.)/;
+ var monthNames = [
+ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
+ 'September', 'October', 'November', 'December'
+ ];
+ var dayNames = [
+ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
+ ];
+ var monthNamesShort = monthNames.map(abbr);
+ var dayNamesShort = dayNames.map(abbr);
+ var suffixes = {
+ 1: 'st',
+ 2: 'nd',
+ 3: 'rd',
+ 'default': 'th'
+ };
+ function abbr(str) {
+ return str.slice(0, 3);
+ }
+ // prototype extensions
+ function daysInMonth(d) {
+ var feb = isLeapYear(d) ? 29 : 28;
+ return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+ }
+ function getDayOfYear(d) {
+ var num = 0;
+ for (var i = 0; i < d.getMonth(); ++i) {
+ num += daysInMonth(d)[i];
+ }
+ return num + d.getDate();
+ }
+ function getWeekOfYear(d, startDay) {
+ // Skip to startDay of this week
+ var now = getDayOfYear(d) + (startDay - d.getDay());
+ // Find the first startDay of the year
+ var jan1 = new Date(d.getFullYear(), 0, 1);
+ var then = (7 - jan1.getDay() + startDay);
+ return String(Math.floor((now - then) / 7) + 1);
+ }
+ function isLeapYear(d) {
+ var year = d.getFullYear();
+ return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));
+ }
+ function getSuffix(d) {
+ var str = d.getDate().toString();
+ var index = parseInt(str.slice(-1));
+ return suffixes[index] || suffixes['default'];
+ }
+ function century(d) {
+ return parseInt(d.getFullYear().toString().substring(0, 2), 10);
+ }
+ // default to 0
+ var padWidths = {
+ d: 2,
+ e: 2,
+ H: 2,
+ I: 2,
+ j: 3,
+ k: 2,
+ l: 2,
+ L: 3,
+ m: 2,
+ M: 2,
+ S: 2,
+ U: 2,
+ W: 2
+ };
+ // default to '0'
+ var padChars = {
+ a: ' ',
+ A: ' ',
+ b: ' ',
+ B: ' ',
+ c: ' ',
+ e: ' ',
+ k: ' ',
+ l: ' ',
+ p: ' ',
+ P: ' '
+ };
+ var formatCodes = {
+ a: function (d) { return dayNamesShort[d.getDay()]; },
+ A: function (d) { return dayNames[d.getDay()]; },
+ b: function (d) { return monthNamesShort[d.getMonth()]; },
+ B: function (d) { return monthNames[d.getMonth()]; },
+ c: function (d) { return d.toLocaleString(); },
+ C: function (d) { return century(d); },
+ d: function (d) { return d.getDate(); },
+ e: function (d) { return d.getDate(); },
+ H: function (d) { return d.getHours(); },
+ I: function (d) { return String(d.getHours() % 12 || 12); },
+ j: function (d) { return getDayOfYear(d); },
+ k: function (d) { return d.getHours(); },
+ l: function (d) { return String(d.getHours() % 12 || 12); },
+ L: function (d) { return d.getMilliseconds(); },
+ m: function (d) { return d.getMonth() + 1; },
+ M: function (d) { return d.getMinutes(); },
+ N: function (d, opts) {
+ var width = Number(opts.width) || 9;
+ var str = String(d.getMilliseconds()).substr(0, width);
+ return padEnd(str, width, '0');
+ },
+ p: function (d) { return (d.getHours() < 12 ? 'AM' : 'PM'); },
+ P: function (d) { return (d.getHours() < 12 ? 'am' : 'pm'); },
+ q: function (d) { return getSuffix(d); },
+ s: function (d) { return Math.round(d.valueOf() / 1000); },
+ S: function (d) { return d.getSeconds(); },
+ u: function (d) { return d.getDay() || 7; },
+ U: function (d) { return getWeekOfYear(d, 0); },
+ w: function (d) { return d.getDay(); },
+ W: function (d) { return getWeekOfYear(d, 1); },
+ x: function (d) { return d.toLocaleDateString(); },
+ X: function (d) { return d.toLocaleTimeString(); },
+ y: function (d) { return d.getFullYear().toString().substring(2, 4); },
+ Y: function (d) { return d.getFullYear(); },
+ z: function (d, opts) {
+ var offset = d.getTimezoneOffset();
+ var nOffset = Math.abs(offset);
+ var h = Math.floor(nOffset / 60);
+ var m = nOffset % 60;
+ return (offset > 0 ? '-' : '+') +
+ padStart(h, 2, '0') +
+ (opts.flags[':'] ? ':' : '') +
+ padStart(m, 2, '0');
+ },
+ 't': function () { return '\t'; },
+ 'n': function () { return '\n'; },
+ '%': function () { return '%'; }
+ };
+ formatCodes.h = formatCodes.b;
+ function strftime (d, formatStr) {
+ var output = '';
+ var remaining = formatStr;
+ var match;
+ while ((match = rFormat.exec(remaining))) {
+ output += remaining.slice(0, match.index);
+ remaining = remaining.slice(match.index + match[0].length);
+ output += format(d, match);
+ }
+ return output + remaining;
+ }
+ function format(d, match) {
+ var e_1, _a;
+ var _b = __read(match, 5), input = _b[0], _c = _b[1], flagStr = _c === void 0 ? '' : _c, width = _b[2], modifier = _b[3], conversion = _b[4];
+ var convert = formatCodes[conversion];
+ if (!convert)
+ return input;
+ var flags = {};
+ try {
+ for (var flagStr_1 = __values(flagStr), flagStr_1_1 = flagStr_1.next(); !flagStr_1_1.done; flagStr_1_1 = flagStr_1.next()) {
+ var flag = flagStr_1_1.value;
+ flags[flag] = true;
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (flagStr_1_1 && !flagStr_1_1.done && (_a = flagStr_1.return)) _a.call(flagStr_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ var ret = String(convert(d, { flags: flags, width: width, modifier: modifier }));
+ var padChar = padChars[conversion] || '0';
+ var padWidth = width || padWidths[conversion] || 0;
+ if (flags['^'])
+ ret = ret.toUpperCase();
+ else if (flags['#'])
+ ret = changeCase(ret);
+ if (flags['_'])
+ padChar = ' ';
+ else if (flags['0'])
+ padChar = '0';
+ if (flags['-'])
+ padWidth = 0;
+ return padStart(ret, padWidth, padChar);
+ }
+
+ function date(v, arg) {
+ var date = v;
+ if (v === 'now' || v === 'today') {
+ date = new Date();
+ }
+ else if (isNumber(v)) {
+ date = new Date(v * 1000);
+ }
+ else if (isString(v)) {
+ date = /^\d+$/.test(v) ? new Date(+v * 1000) : new Date(v);
+ }
+ return isValidDate(date) ? strftime(date, arg) : v;
+ }
+ function isValidDate(date) {
+ return date instanceof Date && !isNaN(date.getTime());
+ }
+
+ function Default(v, arg) {
+ if (isArray(v) || isString(v))
+ return v.length ? v : arg;
+ return isFalsy(toValue(v)) ? arg : v;
+ }
+ function json(v) {
+ return JSON.stringify(v);
+ }
+
+ /**
+ * String related filters
+ *
+ * * prefer stringify() to String() since `undefined`, `null` should eval ''
+ */
+ function append(v, arg) {
+ assert(arg !== undefined, function () { return 'append expect 2 arguments'; });
+ return stringify(v) + stringify(arg);
+ }
+ function prepend(v, arg) {
+ assert(arg !== undefined, function () { return 'prepend expect 2 arguments'; });
+ return stringify(arg) + stringify(v);
+ }
+ function lstrip(v) {
+ return stringify(v).replace(/^\s+/, '');
+ }
+ function downcase(v) {
+ return stringify(v).toLowerCase();
+ }
+ function upcase(str) {
+ return stringify(str).toUpperCase();
+ }
+ function remove(v, arg) {
+ return stringify(v).split(arg).join('');
+ }
+ function removeFirst(v, l) {
+ return stringify(v).replace(l, '');
+ }
+ function rstrip(str) {
+ return stringify(str).replace(/\s+$/, '');
+ }
+ function split(v, arg) {
+ return stringify(v).split(arg);
+ }
+ function strip(v) {
+ return stringify(v).trim();
+ }
+ function stripNewlines(v) {
+ return stringify(v).replace(/\n/g, '');
+ }
+ function capitalize(str) {
+ str = stringify(str);
+ return str.charAt(0).toUpperCase() + str.slice(1);
+ }
+ function replace(v, pattern, replacement) {
+ return stringify(v).split(pattern).join(replacement);
+ }
+ function replaceFirst(v, arg1, arg2) {
+ return stringify(v).replace(arg1, arg2);
+ }
+ function truncate(v, l, o) {
+ if (l === void 0) { l = 50; }
+ if (o === void 0) { o = '...'; }
+ v = stringify(v);
+ if (v.length <= l)
+ return v;
+ return v.substr(0, l - o.length) + o;
+ }
+ function truncatewords(v, l, o) {
+ if (l === void 0) { l = 15; }
+ if (o === void 0) { o = '...'; }
+ var arr = v.split(/\s+/);
+ var ret = arr.slice(0, l).join(' ');
+ if (arr.length >= l)
+ ret += o;
+ return ret;
+ }
+
+
+
+ var builtinFilters = /*#__PURE__*/Object.freeze({
+ escape: escape,
+ escapeOnce: escapeOnce,
+ newlineToBr: newlineToBr,
+ stripHtml: stripHtml,
+ abs: abs,
+ atLeast: atLeast,
+ atMost: atMost,
+ ceil: ceil,
+ dividedBy: dividedBy,
+ floor: floor,
+ minus: minus,
+ modulo: modulo,
+ times: times,
+ round: round,
+ plus: plus,
+ sortNatural: sortNatural,
+ urlDecode: urlDecode,
+ urlEncode: urlEncode,
+ join: join,
+ last: last$1,
+ first: first,
+ reverse: reverse,
+ sort: sort,
+ size: size,
+ map: map,
+ concat: concat,
+ slice: slice,
+ where: where,
+ uniq: uniq,
+ date: date,
+ Default: Default,
+ json: json,
+ append: append,
+ prepend: prepend,
+ lstrip: lstrip,
+ downcase: downcase,
+ upcase: upcase,
+ remove: remove,
+ removeFirst: removeFirst,
+ rstrip: rstrip,
+ split: split,
+ strip: strip,
+ stripNewlines: stripNewlines,
+ capitalize: capitalize,
+ replace: replace,
+ replaceFirst: replaceFirst,
+ truncate: truncate,
+ truncatewords: truncatewords
+ });
+
+ var TagMap = /** @class */ (function () {
+ function TagMap() {
+ this.impls = {};
+ }
+ TagMap.prototype.get = function (name) {
+ var impl = this.impls[name];
+ assert(impl, function () { return "tag \"" + name + "\" not found"; });
+ return impl;
+ };
+ TagMap.prototype.set = function (name, impl) {
+ this.impls[name] = impl;
+ };
+ return TagMap;
+ }());
+
+ var FilterMap = /** @class */ (function () {
+ function FilterMap(strictFilters) {
+ this.strictFilters = strictFilters;
+ this.impls = {};
+ }
+ FilterMap.prototype.get = function (name) {
+ var impl = this.impls[name];
+ assert(impl || !this.strictFilters, function () { return "undefined filter: " + name; });
+ return impl;
+ };
+ FilterMap.prototype.set = function (name, impl) {
+ this.impls[name] = impl;
+ };
+ FilterMap.prototype.create = function (name, args) {
+ return new Filter(name, this.get(name), args);
+ };
+ return FilterMap;
+ }());
+
+ function mkResolve(value) {
+ var ret = {
+ then: function (resolve) { return resolve(value); },
+ catch: function () { return ret; }
+ };
+ return ret;
+ }
+ function mkReject(err) {
+ var ret = {
+ then: function (resolve, reject) {
+ if (reject)
+ return reject(err);
+ return ret;
+ },
+ catch: function (reject) { return reject(err); }
+ };
+ return ret;
+ }
+ function isThenable(val) {
+ return val && isFunction(val.then);
+ }
+ function isCustomIterable(val) {
+ return val && isFunction(val.next) && isFunction(val.throw) && isFunction(val.return);
+ }
+ function toThenable(val) {
+ if (isThenable(val))
+ return val;
+ if (isCustomIterable(val))
+ return reduce();
+ return mkResolve(val);
+ function reduce(prev) {
+ var state;
+ try {
+ state = val.next(prev);
+ }
+ catch (err) {
+ return mkReject(err);
+ }
+ if (state.done)
+ return mkResolve(state.value);
+ return toThenable(state.value).then(reduce, function (err) {
+ var state;
+ try {
+ state = val.throw(err);
+ }
+ catch (e) {
+ return mkReject(e);
+ }
+ if (state.done)
+ return mkResolve(state.value);
+ return reduce(state.value);
+ });
+ }
+ }
+ function toValue$1(val) {
+ var ret;
+ toThenable(val)
+ .then(function (x) {
+ ret = x;
+ return mkResolve(ret);
+ })
+ .catch(function (err) {
+ throw err;
+ });
+ return ret;
+ }
+
+ var Liquid = /** @class */ (function () {
+ function Liquid(opts) {
+ var _this = this;
+ if (opts === void 0) { opts = {}; }
+ this.options = applyDefault(normalize(opts));
+ this.parser = new Parser(this);
+ this.renderer = new Render();
+ this.fs = opts.fs || fs;
+ this.filters = new FilterMap(this.options.strictFilters);
+ this.tags = new TagMap();
+ forOwn(tags, function (conf, name) { return _this.registerTag(snakeCase(name), conf); });
+ forOwn(builtinFilters, function (handler, name) { return _this.registerFilter(snakeCase(name), handler); });
+ }
+ Liquid.prototype.parse = function (html, filepath) {
+ var tokenizer = new Tokenizer(html, filepath);
+ var tokens = tokenizer.readTopLevelTokens(this.options);
+ return this.parser.parse(tokens);
+ };
+ Liquid.prototype._render = function (tpl, scope, opts, sync) {
+ var options = __assign({}, this.options, normalize(opts));
+ var ctx = new Context(scope, options, sync);
+ return this.renderer.renderTemplates(tpl, ctx);
+ };
+ Liquid.prototype.render = function (tpl, scope, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._render(tpl, scope, opts, false))];
+ });
+ });
+ };
+ Liquid.prototype.renderSync = function (tpl, scope, opts) {
+ return toValue$1(this._render(tpl, scope, opts, true));
+ };
+ Liquid.prototype._parseAndRender = function (html, scope, opts, sync) {
+ var tpl = this.parse(html);
+ return this._render(tpl, scope, opts, sync);
+ };
+ Liquid.prototype.parseAndRender = function (html, scope, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._parseAndRender(html, scope, opts, false))];
+ });
+ });
+ };
+ Liquid.prototype.parseAndRenderSync = function (html, scope, opts) {
+ return toValue$1(this._parseAndRender(html, scope, opts, true));
+ };
+ Liquid.prototype._parseFile = function (file, opts, sync) {
+ var options, paths, filepath, paths_1, paths_1_1, filepath, cache, tpls, _a, tpl, _b, _c, e_1_1;
+ var e_1, _d;
+ var _this = this;
+ return __generator(this, function (_e) {
+ switch (_e.label) {
+ case 0:
+ options = __assign({}, this.options, normalize(opts));
+ paths = options.root.map(function (root) { return _this.fs.resolve(root, file, options.extname); });
+ if (this.fs.fallback !== undefined) {
+ filepath = this.fs.fallback(file);
+ if (filepath !== undefined)
+ paths.push(filepath);
+ }
+ _e.label = 1;
+ case 1:
+ _e.trys.push([1, 13, 14, 15]);
+ paths_1 = __values(paths), paths_1_1 = paths_1.next();
+ _e.label = 2;
+ case 2:
+ if (!!paths_1_1.done) return [3 /*break*/, 12];
+ filepath = paths_1_1.value;
+ cache = options.cache;
+ if (!cache) return [3 /*break*/, 4];
+ return [4 /*yield*/, cache.read(filepath)];
+ case 3:
+ tpls = _e.sent();
+ if (tpls)
+ return [2 /*return*/, tpls];
+ _e.label = 4;
+ case 4:
+ if (!sync) return [3 /*break*/, 5];
+ _a = this.fs.existsSync(filepath);
+ return [3 /*break*/, 7];
+ case 5: return [4 /*yield*/, this.fs.exists(filepath)];
+ case 6:
+ _a = _e.sent();
+ _e.label = 7;
+ case 7:
+ if (!(_a))
+ return [3 /*break*/, 11];
+ _b = this.parse;
+ if (!sync) return [3 /*break*/, 8];
+ _c = this.fs.readFileSync(filepath);
+ return [3 /*break*/, 10];
+ case 8: return [4 /*yield*/, this.fs.readFile(filepath)];
+ case 9:
+ _c = _e.sent();
+ _e.label = 10;
+ case 10:
+ tpl = _b.apply(this, [_c, filepath]);
+ if (cache)
+ cache.write(filepath, tpl);
+ return [2 /*return*/, tpl];
+ case 11:
+ paths_1_1 = paths_1.next();
+ return [3 /*break*/, 2];
+ case 12: return [3 /*break*/, 15];
+ case 13:
+ e_1_1 = _e.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 15];
+ case 14:
+ try {
+ if (paths_1_1 && !paths_1_1.done && (_d = paths_1.return)) _d.call(paths_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 15: throw this.lookupError(file, options.root);
+ }
+ });
+ };
+ Liquid.prototype.parseFile = function (file, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._parseFile(file, opts, false))];
+ });
+ });
+ };
+ Liquid.prototype.parseFileSync = function (file, opts) {
+ return toValue$1(this._parseFile(file, opts, true));
+ };
+ Liquid.prototype.renderFile = function (file, ctx, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ var templates;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, this.parseFile(file, opts)];
+ case 1:
+ templates = _a.sent();
+ return [2 /*return*/, this.render(templates, ctx, opts)];
+ }
+ });
+ });
+ };
+ Liquid.prototype.renderFileSync = function (file, ctx, opts) {
+ var options = normalize(opts);
+ var templates = this.parseFileSync(file, options);
+ return this.renderSync(templates, ctx, opts);
+ };
+ Liquid.prototype._evalValue = function (str, ctx) {
+ var value = new Value(str, this.filters);
+ return value.value(ctx);
+ };
+ Liquid.prototype.evalValue = function (str, ctx) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._evalValue(str, ctx))];
+ });
+ });
+ };
+ Liquid.prototype.evalValueSync = function (str, ctx) {
+ return toValue$1(this._evalValue(str, ctx));
+ };
+ Liquid.prototype.registerFilter = function (name, filter) {
+ this.filters.set(name, filter);
+ };
+ Liquid.prototype.registerTag = function (name, tag) {
+ this.tags.set(name, tag);
+ };
+ Liquid.prototype.plugin = function (plugin) {
+ return plugin.call(this, Liquid);
+ };
+ Liquid.prototype.express = function () {
+ var self = this; // eslint-disable-line
+ return function (filePath, ctx, callback) {
+ var opts = { root: __spread(normalizeStringArray(this.root), self.options.root) };
+ self.renderFile(filePath, ctx, opts).then(function (html) { return callback(null, html); }, callback);
+ };
+ };
+ Liquid.prototype.lookupError = function (file, roots) {
+ var err = new Error('ENOENT');
+ err.message = "ENOENT: Failed to lookup \"" + file + "\" in \"" + roots + "\"";
+ err.code = 'ENOENT';
+ return err;
+ };
+ /**
+ * @deprecated use parseFile instead
+ */
+ Liquid.prototype.getTemplate = function (file, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, this.parseFile(file, opts)];
+ });
+ });
+ };
+ /**
+ * @deprecated use parseFileSync instead
+ */
+ Liquid.prototype.getTemplateSync = function (file, opts) {
+ return this.parseFileSync(file, opts);
+ };
+ return Liquid;
+ }());
+
+ exports.AssertionError = AssertionError;
+ exports.Context = Context;
+ exports.Drop = Drop;
+ exports.Emitter = Emitter;
+ exports.Expression = Expression;
+ exports.Hash = Hash;
+ exports.Liquid = Liquid;
+ exports.ParseError = ParseError;
+ exports.ParseStream = ParseStream;
+ exports.TagToken = TagToken;
+ exports.Token = Token;
+ exports.TokenizationError = TokenizationError;
+ exports.Tokenizer = Tokenizer;
+ exports.TypeGuards = typeGuards;
+ exports.assert = assert;
+ exports.evalQuotedToken = evalQuotedToken;
+ exports.evalToken = evalToken;
+ exports.isFalsy = isFalsy;
+ exports.isTruthy = isTruthy;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
+//# sourceMappingURL=liquid.js.map
diff --git a/src/lib/popper.js b/src/lib/popper.js
new file mode 100644
index 0000000..8a17212
--- /dev/null
+++ b/src/lib/popper.js
@@ -0,0 +1,5 @@
+/*
+ Copyright (C) Federico Zivolo 2019
+ Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
+ */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+n+'Width'],10)}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth,10),c=parseFloat(m.borderLeftWidth,10);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop,10),y=parseFloat(m.marginLeft,10);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return le({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return I.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge});
+//# sourceMappingURL=popper.min.js.map
diff --git a/src/lib/pouchdb.js b/src/lib/pouchdb.js
new file mode 100644
index 0000000..9e2812b
--- /dev/null
+++ b/src/lib/pouchdb.js
@@ -0,0 +1,12245 @@
+// PouchDB 7.1.1
+//
+// (c) 2012-2019 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.PouchDB = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){
+'use strict';
+
+module.exports = argsArray;
+
+function argsArray(fun) {
+ return function () {
+ var len = arguments.length;
+ if (len) {
+ var args = [];
+ var i = -1;
+ while (++i < len) {
+ args[i] = arguments[i];
+ }
+ return fun.call(this, args);
+ } else {
+ return fun.call(this, []);
+ }
+ };
+}
+},{}],2:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var objectCreate = Object.create || objectCreatePolyfill
+var objectKeys = Object.keys || objectKeysPolyfill
+var bind = Function.prototype.bind || functionBindPolyfill
+
+function EventEmitter() {
+ if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ }
+
+ this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+var defaultMaxListeners = 10;
+
+var hasDefineProperty;
+try {
+ var o = {};
+ if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
+ hasDefineProperty = o.x === 0;
+} catch (err) { hasDefineProperty = false }
+if (hasDefineProperty) {
+ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
+ enumerable: true,
+ get: function() {
+ return defaultMaxListeners;
+ },
+ set: function(arg) {
+ // check whether the input is a positive number (whose value is zero or
+ // greater and not a NaN).
+ if (typeof arg !== 'number' || arg < 0 || arg !== arg)
+ throw new TypeError('"defaultMaxListeners" must be a positive number');
+ defaultMaxListeners = arg;
+ }
+ });
+} else {
+ EventEmitter.defaultMaxListeners = defaultMaxListeners;
+}
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
+ if (typeof n !== 'number' || n < 0 || isNaN(n))
+ throw new TypeError('"n" argument must be a positive number');
+ this._maxListeners = n;
+ return this;
+};
+
+function $getMaxListeners(that) {
+ if (that._maxListeners === undefined)
+ return EventEmitter.defaultMaxListeners;
+ return that._maxListeners;
+}
+
+EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
+ return $getMaxListeners(this);
+};
+
+// These standalone emit* functions are used to optimize calling of event
+// handlers for fast cases because emit() itself often has a variable number of
+// arguments and can be deoptimized because of that. These functions always have
+// the same number of arguments and thus do not get deoptimized, so the code
+// inside them can execute faster.
+function emitNone(handler, isFn, self) {
+ if (isFn)
+ handler.call(self);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self);
+ }
+}
+function emitOne(handler, isFn, self, arg1) {
+ if (isFn)
+ handler.call(self, arg1);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1);
+ }
+}
+function emitTwo(handler, isFn, self, arg1, arg2) {
+ if (isFn)
+ handler.call(self, arg1, arg2);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1, arg2);
+ }
+}
+function emitThree(handler, isFn, self, arg1, arg2, arg3) {
+ if (isFn)
+ handler.call(self, arg1, arg2, arg3);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1, arg2, arg3);
+ }
+}
+
+function emitMany(handler, isFn, self, args) {
+ if (isFn)
+ handler.apply(self, args);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].apply(self, args);
+ }
+}
+
+EventEmitter.prototype.emit = function emit(type) {
+ var er, handler, len, args, i, events;
+ var doError = (type === 'error');
+
+ events = this._events;
+ if (events)
+ doError = (doError && events.error == null);
+ else if (!doError)
+ return false;
+
+ // If there is no 'error' event listener then throw.
+ if (doError) {
+ if (arguments.length > 1)
+ er = arguments[1];
+ if (er instanceof Error) {
+ throw er; // Unhandled 'error' event
+ } else {
+ // At least give some kind of context to the user
+ var err = new Error('Unhandled "error" event. (' + er + ')');
+ err.context = er;
+ throw err;
+ }
+ return false;
+ }
+
+ handler = events[type];
+
+ if (!handler)
+ return false;
+
+ var isFn = typeof handler === 'function';
+ len = arguments.length;
+ switch (len) {
+ // fast cases
+ case 1:
+ emitNone(handler, isFn, this);
+ break;
+ case 2:
+ emitOne(handler, isFn, this, arguments[1]);
+ break;
+ case 3:
+ emitTwo(handler, isFn, this, arguments[1], arguments[2]);
+ break;
+ case 4:
+ emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
+ break;
+ // slower
+ default:
+ args = new Array(len - 1);
+ for (i = 1; i < len; i++)
+ args[i - 1] = arguments[i];
+ emitMany(handler, isFn, this, args);
+ }
+
+ return true;
+};
+
+function _addListener(target, type, listener, prepend) {
+ var m;
+ var events;
+ var existing;
+
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+
+ events = target._events;
+ if (!events) {
+ events = target._events = objectCreate(null);
+ target._eventsCount = 0;
+ } else {
+ // To avoid recursion in the case that type === "newListener"! Before
+ // adding it to the listeners, first emit "newListener".
+ if (events.newListener) {
+ target.emit('newListener', type,
+ listener.listener ? listener.listener : listener);
+
+ // Re-assign `events` because a newListener handler could have caused the
+ // this._events to be assigned to a new object
+ events = target._events;
+ }
+ existing = events[type];
+ }
+
+ if (!existing) {
+ // Optimize the case of one listener. Don't need the extra array object.
+ existing = events[type] = listener;
+ ++target._eventsCount;
+ } else {
+ if (typeof existing === 'function') {
+ // Adding the second element, need to change to array.
+ existing = events[type] =
+ prepend ? [listener, existing] : [existing, listener];
+ } else {
+ // If we've already got an array, just append.
+ if (prepend) {
+ existing.unshift(listener);
+ } else {
+ existing.push(listener);
+ }
+ }
+
+ // Check for listener leak
+ if (!existing.warned) {
+ m = $getMaxListeners(target);
+ if (m && m > 0 && existing.length > m) {
+ existing.warned = true;
+ var w = new Error('Possible EventEmitter memory leak detected. ' +
+ existing.length + ' "' + String(type) + '" listeners ' +
+ 'added. Use emitter.setMaxListeners() to ' +
+ 'increase limit.');
+ w.name = 'MaxListenersExceededWarning';
+ w.emitter = target;
+ w.type = type;
+ w.count = existing.length;
+ if (typeof console === 'object' && console.warn) {
+ console.warn('%s: %s', w.name, w.message);
+ }
+ }
+ }
+ }
+
+ return target;
+}
+
+EventEmitter.prototype.addListener = function addListener(type, listener) {
+ return _addListener(this, type, listener, false);
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.prependListener =
+ function prependListener(type, listener) {
+ return _addListener(this, type, listener, true);
+ };
+
+function onceWrapper() {
+ if (!this.fired) {
+ this.target.removeListener(this.type, this.wrapFn);
+ this.fired = true;
+ switch (arguments.length) {
+ case 0:
+ return this.listener.call(this.target);
+ case 1:
+ return this.listener.call(this.target, arguments[0]);
+ case 2:
+ return this.listener.call(this.target, arguments[0], arguments[1]);
+ case 3:
+ return this.listener.call(this.target, arguments[0], arguments[1],
+ arguments[2]);
+ default:
+ var args = new Array(arguments.length);
+ for (var i = 0; i < args.length; ++i)
+ args[i] = arguments[i];
+ this.listener.apply(this.target, args);
+ }
+ }
+}
+
+function _onceWrap(target, type, listener) {
+ var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
+ var wrapped = bind.call(onceWrapper, state);
+ wrapped.listener = listener;
+ state.wrapFn = wrapped;
+ return wrapped;
+}
+
+EventEmitter.prototype.once = function once(type, listener) {
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+ this.on(type, _onceWrap(this, type, listener));
+ return this;
+};
+
+EventEmitter.prototype.prependOnceListener =
+ function prependOnceListener(type, listener) {
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+ this.prependListener(type, _onceWrap(this, type, listener));
+ return this;
+ };
+
+// Emits a 'removeListener' event if and only if the listener was removed.
+EventEmitter.prototype.removeListener =
+ function removeListener(type, listener) {
+ var list, events, position, i, originalListener;
+
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+
+ events = this._events;
+ if (!events)
+ return this;
+
+ list = events[type];
+ if (!list)
+ return this;
+
+ if (list === listener || list.listener === listener) {
+ if (--this._eventsCount === 0)
+ this._events = objectCreate(null);
+ else {
+ delete events[type];
+ if (events.removeListener)
+ this.emit('removeListener', type, list.listener || listener);
+ }
+ } else if (typeof list !== 'function') {
+ position = -1;
+
+ for (i = list.length - 1; i >= 0; i--) {
+ if (list[i] === listener || list[i].listener === listener) {
+ originalListener = list[i].listener;
+ position = i;
+ break;
+ }
+ }
+
+ if (position < 0)
+ return this;
+
+ if (position === 0)
+ list.shift();
+ else
+ spliceOne(list, position);
+
+ if (list.length === 1)
+ events[type] = list[0];
+
+ if (events.removeListener)
+ this.emit('removeListener', type, originalListener || listener);
+ }
+
+ return this;
+ };
+
+EventEmitter.prototype.removeAllListeners =
+ function removeAllListeners(type) {
+ var listeners, events, i;
+
+ events = this._events;
+ if (!events)
+ return this;
+
+ // not listening for removeListener, no need to emit
+ if (!events.removeListener) {
+ if (arguments.length === 0) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ } else if (events[type]) {
+ if (--this._eventsCount === 0)
+ this._events = objectCreate(null);
+ else
+ delete events[type];
+ }
+ return this;
+ }
+
+ // emit removeListener for all listeners on all events
+ if (arguments.length === 0) {
+ var keys = objectKeys(events);
+ var key;
+ for (i = 0; i < keys.length; ++i) {
+ key = keys[i];
+ if (key === 'removeListener') continue;
+ this.removeAllListeners(key);
+ }
+ this.removeAllListeners('removeListener');
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ return this;
+ }
+
+ listeners = events[type];
+
+ if (typeof listeners === 'function') {
+ this.removeListener(type, listeners);
+ } else if (listeners) {
+ // LIFO order
+ for (i = listeners.length - 1; i >= 0; i--) {
+ this.removeListener(type, listeners[i]);
+ }
+ }
+
+ return this;
+ };
+
+function _listeners(target, type, unwrap) {
+ var events = target._events;
+
+ if (!events)
+ return [];
+
+ var evlistener = events[type];
+ if (!evlistener)
+ return [];
+
+ if (typeof evlistener === 'function')
+ return unwrap ? [evlistener.listener || evlistener] : [evlistener];
+
+ return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
+}
+
+EventEmitter.prototype.listeners = function listeners(type) {
+ return _listeners(this, type, true);
+};
+
+EventEmitter.prototype.rawListeners = function rawListeners(type) {
+ return _listeners(this, type, false);
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+ if (typeof emitter.listenerCount === 'function') {
+ return emitter.listenerCount(type);
+ } else {
+ return listenerCount.call(emitter, type);
+ }
+};
+
+EventEmitter.prototype.listenerCount = listenerCount;
+function listenerCount(type) {
+ var events = this._events;
+
+ if (events) {
+ var evlistener = events[type];
+
+ if (typeof evlistener === 'function') {
+ return 1;
+ } else if (evlistener) {
+ return evlistener.length;
+ }
+ }
+
+ return 0;
+}
+
+EventEmitter.prototype.eventNames = function eventNames() {
+ return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
+};
+
+// About 1.5x faster than the two-arg version of Array#splice().
+function spliceOne(list, index) {
+ for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
+ list[i] = list[k];
+ list.pop();
+}
+
+function arrayClone(arr, n) {
+ var copy = new Array(n);
+ for (var i = 0; i < n; ++i)
+ copy[i] = arr[i];
+ return copy;
+}
+
+function unwrapListeners(arr) {
+ var ret = new Array(arr.length);
+ for (var i = 0; i < ret.length; ++i) {
+ ret[i] = arr[i].listener || arr[i];
+ }
+ return ret;
+}
+
+function objectCreatePolyfill(proto) {
+ var F = function() {};
+ F.prototype = proto;
+ return new F;
+}
+function objectKeysPolyfill(obj) {
+ var keys = [];
+ for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {
+ keys.push(k);
+ }
+ return k;
+}
+function functionBindPolyfill(context) {
+ var fn = this;
+ return function () {
+ return fn.apply(context, arguments);
+ };
+}
+
+},{}],3:[function(_dereq_,module,exports){
+(function (global){
+'use strict';
+var Mutation = global.MutationObserver || global.WebKitMutationObserver;
+
+var scheduleDrain;
+
+{
+ if (Mutation) {
+ var called = 0;
+ var observer = new Mutation(nextTick);
+ var element = global.document.createTextNode('');
+ observer.observe(element, {
+ characterData: true
+ });
+ scheduleDrain = function () {
+ element.data = (called = ++called % 2);
+ };
+ } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
+ var channel = new global.MessageChannel();
+ channel.port1.onmessage = nextTick;
+ scheduleDrain = function () {
+ channel.port2.postMessage(0);
+ };
+ } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
+ scheduleDrain = function () {
+
+ // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+ // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+ var scriptEl = global.document.createElement('script');
+ scriptEl.onreadystatechange = function () {
+ nextTick();
+
+ scriptEl.onreadystatechange = null;
+ scriptEl.parentNode.removeChild(scriptEl);
+ scriptEl = null;
+ };
+ global.document.documentElement.appendChild(scriptEl);
+ };
+ } else {
+ scheduleDrain = function () {
+ setTimeout(nextTick, 0);
+ };
+ }
+}
+
+var draining;
+var queue = [];
+//named nextTick for less confusing stack traces
+function nextTick() {
+ draining = true;
+ var i, oldQueue;
+ var len = queue.length;
+ while (len) {
+ oldQueue = queue;
+ queue = [];
+ i = -1;
+ while (++i < len) {
+ oldQueue[i]();
+ }
+ len = queue.length;
+ }
+ draining = false;
+}
+
+module.exports = immediate;
+function immediate(task) {
+ if (queue.push(task) === 1 && !draining) {
+ scheduleDrain();
+ }
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],4:[function(_dereq_,module,exports){
+if (typeof Object.create === 'function') {
+ // implementation from standard node.js 'util' module
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ ctor.prototype = Object.create(superCtor.prototype, {
+ constructor: {
+ value: ctor,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ };
+} else {
+ // old school shim for old browsers
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ var TempCtor = function () {}
+ TempCtor.prototype = superCtor.prototype
+ ctor.prototype = new TempCtor()
+ ctor.prototype.constructor = ctor
+ }
+}
+
+},{}],5:[function(_dereq_,module,exports){
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things. But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals. It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+ throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+ throw new Error('clearTimeout has not been defined');
+}
+(function () {
+ try {
+ if (typeof setTimeout === 'function') {
+ cachedSetTimeout = setTimeout;
+ } else {
+ cachedSetTimeout = defaultSetTimout;
+ }
+ } catch (e) {
+ cachedSetTimeout = defaultSetTimout;
+ }
+ try {
+ if (typeof clearTimeout === 'function') {
+ cachedClearTimeout = clearTimeout;
+ } else {
+ cachedClearTimeout = defaultClearTimeout;
+ }
+ } catch (e) {
+ cachedClearTimeout = defaultClearTimeout;
+ }
+} ())
+function runTimeout(fun) {
+ if (cachedSetTimeout === setTimeout) {
+ //normal enviroments in sane situations
+ return setTimeout(fun, 0);
+ }
+ // if setTimeout wasn't available but was latter defined
+ if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+ cachedSetTimeout = setTimeout;
+ return setTimeout(fun, 0);
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedSetTimeout(fun, 0);
+ } catch(e){
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedSetTimeout.call(null, fun, 0);
+ } catch(e){
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+ return cachedSetTimeout.call(this, fun, 0);
+ }
+ }
+
+
+}
+function runClearTimeout(marker) {
+ if (cachedClearTimeout === clearTimeout) {
+ //normal enviroments in sane situations
+ return clearTimeout(marker);
+ }
+ // if clearTimeout wasn't available but was latter defined
+ if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+ cachedClearTimeout = clearTimeout;
+ return clearTimeout(marker);
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedClearTimeout(marker);
+ } catch (e){
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedClearTimeout.call(null, marker);
+ } catch (e){
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+ // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+ return cachedClearTimeout.call(this, marker);
+ }
+ }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+ if (!draining || !currentQueue) {
+ return;
+ }
+ draining = false;
+ if (currentQueue.length) {
+ queue = currentQueue.concat(queue);
+ } else {
+ queueIndex = -1;
+ }
+ if (queue.length) {
+ drainQueue();
+ }
+}
+
+function drainQueue() {
+ if (draining) {
+ return;
+ }
+ var timeout = runTimeout(cleanUpNextTick);
+ draining = true;
+
+ var len = queue.length;
+ while(len) {
+ currentQueue = queue;
+ queue = [];
+ while (++queueIndex < len) {
+ if (currentQueue) {
+ currentQueue[queueIndex].run();
+ }
+ }
+ queueIndex = -1;
+ len = queue.length;
+ }
+ currentQueue = null;
+ draining = false;
+ runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+ var args = new Array(arguments.length - 1);
+ if (arguments.length > 1) {
+ for (var i = 1; i < arguments.length; i++) {
+ args[i - 1] = arguments[i];
+ }
+ }
+ queue.push(new Item(fun, args));
+ if (queue.length === 1 && !draining) {
+ runTimeout(drainQueue);
+ }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+ this.fun = fun;
+ this.array = array;
+}
+Item.prototype.run = function () {
+ this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+ throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+ throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],6:[function(_dereq_,module,exports){
+(function (factory) {
+ if (typeof exports === 'object') {
+ // Node/CommonJS
+ module.exports = factory();
+ } else if (typeof define === 'function' && define.amd) {
+ // AMD
+ define(factory);
+ } else {
+ // Browser globals (with support for web workers)
+ var glob;
+
+ try {
+ glob = window;
+ } catch (e) {
+ glob = self;
+ }
+
+ glob.SparkMD5 = factory();
+ }
+}(function (undefined) {
+
+ 'use strict';
+
+ /*
+ * Fastest md5 implementation around (JKM md5).
+ * Credits: Joseph Myers
+ *
+ * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
+ * @see http://jsperf.com/md5-shootout/7
+ */
+
+ /* this function is much faster,
+ so if possible we use it. Some IEs
+ are the only ones I know of that
+ need the idiotic second function,
+ generated by an if clause. */
+ var add32 = function (a, b) {
+ return (a + b) & 0xFFFFFFFF;
+ },
+ hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+
+
+ function cmn(q, a, b, x, s, t) {
+ a = add32(add32(a, q), add32(x, t));
+ return add32((a << s) | (a >>> (32 - s)), b);
+ }
+
+ function md5cycle(x, k) {
+ var a = x[0],
+ b = x[1],
+ c = x[2],
+ d = x[3];
+
+ a += (b & c | ~b & d) + k[0] - 680876936 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[1] - 389564586 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[2] + 606105819 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & c | ~b & d) + k[4] - 176418897 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[7] - 45705983 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[10] - 42063 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[13] - 40341101 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+
+ a += (b & d | c & ~d) + k[1] - 165796510 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[11] + 643717713 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[0] - 373897302 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b & d | c & ~d) + k[5] - 701558691 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[10] + 38016083 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[15] - 660478335 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[4] - 405537848 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b & d | c & ~d) + k[9] + 568446438 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[3] - 187363961 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[2] - 51403784 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+
+ a += (b ^ c ^ d) + k[5] - 378558 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[14] - 35309556 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[7] - 155497632 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (b ^ c ^ d) + k[13] + 681279174 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[0] - 358537222 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[3] - 722521979 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[6] + 76029189 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (b ^ c ^ d) + k[9] - 640364487 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[12] - 421815835 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[15] + 530742520 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[2] - 995338651 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+
+ a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
+ b = (b << 21 |b >>> 11) + c | 0;
+ a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
+ b = (b << 21 |b >>> 11) + c | 0;
+ a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
+ b = (b << 21 |b >>> 11) + c | 0;
+ a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
+ b = (b << 21 | b >>> 11) + c | 0;
+
+ x[0] = a + x[0] | 0;
+ x[1] = b + x[1] | 0;
+ x[2] = c + x[2] | 0;
+ x[3] = d + x[3] | 0;
+ }
+
+ function md5blk(s) {
+ var md5blks = [],
+ i; /* Andy King said do it this way. */
+
+ for (i = 0; i < 64; i += 4) {
+ md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+ }
+ return md5blks;
+ }
+
+ function md5blk_array(a) {
+ var md5blks = [],
+ i; /* Andy King said do it this way. */
+
+ for (i = 0; i < 64; i += 4) {
+ md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
+ }
+ return md5blks;
+ }
+
+ function md51(s) {
+ var n = s.length,
+ state = [1732584193, -271733879, -1732584194, 271733878],
+ i,
+ length,
+ tail,
+ tmp,
+ lo,
+ hi;
+
+ for (i = 64; i <= n; i += 64) {
+ md5cycle(state, md5blk(s.substring(i - 64, i)));
+ }
+ s = s.substring(i - 64);
+ length = s.length;
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
+ }
+ tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+ if (i > 55) {
+ md5cycle(state, tail);
+ for (i = 0; i < 16; i += 1) {
+ tail[i] = 0;
+ }
+ }
+
+ // Beware that the final length might not fit in 32 bits so we take care of that
+ tmp = n * 8;
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+ lo = parseInt(tmp[2], 16);
+ hi = parseInt(tmp[1], 16) || 0;
+
+ tail[14] = lo;
+ tail[15] = hi;
+
+ md5cycle(state, tail);
+ return state;
+ }
+
+ function md51_array(a) {
+ var n = a.length,
+ state = [1732584193, -271733879, -1732584194, 271733878],
+ i,
+ length,
+ tail,
+ tmp,
+ lo,
+ hi;
+
+ for (i = 64; i <= n; i += 64) {
+ md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
+ }
+
+ // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
+ // containing the last element of the parent array if the sub array specified starts
+ // beyond the length of the parent array - weird.
+ // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
+ a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
+
+ length = a.length;
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= a[i] << ((i % 4) << 3);
+ }
+
+ tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+ if (i > 55) {
+ md5cycle(state, tail);
+ for (i = 0; i < 16; i += 1) {
+ tail[i] = 0;
+ }
+ }
+
+ // Beware that the final length might not fit in 32 bits so we take care of that
+ tmp = n * 8;
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+ lo = parseInt(tmp[2], 16);
+ hi = parseInt(tmp[1], 16) || 0;
+
+ tail[14] = lo;
+ tail[15] = hi;
+
+ md5cycle(state, tail);
+
+ return state;
+ }
+
+ function rhex(n) {
+ var s = '',
+ j;
+ for (j = 0; j < 4; j += 1) {
+ s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
+ }
+ return s;
+ }
+
+ function hex(x) {
+ var i;
+ for (i = 0; i < x.length; i += 1) {
+ x[i] = rhex(x[i]);
+ }
+ return x.join('');
+ }
+
+ // In some cases the fast add32 function cannot be used..
+ if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
+ add32 = function (x, y) {
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+ msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+ };
+ }
+
+ // ---------------------------------------------------
+
+ /**
+ * ArrayBuffer slice polyfill.
+ *
+ * @see https://github.com/ttaubert/node-arraybuffer-slice
+ */
+
+ if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
+ (function () {
+ function clamp(val, length) {
+ val = (val | 0) || 0;
+
+ if (val < 0) {
+ return Math.max(val + length, 0);
+ }
+
+ return Math.min(val, length);
+ }
+
+ ArrayBuffer.prototype.slice = function (from, to) {
+ var length = this.byteLength,
+ begin = clamp(from, length),
+ end = length,
+ num,
+ target,
+ targetArray,
+ sourceArray;
+
+ if (to !== undefined) {
+ end = clamp(to, length);
+ }
+
+ if (begin > end) {
+ return new ArrayBuffer(0);
+ }
+
+ num = end - begin;
+ target = new ArrayBuffer(num);
+ targetArray = new Uint8Array(target);
+
+ sourceArray = new Uint8Array(this, begin, num);
+ targetArray.set(sourceArray);
+
+ return target;
+ };
+ })();
+ }
+
+ // ---------------------------------------------------
+
+ /**
+ * Helpers.
+ */
+
+ function toUtf8(str) {
+ if (/[\u0080-\uFFFF]/.test(str)) {
+ str = unescape(encodeURIComponent(str));
+ }
+
+ return str;
+ }
+
+ function utf8Str2ArrayBuffer(str, returnUInt8Array) {
+ var length = str.length,
+ buff = new ArrayBuffer(length),
+ arr = new Uint8Array(buff),
+ i;
+
+ for (i = 0; i < length; i += 1) {
+ arr[i] = str.charCodeAt(i);
+ }
+
+ return returnUInt8Array ? arr : buff;
+ }
+
+ function arrayBuffer2Utf8Str(buff) {
+ return String.fromCharCode.apply(null, new Uint8Array(buff));
+ }
+
+ function concatenateArrayBuffers(first, second, returnUInt8Array) {
+ var result = new Uint8Array(first.byteLength + second.byteLength);
+
+ result.set(new Uint8Array(first));
+ result.set(new Uint8Array(second), first.byteLength);
+
+ return returnUInt8Array ? result : result.buffer;
+ }
+
+ function hexToBinaryString(hex) {
+ var bytes = [],
+ length = hex.length,
+ x;
+
+ for (x = 0; x < length - 1; x += 2) {
+ bytes.push(parseInt(hex.substr(x, 2), 16));
+ }
+
+ return String.fromCharCode.apply(String, bytes);
+ }
+
+ // ---------------------------------------------------
+
+ /**
+ * SparkMD5 OOP implementation.
+ *
+ * Use this class to perform an incremental md5, otherwise use the
+ * static methods instead.
+ */
+
+ function SparkMD5() {
+ // call reset to init the instance
+ this.reset();
+ }
+
+ /**
+ * Appends a string.
+ * A conversion will be applied if an utf8 string is detected.
+ *
+ * @param {String} str The string to be appended
+ *
+ * @return {SparkMD5} The instance itself
+ */
+ SparkMD5.prototype.append = function (str) {
+ // Converts the string to utf8 bytes if necessary
+ // Then append as binary
+ this.appendBinary(toUtf8(str));
+
+ return this;
+ };
+
+ /**
+ * Appends a binary string.
+ *
+ * @param {String} contents The binary string to be appended
+ *
+ * @return {SparkMD5} The instance itself
+ */
+ SparkMD5.prototype.appendBinary = function (contents) {
+ this._buff += contents;
+ this._length += contents.length;
+
+ var length = this._buff.length,
+ i;
+
+ for (i = 64; i <= length; i += 64) {
+ md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
+ }
+
+ this._buff = this._buff.substring(i - 64);
+
+ return this;
+ };
+
+ /**
+ * Finishes the incremental computation, reseting the internal state and
+ * returning the result.
+ *
+ * @param {Boolean} raw True to get the raw string, false to get the hex string
+ *
+ * @return {String} The result
+ */
+ SparkMD5.prototype.end = function (raw) {
+ var buff = this._buff,
+ length = buff.length,
+ i,
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ ret;
+
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
+ }
+
+ this._finish(tail, length);
+ ret = hex(this._hash);
+
+ if (raw) {
+ ret = hexToBinaryString(ret);
+ }
+
+ this.reset();
+
+ return ret;
+ };
+
+ /**
+ * Resets the internal state of the computation.
+ *
+ * @return {SparkMD5} The instance itself
+ */
+ SparkMD5.prototype.reset = function () {
+ this._buff = '';
+ this._length = 0;
+ this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+ return this;
+ };
+
+ /**
+ * Gets the internal state of the computation.
+ *
+ * @return {Object} The state
+ */
+ SparkMD5.prototype.getState = function () {
+ return {
+ buff: this._buff,
+ length: this._length,
+ hash: this._hash
+ };
+ };
+
+ /**
+ * Gets the internal state of the computation.
+ *
+ * @param {Object} state The state
+ *
+ * @return {SparkMD5} The instance itself
+ */
+ SparkMD5.prototype.setState = function (state) {
+ this._buff = state.buff;
+ this._length = state.length;
+ this._hash = state.hash;
+
+ return this;
+ };
+
+ /**
+ * Releases memory used by the incremental buffer and other additional
+ * resources. If you plan to use the instance again, use reset instead.
+ */
+ SparkMD5.prototype.destroy = function () {
+ delete this._hash;
+ delete this._buff;
+ delete this._length;
+ };
+
+ /**
+ * Finish the final calculation based on the tail.
+ *
+ * @param {Array} tail The tail (will be modified)
+ * @param {Number} length The length of the remaining buffer
+ */
+ SparkMD5.prototype._finish = function (tail, length) {
+ var i = length,
+ tmp,
+ lo,
+ hi;
+
+ tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+ if (i > 55) {
+ md5cycle(this._hash, tail);
+ for (i = 0; i < 16; i += 1) {
+ tail[i] = 0;
+ }
+ }
+
+ // Do the final computation based on the tail and length
+ // Beware that the final length may not fit in 32 bits so we take care of that
+ tmp = this._length * 8;
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+ lo = parseInt(tmp[2], 16);
+ hi = parseInt(tmp[1], 16) || 0;
+
+ tail[14] = lo;
+ tail[15] = hi;
+ md5cycle(this._hash, tail);
+ };
+
+ /**
+ * Performs the md5 hash on a string.
+ * A conversion will be applied if utf8 string is detected.
+ *
+ * @param {String} str The string
+ * @param {Boolean} raw True to get the raw string, false to get the hex string
+ *
+ * @return {String} The result
+ */
+ SparkMD5.hash = function (str, raw) {
+ // Converts the string to utf8 bytes if necessary
+ // Then compute it using the binary function
+ return SparkMD5.hashBinary(toUtf8(str), raw);
+ };
+
+ /**
+ * Performs the md5 hash on a binary string.
+ *
+ * @param {String} content The binary string
+ * @param {Boolean} raw True to get the raw string, false to get the hex string
+ *
+ * @return {String} The result
+ */
+ SparkMD5.hashBinary = function (content, raw) {
+ var hash = md51(content),
+ ret = hex(hash);
+
+ return raw ? hexToBinaryString(ret) : ret;
+ };
+
+ // ---------------------------------------------------
+
+ /**
+ * SparkMD5 OOP implementation for array buffers.
+ *
+ * Use this class to perform an incremental md5 ONLY for array buffers.
+ */
+ SparkMD5.ArrayBuffer = function () {
+ // call reset to init the instance
+ this.reset();
+ };
+
+ /**
+ * Appends an array buffer.
+ *
+ * @param {ArrayBuffer} arr The array to be appended
+ *
+ * @return {SparkMD5.ArrayBuffer} The instance itself
+ */
+ SparkMD5.ArrayBuffer.prototype.append = function (arr) {
+ var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
+ length = buff.length,
+ i;
+
+ this._length += arr.byteLength;
+
+ for (i = 64; i <= length; i += 64) {
+ md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
+ }
+
+ this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
+
+ return this;
+ };
+
+ /**
+ * Finishes the incremental computation, reseting the internal state and
+ * returning the result.
+ *
+ * @param {Boolean} raw True to get the raw string, false to get the hex string
+ *
+ * @return {String} The result
+ */
+ SparkMD5.ArrayBuffer.prototype.end = function (raw) {
+ var buff = this._buff,
+ length = buff.length,
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ i,
+ ret;
+
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= buff[i] << ((i % 4) << 3);
+ }
+
+ this._finish(tail, length);
+ ret = hex(this._hash);
+
+ if (raw) {
+ ret = hexToBinaryString(ret);
+ }
+
+ this.reset();
+
+ return ret;
+ };
+
+ /**
+ * Resets the internal state of the computation.
+ *
+ * @return {SparkMD5.ArrayBuffer} The instance itself
+ */
+ SparkMD5.ArrayBuffer.prototype.reset = function () {
+ this._buff = new Uint8Array(0);
+ this._length = 0;
+ this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+ return this;
+ };
+
+ /**
+ * Gets the internal state of the computation.
+ *
+ * @return {Object} The state
+ */
+ SparkMD5.ArrayBuffer.prototype.getState = function () {
+ var state = SparkMD5.prototype.getState.call(this);
+
+ // Convert buffer to a string
+ state.buff = arrayBuffer2Utf8Str(state.buff);
+
+ return state;
+ };
+
+ /**
+ * Gets the internal state of the computation.
+ *
+ * @param {Object} state The state
+ *
+ * @return {SparkMD5.ArrayBuffer} The instance itself
+ */
+ SparkMD5.ArrayBuffer.prototype.setState = function (state) {
+ // Convert string to buffer
+ state.buff = utf8Str2ArrayBuffer(state.buff, true);
+
+ return SparkMD5.prototype.setState.call(this, state);
+ };
+
+ SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
+
+ SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
+
+ /**
+ * Performs the md5 hash on an array buffer.
+ *
+ * @param {ArrayBuffer} arr The array buffer
+ * @param {Boolean} raw True to get the raw string, false to get the hex one
+ *
+ * @return {String} The result
+ */
+ SparkMD5.ArrayBuffer.hash = function (arr, raw) {
+ var hash = md51_array(new Uint8Array(arr)),
+ ret = hex(hash);
+
+ return raw ? hexToBinaryString(ret) : ret;
+ };
+
+ return SparkMD5;
+}));
+
+},{}],7:[function(_dereq_,module,exports){
+var v1 = _dereq_(10);
+var v4 = _dereq_(11);
+
+var uuid = v4;
+uuid.v1 = v1;
+uuid.v4 = v4;
+
+module.exports = uuid;
+
+},{"10":10,"11":11}],8:[function(_dereq_,module,exports){
+/**
+ * Convert array of 16 byte values to UUID string format of the form:
+ * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+ */
+var byteToHex = [];
+for (var i = 0; i < 256; ++i) {
+ byteToHex[i] = (i + 0x100).toString(16).substr(1);
+}
+
+function bytesToUuid(buf, offset) {
+ var i = offset || 0;
+ var bth = byteToHex;
+ return bth[buf[i++]] + bth[buf[i++]] +
+ bth[buf[i++]] + bth[buf[i++]] + '-' +
+ bth[buf[i++]] + bth[buf[i++]] + '-' +
+ bth[buf[i++]] + bth[buf[i++]] + '-' +
+ bth[buf[i++]] + bth[buf[i++]] + '-' +
+ bth[buf[i++]] + bth[buf[i++]] +
+ bth[buf[i++]] + bth[buf[i++]] +
+ bth[buf[i++]] + bth[buf[i++]];
+}
+
+module.exports = bytesToUuid;
+
+},{}],9:[function(_dereq_,module,exports){
+// Unique ID creation requires a high quality random # generator. In the
+// browser this is a little complicated due to unknown quality of Math.random()
+// and inconsistent support for the `crypto` API. We do the best we can via
+// feature-detection
+
+// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
+var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues.bind(crypto)) ||
+ (typeof(msCrypto) != 'undefined' && msCrypto.getRandomValues.bind(msCrypto));
+if (getRandomValues) {
+ // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
+ var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
+
+ module.exports = function whatwgRNG() {
+ getRandomValues(rnds8);
+ return rnds8;
+ };
+} else {
+ // Math.random()-based (RNG)
+ //
+ // If all else fails, use Math.random(). It's fast, but is of unspecified
+ // quality.
+ var rnds = new Array(16);
+
+ module.exports = function mathRNG() {
+ for (var i = 0, r; i < 16; i++) {
+ if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
+ rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
+ }
+
+ return rnds;
+ };
+}
+
+},{}],10:[function(_dereq_,module,exports){
+var rng = _dereq_(9);
+var bytesToUuid = _dereq_(8);
+
+// **`v1()` - Generate time-based UUID**
+//
+// Inspired by https://github.com/LiosK/UUID.js
+// and http://docs.python.org/library/uuid.html
+
+var _nodeId;
+var _clockseq;
+
+// Previous uuid creation time
+var _lastMSecs = 0;
+var _lastNSecs = 0;
+
+// See https://github.com/broofa/node-uuid for API details
+function v1(options, buf, offset) {
+ var i = buf && offset || 0;
+ var b = buf || [];
+
+ options = options || {};
+ var node = options.node || _nodeId;
+ var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;
+
+ // node and clockseq need to be initialized to random values if they're not
+ // specified. We do this lazily to minimize issues related to insufficient
+ // system entropy. See #189
+ if (node == null || clockseq == null) {
+ var seedBytes = rng();
+ if (node == null) {
+ // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
+ node = _nodeId = [
+ seedBytes[0] | 0x01,
+ seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]
+ ];
+ }
+ if (clockseq == null) {
+ // Per 4.2.2, randomize (14 bit) clockseq
+ clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
+ }
+ }
+
+ // UUID timestamps are 100 nano-second units since the Gregorian epoch,
+ // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
+ // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
+ // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
+ var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();
+
+ // Per 4.2.1.2, use count of uuid's generated during the current clock
+ // cycle to simulate higher resolution clock
+ var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;
+
+ // Time since last uuid creation (in msecs)
+ var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
+
+ // Per 4.2.1.2, Bump clockseq on clock regression
+ if (dt < 0 && options.clockseq === undefined) {
+ clockseq = clockseq + 1 & 0x3fff;
+ }
+
+ // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
+ // time interval
+ if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
+ nsecs = 0;
+ }
+
+ // Per 4.2.1.2 Throw error if too many uuids are requested
+ if (nsecs >= 10000) {
+ throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
+ }
+
+ _lastMSecs = msecs;
+ _lastNSecs = nsecs;
+ _clockseq = clockseq;
+
+ // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
+ msecs += 12219292800000;
+
+ // `time_low`
+ var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
+ b[i++] = tl >>> 24 & 0xff;
+ b[i++] = tl >>> 16 & 0xff;
+ b[i++] = tl >>> 8 & 0xff;
+ b[i++] = tl & 0xff;
+
+ // `time_mid`
+ var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
+ b[i++] = tmh >>> 8 & 0xff;
+ b[i++] = tmh & 0xff;
+
+ // `time_high_and_version`
+ b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
+ b[i++] = tmh >>> 16 & 0xff;
+
+ // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
+ b[i++] = clockseq >>> 8 | 0x80;
+
+ // `clock_seq_low`
+ b[i++] = clockseq & 0xff;
+
+ // `node`
+ for (var n = 0; n < 6; ++n) {
+ b[i + n] = node[n];
+ }
+
+ return buf ? buf : bytesToUuid(b);
+}
+
+module.exports = v1;
+
+},{"8":8,"9":9}],11:[function(_dereq_,module,exports){
+var rng = _dereq_(9);
+var bytesToUuid = _dereq_(8);
+
+function v4(options, buf, offset) {
+ var i = buf && offset || 0;
+
+ if (typeof(options) == 'string') {
+ buf = options === 'binary' ? new Array(16) : null;
+ options = null;
+ }
+ options = options || {};
+
+ var rnds = options.random || (options.rng || rng)();
+
+ // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
+ rnds[6] = (rnds[6] & 0x0f) | 0x40;
+ rnds[8] = (rnds[8] & 0x3f) | 0x80;
+
+ // Copy bytes to buffer, if provided
+ if (buf) {
+ for (var ii = 0; ii < 16; ++ii) {
+ buf[i + ii] = rnds[ii];
+ }
+ }
+
+ return buf || bytesToUuid(rnds);
+}
+
+module.exports = v4;
+
+},{"8":8,"9":9}],12:[function(_dereq_,module,exports){
+'use strict';
+
+/**
+ * Stringify/parse functions that don't operate
+ * recursively, so they avoid call stack exceeded
+ * errors.
+ */
+exports.stringify = function stringify(input) {
+ var queue = [];
+ queue.push({obj: input});
+
+ var res = '';
+ var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix;
+ while ((next = queue.pop())) {
+ obj = next.obj;
+ prefix = next.prefix || '';
+ val = next.val || '';
+ res += prefix;
+ if (val) {
+ res += val;
+ } else if (typeof obj !== 'object') {
+ res += typeof obj === 'undefined' ? null : JSON.stringify(obj);
+ } else if (obj === null) {
+ res += 'null';
+ } else if (Array.isArray(obj)) {
+ queue.push({val: ']'});
+ for (i = obj.length - 1; i >= 0; i--) {
+ arrayPrefix = i === 0 ? '' : ',';
+ queue.push({obj: obj[i], prefix: arrayPrefix});
+ }
+ queue.push({val: '['});
+ } else { // object
+ keys = [];
+ for (k in obj) {
+ if (obj.hasOwnProperty(k)) {
+ keys.push(k);
+ }
+ }
+ queue.push({val: '}'});
+ for (i = keys.length - 1; i >= 0; i--) {
+ key = keys[i];
+ value = obj[key];
+ objPrefix = (i > 0 ? ',' : '');
+ objPrefix += JSON.stringify(key) + ':';
+ queue.push({obj: value, prefix: objPrefix});
+ }
+ queue.push({val: '{'});
+ }
+ }
+ return res;
+};
+
+// Convenience function for the parse function.
+// This pop function is basically copied from
+// pouchCollate.parseIndexableString
+function pop(obj, stack, metaStack) {
+ var lastMetaElement = metaStack[metaStack.length - 1];
+ if (obj === lastMetaElement.element) {
+ // popping a meta-element, e.g. an object whose value is another object
+ metaStack.pop();
+ lastMetaElement = metaStack[metaStack.length - 1];
+ }
+ var element = lastMetaElement.element;
+ var lastElementIndex = lastMetaElement.index;
+ if (Array.isArray(element)) {
+ element.push(obj);
+ } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+ var key = stack.pop();
+ element[key] = obj;
+ } else {
+ stack.push(obj); // obj with key only
+ }
+}
+
+exports.parse = function (str) {
+ var stack = [];
+ var metaStack = []; // stack for arrays and objects
+ var i = 0;
+ var collationIndex,parsedNum,numChar;
+ var parsedString,lastCh,numConsecutiveSlashes,ch;
+ var arrayElement, objElement;
+ while (true) {
+ collationIndex = str[i++];
+ if (collationIndex === '}' ||
+ collationIndex === ']' ||
+ typeof collationIndex === 'undefined') {
+ if (stack.length === 1) {
+ return stack.pop();
+ } else {
+ pop(stack.pop(), stack, metaStack);
+ continue;
+ }
+ }
+ switch (collationIndex) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case ':':
+ case ',':
+ break;
+ case 'n':
+ i += 3; // 'ull'
+ pop(null, stack, metaStack);
+ break;
+ case 't':
+ i += 3; // 'rue'
+ pop(true, stack, metaStack);
+ break;
+ case 'f':
+ i += 4; // 'alse'
+ pop(false, stack, metaStack);
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ parsedNum = '';
+ i--;
+ while (true) {
+ numChar = str[i++];
+ if (/[\d\.\-e\+]/.test(numChar)) {
+ parsedNum += numChar;
+ } else {
+ i--;
+ break;
+ }
+ }
+ pop(parseFloat(parsedNum), stack, metaStack);
+ break;
+ case '"':
+ parsedString = '';
+ lastCh = void 0;
+ numConsecutiveSlashes = 0;
+ while (true) {
+ ch = str[i++];
+ if (ch !== '"' || (lastCh === '\\' &&
+ numConsecutiveSlashes % 2 === 1)) {
+ parsedString += ch;
+ lastCh = ch;
+ if (lastCh === '\\') {
+ numConsecutiveSlashes++;
+ } else {
+ numConsecutiveSlashes = 0;
+ }
+ } else {
+ break;
+ }
+ }
+ pop(JSON.parse('"' + parsedString + '"'), stack, metaStack);
+ break;
+ case '[':
+ arrayElement = { element: [], index: stack.length };
+ stack.push(arrayElement.element);
+ metaStack.push(arrayElement);
+ break;
+ case '{':
+ objElement = { element: {}, index: stack.length };
+ stack.push(objElement.element);
+ metaStack.push(objElement);
+ break;
+ default:
+ throw new Error(
+ 'unexpectedly reached end of input: ' + collationIndex);
+ }
+ }
+};
+
+},{}],13:[function(_dereq_,module,exports){
+(function (process,global){
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var immediate = _interopDefault(_dereq_(3));
+var uuidV4 = _interopDefault(_dereq_(7));
+var Md5 = _interopDefault(_dereq_(6));
+var vuvuzela = _interopDefault(_dereq_(12));
+var getArguments = _interopDefault(_dereq_(1));
+var inherits = _interopDefault(_dereq_(4));
+var events = _dereq_(2);
+
+function mangle(key) {
+ return '$' + key;
+}
+function unmangle(key) {
+ return key.substring(1);
+}
+function Map$1() {
+ this._store = {};
+}
+Map$1.prototype.get = function (key) {
+ var mangled = mangle(key);
+ return this._store[mangled];
+};
+Map$1.prototype.set = function (key, value) {
+ var mangled = mangle(key);
+ this._store[mangled] = value;
+ return true;
+};
+Map$1.prototype.has = function (key) {
+ var mangled = mangle(key);
+ return mangled in this._store;
+};
+Map$1.prototype["delete"] = function (key) {
+ var mangled = mangle(key);
+ var res = mangled in this._store;
+ delete this._store[mangled];
+ return res;
+};
+Map$1.prototype.forEach = function (cb) {
+ var keys = Object.keys(this._store);
+ for (var i = 0, len = keys.length; i < len; i++) {
+ var key = keys[i];
+ var value = this._store[key];
+ key = unmangle(key);
+ cb(value, key);
+ }
+};
+Object.defineProperty(Map$1.prototype, 'size', {
+ get: function () {
+ return Object.keys(this._store).length;
+ }
+});
+
+function Set$1(array) {
+ this._store = new Map$1();
+
+ // init with an array
+ if (array && Array.isArray(array)) {
+ for (var i = 0, len = array.length; i < len; i++) {
+ this.add(array[i]);
+ }
+ }
+}
+Set$1.prototype.add = function (key) {
+ return this._store.set(key, true);
+};
+Set$1.prototype.has = function (key) {
+ return this._store.has(key);
+};
+Set$1.prototype.forEach = function (cb) {
+ this._store.forEach(function (value, key) {
+ cb(key);
+ });
+};
+Object.defineProperty(Set$1.prototype, 'size', {
+ get: function () {
+ return this._store.size;
+ }
+});
+
+/* global Map,Set,Symbol */
+// Based on https://kangax.github.io/compat-table/es6/ we can sniff out
+// incomplete Map/Set implementations which would otherwise cause our tests to fail.
+// Notably they fail in IE11 and iOS 8.4, which this prevents.
+function supportsMapAndSet() {
+ if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') {
+ return false;
+ }
+ var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species);
+ return prop && 'get' in prop && Map[Symbol.species] === Map;
+}
+
+// based on https://github.com/montagejs/collections
+
+var ExportedSet;
+var ExportedMap;
+
+{
+ if (supportsMapAndSet()) { // prefer built-in Map/Set
+ ExportedSet = Set;
+ ExportedMap = Map;
+ } else { // fall back to our polyfill
+ ExportedSet = Set$1;
+ ExportedMap = Map$1;
+ }
+}
+
+function isBinaryObject(object) {
+ return (typeof ArrayBuffer !== 'undefined' && object instanceof ArrayBuffer) ||
+ (typeof Blob !== 'undefined' && object instanceof Blob);
+}
+
+function cloneArrayBuffer(buff) {
+ if (typeof buff.slice === 'function') {
+ return buff.slice(0);
+ }
+ // IE10-11 slice() polyfill
+ var target = new ArrayBuffer(buff.byteLength);
+ var targetArray = new Uint8Array(target);
+ var sourceArray = new Uint8Array(buff);
+ targetArray.set(sourceArray);
+ return target;
+}
+
+function cloneBinaryObject(object) {
+ if (object instanceof ArrayBuffer) {
+ return cloneArrayBuffer(object);
+ }
+ var size = object.size;
+ var type = object.type;
+ // Blob
+ if (typeof object.slice === 'function') {
+ return object.slice(0, size, type);
+ }
+ // PhantomJS slice() replacement
+ return object.webkitSlice(0, size, type);
+}
+
+// most of this is borrowed from lodash.isPlainObject:
+// https://github.com/fis-components/lodash.isplainobject/
+// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js
+
+var funcToString = Function.prototype.toString;
+var objectCtorString = funcToString.call(Object);
+
+function isPlainObject(value) {
+ var proto = Object.getPrototypeOf(value);
+ /* istanbul ignore if */
+ if (proto === null) { // not sure when this happens, but I guess it can
+ return true;
+ }
+ var Ctor = proto.constructor;
+ return (typeof Ctor == 'function' &&
+ Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
+}
+
+function clone(object) {
+ var newObject;
+ var i;
+ var len;
+
+ if (!object || typeof object !== 'object') {
+ return object;
+ }
+
+ if (Array.isArray(object)) {
+ newObject = [];
+ for (i = 0, len = object.length; i < len; i++) {
+ newObject[i] = clone(object[i]);
+ }
+ return newObject;
+ }
+
+ // special case: to avoid inconsistencies between IndexedDB
+ // and other backends, we automatically stringify Dates
+ if (object instanceof Date) {
+ return object.toISOString();
+ }
+
+ if (isBinaryObject(object)) {
+ return cloneBinaryObject(object);
+ }
+
+ if (!isPlainObject(object)) {
+ return object; // don't clone objects like Workers
+ }
+
+ newObject = {};
+ for (i in object) {
+ /* istanbul ignore else */
+ if (Object.prototype.hasOwnProperty.call(object, i)) {
+ var value = clone(object[i]);
+ if (typeof value !== 'undefined') {
+ newObject[i] = value;
+ }
+ }
+ }
+ return newObject;
+}
+
+function once(fun) {
+ var called = false;
+ return getArguments(function (args) {
+ /* istanbul ignore if */
+ if (called) {
+ // this is a smoke test and should never actually happen
+ throw new Error('once called more than once');
+ } else {
+ called = true;
+ fun.apply(this, args);
+ }
+ });
+}
+
+function toPromise(func) {
+ //create the function we will be returning
+ return getArguments(function (args) {
+ // Clone arguments
+ args = clone(args);
+ var self = this;
+ // if the last argument is a function, assume its a callback
+ var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false;
+ var promise = new Promise(function (fulfill, reject) {
+ var resp;
+ try {
+ var callback = once(function (err, mesg) {
+ if (err) {
+ reject(err);
+ } else {
+ fulfill(mesg);
+ }
+ });
+ // create a callback for this invocation
+ // apply the function in the orig context
+ args.push(callback);
+ resp = func.apply(self, args);
+ if (resp && typeof resp.then === 'function') {
+ fulfill(resp);
+ }
+ } catch (e) {
+ reject(e);
+ }
+ });
+ // if there is a callback, call it back
+ if (usedCB) {
+ promise.then(function (result) {
+ usedCB(null, result);
+ }, usedCB);
+ }
+ return promise;
+ });
+}
+
+function logApiCall(self, name, args) {
+ /* istanbul ignore if */
+ if (self.constructor.listeners('debug').length) {
+ var logArgs = ['api', self.name, name];
+ for (var i = 0; i < args.length - 1; i++) {
+ logArgs.push(args[i]);
+ }
+ self.constructor.emit('debug', logArgs);
+
+ // override the callback itself to log the response
+ var origCallback = args[args.length - 1];
+ args[args.length - 1] = function (err, res) {
+ var responseArgs = ['api', self.name, name];
+ responseArgs = responseArgs.concat(
+ err ? ['error', err] : ['success', res]
+ );
+ self.constructor.emit('debug', responseArgs);
+ origCallback(err, res);
+ };
+ }
+}
+
+function adapterFun(name, callback) {
+ return toPromise(getArguments(function (args) {
+ if (this._closed) {
+ return Promise.reject(new Error('database is closed'));
+ }
+ if (this._destroyed) {
+ return Promise.reject(new Error('database is destroyed'));
+ }
+ var self = this;
+ logApiCall(self, name, args);
+ if (!this.taskqueue.isReady) {
+ return new Promise(function (fulfill, reject) {
+ self.taskqueue.addTask(function (failed) {
+ if (failed) {
+ reject(failed);
+ } else {
+ fulfill(self[name].apply(self, args));
+ }
+ });
+ });
+ }
+ return callback.apply(this, args);
+ }));
+}
+
+// like underscore/lodash _.pick()
+function pick(obj, arr) {
+ var res = {};
+ for (var i = 0, len = arr.length; i < len; i++) {
+ var prop = arr[i];
+ if (prop in obj) {
+ res[prop] = obj[prop];
+ }
+ }
+ return res;
+}
+
+// Most browsers throttle concurrent requests at 6, so it's silly
+// to shim _bulk_get by trying to launch potentially hundreds of requests
+// and then letting the majority time out. We can handle this ourselves.
+var MAX_NUM_CONCURRENT_REQUESTS = 6;
+
+function identityFunction(x) {
+ return x;
+}
+
+function formatResultForOpenRevsGet(result) {
+ return [{
+ ok: result
+ }];
+}
+
+// shim for P/CouchDB adapters that don't directly implement _bulk_get
+function bulkGet(db, opts, callback) {
+ var requests = opts.docs;
+
+ // consolidate into one request per doc if possible
+ var requestsById = new ExportedMap();
+ requests.forEach(function (request) {
+ if (requestsById.has(request.id)) {
+ requestsById.get(request.id).push(request);
+ } else {
+ requestsById.set(request.id, [request]);
+ }
+ });
+
+ var numDocs = requestsById.size;
+ var numDone = 0;
+ var perDocResults = new Array(numDocs);
+
+ function collapseResultsAndFinish() {
+ var results = [];
+ perDocResults.forEach(function (res) {
+ res.docs.forEach(function (info) {
+ results.push({
+ id: res.id,
+ docs: [info]
+ });
+ });
+ });
+ callback(null, {results: results});
+ }
+
+ function checkDone() {
+ if (++numDone === numDocs) {
+ collapseResultsAndFinish();
+ }
+ }
+
+ function gotResult(docIndex, id, docs) {
+ perDocResults[docIndex] = {id: id, docs: docs};
+ checkDone();
+ }
+
+ var allRequests = [];
+ requestsById.forEach(function (value, key) {
+ allRequests.push(key);
+ });
+
+ var i = 0;
+
+ function nextBatch() {
+
+ if (i >= allRequests.length) {
+ return;
+ }
+
+ var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length);
+ var batch = allRequests.slice(i, upTo);
+ processBatch(batch, i);
+ i += batch.length;
+ }
+
+ function processBatch(batch, offset) {
+ batch.forEach(function (docId, j) {
+ var docIdx = offset + j;
+ var docRequests = requestsById.get(docId);
+
+ // just use the first request as the "template"
+ // TODO: The _bulk_get API allows for more subtle use cases than this,
+ // but for now it is unlikely that there will be a mix of different
+ // "atts_since" or "attachments" in the same request, since it's just
+ // replicate.js that is using this for the moment.
+ // Also, atts_since is aspirational, since we don't support it yet.
+ var docOpts = pick(docRequests[0], ['atts_since', 'attachments']);
+ docOpts.open_revs = docRequests.map(function (request) {
+ // rev is optional, open_revs disallowed
+ return request.rev;
+ });
+
+ // remove falsey / undefined revisions
+ docOpts.open_revs = docOpts.open_revs.filter(identityFunction);
+
+ var formatResult = identityFunction;
+
+ if (docOpts.open_revs.length === 0) {
+ delete docOpts.open_revs;
+
+ // when fetching only the "winning" leaf,
+ // transform the result so it looks like an open_revs
+ // request
+ formatResult = formatResultForOpenRevsGet;
+ }
+
+ // globally-supplied options
+ ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) {
+ if (param in opts) {
+ docOpts[param] = opts[param];
+ }
+ });
+ db.get(docId, docOpts, function (err, res) {
+ var result;
+ /* istanbul ignore if */
+ if (err) {
+ result = [{error: err}];
+ } else {
+ result = formatResult(res);
+ }
+ gotResult(docIdx, docId, result);
+ nextBatch();
+ });
+ });
+ }
+
+ nextBatch();
+
+}
+
+var hasLocal;
+
+try {
+ localStorage.setItem('_pouch_check_localstorage', 1);
+ hasLocal = !!localStorage.getItem('_pouch_check_localstorage');
+} catch (e) {
+ hasLocal = false;
+}
+
+function hasLocalStorage() {
+ return hasLocal;
+}
+
+// Custom nextTick() shim for browsers. In node, this will just be process.nextTick(). We
+
+inherits(Changes, events.EventEmitter);
+
+/* istanbul ignore next */
+function attachBrowserEvents(self) {
+ if (hasLocalStorage()) {
+ addEventListener("storage", function (e) {
+ self.emit(e.key);
+ });
+ }
+}
+
+function Changes() {
+ events.EventEmitter.call(this);
+ this._listeners = {};
+
+ attachBrowserEvents(this);
+}
+Changes.prototype.addListener = function (dbName, id, db, opts) {
+ /* istanbul ignore if */
+ if (this._listeners[id]) {
+ return;
+ }
+ var self = this;
+ var inprogress = false;
+ function eventFunction() {
+ /* istanbul ignore if */
+ if (!self._listeners[id]) {
+ return;
+ }
+ if (inprogress) {
+ inprogress = 'waiting';
+ return;
+ }
+ inprogress = true;
+ var changesOpts = pick(opts, [
+ 'style', 'include_docs', 'attachments', 'conflicts', 'filter',
+ 'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs'
+ ]);
+
+ /* istanbul ignore next */
+ function onError() {
+ inprogress = false;
+ }
+
+ db.changes(changesOpts).on('change', function (c) {
+ if (c.seq > opts.since && !opts.cancelled) {
+ opts.since = c.seq;
+ opts.onChange(c);
+ }
+ }).on('complete', function () {
+ if (inprogress === 'waiting') {
+ immediate(eventFunction);
+ }
+ inprogress = false;
+ }).on('error', onError);
+ }
+ this._listeners[id] = eventFunction;
+ this.on(dbName, eventFunction);
+};
+
+Changes.prototype.removeListener = function (dbName, id) {
+ /* istanbul ignore if */
+ if (!(id in this._listeners)) {
+ return;
+ }
+ events.EventEmitter.prototype.removeListener.call(this, dbName,
+ this._listeners[id]);
+ delete this._listeners[id];
+};
+
+
+/* istanbul ignore next */
+Changes.prototype.notifyLocalWindows = function (dbName) {
+ //do a useless change on a storage thing
+ //in order to get other windows's listeners to activate
+ if (hasLocalStorage()) {
+ localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
+ }
+};
+
+Changes.prototype.notify = function (dbName) {
+ this.emit(dbName);
+ this.notifyLocalWindows(dbName);
+};
+
+function guardedConsole(method) {
+ /* istanbul ignore else */
+ if (typeof console !== 'undefined' && typeof console[method] === 'function') {
+ var args = Array.prototype.slice.call(arguments, 1);
+ console[method].apply(console, args);
+ }
+}
+
+function randomNumber(min, max) {
+ var maxTimeout = 600000; // Hard-coded default of 10 minutes
+ min = parseInt(min, 10) || 0;
+ max = parseInt(max, 10);
+ if (max !== max || max <= min) {
+ max = (min || 1) << 1; //doubling
+ } else {
+ max = max + 1;
+ }
+ // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout
+ if (max > maxTimeout) {
+ min = maxTimeout >> 1; // divide by two
+ max = maxTimeout;
+ }
+ var ratio = Math.random();
+ var range = max - min;
+
+ return ~~(range * ratio + min); // ~~ coerces to an int, but fast.
+}
+
+function defaultBackOff(min) {
+ var max = 0;
+ if (!min) {
+ max = 2000;
+ }
+ return randomNumber(min, max);
+}
+
+// designed to give info to browser users, who are disturbed
+// when they see http errors in the console
+function explainError(status, str) {
+ guardedConsole('info', 'The above ' + status + ' is totally normal. ' + str);
+}
+
+var assign;
+{
+ if (typeof Object.assign === 'function') {
+ assign = Object.assign;
+ } else {
+ // lite Object.assign polyfill based on
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
+ assign = function (target) {
+ var to = Object(target);
+
+ for (var index = 1; index < arguments.length; index++) {
+ var nextSource = arguments[index];
+
+ if (nextSource != null) { // Skip over if undefined or null
+ for (var nextKey in nextSource) {
+ // Avoid bugs when hasOwnProperty is shadowed
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
+ to[nextKey] = nextSource[nextKey];
+ }
+ }
+ }
+ }
+ return to;
+ };
+ }
+}
+
+var $inject_Object_assign = assign;
+
+inherits(PouchError, Error);
+
+function PouchError(status, error, reason) {
+ Error.call(this, reason);
+ this.status = status;
+ this.name = error;
+ this.message = reason;
+ this.error = true;
+}
+
+PouchError.prototype.toString = function () {
+ return JSON.stringify({
+ status: this.status,
+ name: this.name,
+ message: this.message,
+ reason: this.reason
+ });
+};
+
+var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect.");
+var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'");
+var MISSING_DOC = new PouchError(404, 'not_found', 'missing');
+var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict');
+var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string');
+var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts');
+var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.');
+var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open');
+var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error');
+var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid');
+var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid');
+var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid');
+var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member');
+var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request');
+var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object');
+var DB_MISSING = new PouchError(404, 'not_found', 'Database not found');
+var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown');
+var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown');
+var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown');
+var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function');
+var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format');
+var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.');
+var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found');
+var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid');
+
+function createError(error, reason) {
+ function CustomPouchError(reason) {
+ // inherit error properties from our parent error manually
+ // so as to allow proper JSON parsing.
+ /* jshint ignore:start */
+ for (var p in error) {
+ if (typeof error[p] !== 'function') {
+ this[p] = error[p];
+ }
+ }
+ /* jshint ignore:end */
+ if (reason !== undefined) {
+ this.reason = reason;
+ }
+ }
+ CustomPouchError.prototype = PouchError.prototype;
+ return new CustomPouchError(reason);
+}
+
+function generateErrorFromResponse(err) {
+
+ if (typeof err !== 'object') {
+ var data = err;
+ err = UNKNOWN_ERROR;
+ err.data = data;
+ }
+
+ if ('error' in err && err.error === 'conflict') {
+ err.name = 'conflict';
+ err.status = 409;
+ }
+
+ if (!('name' in err)) {
+ err.name = err.error || 'unknown';
+ }
+
+ if (!('status' in err)) {
+ err.status = 500;
+ }
+
+ if (!('message' in err)) {
+ err.message = err.message || err.reason;
+ }
+
+ return err;
+}
+
+function tryFilter(filter, doc, req) {
+ try {
+ return !filter(doc, req);
+ } catch (err) {
+ var msg = 'Filter function threw: ' + err.toString();
+ return createError(BAD_REQUEST, msg);
+ }
+}
+
+function filterChange(opts) {
+ var req = {};
+ var hasFilter = opts.filter && typeof opts.filter === 'function';
+ req.query = opts.query_params;
+
+ return function filter(change) {
+ if (!change.doc) {
+ // CSG sends events on the changes feed that don't have documents,
+ // this hack makes a whole lot of existing code robust.
+ change.doc = {};
+ }
+
+ var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
+
+ if (typeof filterReturn === 'object') {
+ return filterReturn;
+ }
+
+ if (filterReturn) {
+ return false;
+ }
+
+ if (!opts.include_docs) {
+ delete change.doc;
+ } else if (!opts.attachments) {
+ for (var att in change.doc._attachments) {
+ /* istanbul ignore else */
+ if (change.doc._attachments.hasOwnProperty(att)) {
+ change.doc._attachments[att].stub = true;
+ }
+ }
+ }
+ return true;
+ };
+}
+
+function flatten(arrs) {
+ var res = [];
+ for (var i = 0, len = arrs.length; i < len; i++) {
+ res = res.concat(arrs[i]);
+ }
+ return res;
+}
+
+// shim for Function.prototype.name,
+
+// Determine id an ID is valid
+// - invalid IDs begin with an underescore that does not begin '_design' or
+// '_local'
+// - any other string value is a valid id
+// Returns the specific error object for each case
+function invalidIdError(id) {
+ var err;
+ if (!id) {
+ err = createError(MISSING_ID);
+ } else if (typeof id !== 'string') {
+ err = createError(INVALID_ID);
+ } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
+ err = createError(RESERVED_ID);
+ }
+ if (err) {
+ throw err;
+ }
+}
+
+// Checks if a PouchDB object is "remote" or not. This is
+
+function isRemote(db) {
+ if (typeof db._remote === 'boolean') {
+ return db._remote;
+ }
+ /* istanbul ignore next */
+ if (typeof db.type === 'function') {
+ guardedConsole('warn',
+ 'db.type() is deprecated and will be removed in ' +
+ 'a future version of PouchDB');
+ return db.type() === 'http';
+ }
+ /* istanbul ignore next */
+ return false;
+}
+
+function listenerCount(ee, type) {
+ return 'listenerCount' in ee ? ee.listenerCount(type) :
+ events.EventEmitter.listenerCount(ee, type);
+}
+
+function parseDesignDocFunctionName(s) {
+ if (!s) {
+ return null;
+ }
+ var parts = s.split('/');
+ if (parts.length === 2) {
+ return parts;
+ }
+ if (parts.length === 1) {
+ return [s, s];
+ }
+ return null;
+}
+
+function normalizeDesignDocFunctionName(s) {
+ var normalized = parseDesignDocFunctionName(s);
+ return normalized ? normalized.join('/') : null;
+}
+
+// originally parseUri 1.2.2, now patched by us
+// (c) Steven Levithan <stevenlevithan.com>
+// MIT License
+var keys = ["source", "protocol", "authority", "userInfo", "user", "password",
+ "host", "port", "relative", "path", "directory", "file", "query", "anchor"];
+var qName ="queryKey";
+var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g;
+
+// use the "loose" parser
+/* eslint maxlen: 0, no-useless-escape: 0 */
+var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
+
+function parseUri(str) {
+ var m = parser.exec(str);
+ var uri = {};
+ var i = 14;
+
+ while (i--) {
+ var key = keys[i];
+ var value = m[i] || "";
+ var encoded = ['user', 'password'].indexOf(key) !== -1;
+ uri[key] = encoded ? decodeURIComponent(value) : value;
+ }
+
+ uri[qName] = {};
+ uri[keys[12]].replace(qParser, function ($0, $1, $2) {
+ if ($1) {
+ uri[qName][$1] = $2;
+ }
+ });
+
+ return uri;
+}
+
+// Based on https://github.com/alexdavid/scope-eval v0.0.3
+// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js)
+// This is basically just a wrapper around new Function()
+
+function scopeEval(source, scope) {
+ var keys = [];
+ var values = [];
+ for (var key in scope) {
+ if (scope.hasOwnProperty(key)) {
+ keys.push(key);
+ values.push(scope[key]);
+ }
+ }
+ keys.push(source);
+ return Function.apply(null, keys).apply(null, values);
+}
+
+// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
+// the diffFun tells us what delta to apply to the doc. it either returns
+// the doc, or false if it doesn't need to do an update after all
+function upsert(db, docId, diffFun) {
+ return new Promise(function (fulfill, reject) {
+ db.get(docId, function (err, doc) {
+ if (err) {
+ /* istanbul ignore next */
+ if (err.status !== 404) {
+ return reject(err);
+ }
+ doc = {};
+ }
+
+ // the user might change the _rev, so save it for posterity
+ var docRev = doc._rev;
+ var newDoc = diffFun(doc);
+
+ if (!newDoc) {
+ // if the diffFun returns falsy, we short-circuit as
+ // an optimization
+ return fulfill({updated: false, rev: docRev});
+ }
+
+ // users aren't allowed to modify these values,
+ // so reset them here
+ newDoc._id = docId;
+ newDoc._rev = docRev;
+ fulfill(tryAndPut(db, newDoc, diffFun));
+ });
+ });
+}
+
+function tryAndPut(db, doc, diffFun) {
+ return db.put(doc).then(function (res) {
+ return {
+ updated: true,
+ rev: res.rev
+ };
+ }, function (err) {
+ /* istanbul ignore next */
+ if (err.status !== 409) {
+ throw err;
+ }
+ return upsert(db, doc._id, diffFun);
+ });
+}
+
+var thisAtob = function (str) {
+ return atob(str);
+};
+
+var thisBtoa = function (str) {
+ return btoa(str);
+};
+
+// Abstracts constructing a Blob object, so it also works in older
+// browsers that don't support the native Blob constructor (e.g.
+// old QtWebKit versions, Android < 4.4).
+function createBlob(parts, properties) {
+ /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
+ parts = parts || [];
+ properties = properties || {};
+ try {
+ return new Blob(parts, properties);
+ } catch (e) {
+ if (e.name !== "TypeError") {
+ throw e;
+ }
+ var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
+ typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
+ typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
+ WebKitBlobBuilder;
+ var builder = new Builder();
+ for (var i = 0; i < parts.length; i += 1) {
+ builder.append(parts[i]);
+ }
+ return builder.getBlob(properties.type);
+ }
+}
+
+// From http://stackoverflow.com/questions/14967647/ (continues on next line)
+// encode-decode-image-with-base64-breaks-image (2013-04-21)
+function binaryStringToArrayBuffer(bin) {
+ var length = bin.length;
+ var buf = new ArrayBuffer(length);
+ var arr = new Uint8Array(buf);
+ for (var i = 0; i < length; i++) {
+ arr[i] = bin.charCodeAt(i);
+ }
+ return buf;
+}
+
+function binStringToBluffer(binString, type) {
+ return createBlob([binaryStringToArrayBuffer(binString)], {type: type});
+}
+
+function b64ToBluffer(b64, type) {
+ return binStringToBluffer(thisAtob(b64), type);
+}
+
+//Can't find original post, but this is close
+//http://stackoverflow.com/questions/6965107/ (continues on next line)
+//converting-between-strings-and-arraybuffers
+function arrayBufferToBinaryString(buffer) {
+ var binary = '';
+ var bytes = new Uint8Array(buffer);
+ var length = bytes.byteLength;
+ for (var i = 0; i < length; i++) {
+ binary += String.fromCharCode(bytes[i]);
+ }
+ return binary;
+}
+
+// shim for browsers that don't support it
+function readAsBinaryString(blob, callback) {
+ var reader = new FileReader();
+ var hasBinaryString = typeof reader.readAsBinaryString === 'function';
+ reader.onloadend = function (e) {
+ var result = e.target.result || '';
+ if (hasBinaryString) {
+ return callback(result);
+ }
+ callback(arrayBufferToBinaryString(result));
+ };
+ if (hasBinaryString) {
+ reader.readAsBinaryString(blob);
+ } else {
+ reader.readAsArrayBuffer(blob);
+ }
+}
+
+function blobToBinaryString(blobOrBuffer, callback) {
+ readAsBinaryString(blobOrBuffer, function (bin) {
+ callback(bin);
+ });
+}
+
+function blobToBase64(blobOrBuffer, callback) {
+ blobToBinaryString(blobOrBuffer, function (base64) {
+ callback(thisBtoa(base64));
+ });
+}
+
+// simplified API. universal browser support is assumed
+function readAsArrayBuffer(blob, callback) {
+ var reader = new FileReader();
+ reader.onloadend = function (e) {
+ var result = e.target.result || new ArrayBuffer(0);
+ callback(result);
+ };
+ reader.readAsArrayBuffer(blob);
+}
+
+// this is not used in the browser
+
+var setImmediateShim = global.setImmediate || global.setTimeout;
+var MD5_CHUNK_SIZE = 32768;
+
+function rawToBase64(raw) {
+ return thisBtoa(raw);
+}
+
+function sliceBlob(blob, start, end) {
+ if (blob.webkitSlice) {
+ return blob.webkitSlice(start, end);
+ }
+ return blob.slice(start, end);
+}
+
+function appendBlob(buffer, blob, start, end, callback) {
+ if (start > 0 || end < blob.size) {
+ // only slice blob if we really need to
+ blob = sliceBlob(blob, start, end);
+ }
+ readAsArrayBuffer(blob, function (arrayBuffer) {
+ buffer.append(arrayBuffer);
+ callback();
+ });
+}
+
+function appendString(buffer, string, start, end, callback) {
+ if (start > 0 || end < string.length) {
+ // only create a substring if we really need to
+ string = string.substring(start, end);
+ }
+ buffer.appendBinary(string);
+ callback();
+}
+
+function binaryMd5(data, callback) {
+ var inputIsString = typeof data === 'string';
+ var len = inputIsString ? data.length : data.size;
+ var chunkSize = Math.min(MD5_CHUNK_SIZE, len);
+ var chunks = Math.ceil(len / chunkSize);
+ var currentChunk = 0;
+ var buffer = inputIsString ? new Md5() : new Md5.ArrayBuffer();
+
+ var append = inputIsString ? appendString : appendBlob;
+
+ function next() {
+ setImmediateShim(loadNextChunk);
+ }
+
+ function done() {
+ var raw = buffer.end(true);
+ var base64 = rawToBase64(raw);
+ callback(base64);
+ buffer.destroy();
+ }
+
+ function loadNextChunk() {
+ var start = currentChunk * chunkSize;
+ var end = start + chunkSize;
+ currentChunk++;
+ if (currentChunk < chunks) {
+ append(buffer, data, start, end, next);
+ } else {
+ append(buffer, data, start, end, done);
+ }
+ }
+ loadNextChunk();
+}
+
+function stringMd5(string) {
+ return Md5.hash(string);
+}
+
+function rev(doc, deterministic_revs) {
+ var clonedDoc = clone(doc);
+ if (!deterministic_revs) {
+ return uuidV4.v4().replace(/-/g, '').toLowerCase();
+ }
+
+ delete clonedDoc._rev_tree;
+ return stringMd5(JSON.stringify(clonedDoc));
+}
+
+var uuid = uuidV4.v4;
+
+// We fetch all leafs of the revision tree, and sort them based on tree length
+// and whether they were deleted, undeleted documents with the longest revision
+// tree (most edits) win
+// The final sort algorithm is slightly documented in a sidebar here:
+// http://guide.couchdb.org/draft/conflicts.html
+function winningRev(metadata) {
+ var winningId;
+ var winningPos;
+ var winningDeleted;
+ var toVisit = metadata.rev_tree.slice();
+ var node;
+ while ((node = toVisit.pop())) {
+ var tree = node.ids;
+ var branches = tree[2];
+ var pos = node.pos;
+ if (branches.length) { // non-leaf
+ for (var i = 0, len = branches.length; i < len; i++) {
+ toVisit.push({pos: pos + 1, ids: branches[i]});
+ }
+ continue;
+ }
+ var deleted = !!tree[1].deleted;
+ var id = tree[0];
+ // sort by deleted, then pos, then id
+ if (!winningId || (winningDeleted !== deleted ? winningDeleted :
+ winningPos !== pos ? winningPos < pos : winningId < id)) {
+ winningId = id;
+ winningPos = pos;
+ winningDeleted = deleted;
+ }
+ }
+
+ return winningPos + '-' + winningId;
+}
+
+// Pretty much all below can be combined into a higher order function to
+// traverse revisions
+// The return value from the callback will be passed as context to all
+// children of that node
+function traverseRevTree(revs, callback) {
+ var toVisit = revs.slice();
+
+ var node;
+ while ((node = toVisit.pop())) {
+ var pos = node.pos;
+ var tree = node.ids;
+ var branches = tree[2];
+ var newCtx =
+ callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
+ for (var i = 0, len = branches.length; i < len; i++) {
+ toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
+ }
+ }
+}
+
+function sortByPos(a, b) {
+ return a.pos - b.pos;
+}
+
+function collectLeaves(revs) {
+ var leaves = [];
+ traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
+ if (isLeaf) {
+ leaves.push({rev: pos + "-" + id, pos: pos, opts: opts});
+ }
+ });
+ leaves.sort(sortByPos).reverse();
+ for (var i = 0, len = leaves.length; i < len; i++) {
+ delete leaves[i].pos;
+ }
+ return leaves;
+}
+
+// returns revs of all conflicts that is leaves such that
+// 1. are not deleted and
+// 2. are different than winning revision
+function collectConflicts(metadata) {
+ var win = winningRev(metadata);
+ var leaves = collectLeaves(metadata.rev_tree);
+ var conflicts = [];
+ for (var i = 0, len = leaves.length; i < len; i++) {
+ var leaf = leaves[i];
+ if (leaf.rev !== win && !leaf.opts.deleted) {
+ conflicts.push(leaf.rev);
+ }
+ }
+ return conflicts;
+}
+
+// compact a tree by marking its non-leafs as missing,
+// and return a list of revs to delete
+function compactTree(metadata) {
+ var revs = [];
+ traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+ revHash, ctx, opts) {
+ if (opts.status === 'available' && !isLeaf) {
+ revs.push(pos + '-' + revHash);
+ opts.status = 'missing';
+ }
+ });
+ return revs;
+}
+
+// build up a list of all the paths to the leafs in this revision tree
+function rootToLeaf(revs) {
+ var paths = [];
+ var toVisit = revs.slice();
+ var node;
+ while ((node = toVisit.pop())) {
+ var pos = node.pos;
+ var tree = node.ids;
+ var id = tree[0];
+ var opts = tree[1];
+ var branches = tree[2];
+ var isLeaf = branches.length === 0;
+
+ var history = node.history ? node.history.slice() : [];
+ history.push({id: id, opts: opts});
+ if (isLeaf) {
+ paths.push({pos: (pos + 1 - history.length), ids: history});
+ }
+ for (var i = 0, len = branches.length; i < len; i++) {
+ toVisit.push({pos: pos + 1, ids: branches[i], history: history});
+ }
+ }
+ return paths.reverse();
+}
+
+// for a better overview of what this is doing, read:
+
+function sortByPos$1(a, b) {
+ return a.pos - b.pos;
+}
+
+// classic binary search
+function binarySearch(arr, item, comparator) {
+ var low = 0;
+ var high = arr.length;
+ var mid;
+ while (low < high) {
+ mid = (low + high) >>> 1;
+ if (comparator(arr[mid], item) < 0) {
+ low = mid + 1;
+ } else {
+ high = mid;
+ }
+ }
+ return low;
+}
+
+// assuming the arr is sorted, insert the item in the proper place
+function insertSorted(arr, item, comparator) {
+ var idx = binarySearch(arr, item, comparator);
+ arr.splice(idx, 0, item);
+}
+
+// Turn a path as a flat array into a tree with a single branch.
+// If any should be stemmed from the beginning of the array, that's passed
+// in as the second argument
+function pathToTree(path, numStemmed) {
+ var root;
+ var leaf;
+ for (var i = numStemmed, len = path.length; i < len; i++) {
+ var node = path[i];
+ var currentLeaf = [node.id, node.opts, []];
+ if (leaf) {
+ leaf[2].push(currentLeaf);
+ leaf = currentLeaf;
+ } else {
+ root = leaf = currentLeaf;
+ }
+ }
+ return root;
+}
+
+// compare the IDs of two trees
+function compareTree(a, b) {
+ return a[0] < b[0] ? -1 : 1;
+}
+
+// Merge two trees together
+// The roots of tree1 and tree2 must be the same revision
+function mergeTree(in_tree1, in_tree2) {
+ var queue = [{tree1: in_tree1, tree2: in_tree2}];
+ var conflicts = false;
+ while (queue.length > 0) {
+ var item = queue.pop();
+ var tree1 = item.tree1;
+ var tree2 = item.tree2;
+
+ if (tree1[1].status || tree2[1].status) {
+ tree1[1].status =
+ (tree1[1].status === 'available' ||
+ tree2[1].status === 'available') ? 'available' : 'missing';
+ }
+
+ for (var i = 0; i < tree2[2].length; i++) {
+ if (!tree1[2][0]) {
+ conflicts = 'new_leaf';
+ tree1[2][0] = tree2[2][i];
+ continue;
+ }
+
+ var merged = false;
+ for (var j = 0; j < tree1[2].length; j++) {
+ if (tree1[2][j][0] === tree2[2][i][0]) {
+ queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
+ merged = true;
+ }
+ }
+ if (!merged) {
+ conflicts = 'new_branch';
+ insertSorted(tree1[2], tree2[2][i], compareTree);
+ }
+ }
+ }
+ return {conflicts: conflicts, tree: in_tree1};
+}
+
+function doMerge(tree, path, dontExpand) {
+ var restree = [];
+ var conflicts = false;
+ var merged = false;
+ var res;
+
+ if (!tree.length) {
+ return {tree: [path], conflicts: 'new_leaf'};
+ }
+
+ for (var i = 0, len = tree.length; i < len; i++) {
+ var branch = tree[i];
+ if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
+ // Paths start at the same position and have the same root, so they need
+ // merged
+ res = mergeTree(branch.ids, path.ids);
+ restree.push({pos: branch.pos, ids: res.tree});
+ conflicts = conflicts || res.conflicts;
+ merged = true;
+ } else if (dontExpand !== true) {
+ // The paths start at a different position, take the earliest path and
+ // traverse up until it as at the same point from root as the path we
+ // want to merge. If the keys match we return the longer path with the
+ // other merged After stemming we dont want to expand the trees
+
+ var t1 = branch.pos < path.pos ? branch : path;
+ var t2 = branch.pos < path.pos ? path : branch;
+ var diff = t2.pos - t1.pos;
+
+ var candidateParents = [];
+
+ var trees = [];
+ trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
+ while (trees.length > 0) {
+ var item = trees.pop();
+ if (item.diff === 0) {
+ if (item.ids[0] === t2.ids[0]) {
+ candidateParents.push(item);
+ }
+ continue;
+ }
+ var elements = item.ids[2];
+ for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) {
+ trees.push({
+ ids: elements[j],
+ diff: item.diff - 1,
+ parent: item.ids,
+ parentIdx: j
+ });
+ }
+ }
+
+ var el = candidateParents[0];
+
+ if (!el) {
+ restree.push(branch);
+ } else {
+ res = mergeTree(el.ids, t2.ids);
+ el.parent[2][el.parentIdx] = res.tree;
+ restree.push({pos: t1.pos, ids: t1.ids});
+ conflicts = conflicts || res.conflicts;
+ merged = true;
+ }
+ } else {
+ restree.push(branch);
+ }
+ }
+
+ // We didnt find
+ if (!merged) {
+ restree.push(path);
+ }
+
+ restree.sort(sortByPos$1);
+
+ return {
+ tree: restree,
+ conflicts: conflicts || 'internal_node'
+ };
+}
+
+// To ensure we dont grow the revision tree infinitely, we stem old revisions
+function stem(tree, depth) {
+ // First we break out the tree into a complete list of root to leaf paths
+ var paths = rootToLeaf(tree);
+ var stemmedRevs;
+
+ var result;
+ for (var i = 0, len = paths.length; i < len; i++) {
+ // Then for each path, we cut off the start of the path based on the
+ // `depth` to stem to, and generate a new set of flat trees
+ var path = paths[i];
+ var stemmed = path.ids;
+ var node;
+ if (stemmed.length > depth) {
+ // only do the stemming work if we actually need to stem
+ if (!stemmedRevs) {
+ stemmedRevs = {}; // avoid allocating this object unnecessarily
+ }
+ var numStemmed = stemmed.length - depth;
+ node = {
+ pos: path.pos + numStemmed,
+ ids: pathToTree(stemmed, numStemmed)
+ };
+
+ for (var s = 0; s < numStemmed; s++) {
+ var rev = (path.pos + s) + '-' + stemmed[s].id;
+ stemmedRevs[rev] = true;
+ }
+ } else { // no need to actually stem
+ node = {
+ pos: path.pos,
+ ids: pathToTree(stemmed, 0)
+ };
+ }
+
+ // Then we remerge all those flat trees together, ensuring that we dont
+ // connect trees that would go beyond the depth limit
+ if (result) {
+ result = doMerge(result, node, true).tree;
+ } else {
+ result = [node];
+ }
+ }
+
+ // this is memory-heavy per Chrome profiler, avoid unless we actually stemmed
+ if (stemmedRevs) {
+ traverseRevTree(result, function (isLeaf, pos, revHash) {
+ // some revisions may have been removed in a branch but not in another
+ delete stemmedRevs[pos + '-' + revHash];
+ });
+ }
+
+ return {
+ tree: result,
+ revs: stemmedRevs ? Object.keys(stemmedRevs) : []
+ };
+}
+
+function merge(tree, path, depth) {
+ var newTree = doMerge(tree, path);
+ var stemmed = stem(newTree.tree, depth);
+ return {
+ tree: stemmed.tree,
+ stemmedRevs: stemmed.revs,
+ conflicts: newTree.conflicts
+ };
+}
+
+// return true if a rev exists in the rev tree, false otherwise
+function revExists(revs, rev) {
+ var toVisit = revs.slice();
+ var splitRev = rev.split('-');
+ var targetPos = parseInt(splitRev[0], 10);
+ var targetId = splitRev[1];
+
+ var node;
+ while ((node = toVisit.pop())) {
+ if (node.pos === targetPos && node.ids[0] === targetId) {
+ return true;
+ }
+ var branches = node.ids[2];
+ for (var i = 0, len = branches.length; i < len; i++) {
+ toVisit.push({pos: node.pos + 1, ids: branches[i]});
+ }
+ }
+ return false;
+}
+
+function getTrees(node) {
+ return node.ids;
+}
+
+// check if a specific revision of a doc has been deleted
+// - metadata: the metadata object from the doc store
+// - rev: (optional) the revision to check. defaults to winning revision
+function isDeleted(metadata, rev) {
+ if (!rev) {
+ rev = winningRev(metadata);
+ }
+ var id = rev.substring(rev.indexOf('-') + 1);
+ var toVisit = metadata.rev_tree.map(getTrees);
+
+ var tree;
+ while ((tree = toVisit.pop())) {
+ if (tree[0] === id) {
+ return !!tree[1].deleted;
+ }
+ toVisit = toVisit.concat(tree[2]);
+ }
+}
+
+function isLocalId(id) {
+ return (/^_local/).test(id);
+}
+
+// returns the current leaf node for a given revision
+function latest(rev, metadata) {
+ var toVisit = metadata.rev_tree.slice();
+ var node;
+ while ((node = toVisit.pop())) {
+ var pos = node.pos;
+ var tree = node.ids;
+ var id = tree[0];
+ var opts = tree[1];
+ var branches = tree[2];
+ var isLeaf = branches.length === 0;
+
+ var history = node.history ? node.history.slice() : [];
+ history.push({id: id, pos: pos, opts: opts});
+
+ if (isLeaf) {
+ for (var i = 0, len = history.length; i < len; i++) {
+ var historyNode = history[i];
+ var historyRev = historyNode.pos + '-' + historyNode.id;
+
+ if (historyRev === rev) {
+ // return the rev of this leaf
+ return pos + '-' + id;
+ }
+ }
+ }
+
+ for (var j = 0, l = branches.length; j < l; j++) {
+ toVisit.push({pos: pos + 1, ids: branches[j], history: history});
+ }
+ }
+
+ /* istanbul ignore next */
+ throw new Error('Unable to resolve latest revision for id ' + metadata.id + ', rev ' + rev);
+}
+
+inherits(Changes$1, events.EventEmitter);
+
+function tryCatchInChangeListener(self, change, pending, lastSeq) {
+ // isolate try/catches to avoid V8 deoptimizations
+ try {
+ self.emit('change', change, pending, lastSeq);
+ } catch (e) {
+ guardedConsole('error', 'Error in .on("change", function):', e);
+ }
+}
+
+function Changes$1(db, opts, callback) {
+ events.EventEmitter.call(this);
+ var self = this;
+ this.db = db;
+ opts = opts ? clone(opts) : {};
+ var complete = opts.complete = once(function (err, resp) {
+ if (err) {
+ if (listenerCount(self, 'error') > 0) {
+ self.emit('error', err);
+ }
+ } else {
+ self.emit('complete', resp);
+ }
+ self.removeAllListeners();
+ db.removeListener('destroyed', onDestroy);
+ });
+ if (callback) {
+ self.on('complete', function (resp) {
+ callback(null, resp);
+ });
+ self.on('error', callback);
+ }
+ function onDestroy() {
+ self.cancel();
+ }
+ db.once('destroyed', onDestroy);
+
+ opts.onChange = function (change, pending, lastSeq) {
+ /* istanbul ignore if */
+ if (self.isCancelled) {
+ return;
+ }
+ tryCatchInChangeListener(self, change, pending, lastSeq);
+ };
+
+ var promise = new Promise(function (fulfill, reject) {
+ opts.complete = function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ fulfill(res);
+ }
+ };
+ });
+ self.once('cancel', function () {
+ db.removeListener('destroyed', onDestroy);
+ opts.complete(null, {status: 'cancelled'});
+ });
+ this.then = promise.then.bind(promise);
+ this['catch'] = promise['catch'].bind(promise);
+ this.then(function (result) {
+ complete(null, result);
+ }, complete);
+
+
+
+ if (!db.taskqueue.isReady) {
+ db.taskqueue.addTask(function (failed) {
+ if (failed) {
+ opts.complete(failed);
+ } else if (self.isCancelled) {
+ self.emit('cancel');
+ } else {
+ self.validateChanges(opts);
+ }
+ });
+ } else {
+ self.validateChanges(opts);
+ }
+}
+Changes$1.prototype.cancel = function () {
+ this.isCancelled = true;
+ if (this.db.taskqueue.isReady) {
+ this.emit('cancel');
+ }
+};
+function processChange(doc, metadata, opts) {
+ var changeList = [{rev: doc._rev}];
+ if (opts.style === 'all_docs') {
+ changeList = collectLeaves(metadata.rev_tree)
+ .map(function (x) { return {rev: x.rev}; });
+ }
+ var change = {
+ id: metadata.id,
+ changes: changeList,
+ doc: doc
+ };
+
+ if (isDeleted(metadata, doc._rev)) {
+ change.deleted = true;
+ }
+ if (opts.conflicts) {
+ change.doc._conflicts = collectConflicts(metadata);
+ if (!change.doc._conflicts.length) {
+ delete change.doc._conflicts;
+ }
+ }
+ return change;
+}
+
+Changes$1.prototype.validateChanges = function (opts) {
+ var callback = opts.complete;
+ var self = this;
+
+ /* istanbul ignore else */
+ if (PouchDB._changesFilterPlugin) {
+ PouchDB._changesFilterPlugin.validate(opts, function (err) {
+ if (err) {
+ return callback(err);
+ }
+ self.doChanges(opts);
+ });
+ } else {
+ self.doChanges(opts);
+ }
+};
+
+Changes$1.prototype.doChanges = function (opts) {
+ var self = this;
+ var callback = opts.complete;
+
+ opts = clone(opts);
+ if ('live' in opts && !('continuous' in opts)) {
+ opts.continuous = opts.live;
+ }
+ opts.processChange = processChange;
+
+ if (opts.since === 'latest') {
+ opts.since = 'now';
+ }
+ if (!opts.since) {
+ opts.since = 0;
+ }
+ if (opts.since === 'now') {
+ this.db.info().then(function (info) {
+ /* istanbul ignore if */
+ if (self.isCancelled) {
+ callback(null, {status: 'cancelled'});
+ return;
+ }
+ opts.since = info.update_seq;
+ self.doChanges(opts);
+ }, callback);
+ return;
+ }
+
+ /* istanbul ignore else */
+ if (PouchDB._changesFilterPlugin) {
+ PouchDB._changesFilterPlugin.normalize(opts);
+ if (PouchDB._changesFilterPlugin.shouldFilter(this, opts)) {
+ return PouchDB._changesFilterPlugin.filter(this, opts);
+ }
+ } else {
+ ['doc_ids', 'filter', 'selector', 'view'].forEach(function (key) {
+ if (key in opts) {
+ guardedConsole('warn',
+ 'The "' + key + '" option was passed in to changes/replicate, ' +
+ 'but pouchdb-changes-filter plugin is not installed, so it ' +
+ 'was ignored. Please install the plugin to enable filtering.'
+ );
+ }
+ });
+ }
+
+ if (!('descending' in opts)) {
+ opts.descending = false;
+ }
+
+ // 0 and 1 should return 1 document
+ opts.limit = opts.limit === 0 ? 1 : opts.limit;
+ opts.complete = callback;
+ var newPromise = this.db._changes(opts);
+ /* istanbul ignore else */
+ if (newPromise && typeof newPromise.cancel === 'function') {
+ var cancel = self.cancel;
+ self.cancel = getArguments(function (args) {
+ newPromise.cancel();
+ cancel.apply(this, args);
+ });
+ }
+};
+
+/*
+ * A generic pouch adapter
+ */
+
+function compare(left, right) {
+ return left < right ? -1 : left > right ? 1 : 0;
+}
+
+// Wrapper for functions that call the bulkdocs api with a single doc,
+// if the first result is an error, return an error
+function yankError(callback, docId) {
+ return function (err, results) {
+ if (err || (results[0] && results[0].error)) {
+ err = err || results[0];
+ err.docId = docId;
+ callback(err);
+ } else {
+ callback(null, results.length ? results[0] : results);
+ }
+ };
+}
+
+// clean docs given to us by the user
+function cleanDocs(docs) {
+ for (var i = 0; i < docs.length; i++) {
+ var doc = docs[i];
+ if (doc._deleted) {
+ delete doc._attachments; // ignore atts for deleted docs
+ } else if (doc._attachments) {
+ // filter out extraneous keys from _attachments
+ var atts = Object.keys(doc._attachments);
+ for (var j = 0; j < atts.length; j++) {
+ var att = atts[j];
+ doc._attachments[att] = pick(doc._attachments[att],
+ ['data', 'digest', 'content_type', 'length', 'revpos', 'stub']);
+ }
+ }
+ }
+}
+
+// compare two docs, first by _id then by _rev
+function compareByIdThenRev(a, b) {
+ var idCompare = compare(a._id, b._id);
+ if (idCompare !== 0) {
+ return idCompare;
+ }
+ var aStart = a._revisions ? a._revisions.start : 0;
+ var bStart = b._revisions ? b._revisions.start : 0;
+ return compare(aStart, bStart);
+}
+
+// for every node in a revision tree computes its distance from the closest
+// leaf
+function computeHeight(revs) {
+ var height = {};
+ var edges = [];
+ traverseRevTree(revs, function (isLeaf, pos, id, prnt) {
+ var rev$$1 = pos + "-" + id;
+ if (isLeaf) {
+ height[rev$$1] = 0;
+ }
+ if (prnt !== undefined) {
+ edges.push({from: prnt, to: rev$$1});
+ }
+ return rev$$1;
+ });
+
+ edges.reverse();
+ edges.forEach(function (edge) {
+ if (height[edge.from] === undefined) {
+ height[edge.from] = 1 + height[edge.to];
+ } else {
+ height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]);
+ }
+ });
+ return height;
+}
+
+function allDocsKeysParse(opts) {
+ var keys = ('limit' in opts) ?
+ opts.keys.slice(opts.skip, opts.limit + opts.skip) :
+ (opts.skip > 0) ? opts.keys.slice(opts.skip) : opts.keys;
+ opts.keys = keys;
+ opts.skip = 0;
+ delete opts.limit;
+ if (opts.descending) {
+ keys.reverse();
+ opts.descending = false;
+ }
+}
+
+// all compaction is done in a queue, to avoid attaching
+// too many listeners at once
+function doNextCompaction(self) {
+ var task = self._compactionQueue[0];
+ var opts = task.opts;
+ var callback = task.callback;
+ self.get('_local/compaction')["catch"](function () {
+ return false;
+ }).then(function (doc) {
+ if (doc && doc.last_seq) {
+ opts.last_seq = doc.last_seq;
+ }
+ self._compact(opts, function (err, res) {
+ /* istanbul ignore if */
+ if (err) {
+ callback(err);
+ } else {
+ callback(null, res);
+ }
+ immediate(function () {
+ self._compactionQueue.shift();
+ if (self._compactionQueue.length) {
+ doNextCompaction(self);
+ }
+ });
+ });
+ });
+}
+
+function attachmentNameError(name) {
+ if (name.charAt(0) === '_') {
+ return name + ' is not a valid attachment name, attachment ' +
+ 'names cannot start with \'_\'';
+ }
+ return false;
+}
+
+inherits(AbstractPouchDB, events.EventEmitter);
+
+function AbstractPouchDB() {
+ events.EventEmitter.call(this);
+
+ // re-bind prototyped methods
+ for (var p in AbstractPouchDB.prototype) {
+ if (typeof this[p] === 'function') {
+ this[p] = this[p].bind(this);
+ }
+ }
+}
+
+AbstractPouchDB.prototype.post =
+ adapterFun('post', function (doc, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ if (typeof doc !== 'object' || Array.isArray(doc)) {
+ return callback(createError(NOT_AN_OBJECT));
+ }
+ this.bulkDocs({docs: [doc]}, opts, yankError(callback, doc._id));
+});
+
+AbstractPouchDB.prototype.put = adapterFun('put', function (doc, opts, cb) {
+ if (typeof opts === 'function') {
+ cb = opts;
+ opts = {};
+ }
+ if (typeof doc !== 'object' || Array.isArray(doc)) {
+ return cb(createError(NOT_AN_OBJECT));
+ }
+ invalidIdError(doc._id);
+ if (isLocalId(doc._id) && typeof this._putLocal === 'function') {
+ if (doc._deleted) {
+ return this._removeLocal(doc, cb);
+ } else {
+ return this._putLocal(doc, cb);
+ }
+ }
+ var self = this;
+ if (opts.force && doc._rev) {
+ transformForceOptionToNewEditsOption();
+ putDoc(function (err) {
+ var result = err ? null : {ok: true, id: doc._id, rev: doc._rev};
+ cb(err, result);
+ });
+ } else {
+ putDoc(cb);
+ }
+
+ function transformForceOptionToNewEditsOption() {
+ var parts = doc._rev.split('-');
+ var oldRevId = parts[1];
+ var oldRevNum = parseInt(parts[0], 10);
+
+ var newRevNum = oldRevNum + 1;
+ var newRevId = rev();
+
+ doc._revisions = {
+ start: newRevNum,
+ ids: [newRevId, oldRevId]
+ };
+ doc._rev = newRevNum + '-' + newRevId;
+ opts.new_edits = false;
+ }
+ function putDoc(next) {
+ if (typeof self._put === 'function' && opts.new_edits !== false) {
+ self._put(doc, opts, next);
+ } else {
+ self.bulkDocs({docs: [doc]}, opts, yankError(next, doc._id));
+ }
+ }
+});
+
+AbstractPouchDB.prototype.putAttachment =
+ adapterFun('putAttachment', function (docId, attachmentId, rev$$1,
+ blob, type) {
+ var api = this;
+ if (typeof type === 'function') {
+ type = blob;
+ blob = rev$$1;
+ rev$$1 = null;
+ }
+ // Lets fix in https://github.com/pouchdb/pouchdb/issues/3267
+ /* istanbul ignore if */
+ if (typeof type === 'undefined') {
+ type = blob;
+ blob = rev$$1;
+ rev$$1 = null;
+ }
+ if (!type) {
+ guardedConsole('warn', 'Attachment', attachmentId, 'on document', docId, 'is missing content_type');
+ }
+
+ function createAttachment(doc) {
+ var prevrevpos = '_rev' in doc ? parseInt(doc._rev, 10) : 0;
+ doc._attachments = doc._attachments || {};
+ doc._attachments[attachmentId] = {
+ content_type: type,
+ data: blob,
+ revpos: ++prevrevpos
+ };
+ return api.put(doc);
+ }
+
+ return api.get(docId).then(function (doc) {
+ if (doc._rev !== rev$$1) {
+ throw createError(REV_CONFLICT);
+ }
+
+ return createAttachment(doc);
+ }, function (err) {
+ // create new doc
+ /* istanbul ignore else */
+ if (err.reason === MISSING_DOC.message) {
+ return createAttachment({_id: docId});
+ } else {
+ throw err;
+ }
+ });
+});
+
+AbstractPouchDB.prototype.removeAttachment =
+ adapterFun('removeAttachment', function (docId, attachmentId, rev$$1,
+ callback) {
+ var self = this;
+ self.get(docId, function (err, obj) {
+ /* istanbul ignore if */
+ if (err) {
+ callback(err);
+ return;
+ }
+ if (obj._rev !== rev$$1) {
+ callback(createError(REV_CONFLICT));
+ return;
+ }
+ /* istanbul ignore if */
+ if (!obj._attachments) {
+ return callback();
+ }
+ delete obj._attachments[attachmentId];
+ if (Object.keys(obj._attachments).length === 0) {
+ delete obj._attachments;
+ }
+ self.put(obj, callback);
+ });
+});
+
+AbstractPouchDB.prototype.remove =
+ adapterFun('remove', function (docOrId, optsOrRev, opts, callback) {
+ var doc;
+ if (typeof optsOrRev === 'string') {
+ // id, rev, opts, callback style
+ doc = {
+ _id: docOrId,
+ _rev: optsOrRev
+ };
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ } else {
+ // doc, opts, callback style
+ doc = docOrId;
+ if (typeof optsOrRev === 'function') {
+ callback = optsOrRev;
+ opts = {};
+ } else {
+ callback = opts;
+ opts = optsOrRev;
+ }
+ }
+ opts = opts || {};
+ opts.was_delete = true;
+ var newDoc = {_id: doc._id, _rev: (doc._rev || opts.rev)};
+ newDoc._deleted = true;
+ if (isLocalId(newDoc._id) && typeof this._removeLocal === 'function') {
+ return this._removeLocal(doc, callback);
+ }
+ this.bulkDocs({docs: [newDoc]}, opts, yankError(callback, newDoc._id));
+});
+
+AbstractPouchDB.prototype.revsDiff =
+ adapterFun('revsDiff', function (req, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ var ids = Object.keys(req);
+
+ if (!ids.length) {
+ return callback(null, {});
+ }
+
+ var count = 0;
+ var missing = new ExportedMap();
+
+ function addToMissing(id, revId) {
+ if (!missing.has(id)) {
+ missing.set(id, {missing: []});
+ }
+ missing.get(id).missing.push(revId);
+ }
+
+ function processDoc(id, rev_tree) {
+ // Is this fast enough? Maybe we should switch to a set simulated by a map
+ var missingForId = req[id].slice(0);
+ traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx,
+ opts) {
+ var rev$$1 = pos + '-' + revHash;
+ var idx = missingForId.indexOf(rev$$1);
+ if (idx === -1) {
+ return;
+ }
+
+ missingForId.splice(idx, 1);
+ /* istanbul ignore if */
+ if (opts.status !== 'available') {
+ addToMissing(id, rev$$1);
+ }
+ });
+
+ // Traversing the tree is synchronous, so now `missingForId` contains
+ // revisions that were not found in the tree
+ missingForId.forEach(function (rev$$1) {
+ addToMissing(id, rev$$1);
+ });
+ }
+
+ ids.map(function (id) {
+ this._getRevisionTree(id, function (err, rev_tree) {
+ if (err && err.status === 404 && err.message === 'missing') {
+ missing.set(id, {missing: req[id]});
+ } else if (err) {
+ /* istanbul ignore next */
+ return callback(err);
+ } else {
+ processDoc(id, rev_tree);
+ }
+
+ if (++count === ids.length) {
+ // convert LazyMap to object
+ var missingObj = {};
+ missing.forEach(function (value, key) {
+ missingObj[key] = value;
+ });
+ return callback(null, missingObj);
+ }
+ });
+ }, this);
+});
+
+// _bulk_get API for faster replication, as described in
+// https://github.com/apache/couchdb-chttpd/pull/33
+// At the "abstract" level, it will just run multiple get()s in
+// parallel, because this isn't much of a performance cost
+// for local databases (except the cost of multiple transactions, which is
+// small). The http adapter overrides this in order
+// to do a more efficient single HTTP request.
+AbstractPouchDB.prototype.bulkGet =
+ adapterFun('bulkGet', function (opts, callback) {
+ bulkGet(this, opts, callback);
+});
+
+// compact one document and fire callback
+// by compacting we mean removing all revisions which
+// are further from the leaf in revision tree than max_height
+AbstractPouchDB.prototype.compactDocument =
+ adapterFun('compactDocument', function (docId, maxHeight, callback) {
+ var self = this;
+ this._getRevisionTree(docId, function (err, revTree) {
+ /* istanbul ignore if */
+ if (err) {
+ return callback(err);
+ }
+ var height = computeHeight(revTree);
+ var candidates = [];
+ var revs = [];
+ Object.keys(height).forEach(function (rev$$1) {
+ if (height[rev$$1] > maxHeight) {
+ candidates.push(rev$$1);
+ }
+ });
+
+ traverseRevTree(revTree, function (isLeaf, pos, revHash, ctx, opts) {
+ var rev$$1 = pos + '-' + revHash;
+ if (opts.status === 'available' && candidates.indexOf(rev$$1) !== -1) {
+ revs.push(rev$$1);
+ }
+ });
+ self._doCompaction(docId, revs, callback);
+ });
+});
+
+// compact the whole database using single document
+// compaction
+AbstractPouchDB.prototype.compact =
+ adapterFun('compact', function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ var self = this;
+ opts = opts || {};
+
+ self._compactionQueue = self._compactionQueue || [];
+ self._compactionQueue.push({opts: opts, callback: callback});
+ if (self._compactionQueue.length === 1) {
+ doNextCompaction(self);
+ }
+});
+AbstractPouchDB.prototype._compact = function (opts, callback) {
+ var self = this;
+ var changesOpts = {
+ return_docs: false,
+ last_seq: opts.last_seq || 0
+ };
+ var promises = [];
+
+ function onChange(row) {
+ promises.push(self.compactDocument(row.id, 0));
+ }
+ function onComplete(resp) {
+ var lastSeq = resp.last_seq;
+ Promise.all(promises).then(function () {
+ return upsert(self, '_local/compaction', function deltaFunc(doc) {
+ if (!doc.last_seq || doc.last_seq < lastSeq) {
+ doc.last_seq = lastSeq;
+ return doc;
+ }
+ return false; // somebody else got here first, don't update
+ });
+ }).then(function () {
+ callback(null, {ok: true});
+ })["catch"](callback);
+ }
+ self.changes(changesOpts)
+ .on('change', onChange)
+ .on('complete', onComplete)
+ .on('error', callback);
+};
+
+/* Begin api wrappers. Specific functionality to storage belongs in the
+ _[method] */
+AbstractPouchDB.prototype.get = adapterFun('get', function (id, opts, cb) {
+ if (typeof opts === 'function') {
+ cb = opts;
+ opts = {};
+ }
+ if (typeof id !== 'string') {
+ return cb(createError(INVALID_ID));
+ }
+ if (isLocalId(id) && typeof this._getLocal === 'function') {
+ return this._getLocal(id, cb);
+ }
+ var leaves = [], self = this;
+
+ function finishOpenRevs() {
+ var result = [];
+ var count = leaves.length;
+ /* istanbul ignore if */
+ if (!count) {
+ return cb(null, result);
+ }
+
+ // order with open_revs is unspecified
+ leaves.forEach(function (leaf) {
+ self.get(id, {
+ rev: leaf,
+ revs: opts.revs,
+ latest: opts.latest,
+ attachments: opts.attachments,
+ binary: opts.binary
+ }, function (err, doc) {
+ if (!err) {
+ // using latest=true can produce duplicates
+ var existing;
+ for (var i = 0, l = result.length; i < l; i++) {
+ if (result[i].ok && result[i].ok._rev === doc._rev) {
+ existing = true;
+ break;
+ }
+ }
+ if (!existing) {
+ result.push({ok: doc});
+ }
+ } else {
+ result.push({missing: leaf});
+ }
+ count--;
+ if (!count) {
+ cb(null, result);
+ }
+ });
+ });
+ }
+
+ if (opts.open_revs) {
+ if (opts.open_revs === "all") {
+ this._getRevisionTree(id, function (err, rev_tree) {
+ /* istanbul ignore if */
+ if (err) {
+ return cb(err);
+ }
+ leaves = collectLeaves(rev_tree).map(function (leaf) {
+ return leaf.rev;
+ });
+ finishOpenRevs();
+ });
+ } else {
+ if (Array.isArray(opts.open_revs)) {
+ leaves = opts.open_revs;
+ for (var i = 0; i < leaves.length; i++) {
+ var l = leaves[i];
+ // looks like it's the only thing couchdb checks
+ if (!(typeof (l) === "string" && /^\d+-/.test(l))) {
+ return cb(createError(INVALID_REV));
+ }
+ }
+ finishOpenRevs();
+ } else {
+ return cb(createError(UNKNOWN_ERROR, 'function_clause'));
+ }
+ }
+ return; // open_revs does not like other options
+ }
+
+ return this._get(id, opts, function (err, result) {
+ if (err) {
+ err.docId = id;
+ return cb(err);
+ }
+
+ var doc = result.doc;
+ var metadata = result.metadata;
+ var ctx = result.ctx;
+
+ if (opts.conflicts) {
+ var conflicts = collectConflicts(metadata);
+ if (conflicts.length) {
+ doc._conflicts = conflicts;
+ }
+ }
+
+ if (isDeleted(metadata, doc._rev)) {
+ doc._deleted = true;
+ }
+
+ if (opts.revs || opts.revs_info) {
+ var splittedRev = doc._rev.split('-');
+ var revNo = parseInt(splittedRev[0], 10);
+ var revHash = splittedRev[1];
+
+ var paths = rootToLeaf(metadata.rev_tree);
+ var path = null;
+
+ for (var i = 0; i < paths.length; i++) {
+ var currentPath = paths[i];
+ var hashIndex = currentPath.ids.map(function (x) { return x.id; })
+ .indexOf(revHash);
+ var hashFoundAtRevPos = hashIndex === (revNo - 1);
+
+ if (hashFoundAtRevPos || (!path && hashIndex !== -1)) {
+ path = currentPath;
+ }
+ }
+
+ /* istanbul ignore if */
+ if (!path) {
+ err = new Error('invalid rev tree');
+ err.docId = id;
+ return cb(err);
+ }
+
+ var indexOfRev = path.ids.map(function (x) { return x.id; })
+ .indexOf(doc._rev.split('-')[1]) + 1;
+ var howMany = path.ids.length - indexOfRev;
+ path.ids.splice(indexOfRev, howMany);
+ path.ids.reverse();
+
+ if (opts.revs) {
+ doc._revisions = {
+ start: (path.pos + path.ids.length) - 1,
+ ids: path.ids.map(function (rev$$1) {
+ return rev$$1.id;
+ })
+ };
+ }
+ if (opts.revs_info) {
+ var pos = path.pos + path.ids.length;
+ doc._revs_info = path.ids.map(function (rev$$1) {
+ pos--;
+ return {
+ rev: pos + '-' + rev$$1.id,
+ status: rev$$1.opts.status
+ };
+ });
+ }
+ }
+
+ if (opts.attachments && doc._attachments) {
+ var attachments = doc._attachments;
+ var count = Object.keys(attachments).length;
+ if (count === 0) {
+ return cb(null, doc);
+ }
+ Object.keys(attachments).forEach(function (key) {
+ this._getAttachment(doc._id, key, attachments[key], {
+ // Previously the revision handling was done in adapter.js
+ // getAttachment, however since idb-next doesnt we need to
+ // pass the rev through
+ rev: doc._rev,
+ binary: opts.binary,
+ ctx: ctx
+ }, function (err, data) {
+ var att = doc._attachments[key];
+ att.data = data;
+ delete att.stub;
+ delete att.length;
+ if (!--count) {
+ cb(null, doc);
+ }
+ });
+ }, self);
+ } else {
+ if (doc._attachments) {
+ for (var key in doc._attachments) {
+ /* istanbul ignore else */
+ if (doc._attachments.hasOwnProperty(key)) {
+ doc._attachments[key].stub = true;
+ }
+ }
+ }
+ cb(null, doc);
+ }
+ });
+});
+
+// TODO: I dont like this, it forces an extra read for every
+// attachment read and enforces a confusing api between
+// adapter.js and the adapter implementation
+AbstractPouchDB.prototype.getAttachment =
+ adapterFun('getAttachment', function (docId, attachmentId, opts, callback) {
+ var self = this;
+ if (opts instanceof Function) {
+ callback = opts;
+ opts = {};
+ }
+ this._get(docId, opts, function (err, res) {
+ if (err) {
+ return callback(err);
+ }
+ if (res.doc._attachments && res.doc._attachments[attachmentId]) {
+ opts.ctx = res.ctx;
+ opts.binary = true;
+ self._getAttachment(docId, attachmentId,
+ res.doc._attachments[attachmentId], opts, callback);
+ } else {
+ return callback(createError(MISSING_DOC));
+ }
+ });
+});
+
+AbstractPouchDB.prototype.allDocs =
+ adapterFun('allDocs', function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts.skip = typeof opts.skip !== 'undefined' ? opts.skip : 0;
+ if (opts.start_key) {
+ opts.startkey = opts.start_key;
+ }
+ if (opts.end_key) {
+ opts.endkey = opts.end_key;
+ }
+ if ('keys' in opts) {
+ if (!Array.isArray(opts.keys)) {
+ return callback(new TypeError('options.keys must be an array'));
+ }
+ var incompatibleOpt =
+ ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) {
+ return incompatibleOpt in opts;
+ })[0];
+ if (incompatibleOpt) {
+ callback(createError(QUERY_PARSE_ERROR,
+ 'Query parameter `' + incompatibleOpt +
+ '` is not compatible with multi-get'
+ ));
+ return;
+ }
+ if (!isRemote(this)) {
+ allDocsKeysParse(opts);
+ if (opts.keys.length === 0) {
+ return this._allDocs({limit: 0}, callback);
+ }
+ }
+ }
+
+ return this._allDocs(opts, callback);
+});
+
+AbstractPouchDB.prototype.changes = function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ opts = opts || {};
+
+ // By default set return_docs to false if the caller has opts.live = true,
+ // this will prevent us from collecting the set of changes indefinitely
+ // resulting in growing memory
+ opts.return_docs = ('return_docs' in opts) ? opts.return_docs : !opts.live;
+
+ return new Changes$1(this, opts, callback);
+};
+
+AbstractPouchDB.prototype.close = adapterFun('close', function (callback) {
+ this._closed = true;
+ this.emit('closed');
+ return this._close(callback);
+});
+
+AbstractPouchDB.prototype.info = adapterFun('info', function (callback) {
+ var self = this;
+ this._info(function (err, info) {
+ if (err) {
+ return callback(err);
+ }
+ // assume we know better than the adapter, unless it informs us
+ info.db_name = info.db_name || self.name;
+ info.auto_compaction = !!(self.auto_compaction && !isRemote(self));
+ info.adapter = self.adapter;
+ callback(null, info);
+ });
+});
+
+AbstractPouchDB.prototype.id = adapterFun('id', function (callback) {
+ return this._id(callback);
+});
+
+/* istanbul ignore next */
+AbstractPouchDB.prototype.type = function () {
+ return (typeof this._type === 'function') ? this._type() : this.adapter;
+};
+
+AbstractPouchDB.prototype.bulkDocs =
+ adapterFun('bulkDocs', function (req, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ opts = opts || {};
+
+ if (Array.isArray(req)) {
+ req = {
+ docs: req
+ };
+ }
+
+ if (!req || !req.docs || !Array.isArray(req.docs)) {
+ return callback(createError(MISSING_BULK_DOCS));
+ }
+
+ for (var i = 0; i < req.docs.length; ++i) {
+ if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) {
+ return callback(createError(NOT_AN_OBJECT));
+ }
+ }
+
+ var attachmentError;
+ req.docs.forEach(function (doc) {
+ if (doc._attachments) {
+ Object.keys(doc._attachments).forEach(function (name) {
+ attachmentError = attachmentError || attachmentNameError(name);
+ if (!doc._attachments[name].content_type) {
+ guardedConsole('warn', 'Attachment', name, 'on document', doc._id, 'is missing content_type');
+ }
+ });
+ }
+ });
+
+ if (attachmentError) {
+ return callback(createError(BAD_REQUEST, attachmentError));
+ }
+
+ if (!('new_edits' in opts)) {
+ if ('new_edits' in req) {
+ opts.new_edits = req.new_edits;
+ } else {
+ opts.new_edits = true;
+ }
+ }
+
+ var adapter = this;
+ if (!opts.new_edits && !isRemote(adapter)) {
+ // ensure revisions of the same doc are sorted, so that
+ // the local adapter processes them correctly (#2935)
+ req.docs.sort(compareByIdThenRev);
+ }
+
+ cleanDocs(req.docs);
+
+ // in the case of conflicts, we want to return the _ids to the user
+ // however, the underlying adapter may destroy the docs array, so
+ // create a copy here
+ var ids = req.docs.map(function (doc) {
+ return doc._id;
+ });
+
+ return this._bulkDocs(req, opts, function (err, res) {
+ if (err) {
+ return callback(err);
+ }
+ if (!opts.new_edits) {
+ // this is what couch does when new_edits is false
+ res = res.filter(function (x) {
+ return x.error;
+ });
+ }
+ // add ids for error/conflict responses (not required for CouchDB)
+ if (!isRemote(adapter)) {
+ for (var i = 0, l = res.length; i < l; i++) {
+ res[i].id = res[i].id || ids[i];
+ }
+ }
+
+ callback(null, res);
+ });
+});
+
+AbstractPouchDB.prototype.registerDependentDatabase =
+ adapterFun('registerDependentDatabase', function (dependentDb,
+ callback) {
+ var depDB = new this.constructor(dependentDb, this.__opts);
+
+ function diffFun(doc) {
+ doc.dependentDbs = doc.dependentDbs || {};
+ if (doc.dependentDbs[dependentDb]) {
+ return false; // no update required
+ }
+ doc.dependentDbs[dependentDb] = true;
+ return doc;
+ }
+ upsert(this, '_local/_pouch_dependentDbs', diffFun)
+ .then(function () {
+ callback(null, {db: depDB});
+ })["catch"](callback);
+});
+
+AbstractPouchDB.prototype.destroy =
+ adapterFun('destroy', function (opts, callback) {
+
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ var self = this;
+ var usePrefix = 'use_prefix' in self ? self.use_prefix : true;
+
+ function destroyDb() {
+ // call destroy method of the particular adaptor
+ self._destroy(opts, function (err, resp) {
+ if (err) {
+ return callback(err);
+ }
+ self._destroyed = true;
+ self.emit('destroyed');
+ callback(null, resp || { 'ok': true });
+ });
+ }
+
+ if (isRemote(self)) {
+ // no need to check for dependent DBs if it's a remote DB
+ return destroyDb();
+ }
+
+ self.get('_local/_pouch_dependentDbs', function (err, localDoc) {
+ if (err) {
+ /* istanbul ignore if */
+ if (err.status !== 404) {
+ return callback(err);
+ } else { // no dependencies
+ return destroyDb();
+ }
+ }
+ var dependentDbs = localDoc.dependentDbs;
+ var PouchDB = self.constructor;
+ var deletedMap = Object.keys(dependentDbs).map(function (name) {
+ // use_prefix is only false in the browser
+ /* istanbul ignore next */
+ var trueName = usePrefix ?
+ name.replace(new RegExp('^' + PouchDB.prefix), '') : name;
+ return new PouchDB(trueName, self.__opts).destroy();
+ });
+ Promise.all(deletedMap).then(destroyDb, callback);
+ });
+});
+
+function TaskQueue() {
+ this.isReady = false;
+ this.failed = false;
+ this.queue = [];
+}
+
+TaskQueue.prototype.execute = function () {
+ var fun;
+ if (this.failed) {
+ while ((fun = this.queue.shift())) {
+ fun(this.failed);
+ }
+ } else {
+ while ((fun = this.queue.shift())) {
+ fun();
+ }
+ }
+};
+
+TaskQueue.prototype.fail = function (err) {
+ this.failed = err;
+ this.execute();
+};
+
+TaskQueue.prototype.ready = function (db) {
+ this.isReady = true;
+ this.db = db;
+ this.execute();
+};
+
+TaskQueue.prototype.addTask = function (fun) {
+ this.queue.push(fun);
+ if (this.failed) {
+ this.execute();
+ }
+};
+
+function parseAdapter(name, opts) {
+ var match = name.match(/([a-z-]*):\/\/(.*)/);
+ if (match) {
+ // the http adapter expects the fully qualified name
+ return {
+ name: /https?/.test(match[1]) ? match[1] + '://' + match[2] : match[2],
+ adapter: match[1]
+ };
+ }
+
+ var adapters = PouchDB.adapters;
+ var preferredAdapters = PouchDB.preferredAdapters;
+ var prefix = PouchDB.prefix;
+ var adapterName = opts.adapter;
+
+ if (!adapterName) { // automatically determine adapter
+ for (var i = 0; i < preferredAdapters.length; ++i) {
+ adapterName = preferredAdapters[i];
+ // check for browsers that have been upgraded from websql-only to websql+idb
+ /* istanbul ignore if */
+ if (adapterName === 'idb' && 'websql' in adapters &&
+ hasLocalStorage() && localStorage['_pouch__websqldb_' + prefix + name]) {
+ // log it, because this can be confusing during development
+ guardedConsole('log', 'PouchDB is downgrading "' + name + '" to WebSQL to' +
+ ' avoid data loss, because it was already opened with WebSQL.');
+ continue; // keep using websql to avoid user data loss
+ }
+ break;
+ }
+ }
+
+ var adapter = adapters[adapterName];
+
+ // if adapter is invalid, then an error will be thrown later
+ var usePrefix = (adapter && 'use_prefix' in adapter) ?
+ adapter.use_prefix : true;
+
+ return {
+ name: usePrefix ? (prefix + name) : name,
+ adapter: adapterName
+ };
+}
+
+// OK, so here's the deal. Consider this code:
+// var db1 = new PouchDB('foo');
+// var db2 = new PouchDB('foo');
+// db1.destroy();
+// ^ these two both need to emit 'destroyed' events,
+// as well as the PouchDB constructor itself.
+// So we have one db object (whichever one got destroy() called on it)
+// responsible for emitting the initial event, which then gets emitted
+// by the constructor, which then broadcasts it to any other dbs
+// that may have been created with the same name.
+function prepareForDestruction(self) {
+
+ function onDestroyed(from_constructor) {
+ self.removeListener('closed', onClosed);
+ if (!from_constructor) {
+ self.constructor.emit('destroyed', self.name);
+ }
+ }
+
+ function onClosed() {
+ self.removeListener('destroyed', onDestroyed);
+ self.constructor.emit('unref', self);
+ }
+
+ self.once('destroyed', onDestroyed);
+ self.once('closed', onClosed);
+ self.constructor.emit('ref', self);
+}
+
+inherits(PouchDB, AbstractPouchDB);
+function PouchDB(name, opts) {
+ // In Node our test suite only tests this for PouchAlt unfortunately
+ /* istanbul ignore if */
+ if (!(this instanceof PouchDB)) {
+ return new PouchDB(name, opts);
+ }
+
+ var self = this;
+ opts = opts || {};
+
+ if (name && typeof name === 'object') {
+ opts = name;
+ name = opts.name;
+ delete opts.name;
+ }
+
+ if (opts.deterministic_revs === undefined) {
+ opts.deterministic_revs = true;
+ }
+
+ this.__opts = opts = clone(opts);
+
+ self.auto_compaction = opts.auto_compaction;
+ self.prefix = PouchDB.prefix;
+
+ if (typeof name !== 'string') {
+ throw new Error('Missing/invalid DB name');
+ }
+
+ var prefixedName = (opts.prefix || '') + name;
+ var backend = parseAdapter(prefixedName, opts);
+
+ opts.name = backend.name;
+ opts.adapter = opts.adapter || backend.adapter;
+
+ self.name = name;
+ self._adapter = opts.adapter;
+ PouchDB.emit('debug', ['adapter', 'Picked adapter: ', opts.adapter]);
+
+ if (!PouchDB.adapters[opts.adapter] ||
+ !PouchDB.adapters[opts.adapter].valid()) {
+ throw new Error('Invalid Adapter: ' + opts.adapter);
+ }
+
+ AbstractPouchDB.call(self);
+ self.taskqueue = new TaskQueue();
+
+ self.adapter = opts.adapter;
+
+ PouchDB.adapters[opts.adapter].call(self, opts, function (err) {
+ if (err) {
+ return self.taskqueue.fail(err);
+ }
+ prepareForDestruction(self);
+
+ self.emit('created', self);
+ PouchDB.emit('created', self.name);
+ self.taskqueue.ready(self);
+ });
+
+}
+
+// AbortController was introduced quite a while after fetch and
+// isnt required for PouchDB to function so polyfill if needed
+var a = (typeof AbortController !== 'undefined')
+ ? AbortController
+ : function () { return {abort: function () {}}; };
+
+var f$1 = fetch;
+var h = Headers;
+
+PouchDB.adapters = {};
+PouchDB.preferredAdapters = [];
+
+PouchDB.prefix = '_pouch_';
+
+var eventEmitter = new events.EventEmitter();
+
+function setUpEventEmitter(Pouch) {
+ Object.keys(events.EventEmitter.prototype).forEach(function (key) {
+ if (typeof events.EventEmitter.prototype[key] === 'function') {
+ Pouch[key] = eventEmitter[key].bind(eventEmitter);
+ }
+ });
+
+ // these are created in constructor.js, and allow us to notify each DB with
+ // the same name that it was destroyed, via the constructor object
+ var destructListeners = Pouch._destructionListeners = new ExportedMap();
+
+ Pouch.on('ref', function onConstructorRef(db) {
+ if (!destructListeners.has(db.name)) {
+ destructListeners.set(db.name, []);
+ }
+ destructListeners.get(db.name).push(db);
+ });
+
+ Pouch.on('unref', function onConstructorUnref(db) {
+ if (!destructListeners.has(db.name)) {
+ return;
+ }
+ var dbList = destructListeners.get(db.name);
+ var pos = dbList.indexOf(db);
+ if (pos < 0) {
+ /* istanbul ignore next */
+ return;
+ }
+ dbList.splice(pos, 1);
+ if (dbList.length > 1) {
+ /* istanbul ignore next */
+ destructListeners.set(db.name, dbList);
+ } else {
+ destructListeners["delete"](db.name);
+ }
+ });
+
+ Pouch.on('destroyed', function onConstructorDestroyed(name) {
+ if (!destructListeners.has(name)) {
+ return;
+ }
+ var dbList = destructListeners.get(name);
+ destructListeners["delete"](name);
+ dbList.forEach(function (db) {
+ db.emit('destroyed',true);
+ });
+ });
+}
+
+setUpEventEmitter(PouchDB);
+
+PouchDB.adapter = function (id, obj, addToPreferredAdapters) {
+ /* istanbul ignore else */
+ if (obj.valid()) {
+ PouchDB.adapters[id] = obj;
+ if (addToPreferredAdapters) {
+ PouchDB.preferredAdapters.push(id);
+ }
+ }
+};
+
+PouchDB.plugin = function (obj) {
+ if (typeof obj === 'function') { // function style for plugins
+ obj(PouchDB);
+ } else if (typeof obj !== 'object' || Object.keys(obj).length === 0) {
+ throw new Error('Invalid plugin: got "' + obj + '", expected an object or a function');
+ } else {
+ Object.keys(obj).forEach(function (id) { // object style for plugins
+ PouchDB.prototype[id] = obj[id];
+ });
+ }
+ if (this.__defaults) {
+ PouchDB.__defaults = $inject_Object_assign({}, this.__defaults);
+ }
+ return PouchDB;
+};
+
+PouchDB.defaults = function (defaultOpts) {
+ function PouchAlt(name, opts) {
+ if (!(this instanceof PouchAlt)) {
+ return new PouchAlt(name, opts);
+ }
+
+ opts = opts || {};
+
+ if (name && typeof name === 'object') {
+ opts = name;
+ name = opts.name;
+ delete opts.name;
+ }
+
+ opts = $inject_Object_assign({}, PouchAlt.__defaults, opts);
+ PouchDB.call(this, name, opts);
+ }
+
+ inherits(PouchAlt, PouchDB);
+
+ PouchAlt.preferredAdapters = PouchDB.preferredAdapters.slice();
+ Object.keys(PouchDB).forEach(function (key) {
+ if (!(key in PouchAlt)) {
+ PouchAlt[key] = PouchDB[key];
+ }
+ });
+
+ // make default options transitive
+ // https://github.com/pouchdb/pouchdb/issues/5922
+ PouchAlt.__defaults = $inject_Object_assign({}, this.__defaults, defaultOpts);
+
+ return PouchAlt;
+};
+
+PouchDB.fetch = function (url, opts) {
+ return f$1(url, opts);
+};
+
+// managed automatically by set-version.js
+var version = "7.1.1";
+
+// this would just be "return doc[field]", but fields
+// can be "deep" due to dot notation
+function getFieldFromDoc(doc, parsedField) {
+ var value = doc;
+ for (var i = 0, len = parsedField.length; i < len; i++) {
+ var key = parsedField[i];
+ value = value[key];
+ if (!value) {
+ break;
+ }
+ }
+ return value;
+}
+
+function compare$1(left, right) {
+ return left < right ? -1 : left > right ? 1 : 0;
+}
+
+// Converts a string in dot notation to an array of its components, with backslash escaping
+function parseField(fieldName) {
+ // fields may be deep (e.g. "foo.bar.baz"), so parse
+ var fields = [];
+ var current = '';
+ for (var i = 0, len = fieldName.length; i < len; i++) {
+ var ch = fieldName[i];
+ if (ch === '.') {
+ if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter
+ current = current.substring(0, current.length - 1) + '.';
+ } else { // not escaped, so delimiter
+ fields.push(current);
+ current = '';
+ }
+ } else { // normal character
+ current += ch;
+ }
+ }
+ fields.push(current);
+ return fields;
+}
+
+var combinationFields = ['$or', '$nor', '$not'];
+function isCombinationalField(field) {
+ return combinationFields.indexOf(field) > -1;
+}
+
+function getKey(obj) {
+ return Object.keys(obj)[0];
+}
+
+function getValue(obj) {
+ return obj[getKey(obj)];
+}
+
+
+// flatten an array of selectors joined by an $and operator
+function mergeAndedSelectors(selectors) {
+
+ // sort to ensure that e.g. if the user specified
+ // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into
+ // just {$gt: 'b'}
+ var res = {};
+
+ selectors.forEach(function (selector) {
+ Object.keys(selector).forEach(function (field) {
+ var matcher = selector[field];
+ if (typeof matcher !== 'object') {
+ matcher = {$eq: matcher};
+ }
+
+ if (isCombinationalField(field)) {
+ if (matcher instanceof Array) {
+ res[field] = matcher.map(function (m) {
+ return mergeAndedSelectors([m]);
+ });
+ } else {
+ res[field] = mergeAndedSelectors([matcher]);
+ }
+ } else {
+ var fieldMatchers = res[field] = res[field] || {};
+ Object.keys(matcher).forEach(function (operator) {
+ var value = matcher[operator];
+
+ if (operator === '$gt' || operator === '$gte') {
+ return mergeGtGte(operator, value, fieldMatchers);
+ } else if (operator === '$lt' || operator === '$lte') {
+ return mergeLtLte(operator, value, fieldMatchers);
+ } else if (operator === '$ne') {
+ return mergeNe(value, fieldMatchers);
+ } else if (operator === '$eq') {
+ return mergeEq(value, fieldMatchers);
+ }
+ fieldMatchers[operator] = value;
+ });
+ }
+ });
+ });
+
+ return res;
+}
+
+
+
+// collapse logically equivalent gt/gte values
+function mergeGtGte(operator, value, fieldMatchers) {
+ if (typeof fieldMatchers.$eq !== 'undefined') {
+ return; // do nothing
+ }
+ if (typeof fieldMatchers.$gte !== 'undefined') {
+ if (operator === '$gte') {
+ if (value > fieldMatchers.$gte) { // more specificity
+ fieldMatchers.$gte = value;
+ }
+ } else { // operator === '$gt'
+ if (value >= fieldMatchers.$gte) { // more specificity
+ delete fieldMatchers.$gte;
+ fieldMatchers.$gt = value;
+ }
+ }
+ } else if (typeof fieldMatchers.$gt !== 'undefined') {
+ if (operator === '$gte') {
+ if (value > fieldMatchers.$gt) { // more specificity
+ delete fieldMatchers.$gt;
+ fieldMatchers.$gte = value;
+ }
+ } else { // operator === '$gt'
+ if (value > fieldMatchers.$gt) { // more specificity
+ fieldMatchers.$gt = value;
+ }
+ }
+ } else {
+ fieldMatchers[operator] = value;
+ }
+}
+
+// collapse logically equivalent lt/lte values
+function mergeLtLte(operator, value, fieldMatchers) {
+ if (typeof fieldMatchers.$eq !== 'undefined') {
+ return; // do nothing
+ }
+ if (typeof fieldMatchers.$lte !== 'undefined') {
+ if (operator === '$lte') {
+ if (value < fieldMatchers.$lte) { // more specificity
+ fieldMatchers.$lte = value;
+ }
+ } else { // operator === '$gt'
+ if (value <= fieldMatchers.$lte) { // more specificity
+ delete fieldMatchers.$lte;
+ fieldMatchers.$lt = value;
+ }
+ }
+ } else if (typeof fieldMatchers.$lt !== 'undefined') {
+ if (operator === '$lte') {
+ if (value < fieldMatchers.$lt) { // more specificity
+ delete fieldMatchers.$lt;
+ fieldMatchers.$lte = value;
+ }
+ } else { // operator === '$gt'
+ if (value < fieldMatchers.$lt) { // more specificity
+ fieldMatchers.$lt = value;
+ }
+ }
+ } else {
+ fieldMatchers[operator] = value;
+ }
+}
+
+// combine $ne values into one array
+function mergeNe(value, fieldMatchers) {
+ if ('$ne' in fieldMatchers) {
+ // there are many things this could "not" be
+ fieldMatchers.$ne.push(value);
+ } else { // doesn't exist yet
+ fieldMatchers.$ne = [value];
+ }
+}
+
+// add $eq into the mix
+function mergeEq(value, fieldMatchers) {
+ // these all have less specificity than the $eq
+ // TODO: check for user errors here
+ delete fieldMatchers.$gt;
+ delete fieldMatchers.$gte;
+ delete fieldMatchers.$lt;
+ delete fieldMatchers.$lte;
+ delete fieldMatchers.$ne;
+ fieldMatchers.$eq = value;
+}
+
+//#7458: execute function mergeAndedSelectors on nested $and
+function mergeAndedSelectorsNested(obj) {
+ for (var prop in obj) {
+ if (Array.isArray(obj)) {
+ for (var i in obj) {
+ if (obj[i]['$and']) {
+ obj[i] = mergeAndedSelectors(obj[i]['$and']);
+ }
+ }
+ }
+ var value = obj[prop];
+ if (typeof value === 'object') {
+ mergeAndedSelectorsNested(value); // <- recursive call
+ }
+ }
+ return obj;
+}
+
+//#7458: determine id $and is present in selector (at any level)
+function isAndInSelector(obj, isAnd) {
+ for (var prop in obj) {
+ if (prop === '$and') {
+ isAnd = true;
+ }
+ var value = obj[prop];
+ if (typeof value === 'object') {
+ isAnd = isAndInSelector(value, isAnd); // <- recursive call
+ }
+ }
+ return isAnd;
+}
+
+//
+// normalize the selector
+//
+function massageSelector(input) {
+ var result = clone(input);
+ var wasAnded = false;
+ //#7458: if $and is present in selector (at any level) merge nested $and
+ if (isAndInSelector(result, false)) {
+ result = mergeAndedSelectorsNested(result);
+ if ('$and' in result) {
+ result = mergeAndedSelectors(result['$and']);
+ }
+ wasAnded = true;
+ }
+
+ ['$or', '$nor'].forEach(function (orOrNor) {
+ if (orOrNor in result) {
+ // message each individual selector
+ // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}}
+ result[orOrNor].forEach(function (subSelector) {
+ var fields = Object.keys(subSelector);
+ for (var i = 0; i < fields.length; i++) {
+ var field = fields[i];
+ var matcher = subSelector[field];
+ if (typeof matcher !== 'object' || matcher === null) {
+ subSelector[field] = {$eq: matcher};
+ }
+ }
+ });
+ }
+ });
+
+ if ('$not' in result) {
+ //This feels a little like forcing, but it will work for now,
+ //I would like to come back to this and make the merging of selectors a little more generic
+ result['$not'] = mergeAndedSelectors([result['$not']]);
+ }
+
+ var fields = Object.keys(result);
+
+ for (var i = 0; i < fields.length; i++) {
+ var field = fields[i];
+ var matcher = result[field];
+
+ if (typeof matcher !== 'object' || matcher === null) {
+ matcher = {$eq: matcher};
+ } else if ('$ne' in matcher && !wasAnded) {
+ // I put these in an array, since there may be more than one
+ // but in the "mergeAnded" operation, I already take care of that
+ matcher.$ne = [matcher.$ne];
+ }
+ result[field] = matcher;
+ }
+
+ return result;
+}
+
+function pad(str, padWith, upToLength) {
+ var padding = '';
+ var targetLength = upToLength - str.length;
+ /* istanbul ignore next */
+ while (padding.length < targetLength) {
+ padding += padWith;
+ }
+ return padding;
+}
+
+function padLeft(str, padWith, upToLength) {
+ var padding = pad(str, padWith, upToLength);
+ return padding + str;
+}
+
+var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE
+var MAGNITUDE_DIGITS = 3; // ditto
+var SEP = ''; // set to '_' for easier debugging
+
+function collate(a, b) {
+
+ if (a === b) {
+ return 0;
+ }
+
+ a = normalizeKey(a);
+ b = normalizeKey(b);
+
+ var ai = collationIndex(a);
+ var bi = collationIndex(b);
+ if ((ai - bi) !== 0) {
+ return ai - bi;
+ }
+ switch (typeof a) {
+ case 'number':
+ return a - b;
+ case 'boolean':
+ return a < b ? -1 : 1;
+ case 'string':
+ return stringCollate(a, b);
+ }
+ return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b);
+}
+
+// couch considers null/NaN/Infinity/-Infinity === undefined,
+// for the purposes of mapreduce indexes. also, dates get stringified.
+function normalizeKey(key) {
+ switch (typeof key) {
+ case 'undefined':
+ return null;
+ case 'number':
+ if (key === Infinity || key === -Infinity || isNaN(key)) {
+ return null;
+ }
+ return key;
+ case 'object':
+ var origKey = key;
+ if (Array.isArray(key)) {
+ var len = key.length;
+ key = new Array(len);
+ for (var i = 0; i < len; i++) {
+ key[i] = normalizeKey(origKey[i]);
+ }
+ /* istanbul ignore next */
+ } else if (key instanceof Date) {
+ return key.toJSON();
+ } else if (key !== null) { // generic object
+ key = {};
+ for (var k in origKey) {
+ if (origKey.hasOwnProperty(k)) {
+ var val = origKey[k];
+ if (typeof val !== 'undefined') {
+ key[k] = normalizeKey(val);
+ }
+ }
+ }
+ }
+ }
+ return key;
+}
+
+function indexify(key) {
+ if (key !== null) {
+ switch (typeof key) {
+ case 'boolean':
+ return key ? 1 : 0;
+ case 'number':
+ return numToIndexableString(key);
+ case 'string':
+ // We've to be sure that key does not contain \u0000
+ // Do order-preserving replacements:
+ // 0 -> 1, 1
+ // 1 -> 1, 2
+ // 2 -> 2, 2
+ /* eslint-disable no-control-regex */
+ return key
+ .replace(/\u0002/g, '\u0002\u0002')
+ .replace(/\u0001/g, '\u0001\u0002')
+ .replace(/\u0000/g, '\u0001\u0001');
+ /* eslint-enable no-control-regex */
+ case 'object':
+ var isArray = Array.isArray(key);
+ var arr = isArray ? key : Object.keys(key);
+ var i = -1;
+ var len = arr.length;
+ var result = '';
+ if (isArray) {
+ while (++i < len) {
+ result += toIndexableString(arr[i]);
+ }
+ } else {
+ while (++i < len) {
+ var objKey = arr[i];
+ result += toIndexableString(objKey) +
+ toIndexableString(key[objKey]);
+ }
+ }
+ return result;
+ }
+ }
+ return '';
+}
+
+// convert the given key to a string that would be appropriate
+// for lexical sorting, e.g. within a database, where the
+// sorting is the same given by the collate() function.
+function toIndexableString(key) {
+ var zero = '\u0000';
+ key = normalizeKey(key);
+ return collationIndex(key) + SEP + indexify(key) + zero;
+}
+
+function parseNumber(str, i) {
+ var originalIdx = i;
+ var num;
+ var zero = str[i] === '1';
+ if (zero) {
+ num = 0;
+ i++;
+ } else {
+ var neg = str[i] === '0';
+ i++;
+ var numAsString = '';
+ var magAsString = str.substring(i, i + MAGNITUDE_DIGITS);
+ var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE;
+ /* istanbul ignore next */
+ if (neg) {
+ magnitude = -magnitude;
+ }
+ i += MAGNITUDE_DIGITS;
+ while (true) {
+ var ch = str[i];
+ if (ch === '\u0000') {
+ break;
+ } else {
+ numAsString += ch;
+ }
+ i++;
+ }
+ numAsString = numAsString.split('.');
+ if (numAsString.length === 1) {
+ num = parseInt(numAsString, 10);
+ } else {
+ /* istanbul ignore next */
+ num = parseFloat(numAsString[0] + '.' + numAsString[1]);
+ }
+ /* istanbul ignore next */
+ if (neg) {
+ num = num - 10;
+ }
+ /* istanbul ignore next */
+ if (magnitude !== 0) {
+ // parseFloat is more reliable than pow due to rounding errors
+ // e.g. Number.MAX_VALUE would return Infinity if we did
+ // num * Math.pow(10, magnitude);
+ num = parseFloat(num + 'e' + magnitude);
+ }
+ }
+ return {num: num, length : i - originalIdx};
+}
+
+// move up the stack while parsing
+// this function moved outside of parseIndexableString for performance
+function pop(stack, metaStack) {
+ var obj = stack.pop();
+
+ if (metaStack.length) {
+ var lastMetaElement = metaStack[metaStack.length - 1];
+ if (obj === lastMetaElement.element) {
+ // popping a meta-element, e.g. an object whose value is another object
+ metaStack.pop();
+ lastMetaElement = metaStack[metaStack.length - 1];
+ }
+ var element = lastMetaElement.element;
+ var lastElementIndex = lastMetaElement.index;
+ if (Array.isArray(element)) {
+ element.push(obj);
+ } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+ var key = stack.pop();
+ element[key] = obj;
+ } else {
+ stack.push(obj); // obj with key only
+ }
+ }
+}
+
+function parseIndexableString(str) {
+ var stack = [];
+ var metaStack = []; // stack for arrays and objects
+ var i = 0;
+
+ /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+ while (true) {
+ var collationIndex = str[i++];
+ if (collationIndex === '\u0000') {
+ if (stack.length === 1) {
+ return stack.pop();
+ } else {
+ pop(stack, metaStack);
+ continue;
+ }
+ }
+ switch (collationIndex) {
+ case '1':
+ stack.push(null);
+ break;
+ case '2':
+ stack.push(str[i] === '1');
+ i++;
+ break;
+ case '3':
+ var parsedNum = parseNumber(str, i);
+ stack.push(parsedNum.num);
+ i += parsedNum.length;
+ break;
+ case '4':
+ var parsedStr = '';
+ /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+ while (true) {
+ var ch = str[i];
+ if (ch === '\u0000') {
+ break;
+ }
+ parsedStr += ch;
+ i++;
+ }
+ // perform the reverse of the order-preserving replacement
+ // algorithm (see above)
+ /* eslint-disable no-control-regex */
+ parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000')
+ .replace(/\u0001\u0002/g, '\u0001')
+ .replace(/\u0002\u0002/g, '\u0002');
+ /* eslint-enable no-control-regex */
+ stack.push(parsedStr);
+ break;
+ case '5':
+ var arrayElement = { element: [], index: stack.length };
+ stack.push(arrayElement.element);
+ metaStack.push(arrayElement);
+ break;
+ case '6':
+ var objElement = { element: {}, index: stack.length };
+ stack.push(objElement.element);
+ metaStack.push(objElement);
+ break;
+ /* istanbul ignore next */
+ default:
+ throw new Error(
+ 'bad collationIndex or unexpectedly reached end of input: ' +
+ collationIndex);
+ }
+ }
+}
+
+function arrayCollate(a, b) {
+ var len = Math.min(a.length, b.length);
+ for (var i = 0; i < len; i++) {
+ var sort = collate(a[i], b[i]);
+ if (sort !== 0) {
+ return sort;
+ }
+ }
+ return (a.length === b.length) ? 0 :
+ (a.length > b.length) ? 1 : -1;
+}
+function stringCollate(a, b) {
+ // See: https://github.com/daleharvey/pouchdb/issues/40
+ // This is incompatible with the CouchDB implementation, but its the
+ // best we can do for now
+ return (a === b) ? 0 : ((a > b) ? 1 : -1);
+}
+function objectCollate(a, b) {
+ var ak = Object.keys(a), bk = Object.keys(b);
+ var len = Math.min(ak.length, bk.length);
+ for (var i = 0; i < len; i++) {
+ // First sort the keys
+ var sort = collate(ak[i], bk[i]);
+ if (sort !== 0) {
+ return sort;
+ }
+ // if the keys are equal sort the values
+ sort = collate(a[ak[i]], b[bk[i]]);
+ if (sort !== 0) {
+ return sort;
+ }
+
+ }
+ return (ak.length === bk.length) ? 0 :
+ (ak.length > bk.length) ? 1 : -1;
+}
+// The collation is defined by erlangs ordered terms
+// the atoms null, true, false come first, then numbers, strings,
+// arrays, then objects
+// null/undefined/NaN/Infinity/-Infinity are all considered null
+function collationIndex(x) {
+ var id = ['boolean', 'number', 'string', 'object'];
+ var idx = id.indexOf(typeof x);
+ //false if -1 otherwise true, but fast!!!!1
+ if (~idx) {
+ if (x === null) {
+ return 1;
+ }
+ if (Array.isArray(x)) {
+ return 5;
+ }
+ return idx < 3 ? (idx + 2) : (idx + 3);
+ }
+ /* istanbul ignore next */
+ if (Array.isArray(x)) {
+ return 5;
+ }
+}
+
+// conversion:
+// x yyy zz...zz
+// x = 0 for negative, 1 for 0, 2 for positive
+// y = exponent (for negative numbers negated) moved so that it's >= 0
+// z = mantisse
+function numToIndexableString(num) {
+
+ if (num === 0) {
+ return '1';
+ }
+
+ // convert number to exponential format for easier and
+ // more succinct string sorting
+ var expFormat = num.toExponential().split(/e\+?/);
+ var magnitude = parseInt(expFormat[1], 10);
+
+ var neg = num < 0;
+
+ var result = neg ? '0' : '2';
+
+ // first sort by magnitude
+ // it's easier if all magnitudes are positive
+ var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE);
+ var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS);
+
+ result += SEP + magString;
+
+ // then sort by the factor
+ var factor = Math.abs(parseFloat(expFormat[0])); // [1..10)
+ /* istanbul ignore next */
+ if (neg) { // for negative reverse ordering
+ factor = 10 - factor;
+ }
+
+ var factorStr = factor.toFixed(20);
+
+ // strip zeros from the end
+ factorStr = factorStr.replace(/\.?0+$/, '');
+
+ result += SEP + factorStr;
+
+ return result;
+}
+
+// create a comparator based on the sort object
+function createFieldSorter(sort) {
+
+ function getFieldValuesAsArray(doc) {
+ return sort.map(function (sorting) {
+ var fieldName = getKey(sorting);
+ var parsedField = parseField(fieldName);
+ var docFieldValue = getFieldFromDoc(doc, parsedField);
+ return docFieldValue;
+ });
+ }
+
+ return function (aRow, bRow) {
+ var aFieldValues = getFieldValuesAsArray(aRow.doc);
+ var bFieldValues = getFieldValuesAsArray(bRow.doc);
+ var collation = collate(aFieldValues, bFieldValues);
+ if (collation !== 0) {
+ return collation;
+ }
+ // this is what mango seems to do
+ return compare$1(aRow.doc._id, bRow.doc._id);
+ };
+}
+
+function filterInMemoryFields(rows, requestDef, inMemoryFields) {
+ rows = rows.filter(function (row) {
+ return rowFilter(row.doc, requestDef.selector, inMemoryFields);
+ });
+
+ if (requestDef.sort) {
+ // in-memory sort
+ var fieldSorter = createFieldSorter(requestDef.sort);
+ rows = rows.sort(fieldSorter);
+ if (typeof requestDef.sort[0] !== 'string' &&
+ getValue(requestDef.sort[0]) === 'desc') {
+ rows = rows.reverse();
+ }
+ }
+
+ if ('limit' in requestDef || 'skip' in requestDef) {
+ // have to do the limit in-memory
+ var skip = requestDef.skip || 0;
+ var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip;
+ rows = rows.slice(skip, limit);
+ }
+ return rows;
+}
+
+function rowFilter(doc, selector, inMemoryFields) {
+ return inMemoryFields.every(function (field) {
+ var matcher = selector[field];
+ var parsedField = parseField(field);
+ var docFieldValue = getFieldFromDoc(doc, parsedField);
+ if (isCombinationalField(field)) {
+ return matchCominationalSelector(field, matcher, doc);
+ }
+
+ return matchSelector(matcher, doc, parsedField, docFieldValue);
+ });
+}
+
+function matchSelector(matcher, doc, parsedField, docFieldValue) {
+ if (!matcher) {
+ // no filtering necessary; this field is just needed for sorting
+ return true;
+ }
+
+ // is matcher an object, if so continue recursion
+ if (typeof matcher === 'object') {
+ return Object.keys(matcher).every(function (userOperator) {
+ var userValue = matcher[userOperator];
+ return match(userOperator, doc, userValue, parsedField, docFieldValue);
+ });
+ }
+
+ // no more depth, No need to recurse further
+ return matcher === docFieldValue;
+}
+
+function matchCominationalSelector(field, matcher, doc) {
+
+ if (field === '$or') {
+ return matcher.some(function (orMatchers) {
+ return rowFilter(doc, orMatchers, Object.keys(orMatchers));
+ });
+ }
+
+ if (field === '$not') {
+ return !rowFilter(doc, matcher, Object.keys(matcher));
+ }
+
+ //`$nor`
+ return !matcher.find(function (orMatchers) {
+ return rowFilter(doc, orMatchers, Object.keys(orMatchers));
+ });
+
+}
+
+function match(userOperator, doc, userValue, parsedField, docFieldValue) {
+ if (!matchers[userOperator]) {
+ throw new Error('unknown operator "' + userOperator +
+ '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' +
+ '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all');
+ }
+ return matchers[userOperator](doc, userValue, parsedField, docFieldValue);
+}
+
+function fieldExists(docFieldValue) {
+ return typeof docFieldValue !== 'undefined' && docFieldValue !== null;
+}
+
+function fieldIsNotUndefined(docFieldValue) {
+ return typeof docFieldValue !== 'undefined';
+}
+
+function modField(docFieldValue, userValue) {
+ var divisor = userValue[0];
+ var mod = userValue[1];
+ if (divisor === 0) {
+ throw new Error('Bad divisor, cannot divide by zero');
+ }
+
+ if (parseInt(divisor, 10) !== divisor ) {
+ throw new Error('Divisor is not an integer');
+ }
+
+ if (parseInt(mod, 10) !== mod ) {
+ throw new Error('Modulus is not an integer');
+ }
+
+ if (parseInt(docFieldValue, 10) !== docFieldValue) {
+ return false;
+ }
+
+ return docFieldValue % divisor === mod;
+}
+
+function arrayContainsValue(docFieldValue, userValue) {
+ return userValue.some(function (val) {
+ if (docFieldValue instanceof Array) {
+ return docFieldValue.indexOf(val) > -1;
+ }
+
+ return docFieldValue === val;
+ });
+}
+
+function arrayContainsAllValues(docFieldValue, userValue) {
+ return userValue.every(function (val) {
+ return docFieldValue.indexOf(val) > -1;
+ });
+}
+
+function arraySize(docFieldValue, userValue) {
+ return docFieldValue.length === userValue;
+}
+
+function regexMatch(docFieldValue, userValue) {
+ var re = new RegExp(userValue);
+
+ return re.test(docFieldValue);
+}
+
+function typeMatch(docFieldValue, userValue) {
+
+ switch (userValue) {
+ case 'null':
+ return docFieldValue === null;
+ case 'boolean':
+ return typeof (docFieldValue) === 'boolean';
+ case 'number':
+ return typeof (docFieldValue) === 'number';
+ case 'string':
+ return typeof (docFieldValue) === 'string';
+ case 'array':
+ return docFieldValue instanceof Array;
+ case 'object':
+ return ({}).toString.call(docFieldValue) === '[object Object]';
+ }
+
+ throw new Error(userValue + ' not supported as a type.' +
+ 'Please use one of object, string, array, number, boolean or null.');
+
+}
+
+var matchers = {
+
+ '$elemMatch': function (doc, userValue, parsedField, docFieldValue) {
+ if (!Array.isArray(docFieldValue)) {
+ return false;
+ }
+
+ if (docFieldValue.length === 0) {
+ return false;
+ }
+
+ if (typeof docFieldValue[0] === 'object') {
+ return docFieldValue.some(function (val) {
+ return rowFilter(val, userValue, Object.keys(userValue));
+ });
+ }
+
+ return docFieldValue.some(function (val) {
+ return matchSelector(userValue, doc, parsedField, val);
+ });
+ },
+
+ '$allMatch': function (doc, userValue, parsedField, docFieldValue) {
+ if (!Array.isArray(docFieldValue)) {
+ return false;
+ }
+
+ /* istanbul ignore next */
+ if (docFieldValue.length === 0) {
+ return false;
+ }
+
+ if (typeof docFieldValue[0] === 'object') {
+ return docFieldValue.every(function (val) {
+ return rowFilter(val, userValue, Object.keys(userValue));
+ });
+ }
+
+ return docFieldValue.every(function (val) {
+ return matchSelector(userValue, doc, parsedField, val);
+ });
+ },
+
+ '$eq': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) === 0;
+ },
+
+ '$gte': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) >= 0;
+ },
+
+ '$gt': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) > 0;
+ },
+
+ '$lte': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) <= 0;
+ },
+
+ '$lt': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) < 0;
+ },
+
+ '$exists': function (doc, userValue, parsedField, docFieldValue) {
+ //a field that is null is still considered to exist
+ if (userValue) {
+ return fieldIsNotUndefined(docFieldValue);
+ }
+
+ return !fieldIsNotUndefined(docFieldValue);
+ },
+
+ '$mod': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && modField(docFieldValue, userValue);
+ },
+
+ '$ne': function (doc, userValue, parsedField, docFieldValue) {
+ return userValue.every(function (neValue) {
+ return collate(docFieldValue, neValue) !== 0;
+ });
+ },
+ '$in': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue);
+ },
+
+ '$nin': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue);
+ },
+
+ '$size': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue);
+ },
+
+ '$all': function (doc, userValue, parsedField, docFieldValue) {
+ return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue);
+ },
+
+ '$regex': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue);
+ },
+
+ '$type': function (doc, userValue, parsedField, docFieldValue) {
+ return typeMatch(docFieldValue, userValue);
+ }
+};
+
+// return true if the given doc matches the supplied selector
+function matchesSelector(doc, selector) {
+ /* istanbul ignore if */
+ if (typeof selector !== 'object') {
+ // match the CouchDB error message
+ throw new Error('Selector error: expected a JSON object');
+ }
+
+ selector = massageSelector(selector);
+ var row = {
+ 'doc': doc
+ };
+
+ var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector));
+ return rowsMatched && rowsMatched.length === 1;
+}
+
+function evalFilter(input) {
+ return scopeEval('"use strict";\nreturn ' + input + ';', {});
+}
+
+function evalView(input) {
+ var code = [
+ 'return function(doc) {',
+ ' "use strict";',
+ ' var emitted = false;',
+ ' var emit = function (a, b) {',
+ ' emitted = true;',
+ ' };',
+ ' var view = ' + input + ';',
+ ' view(doc);',
+ ' if (emitted) {',
+ ' return true;',
+ ' }',
+ '};'
+ ].join('\n');
+
+ return scopeEval(code, {});
+}
+
+function validate(opts, callback) {
+ if (opts.selector) {
+ if (opts.filter && opts.filter !== '_selector') {
+ var filterName = typeof opts.filter === 'string' ?
+ opts.filter : 'function';
+ return callback(new Error('selector invalid for filter "' + filterName + '"'));
+ }
+ }
+ callback();
+}
+
+function normalize(opts) {
+ if (opts.view && !opts.filter) {
+ opts.filter = '_view';
+ }
+
+ if (opts.selector && !opts.filter) {
+ opts.filter = '_selector';
+ }
+
+ if (opts.filter && typeof opts.filter === 'string') {
+ if (opts.filter === '_view') {
+ opts.view = normalizeDesignDocFunctionName(opts.view);
+ } else {
+ opts.filter = normalizeDesignDocFunctionName(opts.filter);
+ }
+ }
+}
+
+function shouldFilter(changesHandler, opts) {
+ return opts.filter && typeof opts.filter === 'string' &&
+ !opts.doc_ids && !isRemote(changesHandler.db);
+}
+
+function filter(changesHandler, opts) {
+ var callback = opts.complete;
+ if (opts.filter === '_view') {
+ if (!opts.view || typeof opts.view !== 'string') {
+ var err = createError(BAD_REQUEST,
+ '`view` filter parameter not found or invalid.');
+ return callback(err);
+ }
+ // fetch a view from a design doc, make it behave like a filter
+ var viewName = parseDesignDocFunctionName(opts.view);
+ changesHandler.db.get('_design/' + viewName[0], function (err, ddoc) {
+ /* istanbul ignore if */
+ if (changesHandler.isCancelled) {
+ return callback(null, {status: 'cancelled'});
+ }
+ /* istanbul ignore next */
+ if (err) {
+ return callback(generateErrorFromResponse(err));
+ }
+ var mapFun = ddoc && ddoc.views && ddoc.views[viewName[1]] &&
+ ddoc.views[viewName[1]].map;
+ if (!mapFun) {
+ return callback(createError(MISSING_DOC,
+ (ddoc.views ? 'missing json key: ' + viewName[1] :
+ 'missing json key: views')));
+ }
+ opts.filter = evalView(mapFun);
+ changesHandler.doChanges(opts);
+ });
+ } else if (opts.selector) {
+ opts.filter = function (doc) {
+ return matchesSelector(doc, opts.selector);
+ };
+ changesHandler.doChanges(opts);
+ } else {
+ // fetch a filter from a design doc
+ var filterName = parseDesignDocFunctionName(opts.filter);
+ changesHandler.db.get('_design/' + filterName[0], function (err, ddoc) {
+ /* istanbul ignore if */
+ if (changesHandler.isCancelled) {
+ return callback(null, {status: 'cancelled'});
+ }
+ /* istanbul ignore next */
+ if (err) {
+ return callback(generateErrorFromResponse(err));
+ }
+ var filterFun = ddoc && ddoc.filters && ddoc.filters[filterName[1]];
+ if (!filterFun) {
+ return callback(createError(MISSING_DOC,
+ ((ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1]
+ : 'missing json key: filters')));
+ }
+ opts.filter = evalFilter(filterFun);
+ changesHandler.doChanges(opts);
+ });
+ }
+}
+
+function applyChangesFilterPlugin(PouchDB) {
+ PouchDB._changesFilterPlugin = {
+ validate: validate,
+ normalize: normalize,
+ shouldFilter: shouldFilter,
+ filter: filter
+ };
+}
+
+// TODO: remove from pouchdb-core (breaking)
+PouchDB.plugin(applyChangesFilterPlugin);
+
+PouchDB.version = version;
+
+function toObject(array) {
+ return array.reduce(function (obj, item) {
+ obj[item] = true;
+ return obj;
+ }, {});
+}
+// List of top level reserved words for doc
+var reservedWords = toObject([
+ '_id',
+ '_rev',
+ '_attachments',
+ '_deleted',
+ '_revisions',
+ '_revs_info',
+ '_conflicts',
+ '_deleted_conflicts',
+ '_local_seq',
+ '_rev_tree',
+ //replication documents
+ '_replication_id',
+ '_replication_state',
+ '_replication_state_time',
+ '_replication_state_reason',
+ '_replication_stats',
+ // Specific to Couchbase Sync Gateway
+ '_removed'
+]);
+
+// List of reserved words that should end up the document
+var dataWords = toObject([
+ '_attachments',
+ //replication documents
+ '_replication_id',
+ '_replication_state',
+ '_replication_state_time',
+ '_replication_state_reason',
+ '_replication_stats'
+]);
+
+function parseRevisionInfo(rev$$1) {
+ if (!/^\d+-./.test(rev$$1)) {
+ return createError(INVALID_REV);
+ }
+ var idx = rev$$1.indexOf('-');
+ var left = rev$$1.substring(0, idx);
+ var right = rev$$1.substring(idx + 1);
+ return {
+ prefix: parseInt(left, 10),
+ id: right
+ };
+}
+
+function makeRevTreeFromRevisions(revisions, opts) {
+ var pos = revisions.start - revisions.ids.length + 1;
+
+ var revisionIds = revisions.ids;
+ var ids = [revisionIds[0], opts, []];
+
+ for (var i = 1, len = revisionIds.length; i < len; i++) {
+ ids = [revisionIds[i], {status: 'missing'}, [ids]];
+ }
+
+ return [{
+ pos: pos,
+ ids: ids
+ }];
+}
+
+// Preprocess documents, parse their revisions, assign an id and a
+// revision for new writes that are missing them, etc
+function parseDoc(doc, newEdits, dbOpts) {
+ if (!dbOpts) {
+ dbOpts = {
+ deterministic_revs: true
+ };
+ }
+
+ var nRevNum;
+ var newRevId;
+ var revInfo;
+ var opts = {status: 'available'};
+ if (doc._deleted) {
+ opts.deleted = true;
+ }
+
+ if (newEdits) {
+ if (!doc._id) {
+ doc._id = uuid();
+ }
+ newRevId = rev(doc, dbOpts.deterministic_revs);
+ if (doc._rev) {
+ revInfo = parseRevisionInfo(doc._rev);
+ if (revInfo.error) {
+ return revInfo;
+ }
+ doc._rev_tree = [{
+ pos: revInfo.prefix,
+ ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]]
+ }];
+ nRevNum = revInfo.prefix + 1;
+ } else {
+ doc._rev_tree = [{
+ pos: 1,
+ ids : [newRevId, opts, []]
+ }];
+ nRevNum = 1;
+ }
+ } else {
+ if (doc._revisions) {
+ doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts);
+ nRevNum = doc._revisions.start;
+ newRevId = doc._revisions.ids[0];
+ }
+ if (!doc._rev_tree) {
+ revInfo = parseRevisionInfo(doc._rev);
+ if (revInfo.error) {
+ return revInfo;
+ }
+ nRevNum = revInfo.prefix;
+ newRevId = revInfo.id;
+ doc._rev_tree = [{
+ pos: nRevNum,
+ ids: [newRevId, opts, []]
+ }];
+ }
+ }
+
+ invalidIdError(doc._id);
+
+ doc._rev = nRevNum + '-' + newRevId;
+
+ var result = {metadata : {}, data : {}};
+ for (var key in doc) {
+ /* istanbul ignore else */
+ if (Object.prototype.hasOwnProperty.call(doc, key)) {
+ var specialKey = key[0] === '_';
+ if (specialKey && !reservedWords[key]) {
+ var error = createError(DOC_VALIDATION, key);
+ error.message = DOC_VALIDATION.message + ': ' + key;
+ throw error;
+ } else if (specialKey && !dataWords[key]) {
+ result.metadata[key.slice(1)] = doc[key];
+ } else {
+ result.data[key] = doc[key];
+ }
+ }
+ }
+ return result;
+}
+
+function parseBase64(data) {
+ try {
+ return thisAtob(data);
+ } catch (e) {
+ var err = createError(BAD_ARG,
+ 'Attachment is not a valid base64 string');
+ return {error: err};
+ }
+}
+
+function preprocessString(att, blobType, callback) {
+ var asBinary = parseBase64(att.data);
+ if (asBinary.error) {
+ return callback(asBinary.error);
+ }
+
+ att.length = asBinary.length;
+ if (blobType === 'blob') {
+ att.data = binStringToBluffer(asBinary, att.content_type);
+ } else if (blobType === 'base64') {
+ att.data = thisBtoa(asBinary);
+ } else { // binary
+ att.data = asBinary;
+ }
+ binaryMd5(asBinary, function (result) {
+ att.digest = 'md5-' + result;
+ callback();
+ });
+}
+
+function preprocessBlob(att, blobType, callback) {
+ binaryMd5(att.data, function (md5) {
+ att.digest = 'md5-' + md5;
+ // size is for blobs (browser), length is for buffers (node)
+ att.length = att.data.size || att.data.length || 0;
+ if (blobType === 'binary') {
+ blobToBinaryString(att.data, function (binString) {
+ att.data = binString;
+ callback();
+ });
+ } else if (blobType === 'base64') {
+ blobToBase64(att.data, function (b64) {
+ att.data = b64;
+ callback();
+ });
+ } else {
+ callback();
+ }
+ });
+}
+
+function preprocessAttachment(att, blobType, callback) {
+ if (att.stub) {
+ return callback();
+ }
+ if (typeof att.data === 'string') { // input is a base64 string
+ preprocessString(att, blobType, callback);
+ } else { // input is a blob
+ preprocessBlob(att, blobType, callback);
+ }
+}
+
+function preprocessAttachments(docInfos, blobType, callback) {
+
+ if (!docInfos.length) {
+ return callback();
+ }
+
+ var docv = 0;
+ var overallErr;
+
+ docInfos.forEach(function (docInfo) {
+ var attachments = docInfo.data && docInfo.data._attachments ?
+ Object.keys(docInfo.data._attachments) : [];
+ var recv = 0;
+
+ if (!attachments.length) {
+ return done();
+ }
+
+ function processedAttachment(err) {
+ overallErr = err;
+ recv++;
+ if (recv === attachments.length) {
+ done();
+ }
+ }
+
+ for (var key in docInfo.data._attachments) {
+ if (docInfo.data._attachments.hasOwnProperty(key)) {
+ preprocessAttachment(docInfo.data._attachments[key],
+ blobType, processedAttachment);
+ }
+ }
+ });
+
+ function done() {
+ docv++;
+ if (docInfos.length === docv) {
+ if (overallErr) {
+ callback(overallErr);
+ } else {
+ callback();
+ }
+ }
+ }
+}
+
+function updateDoc(revLimit, prev, docInfo, results,
+ i, cb, writeDoc, newEdits) {
+
+ if (revExists(prev.rev_tree, docInfo.metadata.rev) && !newEdits) {
+ results[i] = docInfo;
+ return cb();
+ }
+
+ // sometimes this is pre-calculated. historically not always
+ var previousWinningRev = prev.winningRev || winningRev(prev);
+ var previouslyDeleted = 'deleted' in prev ? prev.deleted :
+ isDeleted(prev, previousWinningRev);
+ var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted :
+ isDeleted(docInfo.metadata);
+ var isRoot = /^1-/.test(docInfo.metadata.rev);
+
+ if (previouslyDeleted && !deleted && newEdits && isRoot) {
+ var newDoc = docInfo.data;
+ newDoc._rev = previousWinningRev;
+ newDoc._id = docInfo.metadata.id;
+ docInfo = parseDoc(newDoc, newEdits);
+ }
+
+ var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);
+
+ var inConflict = newEdits && ((
+ (previouslyDeleted && deleted && merged.conflicts !== 'new_leaf') ||
+ (!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
+ (previouslyDeleted && !deleted && merged.conflicts === 'new_branch')));
+
+ if (inConflict) {
+ var err = createError(REV_CONFLICT);
+ results[i] = err;
+ return cb();
+ }
+
+ var newRev = docInfo.metadata.rev;
+ docInfo.metadata.rev_tree = merged.tree;
+ docInfo.stemmedRevs = merged.stemmedRevs || [];
+ /* istanbul ignore else */
+ if (prev.rev_map) {
+ docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb
+ }
+
+ // recalculate
+ var winningRev$$1 = winningRev(docInfo.metadata);
+ var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$1);
+
+ // calculate the total number of documents that were added/removed,
+ // from the perspective of total_rows/doc_count
+ var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 :
+ previouslyDeleted < winningRevIsDeleted ? -1 : 1;
+
+ var newRevIsDeleted;
+ if (newRev === winningRev$$1) {
+ // if the new rev is the same as the winning rev, we can reuse that value
+ newRevIsDeleted = winningRevIsDeleted;
+ } else {
+ // if they're not the same, then we need to recalculate
+ newRevIsDeleted = isDeleted(docInfo.metadata, newRev);
+ }
+
+ writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted,
+ true, delta, i, cb);
+}
+
+function rootIsMissing(docInfo) {
+ return docInfo.metadata.rev_tree[0].ids[1].status === 'missing';
+}
+
+function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results,
+ writeDoc, opts, overallCallback) {
+
+ // Default to 1000 locally
+ revLimit = revLimit || 1000;
+
+ function insertDoc(docInfo, resultsIdx, callback) {
+ // Cant insert new deleted documents
+ var winningRev$$1 = winningRev(docInfo.metadata);
+ var deleted = isDeleted(docInfo.metadata, winningRev$$1);
+ if ('was_delete' in opts && deleted) {
+ results[resultsIdx] = createError(MISSING_DOC, 'deleted');
+ return callback();
+ }
+
+ // 4712 - detect whether a new document was inserted with a _rev
+ var inConflict = newEdits && rootIsMissing(docInfo);
+
+ if (inConflict) {
+ var err = createError(REV_CONFLICT);
+ results[resultsIdx] = err;
+ return callback();
+ }
+
+ var delta = deleted ? 0 : 1;
+
+ writeDoc(docInfo, winningRev$$1, deleted, deleted, false,
+ delta, resultsIdx, callback);
+ }
+
+ var newEdits = opts.new_edits;
+ var idsToDocs = new ExportedMap();
+
+ var docsDone = 0;
+ var docsToDo = docInfos.length;
+
+ function checkAllDocsDone() {
+ if (++docsDone === docsToDo && overallCallback) {
+ overallCallback();
+ }
+ }
+
+ docInfos.forEach(function (currentDoc, resultsIdx) {
+
+ if (currentDoc._id && isLocalId(currentDoc._id)) {
+ var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal';
+ api[fun](currentDoc, {ctx: tx}, function (err, res) {
+ results[resultsIdx] = err || res;
+ checkAllDocsDone();
+ });
+ return;
+ }
+
+ var id = currentDoc.metadata.id;
+ if (idsToDocs.has(id)) {
+ docsToDo--; // duplicate
+ idsToDocs.get(id).push([currentDoc, resultsIdx]);
+ } else {
+ idsToDocs.set(id, [[currentDoc, resultsIdx]]);
+ }
+ });
+
+ // in the case of new_edits, the user can provide multiple docs
+ // with the same id. these need to be processed sequentially
+ idsToDocs.forEach(function (docs, id) {
+ var numDone = 0;
+
+ function docWritten() {
+ if (++numDone < docs.length) {
+ nextDoc();
+ } else {
+ checkAllDocsDone();
+ }
+ }
+ function nextDoc() {
+ var value = docs[numDone];
+ var currentDoc = value[0];
+ var resultsIdx = value[1];
+
+ if (fetchedDocs.has(id)) {
+ updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results,
+ resultsIdx, docWritten, writeDoc, newEdits);
+ } else {
+ // Ensure stemming applies to new writes as well
+ var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit);
+ currentDoc.metadata.rev_tree = merged.tree;
+ currentDoc.stemmedRevs = merged.stemmedRevs || [];
+ insertDoc(currentDoc, resultsIdx, docWritten);
+ }
+ }
+ nextDoc();
+ });
+}
+
+// IndexedDB requires a versioned database structure, so we use the
+// version here to manage migrations.
+var ADAPTER_VERSION = 5;
+
+// The object stores created for each database
+// DOC_STORE stores the document meta data, its revision history and state
+// Keyed by document id
+var DOC_STORE = 'document-store';
+// BY_SEQ_STORE stores a particular version of a document, keyed by its
+// sequence id
+var BY_SEQ_STORE = 'by-sequence';
+// Where we store attachments
+var ATTACH_STORE = 'attach-store';
+// Where we store many-to-many relations
+// between attachment digests and seqs
+var ATTACH_AND_SEQ_STORE = 'attach-seq-store';
+
+// Where we store database-wide meta data in a single record
+// keyed by id: META_STORE
+var META_STORE = 'meta-store';
+// Where we store local documents
+var LOCAL_STORE = 'local-store';
+// Where we detect blob support
+var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support';
+
+function safeJsonParse(str) {
+ // This try/catch guards against stack overflow errors.
+ // JSON.parse() is faster than vuvuzela.parse() but vuvuzela
+ // cannot overflow.
+ try {
+ return JSON.parse(str);
+ } catch (e) {
+ /* istanbul ignore next */
+ return vuvuzela.parse(str);
+ }
+}
+
+function safeJsonStringify(json) {
+ try {
+ return JSON.stringify(json);
+ } catch (e) {
+ /* istanbul ignore next */
+ return vuvuzela.stringify(json);
+ }
+}
+
+function idbError(callback) {
+ return function (evt) {
+ var message = 'unknown_error';
+ if (evt.target && evt.target.error) {
+ message = evt.target.error.name || evt.target.error.message;
+ }
+ callback(createError(IDB_ERROR, message, evt.type));
+ };
+}
+
+// Unfortunately, the metadata has to be stringified
+// when it is put into the database, because otherwise
+// IndexedDB can throw errors for deeply-nested objects.
+// Originally we just used JSON.parse/JSON.stringify; now
+// we use this custom vuvuzela library that avoids recursion.
+// If we could do it all over again, we'd probably use a
+// format for the revision trees other than JSON.
+function encodeMetadata(metadata, winningRev, deleted) {
+ return {
+ data: safeJsonStringify(metadata),
+ winningRev: winningRev,
+ deletedOrLocal: deleted ? '1' : '0',
+ seq: metadata.seq, // highest seq for this doc
+ id: metadata.id
+ };
+}
+
+function decodeMetadata(storedObject) {
+ if (!storedObject) {
+ return null;
+ }
+ var metadata = safeJsonParse(storedObject.data);
+ metadata.winningRev = storedObject.winningRev;
+ metadata.deleted = storedObject.deletedOrLocal === '1';
+ metadata.seq = storedObject.seq;
+ return metadata;
+}
+
+// read the doc back out from the database. we don't store the
+// _id or _rev because we already have _doc_id_rev.
+function decodeDoc(doc) {
+ if (!doc) {
+ return doc;
+ }
+ var idx = doc._doc_id_rev.lastIndexOf(':');
+ doc._id = doc._doc_id_rev.substring(0, idx - 1);
+ doc._rev = doc._doc_id_rev.substring(idx + 1);
+ delete doc._doc_id_rev;
+ return doc;
+}
+
+// Read a blob from the database, encoding as necessary
+// and translating from base64 if the IDB doesn't support
+// native Blobs
+function readBlobData(body, type, asBlob, callback) {
+ if (asBlob) {
+ if (!body) {
+ callback(createBlob([''], {type: type}));
+ } else if (typeof body !== 'string') { // we have blob support
+ callback(body);
+ } else { // no blob support
+ callback(b64ToBluffer(body, type));
+ }
+ } else { // as base64 string
+ if (!body) {
+ callback('');
+ } else if (typeof body !== 'string') { // we have blob support
+ readAsBinaryString(body, function (binary) {
+ callback(thisBtoa(binary));
+ });
+ } else { // no blob support
+ callback(body);
+ }
+ }
+}
+
+function fetchAttachmentsIfNecessary(doc, opts, txn, cb) {
+ var attachments = Object.keys(doc._attachments || {});
+ if (!attachments.length) {
+ return cb && cb();
+ }
+ var numDone = 0;
+
+ function checkDone() {
+ if (++numDone === attachments.length && cb) {
+ cb();
+ }
+ }
+
+ function fetchAttachment(doc, att) {
+ var attObj = doc._attachments[att];
+ var digest = attObj.digest;
+ var req = txn.objectStore(ATTACH_STORE).get(digest);
+ req.onsuccess = function (e) {
+ attObj.body = e.target.result.body;
+ checkDone();
+ };
+ }
+
+ attachments.forEach(function (att) {
+ if (opts.attachments && opts.include_docs) {
+ fetchAttachment(doc, att);
+ } else {
+ doc._attachments[att].stub = true;
+ checkDone();
+ }
+ });
+}
+
+// IDB-specific postprocessing necessary because
+// we don't know whether we stored a true Blob or
+// a base64-encoded string, and if it's a Blob it
+// needs to be read outside of the transaction context
+function postProcessAttachments(results, asBlob) {
+ return Promise.all(results.map(function (row) {
+ if (row.doc && row.doc._attachments) {
+ var attNames = Object.keys(row.doc._attachments);
+ return Promise.all(attNames.map(function (att) {
+ var attObj = row.doc._attachments[att];
+ if (!('body' in attObj)) { // already processed
+ return;
+ }
+ var body = attObj.body;
+ var type = attObj.content_type;
+ return new Promise(function (resolve) {
+ readBlobData(body, type, asBlob, function (data) {
+ row.doc._attachments[att] = $inject_Object_assign(
+ pick(attObj, ['digest', 'content_type']),
+ {data: data}
+ );
+ resolve();
+ });
+ });
+ }));
+ }
+ }));
+}
+
+function compactRevs(revs, docId, txn) {
+
+ var possiblyOrphanedDigests = [];
+ var seqStore = txn.objectStore(BY_SEQ_STORE);
+ var attStore = txn.objectStore(ATTACH_STORE);
+ var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+ var count = revs.length;
+
+ function checkDone() {
+ count--;
+ if (!count) { // done processing all revs
+ deleteOrphanedAttachments();
+ }
+ }
+
+ function deleteOrphanedAttachments() {
+ if (!possiblyOrphanedDigests.length) {
+ return;
+ }
+ possiblyOrphanedDigests.forEach(function (digest) {
+ var countReq = attAndSeqStore.index('digestSeq').count(
+ IDBKeyRange.bound(
+ digest + '::', digest + '::\uffff', false, false));
+ countReq.onsuccess = function (e) {
+ var count = e.target.result;
+ if (!count) {
+ // orphaned
+ attStore["delete"](digest);
+ }
+ };
+ });
+ }
+
+ revs.forEach(function (rev$$1) {
+ var index = seqStore.index('_doc_id_rev');
+ var key = docId + "::" + rev$$1;
+ index.getKey(key).onsuccess = function (e) {
+ var seq = e.target.result;
+ if (typeof seq !== 'number') {
+ return checkDone();
+ }
+ seqStore["delete"](seq);
+
+ var cursor = attAndSeqStore.index('seq')
+ .openCursor(IDBKeyRange.only(seq));
+
+ cursor.onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ var digest = cursor.value.digestSeq.split('::')[0];
+ possiblyOrphanedDigests.push(digest);
+ attAndSeqStore["delete"](cursor.primaryKey);
+ cursor["continue"]();
+ } else { // done
+ checkDone();
+ }
+ };
+ };
+ });
+}
+
+function openTransactionSafely(idb, stores, mode) {
+ try {
+ return {
+ txn: idb.transaction(stores, mode)
+ };
+ } catch (err) {
+ return {
+ error: err
+ };
+ }
+}
+
+var changesHandler = new Changes();
+
+function idbBulkDocs(dbOpts, req, opts, api, idb, callback) {
+ var docInfos = req.docs;
+ var txn;
+ var docStore;
+ var bySeqStore;
+ var attachStore;
+ var attachAndSeqStore;
+ var metaStore;
+ var docInfoError;
+ var metaDoc;
+
+ for (var i = 0, len = docInfos.length; i < len; i++) {
+ var doc = docInfos[i];
+ if (doc._id && isLocalId(doc._id)) {
+ continue;
+ }
+ doc = docInfos[i] = parseDoc(doc, opts.new_edits, dbOpts);
+ if (doc.error && !docInfoError) {
+ docInfoError = doc;
+ }
+ }
+
+ if (docInfoError) {
+ return callback(docInfoError);
+ }
+
+ var allDocsProcessed = false;
+ var docCountDelta = 0;
+ var results = new Array(docInfos.length);
+ var fetchedDocs = new ExportedMap();
+ var preconditionErrored = false;
+ var blobType = api._meta.blobSupport ? 'blob' : 'base64';
+
+ preprocessAttachments(docInfos, blobType, function (err) {
+ if (err) {
+ return callback(err);
+ }
+ startTransaction();
+ });
+
+ function startTransaction() {
+
+ var stores = [
+ DOC_STORE, BY_SEQ_STORE,
+ ATTACH_STORE,
+ LOCAL_STORE, ATTACH_AND_SEQ_STORE,
+ META_STORE
+ ];
+ var txnResult = openTransactionSafely(idb, stores, 'readwrite');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ txn = txnResult.txn;
+ txn.onabort = idbError(callback);
+ txn.ontimeout = idbError(callback);
+ txn.oncomplete = complete;
+ docStore = txn.objectStore(DOC_STORE);
+ bySeqStore = txn.objectStore(BY_SEQ_STORE);
+ attachStore = txn.objectStore(ATTACH_STORE);
+ attachAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+ metaStore = txn.objectStore(META_STORE);
+
+ metaStore.get(META_STORE).onsuccess = function (e) {
+ metaDoc = e.target.result;
+ updateDocCountIfReady();
+ };
+
+ verifyAttachments(function (err) {
+ if (err) {
+ preconditionErrored = true;
+ return callback(err);
+ }
+ fetchExistingDocs();
+ });
+ }
+
+ function onAllDocsProcessed() {
+ allDocsProcessed = true;
+ updateDocCountIfReady();
+ }
+
+ function idbProcessDocs() {
+ processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs,
+ txn, results, writeDoc, opts, onAllDocsProcessed);
+ }
+
+ function updateDocCountIfReady() {
+ if (!metaDoc || !allDocsProcessed) {
+ return;
+ }
+ // caching the docCount saves a lot of time in allDocs() and
+ // info(), which is why we go to all the trouble of doing this
+ metaDoc.docCount += docCountDelta;
+ metaStore.put(metaDoc);
+ }
+
+ function fetchExistingDocs() {
+
+ if (!docInfos.length) {
+ return;
+ }
+
+ var numFetched = 0;
+
+ function checkDone() {
+ if (++numFetched === docInfos.length) {
+ idbProcessDocs();
+ }
+ }
+
+ function readMetadata(event) {
+ var metadata = decodeMetadata(event.target.result);
+
+ if (metadata) {
+ fetchedDocs.set(metadata.id, metadata);
+ }
+ checkDone();
+ }
+
+ for (var i = 0, len = docInfos.length; i < len; i++) {
+ var docInfo = docInfos[i];
+ if (docInfo._id && isLocalId(docInfo._id)) {
+ checkDone(); // skip local docs
+ continue;
+ }
+ var req = docStore.get(docInfo.metadata.id);
+ req.onsuccess = readMetadata;
+ }
+ }
+
+ function complete() {
+ if (preconditionErrored) {
+ return;
+ }
+
+ changesHandler.notify(api._meta.name);
+ callback(null, results);
+ }
+
+ function verifyAttachment(digest, callback) {
+
+ var req = attachStore.get(digest);
+ req.onsuccess = function (e) {
+ if (!e.target.result) {
+ var err = createError(MISSING_STUB,
+ 'unknown stub attachment with digest ' +
+ digest);
+ err.status = 412;
+ callback(err);
+ } else {
+ callback();
+ }
+ };
+ }
+
+ function verifyAttachments(finish) {
+
+
+ var digests = [];
+ docInfos.forEach(function (docInfo) {
+ if (docInfo.data && docInfo.data._attachments) {
+ Object.keys(docInfo.data._attachments).forEach(function (filename) {
+ var att = docInfo.data._attachments[filename];
+ if (att.stub) {
+ digests.push(att.digest);
+ }
+ });
+ }
+ });
+ if (!digests.length) {
+ return finish();
+ }
+ var numDone = 0;
+ var err;
+
+ function checkDone() {
+ if (++numDone === digests.length) {
+ finish(err);
+ }
+ }
+ digests.forEach(function (digest) {
+ verifyAttachment(digest, function (attErr) {
+ if (attErr && !err) {
+ err = attErr;
+ }
+ checkDone();
+ });
+ });
+ }
+
+ function writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted,
+ isUpdate, delta, resultsIdx, callback) {
+
+ docInfo.metadata.winningRev = winningRev$$1;
+ docInfo.metadata.deleted = winningRevIsDeleted;
+
+ var doc = docInfo.data;
+ doc._id = docInfo.metadata.id;
+ doc._rev = docInfo.metadata.rev;
+
+ if (newRevIsDeleted) {
+ doc._deleted = true;
+ }
+
+ var hasAttachments = doc._attachments &&
+ Object.keys(doc._attachments).length;
+ if (hasAttachments) {
+ return writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback);
+ }
+
+ docCountDelta += delta;
+ updateDocCountIfReady();
+
+ finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback);
+ }
+
+ function finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback) {
+
+ var doc = docInfo.data;
+ var metadata = docInfo.metadata;
+
+ doc._doc_id_rev = metadata.id + '::' + metadata.rev;
+ delete doc._id;
+ delete doc._rev;
+
+ function afterPutDoc(e) {
+ var revsToDelete = docInfo.stemmedRevs || [];
+
+ if (isUpdate && api.auto_compaction) {
+ revsToDelete = revsToDelete.concat(compactTree(docInfo.metadata));
+ }
+
+ if (revsToDelete && revsToDelete.length) {
+ compactRevs(revsToDelete, docInfo.metadata.id, txn);
+ }
+
+ metadata.seq = e.target.result;
+ // Current _rev is calculated from _rev_tree on read
+ // delete metadata.rev;
+ var metadataToStore = encodeMetadata(metadata, winningRev$$1,
+ winningRevIsDeleted);
+ var metaDataReq = docStore.put(metadataToStore);
+ metaDataReq.onsuccess = afterPutMetadata;
+ }
+
+ function afterPutDocError(e) {
+ // ConstraintError, need to update, not put (see #1638 for details)
+ e.preventDefault(); // avoid transaction abort
+ e.stopPropagation(); // avoid transaction onerror
+ var index = bySeqStore.index('_doc_id_rev');
+ var getKeyReq = index.getKey(doc._doc_id_rev);
+ getKeyReq.onsuccess = function (e) {
+ var putReq = bySeqStore.put(doc, e.target.result);
+ putReq.onsuccess = afterPutDoc;
+ };
+ }
+
+ function afterPutMetadata() {
+ results[resultsIdx] = {
+ ok: true,
+ id: metadata.id,
+ rev: metadata.rev
+ };
+ fetchedDocs.set(docInfo.metadata.id, docInfo.metadata);
+ insertAttachmentMappings(docInfo, metadata.seq, callback);
+ }
+
+ var putReq = bySeqStore.put(doc);
+
+ putReq.onsuccess = afterPutDoc;
+ putReq.onerror = afterPutDocError;
+ }
+
+ function writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback) {
+
+
+ var doc = docInfo.data;
+
+ var numDone = 0;
+ var attachments = Object.keys(doc._attachments);
+
+ function collectResults() {
+ if (numDone === attachments.length) {
+ finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback);
+ }
+ }
+
+ function attachmentSaved() {
+ numDone++;
+ collectResults();
+ }
+
+ attachments.forEach(function (key) {
+ var att = docInfo.data._attachments[key];
+ if (!att.stub) {
+ var data = att.data;
+ delete att.data;
+ att.revpos = parseInt(winningRev$$1, 10);
+ var digest = att.digest;
+ saveAttachment(digest, data, attachmentSaved);
+ } else {
+ numDone++;
+ collectResults();
+ }
+ });
+ }
+
+ // map seqs to attachment digests, which
+ // we will need later during compaction
+ function insertAttachmentMappings(docInfo, seq, callback) {
+
+ var attsAdded = 0;
+ var attsToAdd = Object.keys(docInfo.data._attachments || {});
+
+ if (!attsToAdd.length) {
+ return callback();
+ }
+
+ function checkDone() {
+ if (++attsAdded === attsToAdd.length) {
+ callback();
+ }
+ }
+
+ function add(att) {
+ var digest = docInfo.data._attachments[att].digest;
+ var req = attachAndSeqStore.put({
+ seq: seq,
+ digestSeq: digest + '::' + seq
+ });
+
+ req.onsuccess = checkDone;
+ req.onerror = function (e) {
+ // this callback is for a constaint error, which we ignore
+ // because this docid/rev has already been associated with
+ // the digest (e.g. when new_edits == false)
+ e.preventDefault(); // avoid transaction abort
+ e.stopPropagation(); // avoid transaction onerror
+ checkDone();
+ };
+ }
+ for (var i = 0; i < attsToAdd.length; i++) {
+ add(attsToAdd[i]); // do in parallel
+ }
+ }
+
+ function saveAttachment(digest, data, callback) {
+
+
+ var getKeyReq = attachStore.count(digest);
+ getKeyReq.onsuccess = function (e) {
+ var count = e.target.result;
+ if (count) {
+ return callback(); // already exists
+ }
+ var newAtt = {
+ digest: digest,
+ body: data
+ };
+ var putReq = attachStore.put(newAtt);
+ putReq.onsuccess = callback;
+ };
+ }
+}
+
+// Abstraction over IDBCursor and getAll()/getAllKeys() that allows us to batch our operations
+// while falling back to a normal IDBCursor operation on browsers that don't support getAll() or
+// getAllKeys(). This allows for a much faster implementation than just straight-up cursors, because
+// we're not processing each document one-at-a-time.
+function runBatchedCursor(objectStore, keyRange, descending, batchSize, onBatch) {
+
+ if (batchSize === -1) {
+ batchSize = 1000;
+ }
+
+ // Bail out of getAll()/getAllKeys() in the following cases:
+ // 1) either method is unsupported - we need both
+ // 2) batchSize is 1 (might as well use IDBCursor)
+ // 3) descending – no real way to do this via getAll()/getAllKeys()
+
+ var useGetAll = typeof objectStore.getAll === 'function' &&
+ typeof objectStore.getAllKeys === 'function' &&
+ batchSize > 1 && !descending;
+
+ var keysBatch;
+ var valuesBatch;
+ var pseudoCursor;
+
+ function onGetAll(e) {
+ valuesBatch = e.target.result;
+ if (keysBatch) {
+ onBatch(keysBatch, valuesBatch, pseudoCursor);
+ }
+ }
+
+ function onGetAllKeys(e) {
+ keysBatch = e.target.result;
+ if (valuesBatch) {
+ onBatch(keysBatch, valuesBatch, pseudoCursor);
+ }
+ }
+
+ function continuePseudoCursor() {
+ if (!keysBatch.length) { // no more results
+ return onBatch();
+ }
+ // fetch next batch, exclusive start
+ var lastKey = keysBatch[keysBatch.length - 1];
+ var newKeyRange;
+ if (keyRange && keyRange.upper) {
+ try {
+ newKeyRange = IDBKeyRange.bound(lastKey, keyRange.upper,
+ true, keyRange.upperOpen);
+ } catch (e) {
+ if (e.name === "DataError" && e.code === 0) {
+ return onBatch(); // we're done, startkey and endkey are equal
+ }
+ }
+ } else {
+ newKeyRange = IDBKeyRange.lowerBound(lastKey, true);
+ }
+ keyRange = newKeyRange;
+ keysBatch = null;
+ valuesBatch = null;
+ objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll;
+ objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys;
+ }
+
+ function onCursor(e) {
+ var cursor = e.target.result;
+ if (!cursor) { // done
+ return onBatch();
+ }
+ // regular IDBCursor acts like a batch where batch size is always 1
+ onBatch([cursor.key], [cursor.value], cursor);
+ }
+
+ if (useGetAll) {
+ pseudoCursor = {"continue": continuePseudoCursor};
+ objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll;
+ objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys;
+ } else if (descending) {
+ objectStore.openCursor(keyRange, 'prev').onsuccess = onCursor;
+ } else {
+ objectStore.openCursor(keyRange).onsuccess = onCursor;
+ }
+}
+
+// simple shim for objectStore.getAll(), falling back to IDBCursor
+function getAll(objectStore, keyRange, onSuccess) {
+ if (typeof objectStore.getAll === 'function') {
+ // use native getAll
+ objectStore.getAll(keyRange).onsuccess = onSuccess;
+ return;
+ }
+ // fall back to cursors
+ var values = [];
+
+ function onCursor(e) {
+ var cursor = e.target.result;
+ if (cursor) {
+ values.push(cursor.value);
+ cursor["continue"]();
+ } else {
+ onSuccess({
+ target: {
+ result: values
+ }
+ });
+ }
+ }
+
+ objectStore.openCursor(keyRange).onsuccess = onCursor;
+}
+
+function allDocsKeys(keys, docStore, onBatch) {
+ // It's not guaranted to be returned in right order
+ var valuesBatch = new Array(keys.length);
+ var count = 0;
+ keys.forEach(function (key, index) {
+ docStore.get(key).onsuccess = function (event) {
+ if (event.target.result) {
+ valuesBatch[index] = event.target.result;
+ } else {
+ valuesBatch[index] = {key: key, error: 'not_found'};
+ }
+ count++;
+ if (count === keys.length) {
+ onBatch(keys, valuesBatch, {});
+ }
+ };
+ });
+}
+
+function createKeyRange(start, end, inclusiveEnd, key, descending) {
+ try {
+ if (start && end) {
+ if (descending) {
+ return IDBKeyRange.bound(end, start, !inclusiveEnd, false);
+ } else {
+ return IDBKeyRange.bound(start, end, false, !inclusiveEnd);
+ }
+ } else if (start) {
+ if (descending) {
+ return IDBKeyRange.upperBound(start);
+ } else {
+ return IDBKeyRange.lowerBound(start);
+ }
+ } else if (end) {
+ if (descending) {
+ return IDBKeyRange.lowerBound(end, !inclusiveEnd);
+ } else {
+ return IDBKeyRange.upperBound(end, !inclusiveEnd);
+ }
+ } else if (key) {
+ return IDBKeyRange.only(key);
+ }
+ } catch (e) {
+ return {error: e};
+ }
+ return null;
+}
+
+function idbAllDocs(opts, idb, callback) {
+ var start = 'startkey' in opts ? opts.startkey : false;
+ var end = 'endkey' in opts ? opts.endkey : false;
+ var key = 'key' in opts ? opts.key : false;
+ var keys = 'keys' in opts ? opts.keys : false;
+ var skip = opts.skip || 0;
+ var limit = typeof opts.limit === 'number' ? opts.limit : -1;
+ var inclusiveEnd = opts.inclusive_end !== false;
+
+ var keyRange ;
+ var keyRangeError;
+ if (!keys) {
+ keyRange = createKeyRange(start, end, inclusiveEnd, key, opts.descending);
+ keyRangeError = keyRange && keyRange.error;
+ if (keyRangeError &&
+ !(keyRangeError.name === "DataError" && keyRangeError.code === 0)) {
+ // DataError with error code 0 indicates start is less than end, so
+ // can just do an empty query. Else need to throw
+ return callback(createError(IDB_ERROR,
+ keyRangeError.name, keyRangeError.message));
+ }
+ }
+
+ var stores = [DOC_STORE, BY_SEQ_STORE, META_STORE];
+
+ if (opts.attachments) {
+ stores.push(ATTACH_STORE);
+ }
+ var txnResult = openTransactionSafely(idb, stores, 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var txn = txnResult.txn;
+ txn.oncomplete = onTxnComplete;
+ txn.onabort = idbError(callback);
+ var docStore = txn.objectStore(DOC_STORE);
+ var seqStore = txn.objectStore(BY_SEQ_STORE);
+ var metaStore = txn.objectStore(META_STORE);
+ var docIdRevIndex = seqStore.index('_doc_id_rev');
+ var results = [];
+ var docCount;
+ var updateSeq;
+
+ metaStore.get(META_STORE).onsuccess = function (e) {
+ docCount = e.target.result.docCount;
+ };
+
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ getMaxUpdateSeq(seqStore, function (e) {
+ if (e.target.result && e.target.result.length > 0) {
+ updateSeq = e.target.result[0];
+ }
+ });
+ }
+
+ function getMaxUpdateSeq(objectStore, onSuccess) {
+ function onCursor(e) {
+ var cursor = e.target.result;
+ var maxKey = undefined;
+ if (cursor && cursor.key) {
+ maxKey = cursor.key;
+ }
+ return onSuccess({
+ target: {
+ result: [maxKey]
+ }
+ });
+ }
+ objectStore.openCursor(null, 'prev').onsuccess = onCursor;
+ }
+
+ // if the user specifies include_docs=true, then we don't
+ // want to block the main cursor while we're fetching the doc
+ function fetchDocAsynchronously(metadata, row, winningRev$$1) {
+ var key = metadata.id + "::" + winningRev$$1;
+ docIdRevIndex.get(key).onsuccess = function onGetDoc(e) {
+ row.doc = decodeDoc(e.target.result) || {};
+ if (opts.conflicts) {
+ var conflicts = collectConflicts(metadata);
+ if (conflicts.length) {
+ row.doc._conflicts = conflicts;
+ }
+ }
+ fetchAttachmentsIfNecessary(row.doc, opts, txn);
+ };
+ }
+
+ function allDocsInner(winningRev$$1, metadata) {
+ var row = {
+ id: metadata.id,
+ key: metadata.id,
+ value: {
+ rev: winningRev$$1
+ }
+ };
+ var deleted = metadata.deleted;
+ if (deleted) {
+ if (keys) {
+ results.push(row);
+ // deleted docs are okay with "keys" requests
+ row.value.deleted = true;
+ row.doc = null;
+ }
+ } else if (skip-- <= 0) {
+ results.push(row);
+ if (opts.include_docs) {
+ fetchDocAsynchronously(metadata, row, winningRev$$1);
+ }
+ }
+ }
+
+ function processBatch(batchValues) {
+ for (var i = 0, len = batchValues.length; i < len; i++) {
+ if (results.length === limit) {
+ break;
+ }
+ var batchValue = batchValues[i];
+ if (batchValue.error && keys) {
+ // key was not found with "keys" requests
+ results.push(batchValue);
+ continue;
+ }
+ var metadata = decodeMetadata(batchValue);
+ var winningRev$$1 = metadata.winningRev;
+ allDocsInner(winningRev$$1, metadata);
+ }
+ }
+
+ function onBatch(batchKeys, batchValues, cursor) {
+ if (!cursor) {
+ return;
+ }
+ processBatch(batchValues);
+ if (results.length < limit) {
+ cursor["continue"]();
+ }
+ }
+
+ function onGetAll(e) {
+ var values = e.target.result;
+ if (opts.descending) {
+ values = values.reverse();
+ }
+ processBatch(values);
+ }
+
+ function onResultsReady() {
+ var returnVal = {
+ total_rows: docCount,
+ offset: opts.skip,
+ rows: results
+ };
+
+ /* istanbul ignore if */
+ if (opts.update_seq && updateSeq !== undefined) {
+ returnVal.update_seq = updateSeq;
+ }
+ callback(null, returnVal);
+ }
+
+ function onTxnComplete() {
+ if (opts.attachments) {
+ postProcessAttachments(results, opts.binary).then(onResultsReady);
+ } else {
+ onResultsReady();
+ }
+ }
+
+ // don't bother doing any requests if start > end or limit === 0
+ if (keyRangeError || limit === 0) {
+ return;
+ }
+ if (keys) {
+ return allDocsKeys(opts.keys, docStore, onBatch);
+ }
+ if (limit === -1) { // just fetch everything
+ return getAll(docStore, keyRange, onGetAll);
+ }
+ // else do a cursor
+ // choose a batch size based on the skip, since we'll need to skip that many
+ runBatchedCursor(docStore, keyRange, opts.descending, limit + skip, onBatch);
+}
+
+//
+// Blobs are not supported in all versions of IndexedDB, notably
+// Chrome <37 and Android <5. In those versions, storing a blob will throw.
+//
+// Various other blob bugs exist in Chrome v37-42 (inclusive).
+// Detecting them is expensive and confusing to users, and Chrome 37-42
+// is at very low usage worldwide, so we do a hacky userAgent check instead.
+//
+// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120
+// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916
+// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836
+//
+function checkBlobSupport(txn) {
+ return new Promise(function (resolve) {
+ var blob$$1 = createBlob(['']);
+ var req = txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob$$1, 'key');
+
+ req.onsuccess = function () {
+ var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/);
+ var matchedEdge = navigator.userAgent.match(/Edge\//);
+ // MS Edge pretends to be Chrome 42:
+ // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx
+ resolve(matchedEdge || !matchedChrome ||
+ parseInt(matchedChrome[1], 10) >= 43);
+ };
+
+ req.onerror = txn.onabort = function (e) {
+ // If the transaction aborts now its due to not being able to
+ // write to the database, likely due to the disk being full
+ e.preventDefault();
+ e.stopPropagation();
+ resolve(false);
+ };
+ })["catch"](function () {
+ return false; // error, so assume unsupported
+ });
+}
+
+function countDocs(txn, cb) {
+ var index = txn.objectStore(DOC_STORE).index('deletedOrLocal');
+ index.count(IDBKeyRange.only('0')).onsuccess = function (e) {
+ cb(e.target.result);
+ };
+}
+
+// This task queue ensures that IDB open calls are done in their own tick
+
+var running = false;
+var queue = [];
+
+function tryCode(fun, err, res, PouchDB) {
+ try {
+ fun(err, res);
+ } catch (err) {
+ // Shouldn't happen, but in some odd cases
+ // IndexedDB implementations might throw a sync
+ // error, in which case this will at least log it.
+ PouchDB.emit('error', err);
+ }
+}
+
+function applyNext() {
+ if (running || !queue.length) {
+ return;
+ }
+ running = true;
+ queue.shift()();
+}
+
+function enqueueTask(action, callback, PouchDB) {
+ queue.push(function runAction() {
+ action(function runCallback(err, res) {
+ tryCode(callback, err, res, PouchDB);
+ running = false;
+ immediate(function runNext() {
+ applyNext(PouchDB);
+ });
+ });
+ });
+ applyNext();
+}
+
+function changes(opts, api, dbName, idb) {
+ opts = clone(opts);
+
+ if (opts.continuous) {
+ var id = dbName + ':' + uuid();
+ changesHandler.addListener(dbName, id, api, opts);
+ changesHandler.notify(dbName);
+ return {
+ cancel: function () {
+ changesHandler.removeListener(dbName, id);
+ }
+ };
+ }
+
+ var docIds = opts.doc_ids && new ExportedSet(opts.doc_ids);
+
+ opts.since = opts.since || 0;
+ var lastSeq = opts.since;
+
+ var limit = 'limit' in opts ? opts.limit : -1;
+ if (limit === 0) {
+ limit = 1; // per CouchDB _changes spec
+ }
+
+ var results = [];
+ var numResults = 0;
+ var filter = filterChange(opts);
+ var docIdsToMetadata = new ExportedMap();
+
+ var txn;
+ var bySeqStore;
+ var docStore;
+ var docIdRevIndex;
+
+ function onBatch(batchKeys, batchValues, cursor) {
+ if (!cursor || !batchKeys.length) { // done
+ return;
+ }
+
+ var winningDocs = new Array(batchKeys.length);
+ var metadatas = new Array(batchKeys.length);
+
+ function processMetadataAndWinningDoc(metadata, winningDoc) {
+ var change = opts.processChange(winningDoc, metadata, opts);
+ lastSeq = change.seq = metadata.seq;
+
+ var filtered = filter(change);
+ if (typeof filtered === 'object') { // anything but true/false indicates error
+ return Promise.reject(filtered);
+ }
+
+ if (!filtered) {
+ return Promise.resolve();
+ }
+ numResults++;
+ if (opts.return_docs) {
+ results.push(change);
+ }
+ // process the attachment immediately
+ // for the benefit of live listeners
+ if (opts.attachments && opts.include_docs) {
+ return new Promise(function (resolve) {
+ fetchAttachmentsIfNecessary(winningDoc, opts, txn, function () {
+ postProcessAttachments([change], opts.binary).then(function () {
+ resolve(change);
+ });
+ });
+ });
+ } else {
+ return Promise.resolve(change);
+ }
+ }
+
+ function onBatchDone() {
+ var promises = [];
+ for (var i = 0, len = winningDocs.length; i < len; i++) {
+ if (numResults === limit) {
+ break;
+ }
+ var winningDoc = winningDocs[i];
+ if (!winningDoc) {
+ continue;
+ }
+ var metadata = metadatas[i];
+ promises.push(processMetadataAndWinningDoc(metadata, winningDoc));
+ }
+
+ Promise.all(promises).then(function (changes) {
+ for (var i = 0, len = changes.length; i < len; i++) {
+ if (changes[i]) {
+ opts.onChange(changes[i]);
+ }
+ }
+ })["catch"](opts.complete);
+
+ if (numResults !== limit) {
+ cursor["continue"]();
+ }
+ }
+
+ // Fetch all metadatas/winningdocs from this batch in parallel, then process
+ // them all only once all data has been collected. This is done in parallel
+ // because it's faster than doing it one-at-a-time.
+ var numDone = 0;
+ batchValues.forEach(function (value, i) {
+ var doc = decodeDoc(value);
+ var seq = batchKeys[i];
+ fetchWinningDocAndMetadata(doc, seq, function (metadata, winningDoc) {
+ metadatas[i] = metadata;
+ winningDocs[i] = winningDoc;
+ if (++numDone === batchKeys.length) {
+ onBatchDone();
+ }
+ });
+ });
+ }
+
+ function onGetMetadata(doc, seq, metadata, cb) {
+ if (metadata.seq !== seq) {
+ // some other seq is later
+ return cb();
+ }
+
+ if (metadata.winningRev === doc._rev) {
+ // this is the winning doc
+ return cb(metadata, doc);
+ }
+
+ // fetch winning doc in separate request
+ var docIdRev = doc._id + '::' + metadata.winningRev;
+ var req = docIdRevIndex.get(docIdRev);
+ req.onsuccess = function (e) {
+ cb(metadata, decodeDoc(e.target.result));
+ };
+ }
+
+ function fetchWinningDocAndMetadata(doc, seq, cb) {
+ if (docIds && !docIds.has(doc._id)) {
+ return cb();
+ }
+
+ var metadata = docIdsToMetadata.get(doc._id);
+ if (metadata) { // cached
+ return onGetMetadata(doc, seq, metadata, cb);
+ }
+ // metadata not cached, have to go fetch it
+ docStore.get(doc._id).onsuccess = function (e) {
+ metadata = decodeMetadata(e.target.result);
+ docIdsToMetadata.set(doc._id, metadata);
+ onGetMetadata(doc, seq, metadata, cb);
+ };
+ }
+
+ function finish() {
+ opts.complete(null, {
+ results: results,
+ last_seq: lastSeq
+ });
+ }
+
+ function onTxnComplete() {
+ if (!opts.continuous && opts.attachments) {
+ // cannot guarantee that postProcessing was already done,
+ // so do it again
+ postProcessAttachments(results).then(finish);
+ } else {
+ finish();
+ }
+ }
+
+ var objectStores = [DOC_STORE, BY_SEQ_STORE];
+ if (opts.attachments) {
+ objectStores.push(ATTACH_STORE);
+ }
+ var txnResult = openTransactionSafely(idb, objectStores, 'readonly');
+ if (txnResult.error) {
+ return opts.complete(txnResult.error);
+ }
+ txn = txnResult.txn;
+ txn.onabort = idbError(opts.complete);
+ txn.oncomplete = onTxnComplete;
+
+ bySeqStore = txn.objectStore(BY_SEQ_STORE);
+ docStore = txn.objectStore(DOC_STORE);
+ docIdRevIndex = bySeqStore.index('_doc_id_rev');
+
+ var keyRange = (opts.since && !opts.descending) ?
+ IDBKeyRange.lowerBound(opts.since, true) : null;
+
+ runBatchedCursor(bySeqStore, keyRange, opts.descending, limit, onBatch);
+}
+
+var cachedDBs = new ExportedMap();
+var blobSupportPromise;
+var openReqList = new ExportedMap();
+
+function IdbPouch(opts, callback) {
+ var api = this;
+
+ enqueueTask(function (thisCallback) {
+ init(api, opts, thisCallback);
+ }, callback, api.constructor);
+}
+
+function init(api, opts, callback) {
+
+ var dbName = opts.name;
+
+ var idb = null;
+ api._meta = null;
+
+ // called when creating a fresh new database
+ function createSchema(db) {
+ var docStore = db.createObjectStore(DOC_STORE, {keyPath : 'id'});
+ db.createObjectStore(BY_SEQ_STORE, {autoIncrement: true})
+ .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
+ db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'});
+ db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false});
+ db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
+
+ // added in v2
+ docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
+
+ // added in v3
+ db.createObjectStore(LOCAL_STORE, {keyPath: '_id'});
+
+ // added in v4
+ var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
+ {autoIncrement: true});
+ attAndSeqStore.createIndex('seq', 'seq');
+ attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
+ }
+
+ // migration to version 2
+ // unfortunately "deletedOrLocal" is a misnomer now that we no longer
+ // store local docs in the main doc-store, but whaddyagonnado
+ function addDeletedOrLocalIndex(txn, callback) {
+ var docStore = txn.objectStore(DOC_STORE);
+ docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
+
+ docStore.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ var metadata = cursor.value;
+ var deleted = isDeleted(metadata);
+ metadata.deletedOrLocal = deleted ? "1" : "0";
+ docStore.put(metadata);
+ cursor["continue"]();
+ } else {
+ callback();
+ }
+ };
+ }
+
+ // migration to version 3 (part 1)
+ function createLocalStoreSchema(db) {
+ db.createObjectStore(LOCAL_STORE, {keyPath: '_id'})
+ .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
+ }
+
+ // migration to version 3 (part 2)
+ function migrateLocalStore(txn, cb) {
+ var localStore = txn.objectStore(LOCAL_STORE);
+ var docStore = txn.objectStore(DOC_STORE);
+ var seqStore = txn.objectStore(BY_SEQ_STORE);
+
+ var cursor = docStore.openCursor();
+ cursor.onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ var metadata = cursor.value;
+ var docId = metadata.id;
+ var local = isLocalId(docId);
+ var rev$$1 = winningRev(metadata);
+ if (local) {
+ var docIdRev = docId + "::" + rev$$1;
+ // remove all seq entries
+ // associated with this docId
+ var start = docId + "::";
+ var end = docId + "::~";
+ var index = seqStore.index('_doc_id_rev');
+ var range = IDBKeyRange.bound(start, end, false, false);
+ var seqCursor = index.openCursor(range);
+ seqCursor.onsuccess = function (e) {
+ seqCursor = e.target.result;
+ if (!seqCursor) {
+ // done
+ docStore["delete"](cursor.primaryKey);
+ cursor["continue"]();
+ } else {
+ var data = seqCursor.value;
+ if (data._doc_id_rev === docIdRev) {
+ localStore.put(data);
+ }
+ seqStore["delete"](seqCursor.primaryKey);
+ seqCursor["continue"]();
+ }
+ };
+ } else {
+ cursor["continue"]();
+ }
+ } else if (cb) {
+ cb();
+ }
+ };
+ }
+
+ // migration to version 4 (part 1)
+ function addAttachAndSeqStore(db) {
+ var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
+ {autoIncrement: true});
+ attAndSeqStore.createIndex('seq', 'seq');
+ attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
+ }
+
+ // migration to version 4 (part 2)
+ function migrateAttsAndSeqs(txn, callback) {
+ var seqStore = txn.objectStore(BY_SEQ_STORE);
+ var attStore = txn.objectStore(ATTACH_STORE);
+ var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+
+ // need to actually populate the table. this is the expensive part,
+ // so as an optimization, check first that this database even
+ // contains attachments
+ var req = attStore.count();
+ req.onsuccess = function (e) {
+ var count = e.target.result;
+ if (!count) {
+ return callback(); // done
+ }
+
+ seqStore.openCursor().onsuccess = function (e) {
+ var cursor = e.target.result;
+ if (!cursor) {
+ return callback(); // done
+ }
+ var doc = cursor.value;
+ var seq = cursor.primaryKey;
+ var atts = Object.keys(doc._attachments || {});
+ var digestMap = {};
+ for (var j = 0; j < atts.length; j++) {
+ var att = doc._attachments[atts[j]];
+ digestMap[att.digest] = true; // uniq digests, just in case
+ }
+ var digests = Object.keys(digestMap);
+ for (j = 0; j < digests.length; j++) {
+ var digest = digests[j];
+ attAndSeqStore.put({
+ seq: seq,
+ digestSeq: digest + '::' + seq
+ });
+ }
+ cursor["continue"]();
+ };
+ };
+ }
+
+ // migration to version 5
+ // Instead of relying on on-the-fly migration of metadata,
+ // this brings the doc-store to its modern form:
+ // - metadata.winningrev
+ // - metadata.seq
+ // - stringify the metadata when storing it
+ function migrateMetadata(txn) {
+
+ function decodeMetadataCompat(storedObject) {
+ if (!storedObject.data) {
+ // old format, when we didn't store it stringified
+ storedObject.deleted = storedObject.deletedOrLocal === '1';
+ return storedObject;
+ }
+ return decodeMetadata(storedObject);
+ }
+
+ // ensure that every metadata has a winningRev and seq,
+ // which was previously created on-the-fly but better to migrate
+ var bySeqStore = txn.objectStore(BY_SEQ_STORE);
+ var docStore = txn.objectStore(DOC_STORE);
+ var cursor = docStore.openCursor();
+ cursor.onsuccess = function (e) {
+ var cursor = e.target.result;
+ if (!cursor) {
+ return; // done
+ }
+ var metadata = decodeMetadataCompat(cursor.value);
+
+ metadata.winningRev = metadata.winningRev ||
+ winningRev(metadata);
+
+ function fetchMetadataSeq() {
+ // metadata.seq was added post-3.2.0, so if it's missing,
+ // we need to fetch it manually
+ var start = metadata.id + '::';
+ var end = metadata.id + '::\uffff';
+ var req = bySeqStore.index('_doc_id_rev').openCursor(
+ IDBKeyRange.bound(start, end));
+
+ var metadataSeq = 0;
+ req.onsuccess = function (e) {
+ var cursor = e.target.result;
+ if (!cursor) {
+ metadata.seq = metadataSeq;
+ return onGetMetadataSeq();
+ }
+ var seq = cursor.primaryKey;
+ if (seq > metadataSeq) {
+ metadataSeq = seq;
+ }
+ cursor["continue"]();
+ };
+ }
+
+ function onGetMetadataSeq() {
+ var metadataToStore = encodeMetadata(metadata,
+ metadata.winningRev, metadata.deleted);
+
+ var req = docStore.put(metadataToStore);
+ req.onsuccess = function () {
+ cursor["continue"]();
+ };
+ }
+
+ if (metadata.seq) {
+ return onGetMetadataSeq();
+ }
+
+ fetchMetadataSeq();
+ };
+
+ }
+
+ api._remote = false;
+ api.type = function () {
+ return 'idb';
+ };
+
+ api._id = toPromise(function (callback) {
+ callback(null, api._meta.instanceId);
+ });
+
+ api._bulkDocs = function idb_bulkDocs(req, reqOpts, callback) {
+ idbBulkDocs(opts, req, reqOpts, api, idb, callback);
+ };
+
+ // First we look up the metadata in the ids database, then we fetch the
+ // current revision(s) from the by sequence store
+ api._get = function idb_get(id, opts, callback) {
+ var doc;
+ var metadata;
+ var err;
+ var txn = opts.ctx;
+ if (!txn) {
+ var txnResult = openTransactionSafely(idb,
+ [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ txn = txnResult.txn;
+ }
+
+ function finish() {
+ callback(err, {doc: doc, metadata: metadata, ctx: txn});
+ }
+
+ txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) {
+ metadata = decodeMetadata(e.target.result);
+ // we can determine the result here if:
+ // 1. there is no such document
+ // 2. the document is deleted and we don't ask about specific rev
+ // When we ask with opts.rev we expect the answer to be either
+ // doc (possibly with _deleted=true) or missing error
+ if (!metadata) {
+ err = createError(MISSING_DOC, 'missing');
+ return finish();
+ }
+
+ var rev$$1;
+ if (!opts.rev) {
+ rev$$1 = metadata.winningRev;
+ var deleted = isDeleted(metadata);
+ if (deleted) {
+ err = createError(MISSING_DOC, "deleted");
+ return finish();
+ }
+ } else {
+ rev$$1 = opts.latest ? latest(opts.rev, metadata) : opts.rev;
+ }
+
+ var objectStore = txn.objectStore(BY_SEQ_STORE);
+ var key = metadata.id + '::' + rev$$1;
+
+ objectStore.index('_doc_id_rev').get(key).onsuccess = function (e) {
+ doc = e.target.result;
+ if (doc) {
+ doc = decodeDoc(doc);
+ }
+ if (!doc) {
+ err = createError(MISSING_DOC, 'missing');
+ return finish();
+ }
+ finish();
+ };
+ };
+ };
+
+ api._getAttachment = function (docId, attachId, attachment, opts, callback) {
+ var txn;
+ if (opts.ctx) {
+ txn = opts.ctx;
+ } else {
+ var txnResult = openTransactionSafely(idb,
+ [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ txn = txnResult.txn;
+ }
+ var digest = attachment.digest;
+ var type = attachment.content_type;
+
+ txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) {
+ var body = e.target.result.body;
+ readBlobData(body, type, opts.binary, function (blobData) {
+ callback(null, blobData);
+ });
+ };
+ };
+
+ api._info = function idb_info(callback) {
+ var updateSeq;
+ var docCount;
+
+ var txnResult = openTransactionSafely(idb, [META_STORE, BY_SEQ_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var txn = txnResult.txn;
+ txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
+ docCount = e.target.result.docCount;
+ };
+ txn.objectStore(BY_SEQ_STORE).openCursor(null, 'prev').onsuccess = function (e) {
+ var cursor = e.target.result;
+ updateSeq = cursor ? cursor.key : 0;
+ };
+
+ txn.oncomplete = function () {
+ callback(null, {
+ doc_count: docCount,
+ update_seq: updateSeq,
+ // for debugging
+ idb_attachment_format: (api._meta.blobSupport ? 'binary' : 'base64')
+ });
+ };
+ };
+
+ api._allDocs = function idb_allDocs(opts, callback) {
+ idbAllDocs(opts, idb, callback);
+ };
+
+ api._changes = function idbChanges(opts) {
+ return changes(opts, api, dbName, idb);
+ };
+
+ api._close = function (callback) {
+ // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close
+ // "Returns immediately and closes the connection in a separate thread..."
+ idb.close();
+ cachedDBs["delete"](dbName);
+ callback();
+ };
+
+ api._getRevisionTree = function (docId, callback) {
+ var txnResult = openTransactionSafely(idb, [DOC_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var txn = txnResult.txn;
+ var req = txn.objectStore(DOC_STORE).get(docId);
+ req.onsuccess = function (event) {
+ var doc = decodeMetadata(event.target.result);
+ if (!doc) {
+ callback(createError(MISSING_DOC));
+ } else {
+ callback(null, doc.rev_tree);
+ }
+ };
+ };
+
+ // This function removes revisions of document docId
+ // which are listed in revs and sets this document
+ // revision to to rev_tree
+ api._doCompaction = function (docId, revs, callback) {
+ var stores = [
+ DOC_STORE,
+ BY_SEQ_STORE,
+ ATTACH_STORE,
+ ATTACH_AND_SEQ_STORE
+ ];
+ var txnResult = openTransactionSafely(idb, stores, 'readwrite');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var txn = txnResult.txn;
+
+ var docStore = txn.objectStore(DOC_STORE);
+
+ docStore.get(docId).onsuccess = function (event) {
+ var metadata = decodeMetadata(event.target.result);
+ traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+ revHash, ctx, opts) {
+ var rev$$1 = pos + '-' + revHash;
+ if (revs.indexOf(rev$$1) !== -1) {
+ opts.status = 'missing';
+ }
+ });
+ compactRevs(revs, docId, txn);
+ var winningRev$$1 = metadata.winningRev;
+ var deleted = metadata.deleted;
+ txn.objectStore(DOC_STORE).put(
+ encodeMetadata(metadata, winningRev$$1, deleted));
+ };
+ txn.onabort = idbError(callback);
+ txn.oncomplete = function () {
+ callback();
+ };
+ };
+
+
+ api._getLocal = function (id, callback) {
+ var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var tx = txnResult.txn;
+ var req = tx.objectStore(LOCAL_STORE).get(id);
+
+ req.onerror = idbError(callback);
+ req.onsuccess = function (e) {
+ var doc = e.target.result;
+ if (!doc) {
+ callback(createError(MISSING_DOC));
+ } else {
+ delete doc['_doc_id_rev']; // for backwards compat
+ callback(null, doc);
+ }
+ };
+ };
+
+ api._putLocal = function (doc, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ delete doc._revisions; // ignore this, trust the rev
+ var oldRev = doc._rev;
+ var id = doc._id;
+ if (!oldRev) {
+ doc._rev = '0-1';
+ } else {
+ doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1);
+ }
+
+ var tx = opts.ctx;
+ var ret;
+ if (!tx) {
+ var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ tx = txnResult.txn;
+ tx.onerror = idbError(callback);
+ tx.oncomplete = function () {
+ if (ret) {
+ callback(null, ret);
+ }
+ };
+ }
+
+ var oStore = tx.objectStore(LOCAL_STORE);
+ var req;
+ if (oldRev) {
+ req = oStore.get(id);
+ req.onsuccess = function (e) {
+ var oldDoc = e.target.result;
+ if (!oldDoc || oldDoc._rev !== oldRev) {
+ callback(createError(REV_CONFLICT));
+ } else { // update
+ var req = oStore.put(doc);
+ req.onsuccess = function () {
+ ret = {ok: true, id: doc._id, rev: doc._rev};
+ if (opts.ctx) { // return immediately
+ callback(null, ret);
+ }
+ };
+ }
+ };
+ } else { // new doc
+ req = oStore.add(doc);
+ req.onerror = function (e) {
+ // constraint error, already exists
+ callback(createError(REV_CONFLICT));
+ e.preventDefault(); // avoid transaction abort
+ e.stopPropagation(); // avoid transaction onerror
+ };
+ req.onsuccess = function () {
+ ret = {ok: true, id: doc._id, rev: doc._rev};
+ if (opts.ctx) { // return immediately
+ callback(null, ret);
+ }
+ };
+ }
+ };
+
+ api._removeLocal = function (doc, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ var tx = opts.ctx;
+ if (!tx) {
+ var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ tx = txnResult.txn;
+ tx.oncomplete = function () {
+ if (ret) {
+ callback(null, ret);
+ }
+ };
+ }
+ var ret;
+ var id = doc._id;
+ var oStore = tx.objectStore(LOCAL_STORE);
+ var req = oStore.get(id);
+
+ req.onerror = idbError(callback);
+ req.onsuccess = function (e) {
+ var oldDoc = e.target.result;
+ if (!oldDoc || oldDoc._rev !== doc._rev) {
+ callback(createError(MISSING_DOC));
+ } else {
+ oStore["delete"](id);
+ ret = {ok: true, id: id, rev: '0-0'};
+ if (opts.ctx) { // return immediately
+ callback(null, ret);
+ }
+ }
+ };
+ };
+
+ api._destroy = function (opts, callback) {
+ changesHandler.removeAllListeners(dbName);
+
+ //Close open request for "dbName" database to fix ie delay.
+ var openReq = openReqList.get(dbName);
+ if (openReq && openReq.result) {
+ openReq.result.close();
+ cachedDBs["delete"](dbName);
+ }
+ var req = indexedDB.deleteDatabase(dbName);
+
+ req.onsuccess = function () {
+ //Remove open request from the list.
+ openReqList["delete"](dbName);
+ if (hasLocalStorage() && (dbName in localStorage)) {
+ delete localStorage[dbName];
+ }
+ callback(null, { 'ok': true });
+ };
+
+ req.onerror = idbError(callback);
+ };
+
+ var cached = cachedDBs.get(dbName);
+
+ if (cached) {
+ idb = cached.idb;
+ api._meta = cached.global;
+ return immediate(function () {
+ callback(null, api);
+ });
+ }
+
+ var req = indexedDB.open(dbName, ADAPTER_VERSION);
+ openReqList.set(dbName, req);
+
+ req.onupgradeneeded = function (e) {
+ var db = e.target.result;
+ if (e.oldVersion < 1) {
+ return createSchema(db); // new db, initial schema
+ }
+ // do migrations
+
+ var txn = e.currentTarget.transaction;
+ // these migrations have to be done in this function, before
+ // control is returned to the event loop, because IndexedDB
+
+ if (e.oldVersion < 3) {
+ createLocalStoreSchema(db); // v2 -> v3
+ }
+ if (e.oldVersion < 4) {
+ addAttachAndSeqStore(db); // v3 -> v4
+ }
+
+ var migrations = [
+ addDeletedOrLocalIndex, // v1 -> v2
+ migrateLocalStore, // v2 -> v3
+ migrateAttsAndSeqs, // v3 -> v4
+ migrateMetadata // v4 -> v5
+ ];
+
+ var i = e.oldVersion;
+
+ function next() {
+ var migration = migrations[i - 1];
+ i++;
+ if (migration) {
+ migration(txn, next);
+ }
+ }
+
+ next();
+ };
+
+ req.onsuccess = function (e) {
+
+ idb = e.target.result;
+
+ idb.onversionchange = function () {
+ idb.close();
+ cachedDBs["delete"](dbName);
+ };
+
+ idb.onabort = function (e) {
+ guardedConsole('error', 'Database has a global failure', e.target.error);
+ idb.close();
+ cachedDBs["delete"](dbName);
+ };
+
+ // Do a few setup operations (in parallel as much as possible):
+ // 1. Fetch meta doc
+ // 2. Check blob support
+ // 3. Calculate docCount
+ // 4. Generate an instanceId if necessary
+ // 5. Store docCount and instanceId on meta doc
+
+ var txn = idb.transaction([
+ META_STORE,
+ DETECT_BLOB_SUPPORT_STORE,
+ DOC_STORE
+ ], 'readwrite');
+
+ var storedMetaDoc = false;
+ var metaDoc;
+ var docCount;
+ var blobSupport;
+ var instanceId;
+
+ function completeSetup() {
+ if (typeof blobSupport === 'undefined' || !storedMetaDoc) {
+ return;
+ }
+ api._meta = {
+ name: dbName,
+ instanceId: instanceId,
+ blobSupport: blobSupport
+ };
+
+ cachedDBs.set(dbName, {
+ idb: idb,
+ global: api._meta
+ });
+ callback(null, api);
+ }
+
+ function storeMetaDocIfReady() {
+ if (typeof docCount === 'undefined' || typeof metaDoc === 'undefined') {
+ return;
+ }
+ var instanceKey = dbName + '_id';
+ if (instanceKey in metaDoc) {
+ instanceId = metaDoc[instanceKey];
+ } else {
+ metaDoc[instanceKey] = instanceId = uuid();
+ }
+ metaDoc.docCount = docCount;
+ txn.objectStore(META_STORE).put(metaDoc);
+ }
+
+ //
+ // fetch or generate the instanceId
+ //
+ txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
+ metaDoc = e.target.result || { id: META_STORE };
+ storeMetaDocIfReady();
+ };
+
+ //
+ // countDocs
+ //
+ countDocs(txn, function (count) {
+ docCount = count;
+ storeMetaDocIfReady();
+ });
+
+ //
+ // check blob support
+ //
+ if (!blobSupportPromise) {
+ // make sure blob support is only checked once
+ blobSupportPromise = checkBlobSupport(txn);
+ }
+
+ blobSupportPromise.then(function (val) {
+ blobSupport = val;
+ completeSetup();
+ });
+
+ // only when the metadata put transaction has completed,
+ // consider the setup done
+ txn.oncomplete = function () {
+ storedMetaDoc = true;
+ completeSetup();
+ };
+ txn.onabort = idbError(callback);
+ };
+
+ req.onerror = function () {
+ var msg = 'Failed to open indexedDB, are you in private browsing mode?';
+ guardedConsole('error', msg);
+ callback(createError(IDB_ERROR, msg));
+ };
+}
+
+IdbPouch.valid = function () {
+ // Following #7085 buggy idb versions (typically Safari < 10.1) are
+ // considered valid.
+
+ // On Firefox SecurityError is thrown while referencing indexedDB if cookies
+ // are not allowed. `typeof indexedDB` also triggers the error.
+ try {
+ // some outdated implementations of IDB that appear on Samsung
+ // and HTC Android devices <4.4 are missing IDBKeyRange
+ return typeof indexedDB !== 'undefined' && typeof IDBKeyRange !== 'undefined';
+ } catch (e) {
+ return false;
+ }
+};
+
+function IDBPouch (PouchDB) {
+ PouchDB.adapter('idb', IdbPouch, true);
+}
+
+// dead simple promise pool, inspired by https://github.com/timdp/es6-promise-pool
+// but much smaller in code size. limits the number of concurrent promises that are executed
+
+
+function pool(promiseFactories, limit) {
+ return new Promise(function (resolve, reject) {
+ var running = 0;
+ var current = 0;
+ var done = 0;
+ var len = promiseFactories.length;
+ var err;
+
+ function runNext() {
+ running++;
+ promiseFactories[current++]().then(onSuccess, onError);
+ }
+
+ function doNext() {
+ if (++done === len) {
+ /* istanbul ignore if */
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ } else {
+ runNextBatch();
+ }
+ }
+
+ function onSuccess() {
+ running--;
+ doNext();
+ }
+
+ /* istanbul ignore next */
+ function onError(thisErr) {
+ running--;
+ err = err || thisErr;
+ doNext();
+ }
+
+ function runNextBatch() {
+ while (running < limit && current < len) {
+ runNext();
+ }
+ }
+
+ runNextBatch();
+ });
+}
+
+var CHANGES_BATCH_SIZE = 25;
+var MAX_SIMULTANEOUS_REVS = 50;
+var CHANGES_TIMEOUT_BUFFER = 5000;
+var DEFAULT_HEARTBEAT = 10000;
+
+var supportsBulkGetMap = {};
+
+function readAttachmentsAsBlobOrBuffer(row) {
+ var doc = row.doc || row.ok;
+ var atts = doc && doc._attachments;
+ if (!atts) {
+ return;
+ }
+ Object.keys(atts).forEach(function (filename) {
+ var att = atts[filename];
+ att.data = b64ToBluffer(att.data, att.content_type);
+ });
+}
+
+function encodeDocId(id) {
+ if (/^_design/.test(id)) {
+ return '_design/' + encodeURIComponent(id.slice(8));
+ }
+ if (/^_local/.test(id)) {
+ return '_local/' + encodeURIComponent(id.slice(7));
+ }
+ return encodeURIComponent(id);
+}
+
+function preprocessAttachments$1(doc) {
+ if (!doc._attachments || !Object.keys(doc._attachments)) {
+ return Promise.resolve();
+ }
+
+ return Promise.all(Object.keys(doc._attachments).map(function (key) {
+ var attachment = doc._attachments[key];
+ if (attachment.data && typeof attachment.data !== 'string') {
+ return new Promise(function (resolve) {
+ blobToBase64(attachment.data, resolve);
+ }).then(function (b64) {
+ attachment.data = b64;
+ });
+ }
+ }));
+}
+
+function hasUrlPrefix(opts) {
+ if (!opts.prefix) {
+ return false;
+ }
+ var protocol = parseUri(opts.prefix).protocol;
+ return protocol === 'http' || protocol === 'https';
+}
+
+// Get all the information you possibly can about the URI given by name and
+// return it as a suitable object.
+function getHost(name, opts) {
+ // encode db name if opts.prefix is a url (#5574)
+ if (hasUrlPrefix(opts)) {
+ var dbName = opts.name.substr(opts.prefix.length);
+ // Ensure prefix has a trailing slash
+ var prefix = opts.prefix.replace(/\/?$/, '/');
+ name = prefix + encodeURIComponent(dbName);
+ }
+
+ var uri = parseUri(name);
+ if (uri.user || uri.password) {
+ uri.auth = {username: uri.user, password: uri.password};
+ }
+
+ // Split the path part of the URI into parts using '/' as the delimiter
+ // after removing any leading '/' and any trailing '/'
+ var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/');
+
+ uri.db = parts.pop();
+ // Prevent double encoding of URI component
+ if (uri.db.indexOf('%') === -1) {
+ uri.db = encodeURIComponent(uri.db);
+ }
+
+ uri.path = parts.join('/');
+
+ return uri;
+}
+
+// Generate a URL with the host data given by opts and the given path
+function genDBUrl(opts, path) {
+ return genUrl(opts, opts.db + '/' + path);
+}
+
+// Generate a URL with the host data given by opts and the given path
+function genUrl(opts, path) {
+ // If the host already has a path, then we need to have a path delimiter
+ // Otherwise, the path delimiter is the empty string
+ var pathDel = !opts.path ? '' : '/';
+
+ // If the host already has a path, then we need to have a path delimiter
+ // Otherwise, the path delimiter is the empty string
+ return opts.protocol + '://' + opts.host +
+ (opts.port ? (':' + opts.port) : '') +
+ '/' + opts.path + pathDel + path;
+}
+
+function paramsToStr(params) {
+ return '?' + Object.keys(params).map(function (k) {
+ return k + '=' + encodeURIComponent(params[k]);
+ }).join('&');
+}
+
+function shouldCacheBust(opts) {
+ var ua = (typeof navigator !== 'undefined' && navigator.userAgent) ?
+ navigator.userAgent.toLowerCase() : '';
+ var isIE = ua.indexOf('msie') !== -1;
+ var isTrident = ua.indexOf('trident') !== -1;
+ var isEdge = ua.indexOf('edge') !== -1;
+ var isGET = !('method' in opts) || opts.method === 'GET';
+ return (isIE || isTrident || isEdge) && isGET;
+}
+
+// Implements the PouchDB API for dealing with CouchDB instances over HTTP
+function HttpPouch(opts, callback) {
+
+ // The functions that will be publicly available for HttpPouch
+ var api = this;
+
+ var host = getHost(opts.name, opts);
+ var dbUrl = genDBUrl(host, '');
+
+ opts = clone(opts);
+
+ var ourFetch = function (url, options) {
+
+ options = options || {};
+ options.headers = options.headers || new h();
+
+ options.credentials = 'include';
+
+ if (opts.auth || host.auth) {
+ var nAuth = opts.auth || host.auth;
+ var str = nAuth.username + ':' + nAuth.password;
+ var token = thisBtoa(unescape(encodeURIComponent(str)));
+ options.headers.set('Authorization', 'Basic ' + token);
+ }
+
+ var headers = opts.headers || {};
+ Object.keys(headers).forEach(function (key) {
+ options.headers.append(key, headers[key]);
+ });
+
+ /* istanbul ignore if */
+ if (shouldCacheBust(options)) {
+ url += (url.indexOf('?') === -1 ? '?' : '&') + '_nonce=' + Date.now();
+ }
+
+ var fetchFun = opts.fetch || f$1;
+ return fetchFun(url, options);
+ };
+
+ function adapterFun$$1(name, fun) {
+ return adapterFun(name, getArguments(function (args) {
+ setup().then(function () {
+ return fun.apply(this, args);
+ })["catch"](function (e) {
+ var callback = args.pop();
+ callback(e);
+ });
+ })).bind(api);
+ }
+
+ function fetchJSON(url, options, callback) {
+
+ var result = {};
+
+ options = options || {};
+ options.headers = options.headers || new h();
+
+ if (!options.headers.get('Content-Type')) {
+ options.headers.set('Content-Type', 'application/json');
+ }
+ if (!options.headers.get('Accept')) {
+ options.headers.set('Accept', 'application/json');
+ }
+
+ return ourFetch(url, options).then(function (response) {
+ result.ok = response.ok;
+ result.status = response.status;
+ return response.json();
+ }).then(function (json) {
+ result.data = json;
+ if (!result.ok) {
+ result.data.status = result.status;
+ var err = generateErrorFromResponse(result.data);
+ if (callback) {
+ return callback(err);
+ } else {
+ throw err;
+ }
+ }
+
+ if (Array.isArray(result.data)) {
+ result.data = result.data.map(function (v) {
+ if (v.error || v.missing) {
+ return generateErrorFromResponse(v);
+ } else {
+ return v;
+ }
+ });
+ }
+
+ if (callback) {
+ callback(null, result.data);
+ } else {
+ return result;
+ }
+ });
+ }
+
+ var setupPromise;
+
+ function setup() {
+ if (opts.skip_setup) {
+ return Promise.resolve();
+ }
+
+ // If there is a setup in process or previous successful setup
+ // done then we will use that
+ // If previous setups have been rejected we will try again
+ if (setupPromise) {
+ return setupPromise;
+ }
+
+ setupPromise = fetchJSON(dbUrl)["catch"](function (err) {
+ if (err && err.status && err.status === 404) {
+ // Doesnt exist, create it
+ explainError(404, 'PouchDB is just detecting if the remote exists.');
+ return fetchJSON(dbUrl, {method: 'PUT'});
+ } else {
+ return Promise.reject(err);
+ }
+ })["catch"](function (err) {
+ // If we try to create a database that already exists, skipped in
+ // istanbul since its catching a race condition.
+ /* istanbul ignore if */
+ if (err && err.status && err.status === 412) {
+ return true;
+ }
+ return Promise.reject(err);
+ });
+
+ setupPromise["catch"](function () {
+ setupPromise = null;
+ });
+
+ return setupPromise;
+ }
+
+ immediate(function () {
+ callback(null, api);
+ });
+
+ api._remote = true;
+
+ /* istanbul ignore next */
+ api.type = function () {
+ return 'http';
+ };
+
+ api.id = adapterFun$$1('id', function (callback) {
+ ourFetch(genUrl(host, '')).then(function (response) {
+ return response.json();
+ })["catch"](function () {
+ return {};
+ }).then(function (result) {
+ // Bad response or missing `uuid` should not prevent ID generation.
+ var uuid$$1 = (result && result.uuid) ?
+ (result.uuid + host.db) : genDBUrl(host, '');
+ callback(null, uuid$$1);
+ });
+ });
+
+ // Sends a POST request to the host calling the couchdb _compact function
+ // version: The version of CouchDB it is running
+ api.compact = adapterFun$$1('compact', function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts = clone(opts);
+
+ fetchJSON(genDBUrl(host, '_compact'), {method: 'POST'}).then(function () {
+ function ping() {
+ api.info(function (err, res) {
+ // CouchDB may send a "compact_running:true" if it's
+ // already compacting. PouchDB Server doesn't.
+ /* istanbul ignore else */
+ if (res && !res.compact_running) {
+ callback(null, {ok: true});
+ } else {
+ setTimeout(ping, opts.interval || 200);
+ }
+ });
+ }
+ // Ping the http if it's finished compaction
+ ping();
+ });
+ });
+
+ api.bulkGet = adapterFun('bulkGet', function (opts, callback) {
+ var self = this;
+
+ function doBulkGet(cb) {
+ var params = {};
+ if (opts.revs) {
+ params.revs = true;
+ }
+ if (opts.attachments) {
+ /* istanbul ignore next */
+ params.attachments = true;
+ }
+ if (opts.latest) {
+ params.latest = true;
+ }
+ fetchJSON(genDBUrl(host, '_bulk_get' + paramsToStr(params)), {
+ method: 'POST',
+ body: JSON.stringify({ docs: opts.docs})
+ }).then(function (result) {
+ if (opts.attachments && opts.binary) {
+ result.data.results.forEach(function (res) {
+ res.docs.forEach(readAttachmentsAsBlobOrBuffer);
+ });
+ }
+ cb(null, result.data);
+ })["catch"](cb);
+ }
+
+ /* istanbul ignore next */
+ function doBulkGetShim() {
+ // avoid "url too long error" by splitting up into multiple requests
+ var batchSize = MAX_SIMULTANEOUS_REVS;
+ var numBatches = Math.ceil(opts.docs.length / batchSize);
+ var numDone = 0;
+ var results = new Array(numBatches);
+
+ function onResult(batchNum) {
+ return function (err, res) {
+ // err is impossible because shim returns a list of errs in that case
+ results[batchNum] = res.results;
+ if (++numDone === numBatches) {
+ callback(null, {results: flatten(results)});
+ }
+ };
+ }
+
+ for (var i = 0; i < numBatches; i++) {
+ var subOpts = pick(opts, ['revs', 'attachments', 'binary', 'latest']);
+ subOpts.docs = opts.docs.slice(i * batchSize,
+ Math.min(opts.docs.length, (i + 1) * batchSize));
+ bulkGet(self, subOpts, onResult(i));
+ }
+ }
+
+ // mark the whole database as either supporting or not supporting _bulk_get
+ var dbUrl = genUrl(host, '');
+ var supportsBulkGet = supportsBulkGetMap[dbUrl];
+
+ /* istanbul ignore next */
+ if (typeof supportsBulkGet !== 'boolean') {
+ // check if this database supports _bulk_get
+ doBulkGet(function (err, res) {
+ if (err) {
+ supportsBulkGetMap[dbUrl] = false;
+ explainError(
+ err.status,
+ 'PouchDB is just detecting if the remote ' +
+ 'supports the _bulk_get API.'
+ );
+ doBulkGetShim();
+ } else {
+ supportsBulkGetMap[dbUrl] = true;
+ callback(null, res);
+ }
+ });
+ } else if (supportsBulkGet) {
+ doBulkGet(callback);
+ } else {
+ doBulkGetShim();
+ }
+ });
+
+ // Calls GET on the host, which gets back a JSON string containing
+ // couchdb: A welcome string
+ // version: The version of CouchDB it is running
+ api._info = function (callback) {
+ setup().then(function () {
+ return ourFetch(genDBUrl(host, ''));
+ }).then(function (response) {
+ return response.json();
+ }).then(function (info) {
+ info.host = genDBUrl(host, '');
+ callback(null, info);
+ })["catch"](callback);
+ };
+
+ api.fetch = function (path, options) {
+ return setup().then(function () {
+ var url = path.substring(0, 1) === '/' ?
+ genUrl(host, path.substring(1)) :
+ genDBUrl(host, path);
+ return ourFetch(url, options);
+ });
+ };
+
+ // Get the document with the given id from the database given by host.
+ // The id could be solely the _id in the database, or it may be a
+ // _design/ID or _local/ID path
+ api.get = adapterFun$$1('get', function (id, opts, callback) {
+ // If no options were given, set the callback to the second parameter
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts = clone(opts);
+
+ // List of parameters to add to the GET request
+ var params = {};
+
+ if (opts.revs) {
+ params.revs = true;
+ }
+
+ if (opts.revs_info) {
+ params.revs_info = true;
+ }
+
+ if (opts.latest) {
+ params.latest = true;
+ }
+
+ if (opts.open_revs) {
+ if (opts.open_revs !== "all") {
+ opts.open_revs = JSON.stringify(opts.open_revs);
+ }
+ params.open_revs = opts.open_revs;
+ }
+
+ if (opts.rev) {
+ params.rev = opts.rev;
+ }
+
+ if (opts.conflicts) {
+ params.conflicts = opts.conflicts;
+ }
+
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ params.update_seq = opts.update_seq;
+ }
+
+ id = encodeDocId(id);
+
+ function fetchAttachments(doc) {
+ var atts = doc._attachments;
+ var filenames = atts && Object.keys(atts);
+ if (!atts || !filenames.length) {
+ return;
+ }
+ // we fetch these manually in separate XHRs, because
+ // Sync Gateway would normally send it back as multipart/mixed,
+ // which we cannot parse. Also, this is more efficient than
+ // receiving attachments as base64-encoded strings.
+ function fetchData(filename) {
+ var att = atts[filename];
+ var path = encodeDocId(doc._id) + '/' + encodeAttachmentId(filename) +
+ '?rev=' + doc._rev;
+ return ourFetch(genDBUrl(host, path)).then(function (response) {
+ if (typeof process !== 'undefined' && !process.browser) {
+ return response.buffer();
+ } else {
+ /* istanbul ignore next */
+ return response.blob();
+ }
+ }).then(function (blob) {
+ if (opts.binary) {
+ // TODO: Can we remove this?
+ if (typeof process !== 'undefined' && !process.browser) {
+ blob.type = att.content_type;
+ }
+ return blob;
+ }
+ return new Promise(function (resolve) {
+ blobToBase64(blob, resolve);
+ });
+ }).then(function (data) {
+ delete att.stub;
+ delete att.length;
+ att.data = data;
+ });
+ }
+
+ var promiseFactories = filenames.map(function (filename) {
+ return function () {
+ return fetchData(filename);
+ };
+ });
+
+ // This limits the number of parallel xhr requests to 5 any time
+ // to avoid issues with maximum browser request limits
+ return pool(promiseFactories, 5);
+ }
+
+ function fetchAllAttachments(docOrDocs) {
+ if (Array.isArray(docOrDocs)) {
+ return Promise.all(docOrDocs.map(function (doc) {
+ if (doc.ok) {
+ return fetchAttachments(doc.ok);
+ }
+ }));
+ }
+ return fetchAttachments(docOrDocs);
+ }
+
+ var url = genDBUrl(host, id + paramsToStr(params));
+ fetchJSON(url).then(function (res) {
+ return Promise.resolve().then(function () {
+ if (opts.attachments) {
+ return fetchAllAttachments(res.data);
+ }
+ }).then(function () {
+ callback(null, res.data);
+ });
+ })["catch"](function (e) {
+ e.docId = id;
+ callback(e);
+ });
+ });
+
+
+ // Delete the document given by doc from the database given by host.
+ api.remove = adapterFun$$1('remove', function (docOrId, optsOrRev, opts, cb) {
+ var doc;
+ if (typeof optsOrRev === 'string') {
+ // id, rev, opts, callback style
+ doc = {
+ _id: docOrId,
+ _rev: optsOrRev
+ };
+ if (typeof opts === 'function') {
+ cb = opts;
+ opts = {};
+ }
+ } else {
+ // doc, opts, callback style
+ doc = docOrId;
+ if (typeof optsOrRev === 'function') {
+ cb = optsOrRev;
+ opts = {};
+ } else {
+ cb = opts;
+ opts = optsOrRev;
+ }
+ }
+
+ var rev$$1 = (doc._rev || opts.rev);
+ var url = genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev$$1;
+
+ fetchJSON(url, {method: 'DELETE'}, cb)["catch"](cb);
+ });
+
+ function encodeAttachmentId(attachmentId) {
+ return attachmentId.split("/").map(encodeURIComponent).join("/");
+ }
+
+ // Get the attachment
+ api.getAttachment = adapterFun$$1('getAttachment', function (docId, attachmentId,
+ opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ var params = opts.rev ? ('?rev=' + opts.rev) : '';
+ var url = genDBUrl(host, encodeDocId(docId)) + '/' +
+ encodeAttachmentId(attachmentId) + params;
+ var contentType;
+ ourFetch(url, {method: 'GET'}).then(function (response) {
+ contentType = response.headers.get('content-type');
+ if (!response.ok) {
+ throw response;
+ } else {
+ if (typeof process !== 'undefined' && !process.browser) {
+ return response.buffer();
+ } else {
+ /* istanbul ignore next */
+ return response.blob();
+ }
+ }
+ }).then(function (blob) {
+ // TODO: also remove
+ if (typeof process !== 'undefined' && !process.browser) {
+ blob.type = contentType;
+ }
+ callback(null, blob);
+ })["catch"](function (err) {
+ callback(err);
+ });
+ });
+
+ // Remove the attachment given by the id and rev
+ api.removeAttachment = adapterFun$$1('removeAttachment', function (docId,
+ attachmentId,
+ rev$$1,
+ callback) {
+ var url = genDBUrl(host, encodeDocId(docId) + '/' +
+ encodeAttachmentId(attachmentId)) + '?rev=' + rev$$1;
+ fetchJSON(url, {method: 'DELETE'}, callback)["catch"](callback);
+ });
+
+ // Add the attachment given by blob and its contentType property
+ // to the document with the given id, the revision given by rev, and
+ // add it to the database given by host.
+ api.putAttachment = adapterFun$$1('putAttachment', function (docId, attachmentId,
+ rev$$1, blob,
+ type, callback) {
+ if (typeof type === 'function') {
+ callback = type;
+ type = blob;
+ blob = rev$$1;
+ rev$$1 = null;
+ }
+ var id = encodeDocId(docId) + '/' + encodeAttachmentId(attachmentId);
+ var url = genDBUrl(host, id);
+ if (rev$$1) {
+ url += '?rev=' + rev$$1;
+ }
+
+ if (typeof blob === 'string') {
+ // input is assumed to be a base64 string
+ var binary;
+ try {
+ binary = thisAtob(blob);
+ } catch (err) {
+ return callback(createError(BAD_ARG,
+ 'Attachment is not a valid base64 string'));
+ }
+ blob = binary ? binStringToBluffer(binary, type) : '';
+ }
+
+ // Add the attachment
+ fetchJSON(url, {
+ headers: new h({'Content-Type': type}),
+ method: 'PUT',
+ body: blob
+ }, callback)["catch"](callback);
+ });
+
+ // Update/create multiple documents given by req in the database
+ // given by host.
+ api._bulkDocs = function (req, opts, callback) {
+ // If new_edits=false then it prevents the database from creating
+ // new revision numbers for the documents. Instead it just uses
+ // the old ones. This is used in database replication.
+ req.new_edits = opts.new_edits;
+
+ setup().then(function () {
+ return Promise.all(req.docs.map(preprocessAttachments$1));
+ }).then(function () {
+ // Update/create the documents
+ return fetchJSON(genDBUrl(host, '_bulk_docs'), {
+ method: 'POST',
+ body: JSON.stringify(req)
+ }, callback);
+ })["catch"](callback);
+ };
+
+
+ // Update/create document
+ api._put = function (doc, opts, callback) {
+ setup().then(function () {
+ return preprocessAttachments$1(doc);
+ }).then(function () {
+ return fetchJSON(genDBUrl(host, encodeDocId(doc._id)), {
+ method: 'PUT',
+ body: JSON.stringify(doc)
+ });
+ }).then(function (result) {
+ callback(null, result.data);
+ })["catch"](function (err) {
+ err.docId = doc && doc._id;
+ callback(err);
+ });
+ };
+
+
+ // Get a listing of the documents in the database given
+ // by host and ordered by increasing id.
+ api.allDocs = adapterFun$$1('allDocs', function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts = clone(opts);
+
+ // List of parameters to add to the GET request
+ var params = {};
+ var body;
+ var method = 'GET';
+
+ if (opts.conflicts) {
+ params.conflicts = true;
+ }
+
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ params.update_seq = true;
+ }
+
+ if (opts.descending) {
+ params.descending = true;
+ }
+
+ if (opts.include_docs) {
+ params.include_docs = true;
+ }
+
+ // added in CouchDB 1.6.0
+ if (opts.attachments) {
+ params.attachments = true;
+ }
+
+ if (opts.key) {
+ params.key = JSON.stringify(opts.key);
+ }
+
+ if (opts.start_key) {
+ opts.startkey = opts.start_key;
+ }
+
+ if (opts.startkey) {
+ params.startkey = JSON.stringify(opts.startkey);
+ }
+
+ if (opts.end_key) {
+ opts.endkey = opts.end_key;
+ }
+
+ if (opts.endkey) {
+ params.endkey = JSON.stringify(opts.endkey);
+ }
+
+ if (typeof opts.inclusive_end !== 'undefined') {
+ params.inclusive_end = !!opts.inclusive_end;
+ }
+
+ if (typeof opts.limit !== 'undefined') {
+ params.limit = opts.limit;
+ }
+
+ if (typeof opts.skip !== 'undefined') {
+ params.skip = opts.skip;
+ }
+
+ var paramStr = paramsToStr(params);
+
+ if (typeof opts.keys !== 'undefined') {
+ method = 'POST';
+ body = {keys: opts.keys};
+ }
+
+ fetchJSON(genDBUrl(host, '_all_docs' + paramStr), {
+ method: method,
+ body: JSON.stringify(body)
+ }).then(function (result) {
+ if (opts.include_docs && opts.attachments && opts.binary) {
+ result.data.rows.forEach(readAttachmentsAsBlobOrBuffer);
+ }
+ callback(null, result.data);
+ })["catch"](callback);
+ });
+
+ // Get a list of changes made to documents in the database given by host.
+ // TODO According to the README, there should be two other methods here,
+ // api.changes.addListener and api.changes.removeListener.
+ api._changes = function (opts) {
+
+ // We internally page the results of a changes request, this means
+ // if there is a large set of changes to be returned we can start
+ // processing them quicker instead of waiting on the entire
+ // set of changes to return and attempting to process them at once
+ var batchSize = 'batch_size' in opts ? opts.batch_size : CHANGES_BATCH_SIZE;
+
+ opts = clone(opts);
+
+ if (opts.continuous && !('heartbeat' in opts)) {
+ opts.heartbeat = DEFAULT_HEARTBEAT;
+ }
+
+ var requestTimeout = ('timeout' in opts) ? opts.timeout : 30 * 1000;
+
+ // ensure CHANGES_TIMEOUT_BUFFER applies
+ if ('timeout' in opts && opts.timeout &&
+ (requestTimeout - opts.timeout) < CHANGES_TIMEOUT_BUFFER) {
+ requestTimeout = opts.timeout + CHANGES_TIMEOUT_BUFFER;
+ }
+
+ /* istanbul ignore if */
+ if ('heartbeat' in opts && opts.heartbeat &&
+ (requestTimeout - opts.heartbeat) < CHANGES_TIMEOUT_BUFFER) {
+ requestTimeout = opts.heartbeat + CHANGES_TIMEOUT_BUFFER;
+ }
+
+ var params = {};
+ if ('timeout' in opts && opts.timeout) {
+ params.timeout = opts.timeout;
+ }
+
+ var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false;
+ var leftToFetch = limit;
+
+ if (opts.style) {
+ params.style = opts.style;
+ }
+
+ if (opts.include_docs || opts.filter && typeof opts.filter === 'function') {
+ params.include_docs = true;
+ }
+
+ if (opts.attachments) {
+ params.attachments = true;
+ }
+
+ if (opts.continuous) {
+ params.feed = 'longpoll';
+ }
+
+ if (opts.seq_interval) {
+ params.seq_interval = opts.seq_interval;
+ }
+
+ if (opts.conflicts) {
+ params.conflicts = true;
+ }
+
+ if (opts.descending) {
+ params.descending = true;
+ }
+
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ params.update_seq = true;
+ }
+
+ if ('heartbeat' in opts) {
+ // If the heartbeat value is false, it disables the default heartbeat
+ if (opts.heartbeat) {
+ params.heartbeat = opts.heartbeat;
+ }
+ }
+
+ if (opts.filter && typeof opts.filter === 'string') {
+ params.filter = opts.filter;
+ }
+
+ if (opts.view && typeof opts.view === 'string') {
+ params.filter = '_view';
+ params.view = opts.view;
+ }
+
+ // If opts.query_params exists, pass it through to the changes request.
+ // These parameters may be used by the filter on the source database.
+ if (opts.query_params && typeof opts.query_params === 'object') {
+ for (var param_name in opts.query_params) {
+ /* istanbul ignore else */
+ if (opts.query_params.hasOwnProperty(param_name)) {
+ params[param_name] = opts.query_params[param_name];
+ }
+ }
+ }
+
+ var method = 'GET';
+ var body;
+
+ if (opts.doc_ids) {
+ // set this automagically for the user; it's annoying that couchdb
+ // requires both a "filter" and a "doc_ids" param.
+ params.filter = '_doc_ids';
+ method = 'POST';
+ body = {doc_ids: opts.doc_ids };
+ }
+ /* istanbul ignore next */
+ else if (opts.selector) {
+ // set this automagically for the user, similar to above
+ params.filter = '_selector';
+ method = 'POST';
+ body = {selector: opts.selector };
+ }
+
+ var controller = new a();
+ var lastFetchedSeq;
+
+ // Get all the changes starting wtih the one immediately after the
+ // sequence number given by since.
+ var fetchData = function (since, callback) {
+ if (opts.aborted) {
+ return;
+ }
+ params.since = since;
+ // "since" can be any kind of json object in Cloudant/CouchDB 2.x
+ /* istanbul ignore next */
+ if (typeof params.since === "object") {
+ params.since = JSON.stringify(params.since);
+ }
+
+ if (opts.descending) {
+ if (limit) {
+ params.limit = leftToFetch;
+ }
+ } else {
+ params.limit = (!limit || leftToFetch > batchSize) ?
+ batchSize : leftToFetch;
+ }
+
+ // Set the options for the ajax call
+ var url = genDBUrl(host, '_changes' + paramsToStr(params));
+ var fetchOpts = {
+ signal: controller.signal,
+ method: method,
+ body: JSON.stringify(body)
+ };
+ lastFetchedSeq = since;
+
+ /* istanbul ignore if */
+ if (opts.aborted) {
+ return;
+ }
+
+ // Get the changes
+ setup().then(function () {
+ return fetchJSON(url, fetchOpts, callback);
+ })["catch"](callback);
+ };
+
+ // If opts.since exists, get all the changes from the sequence
+ // number given by opts.since. Otherwise, get all the changes
+ // from the sequence number 0.
+ var results = {results: []};
+
+ var fetched = function (err, res) {
+ if (opts.aborted) {
+ return;
+ }
+ var raw_results_length = 0;
+ // If the result of the ajax call (res) contains changes (res.results)
+ if (res && res.results) {
+ raw_results_length = res.results.length;
+ results.last_seq = res.last_seq;
+ var pending = null;
+ var lastSeq = null;
+ // Attach 'pending' property if server supports it (CouchDB 2.0+)
+ /* istanbul ignore if */
+ if (typeof res.pending === 'number') {
+ pending = res.pending;
+ }
+ if (typeof results.last_seq === 'string' || typeof results.last_seq === 'number') {
+ lastSeq = results.last_seq;
+ }
+ // For each change
+ var req = {};
+ req.query = opts.query_params;
+ res.results = res.results.filter(function (c) {
+ leftToFetch--;
+ var ret = filterChange(opts)(c);
+ if (ret) {
+ if (opts.include_docs && opts.attachments && opts.binary) {
+ readAttachmentsAsBlobOrBuffer(c);
+ }
+ if (opts.return_docs) {
+ results.results.push(c);
+ }
+ opts.onChange(c, pending, lastSeq);
+ }
+ return ret;
+ });
+ } else if (err) {
+ // In case of an error, stop listening for changes and call
+ // opts.complete
+ opts.aborted = true;
+ opts.complete(err);
+ return;
+ }
+
+ // The changes feed may have timed out with no results
+ // if so reuse last update sequence
+ if (res && res.last_seq) {
+ lastFetchedSeq = res.last_seq;
+ }
+
+ var finished = (limit && leftToFetch <= 0) ||
+ (res && raw_results_length < batchSize) ||
+ (opts.descending);
+
+ if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) {
+ // Queue a call to fetch again with the newest sequence number
+ immediate(function () { fetchData(lastFetchedSeq, fetched); });
+ } else {
+ // We're done, call the callback
+ opts.complete(null, results);
+ }
+ };
+
+ fetchData(opts.since || 0, fetched);
+
+ // Return a method to cancel this method from processing any more
+ return {
+ cancel: function () {
+ opts.aborted = true;
+ controller.abort();
+ }
+ };
+ };
+
+ // Given a set of document/revision IDs (given by req), tets the subset of
+ // those that do NOT correspond to revisions stored in the database.
+ // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
+ api.revsDiff = adapterFun$$1('revsDiff', function (req, opts, callback) {
+ // If no options were given, set the callback to be the second parameter
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ // Get the missing document/revision IDs
+ fetchJSON(genDBUrl(host, '_revs_diff'), {
+ method: 'POST',
+ body: JSON.stringify(req)
+ }, callback)["catch"](callback);
+ });
+
+ api._close = function (callback) {
+ callback();
+ };
+
+ api._destroy = function (options, callback) {
+ fetchJSON(genDBUrl(host, ''), {method: 'DELETE'}).then(function (json) {
+ callback(null, json);
+ })["catch"](function (err) {
+ /* istanbul ignore if */
+ if (err.status === 404) {
+ callback(null, {ok: true});
+ } else {
+ callback(err);
+ }
+ });
+ };
+}
+
+// HttpPouch is a valid adapter.
+HttpPouch.valid = function () {
+ return true;
+};
+
+function HttpPouch$1 (PouchDB) {
+ PouchDB.adapter('http', HttpPouch, false);
+ PouchDB.adapter('https', HttpPouch, false);
+}
+
+function QueryParseError(message) {
+ this.status = 400;
+ this.name = 'query_parse_error';
+ this.message = message;
+ this.error = true;
+ try {
+ Error.captureStackTrace(this, QueryParseError);
+ } catch (e) {}
+}
+
+inherits(QueryParseError, Error);
+
+function NotFoundError(message) {
+ this.status = 404;
+ this.name = 'not_found';
+ this.message = message;
+ this.error = true;
+ try {
+ Error.captureStackTrace(this, NotFoundError);
+ } catch (e) {}
+}
+
+inherits(NotFoundError, Error);
+
+function BuiltInError(message) {
+ this.status = 500;
+ this.name = 'invalid_value';
+ this.message = message;
+ this.error = true;
+ try {
+ Error.captureStackTrace(this, BuiltInError);
+ } catch (e) {}
+}
+
+inherits(BuiltInError, Error);
+
+function promisedCallback(promise, callback) {
+ if (callback) {
+ promise.then(function (res) {
+ immediate(function () {
+ callback(null, res);
+ });
+ }, function (reason) {
+ immediate(function () {
+ callback(reason);
+ });
+ });
+ }
+ return promise;
+}
+
+function callbackify(fun) {
+ return getArguments(function (args) {
+ var cb = args.pop();
+ var promise = fun.apply(this, args);
+ if (typeof cb === 'function') {
+ promisedCallback(promise, cb);
+ }
+ return promise;
+ });
+}
+
+// Promise finally util similar to Q.finally
+function fin(promise, finalPromiseFactory) {
+ return promise.then(function (res) {
+ return finalPromiseFactory().then(function () {
+ return res;
+ });
+ }, function (reason) {
+ return finalPromiseFactory().then(function () {
+ throw reason;
+ });
+ });
+}
+
+function sequentialize(queue, promiseFactory) {
+ return function () {
+ var args = arguments;
+ var that = this;
+ return queue.add(function () {
+ return promiseFactory.apply(that, args);
+ });
+ };
+}
+
+// uniq an array of strings, order not guaranteed
+// similar to underscore/lodash _.uniq
+function uniq(arr) {
+ var theSet = new ExportedSet(arr);
+ var result = new Array(theSet.size);
+ var index = -1;
+ theSet.forEach(function (value) {
+ result[++index] = value;
+ });
+ return result;
+}
+
+function mapToKeysArray(map) {
+ var result = new Array(map.size);
+ var index = -1;
+ map.forEach(function (value, key) {
+ result[++index] = key;
+ });
+ return result;
+}
+
+function createBuiltInError(name) {
+ var message = 'builtin ' + name +
+ ' function requires map values to be numbers' +
+ ' or number arrays';
+ return new BuiltInError(message);
+}
+
+function sum(values) {
+ var result = 0;
+ for (var i = 0, len = values.length; i < len; i++) {
+ var num = values[i];
+ if (typeof num !== 'number') {
+ if (Array.isArray(num)) {
+ // lists of numbers are also allowed, sum them separately
+ result = typeof result === 'number' ? [result] : result;
+ for (var j = 0, jLen = num.length; j < jLen; j++) {
+ var jNum = num[j];
+ if (typeof jNum !== 'number') {
+ throw createBuiltInError('_sum');
+ } else if (typeof result[j] === 'undefined') {
+ result.push(jNum);
+ } else {
+ result[j] += jNum;
+ }
+ }
+ } else { // not array/number
+ throw createBuiltInError('_sum');
+ }
+ } else if (typeof result === 'number') {
+ result += num;
+ } else { // add number to array
+ result[0] += num;
+ }
+ }
+ return result;
+}
+
+var log = guardedConsole.bind(null, 'log');
+var isArray = Array.isArray;
+var toJSON = JSON.parse;
+
+function evalFunctionWithEval(func, emit) {
+ return scopeEval(
+ "return (" + func.replace(/;\s*$/, "") + ");",
+ {
+ emit: emit,
+ sum: sum,
+ log: log,
+ isArray: isArray,
+ toJSON: toJSON
+ }
+ );
+}
+
+/*
+ * Simple task queue to sequentialize actions. Assumes
+ * callbacks will eventually fire (once).
+ */
+
+
+function TaskQueue$1() {
+ this.promise = new Promise(function (fulfill) {fulfill(); });
+}
+TaskQueue$1.prototype.add = function (promiseFactory) {
+ this.promise = this.promise["catch"](function () {
+ // just recover
+ }).then(function () {
+ return promiseFactory();
+ });
+ return this.promise;
+};
+TaskQueue$1.prototype.finish = function () {
+ return this.promise;
+};
+
+function stringify(input) {
+ if (!input) {
+ return 'undefined'; // backwards compat for empty reduce
+ }
+ // for backwards compat with mapreduce, functions/strings are stringified
+ // as-is. everything else is JSON-stringified.
+ switch (typeof input) {
+ case 'function':
+ // e.g. a mapreduce map
+ return input.toString();
+ case 'string':
+ // e.g. a mapreduce built-in _reduce function
+ return input.toString();
+ default:
+ // e.g. a JSON object in the case of mango queries
+ return JSON.stringify(input);
+ }
+}
+
+/* create a string signature for a view so we can cache it and uniq it */
+function createViewSignature(mapFun, reduceFun) {
+ // the "undefined" part is for backwards compatibility
+ return stringify(mapFun) + stringify(reduceFun) + 'undefined';
+}
+
+function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) {
+ var viewSignature = createViewSignature(mapFun, reduceFun);
+
+ var cachedViews;
+ if (!temporary) {
+ // cache this to ensure we don't try to update the same view twice
+ cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {};
+ if (cachedViews[viewSignature]) {
+ return cachedViews[viewSignature];
+ }
+ }
+
+ var promiseForView = sourceDB.info().then(function (info) {
+
+ var depDbName = info.db_name + '-mrview-' +
+ (temporary ? 'temp' : stringMd5(viewSignature));
+
+ // save the view name in the source db so it can be cleaned up if necessary
+ // (e.g. when the _design doc is deleted, remove all associated view data)
+ function diffFunction(doc) {
+ doc.views = doc.views || {};
+ var fullViewName = viewName;
+ if (fullViewName.indexOf('/') === -1) {
+ fullViewName = viewName + '/' + viewName;
+ }
+ var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {};
+ /* istanbul ignore if */
+ if (depDbs[depDbName]) {
+ return; // no update necessary
+ }
+ depDbs[depDbName] = true;
+ return doc;
+ }
+ return upsert(sourceDB, '_local/' + localDocName, diffFunction).then(function () {
+ return sourceDB.registerDependentDatabase(depDbName).then(function (res) {
+ var db = res.db;
+ db.auto_compaction = true;
+ var view = {
+ name: depDbName,
+ db: db,
+ sourceDB: sourceDB,
+ adapter: sourceDB.adapter,
+ mapFun: mapFun,
+ reduceFun: reduceFun
+ };
+ return view.db.get('_local/lastSeq')["catch"](function (err) {
+ /* istanbul ignore if */
+ if (err.status !== 404) {
+ throw err;
+ }
+ }).then(function (lastSeqDoc) {
+ view.seq = lastSeqDoc ? lastSeqDoc.seq : 0;
+ if (cachedViews) {
+ view.db.once('destroyed', function () {
+ delete cachedViews[viewSignature];
+ });
+ }
+ return view;
+ });
+ });
+ });
+ });
+
+ if (cachedViews) {
+ cachedViews[viewSignature] = promiseForView;
+ }
+ return promiseForView;
+}
+
+var persistentQueues = {};
+var tempViewQueue = new TaskQueue$1();
+var CHANGES_BATCH_SIZE$1 = 50;
+
+function parseViewName(name) {
+ // can be either 'ddocname/viewname' or just 'viewname'
+ // (where the ddoc name is the same)
+ return name.indexOf('/') === -1 ? [name, name] : name.split('/');
+}
+
+function isGenOne(changes) {
+ // only return true if the current change is 1-
+ // and there are no other leafs
+ return changes.length === 1 && /^1-/.test(changes[0].rev);
+}
+
+function emitError(db, e) {
+ try {
+ db.emit('error', e);
+ } catch (err) {
+ guardedConsole('error',
+ 'The user\'s map/reduce function threw an uncaught error.\n' +
+ 'You can debug this error by doing:\n' +
+ 'myDatabase.on(\'error\', function (err) { debugger; });\n' +
+ 'Please double-check your map/reduce function.');
+ guardedConsole('error', e);
+ }
+}
+
+/**
+ * Returns an "abstract" mapreduce object of the form:
+ *
+ * {
+ * query: queryFun,
+ * viewCleanup: viewCleanupFun
+ * }
+ *
+ * Arguments are:
+ *
+ * localDoc: string
+ * This is for the local doc that gets saved in order to track the
+ * "dependent" DBs and clean them up for viewCleanup. It should be
+ * unique, so that indexer plugins don't collide with each other.
+ * mapper: function (mapFunDef, emit)
+ * Returns a map function based on the mapFunDef, which in the case of
+ * normal map/reduce is just the de-stringified function, but may be
+ * something else, such as an object in the case of pouchdb-find.
+ * reducer: function (reduceFunDef)
+ * Ditto, but for reducing. Modules don't have to support reducing
+ * (e.g. pouchdb-find).
+ * ddocValidator: function (ddoc, viewName)
+ * Throws an error if the ddoc or viewName is not valid.
+ * This could be a way to communicate to the user that the configuration for the
+ * indexer is invalid.
+ */
+function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) {
+
+ function tryMap(db, fun, doc) {
+ // emit an event if there was an error thrown by a map function.
+ // putting try/catches in a single function also avoids deoptimizations.
+ try {
+ fun(doc);
+ } catch (e) {
+ emitError(db, e);
+ }
+ }
+
+ function tryReduce(db, fun, keys, values, rereduce) {
+ // same as above, but returning the result or an error. there are two separate
+ // functions to avoid extra memory allocations since the tryCode() case is used
+ // for custom map functions (common) vs this function, which is only used for
+ // custom reduce functions (rare)
+ try {
+ return {output : fun(keys, values, rereduce)};
+ } catch (e) {
+ emitError(db, e);
+ return {error: e};
+ }
+ }
+
+ function sortByKeyThenValue(x, y) {
+ var keyCompare = collate(x.key, y.key);
+ return keyCompare !== 0 ? keyCompare : collate(x.value, y.value);
+ }
+
+ function sliceResults(results, limit, skip) {
+ skip = skip || 0;
+ if (typeof limit === 'number') {
+ return results.slice(skip, limit + skip);
+ } else if (skip > 0) {
+ return results.slice(skip);
+ }
+ return results;
+ }
+
+ function rowToDocId(row) {
+ var val = row.value;
+ // Users can explicitly specify a joined doc _id, or it
+ // defaults to the doc _id that emitted the key/value.
+ var docId = (val && typeof val === 'object' && val._id) || row.id;
+ return docId;
+ }
+
+ function readAttachmentsAsBlobOrBuffer(res) {
+ res.rows.forEach(function (row) {
+ var atts = row.doc && row.doc._attachments;
+ if (!atts) {
+ return;
+ }
+ Object.keys(atts).forEach(function (filename) {
+ var att = atts[filename];
+ atts[filename].data = b64ToBluffer(att.data, att.content_type);
+ });
+ });
+ }
+
+ function postprocessAttachments(opts) {
+ return function (res) {
+ if (opts.include_docs && opts.attachments && opts.binary) {
+ readAttachmentsAsBlobOrBuffer(res);
+ }
+ return res;
+ };
+ }
+
+ function addHttpParam(paramName, opts, params, asJson) {
+ // add an http param from opts to params, optionally json-encoded
+ var val = opts[paramName];
+ if (typeof val !== 'undefined') {
+ if (asJson) {
+ val = encodeURIComponent(JSON.stringify(val));
+ }
+ params.push(paramName + '=' + val);
+ }
+ }
+
+ function coerceInteger(integerCandidate) {
+ if (typeof integerCandidate !== 'undefined') {
+ var asNumber = Number(integerCandidate);
+ // prevents e.g. '1foo' or '1.1' being coerced to 1
+ if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) {
+ return asNumber;
+ } else {
+ return integerCandidate;
+ }
+ }
+ }
+
+ function coerceOptions(opts) {
+ opts.group_level = coerceInteger(opts.group_level);
+ opts.limit = coerceInteger(opts.limit);
+ opts.skip = coerceInteger(opts.skip);
+ return opts;
+ }
+
+ function checkPositiveInteger(number) {
+ if (number) {
+ if (typeof number !== 'number') {
+ return new QueryParseError('Invalid value for integer: "' +
+ number + '"');
+ }
+ if (number < 0) {
+ return new QueryParseError('Invalid value for positive integer: ' +
+ '"' + number + '"');
+ }
+ }
+ }
+
+ function checkQueryParseError(options, fun) {
+ var startkeyName = options.descending ? 'endkey' : 'startkey';
+ var endkeyName = options.descending ? 'startkey' : 'endkey';
+
+ if (typeof options[startkeyName] !== 'undefined' &&
+ typeof options[endkeyName] !== 'undefined' &&
+ collate(options[startkeyName], options[endkeyName]) > 0) {
+ throw new QueryParseError('No rows can match your key range, ' +
+ 'reverse your start_key and end_key or set {descending : true}');
+ } else if (fun.reduce && options.reduce !== false) {
+ if (options.include_docs) {
+ throw new QueryParseError('{include_docs:true} is invalid for reduce');
+ } else if (options.keys && options.keys.length > 1 &&
+ !options.group && !options.group_level) {
+ throw new QueryParseError('Multi-key fetches for reduce views must use ' +
+ '{group: true}');
+ }
+ }
+ ['group_level', 'limit', 'skip'].forEach(function (optionName) {
+ var error = checkPositiveInteger(options[optionName]);
+ if (error) {
+ throw error;
+ }
+ });
+ }
+
+ function httpQuery(db, fun, opts) {
+ // List of parameters to add to the PUT request
+ var params = [];
+ var body;
+ var method = 'GET';
+ var ok, status;
+
+ // If opts.reduce exists and is defined, then add it to the list
+ // of parameters.
+ // If reduce=false then the results are that of only the map function
+ // not the final result of map and reduce.
+ addHttpParam('reduce', opts, params);
+ addHttpParam('include_docs', opts, params);
+ addHttpParam('attachments', opts, params);
+ addHttpParam('limit', opts, params);
+ addHttpParam('descending', opts, params);
+ addHttpParam('group', opts, params);
+ addHttpParam('group_level', opts, params);
+ addHttpParam('skip', opts, params);
+ addHttpParam('stale', opts, params);
+ addHttpParam('conflicts', opts, params);
+ addHttpParam('startkey', opts, params, true);
+ addHttpParam('start_key', opts, params, true);
+ addHttpParam('endkey', opts, params, true);
+ addHttpParam('end_key', opts, params, true);
+ addHttpParam('inclusive_end', opts, params);
+ addHttpParam('key', opts, params, true);
+ addHttpParam('update_seq', opts, params);
+
+ // Format the list of parameters into a valid URI query string
+ params = params.join('&');
+ params = params === '' ? '' : '?' + params;
+
+ // If keys are supplied, issue a POST to circumvent GET query string limits
+ // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
+ if (typeof opts.keys !== 'undefined') {
+ var MAX_URL_LENGTH = 2000;
+ // according to http://stackoverflow.com/a/417184/680742,
+ // the de facto URL length limit is 2000 characters
+
+ var keysAsString =
+ 'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
+ if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
+ // If the keys are short enough, do a GET. we do this to work around
+ // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239)
+ params += (params[0] === '?' ? '&' : '?') + keysAsString;
+ } else {
+ method = 'POST';
+ if (typeof fun === 'string') {
+ body = {keys: opts.keys};
+ } else { // fun is {map : mapfun}, so append to this
+ fun.keys = opts.keys;
+ }
+ }
+ }
+
+ // We are referencing a query defined in the design doc
+ if (typeof fun === 'string') {
+ var parts = parseViewName(fun);
+ return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, {
+ headers: new h({'Content-Type': 'application/json'}),
+ method: method,
+ body: JSON.stringify(body)
+ }).then(function (response) {
+ ok = response.ok;
+ status = response.status;
+ return response.json();
+ }).then(function (result) {
+ if (!ok) {
+ result.status = status;
+ throw generateErrorFromResponse(result);
+ }
+ // fail the entire request if the result contains an error
+ result.rows.forEach(function (row) {
+ /* istanbul ignore if */
+ if (row.value && row.value.error && row.value.error === "builtin_reduce_error") {
+ throw new Error(row.reason);
+ }
+ });
+ return result;
+ }).then(postprocessAttachments(opts));
+ }
+
+ // We are using a temporary view, terrible for performance, good for testing
+ body = body || {};
+ Object.keys(fun).forEach(function (key) {
+ if (Array.isArray(fun[key])) {
+ body[key] = fun[key];
+ } else {
+ body[key] = fun[key].toString();
+ }
+ });
+
+ return db.fetch('_temp_view' + params, {
+ headers: new h({'Content-Type': 'application/json'}),
+ method: 'POST',
+ body: JSON.stringify(body)
+ }).then(function (response) {
+ ok = response.ok;
+ status = response.status;
+ return response.json();
+ }).then(function (result) {
+ if (!ok) {
+ result.status = status;
+ throw generateErrorFromResponse(result);
+ }
+ return result;
+ }).then(postprocessAttachments(opts));
+ }
+
+ // custom adapters can define their own api._query
+ // and override the default behavior
+ /* istanbul ignore next */
+ function customQuery(db, fun, opts) {
+ return new Promise(function (resolve, reject) {
+ db._query(fun, opts, function (err, res) {
+ if (err) {
+ return reject(err);
+ }
+ resolve(res);
+ });
+ });
+ }
+
+ // custom adapters can define their own api._viewCleanup
+ // and override the default behavior
+ /* istanbul ignore next */
+ function customViewCleanup(db) {
+ return new Promise(function (resolve, reject) {
+ db._viewCleanup(function (err, res) {
+ if (err) {
+ return reject(err);
+ }
+ resolve(res);
+ });
+ });
+ }
+
+ function defaultsTo(value) {
+ return function (reason) {
+ /* istanbul ignore else */
+ if (reason.status === 404) {
+ return value;
+ } else {
+ throw reason;
+ }
+ };
+ }
+
+ // returns a promise for a list of docs to update, based on the input docId.
+ // the order doesn't matter, because post-3.2.0, bulkDocs
+ // is an atomic operation in all three adapters.
+ function getDocsToPersist(docId, view, docIdsToChangesAndEmits) {
+ var metaDocId = '_local/doc_' + docId;
+ var defaultMetaDoc = {_id: metaDocId, keys: []};
+ var docData = docIdsToChangesAndEmits.get(docId);
+ var indexableKeysToKeyValues = docData[0];
+ var changes = docData[1];
+
+ function getMetaDoc() {
+ if (isGenOne(changes)) {
+ // generation 1, so we can safely assume initial state
+ // for performance reasons (avoids unnecessary GETs)
+ return Promise.resolve(defaultMetaDoc);
+ }
+ return view.db.get(metaDocId)["catch"](defaultsTo(defaultMetaDoc));
+ }
+
+ function getKeyValueDocs(metaDoc) {
+ if (!metaDoc.keys.length) {
+ // no keys, no need for a lookup
+ return Promise.resolve({rows: []});
+ }
+ return view.db.allDocs({
+ keys: metaDoc.keys,
+ include_docs: true
+ });
+ }
+
+ function processKeyValueDocs(metaDoc, kvDocsRes) {
+ var kvDocs = [];
+ var oldKeys = new ExportedSet();
+
+ for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) {
+ var row = kvDocsRes.rows[i];
+ var doc = row.doc;
+ if (!doc) { // deleted
+ continue;
+ }
+ kvDocs.push(doc);
+ oldKeys.add(doc._id);
+ doc._deleted = !indexableKeysToKeyValues.has(doc._id);
+ if (!doc._deleted) {
+ var keyValue = indexableKeysToKeyValues.get(doc._id);
+ if ('value' in keyValue) {
+ doc.value = keyValue.value;
+ }
+ }
+ }
+ var newKeys = mapToKeysArray(indexableKeysToKeyValues);
+ newKeys.forEach(function (key) {
+ if (!oldKeys.has(key)) {
+ // new doc
+ var kvDoc = {
+ _id: key
+ };
+ var keyValue = indexableKeysToKeyValues.get(key);
+ if ('value' in keyValue) {
+ kvDoc.value = keyValue.value;
+ }
+ kvDocs.push(kvDoc);
+ }
+ });
+ metaDoc.keys = uniq(newKeys.concat(metaDoc.keys));
+ kvDocs.push(metaDoc);
+
+ return kvDocs;
+ }
+
+ return getMetaDoc().then(function (metaDoc) {
+ return getKeyValueDocs(metaDoc).then(function (kvDocsRes) {
+ return processKeyValueDocs(metaDoc, kvDocsRes);
+ });
+ });
+ }
+
+ // updates all emitted key/value docs and metaDocs in the mrview database
+ // for the given batch of documents from the source database
+ function saveKeyValues(view, docIdsToChangesAndEmits, seq) {
+ var seqDocId = '_local/lastSeq';
+ return view.db.get(seqDocId)[
+ "catch"](defaultsTo({_id: seqDocId, seq: 0}))
+ .then(function (lastSeqDoc) {
+ var docIds = mapToKeysArray(docIdsToChangesAndEmits);
+ return Promise.all(docIds.map(function (docId) {
+ return getDocsToPersist(docId, view, docIdsToChangesAndEmits);
+ })).then(function (listOfDocsToPersist) {
+ var docsToPersist = flatten(listOfDocsToPersist);
+ lastSeqDoc.seq = seq;
+ docsToPersist.push(lastSeqDoc);
+ // write all docs in a single operation, update the seq once
+ return view.db.bulkDocs({docs : docsToPersist});
+ });
+ });
+ }
+
+ function getQueue(view) {
+ var viewName = typeof view === 'string' ? view : view.name;
+ var queue = persistentQueues[viewName];
+ if (!queue) {
+ queue = persistentQueues[viewName] = new TaskQueue$1();
+ }
+ return queue;
+ }
+
+ function updateView(view) {
+ return sequentialize(getQueue(view), function () {
+ return updateViewInQueue(view);
+ })();
+ }
+
+ function updateViewInQueue(view) {
+ // bind the emit function once
+ var mapResults;
+ var doc;
+
+ function emit(key, value) {
+ var output = {id: doc._id, key: normalizeKey(key)};
+ // Don't explicitly store the value unless it's defined and non-null.
+ // This saves on storage space, because often people don't use it.
+ if (typeof value !== 'undefined' && value !== null) {
+ output.value = normalizeKey(value);
+ }
+ mapResults.push(output);
+ }
+
+ var mapFun = mapper(view.mapFun, emit);
+
+ var currentSeq = view.seq || 0;
+
+ function processChange(docIdsToChangesAndEmits, seq) {
+ return function () {
+ return saveKeyValues(view, docIdsToChangesAndEmits, seq);
+ };
+ }
+
+ var queue = new TaskQueue$1();
+
+ function processNextBatch() {
+ return view.sourceDB.changes({
+ return_docs: true,
+ conflicts: true,
+ include_docs: true,
+ style: 'all_docs',
+ since: currentSeq,
+ limit: CHANGES_BATCH_SIZE$1
+ }).then(processBatch);
+ }
+
+ function processBatch(response) {
+ var results = response.results;
+ if (!results.length) {
+ return;
+ }
+ var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results);
+ queue.add(processChange(docIdsToChangesAndEmits, currentSeq));
+ if (results.length < CHANGES_BATCH_SIZE$1) {
+ return;
+ }
+ return processNextBatch();
+ }
+
+ function createDocIdsToChangesAndEmits(results) {
+ var docIdsToChangesAndEmits = new ExportedMap();
+ for (var i = 0, len = results.length; i < len; i++) {
+ var change = results[i];
+ if (change.doc._id[0] !== '_') {
+ mapResults = [];
+ doc = change.doc;
+
+ if (!doc._deleted) {
+ tryMap(view.sourceDB, mapFun, doc);
+ }
+ mapResults.sort(sortByKeyThenValue);
+
+ var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults);
+ docIdsToChangesAndEmits.set(change.doc._id, [
+ indexableKeysToKeyValues,
+ change.changes
+ ]);
+ }
+ currentSeq = change.seq;
+ }
+ return docIdsToChangesAndEmits;
+ }
+
+ function createIndexableKeysToKeyValues(mapResults) {
+ var indexableKeysToKeyValues = new ExportedMap();
+ var lastKey;
+ for (var i = 0, len = mapResults.length; i < len; i++) {
+ var emittedKeyValue = mapResults[i];
+ var complexKey = [emittedKeyValue.key, emittedKeyValue.id];
+ if (i > 0 && collate(emittedKeyValue.key, lastKey) === 0) {
+ complexKey.push(i); // dup key+id, so make it unique
+ }
+ indexableKeysToKeyValues.set(toIndexableString(complexKey), emittedKeyValue);
+ lastKey = emittedKeyValue.key;
+ }
+ return indexableKeysToKeyValues;
+ }
+
+ return processNextBatch().then(function () {
+ return queue.finish();
+ }).then(function () {
+ view.seq = currentSeq;
+ });
+ }
+
+ function reduceView(view, results, options) {
+ if (options.group_level === 0) {
+ delete options.group_level;
+ }
+
+ var shouldGroup = options.group || options.group_level;
+
+ var reduceFun = reducer(view.reduceFun);
+
+ var groups = [];
+ var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY :
+ options.group_level;
+ results.forEach(function (e) {
+ var last = groups[groups.length - 1];
+ var groupKey = shouldGroup ? e.key : null;
+
+ // only set group_level for array keys
+ if (shouldGroup && Array.isArray(groupKey)) {
+ groupKey = groupKey.slice(0, lvl);
+ }
+
+ if (last && collate(last.groupKey, groupKey) === 0) {
+ last.keys.push([e.key, e.id]);
+ last.values.push(e.value);
+ return;
+ }
+ groups.push({
+ keys: [[e.key, e.id]],
+ values: [e.value],
+ groupKey: groupKey
+ });
+ });
+ results = [];
+ for (var i = 0, len = groups.length; i < len; i++) {
+ var e = groups[i];
+ var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false);
+ if (reduceTry.error && reduceTry.error instanceof BuiltInError) {
+ // CouchDB returns an error if a built-in errors out
+ throw reduceTry.error;
+ }
+ results.push({
+ // CouchDB just sets the value to null if a non-built-in errors out
+ value: reduceTry.error ? null : reduceTry.output,
+ key: e.groupKey
+ });
+ }
+ // no total_rows/offset when reducing
+ return {rows: sliceResults(results, options.limit, options.skip)};
+ }
+
+ function queryView(view, opts) {
+ return sequentialize(getQueue(view), function () {
+ return queryViewInQueue(view, opts);
+ })();
+ }
+
+ function queryViewInQueue(view, opts) {
+ var totalRows;
+ var shouldReduce = view.reduceFun && opts.reduce !== false;
+ var skip = opts.skip || 0;
+ if (typeof opts.keys !== 'undefined' && !opts.keys.length) {
+ // equivalent query
+ opts.limit = 0;
+ delete opts.keys;
+ }
+
+ function fetchFromView(viewOpts) {
+ viewOpts.include_docs = true;
+ return view.db.allDocs(viewOpts).then(function (res) {
+ totalRows = res.total_rows;
+ return res.rows.map(function (result) {
+
+ // implicit migration - in older versions of PouchDB,
+ // we explicitly stored the doc as {id: ..., key: ..., value: ...}
+ // this is tested in a migration test
+ /* istanbul ignore next */
+ if ('value' in result.doc && typeof result.doc.value === 'object' &&
+ result.doc.value !== null) {
+ var keys = Object.keys(result.doc.value).sort();
+ // this detection method is not perfect, but it's unlikely the user
+ // emitted a value which was an object with these 3 exact keys
+ var expectedKeys = ['id', 'key', 'value'];
+ if (!(keys < expectedKeys || keys > expectedKeys)) {
+ return result.doc.value;
+ }
+ }
+
+ var parsedKeyAndDocId = parseIndexableString(result.doc._id);
+ return {
+ key: parsedKeyAndDocId[0],
+ id: parsedKeyAndDocId[1],
+ value: ('value' in result.doc ? result.doc.value : null)
+ };
+ });
+ });
+ }
+
+ function onMapResultsReady(rows) {
+ var finalResults;
+ if (shouldReduce) {
+ finalResults = reduceView(view, rows, opts);
+ } else {
+ finalResults = {
+ total_rows: totalRows,
+ offset: skip,
+ rows: rows
+ };
+ }
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ finalResults.update_seq = view.seq;
+ }
+ if (opts.include_docs) {
+ var docIds = uniq(rows.map(rowToDocId));
+
+ return view.sourceDB.allDocs({
+ keys: docIds,
+ include_docs: true,
+ conflicts: opts.conflicts,
+ attachments: opts.attachments,
+ binary: opts.binary
+ }).then(function (allDocsRes) {
+ var docIdsToDocs = new ExportedMap();
+ allDocsRes.rows.forEach(function (row) {
+ docIdsToDocs.set(row.id, row.doc);
+ });
+ rows.forEach(function (row) {
+ var docId = rowToDocId(row);
+ var doc = docIdsToDocs.get(docId);
+ if (doc) {
+ row.doc = doc;
+ }
+ });
+ return finalResults;
+ });
+ } else {
+ return finalResults;
+ }
+ }
+
+ if (typeof opts.keys !== 'undefined') {
+ var keys = opts.keys;
+ var fetchPromises = keys.map(function (key) {
+ var viewOpts = {
+ startkey : toIndexableString([key]),
+ endkey : toIndexableString([key, {}])
+ };
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ viewOpts.update_seq = true;
+ }
+ return fetchFromView(viewOpts);
+ });
+ return Promise.all(fetchPromises).then(flatten).then(onMapResultsReady);
+ } else { // normal query, no 'keys'
+ var viewOpts = {
+ descending : opts.descending
+ };
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ viewOpts.update_seq = true;
+ }
+ var startkey;
+ var endkey;
+ if ('start_key' in opts) {
+ startkey = opts.start_key;
+ }
+ if ('startkey' in opts) {
+ startkey = opts.startkey;
+ }
+ if ('end_key' in opts) {
+ endkey = opts.end_key;
+ }
+ if ('endkey' in opts) {
+ endkey = opts.endkey;
+ }
+ if (typeof startkey !== 'undefined') {
+ viewOpts.startkey = opts.descending ?
+ toIndexableString([startkey, {}]) :
+ toIndexableString([startkey]);
+ }
+ if (typeof endkey !== 'undefined') {
+ var inclusiveEnd = opts.inclusive_end !== false;
+ if (opts.descending) {
+ inclusiveEnd = !inclusiveEnd;
+ }
+
+ viewOpts.endkey = toIndexableString(
+ inclusiveEnd ? [endkey, {}] : [endkey]);
+ }
+ if (typeof opts.key !== 'undefined') {
+ var keyStart = toIndexableString([opts.key]);
+ var keyEnd = toIndexableString([opts.key, {}]);
+ if (viewOpts.descending) {
+ viewOpts.endkey = keyStart;
+ viewOpts.startkey = keyEnd;
+ } else {
+ viewOpts.startkey = keyStart;
+ viewOpts.endkey = keyEnd;
+ }
+ }
+ if (!shouldReduce) {
+ if (typeof opts.limit === 'number') {
+ viewOpts.limit = opts.limit;
+ }
+ viewOpts.skip = skip;
+ }
+ return fetchFromView(viewOpts).then(onMapResultsReady);
+ }
+ }
+
+ function httpViewCleanup(db) {
+ return db.fetch('_view_cleanup', {
+ headers: new h({'Content-Type': 'application/json'}),
+ method: 'POST'
+ }).then(function (response) {
+ return response.json();
+ });
+ }
+
+ function localViewCleanup(db) {
+ return db.get('_local/' + localDocName).then(function (metaDoc) {
+ var docsToViews = new ExportedMap();
+ Object.keys(metaDoc.views).forEach(function (fullViewName) {
+ var parts = parseViewName(fullViewName);
+ var designDocName = '_design/' + parts[0];
+ var viewName = parts[1];
+ var views = docsToViews.get(designDocName);
+ if (!views) {
+ views = new ExportedSet();
+ docsToViews.set(designDocName, views);
+ }
+ views.add(viewName);
+ });
+ var opts = {
+ keys : mapToKeysArray(docsToViews),
+ include_docs : true
+ };
+ return db.allDocs(opts).then(function (res) {
+ var viewsToStatus = {};
+ res.rows.forEach(function (row) {
+ var ddocName = row.key.substring(8); // cuts off '_design/'
+ docsToViews.get(row.key).forEach(function (viewName) {
+ var fullViewName = ddocName + '/' + viewName;
+ /* istanbul ignore if */
+ if (!metaDoc.views[fullViewName]) {
+ // new format, without slashes, to support PouchDB 2.2.0
+ // migration test in pouchdb's browser.migration.js verifies this
+ fullViewName = viewName;
+ }
+ var viewDBNames = Object.keys(metaDoc.views[fullViewName]);
+ // design doc deleted, or view function nonexistent
+ var statusIsGood = row.doc && row.doc.views &&
+ row.doc.views[viewName];
+ viewDBNames.forEach(function (viewDBName) {
+ viewsToStatus[viewDBName] =
+ viewsToStatus[viewDBName] || statusIsGood;
+ });
+ });
+ });
+ var dbsToDelete = Object.keys(viewsToStatus).filter(
+ function (viewDBName) { return !viewsToStatus[viewDBName]; });
+ var destroyPromises = dbsToDelete.map(function (viewDBName) {
+ return sequentialize(getQueue(viewDBName), function () {
+ return new db.constructor(viewDBName, db.__opts).destroy();
+ })();
+ });
+ return Promise.all(destroyPromises).then(function () {
+ return {ok: true};
+ });
+ });
+ }, defaultsTo({ok: true}));
+ }
+
+ function queryPromised(db, fun, opts) {
+ /* istanbul ignore next */
+ if (typeof db._query === 'function') {
+ return customQuery(db, fun, opts);
+ }
+ if (isRemote(db)) {
+ return httpQuery(db, fun, opts);
+ }
+
+ if (typeof fun !== 'string') {
+ // temp_view
+ checkQueryParseError(opts, fun);
+
+ tempViewQueue.add(function () {
+ var createViewPromise = createView(
+ /* sourceDB */ db,
+ /* viewName */ 'temp_view/temp_view',
+ /* mapFun */ fun.map,
+ /* reduceFun */ fun.reduce,
+ /* temporary */ true,
+ /* localDocName */ localDocName);
+ return createViewPromise.then(function (view) {
+ return fin(updateView(view).then(function () {
+ return queryView(view, opts);
+ }), function () {
+ return view.db.destroy();
+ });
+ });
+ });
+ return tempViewQueue.finish();
+ } else {
+ // persistent view
+ var fullViewName = fun;
+ var parts = parseViewName(fullViewName);
+ var designDocName = parts[0];
+ var viewName = parts[1];
+ return db.get('_design/' + designDocName).then(function (doc) {
+ var fun = doc.views && doc.views[viewName];
+
+ if (!fun) {
+ // basic validator; it's assumed that every subclass would want this
+ throw new NotFoundError('ddoc ' + doc._id + ' has no view named ' +
+ viewName);
+ }
+
+ ddocValidator(doc, viewName);
+ checkQueryParseError(opts, fun);
+
+ var createViewPromise = createView(
+ /* sourceDB */ db,
+ /* viewName */ fullViewName,
+ /* mapFun */ fun.map,
+ /* reduceFun */ fun.reduce,
+ /* temporary */ false,
+ /* localDocName */ localDocName);
+ return createViewPromise.then(function (view) {
+ if (opts.stale === 'ok' || opts.stale === 'update_after') {
+ if (opts.stale === 'update_after') {
+ immediate(function () {
+ updateView(view);
+ });
+ }
+ return queryView(view, opts);
+ } else { // stale not ok
+ return updateView(view).then(function () {
+ return queryView(view, opts);
+ });
+ }
+ });
+ });
+ }
+ }
+
+ function abstractQuery(fun, opts, callback) {
+ var db = this;
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts = opts ? coerceOptions(opts) : {};
+
+ if (typeof fun === 'function') {
+ fun = {map : fun};
+ }
+
+ var promise = Promise.resolve().then(function () {
+ return queryPromised(db, fun, opts);
+ });
+ promisedCallback(promise, callback);
+ return promise;
+ }
+
+ var abstractViewCleanup = callbackify(function () {
+ var db = this;
+ /* istanbul ignore next */
+ if (typeof db._viewCleanup === 'function') {
+ return customViewCleanup(db);
+ }
+ if (isRemote(db)) {
+ return httpViewCleanup(db);
+ }
+ return localViewCleanup(db);
+ });
+
+ return {
+ query: abstractQuery,
+ viewCleanup: abstractViewCleanup
+ };
+}
+
+var builtInReduce = {
+ _sum: function (keys, values) {
+ return sum(values);
+ },
+
+ _count: function (keys, values) {
+ return values.length;
+ },
+
+ _stats: function (keys, values) {
+ // no need to implement rereduce=true, because Pouch
+ // will never call it
+ function sumsqr(values) {
+ var _sumsqr = 0;
+ for (var i = 0, len = values.length; i < len; i++) {
+ var num = values[i];
+ _sumsqr += (num * num);
+ }
+ return _sumsqr;
+ }
+ return {
+ sum : sum(values),
+ min : Math.min.apply(null, values),
+ max : Math.max.apply(null, values),
+ count : values.length,
+ sumsqr : sumsqr(values)
+ };
+ }
+};
+
+function getBuiltIn(reduceFunString) {
+ if (/^_sum/.test(reduceFunString)) {
+ return builtInReduce._sum;
+ } else if (/^_count/.test(reduceFunString)) {
+ return builtInReduce._count;
+ } else if (/^_stats/.test(reduceFunString)) {
+ return builtInReduce._stats;
+ } else if (/^_/.test(reduceFunString)) {
+ throw new Error(reduceFunString + ' is not a supported reduce function.');
+ }
+}
+
+function mapper(mapFun, emit) {
+ // for temp_views one can use emit(doc, emit), see #38
+ if (typeof mapFun === "function" && mapFun.length === 2) {
+ var origMap = mapFun;
+ return function (doc) {
+ return origMap(doc, emit);
+ };
+ } else {
+ return evalFunctionWithEval(mapFun.toString(), emit);
+ }
+}
+
+function reducer(reduceFun) {
+ var reduceFunString = reduceFun.toString();
+ var builtIn = getBuiltIn(reduceFunString);
+ if (builtIn) {
+ return builtIn;
+ } else {
+ return evalFunctionWithEval(reduceFunString);
+ }
+}
+
+function ddocValidator(ddoc, viewName) {
+ var fun = ddoc.views && ddoc.views[viewName];
+ if (typeof fun.map !== 'string') {
+ throw new NotFoundError('ddoc ' + ddoc._id + ' has no string view named ' +
+ viewName + ', instead found object of type: ' + typeof fun.map);
+ }
+}
+
+var localDocName = 'mrviews';
+var abstract = createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator);
+
+function query(fun, opts, callback) {
+ return abstract.query.call(this, fun, opts, callback);
+}
+
+function viewCleanup(callback) {
+ return abstract.viewCleanup.call(this, callback);
+}
+
+var mapreduce = {
+ query: query,
+ viewCleanup: viewCleanup
+};
+
+function isGenOne$1(rev$$1) {
+ return /^1-/.test(rev$$1);
+}
+
+function fileHasChanged(localDoc, remoteDoc, filename) {
+ return !localDoc._attachments ||
+ !localDoc._attachments[filename] ||
+ localDoc._attachments[filename].digest !== remoteDoc._attachments[filename].digest;
+}
+
+function getDocAttachments(db, doc) {
+ var filenames = Object.keys(doc._attachments);
+ return Promise.all(filenames.map(function (filename) {
+ return db.getAttachment(doc._id, filename, {rev: doc._rev});
+ }));
+}
+
+function getDocAttachmentsFromTargetOrSource(target, src, doc) {
+ var doCheckForLocalAttachments = isRemote(src) && !isRemote(target);
+ var filenames = Object.keys(doc._attachments);
+
+ if (!doCheckForLocalAttachments) {
+ return getDocAttachments(src, doc);
+ }
+
+ return target.get(doc._id).then(function (localDoc) {
+ return Promise.all(filenames.map(function (filename) {
+ if (fileHasChanged(localDoc, doc, filename)) {
+ return src.getAttachment(doc._id, filename);
+ }
+
+ return target.getAttachment(localDoc._id, filename);
+ }));
+ })["catch"](function (error) {
+ /* istanbul ignore if */
+ if (error.status !== 404) {
+ throw error;
+ }
+
+ return getDocAttachments(src, doc);
+ });
+}
+
+function createBulkGetOpts(diffs) {
+ var requests = [];
+ Object.keys(diffs).forEach(function (id) {
+ var missingRevs = diffs[id].missing;
+ missingRevs.forEach(function (missingRev) {
+ requests.push({
+ id: id,
+ rev: missingRev
+ });
+ });
+ });
+
+ return {
+ docs: requests,
+ revs: true,
+ latest: true
+ };
+}
+
+//
+// Fetch all the documents from the src as described in the "diffs",
+// which is a mapping of docs IDs to revisions. If the state ever
+// changes to "cancelled", then the returned promise will be rejected.
+// Else it will be resolved with a list of fetched documents.
+//
+function getDocs(src, target, diffs, state) {
+ diffs = clone(diffs); // we do not need to modify this
+
+ var resultDocs = [],
+ ok = true;
+
+ function getAllDocs() {
+
+ var bulkGetOpts = createBulkGetOpts(diffs);
+
+ if (!bulkGetOpts.docs.length) { // optimization: skip empty requests
+ return;
+ }
+
+ return src.bulkGet(bulkGetOpts).then(function (bulkGetResponse) {
+ /* istanbul ignore if */
+ if (state.cancelled) {
+ throw new Error('cancelled');
+ }
+ return Promise.all(bulkGetResponse.results.map(function (bulkGetInfo) {
+ return Promise.all(bulkGetInfo.docs.map(function (doc) {
+ var remoteDoc = doc.ok;
+
+ if (doc.error) {
+ // when AUTO_COMPACTION is set, docs can be returned which look
+ // like this: {"missing":"1-7c3ac256b693c462af8442f992b83696"}
+ ok = false;
+ }
+
+ if (!remoteDoc || !remoteDoc._attachments) {
+ return remoteDoc;
+ }
+
+ return getDocAttachmentsFromTargetOrSource(target, src, remoteDoc)
+ .then(function (attachments) {
+ var filenames = Object.keys(remoteDoc._attachments);
+ attachments
+ .forEach(function (attachment, i) {
+ var att = remoteDoc._attachments[filenames[i]];
+ delete att.stub;
+ delete att.length;
+ att.data = attachment;
+ });
+
+ return remoteDoc;
+ });
+ }));
+ }))
+
+ .then(function (results) {
+ resultDocs = resultDocs.concat(flatten(results).filter(Boolean));
+ });
+ });
+ }
+
+ function hasAttachments(doc) {
+ return doc._attachments && Object.keys(doc._attachments).length > 0;
+ }
+
+ function hasConflicts(doc) {
+ return doc._conflicts && doc._conflicts.length > 0;
+ }
+
+ function fetchRevisionOneDocs(ids) {
+ // Optimization: fetch gen-1 docs and attachments in
+ // a single request using _all_docs
+ return src.allDocs({
+ keys: ids,
+ include_docs: true,
+ conflicts: true
+ }).then(function (res) {
+ if (state.cancelled) {
+ throw new Error('cancelled');
+ }
+ res.rows.forEach(function (row) {
+ if (row.deleted || !row.doc || !isGenOne$1(row.value.rev) ||
+ hasAttachments(row.doc) || hasConflicts(row.doc)) {
+ // if any of these conditions apply, we need to fetch using get()
+ return;
+ }
+
+ // strip _conflicts array to appease CSG (#5793)
+ /* istanbul ignore if */
+ if (row.doc._conflicts) {
+ delete row.doc._conflicts;
+ }
+
+ // the doc we got back from allDocs() is sufficient
+ resultDocs.push(row.doc);
+ delete diffs[row.id];
+ });
+ });
+ }
+
+ function getRevisionOneDocs() {
+ // filter out the generation 1 docs and get them
+ // leaving the non-generation one docs to be got otherwise
+ var ids = Object.keys(diffs).filter(function (id) {
+ var missing = diffs[id].missing;
+ return missing.length === 1 && isGenOne$1(missing[0]);
+ });
+ if (ids.length > 0) {
+ return fetchRevisionOneDocs(ids);
+ }
+ }
+
+ function returnResult() {
+ return { ok:ok, docs:resultDocs };
+ }
+
+ return Promise.resolve()
+ .then(getRevisionOneDocs)
+ .then(getAllDocs)
+ .then(returnResult);
+}
+
+var CHECKPOINT_VERSION = 1;
+var REPLICATOR = "pouchdb";
+// This is an arbitrary number to limit the
+// amount of replication history we save in the checkpoint.
+// If we save too much, the checkpoing docs will become very big,
+// if we save fewer, we'll run a greater risk of having to
+// read all the changes from 0 when checkpoint PUTs fail
+// CouchDB 2.0 has a more involved history pruning,
+// but let's go for the simple version for now.
+var CHECKPOINT_HISTORY_SIZE = 5;
+var LOWEST_SEQ = 0;
+
+function updateCheckpoint(db, id, checkpoint, session, returnValue) {
+ return db.get(id)["catch"](function (err) {
+ if (err.status === 404) {
+ if (db.adapter === 'http' || db.adapter === 'https') {
+ explainError(
+ 404, 'PouchDB is just checking if a remote checkpoint exists.'
+ );
+ }
+ return {
+ session_id: session,
+ _id: id,
+ history: [],
+ replicator: REPLICATOR,
+ version: CHECKPOINT_VERSION
+ };
+ }
+ throw err;
+ }).then(function (doc) {
+ if (returnValue.cancelled) {
+ return;
+ }
+
+ // if the checkpoint has not changed, do not update
+ if (doc.last_seq === checkpoint) {
+ return;
+ }
+
+ // Filter out current entry for this replication
+ doc.history = (doc.history || []).filter(function (item) {
+ return item.session_id !== session;
+ });
+
+ // Add the latest checkpoint to history
+ doc.history.unshift({
+ last_seq: checkpoint,
+ session_id: session
+ });
+
+ // Just take the last pieces in history, to
+ // avoid really big checkpoint docs.
+ // see comment on history size above
+ doc.history = doc.history.slice(0, CHECKPOINT_HISTORY_SIZE);
+
+ doc.version = CHECKPOINT_VERSION;
+ doc.replicator = REPLICATOR;
+
+ doc.session_id = session;
+ doc.last_seq = checkpoint;
+
+ return db.put(doc)["catch"](function (err) {
+ if (err.status === 409) {
+ // retry; someone is trying to write a checkpoint simultaneously
+ return updateCheckpoint(db, id, checkpoint, session, returnValue);
+ }
+ throw err;
+ });
+ });
+}
+
+function Checkpointer(src, target, id, returnValue, opts) {
+ this.src = src;
+ this.target = target;
+ this.id = id;
+ this.returnValue = returnValue;
+ this.opts = opts || {};
+}
+
+Checkpointer.prototype.writeCheckpoint = function (checkpoint, session) {
+ var self = this;
+ return this.updateTarget(checkpoint, session).then(function () {
+ return self.updateSource(checkpoint, session);
+ });
+};
+
+Checkpointer.prototype.updateTarget = function (checkpoint, session) {
+ if (this.opts.writeTargetCheckpoint) {
+ return updateCheckpoint(this.target, this.id, checkpoint,
+ session, this.returnValue);
+ } else {
+ return Promise.resolve(true);
+ }
+};
+
+Checkpointer.prototype.updateSource = function (checkpoint, session) {
+ if (this.opts.writeSourceCheckpoint) {
+ var self = this;
+ return updateCheckpoint(this.src, this.id, checkpoint,
+ session, this.returnValue)[
+ "catch"](function (err) {
+ if (isForbiddenError(err)) {
+ self.opts.writeSourceCheckpoint = false;
+ return true;
+ }
+ throw err;
+ });
+ } else {
+ return Promise.resolve(true);
+ }
+};
+
+var comparisons = {
+ "undefined": function (targetDoc, sourceDoc) {
+ // This is the previous comparison function
+ if (collate(targetDoc.last_seq, sourceDoc.last_seq) === 0) {
+ return sourceDoc.last_seq;
+ }
+ /* istanbul ignore next */
+ return 0;
+ },
+ "1": function (targetDoc, sourceDoc) {
+ // This is the comparison function ported from CouchDB
+ return compareReplicationLogs(sourceDoc, targetDoc).last_seq;
+ }
+};
+
+Checkpointer.prototype.getCheckpoint = function () {
+ var self = this;
+
+ if (self.opts && self.opts.writeSourceCheckpoint && !self.opts.writeTargetCheckpoint) {
+ return self.src.get(self.id).then(function (sourceDoc) {
+ return sourceDoc.last_seq || LOWEST_SEQ;
+ })["catch"](function (err) {
+ /* istanbul ignore if */
+ if (err.status !== 404) {
+ throw err;
+ }
+ return LOWEST_SEQ;
+ });
+ }
+
+ return self.target.get(self.id).then(function (targetDoc) {
+ if (self.opts && self.opts.writeTargetCheckpoint && !self.opts.writeSourceCheckpoint) {
+ return targetDoc.last_seq || LOWEST_SEQ;
+ }
+
+ return self.src.get(self.id).then(function (sourceDoc) {
+ // Since we can't migrate an old version doc to a new one
+ // (no session id), we just go with the lowest seq in this case
+ /* istanbul ignore if */
+ if (targetDoc.version !== sourceDoc.version) {
+ return LOWEST_SEQ;
+ }
+
+ var version;
+ if (targetDoc.version) {
+ version = targetDoc.version.toString();
+ } else {
+ version = "undefined";
+ }
+
+ if (version in comparisons) {
+ return comparisons[version](targetDoc, sourceDoc);
+ }
+ /* istanbul ignore next */
+ return LOWEST_SEQ;
+ }, function (err) {
+ if (err.status === 404 && targetDoc.last_seq) {
+ return self.src.put({
+ _id: self.id,
+ last_seq: LOWEST_SEQ
+ }).then(function () {
+ return LOWEST_SEQ;
+ }, function (err) {
+ if (isForbiddenError(err)) {
+ self.opts.writeSourceCheckpoint = false;
+ return targetDoc.last_seq;
+ }
+ /* istanbul ignore next */
+ return LOWEST_SEQ;
+ });
+ }
+ throw err;
+ });
+ })["catch"](function (err) {
+ if (err.status !== 404) {
+ throw err;
+ }
+ return LOWEST_SEQ;
+ });
+};
+// This checkpoint comparison is ported from CouchDBs source
+// they come from here:
+// https://github.com/apache/couchdb-couch-replicator/blob/master/src/couch_replicator.erl#L863-L906
+
+function compareReplicationLogs(srcDoc, tgtDoc) {
+ if (srcDoc.session_id === tgtDoc.session_id) {
+ return {
+ last_seq: srcDoc.last_seq,
+ history: srcDoc.history
+ };
+ }
+
+ return compareReplicationHistory(srcDoc.history, tgtDoc.history);
+}
+
+function compareReplicationHistory(sourceHistory, targetHistory) {
+ // the erlang loop via function arguments is not so easy to repeat in JS
+ // therefore, doing this as recursion
+ var S = sourceHistory[0];
+ var sourceRest = sourceHistory.slice(1);
+ var T = targetHistory[0];
+ var targetRest = targetHistory.slice(1);
+
+ if (!S || targetHistory.length === 0) {
+ return {
+ last_seq: LOWEST_SEQ,
+ history: []
+ };
+ }
+
+ var sourceId = S.session_id;
+ /* istanbul ignore if */
+ if (hasSessionId(sourceId, targetHistory)) {
+ return {
+ last_seq: S.last_seq,
+ history: sourceHistory
+ };
+ }
+
+ var targetId = T.session_id;
+ if (hasSessionId(targetId, sourceRest)) {
+ return {
+ last_seq: T.last_seq,
+ history: targetRest
+ };
+ }
+
+ return compareReplicationHistory(sourceRest, targetRest);
+}
+
+function hasSessionId(sessionId, history) {
+ var props = history[0];
+ var rest = history.slice(1);
+
+ if (!sessionId || history.length === 0) {
+ return false;
+ }
+
+ if (sessionId === props.session_id) {
+ return true;
+ }
+
+ return hasSessionId(sessionId, rest);
+}
+
+function isForbiddenError(err) {
+ return typeof err.status === 'number' && Math.floor(err.status / 100) === 4;
+}
+
+var STARTING_BACK_OFF = 0;
+
+function backOff(opts, returnValue, error, callback) {
+ if (opts.retry === false) {
+ returnValue.emit('error', error);
+ returnValue.removeAllListeners();
+ return;
+ }
+ /* istanbul ignore if */
+ if (typeof opts.back_off_function !== 'function') {
+ opts.back_off_function = defaultBackOff;
+ }
+ returnValue.emit('requestError', error);
+ if (returnValue.state === 'active' || returnValue.state === 'pending') {
+ returnValue.emit('paused', error);
+ returnValue.state = 'stopped';
+ var backOffSet = function backoffTimeSet() {
+ opts.current_back_off = STARTING_BACK_OFF;
+ };
+ var removeBackOffSetter = function removeBackOffTimeSet() {
+ returnValue.removeListener('active', backOffSet);
+ };
+ returnValue.once('paused', removeBackOffSetter);
+ returnValue.once('active', backOffSet);
+ }
+
+ opts.current_back_off = opts.current_back_off || STARTING_BACK_OFF;
+ opts.current_back_off = opts.back_off_function(opts.current_back_off);
+ setTimeout(callback, opts.current_back_off);
+}
+
+function sortObjectPropertiesByKey(queryParams) {
+ return Object.keys(queryParams).sort(collate).reduce(function (result, key) {
+ result[key] = queryParams[key];
+ return result;
+ }, {});
+}
+
+// Generate a unique id particular to this replication.
+// Not guaranteed to align perfectly with CouchDB's rep ids.
+function generateReplicationId(src, target, opts) {
+ var docIds = opts.doc_ids ? opts.doc_ids.sort(collate) : '';
+ var filterFun = opts.filter ? opts.filter.toString() : '';
+ var queryParams = '';
+ var filterViewName = '';
+ var selector = '';
+
+ // possibility for checkpoints to be lost here as behaviour of
+ // JSON.stringify is not stable (see #6226)
+ /* istanbul ignore if */
+ if (opts.selector) {
+ selector = JSON.stringify(opts.selector);
+ }
+
+ if (opts.filter && opts.query_params) {
+ queryParams = JSON.stringify(sortObjectPropertiesByKey(opts.query_params));
+ }
+
+ if (opts.filter && opts.filter === '_view') {
+ filterViewName = opts.view.toString();
+ }
+
+ return Promise.all([src.id(), target.id()]).then(function (res) {
+ var queryData = res[0] + res[1] + filterFun + filterViewName +
+ queryParams + docIds + selector;
+ return new Promise(function (resolve) {
+ binaryMd5(queryData, resolve);
+ });
+ }).then(function (md5sum) {
+ // can't use straight-up md5 alphabet, because
+ // the char '/' is interpreted as being for attachments,
+ // and + is also not url-safe
+ md5sum = md5sum.replace(/\//g, '.').replace(/\+/g, '_');
+ return '_local/' + md5sum;
+ });
+}
+
+function replicate(src, target, opts, returnValue, result) {
+ var batches = []; // list of batches to be processed
+ var currentBatch; // the batch currently being processed
+ var pendingBatch = {
+ seq: 0,
+ changes: [],
+ docs: []
+ }; // next batch, not yet ready to be processed
+ var writingCheckpoint = false; // true while checkpoint is being written
+ var changesCompleted = false; // true when all changes received
+ var replicationCompleted = false; // true when replication has completed
+ var last_seq = 0;
+ var continuous = opts.continuous || opts.live || false;
+ var batch_size = opts.batch_size || 100;
+ var batches_limit = opts.batches_limit || 10;
+ var changesPending = false; // true while src.changes is running
+ var doc_ids = opts.doc_ids;
+ var selector = opts.selector;
+ var repId;
+ var checkpointer;
+ var changedDocs = [];
+ // Like couchdb, every replication gets a unique session id
+ var session = uuid();
+
+ result = result || {
+ ok: true,
+ start_time: new Date().toISOString(),
+ docs_read: 0,
+ docs_written: 0,
+ doc_write_failures: 0,
+ errors: []
+ };
+
+ var changesOpts = {};
+ returnValue.ready(src, target);
+
+ function initCheckpointer() {
+ if (checkpointer) {
+ return Promise.resolve();
+ }
+ return generateReplicationId(src, target, opts).then(function (res) {
+ repId = res;
+
+ var checkpointOpts = {};
+ if (opts.checkpoint === false) {
+ checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: false };
+ } else if (opts.checkpoint === 'source') {
+ checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: false };
+ } else if (opts.checkpoint === 'target') {
+ checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: true };
+ } else {
+ checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: true };
+ }
+
+ checkpointer = new Checkpointer(src, target, repId, returnValue, checkpointOpts);
+ });
+ }
+
+ function writeDocs() {
+ changedDocs = [];
+
+ if (currentBatch.docs.length === 0) {
+ return;
+ }
+ var docs = currentBatch.docs;
+ var bulkOpts = {timeout: opts.timeout};
+ return target.bulkDocs({docs: docs, new_edits: false}, bulkOpts).then(function (res) {
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ throw new Error('cancelled');
+ }
+
+ // `res` doesn't include full documents (which live in `docs`), so we create a map of
+ // (id -> error), and check for errors while iterating over `docs`
+ var errorsById = Object.create(null);
+ res.forEach(function (res) {
+ if (res.error) {
+ errorsById[res.id] = res;
+ }
+ });
+
+ var errorsNo = Object.keys(errorsById).length;
+ result.doc_write_failures += errorsNo;
+ result.docs_written += docs.length - errorsNo;
+
+ docs.forEach(function (doc) {
+ var error = errorsById[doc._id];
+ if (error) {
+ result.errors.push(error);
+ // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway)
+ var errorName = (error.name || '').toLowerCase();
+ if (errorName === 'unauthorized' || errorName === 'forbidden') {
+ returnValue.emit('denied', clone(error));
+ } else {
+ throw error;
+ }
+ } else {
+ changedDocs.push(doc);
+ }
+ });
+
+ }, function (err) {
+ result.doc_write_failures += docs.length;
+ throw err;
+ });
+ }
+
+ function finishBatch() {
+ if (currentBatch.error) {
+ throw new Error('There was a problem getting docs.');
+ }
+ result.last_seq = last_seq = currentBatch.seq;
+ var outResult = clone(result);
+ if (changedDocs.length) {
+ outResult.docs = changedDocs;
+ // Attach 'pending' property if server supports it (CouchDB 2.0+)
+ /* istanbul ignore if */
+ if (typeof currentBatch.pending === 'number') {
+ outResult.pending = currentBatch.pending;
+ delete currentBatch.pending;
+ }
+ returnValue.emit('change', outResult);
+ }
+ writingCheckpoint = true;
+ return checkpointer.writeCheckpoint(currentBatch.seq,
+ session).then(function () {
+ writingCheckpoint = false;
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ throw new Error('cancelled');
+ }
+ currentBatch = undefined;
+ getChanges();
+ })["catch"](function (err) {
+ onCheckpointError(err);
+ throw err;
+ });
+ }
+
+ function getDiffs() {
+ var diff = {};
+ currentBatch.changes.forEach(function (change) {
+ // Couchbase Sync Gateway emits these, but we can ignore them
+ /* istanbul ignore if */
+ if (change.id === "_user/") {
+ return;
+ }
+ diff[change.id] = change.changes.map(function (x) {
+ return x.rev;
+ });
+ });
+ return target.revsDiff(diff).then(function (diffs) {
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ throw new Error('cancelled');
+ }
+ // currentBatch.diffs elements are deleted as the documents are written
+ currentBatch.diffs = diffs;
+ });
+ }
+
+ function getBatchDocs() {
+ return getDocs(src, target, currentBatch.diffs, returnValue).then(function (got) {
+ currentBatch.error = !got.ok;
+ got.docs.forEach(function (doc) {
+ delete currentBatch.diffs[doc._id];
+ result.docs_read++;
+ currentBatch.docs.push(doc);
+ });
+ });
+ }
+
+ function startNextBatch() {
+ if (returnValue.cancelled || currentBatch) {
+ return;
+ }
+ if (batches.length === 0) {
+ processPendingBatch(true);
+ return;
+ }
+ currentBatch = batches.shift();
+ getDiffs()
+ .then(getBatchDocs)
+ .then(writeDocs)
+ .then(finishBatch)
+ .then(startNextBatch)[
+ "catch"](function (err) {
+ abortReplication('batch processing terminated with error', err);
+ });
+ }
+
+
+ function processPendingBatch(immediate$$1) {
+ if (pendingBatch.changes.length === 0) {
+ if (batches.length === 0 && !currentBatch) {
+ if ((continuous && changesOpts.live) || changesCompleted) {
+ returnValue.state = 'pending';
+ returnValue.emit('paused');
+ }
+ if (changesCompleted) {
+ completeReplication();
+ }
+ }
+ return;
+ }
+ if (
+ immediate$$1 ||
+ changesCompleted ||
+ pendingBatch.changes.length >= batch_size
+ ) {
+ batches.push(pendingBatch);
+ pendingBatch = {
+ seq: 0,
+ changes: [],
+ docs: []
+ };
+ if (returnValue.state === 'pending' || returnValue.state === 'stopped') {
+ returnValue.state = 'active';
+ returnValue.emit('active');
+ }
+ startNextBatch();
+ }
+ }
+
+
+ function abortReplication(reason, err) {
+ if (replicationCompleted) {
+ return;
+ }
+ if (!err.message) {
+ err.message = reason;
+ }
+ result.ok = false;
+ result.status = 'aborting';
+ batches = [];
+ pendingBatch = {
+ seq: 0,
+ changes: [],
+ docs: []
+ };
+ completeReplication(err);
+ }
+
+
+ function completeReplication(fatalError) {
+ if (replicationCompleted) {
+ return;
+ }
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ result.status = 'cancelled';
+ if (writingCheckpoint) {
+ return;
+ }
+ }
+ result.status = result.status || 'complete';
+ result.end_time = new Date().toISOString();
+ result.last_seq = last_seq;
+ replicationCompleted = true;
+
+ if (fatalError) {
+ // need to extend the error because Firefox considers ".result" read-only
+ fatalError = createError(fatalError);
+ fatalError.result = result;
+
+ // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway)
+ var errorName = (fatalError.name || '').toLowerCase();
+ if (errorName === 'unauthorized' || errorName === 'forbidden') {
+ returnValue.emit('error', fatalError);
+ returnValue.removeAllListeners();
+ } else {
+ backOff(opts, returnValue, fatalError, function () {
+ replicate(src, target, opts, returnValue);
+ });
+ }
+ } else {
+ returnValue.emit('complete', result);
+ returnValue.removeAllListeners();
+ }
+ }
+
+
+ function onChange(change, pending, lastSeq) {
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ return completeReplication();
+ }
+ // Attach 'pending' property if server supports it (CouchDB 2.0+)
+ /* istanbul ignore if */
+ if (typeof pending === 'number') {
+ pendingBatch.pending = pending;
+ }
+
+ var filter = filterChange(opts)(change);
+ if (!filter) {
+ return;
+ }
+ pendingBatch.seq = change.seq || lastSeq;
+ pendingBatch.changes.push(change);
+ immediate(function () {
+ processPendingBatch(batches.length === 0 && changesOpts.live);
+ });
+ }
+
+
+ function onChangesComplete(changes) {
+ changesPending = false;
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ return completeReplication();
+ }
+
+ // if no results were returned then we're done,
+ // else fetch more
+ if (changes.results.length > 0) {
+ changesOpts.since = changes.results[changes.results.length - 1].seq;
+ getChanges();
+ processPendingBatch(true);
+ } else {
+
+ var complete = function () {
+ if (continuous) {
+ changesOpts.live = true;
+ getChanges();
+ } else {
+ changesCompleted = true;
+ }
+ processPendingBatch(true);
+ };
+
+ // update the checkpoint so we start from the right seq next time
+ if (!currentBatch && changes.results.length === 0) {
+ writingCheckpoint = true;
+ checkpointer.writeCheckpoint(changes.last_seq,
+ session).then(function () {
+ writingCheckpoint = false;
+ result.last_seq = last_seq = changes.last_seq;
+ complete();
+ })[
+ "catch"](onCheckpointError);
+ } else {
+ complete();
+ }
+ }
+ }
+
+
+ function onChangesError(err) {
+ changesPending = false;
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ return completeReplication();
+ }
+ abortReplication('changes rejected', err);
+ }
+
+
+ function getChanges() {
+ if (!(
+ !changesPending &&
+ !changesCompleted &&
+ batches.length < batches_limit
+ )) {
+ return;
+ }
+ changesPending = true;
+ function abortChanges() {
+ changes.cancel();
+ }
+ function removeListener() {
+ returnValue.removeListener('cancel', abortChanges);
+ }
+
+ if (returnValue._changes) { // remove old changes() and listeners
+ returnValue.removeListener('cancel', returnValue._abortChanges);
+ returnValue._changes.cancel();
+ }
+ returnValue.once('cancel', abortChanges);
+
+ var changes = src.changes(changesOpts)
+ .on('change', onChange);
+ changes.then(removeListener, removeListener);
+ changes.then(onChangesComplete)[
+ "catch"](onChangesError);
+
+ if (opts.retry) {
+ // save for later so we can cancel if necessary
+ returnValue._changes = changes;
+ returnValue._abortChanges = abortChanges;
+ }
+ }
+
+
+ function startChanges() {
+ initCheckpointer().then(function () {
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ return;
+ }
+ return checkpointer.getCheckpoint().then(function (checkpoint) {
+ last_seq = checkpoint;
+ changesOpts = {
+ since: last_seq,
+ limit: batch_size,
+ batch_size: batch_size,
+ style: 'all_docs',
+ doc_ids: doc_ids,
+ selector: selector,
+ return_docs: true // required so we know when we're done
+ };
+ if (opts.filter) {
+ if (typeof opts.filter !== 'string') {
+ // required for the client-side filter in onChange
+ changesOpts.include_docs = true;
+ } else { // ddoc filter
+ changesOpts.filter = opts.filter;
+ }
+ }
+ if ('heartbeat' in opts) {
+ changesOpts.heartbeat = opts.heartbeat;
+ }
+ if ('timeout' in opts) {
+ changesOpts.timeout = opts.timeout;
+ }
+ if (opts.query_params) {
+ changesOpts.query_params = opts.query_params;
+ }
+ if (opts.view) {
+ changesOpts.view = opts.view;
+ }
+ getChanges();
+ });
+ })["catch"](function (err) {
+ abortReplication('getCheckpoint rejected with ', err);
+ });
+ }
+
+ /* istanbul ignore next */
+ function onCheckpointError(err) {
+ writingCheckpoint = false;
+ abortReplication('writeCheckpoint completed with error', err);
+ }
+
+ /* istanbul ignore if */
+ if (returnValue.cancelled) { // cancelled immediately
+ completeReplication();
+ return;
+ }
+
+ if (!returnValue._addedListeners) {
+ returnValue.once('cancel', completeReplication);
+
+ if (typeof opts.complete === 'function') {
+ returnValue.once('error', opts.complete);
+ returnValue.once('complete', function (result) {
+ opts.complete(null, result);
+ });
+ }
+ returnValue._addedListeners = true;
+ }
+
+ if (typeof opts.since === 'undefined') {
+ startChanges();
+ } else {
+ initCheckpointer().then(function () {
+ writingCheckpoint = true;
+ return checkpointer.writeCheckpoint(opts.since, session);
+ }).then(function () {
+ writingCheckpoint = false;
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ return;
+ }
+ last_seq = opts.since;
+ startChanges();
+ })["catch"](onCheckpointError);
+ }
+}
+
+// We create a basic promise so the caller can cancel the replication possibly
+// before we have actually started listening to changes etc
+inherits(Replication, events.EventEmitter);
+function Replication() {
+ events.EventEmitter.call(this);
+ this.cancelled = false;
+ this.state = 'pending';
+ var self = this;
+ var promise = new Promise(function (fulfill, reject) {
+ self.once('complete', fulfill);
+ self.once('error', reject);
+ });
+ self.then = function (resolve, reject) {
+ return promise.then(resolve, reject);
+ };
+ self["catch"] = function (reject) {
+ return promise["catch"](reject);
+ };
+ // As we allow error handling via "error" event as well,
+ // put a stub in here so that rejecting never throws UnhandledError.
+ self["catch"](function () {});
+}
+
+Replication.prototype.cancel = function () {
+ this.cancelled = true;
+ this.state = 'cancelled';
+ this.emit('cancel');
+};
+
+Replication.prototype.ready = function (src, target) {
+ var self = this;
+ if (self._readyCalled) {
+ return;
+ }
+ self._readyCalled = true;
+
+ function onDestroy() {
+ self.cancel();
+ }
+ src.once('destroyed', onDestroy);
+ target.once('destroyed', onDestroy);
+ function cleanup() {
+ src.removeListener('destroyed', onDestroy);
+ target.removeListener('destroyed', onDestroy);
+ }
+ self.once('complete', cleanup);
+};
+
+function toPouch(db, opts) {
+ var PouchConstructor = opts.PouchConstructor;
+ if (typeof db === 'string') {
+ return new PouchConstructor(db, opts);
+ } else {
+ return db;
+ }
+}
+
+function replicateWrapper(src, target, opts, callback) {
+
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ if (typeof opts === 'undefined') {
+ opts = {};
+ }
+
+ if (opts.doc_ids && !Array.isArray(opts.doc_ids)) {
+ throw createError(BAD_REQUEST,
+ "`doc_ids` filter parameter is not a list.");
+ }
+
+ opts.complete = callback;
+ opts = clone(opts);
+ opts.continuous = opts.continuous || opts.live;
+ opts.retry = ('retry' in opts) ? opts.retry : false;
+ /*jshint validthis:true */
+ opts.PouchConstructor = opts.PouchConstructor || this;
+ var replicateRet = new Replication(opts);
+ var srcPouch = toPouch(src, opts);
+ var targetPouch = toPouch(target, opts);
+ replicate(srcPouch, targetPouch, opts, replicateRet);
+ return replicateRet;
+}
+
+inherits(Sync, events.EventEmitter);
+function sync(src, target, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ if (typeof opts === 'undefined') {
+ opts = {};
+ }
+ opts = clone(opts);
+ /*jshint validthis:true */
+ opts.PouchConstructor = opts.PouchConstructor || this;
+ src = toPouch(src, opts);
+ target = toPouch(target, opts);
+ return new Sync(src, target, opts, callback);
+}
+
+function Sync(src, target, opts, callback) {
+ var self = this;
+ this.canceled = false;
+
+ var optsPush = opts.push ? $inject_Object_assign({}, opts, opts.push) : opts;
+ var optsPull = opts.pull ? $inject_Object_assign({}, opts, opts.pull) : opts;
+
+ this.push = replicateWrapper(src, target, optsPush);
+ this.pull = replicateWrapper(target, src, optsPull);
+
+ this.pushPaused = true;
+ this.pullPaused = true;
+
+ function pullChange(change) {
+ self.emit('change', {
+ direction: 'pull',
+ change: change
+ });
+ }
+ function pushChange(change) {
+ self.emit('change', {
+ direction: 'push',
+ change: change
+ });
+ }
+ function pushDenied(doc) {
+ self.emit('denied', {
+ direction: 'push',
+ doc: doc
+ });
+ }
+ function pullDenied(doc) {
+ self.emit('denied', {
+ direction: 'pull',
+ doc: doc
+ });
+ }
+ function pushPaused() {
+ self.pushPaused = true;
+ /* istanbul ignore if */
+ if (self.pullPaused) {
+ self.emit('paused');
+ }
+ }
+ function pullPaused() {
+ self.pullPaused = true;
+ /* istanbul ignore if */
+ if (self.pushPaused) {
+ self.emit('paused');
+ }
+ }
+ function pushActive() {
+ self.pushPaused = false;
+ /* istanbul ignore if */
+ if (self.pullPaused) {
+ self.emit('active', {
+ direction: 'push'
+ });
+ }
+ }
+ function pullActive() {
+ self.pullPaused = false;
+ /* istanbul ignore if */
+ if (self.pushPaused) {
+ self.emit('active', {
+ direction: 'pull'
+ });
+ }
+ }
+
+ var removed = {};
+
+ function removeAll(type) { // type is 'push' or 'pull'
+ return function (event, func) {
+ var isChange = event === 'change' &&
+ (func === pullChange || func === pushChange);
+ var isDenied = event === 'denied' &&
+ (func === pullDenied || func === pushDenied);
+ var isPaused = event === 'paused' &&
+ (func === pullPaused || func === pushPaused);
+ var isActive = event === 'active' &&
+ (func === pullActive || func === pushActive);
+
+ if (isChange || isDenied || isPaused || isActive) {
+ if (!(event in removed)) {
+ removed[event] = {};
+ }
+ removed[event][type] = true;
+ if (Object.keys(removed[event]).length === 2) {
+ // both push and pull have asked to be removed
+ self.removeAllListeners(event);
+ }
+ }
+ };
+ }
+
+ if (opts.live) {
+ this.push.on('complete', self.pull.cancel.bind(self.pull));
+ this.pull.on('complete', self.push.cancel.bind(self.push));
+ }
+
+ function addOneListener(ee, event, listener) {
+ if (ee.listeners(event).indexOf(listener) == -1) {
+ ee.on(event, listener);
+ }
+ }
+
+ this.on('newListener', function (event) {
+ if (event === 'change') {
+ addOneListener(self.pull, 'change', pullChange);
+ addOneListener(self.push, 'change', pushChange);
+ } else if (event === 'denied') {
+ addOneListener(self.pull, 'denied', pullDenied);
+ addOneListener(self.push, 'denied', pushDenied);
+ } else if (event === 'active') {
+ addOneListener(self.pull, 'active', pullActive);
+ addOneListener(self.push, 'active', pushActive);
+ } else if (event === 'paused') {
+ addOneListener(self.pull, 'paused', pullPaused);
+ addOneListener(self.push, 'paused', pushPaused);
+ }
+ });
+
+ this.on('removeListener', function (event) {
+ if (event === 'change') {
+ self.pull.removeListener('change', pullChange);
+ self.push.removeListener('change', pushChange);
+ } else if (event === 'denied') {
+ self.pull.removeListener('denied', pullDenied);
+ self.push.removeListener('denied', pushDenied);
+ } else if (event === 'active') {
+ self.pull.removeListener('active', pullActive);
+ self.push.removeListener('active', pushActive);
+ } else if (event === 'paused') {
+ self.pull.removeListener('paused', pullPaused);
+ self.push.removeListener('paused', pushPaused);
+ }
+ });
+
+ this.pull.on('removeListener', removeAll('pull'));
+ this.push.on('removeListener', removeAll('push'));
+
+ var promise = Promise.all([
+ this.push,
+ this.pull
+ ]).then(function (resp) {
+ var out = {
+ push: resp[0],
+ pull: resp[1]
+ };
+ self.emit('complete', out);
+ if (callback) {
+ callback(null, out);
+ }
+ self.removeAllListeners();
+ return out;
+ }, function (err) {
+ self.cancel();
+ if (callback) {
+ // if there's a callback, then the callback can receive
+ // the error event
+ callback(err);
+ } else {
+ // if there's no callback, then we're safe to emit an error
+ // event, which would otherwise throw an unhandled error
+ // due to 'error' being a special event in EventEmitters
+ self.emit('error', err);
+ }
+ self.removeAllListeners();
+ if (callback) {
+ // no sense throwing if we're already emitting an 'error' event
+ throw err;
+ }
+ });
+
+ this.then = function (success, err) {
+ return promise.then(success, err);
+ };
+
+ this["catch"] = function (err) {
+ return promise["catch"](err);
+ };
+}
+
+Sync.prototype.cancel = function () {
+ if (!this.canceled) {
+ this.canceled = true;
+ this.push.cancel();
+ this.pull.cancel();
+ }
+};
+
+function replication(PouchDB) {
+ PouchDB.replicate = replicateWrapper;
+ PouchDB.sync = sync;
+
+ Object.defineProperty(PouchDB.prototype, 'replicate', {
+ get: function () {
+ var self = this;
+ if (typeof this.replicateMethods === 'undefined') {
+ this.replicateMethods = {
+ from: function (other, opts, callback) {
+ return self.constructor.replicate(other, self, opts, callback);
+ },
+ to: function (other, opts, callback) {
+ return self.constructor.replicate(self, other, opts, callback);
+ }
+ };
+ }
+ return this.replicateMethods;
+ }
+ });
+
+ PouchDB.prototype.sync = function (dbName, opts, callback) {
+ return this.constructor.sync(this, dbName, opts, callback);
+ };
+}
+
+PouchDB.plugin(IDBPouch)
+ .plugin(HttpPouch$1)
+ .plugin(mapreduce)
+ .plugin(replication);
+
+// Pull from src because pouchdb-node/pouchdb-browser themselves
+
+module.exports = PouchDB;
+
+}).call(this,_dereq_(5),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"1":1,"12":12,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7}]},{},[13])(13)
+});
diff --git a/src/lib/toaster.js b/src/lib/toaster.js
new file mode 100644
index 0000000..565957e
--- /dev/null
+++ b/src/lib/toaster.js
@@ -0,0 +1,146 @@
+// License: https://github.com/ivarlovlie/bootstrap-v5-toaster/blob/master/LICENSE
+/** Class representing a Bootstrap 5 Toaster. */
+class Toaster {
+ constructor(options) {
+ if (!options) {
+ options = {
+ hideAfter: 3500,
+ position: "top-right",
+ };
+ }
+ this.root = document.createElement("div");
+ this.root.id = "toaster-container";
+ switch (options.position) {
+ case "top-right":
+ this.root.style =
+ "display: flex; align-items: end; flex-direction: column; position: absolute; top: 0; right: 0; padding: 15px;";
+ break;
+ case "top-left":
+ this.root.style = "position: absolute; top: 0; padding: 15px;";
+ break;
+ case "bottom-right":
+ this.root.style =
+ "display: flex; align-items: end; flex-direction: column; position: absolute; bottom: 0; right: 0; padding: 15px;";
+ break;
+ case "bottom-left":
+ this.root.style = "position: absolute; bottom: 0; padding: 15px;";
+ break;
+ default:
+ // top-right
+ this.root.style =
+ "display: flex; align-items: end; flex-direction: column; position: absolute; top: 0; right: 0; padding: 15px;";
+ break;
+ }
+ document.body.appendChild(this.root);
+ this.defaultTimeout = options.hideAfter ? options.hideAfter : 3500;
+ this.toastTypes = {
+ error: "error",
+ success: "success",
+ info: "info",
+ };
+ }
+ display(title, message, autohide, type) {
+ if (!title || typeof title !== "string" || typeof message !== "string") {
+ throw new Error("Toaster: title &| message is empty or not a string");
+ }
+ let toast = document.createElement("div");
+ toast.className = "toast";
+ toast.role = "alert";
+ toast.id = Math.random().toString(36).substring(2) + Date.now().toString(36);
+ let toastHeader = document.createElement("div");
+ toastHeader.className = "toast-header";
+ let toastTypeIndicator = document.createElement("div");
+ switch (type) {
+ case this.toastTypes.error:
+ toastTypeIndicator.className = "toast-type-indicator rounded mr-2 bg-danger";
+ toast.style =
+ "width: max-content; min-width: 300px; border-color: var(--bs-danger);";
+ break;
+ case this.toastTypes.success:
+ toastTypeIndicator.className = "toast-type-indicator rounded mr-2 bg-success";
+ toast.style =
+ "width: max-content; min-width: 300px; border-color: var(--bs-success);";
+ break;
+ case this.toastTypes.info:
+ toastTypeIndicator.className = "toast-type-indicator rounded mr-2 bg-info";
+ toast.style = "width: max-content; min-width: 300px; border-color: var(--bs-info);";
+ break;
+ }
+ toastTypeIndicator.style = "width: 18px; height: 18px;";
+ toastHeader.appendChild(toastTypeIndicator);
+ let toastTitle = document.createElement("strong");
+ toastTitle.className = "mr-auto text-truncate";
+ toastTitle.innerText = title;
+ toastHeader.appendChild(toastTitle);
+ let toastCloseButton = document.createElement("button");
+ toastCloseButton.className = "ml-2 mb-1 close";
+ toastCloseButton.dataset.dismiss = "toast";
+ toastCloseButton.onclick = () => {
+ setTimeout(() => {
+ toast.parentNode.removeChild(toast);
+ }, parseInt(1000));
+ };
+ if (!autohide) {
+ let toastCloseButtonIcon = document.createElement("img");
+ // icon license: https://github.com/twbs/icons/blob/master/LICENSE.md
+ toastCloseButtonIcon.src =
+ 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="1em" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M4.146 4.146a.5.5 0 000 .708l7 7a.5.5 0 00.708-.708l-7-7a.5.5 0 00-.708 0z" clip-rule="evenodd"/></svg>';
+ toastCloseButtonIcon.alt = "x";
+ toastCloseButtonIcon.dataset.ariaHidden = "true";
+ toastCloseButton.appendChild(toastCloseButtonIcon);
+ toastHeader.appendChild(toastCloseButton);
+ }
+ toast.appendChild(toastHeader);
+ if (message) {
+ let toastBody = document.createElement("div");
+ toastBody.className = "toast-body";
+ toastBody.style = "word-wrap: break-word;";
+ toastBody.innerText = message;
+ toast.appendChild(toastBody);
+ }
+ this.root.appendChild(toast);
+ let delay = 0;
+ if (typeof autohide === "number" && autohide !== 0) {
+ delay = autohide;
+ autohide = true;
+ } else if (autohide) {
+ delay = this.defaultTimeout;
+ }
+ new bootstrap.Toast(document.getElementById(toast.id), {
+ animation: true,
+ autohide,
+ delay,
+ }).show();
+ if (delay)
+ setTimeout(() => {
+ toast.parentNode.removeChild(toast);
+ }, parseInt(delay + 1000));
+ }
+ /**
+ * Display an toast indicating an error.
+ * @param {string} title Title of the toast
+ * @param {string} message Message of the toast
+ * @param {boolean} autohide Autohide toast
+ */
+ error(title, message = "", autohide = true) {
+ this.display(title, message, autohide, this.toastTypes.error);
+ }
+ /**
+ * Display an toast indicating an successfull operation.
+ * @param {string} title Title of the toast
+ * @param {string} message Message of the toast
+ * @param {boolean} autohide Autohide toast
+ */
+ success(title, message = "", autohide = true) {
+ this.display(title, message, autohide, this.toastTypes.success);
+ }
+ /**
+ * Display an informational toast.
+ * @param {string} title Title of the toast
+ * @param {string} message Message of the toast
+ * @param {boolean} autohide Autohide toast
+ */
+ info(title, message = "", autohide = true) {
+ this.display(title, message, autohide, this.toastTypes.info);
+ }
+}
diff --git a/src/scripts/index.js b/src/scripts/index.js
new file mode 100644
index 0000000..3671a87
--- /dev/null
+++ b/src/scripts/index.js
@@ -0,0 +1,379 @@
+const toaster = new Toaster();
+
+const searchForm = document.querySelector("#search-form");
+const searchInput = document.querySelector("#search-input");
+
+const cardsContainer = document.querySelector("#cards");
+
+const commandElements = {
+ createCardModalButton: document.querySelector("#open-new-card-modal-button"),
+ importPinsModalButton: document.querySelector("#open-import-pins-modal-button"),
+ openOptionsModalButton: document.querySelector("#open-options-modal-button")
+};
+
+const cardModalElements = {
+ modal: document.querySelector("#card-modal"),
+ save: document.querySelector("#card-modal #save-card-button"),
+ name: document.querySelector("#card-modal #card-name"),
+ header: document.querySelector("#card-modal .modal-title"),
+ cardLinksContainer: document.querySelector("#card-modal #card-links"),
+ cardLinksUrlInputs: document.querySelectorAll(
+ "#card-modal #card-links .link input[name='url']"
+ ),
+};
+
+const optionsModalElements = {
+ modal: document.querySelector("#options-modal"),
+ save: document.querySelector("#options-modal #save-options-button")
+};
+
+
+const fileInput = document.querySelector("#file");
+
+const cardModalBootstrap = new bootstrap.Modal(cardModalElements.modal);
+const showCardModal = () => cardModalBootstrap.show();
+const hideCardModal = () => cardModalBootstrap.hide();
+
+const optionsModalBootstrap = new bootstrap.Modal(optionsModalElements.modal);
+const showOptionsModal = () => optionsModalBootstrap.show();
+const hideOptionsModal = () => optionsModalBootstrap.hide();
+
+const constants = {
+ messages: {},
+ database: {
+ name: "startpage",
+ keys: {
+ cards: "cards",
+ pins: "pins",
+ settings: "settings"
+ },
+ },
+ flags: {
+ debug: true,
+ },
+ toast_types: {
+ success: "success",
+ error: "error",
+ info: "info",
+ },
+};
+
+let database;
+
+function initialize() {
+ database = new PouchDB(constants.database.name);
+ addEventListeners();
+ renderCards();
+}
+
+function addEventListeners() {
+ cardModalElements.save.addEventListener("click", submitCardForm);
+ cardModalElements.cardLinksUrlInputs.forEach((element) => {
+ element.addEventListener("keypress", keypressOnLinkUrlInput);
+ });
+
+ commandElements.createCardModalButton.addEventListener("click", openCreateCardModal);
+ commandElements.openOptionsModalButton.addEventListener("click", openSettingsModal);
+ commandElements.importPinsModalButton.addEventListener("click", () => fileInput.click());
+
+ fileInput.addEventListener("change", function () {
+ const file = fileInput.files[0];
+ console.log(file);
+ const reader = new FileReader();
+ reader.onload = content => importPins(content.target.result);
+ reader.readAsText(file);
+ });
+
+ cardModalElements.modal.addEventListener("hidden.bs.modal", function (event) {
+ cardModalElements.name.value = "";
+ cardModalElements.cardLinksContainer.empty();
+ });
+ document.addEventListener("hidden.bs.modal", function (event) {
+ searchInput.focus();
+ });
+}
+
+function openSettingsModal() {
+ showOptionsModal();
+}
+
+let pin = {
+ description: "",
+ extended: "",
+ hash: "",
+ href: "",
+ meta: "",
+ tags: "",
+ time: "",
+ toread: "",
+};
+
+
+function importPins(json) {
+ JSON.parse(json).forEach(pin => {
+ if (!addPin(pin)) throw new Error("WHOOPS");
+ });
+}
+
+function logPins() {
+ database
+ .get(constants.database.keys.pins)
+ .then(pins => {
+ pins.data.forEach(element => {
+ console.log(element);
+ });
+ });
+}
+
+function addPin(pin) {
+ database
+ .get(constants.database.keys.pins)
+ .then((pins) => {
+ pins._rev = pins._rev;
+ pins._id = constants.database.keys.pins;
+ if (!pin._id) pin._id = guid();
+ let current = pins.data.find((item) => item._id == pin._id);
+ if (current) return true;
+ pins.data.push(pin);
+ return database.put(pins);
+ })
+ .then((updated) => {
+ return true;
+ })
+ .catch((err) => {
+ if (err.status === 404) {
+ let newPinsDb = {
+ _id: constants.database.keys.pins,
+ data: [],
+ };
+ pin._id = guid();
+ newPinsDb.data.push(pin);
+ database
+ .put(newPinsDb)
+ .then((added) => {
+ console.log("created pins");
+ })
+ .catch((err) => { logError("failed to create pins", err); return false; });
+ } else {
+ logError("failed to update pins", err);
+ return false;
+ }
+ });
+}
+
+
+function openEditCardModal(id) {
+ if (!id) return;
+ database
+ .get(constants.database.keys.cards)
+ .then((cardDoc) => {
+ console.log(cardDoc);
+ let card = cardDoc.data.find((card) => card._id == id);
+ if (!card) {
+ renderCards();
+ console.log("did not find card");
+ }
+ cardModalElements.name.value = card.name;
+ cardModalElements.header.innerText = "Rediger " + card.name;
+ cardModalElements.modal.dataset.id = card._id;
+ card.links.forEach((link) => addNewLinkInputs(false, link.name, link.url));
+ })
+ .catch((err) => logError(err));
+ showCardModal();
+ cardModalElements.name.focus();
+ cardModalElements.modal.scrollTop = cardModalElements.modal.scrollHeight;
+}
+
+function openCreateCardModal() {
+ cardModalElements.header.innerText = "Nytt kort";
+ cardModalElements.name.value = "";
+ showCardModal();
+ cardModalElements.name.focus();
+ addNewLinkInputs();
+}
+
+function submitCardForm(event) {
+ event.preventDefault();
+ if (!cardModalElements.name.value) return;
+ let card = {
+ name: cardModalElements.name.value,
+ links: [],
+ };
+ if (cardModalElements.modal.dataset.id) card._id = cardModalElements.modal.dataset.id;
+ document.querySelectorAll("#card-modal #card-links .link").forEach((linkElement) => {
+ let name = linkElement.firstElementChild.value;
+ let url = linkElement.lastElementChild.value;
+ if (!name || !url || !url.startsWith("http")) return;
+ name = name.trim();
+ url = url.trim();
+ card.links.push({
+ name,
+ url,
+ });
+ });
+ if (card.links.length == 0) return;
+ addOrUpdateCard(card);
+ hideCardModal();
+}
+
+function addNewLinkInputs(changeFocus, name, url) {
+ let inputGroup = document.createElement("div");
+ inputGroup.className = "link mt-1 p-2 d-flex align-items-center";
+ let nameInput = document.createElement("input");
+ nameInput.name = "name";
+ nameInput.className = "form-control";
+ nameInput.placeholder = "Navn";
+ if (name) nameInput.value = name;
+ inputGroup.appendChild(nameInput);
+ let arrow = document.createElement("img");
+ arrow.src = "assets/icons/arrow-right.svg";
+ arrow.className = "mx-3";
+ arrow.alt = "";
+ arrow.width = "32";
+ arrow.height = "32";
+ inputGroup.appendChild(arrow);
+ let urlInput = document.createElement("input");
+ urlInput.name = "url";
+ urlInput.className = "form-control";
+ urlInput.placeholder = "Url";
+ urlInput.value = url ? url : "http://";
+ urlInput.addEventListener("keypress", keypressOnLinkUrlInput);
+ inputGroup.appendChild(urlInput);
+ cardModalElements.cardLinksContainer.appendChild(inputGroup);
+ if (changeFocus) nameInput.focus();
+ cardModalElements.modal.scrollTop = cardModalElements.modal.scrollHeight;
+}
+
+function keypressOnLinkUrlInput(event) {
+ if (event.keyCode == 13) {
+ let shouldCreateNewInputs = event.target.parentElement.nextElementSibling == null;
+ if (shouldCreateNewInputs) {
+ addNewLinkInputs(true);
+ }
+ }
+}
+
+function addOrUpdateCard(card) {
+ if (!card.name) return;
+ database
+ .get(constants.database.keys.cards)
+ .then((cards) => {
+ cards._rev = cards._rev;
+ cards._id = constants.database.keys.cards;
+ if (!card._id) card._id = guid();
+ let current = cards.data.find((item) => item._id == card._id);
+ if (current) {
+ current.name = card.name;
+ current.links = card.links;
+ } else cards.data.push(card);
+ return database.put(cards);
+ })
+ .then((updated) => {
+ console.log("updated carddb");
+ renderCards();
+ })
+ .catch((err) => {
+ if (err.status === 404) {
+ let newCardDocument = {
+ _id: constants.database.keys.cards,
+ data: [],
+ };
+ card._id = guid();
+ newCardDocument.data.push(card);
+ database
+ .put(newCardDocument)
+ .then((added) => {
+ console.log("created carddb");
+ renderCards();
+ })
+ .catch((err) => logError("failed to create carddb", err));
+ } else {
+ logError("failed to update carddb", err);
+ }
+ });
+}
+
+
+function logError(msg, error) {
+ console.error("!!!");
+ console.error(msg);
+ toaster.error("Whoops!", msg);
+ console.error(error);
+ console.error("!!!");
+}
+
+function wipeData() {
+ new PouchDB(constants.database.names.cards)
+ .destroy()
+ .then(function () {
+ console.log("wiped data");
+ })
+ .catch(function (err) {
+ console.error(err);
+ });
+}
+
+function renderCards() {
+ cardsContainer.empty();
+ database
+ .get(constants.database.keys.cards)
+ .then((cardDoc) => {
+ cardDoc.data.sort((a, b) => a.order - b.order).forEach((card) => {
+ let columElement = document.createElement("div");
+ columElement.className = "col";
+ let cardElement = document.createElement("div");
+ cardElement.className = "card";
+ columElement.appendChild(cardElement);
+ let cardHeader = document.createElement("div");
+ cardHeader.className =
+ "card-header d-flex text-truncate justify-content-between align-items-center";
+ let cardHeaderText = document.createElement("span");
+ cardHeaderText.innerText = card.name;
+ cardHeader.appendChild(cardHeaderText);
+ let cardHeaderEditButton = document.createElement("img");
+ cardHeaderEditButton.src = "assets/icons/pencil-square.svg";
+ cardHeaderEditButton.title = "Rediger " + card.name;
+ cardHeaderEditButton.width = "18";
+ cardHeaderEditButton.type = "button";
+ cardHeaderEditButton.height = "18";
+ cardHeaderEditButton.onclick = () => openEditCardModal(card._id);
+ cardHeader.appendChild(cardHeaderEditButton);
+ cardElement.appendChild(cardHeader);
+ let linkList = document.createElement("ul");
+ linkList.className = "list-group list-group-flush";
+ card.links.forEach((link) => {
+ let listItem = document.createElement("a");
+ listItem.innerText = link.name;
+ listItem.className = "list-group-item";
+ listItem.href = link.url;
+ linkList.appendChild(listItem);
+ });
+ cardElement.appendChild(linkList);
+ cardsContainer.append(columElement);
+ });
+
+ })
+ .catch((error) => {
+ if (error.status !== 404) logError(error);
+ });
+}
+
+function guid() {
+ let index,
+ tea,
+ result = "";
+ for (index = 0; index < 32; index++)
+ (tea = (16 * Math.random()) | 0),
+ (8 != index && 12 != index && 16 != index && 20 != index) || (result += "-"),
+ (result += (12 == index ? 4 : 16 == index ? (3 & tea) | 8 : tea).toString(16));
+ return result;
+}
+
+Element.prototype.empty = function () {
+ while (this.firstChild) {
+ this.removeChild(this.firstChild);
+ }
+};
+
+initialize();
+
diff --git a/src/styles/index.css b/src/styles/index.css
new file mode 100644
index 0000000..e91972e
--- /dev/null
+++ b/src/styles/index.css
@@ -0,0 +1,28 @@
+img {
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+#cards {
+ overflow-x: auto;
+ flex-wrap: unset;
+}
+#cards .col {
+ width: 18rem;
+ max-width: 18rem;
+ min-width: 18rem;
+ overflow-y: auto;
+}
+#cards .col .card .card-header img {
+ cursor: pointer;
+}
+#cards .col .card .list-group {
+ max-height: 33.3vh;
+ overflow: auto;
+}
+#cards .col .card .list-group .list-group-item {
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+} \ No newline at end of file
diff --git a/src/styles/index.scss b/src/styles/index.scss
new file mode 100644
index 0000000..9175250
--- /dev/null
+++ b/src/styles/index.scss
@@ -0,0 +1,30 @@
+img {
+ user-select: none;
+}
+
+#cards {
+ overflow-x: auto;
+ flex-wrap: unset;
+
+ .col {
+ width: 18rem;
+ max-width: 18rem;
+ min-width: 18rem;
+ overflow-y: auto;
+
+ .card .card-header img {
+ cursor: pointer;
+ }
+
+ .card .list-group {
+ max-height: 33.3vh;
+ overflow: auto;
+
+ .list-group-item {
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+ }
+ }
+}
diff --git a/src/styles/prepros.config b/src/styles/prepros.config
new file mode 100644
index 0000000..d01ba43
--- /dev/null
+++ b/src/styles/prepros.config
@@ -0,0 +1,908 @@
+{
+ "version": "7",
+ "about": "This is a Prepros (https://prepros.io) configuration file. You can commit this file to a git repo to backup and sync project configurations.",
+ "config": {
+ "proxy": {
+ "enable": false,
+ "target": "",
+ "useLocalAssets": false
+ },
+ "reload": {
+ "enable": true,
+ "delay": 0,
+ "animate": true,
+ "afterUpload": false
+ },
+ "sync": {
+ "enable": false,
+ "mouse": true,
+ "keyboard": true,
+ "form": true,
+ "scroll": true
+ },
+ "watcher": {
+ "enable": true,
+ "maxFiles": 2000,
+ "usePolling": false,
+ "pollingInterval": 500,
+ "extensions": [
+ ".html",
+ ".htm",
+ ".php"
+ ],
+ "ignore": {
+ "patterns": [
+ ".*",
+ "wp-admin",
+ "wp-includes",
+ "node_modules",
+ "Prepros Export",
+ "bower_components"
+ ],
+ "exceptions": []
+ }
+ },
+ "exporter": {
+ "ignore": {
+ "patterns": [
+ ".*",
+ "desktop.ini",
+ "prepros.cfg",
+ "node_modules",
+ "Prepros Export",
+ "prepros.config",
+ "prepros-6.config",
+ "*-original.jpg",
+ "*-original.jpeg",
+ "*-original.png",
+ "*-original.svg",
+ "*.scss",
+ "*.sass",
+ "*.less",
+ "*.pug",
+ "*.jade",
+ "*.styl",
+ "*.haml",
+ "*.slim",
+ "*.coffee",
+ "*.kit",
+ "*.turf",
+ "*.ts"
+ ],
+ "exceptions": []
+ }
+ },
+ "uploader": {
+ "remotePath": "",
+ "timeout": 20000,
+ "autoUpload": false,
+ "connectionType": "ftp",
+ "history": []
+ },
+ "packages": {
+ "createPackageLock": true
+ },
+ "tasks": {
+ "autoprefixer": {
+ "cascade": true,
+ "add": true,
+ "remove": true,
+ "supports": true,
+ "flexbox": true,
+ "grid": "autoplace",
+ "browsers": [
+ "> 2%",
+ "not dead"
+ ],
+ "sourceMap": false
+ },
+ "babel": {
+ "sourceMap": false,
+ "presets": {
+ "@babel/preset-env": {
+ "enable": true,
+ "options": {
+ "targets": [
+ "> 2%",
+ "not dead"
+ ],
+ "preserveImports": false
+ }
+ },
+ "@babel/preset-react": true,
+ "@babel/preset-flow": false
+ },
+ "plugins": {
+ "@babel/plugin-proposal-class-properties": false,
+ "@babel/plugin-proposal-decorators": {
+ "enable": false,
+ "options": {
+ "decoratorsBeforeExport": true
+ }
+ },
+ "@babel/plugin-proposal-export-namespace-from": false,
+ "@babel/plugin-proposal-function-sent": false,
+ "@babel/plugin-proposal-nullish-coalescing-operator": false,
+ "@babel/plugin-proposal-numeric-separator": false,
+ "@babel/plugin-proposal-optional-chaining": false,
+ "@babel/plugin-proposal-private-methods": false,
+ "@babel/plugin-proposal-throw-expressions": false
+ },
+ "customPresets": [],
+ "customPlugins": []
+ },
+ "bundle-js": {
+ "sourceMap": false,
+ "exclude": [
+ "node_modules",
+ "bower_components"
+ ],
+ "devMode": true,
+ "globals": [],
+ "externals": [],
+ "babel": {
+ "enable": true,
+ "options": {
+ "sourceMap": false,
+ "presets": {
+ "@babel/preset-env": {
+ "enable": true,
+ "options": {
+ "targets": [
+ "> 2%",
+ "not dead"
+ ],
+ "preserveImports": false
+ }
+ },
+ "@babel/preset-react": true,
+ "@babel/preset-flow": false
+ },
+ "plugins": {
+ "@babel/plugin-proposal-class-properties": false,
+ "@babel/plugin-proposal-decorators": {
+ "enable": false,
+ "options": {
+ "decoratorsBeforeExport": true
+ }
+ },
+ "@babel/plugin-proposal-export-namespace-from": false,
+ "@babel/plugin-proposal-function-sent": false,
+ "@babel/plugin-proposal-nullish-coalescing-operator": false,
+ "@babel/plugin-proposal-numeric-separator": false,
+ "@babel/plugin-proposal-optional-chaining": false,
+ "@babel/plugin-proposal-private-methods": false,
+ "@babel/plugin-proposal-throw-expressions": false
+ },
+ "customPresets": [],
+ "customPlugins": []
+ }
+ },
+ "css": {
+ "enable": true
+ },
+ "fonts": {
+ "enable": true
+ }
+ },
+ "coffeescript": {
+ "header": false,
+ "bare": false,
+ "sourceMap": false
+ },
+ "command": {
+ "command": "",
+ "rootDir": ""
+ },
+ "concat-js": {
+ "sourceMap": false,
+ "rootDir": ""
+ },
+ "copy": {
+ "sourceMap": false
+ },
+ "dart-sass": {
+ "indentType": "space",
+ "indentWidth": 2,
+ "linefeed": "lf",
+ "sourceMap": false
+ },
+ "haml": {
+ "doubleQuoteAttributes": true
+ },
+ "jpg": {
+ "quality": 90
+ },
+ "less": {
+ "javascriptEnabled": false,
+ "strictImports": false,
+ "insecure": false,
+ "math": "always",
+ "strictUnits": false,
+ "dumpLineNumbers": false,
+ "sourceMap": false
+ },
+ "markdown": {
+ "githubFlavored": true,
+ "wrapWithHtml": false
+ },
+ "minify-css": {
+ "sourceMap": false
+ },
+ "minify-html": {
+ "caseSensitive": false,
+ "collapseBooleanAttributes": true,
+ "collapseInlineTagWhitespace": false,
+ "collapseWhitespace": true,
+ "conservativeCollapse": false,
+ "decodeEntities": false,
+ "html5": true,
+ "includeAutoGeneratedTags": true,
+ "keepClosingSlash": false,
+ "minifyCSS": true,
+ "minifyJS": true,
+ "preserveLineBreaks": false,
+ "preventAttributesEscaping": false,
+ "processConditionalComments": false,
+ "removeAttributeQuotes": false,
+ "removeComments": true,
+ "removeEmptyAttributes": false,
+ "removeEmptyElement": false,
+ "removeOptionalTags": false,
+ "removeRedundantAttributes": false,
+ "removeScriptTypeAttributes": false,
+ "removeStyleLinkTypeAttributes": false,
+ "removeTagWhitespace": false,
+ "sortAttributes": false,
+ "sortClassName": false,
+ "useShortDoctype": true
+ },
+ "minify-js": {
+ "parse": {
+ "bare_returns": false
+ },
+ "compress": {
+ "arrows": true,
+ "arguments": false,
+ "booleans": true,
+ "booleans_as_integers": false,
+ "collapse_vars": true,
+ "comparisons": true,
+ "computed_props": true,
+ "conditionals": true,
+ "dead_code": true,
+ "directives": true,
+ "drop_console": false,
+ "drop_debugger": true,
+ "evaluate": true,
+ "expression": false,
+ "global_defs": [],
+ "hoist_funs": false,
+ "hoist_props": true,
+ "hoist_vars": false,
+ "if_return": true,
+ "inline": 3,
+ "join_vars": true,
+ "keep_fargs": true,
+ "keep_infinity": false,
+ "loops": true,
+ "negate_iife": true,
+ "properties": true,
+ "pure_funcs": [],
+ "pure_getters": false,
+ "reduce_vars": true,
+ "sequences": true,
+ "side_effects": true,
+ "switches": true,
+ "top_retain": [],
+ "typeofs": true,
+ "unsafe": false,
+ "unsafe_arrows": false,
+ "unsafe_comps": false,
+ "unsafe_Function": false,
+ "unsafe_math": false,
+ "unsafe_proto": false,
+ "unsafe_regexp": false,
+ "unsafe_undefined": false,
+ "unused": true
+ },
+ "mangle": {
+ "eval": false,
+ "reserved": []
+ },
+ "output": {
+ "ascii_only": false,
+ "braces": false,
+ "comments": "none",
+ "inline_script": true,
+ "keep_numbers": false,
+ "keep_quoted_props": false,
+ "preamble": null,
+ "quote_keys": false,
+ "quote_style": 0,
+ "semicolons": true,
+ "shebang": true,
+ "webkit": false,
+ "wrap_iife": false,
+ "wrap_func_args": true
+ },
+ "sourceMap": false,
+ "toplevel": false,
+ "ie8": false,
+ "keep_classnames": false,
+ "keep_fnames": false,
+ "safari10": false
+ },
+ "node-sass": {
+ "indentType": "space",
+ "indentWidth": 2,
+ "linefeed": "lf",
+ "outputStyle": "expanded",
+ "precision": 10,
+ "sourceMap": false,
+ "sourceComments": false
+ },
+ "png": {
+ "quality": 90
+ },
+ "postcss-import": {
+ "ignoreKeywords": [],
+ "sourceMap": false
+ },
+ "postcss-preset-env": {
+ "stage": 2,
+ "browsers": [
+ "> 2%",
+ "not dead"
+ ],
+ "sourceMap": false
+ },
+ "pug": {
+ "pretty": true
+ },
+ "slim": {
+ "indent": "space",
+ "indentSize": 2,
+ "pretty": true
+ },
+ "stylus": {
+ "useNib": true,
+ "sourceMap": false,
+ "linenos": false
+ },
+ "svg": {
+ "cleanupAttrs": true,
+ "removeDoctype": true,
+ "removeXMLProcInst": true,
+ "removeComments": true,
+ "removeMetadata": true,
+ "removeTitle": true,
+ "removeDesc": true,
+ "removeUselessDefs": true,
+ "removeEditorsNSData": true,
+ "removeEmptyAttrs": true,
+ "removeHiddenElems": true,
+ "removeEmptyText": true,
+ "removeEmptyContainers": true,
+ "removeViewBox": false,
+ "cleanupEnableBackground": true,
+ "convertStyleToAttrs": true,
+ "convertColors": true,
+ "convertPathData": true,
+ "convertTransform": true,
+ "removeUnknownsAndDefaults": true,
+ "removeNonInheritableGroupAttrs": true,
+ "removeUselessStrokeAndFill": true,
+ "removeUnusedNS": true,
+ "cleanupIDs": true,
+ "cleanupNumericValues": true,
+ "moveElemsAttrsToGroup": true,
+ "moveGroupAttrsToElems": true,
+ "collapseGroups": true,
+ "removeRasterImages": false,
+ "mergePaths": true,
+ "convertShapeToPath": true,
+ "sortAttrs": true,
+ "removeDimensions": true
+ },
+ "turf": {
+ "rootDir": ""
+ },
+ "typescript": {
+ "allowJs": false,
+ "allowSyntheticDefaultImports": true,
+ "allowUmdGlobalAccess": false,
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": false,
+ "alwaysStrict": false,
+ "charset": "utf8",
+ "checkJs": false,
+ "declaration": false,
+ "disableSizeLimit": false,
+ "downlevelIteration": false,
+ "emitBOM": false,
+ "emitDecoratorMetadata": false,
+ "experimentalDecorators": false,
+ "forceConsistentCasingInFileNames": false,
+ "importHelpers": false,
+ "jsx": "React",
+ "keyofStringsOnly": false,
+ "lib": [],
+ "maxNodeModuleJsDepth": 0,
+ "module": "ES2015",
+ "moduleResolution": "NodeJs",
+ "newLine": "LineFeed",
+ "noFallthroughCasesInSwitch": false,
+ "noImplicitAny": false,
+ "noImplicitReturns": false,
+ "noImplicitThis": false,
+ "noStrictGenericChecks": false,
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
+ "noImplicitUseStrict": false,
+ "noLib": false,
+ "noResolve": false,
+ "preserveConstEnums": false,
+ "jsxFactory": "React.createElement",
+ "removeComments": false,
+ "skipLibCheck": false,
+ "sourceMap": false,
+ "strict": false,
+ "strictFunctionTypes": false,
+ "strictBindCallApply": false,
+ "strictNullChecks": false,
+ "strictPropertyInitialization": false,
+ "suppressExcessPropertyErrors": false,
+ "suppressImplicitAnyIndexErrors": false,
+ "target": "ES3",
+ "resolveJsonModule": false,
+ "esModuleInterop": false,
+ "useDefineForClassFields": false
+ }
+ },
+ "fileTypes": {
+ "sass": {
+ "extensions": [
+ ".scss",
+ ".sass"
+ ],
+ "autoCompile": true,
+ "sourceMap": false,
+ "tasks": [
+ {
+ "task": "dart-sass",
+ "enable": true
+ },
+ {
+ "task": "autoprefixer",
+ "enable": true
+ },
+ {
+ "task": "minify-css",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".css",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "scss",
+ "replaceWith": "css"
+ },
+ {
+ "segment": "sass",
+ "replaceWith": "css"
+ }
+ ]
+ }
+ },
+ "less": {
+ "extensions": [
+ ".less"
+ ],
+ "autoCompile": true,
+ "sourceMap": false,
+ "tasks": [
+ {
+ "task": "less",
+ "enable": true
+ },
+ {
+ "task": "autoprefixer",
+ "enable": true
+ },
+ {
+ "task": "minify-css",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".css",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "less",
+ "replaceWith": "css"
+ }
+ ]
+ }
+ },
+ "pug": {
+ "extensions": [
+ ".pug",
+ ".jade"
+ ],
+ "autoCompile": true,
+ "tasks": [
+ {
+ "task": "pug",
+ "enable": true
+ },
+ {
+ "task": "minify-html",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".html",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "pug",
+ "replaceWith": "html"
+ }
+ ]
+ }
+ },
+ "css": {
+ "extensions": [
+ ".css"
+ ],
+ "autoCompile": false,
+ "sourceMap": false,
+ "tasks": [
+ {
+ "task": "copy",
+ "enable": true
+ },
+ {
+ "task": "postcss-import",
+ "enable": false
+ },
+ {
+ "task": "postcss-preset-env",
+ "enable": false
+ },
+ {
+ "task": "autoprefixer",
+ "enable": true
+ },
+ {
+ "task": "minify-css",
+ "enable": true
+ }
+ ],
+ "output": {
+ "extension": ".css",
+ "type": "SOURCE_RELATIVE",
+ "relativePath": "",
+ "suffix": "-dist",
+ "alwaysSuffix": false
+ }
+ },
+ "javascript": {
+ "extensions": [
+ ".js",
+ ".jsx"
+ ],
+ "autoCompile": false,
+ "sourceMap": false,
+ "tasks": [
+ {
+ "task": "copy",
+ "enable": true
+ },
+ {
+ "task": "concat-js",
+ "enable": false
+ },
+ {
+ "task": "babel",
+ "enable": false
+ },
+ {
+ "task": "bundle-js",
+ "enable": false
+ },
+ {
+ "task": "minify-js",
+ "enable": true
+ }
+ ],
+ "output": {
+ "extension": ".js",
+ "type": "SOURCE_RELATIVE",
+ "relativePath": "",
+ "suffix": "-dist",
+ "alwaysSuffix": false
+ }
+ },
+ "stylus": {
+ "extensions": [
+ ".styl"
+ ],
+ "autoCompile": true,
+ "sourceMap": false,
+ "tasks": [
+ {
+ "task": "stylus",
+ "enable": true
+ },
+ {
+ "task": "autoprefixer",
+ "enable": true
+ },
+ {
+ "task": "minify-css",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".css",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "stylus",
+ "replaceWith": "css"
+ },
+ {
+ "segment": "styl",
+ "replaceWith": "css"
+ }
+ ]
+ }
+ },
+ "markdown": {
+ "extensions": [
+ ".md",
+ ".markdown",
+ ".mkd"
+ ],
+ "autoCompile": false,
+ "tasks": [
+ {
+ "task": "markdown",
+ "enable": true
+ },
+ {
+ "task": "minify-html",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".html",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "markdown",
+ "replaceWith": "html"
+ }
+ ]
+ }
+ },
+ "haml": {
+ "extensions": [
+ ".haml"
+ ],
+ "autoCompile": true,
+ "tasks": [
+ {
+ "task": "haml",
+ "enable": true
+ },
+ {
+ "task": "minify-html",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".html",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "haml",
+ "replaceWith": "html"
+ }
+ ]
+ }
+ },
+ "slim": {
+ "extensions": [
+ ".slim"
+ ],
+ "autoCompile": true,
+ "tasks": [
+ {
+ "task": "slim",
+ "enable": true
+ },
+ {
+ "task": "minify-html",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".html",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "slim",
+ "replaceWith": "html"
+ }
+ ]
+ }
+ },
+ "coffeescript": {
+ "extensions": [
+ ".coffee"
+ ],
+ "autoCompile": true,
+ "sourceMap": false,
+ "tasks": [
+ {
+ "task": "coffeescript",
+ "enable": true
+ },
+ {
+ "task": "babel",
+ "enable": false
+ },
+ {
+ "task": "bundle-js",
+ "enable": false
+ },
+ {
+ "task": "minify-js",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".js",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "coffee-script",
+ "replaceWith": "js"
+ },
+ {
+ "segment": "coffeescript",
+ "replaceWith": "js"
+ },
+ {
+ "segment": "coffee",
+ "replaceWith": "js"
+ }
+ ]
+ }
+ },
+ "turf": {
+ "extensions": [
+ ".turf",
+ ".kit"
+ ],
+ "autoCompile": true,
+ "tasks": [
+ {
+ "task": "turf",
+ "enable": true
+ },
+ {
+ "task": "minify-html",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".html",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "turf",
+ "replaceWith": "html"
+ }
+ ]
+ }
+ },
+ "typescript": {
+ "extensions": [
+ ".ts",
+ ".tsx"
+ ],
+ "autoCompile": true,
+ "sourceMap": false,
+ "tasks": [
+ {
+ "task": "typescript",
+ "enable": true
+ },
+ {
+ "task": "babel",
+ "enable": false
+ },
+ {
+ "task": "bundle-js",
+ "enable": false
+ },
+ {
+ "task": "minify-js",
+ "enable": false
+ }
+ ],
+ "output": {
+ "extension": ".js",
+ "type": "REPLACE_SEGMENTS",
+ "segments": [
+ {
+ "segment": "typescript",
+ "replaceWith": "js"
+ },
+ {
+ "segment": "ts",
+ "replaceWith": "js"
+ }
+ ]
+ }
+ },
+ "jpg": {
+ "extensions": [
+ ".jpg",
+ ".jpeg"
+ ],
+ "tasks": [
+ {
+ "task": "jpg",
+ "enable": true
+ }
+ ],
+ "output": {
+ "extension": ".jpg",
+ "type": "SOURCE_RELATIVE",
+ "relativePath": ""
+ }
+ },
+ "png": {
+ "extensions": [
+ ".png"
+ ],
+ "tasks": [
+ {
+ "task": "png",
+ "enable": true
+ }
+ ],
+ "output": {
+ "extension": ".png",
+ "type": "SOURCE_RELATIVE",
+ "relativePath": ""
+ }
+ },
+ "svg": {
+ "extensions": [
+ ".svg"
+ ],
+ "tasks": [
+ {
+ "task": "svg",
+ "enable": true
+ }
+ ],
+ "output": {
+ "extension": ".svg",
+ "type": "SOURCE_RELATIVE",
+ "relativePath": ""
+ }
+ }
+ },
+ "files": []
+ }
+}