develop #1

Merged
itdominator merged 11 commits from develop into master 2024-02-11 01:53:01 +00:00
1742 changed files with 20367 additions and 239 deletions
README.md
src
user_config
bin
usr
share
app_name
context_path
index.html
resources
css
context-menu.css
libs
bootstrap-icons
123.svgactivity.svgalarm-fill.svgalarm.svgalign-bottom.svgalign-center.svgalign-end.svgalign-middle.svgalign-start.svgalign-top.svgalt.svgapp-indicator.svgapp.svgapple.svgarchive-fill.svgarchive.svgarrow-90deg-down.svgarrow-90deg-left.svgarrow-90deg-right.svgarrow-90deg-up.svgarrow-bar-down.svgarrow-bar-left.svgarrow-bar-right.svgarrow-bar-up.svgarrow-clockwise.svgarrow-counterclockwise.svgarrow-down-circle-fill.svgarrow-down-circle.svgarrow-down-left-circle-fill.svgarrow-down-left-circle.svgarrow-down-left-square-fill.svgarrow-down-left-square.svgarrow-down-left.svgarrow-down-right-circle-fill.svgarrow-down-right-circle.svgarrow-down-right-square-fill.svgarrow-down-right-square.svgarrow-down-right.svgarrow-down-short.svgarrow-down-square-fill.svgarrow-down-square.svgarrow-down-up.svgarrow-down.svgarrow-left-circle-fill.svgarrow-left-circle.svgarrow-left-right.svgarrow-left-short.svgarrow-left-square-fill.svgarrow-left-square.svgarrow-left.svgarrow-repeat.svgarrow-return-left.svgarrow-return-right.svgarrow-right-circle-fill.svgarrow-right-circle.svgarrow-right-short.svgarrow-right-square-fill.svgarrow-right-square.svgarrow-right.svgarrow-through-heart-fill.svgarrow-through-heart.svgarrow-up-circle-fill.svgarrow-up-circle.svgarrow-up-left-circle-fill.svgarrow-up-left-circle.svgarrow-up-left-square-fill.svgarrow-up-left-square.svgarrow-up-left.svgarrow-up-right-circle-fill.svgarrow-up-right-circle.svgarrow-up-right-square-fill.svgarrow-up-right-square.svgarrow-up-right.svgarrow-up-short.svgarrow-up-square-fill.svgarrow-up-square.svgarrow-up.svgarrows-angle-contract.svgarrows-angle-expand.svgarrows-collapse.svgarrows-expand.svgarrows-fullscreen.svgarrows-move.svgaspect-ratio-fill.svgaspect-ratio.svgasterisk.svgat.svgaward-fill.svgaward.svgback.svgbackspace-fill.svgbackspace-reverse-fill.svgbackspace-reverse.svgbackspace.svgbadge-3d-fill.svgbadge-3d.svgbadge-4k-fill.svgbadge-4k.svgbadge-8k-fill.svgbadge-8k.svgbadge-ad-fill.svgbadge-ad.svgbadge-ar-fill.svgbadge-ar.svgbadge-cc-fill.svgbadge-cc.svgbadge-hd-fill.svgbadge-hd.svgbadge-sd-fill.svgbadge-sd.svgbadge-tm-fill.svgbadge-tm.svgbadge-vo-fill.svgbadge-vo.svgbadge-vr-fill.svgbadge-vr.svgbadge-wc-fill.svgbadge-wc.svgbag-check-fill.svgbag-check.svgbag-dash-fill.svgbag-dash.svgbag-fill.svgbag-heart-fill.svgbag-heart.svgbag-plus-fill.svgbag-plus.svgbag-x-fill.svgbag-x.svgbag.svgballoon-fill.svgballoon-heart-fill.svgballoon-heart.svgballoon.svgbandaid-fill.svgbandaid.svgbank.svgbank2.svgbar-chart-fill.svgbar-chart-line-fill.svgbar-chart-line.svgbar-chart-steps.svgbar-chart.svgbasket-fill.svgbasket.svgbasket2-fill.svgbasket2.svgbasket3-fill.svgbasket3.svgbattery-charging.svgbattery-full.svgbattery-half.svgbattery.svgbehance.svgbell-fill.svgbell-slash-fill.svgbell-slash.svgbell.svgbezier.svgbezier2.svgbicycle.svgbinoculars-fill.svgbinoculars.svgblockquote-left.svgblockquote-right.svgbluetooth.svgbody-text.svgbook-fill.svgbook-half.svgbook.svgbookmark-check-fill.svgbookmark-check.svgbookmark-dash-fill.svgbookmark-dash.svgbookmark-fill.svgbookmark-heart-fill.svgbookmark-heart.svgbookmark-plus-fill.svgbookmark-plus.svgbookmark-star-fill.svgbookmark-star.svgbookmark-x-fill.svgbookmark-x.svgbookmark.svgbookmarks-fill.svgbookmarks.svgbookshelf.svgboombox-fill.svgboombox.svgbootstrap-fill.svgbootstrap-icons.cssbootstrap-icons.jsonbootstrap-icons.scssbootstrap-icons.svgbootstrap-reboot.svgbootstrap.svgborder-all.svgborder-bottom.svgborder-center.svgborder-inner.svgborder-left.svgborder-middle.svgborder-outer.svgborder-right.svgborder-style.svgborder-top.svgborder-width.svgborder.svgbounding-box-circles.svgbounding-box.svgbox-arrow-down-left.svgbox-arrow-down-right.svgbox-arrow-down.svgbox-arrow-in-down-left.svgbox-arrow-in-down-right.svgbox-arrow-in-down.svgbox-arrow-in-left.svgbox-arrow-in-right.svgbox-arrow-in-up-left.svgbox-arrow-in-up-right.svgbox-arrow-in-up.svgbox-arrow-left.svgbox-arrow-right.svgbox-arrow-up-left.svgbox-arrow-up-right.svgbox-arrow-up.svgbox-seam.svgbox.svgbox2-fill.svgbox2-heart-fill.svgbox2-heart.svgbox2.svgboxes.svgbraces-asterisk.svgbraces.svgbricks.svgbriefcase-fill.svgbriefcase.svgbrightness-alt-high-fill.svgbrightness-alt-high.svgbrightness-alt-low-fill.svgbrightness-alt-low.svgbrightness-high-fill.svgbrightness-high.svgbrightness-low-fill.svgbrightness-low.svgbroadcast-pin.svgbroadcast.svgbrush-fill.svgbrush.svgbucket-fill.svgbucket.svgbug-fill.svgbug.svgbuilding.svgbullseye.svgcalculator-fill.svgcalculator.svgcalendar-check-fill.svgcalendar-check.svgcalendar-date-fill.svgcalendar-date.svgcalendar-day-fill.svgcalendar-day.svgcalendar-event-fill.svgcalendar-event.svgcalendar-fill.svgcalendar-heart-fill.svgcalendar-heart.svgcalendar-minus-fill.svgcalendar-minus.svgcalendar-month-fill.svgcalendar-month.svgcalendar-plus-fill.svgcalendar-plus.svgcalendar-range-fill.svgcalendar-range.svgcalendar-week-fill.svgcalendar-week.svgcalendar-x-fill.svgcalendar-x.svgcalendar.svgcalendar2-check-fill.svgcalendar2-check.svgcalendar2-date-fill.svgcalendar2-date.svgcalendar2-day-fill.svgcalendar2-day.svgcalendar2-event-fill.svgcalendar2-event.svgcalendar2-fill.svgcalendar2-heart-fill.svgcalendar2-heart.svgcalendar2-minus-fill.svgcalendar2-minus.svgcalendar2-month-fill.svgcalendar2-month.svgcalendar2-plus-fill.svgcalendar2-plus.svgcalendar2-range-fill.svgcalendar2-range.svgcalendar2-week-fill.svgcalendar2-week.svgcalendar2-x-fill.svgcalendar2-x.svgcalendar2.svgcalendar3-event-fill.svgcalendar3-event.svgcalendar3-fill.svgcalendar3-range-fill.svgcalendar3-range.svgcalendar3-week-fill.svgcalendar3-week.svgcalendar3.svgcalendar4-event.svgcalendar4-range.svgcalendar4-week.svgcalendar4.svgcamera-fill.svgcamera-reels-fill.svgcamera-reels.svgcamera-video-fill.svgcamera-video-off-fill.svgcamera-video-off.svgcamera-video.svgcamera.svgcamera2.svgcapslock-fill.svgcapslock.svgcard-checklist.svgcard-heading.svgcard-image.svgcard-list.svgcard-text.svgcaret-down-fill.svgcaret-down-square-fill.svgcaret-down-square.svgcaret-down.svgcaret-left-fill.svgcaret-left-square-fill.svgcaret-left-square.svgcaret-left.svgcaret-right-fill.svgcaret-right-square-fill.svgcaret-right-square.svgcaret-right.svgcaret-up-fill.svgcaret-up-square-fill.svgcaret-up-square.svgcaret-up.svgcart-check-fill.svgcart-check.svgcart-dash-fill.svgcart-dash.svgcart-fill.svgcart-plus-fill.svgcart-plus.svgcart-x-fill.svgcart-x.svgcart.svgcart2.svgcart3.svgcart4.svgcash-coin.svgcash-stack.svgcash.svgcast.svgchat-dots-fill.svgchat-dots.svgchat-fill.svgchat-heart-fill.svgchat-heart.svgchat-left-dots-fill.svgchat-left-dots.svgchat-left-fill.svgchat-left-heart-fill.svgchat-left-heart.svgchat-left-quote-fill.svgchat-left-quote.svgchat-left-text-fill.svgchat-left-text.svgchat-left.svgchat-quote-fill.svgchat-quote.svgchat-right-dots-fill.svgchat-right-dots.svgchat-right-fill.svgchat-right-heart-fill.svgchat-right-heart.svgchat-right-quote-fill.svgchat-right-quote.svgchat-right-text-fill.svgchat-right-text.svgchat-right.svgchat-square-dots-fill.svgchat-square-dots.svgchat-square-fill.svgchat-square-heart-fill.svgchat-square-heart.svgchat-square-quote-fill.svgchat-square-quote.svgchat-square-text-fill.svgchat-square-text.svgchat-square.svgchat-text-fill.svgchat-text.svgchat.svgcheck-all.svgcheck-circle-fill.svgcheck-circle.svgcheck-lg.svgcheck-square-fill.svgcheck-square.svgcheck.svgcheck2-all.svgcheck2-circle.svgcheck2-square.svgcheck2.svgchevron-bar-contract.svgchevron-bar-down.svgchevron-bar-expand.svgchevron-bar-left.svgchevron-bar-right.svgchevron-bar-up.svgchevron-compact-down.svgchevron-compact-left.svgchevron-compact-right.svgchevron-compact-up.svgchevron-contract.svgchevron-double-down.svgchevron-double-left.svgchevron-double-right.svgchevron-double-up.svgchevron-down.svgchevron-expand.svgchevron-left.svgchevron-right.svgchevron-up.svgcircle-fill.svgcircle-half.svgcircle-square.svgcircle.svgclipboard-check-fill.svgclipboard-check.svgclipboard-data-fill.svgclipboard-data.svgclipboard-fill.svgclipboard-heart-fill.svgclipboard-heart.svgclipboard-minus-fill.svgclipboard-minus.svgclipboard-plus-fill.svgclipboard-plus.svgclipboard-pulse.svgclipboard-x-fill.svgclipboard-x.svgclipboard.svgclipboard2-check-fill.svgclipboard2-check.svgclipboard2-data-fill.svgclipboard2-data.svgclipboard2-fill.svgclipboard2-heart-fill.svgclipboard2-heart.svgclipboard2-minus-fill.svgclipboard2-minus.svgclipboard2-plus-fill.svgclipboard2-plus.svgclipboard2-pulse-fill.svgclipboard2-pulse.svgclipboard2-x-fill.svgclipboard2-x.svgclipboard2.svgclock-fill.svgclock-history.svgclock.svgcloud-arrow-down-fill.svgcloud-arrow-down.svgcloud-arrow-up-fill.svgcloud-arrow-up.svgcloud-check-fill.svgcloud-check.svgcloud-download-fill.svgcloud-download.svgcloud-drizzle-fill.svgcloud-drizzle.svgcloud-fill.svgcloud-fog-fill.svgcloud-fog.svgcloud-fog2-fill.svgcloud-fog2.svgcloud-hail-fill.svgcloud-hail.svgcloud-haze-fill.svgcloud-haze.svgcloud-haze2-fill.svgcloud-haze2.svgcloud-lightning-fill.svgcloud-lightning-rain-fill.svgcloud-lightning-rain.svgcloud-lightning.svgcloud-minus-fill.svgcloud-minus.svgcloud-moon-fill.svgcloud-moon.svgcloud-plus-fill.svgcloud-plus.svgcloud-rain-fill.svgcloud-rain-heavy-fill.svgcloud-rain-heavy.svgcloud-rain.svgcloud-slash-fill.svgcloud-slash.svgcloud-sleet-fill.svgcloud-sleet.svgcloud-snow-fill.svgcloud-snow.svgcloud-sun-fill.svgcloud-sun.svgcloud-upload-fill.svgcloud-upload.svgcloud.svgclouds-fill.svgclouds.svgcloudy-fill.svgcloudy.svgcode-slash.svgcode-square.svgcode.svgcoin.svgcollection-fill.svgcollection-play-fill.svgcollection-play.svgcollection.svgcolumns-gap.svgcolumns.svgcommand.svgcompass-fill.svgcompass.svgcone-striped.svgcone.svgcontroller.svgcpu-fill.svgcpu.svgcredit-card-2-back-fill.svgcredit-card-2-back.svgcredit-card-2-front-fill.svgcredit-card-2-front.svgcredit-card-fill.svgcredit-card.svgcrop.svgcup-fill.svgcup-straw.svgcup.svgcurrency-bitcoin.svgcurrency-dollar.svgcurrency-euro.svgcurrency-exchange.svgcurrency-pound.svgcurrency-yen.svgcursor-fill.svgcursor-text.svgcursor.svgdash-circle-dotted.svgdash-circle-fill.svgdash-circle.svgdash-lg.svgdash-square-dotted.svgdash-square-fill.svgdash-square.svgdash.svgdevice-hdd-fill.svgdevice-hdd.svgdevice-ssd-fill.svgdevice-ssd.svgdiagram-2-fill.svgdiagram-2.svgdiagram-3-fill.svgdiagram-3.svgdiamond-fill.svgdiamond-half.svgdiamond.svgdice-1-fill.svgdice-1.svgdice-2-fill.svgdice-2.svgdice-3-fill.svgdice-3.svgdice-4-fill.svgdice-4.svgdice-5-fill.svgdice-5.svgdice-6-fill.svgdice-6.svgdisc-fill.svgdisc.svgdiscord.svgdisplay-fill.svgdisplay.svgdisplayport-fill.svgdisplayport.svgdistribute-horizontal.svgdistribute-vertical.svgdoor-closed-fill.svgdoor-closed.svgdoor-open-fill.svgdoor-open.svgdot.svgdownload.svgdpad-fill.svgdpad.svgdribbble.svgdroplet-fill.svgdroplet-half.svgdroplet.svgear-fill.svgear.svgearbuds.svgeasel-fill.svgeasel.svgeasel2-fill.svgeasel2.svgeasel3-fill.svgeasel3.svgegg-fill.svgegg-fried.svgegg.svgeject-fill.svgeject.svgemoji-angry-fill.svgemoji-angry.svgemoji-dizzy-fill.svgemoji-dizzy.svgemoji-expressionless-fill.svgemoji-expressionless.svgemoji-frown-fill.svgemoji-frown.svgemoji-heart-eyes-fill.svgemoji-heart-eyes.svgemoji-kiss-fill.svgemoji-kiss.svgemoji-laughing-fill.svgemoji-laughing.svgemoji-neutral-fill.svgemoji-neutral.svgemoji-smile-fill.svgemoji-smile-upside-down-fill.svgemoji-smile-upside-down.svgemoji-smile.svgemoji-sunglasses-fill.svgemoji-sunglasses.svgemoji-wink-fill.svgemoji-wink.svgenvelope-check-fill.svgenvelope-check.svgenvelope-dash-fill.svgenvelope-dash.svgenvelope-exclamation-fill.svgenvelope-exclamation.svgenvelope-fill.svgenvelope-heart-fill.svgenvelope-heart.svgenvelope-open-fill.svgenvelope-open-heart-fill.svgenvelope-open-heart.svgenvelope-open.svgenvelope-paper-fill.svgenvelope-paper-heart-fill.svgenvelope-paper-heart.svgenvelope-paper.svgenvelope-plus-fill.svgenvelope-plus.svgenvelope-slash-fill.svgenvelope-slash.svgenvelope-x-fill.svgenvelope-x.svgenvelope.svgeraser-fill.svgeraser.svgethernet.svgexclamation-circle-fill.svgexclamation-circle.svgexclamation-diamond-fill.svgexclamation-diamond.svgexclamation-lg.svgexclamation-octagon-fill.svgexclamation-octagon.svgexclamation-square-fill.svgexclamation-square.svgexclamation-triangle-fill.svgexclamation-triangle.svgexclamation.svgexclude.svgexplicit-fill.svgexplicit.svgeye-fill.svgeye-slash-fill.svgeye-slash.svgeye.svgeyedropper.svgeyeglasses.svgfacebook.svgfan.svgfile-arrow-down-fill.svgfile-arrow-down.svgfile-arrow-up-fill.svgfile-arrow-up.svgfile-bar-graph-fill.svgfile-bar-graph.svgfile-binary-fill.svgfile-binary.svgfile-break-fill.svgfile-break.svgfile-check-fill.svgfile-check.svgfile-code-fill.svgfile-code.svgfile-diff-fill.svgfile-diff.svgfile-earmark-arrow-down-fill.svgfile-earmark-arrow-down.svgfile-earmark-arrow-up-fill.svgfile-earmark-arrow-up.svgfile-earmark-bar-graph-fill.svgfile-earmark-bar-graph.svgfile-earmark-binary-fill.svgfile-earmark-binary.svgfile-earmark-break-fill.svgfile-earmark-break.svgfile-earmark-check-fill.svgfile-earmark-check.svgfile-earmark-code-fill.svgfile-earmark-code.svgfile-earmark-diff-fill.svgfile-earmark-diff.svgfile-earmark-easel-fill.svgfile-earmark-easel.svgfile-earmark-excel-fill.svgfile-earmark-excel.svgfile-earmark-fill.svgfile-earmark-font-fill.svgfile-earmark-font.svgfile-earmark-image-fill.svgfile-earmark-image.svgfile-earmark-lock-fill.svgfile-earmark-lock.svgfile-earmark-lock2-fill.svgfile-earmark-lock2.svgfile-earmark-medical-fill.svgfile-earmark-medical.svgfile-earmark-minus-fill.svgfile-earmark-minus.svgfile-earmark-music-fill.svgfile-earmark-music.svgfile-earmark-pdf-fill.svgfile-earmark-pdf.svgfile-earmark-person-fill.svgfile-earmark-person.svgfile-earmark-play-fill.svgfile-earmark-play.svgfile-earmark-plus-fill.svgfile-earmark-plus.svgfile-earmark-post-fill.svgfile-earmark-post.svgfile-earmark-ppt-fill.svgfile-earmark-ppt.svgfile-earmark-richtext-fill.svgfile-earmark-richtext.svgfile-earmark-ruled-fill.svgfile-earmark-ruled.svgfile-earmark-slides-fill.svgfile-earmark-slides.svgfile-earmark-spreadsheet-fill.svgfile-earmark-spreadsheet.svgfile-earmark-text-fill.svgfile-earmark-text.svgfile-earmark-word-fill.svgfile-earmark-word.svgfile-earmark-x-fill.svgfile-earmark-x.svgfile-earmark-zip-fill.svgfile-earmark-zip.svgfile-earmark.svgfile-easel-fill.svgfile-easel.svgfile-excel-fill.svgfile-excel.svgfile-fill.svgfile-font-fill.svgfile-font.svgfile-image-fill.svgfile-image.svgfile-lock-fill.svgfile-lock.svgfile-lock2-fill.svgfile-lock2.svgfile-medical-fill.svgfile-medical.svgfile-minus-fill.svgfile-minus.svgfile-music-fill.svgfile-music.svgfile-pdf-fill.svgfile-pdf.svgfile-person-fill.svgfile-person.svgfile-play-fill.svgfile-play.svgfile-plus-fill.svgfile-plus.svgfile-post-fill.svgfile-post.svgfile-ppt-fill.svgfile-ppt.svgfile-richtext-fill.svgfile-richtext.svgfile-ruled-fill.svgfile-ruled.svgfile-slides-fill.svgfile-slides.svgfile-spreadsheet-fill.svgfile-spreadsheet.svgfile-text-fill.svgfile-text.svgfile-word-fill.svgfile-word.svgfile-x-fill.svgfile-x.svgfile-zip-fill.svgfile-zip.svgfile.svgfiles-alt.svgfiles.svgfiletype-aac.svgfiletype-ai.svgfiletype-bmp.svgfiletype-cs.svgfiletype-css.svgfiletype-csv.svgfiletype-doc.svgfiletype-docx.svgfiletype-exe.svgfiletype-gif.svgfiletype-heic.svgfiletype-html.svgfiletype-java.svgfiletype-jpg.svgfiletype-js.svgfiletype-json.svgfiletype-jsx.svgfiletype-key.svgfiletype-m4p.svgfiletype-md.svgfiletype-mdx.svgfiletype-mov.svgfiletype-mp3.svgfiletype-mp4.svgfiletype-otf.svgfiletype-pdf.svgfiletype-php.svgfiletype-png.svgfiletype-ppt.svgfiletype-pptx.svgfiletype-psd.svgfiletype-py.svgfiletype-raw.svgfiletype-rb.svgfiletype-sass.svgfiletype-scss.svgfiletype-sh.svgfiletype-svg.svgfiletype-tiff.svgfiletype-tsx.svgfiletype-ttf.svgfiletype-txt.svgfiletype-wav.svgfiletype-woff.svgfiletype-xls.svgfiletype-xlsx.svgfiletype-xml.svgfiletype-yml.svgfilm.svgfilter-circle-fill.svgfilter-circle.svgfilter-left.svgfilter-right.svgfilter-square-fill.svgfilter-square.svgfilter.svgfingerprint.svgflag-fill.svgflag.svgflower1.svgflower2.svgflower3.svgfolder-check.svgfolder-fill.svgfolder-minus.svgfolder-plus.svgfolder-symlink-fill.svgfolder-symlink.svgfolder-x.svgfolder.svgfolder2-open.svgfolder2.svgfonts.svg
fonts
forward-fill.svgforward.svgfront.svgfullscreen-exit.svgfullscreen.svgfunnel-fill.svgfunnel.svggear-fill.svggear-wide-connected.svggear-wide.svggear.svggem.svggender-ambiguous.svggender-female.svggender-male.svggender-trans.svggeo-alt-fill.svggeo-alt.svggeo-fill.svggeo.svggift-fill.svggift.svggit.svggithub.svgglobe.svgglobe2.svggoogle.svggpu-card.svggraph-down-arrow.svggraph-down.svggraph-up-arrow.svggraph-up.svggrid-1x2-fill.svggrid-1x2.svggrid-3x2-gap-fill.svggrid-3x2-gap.svggrid-3x2.svggrid-3x3-gap-fill.svggrid-3x3-gap.svggrid-3x3.svggrid-fill.svggrid.svggrip-horizontal.svggrip-vertical.svghammer.svghand-index-fill.svghand-index-thumb-fill.svghand-index-thumb.svghand-index.svghand-thumbs-down-fill.svghand-thumbs-down.svghand-thumbs-up-fill.svghand-thumbs-up.svghandbag-fill.svghandbag.svghash.svghdd-fill.svghdd-network-fill.svghdd-network.svghdd-rack-fill.svghdd-rack.svghdd-stack-fill.svghdd-stack.svghdd.svghdmi-fill.svghdmi.svgheadphones.svgheadset-vr.svgheadset.svgheart-arrow.svgheart-fill.svgheart-half.svgheart-pulse-fill.svgheart-pulse.svgheart.svgheartbreak-fill.svgheartbreak.svghearts.svgheptagon-fill.svgheptagon-half.svgheptagon.svghexagon-fill.svghexagon-half.svghexagon.svghospital-fill.svghospital.svghourglass-bottom.svghourglass-split.svghourglass-top.svghourglass.svghouse-door-fill.svghouse-door.svghouse-fill.svghouse-heart-fill.svghouse-heart.svghouse.svghr.svghurricane.svghypnotize.svgimage-alt.svgimage-fill.svgimage.svgimages.svginbox-fill.svginbox.svginboxes-fill.svginboxes.svgincognito.svgindex.htmlinfinity.svginfo-circle-fill.svginfo-circle.svginfo-lg.svginfo-square-fill.svginfo-square.svginfo.svginput-cursor-text.svginput-cursor.svginstagram.svgintersect.svgjournal-album.svgjournal-arrow-down.svgjournal-arrow-up.svgjournal-bookmark-fill.svgjournal-bookmark.svgjournal-check.svgjournal-code.svgjournal-medical.svgjournal-minus.svgjournal-plus.svgjournal-richtext.svgjournal-text.svgjournal-x.svgjournal.svgjournals.svgjoystick.svgjustify-left.svgjustify-right.svgjustify.svgkanban-fill.svgkanban.svgkey-fill.svgkey.svgkeyboard-fill.svgkeyboard.svgladder.svglamp-fill.svglamp.svglaptop-fill.svglaptop.svglayer-backward.svglayer-forward.svglayers-fill.svglayers-half.svglayers.svglayout-sidebar-inset-reverse.svglayout-sidebar-inset.svglayout-sidebar-reverse.svglayout-sidebar.svglayout-split.svglayout-text-sidebar-reverse.svglayout-text-sidebar.svglayout-text-window-reverse.svglayout-text-window.svglayout-three-columns.svglayout-wtf.svglife-preserver.svglightbulb-fill.svglightbulb-off-fill.svglightbulb-off.svglightbulb.svglightning-charge-fill.svglightning-charge.svglightning-fill.svglightning.svgline.svglink-45deg.svglink.svglinkedin.svglist-check.svglist-columns-reverse.svglist-columns.svglist-nested.svglist-ol.svglist-stars.svglist-task.svglist-ul.svglist.svglock-fill.svglock.svgmagic.svgmagnet-fill.svgmagnet.svgmailbox.svgmailbox2.svgmap-fill.svgmap.svgmarkdown-fill.svgmarkdown.svgmask.svgmastodon.svgmedium.svgmegaphone-fill.svgmegaphone.svgmemory.svgmenu-app-fill.svgmenu-app.svgmenu-button-fill.svgmenu-button-wide-fill.svgmenu-button-wide.svgmenu-button.svgmenu-down.svgmenu-up.svgmessenger.svgmeta.svgmic-fill.svgmic-mute-fill.svgmic-mute.svgmic.svgmicrosoft.svgminecart-loaded.svgminecart.svgmodem-fill.svgmodem.svgmoisture.svgmoon-fill.svgmoon-stars-fill.svgmoon-stars.svgmoon.svgmortarboard-fill.svgmortarboard.svgmotherboard-fill.svgmotherboard.svgmouse-fill.svgmouse.svgmouse2-fill.svgmouse2.svgmouse3-fill.svgmouse3.svgmusic-note-beamed.svgmusic-note-list.svgmusic-note.svgmusic-player-fill.svgmusic-player.svgnewspaper.svgnintendo-switch.svgnode-minus-fill.svgnode-minus.svgnode-plus-fill.svgnode-plus.svgnut-fill.svgnut.svgoctagon-fill.svgoctagon-half.svgoctagon.svgoptical-audio-fill.svgoptical-audio.svgoption.svgoutlet.svgpaint-bucket.svgpalette-fill.svgpalette.svgpalette2.svgpaperclip.svgparagraph.svgpatch-check-fill.svgpatch-check.svgpatch-exclamation-fill.svgpatch-exclamation.svgpatch-minus-fill.svgpatch-minus.svgpatch-plus-fill.svgpatch-plus.svgpatch-question-fill.svgpatch-question.svgpause-btn-fill.svgpause-btn.svgpause-circle-fill.svgpause-circle.svgpause-fill.svgpause.svgpaypal.svgpc-display-horizontal.svgpc-display.svgpc-horizontal.svgpc.svgpci-card.svgpeace-fill.svgpeace.svgpen-fill.svgpen.svgpencil-fill.svgpencil-square.svgpencil.svgpentagon-fill.svgpentagon-half.svgpentagon.svgpeople-fill.svgpeople.svgpercent.svgperson-badge-fill.svgperson-badge.svgperson-bounding-box.svgperson-check-fill.svgperson-check.svgperson-circle.svgperson-dash-fill.svgperson-dash.svgperson-fill.svgperson-heart.svgperson-hearts.svgperson-lines-fill.svgperson-plus-fill.svgperson-plus.svgperson-rolodex.svgperson-square.svgperson-video.svgperson-video2.svgperson-video3.svgperson-workspace.svgperson-x-fill.svgperson-x.svgperson.svgphone-fill.svgphone-flip.svgphone-landscape-fill.svgphone-landscape.svgphone-vibrate-fill.svgphone-vibrate.svgphone.svgpie-chart-fill.svgpie-chart.svgpiggy-bank-fill.svgpiggy-bank.svgpin-angle-fill.svgpin-angle.svgpin-fill.svgpin-map-fill.svgpin-map.svgpin.svgpinterest.svgpip-fill.svgpip.svgplay-btn-fill.svgplay-btn.svgplay-circle-fill.svgplay-circle.svgplay-fill.svgplay.svgplaystation.svgplug-fill.svgplug.svgplugin.svgplus-circle-dotted.svgplus-circle-fill.svgplus-circle.svgplus-lg.svgplus-slash-minus.svgplus-square-dotted.svgplus-square-fill.svgplus-square.svgplus.svgpostage-fill.svgpostage-heart-fill.svgpostage-heart.svgpostage.svgpostcard-fill.svgpostcard-heart-fill.svgpostcard-heart.svgpostcard.svgpower.svgprinter-fill.svgprinter.svgprojector-fill.svgprojector.svgpuzzle-fill.svgpuzzle.svgqr-code-scan.svgqr-code.svgquestion-circle-fill.svgquestion-circle.svgquestion-diamond-fill.svgquestion-diamond.svgquestion-lg.svgquestion-octagon-fill.svgquestion-octagon.svgquestion-square-fill.svgquestion-square.svgquestion.svgquora.svgquote.svgradioactive.svgrainbow.svgreceipt-cutoff.svgreceipt.svgreception-0.svgreception-1.svgreception-2.svgreception-3.svgreception-4.svgrecord-btn-fill.svgrecord-btn.svgrecord-circle-fill.svgrecord-circle.svgrecord-fill.svgrecord.svgrecord2-fill.svgrecord2.svgrecycle.svgreddit.svgreply-all-fill.svgreply-all.svgreply-fill.svgreply.svgrobot.svgrouter-fill.svgrouter.svgrss-fill.svgrss.svgrulers.svgsafe-fill.svgsafe.svgsafe2-fill.svgsafe2.svgsave-fill.svgsave.svgsave2-fill.svgsave2.svgscissors.svgscrewdriver.svgsd-card-fill.svgsd-card.svgsearch-heart-fill.svgsearch-heart.svgsearch.svgsegmented-nav.svgsend-check-fill.svgsend-check.svgsend-dash-fill.svgsend-dash.svgsend-exclamation-fill.svgsend-exclamation.svgsend-fill.svgsend-plus-fill.svgsend-plus.svgsend-slash-fill.svgsend-slash.svgsend-x-fill.svgsend-x.svgsend.svgserver.svgshare-fill.svgshare.svgshield-check.svgshield-exclamation.svgshield-fill-check.svgshield-fill-exclamation.svgshield-fill-minus.svgshield-fill-plus.svgshield-fill-x.svgshield-fill.svgshield-lock-fill.svgshield-lock.svgshield-minus.svgshield-plus.svgshield-shaded.svgshield-slash-fill.svgshield-slash.svgshield-x.svgshield.svgshift-fill.svgshift.svgshop-window.svgshop.svgshuffle.svgsignal.svgsignpost-2-fill.svgsignpost-2.svgsignpost-fill.svgsignpost-split-fill.svgsignpost-split.svgsignpost.svgsim-fill.svgsim.svgskip-backward-btn-fill.svgskip-backward-btn.svgskip-backward-circle-fill.svgskip-backward-circle.svgskip-backward-fill.svgskip-backward.svgskip-end-btn-fill.svgskip-end-btn.svgskip-end-circle-fill.svgskip-end-circle.svgskip-end-fill.svgskip-end.svgskip-forward-btn-fill.svgskip-forward-btn.svgskip-forward-circle-fill.svgskip-forward-circle.svgskip-forward-fill.svgskip-forward.svgskip-start-btn-fill.svgskip-start-btn.svgskip-start-circle-fill.svgskip-start-circle.svgskip-start-fill.svgskip-start.svgskype.svgslack.svgslash-circle-fill.svgslash-circle.svgslash-lg.svgslash-square-fill.svgslash-square.svgslash.svgsliders.svgsliders2-vertical.svgsliders2.svgsmartwatch.svgsnapchat.svgsnow.svgsnow2.svgsnow3.svgsort-alpha-down-alt.svgsort-alpha-down.svgsort-alpha-up-alt.svgsort-alpha-up.svgsort-down-alt.svgsort-down.svgsort-numeric-down-alt.svgsort-numeric-down.svgsort-numeric-up-alt.svgsort-numeric-up.svgsort-up-alt.svgsort-up.svgsoundwave.svgspeaker-fill.svgspeaker.svgspeedometer.svgspeedometer2.svgspellcheck.svgspotify.svgsquare-fill.svgsquare-half.svgsquare.svgstack-overflow.svgstack.svgstar-fill.svgstar-half.svgstar.svgstars.svgsteam.svgstickies-fill.svgstickies.svgsticky-fill.svgsticky.svgstop-btn-fill.svgstop-btn.svgstop-circle-fill.svgstop-circle.svgstop-fill.svgstop.svgstoplights-fill.svgstoplights.svgstopwatch-fill.svgstopwatch.svgstrava.svgsubtract.svgsuit-club-fill.svgsuit-club.svgsuit-diamond-fill.svgsuit-diamond.svgsuit-heart-fill.svgsuit-heart.svgsuit-spade-fill.svgsuit-spade.svgsun-fill.svgsun.svgsunglasses.svgsunrise-fill.svgsunrise.svgsunset-fill.svgsunset.svgsymmetry-horizontal.svgsymmetry-vertical.svgtable.svgtablet-fill.svgtablet-landscape-fill.svgtablet-landscape.svgtablet.svgtag-fill.svgtag.svgtags-fill.svgtags.svgtelegram.svgtelephone-fill.svgtelephone-forward-fill.svgtelephone-forward.svgtelephone-inbound-fill.svgtelephone-inbound.svgtelephone-minus-fill.svgtelephone-minus.svgtelephone-outbound-fill.svgtelephone-outbound.svgtelephone-plus-fill.svgtelephone-plus.svgtelephone-x-fill.svgtelephone-x.svgtelephone.svgterminal-dash.svgterminal-fill.svgterminal-plus.svgterminal-split.svgterminal-x.svgterminal.svgtext-center.svgtext-indent-left.svgtext-indent-right.svgtext-left.svgtext-paragraph.svgtext-right.svgtextarea-resize.svgtextarea-t.svgtextarea.svgthermometer-half.svgthermometer-high.svgthermometer-low.svgthermometer-snow.svgthermometer-sun.svgthermometer.svgthree-dots-vertical.svgthree-dots.svgthunderbolt-fill.svgthunderbolt.svgticket-detailed-fill.svgticket-detailed.svgticket-fill.svgticket-perforated-fill.svgticket-perforated.svgticket.svgtiktok.svgtoggle-off.svgtoggle-on.svgtoggle2-off.svgtoggle2-on.svgtoggles.svgtoggles2.svgtools.svgtornado.svgtranslate.svgtrash-fill.svgtrash.svgtrash2-fill.svgtrash2.svgtrash3-fill.svgtrash3.svgtree-fill.svgtree.svgtriangle-fill.svgtriangle-half.svgtriangle.svgtrophy-fill.svgtrophy.svgtropical-storm.svgtruck-flatbed.svgtruck.svgtsunami.svgtv-fill.svgtv.svgtwitch.svgtwitter.svgtype-bold.svgtype-h1.svgtype-h2.svgtype-h3.svgtype-italic.svgtype-strikethrough.svgtype-underline.svgtype.svgui-checks-grid.svgui-checks.svgui-radios-grid.svgui-radios.svgumbrella-fill.svgumbrella.svgunion.svgunlock-fill.svgunlock.svgupc-scan.svgupc.svgupload.svgusb-c-fill.svgusb-c.svgusb-drive-fill.svgusb-drive.svgusb-fill.svgusb-micro-fill.svgusb-micro.svgusb-mini-fill.svgusb-mini.svgusb-plug-fill.svgusb-plug.svgusb-symbol.svgusb.svgvalentine.svgvalentine2.svgvector-pen.svgview-list.svgview-stacked.svgvimeo.svgvinyl-fill.svgvinyl.svgvoicemail.svgvolume-down-fill.svgvolume-down.svgvolume-mute-fill.svgvolume-mute.svgvolume-off-fill.svgvolume-off.svgvolume-up-fill.svgvolume-up.svgvr.svgwallet-fill.svgwallet.svgwallet2.svgwatch.svgwater.svgwebcam-fill.svgwebcam.svgwhatsapp.svgwifi-1.svgwifi-2.svgwifi-off.svgwifi.svgwind.svgwindow-dash.svgwindow-desktop.svgwindow-dock.svgwindow-fullscreen.svgwindow-plus.svgwindow-sidebar.svgwindow-split.svgwindow-stack.svgwindow-x.svgwindow.svgwindows.svgwordpress.svgwrench-adjustable-circle-fill.svgwrench-adjustable-circle.svgwrench-adjustable.svgwrench.svgx-circle-fill.svgx-circle.svgx-diamond-fill.svgx-diamond.svgx-lg.svgx-octagon-fill.svgx-octagon.svgx-square-fill.svgx-square.svgx.svgxbox.svgyin-yang.svgyoutube.svgzoom-in.svgzoom-out.svg
bootstrap5
main.cssoverrides.css
js

