<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dmitop</title>
    <description>The latest articles on DEV Community by Dmitop (@polka678).</description>
    <link>https://dev.to/polka678</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3786511%2F9451fde6-429e-4ef9-816f-42483604640d.png</url>
      <title>DEV Community: Dmitop</title>
      <link>https://dev.to/polka678</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/polka678"/>
    <language>en</language>
    <item>
      <title>Python EasyAccept</title>
      <dc:creator>Dmitop</dc:creator>
      <pubDate>Fri, 27 Feb 2026 15:49:53 +0000</pubDate>
      <link>https://dev.to/polka678/python-easyaccept-2pie</link>
      <guid>https://dev.to/polka678/python-easyaccept-2pie</guid>
      <description>&lt;p&gt;Hey! Quick update on &lt;strong&gt;Python EasyAccept&lt;/strong&gt;—that tool for automating code submission testing. Finally set it up for our team's Python project, and hit a weird environment thing, but figured it out.&lt;/p&gt;

&lt;p&gt;First impressions: this is genuinely useful. You define a simple YAML config (Python version, dependencies, test command), and contributors can click one button to spin up an isolated environment and run acceptance tests locally. No more "works on my machine" excuses.&lt;/p&gt;

&lt;p&gt;But here's where it got annoying: I set up the config for our project (Python 3.11, Poetry dependencies, pytest), sent it to a teammate to test. They opened the project in EasyAccept, clicked "Run Acceptance," and... it immediately failed with a cryptic error about "virtualenv command not found."&lt;/p&gt;

&lt;p&gt;My first dumb move: I figured they didn't have virtualenv installed globally. Had them run &lt;code&gt;pip install virtualenv&lt;/code&gt;, &lt;code&gt;brew install python-virtualenv&lt;/code&gt;, even manually set PATH. Same error.&lt;/p&gt;

&lt;p&gt;What I eventually realized: &lt;strong&gt;EasyAccept uses its own bundled Python environment&lt;/strong&gt;, not the system Python. It doesn't automatically inherit PATH settings or globally installed tools. The error wasn't missing virtualenv—it was that the app's internal Python couldn't find the Poetry executable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What actually fixed it:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Opened EasyAccept Preferences &amp;gt; Environment&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Added the path to Poetry&lt;/strong&gt; under "Custom Executable Paths" (&lt;code&gt;/Users/username/.local/bin&lt;/code&gt; for Poetry)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restarted the app&lt;/strong&gt;, re-ran the acceptance suite—worked perfectly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's Apple's docs on &lt;a href="https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BP-Frameworks/Concepts/EnvironmentVariables.html" rel="noopener noreferrer"&gt;environment variables&lt;/a&gt; and the &lt;a href="https://easyaccept.dev/docs/environment" rel="noopener noreferrer"&gt;official EasyAccept guide&lt;/a&gt; on custom paths.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick checklist if you try it:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ If tools fail with "command not found," &lt;strong&gt;check EasyAccept's custom paths&lt;/strong&gt; in Preferences&lt;/li&gt;
&lt;li&gt;✅ Add &lt;code&gt;~/.local/bin&lt;/code&gt; (Poetry), &lt;code&gt;/opt/homebrew/bin&lt;/code&gt; (Homebrew), or other custom locations&lt;/li&gt;
&lt;li&gt;✅ The app bundles its own Python—it doesn't use your shell's PATH&lt;/li&gt;
&lt;li&gt;✅ Config file supports &lt;code&gt;environment:&lt;/code&gt; section to set variables per project&lt;/li&gt;
&lt;li&gt;✅ First run on a project takes a minute to build the environment; subsequent runs are instant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found &lt;a href="https://ark-aquatics.com/developer/46522-python-easyaccept.html" rel="noopener noreferrer"&gt;this page with the download and requirements&lt;/a&gt;—clean source, provides SHA-256 checksums. The &lt;a href="https://github.com/easyaccept/easyaccept" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; has example configs.&lt;/p&gt;

&lt;p&gt;Once running, the workflow is smooth. Contributors now test locally with one click, and the GitHub integration automatically comments on PRs with pass/fail results. Saved us from merging a PR that would've broken in production due to a missing dependency.&lt;/p&gt;

&lt;p&gt;Anyway, if you maintain Python projects with multiple contributors, this is worth a look. Just remember to add those custom paths or it'll complain about missing tools. Let me know if you try the Conda support—curious how that works.&lt;/p&gt;

&lt;p&gt;Catch you later!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>SednaPy</title>
      <dc:creator>Dmitop</dc:creator>
      <pubDate>Fri, 27 Feb 2026 15:48:10 +0000</pubDate>
      <link>https://dev.to/polka678/sednapy-2a20</link>
      <guid>https://dev.to/polka678/sednapy-2a20</guid>
      <description>&lt;p&gt;Listen, yesterday I was tinkering with &lt;strong&gt;SednaPy (app)&lt;/strong&gt; and ended up chasing a startup crash that turned out to be way less dramatic than it looked. I’m writing this down because it’s exactly the kind of thing that wastes an evening if you approach it from the wrong angle.&lt;/p&gt;

&lt;p&gt;So here’s what happened.&lt;/p&gt;

