[{"data":1,"prerenderedAt":248},["ShallowReactive",2],{"i-lucide:chevron-down":3,"i-lucide:arrow-up-right":8,"i-simple-icons:github":10,"i-simple-icons:x":12,"i-brand:linkedin":14,"i-simple-icons:medium":18,"i-lucide:mail":20,"i-lucide:sun":22,"project:\u002Fprojects\u002Feasyshoot":24,"project-more:\u002Fprojects\u002Feasyshoot":209,"i-lucide:briefcase-business":230,"i-lucide:calendar":232,"i-lucide:globe":234,"i-lucide:languages":236,"i-lucide:frame":238,"i-lucide:copy":240,"i-lucide:square-dashed":242,"i-lucide:pencil":244,"i-lucide:hard-drive":246},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 7h10v10M7 17L17 7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cpath fill=\"currentColor\" d=\"M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z\"\u002F>",{"left":4,"top":15,"width":16,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":17},32,448,"\u003Cpath fill=\"currentColor\" d=\"M416 32L31.9 32C14.3 32 0 46.5 0 64.3L0 447.7C0 465.5 14.3 480 31.9 480L416 480c17.6 0 32-14.5 32-32.3l0-383.4C448 46.5 433.6 32 416 32zM135.4 416l-66.4 0 0-213.8 66.5 0 0 213.8-.1 0zM102.2 96a38.5 38.5 0 1 1 0 77 38.5 38.5 0 1 1 0-77zM384.3 416l-66.4 0 0-104c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9l0 105.8-66.4 0 0-213.8 63.7 0 0 29.2 .9 0c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9l0 117.2z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cpath fill=\"currentColor\" d=\"M4.21 0A4.2 4.2 0 0 0 0 4.21v15.58A4.2 4.2 0 0 0 4.21 24h15.58A4.2 4.2 0 0 0 24 19.79v-1.093a5 5 0 0 1-.422.02c-2.577 0-4.027-2.146-4.09-4.832a8 8 0 0 1 .022-.708c.093-1.186.475-2.241 1.105-3.022a3.9 3.9 0 0 1 1.395-1.1c.468-.237 1.127-.367 1.664-.367h.023q.151 0 .303.01V4.211A4.2 4.2 0 0 0 19.79 0Zm.198 5.583h4.165l3.588 8.435l3.59-8.435h3.864v.146l-.019.004c-.705.16-1.063.397-1.063 1.254h-.003l.003 10.274c.06.676.424.885 1.063 1.03l.02.004v.145h-4.923v-.145l.019-.005c.639-.144.994-.353 1.054-1.03V7.267l-4.745 11.15h-.261L6.15 7.569v9.445c0 .857.358 1.094 1.063 1.253l.02.004v.147H4.405v-.147l.019-.004c.705-.16 1.065-.397 1.065-1.253V6.987c0-.857-.358-1.094-1.064-1.254l-.018-.004zm19.25 3.668c-1.086.023-1.733 1.323-1.813 3.124H24V9.298a1.4 1.4 0 0 0-.342-.047m-1.862 3.632c-.1 1.756.86 3.239 2.204 3.634v-3.634z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":21},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m22 7l-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":23},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"page":25,"project":193},{"id":26,"title":27,"body":28,"description":184,"extension":185,"meta":186,"navigation":187,"path":188,"seo":189,"sitemap":190,"stem":191,"__hash__":192},"projectPages\u002Fprojects\u002Feasyshoot.md","Easyshoot",{"type":29,"value":30,"toc":170},"minimark",[31,36,40,44,47,76,80,88,94,100,106,112,116,133,137,141,145,152,155,160,163,167],[32,33,35],"h2",{"id":34},"overview","Overview",[37,38,39],"p",{},"EasyShoot is a free, open-source screenshot app for macOS. It lives in the menu bar: one shortcut captures an area, a window, the full screen or a long scrolling page, and the editor marks it up and frames it before it's copied or saved. I started it in October 2026 and maintain it on GitHub, where anyone can contribute.",[32,41,43],{"id":42},"the-problem","The problem",[37,45,46],{},"Sharing a clear screenshot took more steps than it should.",[48,49,50,58,64,70],"ul",{},[51,52,53,57],"li",{},[54,55,56],"strong",{},"Too many apps."," Capturing, cropping, annotating and framing each happened in a different tool.",[51,59,60,63],{},[54,61,62],{},"Long pages."," Chats, documents and web pages that scroll needed several screenshots joined by hand.",[51,65,66,69],{},[54,67,68],{},"Arabic text."," Annotation tools often drew Arabic left-to-right or with broken letter shapes.",[51,71,72,75],{},[54,73,74],{},"Privacy."," Some screenshot tools upload images to a cloud by default.",[32,77,79],{"id":78},"the-solution","The solution",[81,82,85],"sketch-figure",{"alt":83,"name":84},"Before: a screenshot goes through four steps in separate apps: capture, crop in another app, annotate in a third, frame in a design tool. Long pages need several shots, Arabic text breaks, and some tools upload the image. With EasyShoot: one shortcut, then mark up and frame in one window, then copy, save or drag. Scrolling capture stitches long pages into one image, and everything stays on the Mac.","easyshoot\u002Fbefore-after",[37,86,87],{},"Capture, mark-up and framing happen in one window, and nothing leaves the Mac.",[37,89,90,93],{},[54,91,92],{},"One window."," Arrows, text, numbered steps, highlights, crop and a background tool sit in the same editor, and presets keep every screenshot in one style.",[37,95,96,99],{},[54,97,98],{},"Scrolling capture."," EasyShoot records a region while it scrolls and stitches the frames into one tall image, in any app.",[37,101,102,105],{},[54,103,104],{},"Arabic first."," Text detects Arabic and writes right-to-left with correct shaping, in any installed font or one downloaded from Google Fonts.",[37,107,108,111],{},[54,109,110],{},"Local only."," There is no account and no cloud. Images are saved, copied or dragged straight from the Mac.",[32,113,115],{"id":114},"what-i-did","What I did",[48,117,118,121,124,127,130],{},[51,119,120],{},"Defined the product, its features and its privacy rule: nothing is uploaded.",[51,122,123],{},"Designed the brand, the app icon and the interface, including the Liquid Glass look on macOS 26.",[51,125,126],{},"Built the app with a coding agent: I set the scope and the design, and reviewed every change before it shipped.",[51,128,129],{},"Set up the build, tests and release pipeline, and the website in five languages.",[51,131,132],{},"Opened the project to contributors with a guide, issue forms and a code of conduct.",[32,134,136],{"id":135},"what-it-offers","What it offers",[138,139],"feature-grid",{":items":140},"[{\"icon\":\"lucide:square-dashed\",\"title\":\"Every kind of capture\",\"text\":\"Area, window, fullscreen and scrolling capture, each on a shortcut you can change.\"},{\"icon\":\"lucide:pencil\",\"title\":\"Marks that stay editable\",\"text\":\"Arrows, shapes, text, counters, highlighter, pen and pixelate can be moved and restyled at any time.\"},{\"icon\":\"lucide:languages\",\"title\":\"Arabic and five languages\",\"text\":\"Right-to-left text in the editor, and an interface in English, Arabic, French, Spanish and German.\"},{\"icon\":\"lucide:frame\",\"title\":\"Backgrounds and presets\",\"text\":\"Gradients, padding, corners, shadow and aspect ratios, saved as presets that apply to new captures.\"},{\"icon\":\"lucide:copy\",\"title\":\"Quick Access\",\"text\":\"A thumbnail after each capture to copy, save, annotate or drag the image into another app.\"},{\"icon\":\"lucide:hard-drive\",\"title\":\"Stays on the Mac\",\"text\":\"No account, no cloud and no analytics; the app only goes online to download a font you pick.\"}]",[32,142,144],{"id":143},"system-design","System design",[81,146,149],{"alt":147,"name":148},"Capture sources on the left: area, window and fullscreen capture, and scrolling frames that a stitcher joins row by row. They feed a document that holds the image, the marks and the frame. One renderer draws the document to both the editor and the exported file. Presets, any font and right-to-left text shape the document.","easyshoot\u002Farchitecture",[37,150,151],{},"The editor and the exported image are drawn by the same renderer.",[37,153,154],{},"Captures become a document: the image, every mark and the frame around it. A single renderer draws that document on screen and into the exported file, so what you see is exactly what you save.",[156,157,159],"h3",{"id":158},"scrolling-capture","Scrolling capture",[37,161,162],{},"The capture records a fixed region while the page scrolls. Each new frame is matched to the previous one row by row, so only the new rows are added, and headers that stay in place appear once. The stitcher is plain code with unit tests, which makes it easy for contributors to improve.",[156,164,166],{"id":165},"open-to-contributors","Open to contributors",[37,168,169],{},"The app uses only Apple's own frameworks, and every change runs through a pipeline that builds the app, runs the tests, checks every translation and launches the app. A guide in the repository explains how to set it up and how to add a language.",{"title":171,"searchDepth":172,"depth":172,"links":173},"",2,[174,175,176,177,178,179],{"id":34,"depth":172,"text":35},{"id":42,"depth":172,"text":43},{"id":78,"depth":172,"text":79},{"id":114,"depth":172,"text":115},{"id":135,"depth":172,"text":136},{"id":143,"depth":172,"text":144,"children":180},[181,183],{"id":158,"depth":182,"text":159},3,{"id":165,"depth":182,"text":166},"EasyShoot is my open-source screenshot app for macOS: capture, mark up and frame screenshots in one window, with scrolling capture, Arabic right-to-left text and nothing uploaded.","md",{},true,"\u002Fprojects\u002Feasyshoot",{"description":184},{"loc":188},"projects\u002Feasyshoot","DZ1lARsORbmjTiIX9asvmkv4aryI20jzSNgi1uQqP9s",{"id":194,"title":195,"context":196,"description":197,"extension":198,"highlight":199,"links":200,"mark":204,"meta":206,"order":172,"stem":191,"year":207,"__hash__":208},"projects\u002Fprojects\u002Feasyshoot.yml","EasyShoot · Screenshot app for macOS","Creator · Oct 2026 – now","My open-source Mac app for capturing, marking up and framing screenshots, with scrolling capture and Arabic right-to-left text.","yml",null,[201],{"label":202,"to":203},"github.com\u002FHaythamasalama\u002Feasyshoot","https:\u002F\u002Fgithub.com\u002FHaythamasalama\u002Feasyshoot",{"logo":205},"easyshoot",{},2026,"Kv7PgKRG-Zy9uhTuU4UTgXhWy09XwTbHGtuZU7wJ7hA",[210,216,223],{"path":211,"title":212,"description":213,"mark":214,"year":207},"\u002Fprojects\u002Frunarks","Runarks · Governed access to production databases","My own product: every query against a production database is reviewed, approved, run once and logged, and nobody sees a password.",{"logo":215},"runarks",{"path":217,"title":218,"description":219,"mark":220,"year":222},"\u002Fprojects\u002Fsanad","Sanad · Real-estate investment platform","The API and admin dashboard I built for a Saudi real-estate investment platform: verified investors, a wallet, investments and returns paid on a schedule.",{"logo":221},"sanad",2024,{"path":224,"title":225,"description":226,"mark":227,"year":229},"\u002Fprojects\u002Fwinch","WINCH · Saudi logistics platform","The back end of a Saudi logistics platform for businesses and carriers: more than 50 domains, and the integration engine I built for government services, payments and AI.",{"logo":228},"winch",2023,{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":231},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12 12h.01M16 6V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2m14 7a18.15 18.15 0 0 1-20 0\"\u002F>\u003Crect width=\"20\" height=\"14\" x=\"2\" y=\"6\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":233},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M8 2v3m8-3v3\"\u002F>\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M3 9h18\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":235},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"M12 2a14.5 14.5 0 0 0 0 20a14.5 14.5 0 0 0 0-20M2 12h20\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":237},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m5 8l6 6m-7 0l6-6l2-3M2 5h12M7 2h1m14 20l-5-10l-5 10m2-4h6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":239},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M22 6H2m20 12H2M6 2v20M18 2v20\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":241},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":243},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 3a2 2 0 0 0-2 2m16-2a2 2 0 0 1 2 2m0 14a2 2 0 0 1-2 2M5 21a2 2 0 0 1-2-2M9 3h1M9 21h1m4-18h1m-1 18h1M3 9v1m18-1v1M3 14v1m18-1v1\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":245},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497zM15 5l4 4\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":247},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 16h.01m-7.798-4.423a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11zm19.734.436H2.054M6 16h.01\"\u002F>",1792514545569]