@@ -8,6 +8,8 @@ A template project for Python with Gtk applications.
* sqlmodel (SQL databases and is powered by Pydantic and SQLAlchemy)
### Note
* Move respetive sub folder content under user_config to the same places in Linux. Though, user/share/<app name> can go to ~/.config folder if prefered.
* In additiion, place the plugins folder in the same app folder you moved to /usr/share/<app name> or ~/.config/<app name> .
There are a "\<change_me\>" strings and files that need to be set according to your app's name located at:
* \_\_builtins\_\_.py
* user_config/bin/app_name

@@ -6,25 +6,29 @@ import sys
# Lib imports
# Application imports
from utils.models import engine
from utils.event_system import EventSystem
from utils.endpoint_registry import EndpointRegistry
from utils.keybindings import Keybindings
from utils.logger import Logger
from utils.settings_manager.manager import SettingsManager
# from libs.db import DB
from libs.event_system import EventSystem
from libs.endpoint_registry import EndpointRegistry
from libs.keybindings import Keybindings
from libs.logger import Logger
from libs.settings_manager.manager import SettingsManager
# NOTE: Threads WILL NOT die with parent's destruction.
def threaded_wrapper(fn):
def wrapper(*args, **kwargs):
threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start()
thread = threading.Thread(target = fn, args = args, kwargs = kwargs, daemon = False)
thread.start()
return thread
return wrapper
# NOTE: Threads WILL die with parent's destruction.
def daemon_threaded_wrapper(fn):
def wrapper(*args, **kwargs):
threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
thread = threading.Thread(target = fn, args = args, kwargs = kwargs, daemon = True)
thread.start()
return thread
return wrapper
@@ -32,12 +36,12 @@ def daemon_threaded_wrapper(fn):
# NOTE: Just reminding myself we can add to builtins two different ways...
# __builtins__.update({"event_system": Builtins()})
builtins.app_name = "<change_me>"
builtins.db = engine
builtins.keybindings = Keybindings()
builtins.event_system = EventSystem()
builtins.endpoint_registry = EndpointRegistry()
builtins.settings_manager = SettingsManager()
# builtins.db = DB()
settings_manager.load_settings()