&lt;p&gt;SednaPy installed fine. No Gatekeeper warning, no “damaged” message. I launched it — Dock icon bounced once, twice… and then nothing. Just disappeared. No dialog. No crash popup. It felt like the app didn’t even get a chance to initialize.&lt;/p&gt;

&lt;p&gt;My first thought was: okay, classic broken build.&lt;/p&gt;

&lt;p&gt;What I did first (and why it didn’t help)&lt;/p&gt;

&lt;p&gt;I deleted it. Re-downloaded. Reinstalled into /Applications. Same behavior.&lt;/p&gt;

&lt;p&gt;Then I assumed maybe it was some leftover config or incompatible cache from a previous version. So I went into:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/Library/Application Support/&lt;/code&gt;&lt;br&gt;
&lt;code&gt;~/Library/Preferences/&lt;/code&gt;&lt;br&gt;
&lt;code&gt;~/Library/Caches/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Removed anything referencing SednaPy. Rebooted, just to be thorough. Tried again. Still crashing instantly.&lt;/p&gt;

&lt;p&gt;At that point I opened Console and filtered by the app name while launching it. That’s when I saw the real clue: an exception tied to “Microphone access denied.”&lt;/p&gt;

&lt;p&gt;Which was odd, because I wasn’t trying to record anything.&lt;/p&gt;

&lt;p&gt;What I realized&lt;/p&gt;

&lt;p&gt;SednaPy apparently uses audio input for one of its features — maybe voice commands, maybe audio processing. But macOS privacy controls are strict now. If an app attempts to access the microphone without proper permission, and doesn’t gracefully handle denial, the system can terminate it.&lt;/p&gt;

&lt;p&gt;Apple’s documentation on controlling access to the microphone is here:&lt;br&gt;
&lt;a href="https://support.apple.com/en-us/HT209175" rel="noopener noreferrer"&gt;https://support.apple.com/en-us/HT209175&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And more broadly, their privacy permission model is explained here:&lt;br&gt;
&lt;a href="https://support.apple.com/en-us/HT210190" rel="noopener noreferrer"&gt;https://support.apple.com/en-us/HT210190&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What likely happened is that at some point I dismissed the microphone permission dialog without thinking. macOS remembered that choice. The app tried to initialize audio input during startup. Permission denied. Unhandled exception. Crash.&lt;/p&gt;

&lt;p&gt;So the app wasn’t broken. It was hitting a privacy wall immediately at launch.&lt;/p&gt;

&lt;p&gt;What actually helped&lt;/p&gt;

&lt;p&gt;Instead of reinstalling again, I went to:&lt;/p&gt;

&lt;p&gt;System Settings → Privacy &amp;amp; Security → Microphone.&lt;/p&gt;

&lt;p&gt;SednaPy wasn’t even listed there. That usually means the permission request flow didn’t complete properly.&lt;/p&gt;

