AI 资讯
Evaluating Agents With an LLM-as-Judge Harness (Without Kidding Yourself About It)
Key Takeaways You can't unit-test a coach agent the way you test a pure function — the output is non-deterministic and "good" is a judgment call, not an assertion. An LLM-as-judge harness lets you grade a whole test set automatically against a rubric, which is the only way solo-scale eval stays sustainable. But the judge is itself a fallible model. If you don't design around its known biases — position, verbosity, self-preference, and quiet drift when the judge model updates — you build a green dashboard that means nothing. The mitigations that actually work are mechanical, not prompt-magic: shuffle order on every pairwise call, pin the judge version, keep a small human-labelled anchor set, and re-check the judge against it. The problem I actually had FamNest's coach agent generates responses to parents — check-ins, encouragement, the occasional gentle redirect. I have a growing pile of these interactions, and every time I change a prompt, swap a model, or adjust the pipeline, I need to know one thing: did I just make it better or worse? For normal code, that's what tests are for. I change something, the suite runs, red or green, done. But there's no assertEqual for "was this an empathetic, useful response to a tired parent." The output changes every run even at temperature zero-ish, and the quality bar is a human judgment, not a fixed string. Two responses can be worded completely differently and both be good. One can match my "expected output" word for word and still be worse than a version that didn't. So the honest options were: read every response by hand every time I change something (does not scale past about week two), or build a harness where a model grades the outputs against a rubric. I built the harness. Then I spent an uncomfortable amount of time learning all the ways a harness like that can lie to you. What the harness actually is At its simplest, it's a loop: def evaluate ( test_cases , coach_agent , judge ): results = [] for case in test_cases : res
AI 资讯
Codegarden 2026 - a little late, because it gave me something to build
A few weeks ago I was in Copenhagen for my first Codegarden, and one quiet thought has stuck with me since. It didn't come from a keynote. It came from the bit the keynote leaves out. I've worked with Umbraco for years, but I'd never been to Codegarden, and I turned up without much of a fixed idea of what the two days would be. I kept that open on purpose. I wanted to take it in rather than measure it against something I'd decided in advance. What struck me most was that the value came from two places at once. The sessions were a fantastic source of inspiration; everything from keynotes to guest speakers all seemed to resonate in some way or another. The conversations in between the sessions - drifting around the event space and finding common ground with anyone and everyone - proved just as valuable. I came home more energised than I've been in a while, with a notebook full of half-formed ideas and a better feel for the community I'm part of. But the thing I kept turning over afterwards was that bit the keynote leaves out. That's what I want to write about. The easy half and the hard half Every major Umbraco release gets the same treatment. A polished keynote, a clean demo, a feature that looks effortless on stage. There's plenty in 18, and which part matters most depends on what you're building. For me it's Elements: a new Library section where you manage reusable content and reference it through a new element picker. Create once, use everywhere. It's a genuinely good direction. Reusable content has lived awkwardly in the content tree for years, and Library finally gives it a proper home. What the demos don't show you is the part I've been playing around with for the past few weeks. Taking a real Umbraco 17 site, with content pickers threaded through block lists, block grids, rich text blocks and base document properties, and getting all of it to point at the new Library without an editor ever noticing anything moved underneath them. The feature is the easy half.
AI 资讯
I finally understood cron expressions by building an explainer for them
For years I copied cron expressions off Stack Overflow, pasted them into a config file, crossed my fingers, and moved on. 0 9 * * 1-5 ? Sure, that "looks like weekday morning." */15 * * * * ? "Every 15 minutes, probably." I never actually read them. So I did the thing that always cures this for me: I built a tool that parses a cron expression, explains it in plain English, and shows the next five times it will fire. No library. About 50 lines of real logic. Here's everything I learned. The five fields (and the order that trips everyone up) A standard cron expression is exactly five fields separated by spaces: ┌──────── minute 0 - 59 │ ┌────── hour 0 - 23 │ │ ┌──── day - of - month 1 - 31 │ │ │ ┌── month 1 - 12 │ │ │ │ ┌ day - of - week 0 - 6 ( 0 = Sunday ) * * * * * The order never changes, and the number-one beginner mistake is swapping the first two. Minute comes first. If you write 9 30 * * * thinking "9:30am," you actually get "minute 9, hour 30" — which is invalid, because hours only go to 23. Say it out loud every time: minute, hour, day-of-month, month, day-of-week. Each field answers one question: which values of this unit does the job run on? An * means "every value." Most real schedules pin down a couple of fields and leave the rest as * . Daily at 9am is 0 9 * * * — minute and hour fixed, everything else "every." Lists, ranges, and steps Beyond single numbers, each field understands three operators, and they combine: Comma makes a list: 1,15 in the day field means the 1st and the 15th. Hyphen makes an inclusive range: 1-5 in the day-of-week field means Monday through Friday. Slash makes a step, taking every n-th value: */15 in the minute field means 0, 15, 30, 45 . Steps can apply to a range too, so 0-30/10 means 0, 10, 20, 30 . That's the whole grammar. Number, list, range, step. Once you can expand a field into the concrete set of numbers it matches, you understand cron. Here's the expansion function, which is the heart of the parser: function expandFie
AI 资讯
The State of Email in 2026: what 50,000 domains reveal about MX, SPF & DMARC
By the team at MailTester Ninja — a real-time email verification API that stores nothing. We verify a lot of email for a living. So we pointed our infrastructure at a representative panel of 50,000 of the world's most-linked domains and measured how email is actually configured in 2026 — MX providers, SPF and DMARC. Pure DNS, aggregate only, no personal data . Here's what the internet's mail setup looks like right now. Email is still (almost) everywhere 79.9% of these domains are mail-enabled (they publish MX records). Email isn't going anywhere. Authentication: adopted, but not enforced 75.8% publish an SPF record 64% publish a DMARC record …but only 22.6% actually enforce it with p=reject That last number is the real story. Of the domains that bother to publish DMARC, only 35.2% are on p=reject — the rest sit on p=none (37.2%, monitoring only) or quarantine (27.6%). Most of the web announces a policy it doesn't enforce. That's a deliverability and spoofing gap hiding in plain sight. Who runs the world's inboxes? Other / self-hosted — 32.6% Google Workspace / Gmail — 28.2% Microsoft 365 / Outlook — 22.5% Proofpoint — 5.5% Mimecast — 3.1% Tencent QQ — 2% Namecheap — 1.3% Cisco IronPort — 0.9% Self-hosted and the two hyperscalers (Google Workspace and Microsoft 365) dominate, but the long tail of providers is very real — which is exactly why deliverability is hard: every provider blocks, greylists and reputation-scores differently. Why we publish this We built an open, daily-updated dataset and a live dashboard because deliverability decisions should be based on data, not folklore. It's CC BY 4.0 — use it, cite it, build on it. Want to check a specific domain? Our free analyzer shows any domain's MX / SPF / DMARC in one click — no signup, nothing stored. Methodology: Live DNS scan (MX/SPF/DMARC). Aggregate only — no email sent, no personal data. Sample updated Wed, 01 Jul 2026 12:31:00 GMT.
AI 资讯
Stop Over-Optimizing Performance: The Modern Full-Stack Toolkit in 2026
Let’s face it: if your current frontend optimization strategy still involves manually auditing codebases for missing useMemo hooks, micro-managing dependency arrays, or aggressively fighting layout shifts with complex client-side state management, you are wasting your engineering leverage. As we cross the midpoint of 2026, web framework architecture has quietly undergone a massive shift. We have firmly moved out of the era of manual performance tweaking and entered the era of automated, compile-time optimization . The goal of modern development is no longer just shipping fewer kilobytes to human users—it's also about optimizing data chunk delivery for AI web crawlers that evaluate your site in real-time. Here is how the modern full-stack ecosystem redefined performance this year, and what you should focus on instead. 1. The Death of Manual Memoization (Thanks, React Compiler) For years, React developers bore the cognitive load of rendering performance. One misplaced reference and your entire component tree re-rendered down to the root. With the absolute maturity and default adoption of the React Compiler across production frameworks, that paradigm is officially legacy code. The compiler handles component memoization automatically at the build step by analyzing javascript structures directly. // ❌ THE OLD WAY (Pre-2026 Manual Overhead) const ExpensiveComponent = memo (({ data }) => { const processedData = useMemo (() => computeHeavyMetrics ( data ), [ data ]); const handleAction = useCallback (() => { ... }, []); return < DataGrid items = " {processedData} " onAction = " {handleAction} " /> ; }); // THE MODERN WAY (Zero Performance Boilerplate) export function ModernComponent ({ data }) { const processedData = computeHeavyMetrics ( data ); const handleAction = () => { ... }; return < DataGrid items = " {processedData} " onAction = " {handleAction} " /> ; } Because the compiler injects optimization markers directly into the output code, human engineers can stop arguin
AI 资讯
HeroUI v3 Lands as a Ground-Up Rewrite for React and React Native, Built on Tailwind CSS v4
HeroUI v3 is a redesigned React component library, previously NextUI, offering over 75 components, including 21 new ones, and a new React Native library with 37 components. Built on React Aria and Tailwind CSS v4, it emphasizes accessibility and customization. The library has experienced many updates since its release, and migration from the previous version is necessary. By Daniel Curtis
安全
I Tried to Escape LeetCode for 2 Years (But Here We Are)
Seriously, LeetCode in 2026? Everyone is saying HackerRank just killed LeetCode, and yet here I am,...
AI 资讯
Navigating the Shift: Why Building Faster Means We Must Think Smarter
While researching the massive wave of digital transformation rewriting the rules for startups this year, I stumbled upon an insightful podcast by the tech firm GeekyAnts. Hosted by Prem, the episode featured Sanket Sahu, the co-founder of GeekyAnts, who recently emerged from a year and a half hiatus to discuss what he calls the " AI-native shift ." As someone navigating the unpredictable US tech market in 2026, listening to their conversation felt like a reality check. We are constantly flooded with news about AI replacing engineers or cutting budgets, but this discussion offered a grounded perspective on what is actually happening on the ground in software development. The Illusion of Speed The central theme that caught my attention was the sheer velocity of modern AI adoption. Sanket made a striking contrast: while television took decades to become a common household utility, modern AI systems like ChatGPT or Claude reached exponential revenue and widespread adoption in mere months. But here is where the critical analysis kicks in. As founders, we often mistake engineering speed for product success. The podcast highlighted a massive bottleneck that many of us are guilty of overlooking: the human limit. While AI can spin up code in hours instead of months, the time required for human review, validation, and team collaboration remains relatively static. If an organization rushes to ship code simply because it can, they risk launching products that lack deep market validation. True product development still requires user testing and meticulous iteration. The building phase might be operating at 10x speed, but the surrounding human infrastructure is only moving at 1.5x. Fluid Roles and the Rise of the "Builder" Another significant takeaway for Western businesses is the shifting definition of software roles. The traditional silos dividing front-end, back-end, and DevOps are rapidly blurring. According to the insights shared in the video, the engineering ecosystem is mo
AI 资讯
CalcMora just crossed 200 tools | Here's what changed under the hood
CalcMora just crossed 200 live tools calculators and converters spanning finance, health, math, unit conversions, date/time, everyday life, and sports. It's a small milestone against the bigger target (3,000 tools within a year), but it's the first one that felt like proof the approach actually works. What CalcMora is A free calculator and converter site, built to be fast and genuinely useful rather than bloated with unnecessary interactivity. Every tool lives on its own page, static by default, ad-supported, and designed to actually rank and hold up in search rather than just exist. The stack is intentionally boring: Astro for static output, hosted on Cloudflare Pages . No client-side framework runtime, no heavy JS bundles. That choice is mostly why the site stays fast even as the tool count climbs into the hundreds; static pages don't get slower just because there are more of them. Consistency at scale Going from a handful of tools to 200 forced us to think hard about repeatability. Every tool page follows the same underlying template: a calculator, supporting explanatory content, an FAQ section, and standard trust/attribution elements (author info, last-updated date, disclaimers where relevant). That consistency is what makes it realistic to keep scaling toward thousands of pages without every single one needing a bespoke pass. Structured data (schema.org markup) is baked into every page too; it's a big part of why individual calculators show up well in search, and it's applied consistently rather than as an afterthought. New: embeddable tools The other big addition alongside the 200-tool mark is an embed system — every tool on CalcMora can now be dropped into someone else's site as a lightweight, ad-free widget. Site owners get a copy-paste snippet, no signup required. The implementation leans on a couple of iframe and query-param tricks to keep embedded calculators fast and chrome-free (no header, footer, or ads, just the tool), without needing any JS framework
AI 资讯
From Vibe Coding to Production: A Step-by-Step Guide to Shipping AI-Generated Code Safely in 2026
Here's an uncomfortable truth nobody wants to admit out loud: most teams can generate a working app in minutes now, but almost none of them can ship it to production without breaking something important. Only a small fraction of organizations have actually moved their AI-built systems past the pilot stage. The gap between "it works on my machine" and "it works for real users" has never been wider, and closing that gap is quickly becoming the single most valuable skill a developer can have this year. If you have been prompting your way to a working prototype and then hitting a wall when it's time to actually deploy, this guide walks through exactly how to close that gap, with working examples at every step. Why This Matters Right Now Vibe coding, meaning describing what you want in plain language and letting an AI model scaffold the implementation, has gone from a novelty to a default workflow. Developers are shipping REST APIs , auth flows, and full CRUD apps with a single well-written prompt. But speed of generation is not the same as readiness for production. Untested edge cases, missing validation, weak error handling, and security gaps show up constantly in AI-generated code because the model optimized for "looks correct" rather than "survives real traffic." The developers who stand out this year are not the ones who can generate code fastest. They are the ones who know how to validate it, harden it, and integrate it responsibly. Below is a practical checklist you can apply to any AI-generated codebase before it touches a real user. Step 1: Treat the AI Output as a First Draft, Not a Final Answer Say your AI assistant generates this login handler: \ javascript // AI-generated first draft app.post('/login', async (req, res) => { const { email, password } = req.body; const user = await db.query( SELECT * FROM users WHERE email = '${email}' ); if (user.password === password) { res.json({ token: generateToken(user) }); } }); \ \ Looks functional. It is also a SQL in
AI 资讯
I Built 5 Free AI Tools That Replace $200/month in SaaS Subscriptions
The Subscription Fatigue is Real I was paying $47 for ChatGPT Plus, $29 for Jasper, $19 for Grammarly, $16 for Copy.ai, and $15 for an SEO tool. That's $126/month just for AI writing tools. So I built my own. Five tools, one dashboard, completely free to start. Here's how each one works and what it replaces. 1. AI Content Writer (Replaces Jasper, Copy.ai — $66/month combined) The content writer generates blog posts, articles, product descriptions, and marketing copy. You pick: Content type : blog post, article, product description, marketing copy, newsletter Tone : professional, casual, friendly, authoritative, humorous, persuasive Length : short (100-200 words), medium (300-500 words), or long (800-1200 words) The key difference from Jasper: no templates, no "brand voice" setup. You just describe what you want and get it. Simpler, faster. 2. AI Email Composer (Replaces Grammarly Business — $16/month) This one handles the emails I hate writing: Cold outreach to potential clients Follow-up emails after meetings Professional inquiries Customer support replies You set the formality level (formal, semi-formal, casual) and urgency. It writes the subject line AND the body. I've used it for 50+ cold emails last month. 3. Social Media Caption Generator (Replaces Later + caption tools — $29/month) Generates 3 caption variations per request. Platform-specific: Instagram : emojis, hashtags, engagement hooks Twitter/X : concise, thread-ready LinkedIn : professional, thought-leadership style TikTok : casual, trend-aware Options for emojis, hashtags, and CTAs are toggleable. You can mix and match from the 3 generated options. 4. AI Code Helper (Replaces GitHub Copilot Chat — $10/month) Five modes: Generate : write code from description Debug : find and fix errors in pasted code Explain : break down complex code Refactor : improve code quality Convert : translate between 20+ languages Supports Python, JavaScript, TypeScript, Java, C++, Go, Rust, SQL, and more. Not as deeply integr
AI 资讯
The Token Bucket Algorithm: Build Server-Side API Rate Limiting in ~40 Lines
The Token Bucket Algorithm: Server-Side API Rate Limiting in ~40 Lines Plenty of tutorials teach you how to survive someone else's rate limit with retries and backoff. Far fewer show you how to build one. If you run an API, you need rate limiting on your side too — to protect your database from a runaway client, keep one noisy tenant from starving everyone else, and give abusive traffic a polite 429 instead of a melted server. The cleanest algorithm for the job is the token bucket . Let's implement it from scratch, then make it production-ready. How token bucket works Picture a bucket that holds up to capacity tokens. Every request removes one token. The bucket refills at a steady refillRate (tokens per second), up to its cap. If a request arrives and the bucket is empty, it's rejected. This gives you two useful properties at once: A sustained rate — the long-run average, set by refillRate . A burst allowance — clients can spend the whole bucket at once, set by capacity . That burst tolerance is why token bucket feels fair. A user who's been quiet for a minute can fire off a batch of requests without being punished for it. A minimal implementation Here's a self-contained bucket in JavaScript. No dependencies, no timers — we compute refill lazily based on elapsed time, which is both simpler and more accurate than a background interval. class TokenBucket { constructor ( capacity , refillRatePerSec ) { this . capacity = capacity ; this . refillRate = refillRatePerSec ; this . tokens = capacity ; this . lastRefill = Date . now (); } _refill () { const now = Date . now (); const elapsedSec = ( now - this . lastRefill ) / 1000 ; this . tokens = Math . min ( this . capacity , this . tokens + elapsedSec * this . refillRate ); this . lastRefill = now ; } take ( cost = 1 ) { this . _refill (); if ( this . tokens >= cost ) { this . tokens -= cost ; return { ok : true , remaining : Math . floor ( this . tokens ) }; } const deficit = cost - this . tokens ; const retryAfter = Mat
AI 资讯
Shielded Token Contracts on Midnight: Real Errors, Real Fixes
Written from months of grinding on shielded liquidity DeFi protocols on Midnight. If you've been trying to build anything serious with shielded fungible tokens on Midnight lending protocols, liquidity pools, DEXes you've probably hit some walls that the documentation doesn't fully prepare you for. The Midnight programming model around shielded tokens is genuinely different from anything in the EVM world, and a lot of the intuitions you carry from Solidity or even other ZK environments will get you into trouble fast. This post is a breakdown of the most impactful errors and misconceptions I ran into while building shielded liquidity DeFi contracts using Midnight's Compact language. These are not theoretical every single one of these either broke a circuit or caused a proof server failure at some point. I'll walk through what the issue is, why it happens, and what the correct pattern looks like. Background: How Shielded Tokens Actually Work Under the Hood Before we get into the errors, let's get clear on the underlying mechanics because this context is what makes the errors make sense. Midnight uses a protocol called Zswap for shielded token operations. When a user sends tokens to your contract by calling receiveShielded , what actually happens is more involved than it looks on the surface. When your circuit calls receiveShielded(coin) , the Compact runtime records a shielded receive obligation in the transaction being constructed. At this point, the proof server kicks in to generate the ZK proof for your circuit. But here's the thing your circuit only describes what the contract side is doing. The transaction still needs to be balanced : the tokens being received by the contract have to come from somewhere. This is where the wallet gets involved through an internal mechanism that runs beneath your circuit. The wallet looks at the ShieldedCoinInfo you're receiving the coin's color (token type) and value and finds a matching UTXO in the user's private coin set. It then
AI 资讯
Web Scraping with Python in 2026: Best Libraries and Anti-Bot Strategies
Web Scraping with Python in 2026: Best Libraries and Anti-Bot Strategies Web scraping in 2026 looks very different from 2020. Sites are smarter, anti-bot systems are more aggressive, and the legal landscape has evolved. Here's what actually works now. The 2026 Scraping Landscape Challenge 2020 Solution 2026 Solution Bot detection Rotate User-Agent Fingerprint randomization + residential proxies CAPTCHAs Manual solving Turnstile/hCaptcha solvers JavaScript rendering Selenium Playwright (faster, more reliable) Rate limiting Sleep between requests Adaptive pacing + request signing IP blocking VPN rotation Residential proxy pools Best Libraries in 2026 1. Playwright (Best for JS-heavy sites) from playwright.sync_api import sync_playwright def scrape_with_playwright ( url ): with sync_playwright () as p : browser = p . chromium . launch ( headless = True ) page = browser . new_page () page . goto ( url , wait_until = " networkidle " ) data = page . query_selector_all ( " .job-item " ) results = [] for item in data : title = item . query_selector ( " h2 " ). text_content () results . append ( title ) browser . close () return results 2. httpx + Selectolax (Fast, no JS needed) import httpx from selectolax.parser import HTMLParser def scrape_static ( url ): resp = httpx . get ( url , headers = { " User-Agent " : " Mozilla/5.0 " }) tree = HTMLParser ( resp . text ) for node in tree . css ( " .listing " ): print ( node . text ()) 3. API-First Approach (Always check first!) Many sites have hidden or public APIs that make scraping unnecessary: url = " https://www.freelancer.com/api/projects/0.1/projects/active/?query=python " data = httpx . get ( url ). json () Anti-Bot Strategies That Work 1. Request Fingerprint Randomization import random def get_random_headers (): browsers = [ " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " , " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 " , ] return { " User-Agent " : random . choice ( browsers ), " A
AI 资讯
How We Translate 300-Page Books Using Claude Without Hitting Token Limits
Breaking long documents into overlapping chunks, preserving context, and reassembling with FastAPI At LectuLibre, we’ve built an AI‑powered platform that translates entire books—EPUBs and PDFs—using large language models. When we first hooked up Claude’s API, we naively fed it a 300‑page PDF in one request. It failed immediately. Claude 3 Opus has a 200K token window, but a 300‑page book can easily run to 300K tokens or more. Even if we squeezed it in, the output would be truncated and the quality would degrade at the extremes of the context window. So we faced a classic long‑document problem: how do you translate a book that’s larger than the model’s context window? Here’s the real approach we ended up with, the code we wrote, and the lessons we learned. The Problem: Token Limits Are Real Claude 3 Opus and Haiku models (and most LLMs) have a maximum context length—200,000 tokens for Opus. A token is roughly ¾ of a word. A 300‑page novel with ~75,000 words translates to about 100K tokens, so it should fit, right? But translations from English to Spanish can expand by 15–20%, and the prompt instructions, system message, and the user message itself all eat into that budget. Plus, we needed to send the entire source text in every call to give the model full context. That’s not feasible. We could have tried a simple split: cut the book at arbitrary page boundaries and translate piecemeal. That fails spectacularly. Narrative breaks mid‑sentence, and phrases like “the previous chapter” lose their referents. We needed a more intelligent chunking strategy. Our Approach: Sliding Window with Overlapping Paragraphs We settled on a sliding window chunking algorithm based on paragraphs, with a generous overlap. Here’s the idea: Split the source text into paragraphs (using \n\n ). Build chunks of max_chunk_tokens (we used 180,000 to keep a safety margin), adding paragraphs one by one and counting tokens with tiktoken . When the chunk exceeds the limit, we start a new chunk but we
AI 资讯
Build a Minimal WebMCP Agent with Playwright and Gemini
WebMCP lets a web page expose tools that AI agents can discover and execute inside the browser. That...
AI 资讯
Privacy by design: what it is and how to apply it
"Privacy by design" is one of those phrases you read everywhere and rarely understand. It is often treated as a document to attach to a project, a box to tick before going live. In reality it is not a piece of paperwork: it is the way software is conceived and built from the very first line, so that it protects people's data without anyone having to remember to do so afterwards. What the GDPR actually says The principle is written plainly in Article 25 of the GDPR, which speaks of "data protection by design and by default". These are two distinct things. Protection by design concerns the choices made while the system is being built. Protection by default concerns how the system behaves the moment it is switched on, before anyone touches a single setting. The law does not mandate a specific technology. It asks for an outcome: that data protection be built into the system, proportionate to the risks, and not bolted on afterwards as a patch. It is a difference of substance, not of form. A well-designed system does not have to chase compliance: it already has it inside. It is not a document, it is an architecture The most common mistake is to reduce privacy by design to a file. A report is written, filed, and the building goes on exactly as before. But a PDF protects no data. What protects data are the technical decisions: what information is collected, where it is stored, who can see it, how long it stays, what happens when it is no longer needed. These decisions are made at design time, and changing them later costs far more than getting them right at the start. The principles, turned into concrete choices Privacy by design becomes useful only when it stops being a slogan and turns into a series of choices. Translated into practice, the principles sound like this. Minimisation. You collect only the data genuinely needed to deliver the service. A field you do not collect does not need protecting, cannot be lost in a breach, does not need keeping. The safest piece of da
AI 资讯
AnimaStage Lite v1.2.3: Google Play Release, Better Multi-Model Performance & Physics Stability
After several weeks of optimization and community feedback, AnimaStage Lite v1.2.3 is now available. The biggest milestone of this release is that AnimaStage Lite is now available on Google Play, alongside the browser version. 📱 Google Play https://play.google.com/store/apps/details?id=com.webmmd.suite 🌐 Browser https://animastage-lite.app What's new in v1.2.3 📱 Google Play Release AnimaStage Lite is now officially available on Android through Google Play, making it easier to access the editor without manually installing APKs. ⚡ Multi-model performance improvements Working with multiple characters is now much smoother. Improvements include: Performance governor now reacts to the number of visible models. Background characters use a lighter rendering path. When playback is paused, Bullet Physics is simulated only for the selected character. Bullet Physics substeps are capped to improve stability and maintain FPS. 🔄 Physics stability A new Global Physics Stability Registry helps keep simulations more reliable across different scenes. Added: Fix Physics — a soft physics reset that restores the simulation without interrupting the animation timeline. This was implemented after feedback from users who experienced unstable physics when working with multiple models. 🛠 Bug fixes Fixed: SITE_URL is not defined in officialProject.ts General stability improvements Various internal cleanups Project goals AnimaStage Lite is an experimental browser-native MikuMikuDance studio built with WebGL and WASM. Current features include: PMX / PMD support VMD animation playback Bullet Physics Timeline editor MP4 export Browser + Android support The long-term goal is to make MMD creation accessible without requiring a desktop installation. Links 🌐 Website https://animastage-lite.app 📱 Google Play https://play.google.com/store/apps/details?id=com.webmmd.suite 💻 GitHub https://github.com/FBNonaMe/animastage-lite Feedback, bug reports, and feature suggestions are always appreciated. Every relea
AI 资讯
My landing page passed every CI check and was still broken on my customer's phone
A customer texted me a screenshot last month. It was my own landing page, open on their Pixel. The headline — "Financial infrastructure to grow your revenue" — was clipped at "...grow your reven". The signup button below it was gray-on-slightly-lighter-gray, basically unreadable. And the hero image? A broken-image icon. Here's the part that stung: every check I had was green. Lighthouse: 98. My Playwright tests: passing. CI: all checkmarks. I had shipped that page an hour earlier feeling good about it. None of my tooling caught any of it. I want to walk through why , because I think a lot of us have this blind spot, and then I'll tell you what I did about it. CI tests the DOM. It does not test what a human sees. This is the core issue. My tests asserted things like "the signup button exists" and "the form has an email input." All true. The button was in the DOM . It just rendered unreadable on a 412px-wide screen with the system in light mode. Lighthouse runs one viewport (usually a throttled Moto G4 emulation) and scores performance/SEO/a11y heuristically . It does not look at your page across the actual range of devices your visitors use and say "this headline is physically clipped on a Pixel 8." And my "responsive testing"? I was dragging the Chrome devtools responsive bar to two breakpoints — 375 and 1440 — eyeballing it, and moving on. That's not testing. That's hoping. The three bugs that slipped through Let me get specific, because the category of each bug is instructive. 1. The clipped headline — a measurable, deterministic bug .hero-title { white-space : nowrap ; /* the culprit */ width : 100% ; overflow : hidden ; } On desktop, the headline fit. On a narrow viewport, white-space: nowrap refused to wrap, overflow: hidden clipped the overflow, and the last word vanished. The brutal thing: this is trivially detectable in code . The element's scrollWidth was greater than its clientWidth . That's a one-line check: const clipped = el . scrollWidth > el . clientW
AI 资讯
TRON Vanity Address Generator: How to Get a Custom Wallet Address That Stands Out
TRON Vanity Address Generator: How to Get a Custom Wallet Address That Stands Out If you've spent any time in crypto, you've probably noticed that most wallet addresses look like random noise — a string of 34 characters nobody remembers and nobody trusts at a glance. That's exactly the problem vanity addresses solve, and it's exactly what the new tool at tronsec.io/app is built for: generating custom TRON (TRX/USDT-TRC20) addresses that start or end with a sequence you choose. What Is a Vanity Address, Exactly? A vanity address is a regular blockchain wallet address that contains a custom, human-readable pattern — your name, your project's ticker, a lucky number, anything you like — instead of (or alongside) a random string of characters. Technically, nothing about a vanity address is different from any other address. It's generated by the same elliptic curve cryptography as every other TRON wallet. The "vanity" part comes from brute-forcing key pairs until one produces a public address matching your desired pattern. The private key is yours, generated locally, and the math behind it is identical to a standard wallet — there's no special vulnerability baked in just because the address looks nicer. Why Traders and Crypto Projects Actually Use Them It's easy to dismiss vanity addresses as a cosmetic gimmick, but there are real, practical reasons they've become popular in the TRON ecosystem specifically — especially since TRON is the dominant network for USDT transfers. 1. Phishing and typosquat protection. TRON addresses are long Base58 strings. Most users only glance at the first and last few characters before confirming a transfer. Scammers exploit this by generating addresses that look similar to a target address (this is sometimes called address poisoning) and slipping them into transaction history hoping you copy the wrong one. A vanity address with a recognizable prefix — say, your project name or a distinctive token — makes it much harder for a lookalike addres