@@ -10,9 +10,6 @@ import tracemalloc
tracemalloc.start()
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from __builtins__ import *
@@ -20,24 +17,8 @@ from app import Application
if __name__ == "__main__":
''' Set process title, get arguments, and create GTK main thread. '''
try:
def main(args, unknownargs):
setproctitle(f'{app_name}')
faulthandler.enable() # For better debug info
parser = argparse.ArgumentParser()
# Add long and short arguments
parser.add_argument("--debug", "-d", default="false", help="Do extra console messaging.")
parser.add_argument("--trace-debug", "-td", default="false", help="Disable saves, ignore IPC lock, do extra console messaging.")
parser.add_argument("--no-plugins", "-np", default="false", help="Do not load plugins.")
parser.add_argument("--new-tab", "-nt", default="false", help="Opens a 'New Tab' if a handler is set for it.")
parser.add_argument("--file", "-f", default="default", help="JUST SOME FILE ARG.")
# Read arguments (If any...)
args, unknownargs = parser.parse_known_args()
if args.debug == "true":
settings_manager.set_debug(True)
@@ -47,7 +28,27 @@ if __name__ == "__main__":
settings_manager.do_dirty_start_check()
Application(args, unknownargs)
Gtk.main()
if __name__ == "__main__":
''' Set process title, get arguments, and create GTK main thread. '''
parser = argparse.ArgumentParser()
# Add long and short arguments
parser.add_argument("--debug", "-d", default="false", help="Do extra console messaging.")
parser.add_argument("--trace-debug", "-td", default="false", help="Disable saves, ignore IPC lock, do extra console messaging.")
parser.add_argument("--no-plugins", "-np", default="false", help="Do not load plugins.")
parser.add_argument("--new-tab", "-nt", default="false", help="Opens a 'New Tab' if a handler is set for it.")
parser.add_argument("--file", "-f", default="default", help="JUST SOME FILE ARG.")
# Read arguments (If any...)
args, unknownargs = parser.parse_known_args()
try:
faulthandler.enable() # For better debug info
main(args, unknownargs)
except Exception as e:
traceback.print_exc()
quit()