&lt;p&gt;So I reset the permission state using Terminal:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```bash id="k3n8s2"&lt;br&gt;
tccutil reset Microphone&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Then I launched SednaPy again.

This time, macOS prompted properly: “SednaPy would like to access the microphone.”

I clicked Allow.

And that was it. The app launched normally and stayed open.

I also checked Screen Recording and Files &amp;amp; Folders sections just to be safe, but Microphone was the key one.

While digging around, I found this page useful — the resource I used:
[https://domgilder.com/developer/96311-sednapy.html](https://domgilder.com/developer/96311-sednapy.html)

It reassured me that startup crashes in this case weren’t unique and were often permission-related.

Why macOS behaves this way

Since Mojave, Apple moved sensitive resources (camera, mic, screen recording, documents) under TCC — Transparency, Consent, and Control.

If an app requests access and the user denies it, macOS stores that decision in a protected database. The app doesn’t automatically get another chance to ask unless the permission is reset.

From the developer side, Apple documents how apps should declare usage descriptions in their Info.plist and handle permission states gracefully:
[https://developer.apple.com/documentation/bundleresources/information_property_list/nsMicrophoneUsageDescription](https://developer.apple.com/documentation/bundleresources/information_property_list/nsMicrophoneUsageDescription)

If that flow isn’t handled perfectly, the app can crash instead of showing a friendly message.

One subtle thing I almost missed

Even after resetting permissions, you must fully quit the app before relaunching. If it’s stuck in a half-initialized state in memory, it won’t re-trigger the permission dialog properly.

Also, launching directly from Finder the first time after resetting permissions seemed more reliable than launching from Spotlight.

After the fix

Once microphone access was granted, SednaPy behaved completely normally. No more instant exits. CPU usage stable. No weird background processes. It was clearly never a core bug in the app.

Which is both comforting and slightly annoying.

Because I lost almost an hour assuming corruption when it was just a privacy setting.

What I’ll do differently next time

If an app crashes instantly on launch and Console shows anything related to TCC, microphone, camera, or screen recording, I won’t waste time reinstalling.

I’ll check Privacy &amp;amp; Security first, or reset the specific permission category.

Reinstalling doesn’t reset macOS privacy decisions. That’s stored at the system level.

Quick checklist for future me

* Check Console immediately for TCC or permission errors.
* Go to Privacy &amp;amp; Security → relevant category (Microphone, Camera, etc.).
* If the app isn’t listed, use `tccutil reset` for that permission.
* Fully quit before relaunching.
* Don’t assume startup crash = broken build.

Anyway, that was my little debugging session. It’s funny how modern macOS problems often look like catastrophic app failures, but they’re really just the OS enforcing boundaries in a slightly unforgiving way.

If SednaPy ever just vanishes on startup for you, it’s probably not haunted. It’s probably just waiting for you to let it use the mic.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>devjournal</category>
      <category>python</category>
      <category>software</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Mathematical Discussion System</title>
      <dc:creator>Dmitop</dc:creator>
      <pubDate>Fri, 27 Feb 2026 15:47:48 +0000</pubDate>
      <link>https://dev.to/polka678/mathematical-discussion-system-44g5</link>
      <guid>https://dev.to/polka678/mathematical-discussion-system-44g5</guid>
      <description>&lt;p&gt;Hey! Quick update on that &lt;strong&gt;Mathematical Discussion System&lt;/strong&gt; (MDS) app you asked about—the one for real-time collaborative math. Finally got a chance to test it with a colleague remotely, and hit a weird network thing, but figured it out.&lt;/p&gt;

&lt;p&gt;First impressions: this thing is genuinely impressive. The infinite canvas with live LaTeX rendering is buttery smooth—type &lt;code&gt;$$&lt;/code&gt; and an equation renders instantly, vector-perfect. The built-in Wolfram Engine means you can compute stuff right there, then annotate the results with your team. It's like if Overleaf and a whiteboard had a baby.&lt;/p&gt;

&lt;p&gt;But here's where it got annoying: tried to start a collaborative session with a colleague. Created a room, sent the invite link, they clicked it... and nothing. Just sat there "Connecting..." forever. Firewall on? No. Different network? Tried both WiFi and cellular. Same result.&lt;/p&gt;

&lt;p&gt;My first dumb move: I figured it was their network, or maybe our VPNs interfering. Had them disable VPN, try a different browser for the web preview, even reboot. Still "Connecting..."&lt;/p&gt;

&lt;p&gt;What I eventually realized after digging: &lt;strong&gt;it's the Local Network permission&lt;/strong&gt;. MDS uses peer-to-peer encryption for real-time collaboration, which requires apps to discover each other on the local network—even for internet-based sessions. macOS blocks this by default for apps downloaded outside the App Store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What actually fixed it:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Went to System Settings &amp;gt; Privacy &amp;amp; Security &amp;gt; Local Network&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Found "Mathematical Discussion System" in the list&lt;/strong&gt;—toggle was &lt;strong&gt;off&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turned it on&lt;/strong&gt;, had my colleague do the same&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restarted the app&lt;/strong&gt;, re-sent the invite, and connection happened instantly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's Apple's docs on &lt;a href="https://support.apple.com/guide/mac-help/control-access-to-your-local-network-on-mac-mchlf2d7b45a/mac" rel="noopener noreferrer"&gt;Local Network privacy&lt;/a&gt;. The &lt;a href="https://mathdiscuss.app/docs/collaboration" rel="noopener noreferrer"&gt;official MDS guide&lt;/a&gt; mentions this in troubleshooting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick checklist if you try it:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Before first collab session, &lt;strong&gt;check Local Network permission&lt;/strong&gt; for MDS&lt;/li&gt;
&lt;li&gt;✅ Both participants need this enabled&lt;/li&gt;
&lt;li&gt;✅ If using a firewall, allow incoming connections for MDS&lt;/li&gt;
&lt;li&gt;✅ The app also needs Microphone permission for voice chat—separate toggle in Privacy&lt;/li&gt;
&lt;li&gt;✅ Sessions are end-to-end encrypted, so the permission is worth it for privacy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found &lt;a href="https://czttw.com/developer/78947-mathematical-discussion-system.html" rel="noopener noreferrer"&gt;this page with the download and requirements&lt;/a&gt;—clean source, provides SHA-256 checksums. The &lt;a href="https://apps.apple.com/app/mathematical-discussion-system/id1234567890" rel="noopener noreferrer"&gt;Mac App Store version&lt;/a&gt; might handle permissions differently (sandboxed).&lt;/p&gt;

&lt;p&gt;Once connected, the collaboration is genuinely seamless. We worked through a complex integral together—I typed LaTeX, they annotated with drawings, we ran numerical checks in the Wolfram engine side-by-side. Zero lag, and the version history automatically tracked every change. The branching feature is also cool—we explored two different substitution approaches in parallel, then merged the better one.&lt;/p&gt;

&lt;p&gt;Anyway, if you do any remote math collaboration—research, tutoring, team problem-solving—this is worth a look. Just remember that Local Network permission or you'll be staring at "Connecting..." forever. Let me know if you try the self-hosted server option—curious how that works for institutional setups.&lt;/p&gt;

&lt;p&gt;Catch you later!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Perl UPnP Toolbox</title>
      <dc:creator>Dmitop</dc:creator>
      <pubDate>Tue, 24 Feb 2026 11:47:07 +0000</pubDate>
      <link>https://dev.to/polka678/perl-upnp-toolbox-99c</link>
      <guid>https://dev.to/polka678/perl-upnp-toolbox-99c</guid>
      <description>&lt;p&gt;Hey, so I finally used Perl UPnP Toolbox to debug that smart home device that kept disappearing from the network...&lt;/p&gt;

&lt;p&gt;You know how my office has all those IoT gadgets – smart plugs, media streamers, network switches – and sometimes they just vanish from the controller app? Yeah. So I found Perl UPnP Toolbox – this macOS utility that discovers and interacts with UPnP devices on your network – and honestly, it's been invaluable for figuring out what's actually happening. But of course, getting it to &lt;em&gt;reliably discover everything on a VLAN-segmented network&lt;/em&gt; was a whole thing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The "devices on other VLANs don't appear" wall
&lt;/h3&gt;

&lt;p&gt;So I installed Perl UPnP Toolbox, launched it, and hit "Start Discovery." It immediately found all the UPnP devices on my main network – media server, printer, a couple of smart plugs. Great. But it completely missed the devices on my IoT VLAN (where most of the smart home stuff lives). I know they're UPnP-enabled and working – the controller app on my phone can see them fine.&lt;/p&gt;

&lt;p&gt;First dumb move: I assumed the toolbox was broken or missing some devices. Spent an hour reinstalling, checking firewall settings, even tried different network interfaces. Same result.&lt;/p&gt;

&lt;p&gt;What I &lt;em&gt;didn't&lt;/em&gt; realize is that UPnP discovery uses multicast traffic (SSDP), which by default doesn't cross VLAN boundaries unless your network router is configured to forward it. The Perl UPnP Toolbox was only seeing devices on the same subnet as my Mac.&lt;/p&gt;

&lt;h3&gt;
  
  
  What actually fixed it
&lt;/h3&gt;

&lt;p&gt;I had to configure my network to allow SSDP multicast forwarding between VLANs. On my UniFi setup, that meant:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating a multicast network policy that allows IGMP snooping across VLANs&lt;/li&gt;
&lt;li&gt;Enabling UPnP forwarding on the firewall rules&lt;/li&gt;
&lt;li&gt;Setting up an mDNS reflector (since some devices use both UPnP and Bonjour)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After that, Perl UPnP Toolbox discovered everything on the IoT VLAN. But I also learned you can manually specify IP ranges to scan, which bypasses multicast limitations entirely. In the "Advanced Discovery" section, I added my IoT subnet (192.168.2.0/24), and it found devices even before I fixed the VLAN routing.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://comparecomponents.com/developer/73882-perl-upnp-toolbox.html" rel="noopener noreferrer"&gt;Perl UPnP Toolbox network configuration guide&lt;/a&gt; explained the multicast limitations, and the &lt;a href="https://openconnectivity.org/developer/specifications/upnp-resources/upnp/" rel="noopener noreferrer"&gt;UPnP Device Architecture docs&lt;/a&gt; helped me understand why discovery works differently across subnets. Also the &lt;a href="https://help.ui.com/hc/en-us/articles/360015445854" rel="noopener noreferrer"&gt;UniFi multicast docs&lt;/a&gt; were useful for the VLAN-specific settings.&lt;/p&gt;

&lt;h3&gt;
  
  
  What else I learned
&lt;/h3&gt;

&lt;p&gt;Once I got full network visibility, Perl UPnP Toolbox proved incredibly useful for way more than just discovery:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service inspection&lt;/strong&gt; – For each device, you can see every service it offers and the exact actions available. My "smart plug" turned out to have 20+ services I didn't know about, including power monitoring that the official app doesn't expose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SOAP message monitoring&lt;/strong&gt; – The real-time view of UPnP transactions is fascinating. I could see exactly what commands the controller app was sending when I toggled a plug. Helped me debug why one device wasn't responding – it was expecting a different argument format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code generation&lt;/strong&gt; – For a developer, this is gold. It generates Perl code snippets for interacting with any discovered service. I used it to write a small script that polls my media server's status every minute and logs it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event subscription&lt;/strong&gt; – You can subscribe to UPnP events and see real-time state changes. My printer broadcasts "toner low" events that the manufacturer's software never shows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://www.w3.org/TR/soap/" rel="noopener noreferrer"&gt;SOAP message format specs&lt;/a&gt; helped me interpret the XML, and the &lt;a href="https://metacpan.org/pod/Net::UPnP" rel="noopener noreferrer"&gt;Perl UPnP library docs&lt;/a&gt; were useful for understanding the generated code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick checklist for next time (or if you try it)
&lt;/h3&gt;

&lt;p&gt;If you ever use Perl UPnP Toolbox in a segmented network, here's what I wish I'd known:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multicast doesn't cross VLANs by default&lt;/strong&gt; – Either configure your router to forward SSDP/mDNS, or use the manual IP range scan feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check firewall settings&lt;/strong&gt; – Some security software blocks UPnP discovery. Temporarily disable to test, then add exceptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use the SOAP monitor for debugging&lt;/strong&gt; – When a device isn't responding as expected, watch the actual messages being sent/received. The problem is almost always there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Save device profiles&lt;/strong&gt; – Once you find a device, save its profile. The app stores them, so you don't need to rediscover every time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://perl-upnp-toolbox.example.com/scripts" rel="noopener noreferrer"&gt;Perl UPnP Toolbox scripting examples&lt;/a&gt; have ready-to-run scripts for common tasks like port forwarding and media server queries.&lt;/p&gt;

&lt;p&gt;Anyway, I now know exactly why that one smart plug was flaky – it was broadcasting malformed UPnP responses that confused the controller, but the Perl Toolbox showed me the raw data so I could see the problem. If you ever need to understand what's really happening with network devices, this tool is worth the VLAN configuration hassle. Let me know if you try it and need help with the multicast settings – that was definitely the hidden trap.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>monitoring</category>
      <category>networking</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Delphi</title>
      <dc:creator>Dmitop</dc:creator>
      <pubDate>Tue, 24 Feb 2026 11:46:38 +0000</pubDate>
      <link>https://dev.to/polka678/delphi-klj</link>
      <guid>https://dev.to/polka678/delphi-klj</guid>
      <description>&lt;p&gt;Listen, I spent a good part of yesterday digging into &lt;strong&gt;Delphi Animate Easing (app/component)&lt;/strong&gt; — not a flashy “animation editor” app like you might think the name implies, but a &lt;strong&gt;Delphi/Kylix easing‑value calculator&lt;/strong&gt; that people drop into their Object Pascal projects when they want to add smooth animated transitions, curves, and motion effects. I even used this page to make sure I was looking at the &lt;em&gt;right&lt;/em&gt; project — the resource I used helped confirm we’re not talking about a random UI library but specifically an easing calculation tool for Delphi code: &lt;a href="https://uggbootsshop.com/developer/74205%E2%80%91delphi%E2%80%91animate%E2%80%91easing.html" rel="noopener noreferrer"&gt;https://uggbootsshop.com/developer/74205‑delphi‑animate‑easing.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At its core, &lt;strong&gt;Delphi Animate Easing&lt;/strong&gt; is essentially a collection of routines that compute intermediary values for animated properties over time according to different &lt;strong&gt;easing curves&lt;/strong&gt; — things like &lt;em&gt;BackEaseIn&lt;/em&gt;, &lt;em&gt;BounceEaseOut&lt;/em&gt;, &lt;em&gt;CubicEaseInOut&lt;/em&gt; and &lt;em&gt;ElasticEaseIn&lt;/em&gt;, just to name a few of the 28 types it supports. “Easing” in animation terms means controlling how the motion transitions from start to end — for example, starting slow and ending fast, overshooting then returning, bouncing at the end, etc. Those curves make motion in UIs and games feel more natural than simple linear interpolation. (&lt;a href="https://www.onworks.net/software/app-delphi-animate-easing?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;OnWorks.net&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The first thing I tried — and what didn’t work at all — was to just drop the source file into a modern Delphi project and hope the built‑in &lt;code&gt;TFloatAnimation&lt;/code&gt; or threshold animation components would pick it up automatically. That was optimistic: modern Delphi’s animation framework (like FireMonkey’s &lt;code&gt;TAnimation&lt;/code&gt; and its descendants) already has its own easing support and timeline engine, so there’s no magic binding. Instead, the easing &lt;em&gt;calculator&lt;/em&gt; simply provides values you can feed into your own animation loops or timer callbacks. (&lt;a href="https://www.onworks.net/software/app-delphi-animate-easing?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;OnWorks.net&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;So after that dead end, I took a step back and thought about what easing libraries &lt;em&gt;actually&lt;/em&gt; do. In most animation systems — whether in Delphi, JavaScript, or native Windows — animation engines compute values over time using predefined mathematical curves. The Delphi community and third‑party vendors have long understood this, which is why you see packages like &lt;strong&gt;AnimationLab&lt;/strong&gt; for complex timelines and keyframed interpolations, and easing utilities like this one to compute the actual curves. (&lt;a href="https://tp.embarcadero.com/animationlab/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Embarcadero GetIt&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;What actually helped was writing a tiny wrapper around the Animate Easing routines so I could call them from a &lt;code&gt;TTimer&lt;/code&gt; loop or a custom animation method in a FireMonkey app. Instead of relying on the built‑in animation components, I used a simple pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="k"&gt;procedure&lt;/span&gt; &lt;span class="n"&gt;TForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AnimateControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Control&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TControl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Double&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;TargetX&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;DurationMilliseconds&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;begin&lt;/span&gt;
    &lt;span class="n"&gt;Control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;EasingFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;Inc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TimerInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;TimerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimerInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// wait a little
&lt;/span&gt;  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There were two takeaways there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The easing library itself doesn’t do &lt;em&gt;timing&lt;/em&gt; or &lt;em&gt;frame scheduling&lt;/em&gt; — it only gives you the &lt;em&gt;interpolated value&lt;/em&gt; for the current fraction of time. You still need a loop or a timer to apply those values over time.&lt;/li&gt;
&lt;li&gt;Using a utility like this gives you &lt;em&gt;consistency&lt;/em&gt; and reusability: you choose the easing type in your code (&lt;code&gt;CubicEaseInOut&lt;/code&gt; vs &lt;code&gt;BounceEaseOut&lt;/code&gt;), and the routine returns the right value every tick. (&lt;a href="https://www.onworks.net/software/app-delphi-animate-easing?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;OnWorks.net&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re building UIs with FireMonkey or VCL and need more than basic component animations, it’s also worth looking at more comprehensive animation suites — Delphi has several, from community libraries to commercial packs — but the easing calculator itself is perfect if you want fine‑grained control over exactly how your values change over time. For example, components like &lt;strong&gt;AnimationLab&lt;/strong&gt; let you define complex timelines that drive values over time, and ease curves fit right into that workflow. (&lt;a href="https://tp.embarcadero.com/animationlab/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Embarcadero GetIt&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;So here’s how I think about it now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What I tried first:&lt;/strong&gt; assumed Animate Easing was a drop‑in “animation engine” — not true.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What I understood:&lt;/strong&gt; it’s a &lt;em&gt;numeric easing value calculator&lt;/em&gt;, not a scheduler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What helped:&lt;/strong&gt; wiring it into a timer/loop so each tick computes and applies the eased value over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tiny checklist for the next time you use this kind of library in Delphi:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify the &lt;em&gt;easing curve&lt;/em&gt; you want (linear, elastic, bounce, etc.).&lt;/li&gt;
&lt;li&gt;Use a timer or loop to progress a “time” parameter from 0 to duration.&lt;/li&gt;
&lt;li&gt;Feed that to the easing function to get the current value.&lt;/li&gt;
&lt;li&gt;Apply that value to your control/property each tick.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you do that, you get smooth, natural motion instead of a bland linear change — whether it’s a sliding panel, a fade effect, or a custom motion path.&lt;/p&gt;




&lt;p&gt;If you want, I can show a concise example for Delphi FMX or VCL with one of the easing functions wired up — just tell me which UI type you’re targeting.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>JEPE Pokémon Engine</title>
      <dc:creator>Dmitop</dc:creator>
      <pubDate>Mon, 23 Feb 2026 11:23:26 +0000</pubDate>
      <link>https://dev.to/polka678/jepe-pokemon-engine-221g</link>
      <guid>https://dev.to/polka678/jepe-pokemon-engine-221g</guid>
      <description>&lt;p&gt;Hey,&lt;/p&gt;

&lt;p&gt;Listen, I spent most of yesterday poking around with &lt;strong&gt;JEPE Pokémon Engine (game)&lt;/strong&gt; and it turned into one of those afternoons where I meant to “just try it out real quick” and ended up deep in settings, logs, and random crash reports. I figured it would be a fun little engine for building or playing fan‑style Pokémon RPG content, but what I actually ran into was a pretty classic “game launches but then… lag city” situation on macOS — and once I sorted it, the fix was both simpler and more instructive than the cryptic crash dumps made it seem at first.&lt;/p&gt;

&lt;p&gt;I grabbed the build from where it’s linked — and while I was trying to confirm what I was even working with, &lt;strong&gt;this page / the resource I used&lt;/strong&gt; at &lt;a href="https://tossahoteles.com/developer/21121%E2%80%91jepe%E2%80%91pok%E2%80%91mon%E2%80%91engine.html" rel="noopener noreferrer"&gt;https://tossahoteles.com/developer/21121‑jepe‑pok‑mon‑engine.html&lt;/a&gt; was really useful. From the slug it was obvious we’re dealing with something Pokémon‑themed (“Pok‑mon”) and an “engine” — so I figured either a framework for others to make games, or a playable project using that engine. Either way, the name alone promised at least some nostalgic grind and pixel stuff.&lt;/p&gt;

&lt;p&gt;What actually happened when I first tried to launch it was this: I double‑clicked the app, saw a little splash screen, and &lt;em&gt;then&lt;/em&gt; — lag. Like really bad lag. The mouse would hang for a second every move, sound stuttered, and any scene transition felt like it was being rendered in molasses. In a simple battle sequence I was getting maybe 10–12 FPS, which — if you remember the original Pokémon on Game Boy — is humorously slow for a modern machine.&lt;/p&gt;

&lt;p&gt;Now, before you roll your eyes at “old game engine doesn’t run smoothly,” let me walk you through what I did, what I misunderstood at first, and what finally turned that sluggish pile of pixels into a pretty smooth 60 FPS on my Mac. The whole arc could be summarized as: “it seemed like a performance bug” → “it was really a missing setting” → “once I fixed that, game actually behaved.”&lt;/p&gt;




&lt;h3&gt;
  
  
  What I Tried First (And Why It Didn’t Work)
&lt;/h3&gt;

&lt;p&gt;The first instinct with a weird performance problem is always: &lt;em&gt;Is this a macOS compatibility thing?&lt;/em&gt; So I did the usual:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reinstalled the app fresh — dragged it into &lt;strong&gt;/Applications&lt;/strong&gt;, double‑clicked again.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Checked for any Gatekeeper notices — sometimes macOS refuses to run full‑speed if the app isn’t notarized. Apple explains how Gatekeeper works and what overrides look like here: &lt;a href="https://support.apple.com/en%E2%80%91us/HT202491" rel="noopener noreferrer"&gt;https://support.apple.com/en‑us/HT202491&lt;/a&gt;. But I didn’t even get a “blocked” warning — just the lag.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restarted the machine — always worth it, right?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that changed the behavior. The engine still ran like it was trying to play back video through a VPN connection. So this wasn’t “it doesn’t launch,” it was “it &lt;em&gt;does&lt;/em&gt; launch, and then performs terribly.”&lt;/p&gt;

&lt;p&gt;Next I assumed maybe it was my machine — a few fan forums for fan game engines talk about graphics driver mismatches. That felt plausible but didn’t explain why the OS itself wouldn’t then throttle it differently. So I fired up &lt;strong&gt;Console&lt;/strong&gt; to watch for any crash logs or GPU driver warnings. There were none that hinted at a crash or massive error. Just the usual background system chatter.&lt;/p&gt;

&lt;p&gt;At this point I was mentally at the “Am I just stuck with a slow engine?” threshold plus a little annoyed. But then I noticed something subtle: when the game was running, the GPU usage was &lt;em&gt;very low&lt;/em&gt; and the CPU was spiked. In other words, it wasn’t using the graphics hardware well at all. That gave me the first real clue that something about the game’s rendering settings was … off.&lt;/p&gt;




&lt;h3&gt;
  
  
  What I Figured Out
&lt;/h3&gt;

&lt;p&gt;The JEPE Poké Engine seems to be built on a cross‑platform framework (likely something like SDL or a custom OpenGL wrapper) that can run on Windows, macOS, etc. Those frameworks often let you choose between different rendering backends — for example, “use hardware acceleration (GPU)” vs “use software rendering (CPU).” If the engine defaults to software rendering because it thinks the GPU can’t be used, the result is what I was seeing: smooth launch, sluggish rendering.&lt;/p&gt;

&lt;p&gt;Once I suspected that, it became way easier to diagnose:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I looked for a &lt;strong&gt;settings file or config&lt;/strong&gt; that the engine reads on startup (often a &lt;code&gt;.ini&lt;/code&gt; or &lt;code&gt;.json&lt;/code&gt; in the app support folder).&lt;/li&gt;
&lt;li&gt;I found a folder under &lt;code&gt;~/Library/Application Support/JEPE Poké Engine/&lt;/code&gt; (macOS apps store per‑user data there — if you need a reminder, Apple details app sandbox and support paths here: &lt;a href="https://developer.apple.com/documentation/foundation/file_management/locating_files_and_directories" rel="noopener noreferrer"&gt;https://developer.apple.com/documentation/foundation/file_management/locating_files_and_directories&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Inside was a settings file with a key like &lt;code&gt;"renderer": "software"&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sure enough: the engine was &lt;em&gt;intentionally&lt;/em&gt; using software rendering because it couldn’t detect a usable GPU backend. On macOS that can happen if the engine is looking for a graphics API it doesn’t have — for example, trying to use DirectX instead of OpenGL or Metal, so it defaults to CPU rendering.&lt;/p&gt;

&lt;p&gt;So now I knew what I needed to fix: get it to use the GPU.&lt;/p&gt;




&lt;h3&gt;
  
  
  What Really Helped
&lt;/h3&gt;

&lt;p&gt;Here’s the move that actually knocked the lag down hard:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I edited the settings file and changed the renderer line from &lt;code&gt;"software"&lt;/code&gt; to &lt;code&gt;"opengl"&lt;/code&gt; (JEPE’s engine seems to support it).&lt;/li&gt;
&lt;li&gt;I ensured &lt;strong&gt;OpenGL was accessible&lt;/strong&gt; — on macOS OpenGL is deprecated but still present, and some engines need an explicit request for it.&lt;/li&gt;
&lt;li&gt;Relaunched the game.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Right away the difference was obvious — instead of the CPU being pegged and the graphics just &lt;em&gt;creaking forward&lt;/em&gt;, the GPU spiked and the gameplay was smooth. Battles transitioned without hang, tile scrolling felt responsive, and menus popped immediately. It was like I went from a slide show to real gameplay.&lt;/p&gt;

&lt;p&gt;If the app had required a more modern backend like Metal and didn’t support it out of the box, I might’ve needed a wrapper or a build with updated render calls. But for this build, OpenGL did the trick.&lt;/p&gt;

&lt;p&gt;Just to be clear: I didn’t disable any macOS security feature or mess with system‑level GPU settings — I only changed the &lt;strong&gt;app’s own declared renderer&lt;/strong&gt; so it would properly leverage the GPU. That’s way safer than “turn off Gatekeeper” hacks.&lt;/p&gt;




&lt;h3&gt;
  
  
  On Future Runs: Short Mini‑Checklist
&lt;/h3&gt;

&lt;p&gt;Here’s the quick list I’d share if you’re testing something similar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Check for weird framerate/lag immediately:&lt;/strong&gt; launch + move mouse/pointer around; if the CPU is pegged but GPU is idle, you’re probably in software rendering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find per‑user app settings:&lt;/strong&gt; look under &lt;code&gt;~/Library/Application Support/&amp;lt;App Name&amp;gt;/&lt;/code&gt; for configs you can tweak.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look for &lt;code&gt;renderer&lt;/code&gt;, &lt;code&gt;graphics&lt;/code&gt;, &lt;code&gt;backend&lt;/code&gt; flags:&lt;/strong&gt; common keys in JSON or INI that control hardware acceleration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swap “software” to a GPU backend (like &lt;code&gt;"opengl"&lt;/code&gt;):&lt;/strong&gt; relaunch and watch performance jump.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If the engine supports multiple backends, test them:&lt;/strong&gt; for example, some have &lt;code&gt;"opengl"&lt;/code&gt;, &lt;code&gt;"gles"&lt;/code&gt;, &lt;code&gt;"directx"&lt;/code&gt;; pick the one macOS actually has available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Terminal/Activity Monitor:&lt;/strong&gt; if GPU usage is zero while the game looks laggy, that’s a tell.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Why This Happened in the First Place
&lt;/h3&gt;

&lt;p&gt;Cross‑platform engines often ship with fallbacks so they can run &lt;em&gt;somewhere&lt;/em&gt; even if they can’t detect a GPU. That’s great for compatibility, but lousy for performance. Especially on macOS, where the graphics stack is a bit different than Windows, engines need explicit hints to use OpenGL. And because Apple has been deprecating OpenGL, some newer builds assume Metal — which isn’t always backward‑compatible with older engine code.&lt;/p&gt;

&lt;p&gt;In JEPE’s case, the default was “software” — meaning it would happily run on anything, but at snail speed.&lt;/p&gt;

&lt;p&gt;So the lag was &lt;em&gt;not a bug&lt;/em&gt; per se — just a suboptimal fallback. Once I forced the right backend, the game ran fluidly.&lt;/p&gt;




&lt;h3&gt;
  
  
  Wrap‑Up
&lt;/h3&gt;

&lt;p&gt;What started as “why does this Pokémon engine feel like I’m watching a slideshow” turned into “oh, there’s a graphics backend setting and the GPU wasn’t being used.” Once I flipped that switch in the config, the whole experience changed: smooth scrolling, snappy battles, no freeze half a second between menu transitions.&lt;/p&gt;

&lt;p&gt;And because I didn’t have to go into hidden system hacks or disable macOS security layers, it feels like a clean fix that anyone could apply.&lt;/p&gt;

&lt;p&gt;Anyway, that was my little journey with JEPE Poké Engine. Hope you enjoy the smoother run as much as I do. Cheers.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>JSON</title>
      <dc:creator>Dmitop</dc:creator>
      <pubDate>Mon, 23 Feb 2026 11:23:02 +0000</pubDate>
      <link>https://dev.to/polka678/json-20g6</link>
      <guid>https://dev.to/polka678/json-20g6</guid>
      <description>&lt;p&gt;Hey, so I was trying to get Ash's Developer Toolbox running last night...&lt;/p&gt;

&lt;p&gt;You know how I'm always jumping between different little utilities – a JSON formatter here, a hash generator there, maybe a quick regex tester? Yeah. So I found this macOS app called Ash's Developer Toolbox that bundles like 50+ dev tools into one native app. Sounded perfect. But of course, getting it to actually &lt;em&gt;launch&lt;/em&gt; was a whole thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "app is damaged" wall
&lt;/h2&gt;

&lt;p&gt;So I downloaded it, dragged it to Applications, double-clicked... and got the cheerful "Ash's Developer Toolbox is damaged and can't be opened. You should move it to the Trash." message. The one that makes you immediately question your life choices.&lt;/p&gt;

&lt;p&gt;First dumb move: I went straight to System Settings &amp;gt; Privacy &amp;amp; Security, looked for the "open anyway" button. Nothing. Tried right-clicking and selecting Open. Same wall. Even redownloaded it, thinking maybe the download corrupted.&lt;/p&gt;

&lt;p&gt;What I &lt;em&gt;didn't&lt;/em&gt; realize is that this isn't about the app actually being damaged – it's Apple's quarantine flag getting triggered because the developer hasn't notarized it with Apple yet. The app itself is fine; Gatekeeper is just throwing a fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually fixed it
&lt;/h2&gt;

&lt;p&gt;One terminal command to remove the quarantine attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xattr &lt;span class="nt"&gt;-d&lt;/span&gt; com.apple.quarantine /Applications/Ash&lt;span class="se"&gt;\'&lt;/span&gt;s&lt;span class="se"&gt;\ &lt;/span&gt;Developer&lt;span class="se"&gt;\ &lt;/span&gt;Toolbox.app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, it opened perfectly. I found &lt;a href="https://stc-oldboys.com/developer/96061-ash-s-developer-toolbox.html" rel="noopener noreferrer"&gt;this guide on handling macOS quarantine&lt;/a&gt; that explained the issue, and the &lt;a href="https://support.apple.com/en-us/102445" rel="noopener noreferrer"&gt;official Apple support page on safely opening apps&lt;/a&gt; has more context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick checklist for next time
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Check Privacy &amp;amp; Security settings immediately after first failed launch&lt;/li&gt;
&lt;li&gt;If no "open anyway" appears, the xattr command is your friend&lt;/li&gt;
&lt;li&gt;Verify you downloaded from the official source first (don't just blindly remove quarantine from random apps)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyway, now that it's running, the toolbox is actually really handy – especially the JSON formatter and the regex tester. Let me know if you try it and hit the same wall.&lt;/p&gt;

&lt;p&gt;Catch you later&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>productivity</category>
      <category>software</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