@@ -5,8 +5,8 @@ import os
# Lib imports
# Application imports
from utils.debugging import debug_signal_handler
from utils.ipc_server import IPCServer
from libs.debugging import debug_signal_handler
from libs.ipc_server import IPCServer
from core.window import Window
@@ -15,35 +15,40 @@ class AppLaunchException(Exception):
...
class Application(IPCServer):
class Application:
""" docstring for Application. """
def __init__(self, args, unknownargs):
super(Application, self).__init__()
if not settings_manager.is_trace_debug():
self.socket_realization_check()
self.load_ipc(args, unknownargs)
if not self.is_ipc_alive:
self.setup_debug_hook()
Window(args, unknownargs).main()
def load_ipc(self, args, unknownargs):
ipc_server = IPCServer()
self.ipc_realization_check(ipc_server)
if not ipc_server.is_ipc_alive:
for arg in unknownargs + [args.new_tab,]:
if os.path.isfile(arg):
message = f"FILE|{arg}"
self.send_ipc_message(message)
ipc_server.send_ipc_message(message)
raise AppLaunchException(f"{app_name} IPC Server Exists: Will send path(s) to it and close...")
raise AppLaunchException(f"{app_name} IPC Server Exists: Have sent path(s) to it and closing...")
self.setup_debug_hook()
Window(args, unknownargs)
def socket_realization_check(self):
def ipc_realization_check(self, ipc_server):
try:
self.create_ipc_listener()
ipc_server.create_ipc_listener()
except Exception:
self.send_test_ipc_message()
ipc_server.send_test_ipc_message()
try:
self.create_ipc_listener()
ipc_server.create_ipc_listener()
except Exception as e:
...

@@ -6,9 +6,8 @@ gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from .left_container import LeftContainer
from .center_container import CenterContainer
from .right_container import RightContainer
from .header_container import HeaderContainer
from .body_container import BodyContainer
@@ -38,9 +37,8 @@ class BaseContainer(Gtk.Box):
event_system.subscribe("remove_transparency", self._remove_transparency)
def _load_widgets(self):
self.add(LeftContainer())
self.add(CenterContainer())
self.add(RightContainer())
self.add(HeaderContainer())
self.add(BodyContainer())
def _update_transparency(self):
self.ctx.add_class(f"mw_transparency_{settings.theming.transparency}")

@@ -0,0 +1,44 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from .left_container import LeftContainer
from .center_container import CenterContainer
from .right_container import RightContainer
class BodyContainer(Gtk.Box):
def __init__(self):
super(BodyContainer, self).__init__()
self.ctx = self.get_style_context()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets()
self.show_all()
def _setup_styling(self):
self.set_orientation(Gtk.Orientation.HORIZONTAL)
self.ctx.add_class("body-container")
self.set_homogeneous(True)
def _setup_signals(self):
...
def _subscribe_to_events(self):
...
def _load_widgets(self):
self.add(LeftContainer())
self.add(CenterContainer())
self.add(RightContainer())

@@ -6,7 +6,8 @@ gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from ..widgets.transparency_scale import TransparencyScale
from ..widgets.webkit.webkit_ui import WebkitUI
class CenterContainer(Gtk.Box):
@@ -35,21 +36,13 @@ class CenterContainer(Gtk.Box):
def _load_widgets(self):
glade_box = self._builder.get_object("glade_box")
glade_box = self._builder.get_object("glade_box")
button = Gtk.Button(label = "Interactive Debug")
button2 = Gtk.Button(label = "Click Me!")
button = Gtk.Button(label = "Click Me!")
button.connect("clicked", self._interactive_debug)
button2.connect("clicked", self._hello_world)
button.connect("clicked", self._hello_world)
self.add(TransparencyScale())
self.add(button)
self.add(button2)
self.add(glade_box)
def _interactive_debug(self, widget = None, eve = None):
event_system.emit("load_interactive_debug")
self.add( WebkitUI() )
def _hello_world(self, widget = None, eve = None):
logger.debug("Hello, World!")

@@ -0,0 +1,46 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from ..widgets.transparency_scale import TransparencyScale
class HeaderContainer(Gtk.Box):
def __init__(self):
super(HeaderContainer, self).__init__()
self.ctx = self.get_style_context()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets()
self.show_all()
def _setup_styling(self):
self.set_orientation(Gtk.Orientation.HORIZONTAL)
self.ctx.add_class("header-container")
def _setup_signals(self):
...
def _subscribe_to_events(self):
...
def _load_widgets(self):
button = Gtk.Button(label = "Interactive Debug")
button.connect("clicked", self._interactive_debug)
self.add(TransparencyScale())
self.add(button)
def _interactive_debug(self, widget = None, eve = None):
event_system.emit("load_interactive_debug")

@@ -0,0 +1,3 @@
"""
Controllers Module
"""

@@ -7,22 +7,24 @@ gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from .mixins.signals_mixins import SignalsMixins
from .mixins.dummy_mixin import DummyMixin
from .controller_data import ControllerData
from .containers.base_container import BaseContainer
from libs.mixins.ipc_signals_mixin import IPCSignalsMixin
from libs.mixins.keyboard_signals_mixin import KeyboardSignalsMixin
from ..containers.base_container import BaseContainer
from .base_controller_data import BaseControllerData
from .bridge_controller import BridgeController
class Controller(DummyMixin, SignalsMixins, ControllerData):
class BaseController(IPCSignalsMixin, KeyboardSignalsMixin, BaseControllerData):
def __init__(self, args, unknownargs):
self.setup_controller_data()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self.print_hello_world() # A mixin method from the DummyMixin file
self._load_controllers()
if args.no_plugins == "false":
self.plugins.launch_plugins()
@@ -53,6 +55,9 @@ class Controller(DummyMixin, SignalsMixins, ControllerData):
event_system.subscribe("handle_dir_from_ipc", self.handle_dir_from_ipc)
event_system.subscribe("tggl_top_main_menubar", self._tggl_top_main_menubar)
def _load_controllers(self):
BridgeController()
def _tggl_top_main_menubar(self):
logger.debug("_tggl_top_main_menubar > stub...")

@@ -10,8 +10,8 @@ from plugins.plugins_controller import PluginsController
class ControllerData:
''' ControllerData contains most of the state of the app at ay given time. It also has some support methods. '''
class BaseControllerData:
''' BaseControllerData contains most of the state of the app at ay given time. It also has some support methods. '''
def setup_controller_data(self) -> None:
self.window = settings_manager.get_main_window()

@@ -0,0 +1,43 @@
# Python imports
import base64
# Lib imports
# Application imports
class BridgeController:
def __init__(self):
self.opened_files = {}
self._setup_signals()
self._subscribe_to_events()
def _setup_signals(self):
...
def _subscribe_to_events(self):
event_system.subscribe("handle_bridge_event", self.handle_bridge_event)
def handle_bridge_event(self, event):
match event.topic:
case "save":
event_system.emit(f"handle_file_event_{event.originator}", (event,))
case "close":
event_system.emit(f"handle_file_event_{event.originator}", (event,))
case "load_buffer":
event_system.emit(f"handle_file_event_{event.originator}", (event,))
case "load_file":
event_system.emit(f"handle_file_event_{event.originator}", (event,))
case "alert":
content = base64.b64decode( event.content.encode() ).decode("utf-8")
logger.info(f"\nMessage Topic: {event.topic}\nMessage Content: {content}")
case "error":
content = base64.b64decode( event.content.encode() ).decode("utf-8")
logger.info(content)
case _:
...

@@ -1,3 +0,0 @@
"""
Generic Mixins Module
"""

@@ -1,13 +0,0 @@
# Python imports
# Lib imports
# Application imports
class DummyMixin:
""" DummyMixin is an example of how mixins are used and structured in a project. """
def print_hello_world(self) -> None:
logger.debug("Hello, World!")

@@ -1,3 +0,0 @@
"""
Signals module
"""

@@ -1,13 +0,0 @@
# Python imports
# Lib imports
# Application imports
from .signals.ipc_signals_mixin import IPCSignalsMixin
from .signals.keyboard_signals_mixin import KeyboardSignalsMixin
class SignalsMixins(KeyboardSignalsMixin, IPCSignalsMixin):
...

@@ -26,7 +26,7 @@ class TransparencyScale(Gtk.Scale):
self.set_digits(0)
self.set_value_pos(Gtk.PositionType.RIGHT)
self.add_mark(50.0, Gtk.PositionType.TOP, "50%")
self.set_hexpand(True)
def _setup_signals(self):
self.connect("value-changed", self._update_transparency)

@@ -0,0 +1,3 @@
"""
WebKit2 UI Module
"""

@@ -0,0 +1,108 @@
# Python imports
import json
# Lib imports
import gi
gi.require_version('Gdk', '3.0')
gi.require_version('WebKit2', '4.0')
from gi.repository import Gdk
from gi.repository import WebKit2
# Application imports
from libs.data_types import Event
class WebkitUI(WebKit2.WebView):
def __init__(self):
super(WebkitUI, self).__init__()
# self.get_context().set_sandbox_enabled(False)
self._load_settings()
self._setup_styling()
self._subscribe_to_events()
self._load_view()
self._setup_content_manager()
self.show_all()
if settings_manager.is_debug():
inspector = self.get_inspector()
inspector.show()
def _setup_styling(self):
self.set_vexpand(True)
self.set_hexpand(True)
self.set_background_color( Gdk.RGBA(0, 0, 0, 0.0) )
def _subscribe_to_events(self):
event_system.subscribe(f"ui_message", self.ui_message)
def _load_settings(self):
self.set_settings( WebkitUISettings() )
def _load_view(self):
path = settings_manager.get_context_path()
data = None
with open(f"{path}/index.html", "r") as f:
data = f.read()
self.load_html(content = data, base_uri = f"file://{path}/")
def _setup_content_manager(self):
content_manager = self.get_user_content_manager()
content_manager.connect("script-message-received", self._process_js_message)
content_manager.register_script_message_handler("backend")
def _process_js_message(self, user_content_manager, js_result):
js_value = js_result.get_js_value()
message = js_value.to_string()
try:
event = Event( **json.loads(message) )
event_system.emit("handle_bridge_event", (event,))
except Exception as e:
logger.info(e)
def ui_message(self, mtype, message):
command = f"displayMessage('{message}', '{mtype}', '3')"
self.run_javascript(command, None, None)
class WebkitUISettings(WebKit2.Settings):
def __init__(self):
super(WebkitUISettings, self).__init__()
self._set_default_settings()
# Note: Highly insecure setup but most "app" like setup I could think of.
# Audit heavily any scripts/links ran/clicked under this setup!
def _set_default_settings(self):
# self.set_enable_xss_auditor(True)
# self.set_enable_hyperlink_auditing(True)
self.set_enable_xss_auditor(False)
self.set_enable_hyperlink_auditing(False)
self.set_enable_dns_prefetching(False)
self.set_allow_file_access_from_file_urls(True)
self.set_allow_universal_access_from_file_urls(True)
# self.set_enable_java(True)
self.set_enable_page_cache(False)
self.set_enable_offline_web_application_cache(False)
self.set_enable_html5_local_storage(False)
self.set_enable_html5_database(False)
self.set_print_backgrounds(False)
self.set_enable_tabs_to_links(False)
self.set_enable_fullscreen(True)
self.set_enable_developer_extras(True)
self.set_enable_webrtc(True)
self.set_enable_webaudio(True)
self.set_enable_accelerated_2d_canvas(True)
self.set_user_agent(f"Mozilla/5.0 {app_name}")

@@ -0,0 +1,64 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gdk', '3.0')
gi.require_version('WebKit2', '4.0')
from gi.repository import Gdk
from gi.repository import WebKit2
# Application imports
from libs.settings_manager.other.webkit_ui_settings import WebkitUISettings
class WebkitUI(WebKit2.WebView):
def __init__(self):
super(WebkitUI, self).__init__()
self._setup_styling()
self._subscribe_to_events()
self._load_view()
self._setup_content_manager()
self.show_all()
def _setup_styling(self):
self.set_vexpand(True)
self.set_hexpand(True)
self.set_background_color( Gdk.RGBA(0, 0, 0, 0.0) )
def _subscribe_to_events(self):
event_system.subscribe(f"ui_message", self.ui_message)
def _load_settings(self):
self.set_settings( WebkitUISettings() )
def _load_view(self):
path = settings_manager.get_context_path()
data = None
with open(f"{path}/index.html", "r") as f:
data = f.read()
self.load_html(content = data, base_uri = f"file://{path}/")
def _setup_content_manager(self):
content_manager = self.get_user_content_manager()
content_manager.connect("script-message-received", self._process_js_message)
content_manager.register_script_message_handler("backend")
def _process_js_message(self, user_content_manager, js_result):
js_value = js_result.get_js_value()
message = js_value.to_string()
try:
event = Event( **json.loads(message) )
event_system.emit("handle_bridge_event", (event,))
except Exception as e:
logger.info(e)
def ui_message(self, message, mtype):
command = f"displayMessage('{message}', '{mtype}', '3')"
self.run_javascript(command, None, None)

@@ -11,7 +11,8 @@ from gi.repository import Gdk
from gi.repository import GLib
# Application imports
from core.controller import Controller
from core.controllers.base_controller import BaseController
class ControllerStartExceptiom(Exception):
@@ -19,7 +20,6 @@ class ControllerStartExceptiom(Exception):
class Window(Gtk.ApplicationWindow):
""" docstring for Window. """
@@ -29,13 +29,14 @@ class Window(Gtk.ApplicationWindow):
self._controller = None
self._set_window_data()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets(args, unknownargs)
self._set_window_data()
self._set_size_constraints()
self.show()
@@ -50,8 +51,11 @@ class Window(Gtk.ApplicationWindow):
ctx.add_class(f"mw_transparency_{settings.theming.transparency}")
def _setup_signals(self):
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self._tear_down)
self.connect("focus-in-event", self._on_focus_in_event)
self.connect("focus-out-event", self._on_focus_out_event)
self.connect("delete-event", self._tear_down)
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self._tear_down)
def _subscribe_to_events(self):
event_system.subscribe("tear_down", self._tear_down)
@@ -61,9 +65,9 @@ class Window(Gtk.ApplicationWindow):
if settings_manager.is_debug():
self.set_interactive_debugging(True)
self._controller = Controller(args, unknownargs)
self._controller = BaseController(args, unknownargs)
if not self._controller:
raise ControllerStartException("Controller exited and doesn't exist...")
raise ControllerStartException("BaseController exited and doesn't exist...")
self.add( self._controller.get_base_container() )
@@ -101,6 +105,13 @@ class Window(Gtk.ApplicationWindow):
cr.paint()
cr.set_operator(cairo.OPERATOR_OVER)
def _on_focus_in_event(self, widget, event):
event_system.emit("pause_dnd_signals")
def _on_focus_out_event(self, widget, event):
event_system.emit("listen_dnd_signals")
def _load_interactive_debug(self):
self.set_interactive_debugging(True)
@@ -108,7 +119,7 @@ class Window(Gtk.ApplicationWindow):
def _tear_down(self, widget = None, eve = None):
event_system.emit("shutting_down")
size = self.get_default_size()
size = self.get_size()
pos = self.get_position()
settings_manager.set_main_window_width(size.width)
@@ -119,3 +130,6 @@ class Window(Gtk.ApplicationWindow):
settings_manager.clear_pid()
Gtk.main_quit()
def main(self):
Gtk.main()

@@ -0,0 +1,5 @@
"""
Dasta Class module
"""
from .event import Event

@@ -0,0 +1,14 @@
# Python imports
from dataclasses import dataclass, field
# Lib imports
# Application imports
@dataclass
class Event:
topic: str
content: str
raw_content: str

42
src/libs/db.py Normal file

@@ -0,0 +1,42 @@
# Python imports
from typing import Optional
from os import path
# Lib imports
from sqlmodel import Session, create_engine
# Application imports
from .models import SQLModel, User
class DB:
def __init__(self):
super(DB, self).__init__()
self.engine = None
self.create_engine()
def create_engine(self):
db_path = f"sqlite:///{settings_manager.get_home_config_path()}/database.db"
self.engine = create_engine(db_path)
SQLModel.metadata.create_all(self.engine)
def _add_entry(self, entry):
with Session(self.engine) as session:
session.add(entry)
session.commit()
def add_user_entry(self, name = None, password = None, email = None):
if not name or not password or not email: return
user = User()
user.name = name
user.password = password
user.email = email
self._add_entry(user)

@@ -0,0 +1,3 @@
"""
Utils/Mixins module
"""

@@ -0,0 +1,70 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import Gio
# Application imports
class DnDMixin:
def _setup_dnd(self):
flags = Gtk.DestDefaults.ALL
PLAIN_TEXT_TARGET_TYPE = 70
URI_TARGET_TYPE = 80
text_target = Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags(0), PLAIN_TEXT_TARGET_TYPE)
uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE)
# targets = [ text_target, uri_target ]
targets = [ uri_target ]
action = Gdk.DragAction.COPY
# self.drag_dest_set_target_list(targets)
self.drag_dest_set(flags, targets, action)
self._setup_dnd_signals()
def _setup_dnd_signals(self):
# self.connect("drag-motion", self._on_drag_motion)
# self.connect('drag-drop', self._on_drag_set)
self.connect("drag-data-received", self._on_drag_data_received)
def _on_drag_motion(self, widget, drag_context, x, y, time):
Gdk.drag_status(drag_context, drag_context.get_actions(), time)
return False
def _on_drag_set(self, widget, drag_context, data, info, time):
self.drag_get_data(drag_context, drag_context.list_targets()[-1], time)
return False
def _on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
if info == 70: return
if info == 80:
uris = data.get_uris()
files = []
if len(uris) == 0:
uris = data.get_text().split("\n")
for uri in uris:
gfile = None
try:
gfile = Gio.File.new_for_uri(uri)
except Exception as e:
gfile = Gio.File.new_for_path(uri)
files.append(gfile)
event_system.emit('set_pre_drop_dnd', (files,))

@@ -25,6 +25,14 @@ class KeyboardSignalsMixin:
self.shift_down = False
self.alt_down = False
def unmap_special_keys(self, keyname):
if "control" in keyname:
self.ctrl_down = False
if "shift" in keyname:
self.shift_down = False
if "alt" in keyname:
self.alt_down = False
def on_global_key_press_controller(self, eve, user_data):
keyname = Gdk.keyval_name(user_data.keyval).lower()
modifiers = Gdk.ModifierType(user_data.get_state() & ~Gdk.ModifierType.LOCK_MASK)
@@ -46,15 +54,8 @@ class KeyboardSignalsMixin:
if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]:
should_return = self.was_midified_key and (self.ctrl_down or self.shift_down or self.alt_down)
self.unmap_special_keys(keyname)
if "control" in keyname:
self.ctrl_down = False
if "shift" in keyname:
self.shift_down = False
if "alt" in keyname:
self.alt_down = False
# NOTE: In effect a filter after releasing a modifier and we have a modifier mapped
if should_return:
self.was_midified_key = False
return
@@ -65,30 +66,33 @@ class KeyboardSignalsMixin:
logger.debug(f"on_global_key_release_controller > mapping > {mapping}")
if mapping:
# See if in controller scope
self.handle_mapped_key_event(mapping)
else:
self.handle_as_key_event_scope(mapping)
def handle_mapped_key_event(self, mapping):
try:
getattr(self, mapping)()
return True
self.handle_as_controller_scope()
except Exception:
# Must be plugins scope, event call, OR we forgot to add method to controller scope
self.handle_as_plugin_scope(mapping)
def handle_as_controller_scope(self, mapping):
getattr(self, mapping)()
def handle_as_plugin_scope(self, mapping):
if "||" in mapping:
sender, eve_type = mapping.split("||")
else:
sender = ""
eve_type = mapping
self.handle_key_event_system(sender, eve_type)
else:
self.handle_as_key_event_system(sender, eve_type)
def handle_as_key_event_scope(self, mapping):
logger.debug(f"on_global_key_release_controller > key > {keyname}")
if self.ctrl_down:
if not keyname in ["1", "kp_1", "2", "kp_2", "3", "kp_3", "4", "kp_4"]:
if self.ctrl_down and not keyname in ["1", "kp_1", "2", "kp_2", "3", "kp_3", "4", "kp_4"]:
self.handle_key_event_system(None, mapping)
else:
...
def handle_key_event_system(self, sender, eve_type):
event_system.emit(eve_type)
def keyboard_close_tab(self):
...

15
src/libs/models.py Normal file

@@ -0,0 +1,15 @@
# Python imports
from typing import Optional
# Lib imports
from sqlmodel import SQLModel, Field
# Application imports
class User(SQLModel, table = True):
id: Optional[int] = Field(default = None, primary_key = True)
name: str
password: str
email: Optional[str] = None

@@ -1,8 +1,6 @@
# Python imports
import signal
import io
import json
import inspect
import json
import zipfile
from os import path
@@ -30,6 +28,7 @@ class SettingsManager(StartCheckMixin, Singleton):
self._USR_PATH = f"/usr/share/{app_name.lower()}"
self._USR_CONFIG_FILE = f"{self._USR_PATH}/settings.json"
self._CONTEXT_PATH = f"{self._HOME_CONFIG_PATH}/context_path"
self._PLUGINS_PATH = f"{self._HOME_CONFIG_PATH}/plugins"
self._DEFAULT_ICONS = f"{self._HOME_CONFIG_PATH}/icons"
self._CONFIG_FILE = f"{self._HOME_CONFIG_PATH}/settings.json"
@@ -146,6 +145,7 @@ class SettingsManager(StartCheckMixin, Singleton):
def get_ui_widgets_path(self) -> str: return self._UI_WIDEGTS_PATH
def get_context_menu_data(self) -> str: return self._context_menu_data
def get_context_path(self) -> str: return self._CONTEXT_PATH
def get_plugins_path(self) -> str: return self._PLUGINS_PATH
def get_icon_theme(self) -> str: return self._ICON_THEME
def get_css_file(self) -> str: return self._CSS_FILE

@@ -0,0 +1,3 @@
"""
Settings Other module
"""

@@ -0,0 +1,42 @@
# Python imports
# Lib imports
import gi
gi.require_version('WebKit2', '4.0')
from gi.repository import WebKit2
# Application imports
class WebkitUISettings(WebKit2.Settings):
def __init__(self):
super(WebkitUISettings, self).__init__()
self._set_default_settings()
# Note: Highly insecure setup but most "app" like setup I could think of.
# Audit heavily any scripts/links ran/clicked under this setup!
def _set_default_settings(self):
self.set_enable_xss_auditor(True)
self.set_enable_hyperlink_auditing(True)
# self.set_enable_xss_auditor(False)
# self.set_enable_hyperlink_auditing(False)
self.set_allow_file_access_from_file_urls(True)
self.set_allow_universal_access_from_file_urls(True)
self.set_enable_page_cache(False)
self.set_enable_offline_web_application_cache(False)
self.set_enable_html5_local_storage(False)
self.set_enable_html5_database(False)
self.set_enable_fullscreen(False)
self.set_print_backgrounds(False)
self.set_enable_tabs_to_links(False)
self.set_enable_developer_extras(True)
self.set_enable_webrtc(True)
self.set_enable_webaudio(True)
self.set_enable_accelerated_2d_canvas(True)
self.set_user_agent(f"{app_name}")

@@ -0,0 +1,63 @@
# Python imports
import os
import json
import inspect
# Lib imports
# Application imports
class StartCheckMixin:
def is_dirty_start(self) -> bool:
return self._dirty_start
def clear_pid(self):
if not self.is_trace_debug():
self._clean_pid()
def do_dirty_start_check(self):
if self.is_trace_debug():
pid = os.getpid()
self._print_pid(pid)
return
if os.path.exists(self._PID_FILE):
with open(self._PID_FILE, "r") as f:
pid = f.readline().strip()
if pid not in ("", None):
if self.is_pid_alive( int(pid) ):
print("PID file exists and PID is alive... Letting downstream errors (sans debug args) handle app closure propigation.")
return
self._write_new_pid()
""" Check For the existence of a unix pid. """
def is_pid_alive(self, pid):
print(f"PID Found: {pid}")
try:
os.kill(pid, 0)
except OSError:
print(f"{app_name} PID file exists but PID is irrelevant; starting dirty...")
self._dirty_start = True
return False
return True
def _write_new_pid(self):
pid = os.getpid()
self._write_pid(pid)
self._print_pid(pid)
def _print_pid(self, pid):
print(f"{app_name} PID: {pid}")
def _clean_pid(self):
os.unlink(self._PID_FILE)
def _write_pid(self, pid):
with open(self._PID_FILE, "w") as _pid:
_pid.write(f"{pid}")

@@ -1,25 +0,0 @@
# Python imports
from typing import Optional
# Lib imports
from sqlmodel import Field, Session, SQLModel, create_engine
# Application imports
class User(SQLModel, table = True):
id: Optional[int] = Field(default = None, primary_key = True)
name: str
password: str
email: Optional[str] = None
# NOTE: for sake of example we create an admin user with no password set.
user = User(name = "Admin", password = "", email = "admin@domain.com")
engine = create_engine("sqlite:///database.db")
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
session.add(user)
session.commit()

@@ -1,51 +0,0 @@
# Python imports
import os
import json
import inspect
# Lib imports
# Application imports
class StartCheckMixin:
def is_dirty_start(self) -> bool: return self._dirty_start
def clear_pid(self): self._clean_pid()
def do_dirty_start_check(self):
if not os.path.exists(self._PID_FILE):
self._write_new_pid()
else:
with open(self._PID_FILE, "r") as _pid:
pid = _pid.readline().strip()
if pid not in ("", None):
self._check_alive_status(int(pid))
else:
self._write_new_pid()
""" Check For the existence of a unix pid. """
def _check_alive_status(self, pid):
print(f"PID Found: {pid}")
try:
os.kill(pid, 0)
except OSError:
print(f"{app_name} is starting dirty...")
self._dirty_start = True
self._write_new_pid()
return
print("PID is alive... Let downstream errors (sans debug args) handle app closure propigation.")
def _write_new_pid(self):
pid = os.getpid()
self._write_pid(pid)
print(f"{app_name} PID: {pid}")
def _clean_pid(self):
os.unlink(self._PID_FILE)
def _write_pid(self, pid):
with open(self._PID_FILE, "w") as _pid:
_pid.write(f"{pid}")

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Gtk + HTML + Python App</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="resources/css/libs/bootstrap5/bootstrap.min.css">
<link rel="stylesheet" href="resources/css/libs/bootstrap-icons/bootstrap-icons.css">
<!-- Site CSS -->
<!-- <link rel="stylesheet" href="resources/css/context-menu.css"> -->
<link rel="stylesheet" href="resources/css/main.css">
<link rel="stylesheet" href="resources/css/overrides.css">
</head>
<body>
<div class="container">
<div class="row">
<div id="page-alert-zone" class="col">
</div>
</div>
<div class="row">
<div class="col text-center scroller">
<button id="helloBttn" class=" btn btn-success">Button in WebView</button>
</div>
</div>
</div>
<!-- For internal scripts... -->
<!-- <script src="js/libs/jquery-3.7.1.min.js"></script> -->
<!-- For Bootstrap... -->
<script src="resources/js/libs/bootstrap5/bootstrap.bundle.min.js"></script>
<!-- For Application... -->
<script src="resources/js/globals.js"></script>
<!-- <script src="resources/js/post-ajax.js"></script> -->
<!-- <script src="resources/js/ajax.js"></script> -->
<script src="resources/js/utils.js"></script>
<script src="resources/js/ui-logic.js"></script>
<script src="resources/js/events.js"></script>
</body>
</html>

@@ -0,0 +1,50 @@
.menu {
width: 165px;
z-index: 999;
box-shadow: 0 4px 5px 3px rgba(0, 0, 0, 0.2);
background-color: rgba(0, 0, 0, 0.64);
position: fixed;
display: none;
transition: 0.2s display ease-in;
}
.menu .menu-options {
list-style: none;
padding: 10px 0;
z-index: 1;
}
.menu .menu-options .menu-option {
font-weight: 500;
z-index: 1;
padding: 10px 40px 10px 20px;
cursor: pointer;
}
.menu .menu-options .menu-option:hover {
background: rgba(255, 255, 255, 0.64);
color: rgba(0, 0, 0, 0.5);
}
button {
background: grey;
border: none;
}
button .next {
color: green;
}
button[disabled="false"]:hover .next {
color: red;
animation: move 0.5s;
animation-iteration-count: 2;
}
@keyframes move {
from {
transform: translate(0%);
}
50% {
transform: translate(-40%);
}
to {
transform: transform(0%);
}
}

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-123" viewBox="0 0 16 16">
<path d="M2.873 11.297V4.142H1.699L0 5.379v1.137l1.64-1.18h.06v5.961h1.174Zm3.213-5.09v-.063c0-.618.44-1.169 1.196-1.169.676 0 1.174.44 1.174 1.106 0 .624-.42 1.101-.807 1.526L4.99 10.553v.744h4.78v-.99H6.643v-.069L8.41 8.252c.65-.724 1.237-1.332 1.237-2.27C9.646 4.849 8.723 4 7.308 4c-1.573 0-2.36 1.064-2.36 2.15v.057h1.138Zm6.559 1.883h.786c.823 0 1.374.481 1.379 1.179.01.707-.55 1.216-1.421 1.21-.77-.005-1.326-.419-1.379-.953h-1.095c.042 1.053.938 1.918 2.464 1.918 1.478 0 2.642-.839 2.62-2.144-.02-1.143-.922-1.651-1.551-1.714v-.063c.535-.09 1.347-.66 1.326-1.678-.026-1.053-.933-1.855-2.359-1.845-1.5.005-2.317.88-2.348 1.898h1.116c.032-.498.498-.944 1.206-.944.703 0 1.206.435 1.206 1.07.005.64-.504 1.106-1.2 1.106h-.75v.96Z"/>
</svg>

After

(image error) Size: 870 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-activity" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6 2a.5.5 0 0 1 .47.33L10 12.036l1.53-4.208A.5.5 0 0 1 12 7.5h3.5a.5.5 0 0 1 0 1h-3.15l-1.88 5.17a.5.5 0 0 1-.94 0L6 3.964 4.47 8.171A.5.5 0 0 1 4 8.5H.5a.5.5 0 0 1 0-1h3.15l1.88-5.17A.5.5 0 0 1 6 2Z"/>
</svg>

After

(image error) Size: 367 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-alarm-fill" viewBox="0 0 16 16">
<path d="M6 .5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1H9v1.07a7.001 7.001 0 0 1 3.274 12.474l.601.602a.5.5 0 0 1-.707.708l-.746-.746A6.97 6.97 0 0 1 8 16a6.97 6.97 0 0 1-3.422-.892l-.746.746a.5.5 0 0 1-.707-.708l.602-.602A7.001 7.001 0 0 1 7 2.07V1h-.5A.5.5 0 0 1 6 .5zm2.5 5a.5.5 0 0 0-1 0v3.362l-1.429 2.38a.5.5 0 1 0 .858.515l1.5-2.5A.5.5 0 0 0 8.5 9V5.5zM.86 5.387A2.5 2.5 0 1 1 4.387 1.86 8.035 8.035 0 0 0 .86 5.387zM11.613 1.86a2.5 2.5 0 1 1 3.527 3.527 8.035 8.035 0 0 0-3.527-3.527z"/>
</svg>

After

(image error) Size: 626 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-alarm" viewBox="0 0 16 16">
<path d="M8.5 5.5a.5.5 0 0 0-1 0v3.362l-1.429 2.38a.5.5 0 1 0 .858.515l1.5-2.5A.5.5 0 0 0 8.5 9V5.5z"/>
<path d="M6.5 0a.5.5 0 0 0 0 1H7v1.07a7.001 7.001 0 0 0-3.273 12.474l-.602.602a.5.5 0 0 0 .707.708l.746-.746A6.97 6.97 0 0 0 8 16a6.97 6.97 0 0 0 3.422-.892l.746.746a.5.5 0 0 0 .707-.708l-.601-.602A7.001 7.001 0 0 0 9 2.07V1h.5a.5.5 0 0 0 0-1h-3zm1.038 3.018a6.093 6.093 0 0 1 .924 0 6 6 0 1 1-.924 0zM0 3.5c0 .753.333 1.429.86 1.887A8.035 8.035 0 0 1 4.387 1.86 2.5 2.5 0 0 0 0 3.5zM13.5 1c-.753 0-1.429.333-1.887.86a8.035 8.035 0 0 1 3.527 3.527A2.5 2.5 0 0 0 13.5 1z"/>
</svg>

After

(image error) Size: 711 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-bottom" viewBox="0 0 16 16">
<rect width="4" height="12" x="6" y="1" rx="1"/>
<path d="M1.5 14a.5.5 0 0 0 0 1v-1zm13 1a.5.5 0 0 0 0-1v1zm-13 0h13v-1h-13v1z"/>
</svg>

After

(image error) Size: 271 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-center" viewBox="0 0 16 16">
<path d="M8 1a.5.5 0 0 1 .5.5V6h-1V1.5A.5.5 0 0 1 8 1zm0 14a.5.5 0 0 1-.5-.5V10h1v4.5a.5.5 0 0 1-.5.5zM2 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7z"/>
</svg>

After

(image error) Size: 315 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-end" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M14.5 1a.5.5 0 0 0-.5.5v13a.5.5 0 0 0 1 0v-13a.5.5 0 0 0-.5-.5z"/>
<path d="M13 7a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V7z"/>
</svg>

After

(image error) Size: 318 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-middle" viewBox="0 0 16 16">
<path d="M6 13a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1v10zM1 8a.5.5 0 0 0 .5.5H6v-1H1.5A.5.5 0 0 0 1 8zm14 0a.5.5 0 0 1-.5.5H10v-1h4.5a.5.5 0 0 1 .5.5z"/>
</svg>

After

(image error) Size: 316 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-start" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.5 1a.5.5 0 0 1 .5.5v13a.5.5 0 0 1-1 0v-13a.5.5 0 0 1 .5-.5z"/>
<path d="M3 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7z"/>
</svg>

After

(image error) Size: 318 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-top" viewBox="0 0 16 16">
<rect width="4" height="12" rx="1" transform="matrix(1 0 0 -1 6 15)"/>
<path d="M1.5 2a.5.5 0 0 1 0-1v1zm13-1a.5.5 0 0 1 0 1V1zm-13 0h13v1h-13V1z"/>
</svg>

After

(image error) Size: 287 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-alt" viewBox="0 0 16 16">
<path d="M1 13.5a.5.5 0 0 0 .5.5h3.797a.5.5 0 0 0 .439-.26L11 3h3.5a.5.5 0 0 0 0-1h-3.797a.5.5 0 0 0-.439.26L5 13H1.5a.5.5 0 0 0-.5.5zm10 0a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 0-1h-3a.5.5 0 0 0-.5.5z"/>
</svg>

After

(image error) Size: 326 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-app-indicator" viewBox="0 0 16 16">
<path d="M5.5 2A3.5 3.5 0 0 0 2 5.5v5A3.5 3.5 0 0 0 5.5 14h5a3.5 3.5 0 0 0 3.5-3.5V8a.5.5 0 0 1 1 0v2.5a4.5 4.5 0 0 1-4.5 4.5h-5A4.5 4.5 0 0 1 1 10.5v-5A4.5 4.5 0 0 1 5.5 1H8a.5.5 0 0 1 0 1H5.5z"/>
<path d="M16 3a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
</svg>

After

(image error) Size: 387 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-app" viewBox="0 0 16 16">
<path d="M11 2a3 3 0 0 1 3 3v6a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3V5a3 3 0 0 1 3-3h6zM5 1a4 4 0 0 0-4 4v6a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4V5a4 4 0 0 0-4-4H5z"/>
</svg>

After

(image error) Size: 282 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-apple" viewBox="0 0 16 16">
<path d="M11.182.008C11.148-.03 9.923.023 8.857 1.18c-1.066 1.156-.902 2.482-.878 2.516.024.034 1.52.087 2.475-1.258.955-1.345.762-2.391.728-2.43zm3.314 11.733c-.048-.096-2.325-1.234-2.113-3.422.212-2.189 1.675-2.789 1.698-2.854.023-.065-.597-.79-1.254-1.157a3.692 3.692 0 0 0-1.563-.434c-.108-.003-.483-.095-1.254.116-.508.139-1.653.589-1.968.607-.316.018-1.256-.522-2.267-.665-.647-.125-1.333.131-1.824.328-.49.196-1.422.754-2.074 2.237-.652 1.482-.311 3.83-.067 4.56.244.729.625 1.924 1.273 2.796.576.984 1.34 1.667 1.659 1.899.319.232 1.219.386 1.843.067.502-.308 1.408-.485 1.766-.472.357.013 1.061.154 1.782.539.571.197 1.111.115 1.652-.105.541-.221 1.324-1.059 2.238-2.758.347-.79.505-1.217.473-1.282z"/>
<path d="M11.182.008C11.148-.03 9.923.023 8.857 1.18c-1.066 1.156-.902 2.482-.878 2.516.024.034 1.52.087 2.475-1.258.955-1.345.762-2.391.728-2.43zm3.314 11.733c-.048-.096-2.325-1.234-2.113-3.422.212-2.189 1.675-2.789 1.698-2.854.023-.065-.597-.79-1.254-1.157a3.692 3.692 0 0 0-1.563-.434c-.108-.003-.483-.095-1.254.116-.508.139-1.653.589-1.968.607-.316.018-1.256-.522-2.267-.665-.647-.125-1.333.131-1.824.328-.49.196-1.422.754-2.074 2.237-.652 1.482-.311 3.83-.067 4.56.244.729.625 1.924 1.273 2.796.576.984 1.34 1.667 1.659 1.899.319.232 1.219.386 1.843.067.502-.308 1.408-.485 1.766-.472.357.013 1.061.154 1.782.539.571.197 1.111.115 1.652-.105.541-.221 1.324-1.059 2.238-2.758.347-.79.505-1.217.473-1.282z"/>
</svg>

After

(image error) Size: 1.5 KiB

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-archive-fill" viewBox="0 0 16 16">
<path d="M12.643 15C13.979 15 15 13.845 15 12.5V5H1v7.5C1 13.845 2.021 15 3.357 15h9.286zM5.5 7h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1 0-1zM.8 1a.8.8 0 0 0-.8.8V3a.8.8 0 0 0 .8.8h14.4A.8.8 0 0 0 16 3V1.8a.8.8 0 0 0-.8-.8H.8z"/>
</svg>

After

(image error) Size: 359 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-archive" viewBox="0 0 16 16">
<path d="M0 2a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1v7.5a2.5 2.5 0 0 1-2.5 2.5h-9A2.5 2.5 0 0 1 1 12.5V5a1 1 0 0 1-1-1V2zm2 3v7.5A1.5 1.5 0 0 0 3.5 14h9a1.5 1.5 0 0 0 1.5-1.5V5H2zm13-3H1v2h14V2zM5 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5z"/>
</svg>

After

(image error) Size: 401 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-90deg-down" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4.854 14.854a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L4 13.293V3.5A2.5 2.5 0 0 1 6.5 1h8a.5.5 0 0 1 0 1h-8A1.5 1.5 0 0 0 5 3.5v9.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4z"/>
</svg>

After

(image error) Size: 350 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-90deg-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.146 4.854a.5.5 0 0 1 0-.708l4-4a.5.5 0 1 1 .708.708L2.707 4H12.5A2.5 2.5 0 0 1 15 6.5v8a.5.5 0 0 1-1 0v-8A1.5 1.5 0 0 0 12.5 5H2.707l3.147 3.146a.5.5 0 1 1-.708.708l-4-4z"/>
</svg>

After

(image error) Size: 349 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-90deg-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M14.854 4.854a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708.708L13.293 4H3.5A2.5 2.5 0 0 0 1 6.5v8a.5.5 0 0 0 1 0v-8A1.5 1.5 0 0 1 3.5 5h9.793l-3.147 3.146a.5.5 0 0 0 .708.708l4-4z"/>
</svg>

After

(image error) Size: 350 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-90deg-up" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4.854 1.146a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L4 2.707V12.5A2.5 2.5 0 0 0 6.5 15h8a.5.5 0 0 0 0-1h-8A1.5 1.5 0 0 1 5 12.5V2.707l3.146 3.147a.5.5 0 1 0 .708-.708l-4-4z"/>
</svg>

After

(image error) Size: 349 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-bar-down" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 3.5a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13a.5.5 0 0 1-.5-.5zM8 6a.5.5 0 0 1 .5.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 0 1 .708-.708L7.5 12.293V6.5A.5.5 0 0 1 8 6z"/>
</svg>

After

(image error) Size: 375 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-bar-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M12.5 15a.5.5 0 0 1-.5-.5v-13a.5.5 0 0 1 1 0v13a.5.5 0 0 1-.5.5zM10 8a.5.5 0 0 1-.5.5H3.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L3.707 7.5H9.5a.5.5 0 0 1 .5.5z"/>
</svg>

After

(image error) Size: 375 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-bar-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6 8a.5.5 0 0 0 .5.5h5.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L12.293 7.5H6.5A.5.5 0 0 0 6 8zm-2.5 7a.5.5 0 0 1-.5-.5v-13a.5.5 0 0 1 1 0v13a.5.5 0 0 1-.5.5z"/>
</svg>

After

(image error) Size: 375 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-bar-up" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 10a.5.5 0 0 0 .5-.5V3.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 3.707V9.5a.5.5 0 0 0 .5.5zm-7 2.5a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13a.5.5 0 0 1-.5-.5z"/>
</svg>

After

(image error) Size: 376 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"/>
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"/>
</svg>

After

(image error) Size: 352 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z"/>
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z"/>
</svg>

After

(image error) Size: 359 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
</svg>

After

(image error) Size: 321 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-circle" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
</svg>

After

(image error) Size: 370 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-left-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 0 0 8a8 8 0 0 0 16 0zm-5.904-2.803a.5.5 0 1 1 .707.707L6.707 10h2.768a.5.5 0 0 1 0 1H5.5a.5.5 0 0 1-.5-.5V6.525a.5.5 0 0 1 1 0v2.768l4.096-4.096z"/>
</svg>

After

(image error) Size: 326 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-left-circle" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-5.904-2.854a.5.5 0 1 1 .707.708L6.707 9.95h2.768a.5.5 0 1 1 0 1H5.5a.5.5 0 0 1-.5-.5V6.475a.5.5 0 1 1 1 0v2.768l4.096-4.097z"/>
</svg>

After

(image error) Size: 377 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-left-square-fill" viewBox="0 0 16 16">
<path d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm8.096-10.803L6 9.293V6.525a.5.5 0 0 0-1 0V10.5a.5.5 0 0 0 .5.5h3.975a.5.5 0 0 0 0-1H6.707l4.096-4.096a.5.5 0 1 0-.707-.707z"/>
</svg>

After

(image error) Size: 363 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-left-square" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M15 2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2zM0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm10.096 3.146a.5.5 0 1 1 .707.708L6.707 9.95h2.768a.5.5 0 1 1 0 1H5.5a.5.5 0 0 1-.5-.5V6.475a.5.5 0 1 1 1 0v2.768l4.096-4.097z"/>
</svg>

After

(image error) Size: 451 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M2 13.5a.5.5 0 0 0 .5.5h6a.5.5 0 0 0 0-1H3.707L13.854 2.854a.5.5 0 0 0-.708-.708L3 12.293V7.5a.5.5 0 0 0-1 0v6z"/>
</svg>

After

(image error) Size: 286 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-right-circle-fill" viewBox="0 0 16 16">
<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm5.904-2.803a.5.5 0 1 0-.707.707L9.293 10H6.525a.5.5 0 0 0 0 1H10.5a.5.5 0 0 0 .5-.5V6.525a.5.5 0 0 0-1 0v2.768L5.904 5.197z"/>
</svg>

After

(image error) Size: 326 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-right-circle" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.854 5.146a.5.5 0 1 0-.708.708L9.243 9.95H6.475a.5.5 0 1 0 0 1h3.975a.5.5 0 0 0 .5-.5V6.475a.5.5 0 1 0-1 0v2.768L5.854 5.146z"/>
</svg>

After

(image error) Size: 379 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-right-square-fill" viewBox="0 0 16 16">
<path d="M14 16a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12zM5.904 5.197 10 9.293V6.525a.5.5 0 0 1 1 0V10.5a.5.5 0 0 1-.5.5H6.525a.5.5 0 0 1 0-1h2.768L5.197 5.904a.5.5 0 0 1 .707-.707z"/>
</svg>

After

(image error) Size: 365 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-right-square" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M15 2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2zM0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm5.854 3.146a.5.5 0 1 0-.708.708L9.243 9.95H6.475a.5.5 0 1 0 0 1h3.975a.5.5 0 0 0 .5-.5V6.475a.5.5 0 1 0-1 0v2.768L5.854 5.146z"/>
</svg>

After

(image error) Size: 453 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M14 13.5a.5.5 0 0 1-.5.5h-6a.5.5 0 0 1 0-1h4.793L2.146 2.854a.5.5 0 1 1 .708-.708L13 12.293V7.5a.5.5 0 0 1 1 0v6z"/>
</svg>

After

(image error) Size: 289 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-short" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 4a.5.5 0 0 1 .5.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5A.5.5 0 0 1 8 4z"/>
</svg>

After

(image error) Size: 314 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"/>
</svg>

After

(image error) Size: 359 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-square" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M15 2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2zM0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm8.5 2.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
</svg>

After

(image error) Size: 444 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-up" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M11.5 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L11 2.707V14.5a.5.5 0 0 0 .5.5zm-7-14a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L4 13.293V1.5a.5.5 0 0 1 .5-.5z"/>
</svg>

After

(image error) Size: 457 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z"/>
</svg>

After

(image error) Size: 309 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left-circle-fill" viewBox="0 0 16 16">
<path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm3.5 7.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H11.5z"/>
</svg>

After

(image error) Size: 320 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left-circle" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-4.5-.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H11.5z"/>
</svg>

After

(image error) Size: 370 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 11.5a.5.5 0 0 0 .5.5h11.793l-3.147 3.146a.5.5 0 0 0 .708.708l4-4a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708.708L13.293 11H1.5a.5.5 0 0 0-.5.5zm14-7a.5.5 0 0 1-.5.5H2.707l3.147 3.146a.5.5 0 1 1-.708.708l-4-4a.5.5 0 0 1 0-.708l4-4a.5.5 0 1 1 .708.708L2.707 4H14.5a.5.5 0 0 1 .5.5z"/>
</svg>

After

(image error) Size: 453 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left-short" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M12 8a.5.5 0 0 1-.5.5H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H11.5a.5.5 0 0 1 .5.5z"/>
</svg>

After

(image error) Size: 314 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left-square-fill" viewBox="0 0 16 16">
<path d="M16 14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12zm-4.5-6.5H5.707l2.147-2.146a.5.5 0 1 0-.708-.708l-3 3a.5.5 0 0 0 0 .708l3 3a.5.5 0 0 0 .708-.708L5.707 8.5H11.5a.5.5 0 0 0 0-1z"/>
</svg>

After

(image error) Size: 362 B

Some files were not shown because too many files have changed in this diff Show More