<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Notes on Technology and Software Development | Kumar Abhishek</title>
<subtitle>A technology blog by Kumar Abhishek. I write about technology and software development.</subtitle>
<link href="https://abhi.am/feed.xml" rel="self"/>
<link href="https://abhi.am/"/>
<updated>2025-04-12T14:53:50Z</updated>
<id>https://abhi.am/</id>
<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
<entry>
	<title>Google’s A2A Protocol and the MCP Paradigm: A New Era of Interoperable AI Agents | Notes</title>
	<link href="https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/" length="27572"/>
	<updated>2025-04-12T14:53:50Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="agentic-ai" scheme="https://abhi.am/notes/tags/" />
	<category term="a2a" scheme="https://abhi.am/notes/tags/" />
	<category term="mcp" scheme="https://abhi.am/notes/tags/" />
	<category term="llm" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">&lt;p&gt;&lt;img src=&quot;https://abhi.am/assets/img/notes/a2a-protocol/a2a_protocol.png&quot;&gt;&lt;/p&gt;&lt;p&gt;Google has recently announced &lt;a href=&quot;https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Agent2Agent&lt;/a&gt; (A2A), a new open protocol for AI systems. What exactly is A2A, and why is it significant for the AI industry? Furthermore, how does it relate to MCP—does it compete with or complement it?&lt;/p&gt;
&lt;h2 id=&quot;what-are-ai-agents-and-agentic-ai&quot; tabindex=&quot;-1&quot;&gt;What Are AI Agents and Agentic AI? &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#what-are-ai-agents-and-agentic-ai&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before diving deep, let’s quickly demystify the terms for those who may not be familiar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI agents&lt;/strong&gt; are software programs powered by large language models or other AI techniques, designed to act autonomously or semi-autonomously to perform specific tasks. Unlike traditional software scripts that follow rigid instructions, agents are more &lt;em&gt;goal-directed&lt;/em&gt; — they interpret intent, make decisions, access tools or APIs, and even communicate with other agents or systems to accomplish their objectives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agentic AI&lt;/strong&gt; refers to this class of AI systems that exhibit characteristics like planning, tool use, memory, and collaboration. It’s the difference between a chatbot that just answers questions and a system that can, say, book a flight by comparing options, checking your calendar, and informing your manager — all by coordinating various subtasks across internal and external services.&lt;/p&gt;
&lt;p&gt;This shift from passive assistants to proactive digital collaborators is what makes agentic AI such a transformative leap in enterprise software.&lt;/p&gt;
&lt;h2 id=&quot;the-need-for-a-common-language-in-agentic-ai&quot; tabindex=&quot;-1&quot;&gt;The Need for a Common Language in Agentic AI &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#the-need-for-a-common-language-in-agentic-ai&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;AI agents are becoming practical co-workers in our digital workplaces. But as these &lt;em&gt;agentic&lt;/em&gt; AI systems proliferate, a new challenge emerges: &lt;strong&gt;how will all these agents talk to each other?&lt;/strong&gt; In a single company you might have one AI assistant for customer support, another analyzing financial data, and yet another managing IT workflows. If each agent lives in a silo, we miss out on huge productivity gains. Agents need a shared language to collaborate across applications and data silos. In other words, interoperability isn’t just a “nice-to-have” – it’s critical for scaling autonomy and avoiding a tangle of one-off integrations.&lt;/p&gt;
&lt;p&gt;To draw an analogy, imagine early computers before networking: powerful on their own, but isolated. It took the &lt;strong&gt;Internet’s common protocols&lt;/strong&gt; (like HTTP and TCP/IP) to unlock collaborative potential among computers. Similarly, AI agents today need their own &lt;strong&gt;“internet of agents”&lt;/strong&gt;. Each agent might be built by different vendors or frameworks, yet to work together they must speak a common protocol. Without open standards, we risk an “agent Babel” where valuable AI workers can’t understand each other. This is why industry leaders are racing to define protocols for agent interoperability; for a future where AI agents seamlessly collaborate regardless of origin.&lt;/p&gt;
&lt;h2 id=&quot;understanding-the-model-context-protocol-mcp-paradigm&quot; tabindex=&quot;-1&quot;&gt;Understanding the Model-Context-Protocol (MCP) Paradigm &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#understanding-the-model-context-protocol-mcp-paradigm&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One pillar of this vision was laid by Anthropic with the &lt;a href=&quot;https://modelcontextprotocol.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;&lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt;&lt;/a&gt;. Think of MCP like a “USB-C port” for AI applications – a standardized plug-and-play interface connecting AI models to tools and data. In technical terms, MCP is an open standard that defines how external context (databases, APIs, file systems, etc.) is provided to language models or AI assistants. It creates a secure two-way channel between an AI &lt;strong&gt;model&lt;/strong&gt; and its operating &lt;strong&gt;context&lt;/strong&gt; — be it company data, third-party services, or user-specific information.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://abhi.am/assets/img/notes/a2a-protocol/mcp.jpg&quot; alt=&quot;MCP architecture&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In the MCP paradigm, an AI agent isn’t an island; it’s a hub that can attach various tools and knowledge sources as &lt;em&gt;context&lt;/em&gt;. For example, using MCP, a chatbot could query a CRM database or execute code via a standardized interface, regardless of who built that database connector. Anthropic’s vision was that by standardizing these interfaces, any large language model (LLM) can access a broad ecosystem of tools in a uniform way. This dramatically simplifies building complex agents: you can “plug in” new capabilities (like a Salesforce connector or a web browser tool) just as easily as plugging a new device into a USB-C port.&lt;/p&gt;
&lt;p&gt;Crucially, MCP focuses on how an AI model &lt;strong&gt;uses tools and data&lt;/strong&gt; – essentially the &lt;strong&gt;Model ↔ Context&lt;/strong&gt; connection. What it doesn’t fully address is how multiple autonomous agents coordinate with each other. That’s where Google’s new protocol comes in, picking up the baton for the &lt;strong&gt;Protocol&lt;/strong&gt; part of the Model-Context-Protocol triad.&lt;/p&gt;
&lt;h2 id=&quot;googles-agent-to-agent-a2a-protocol-http-for-ai-agents&quot; tabindex=&quot;-1&quot;&gt;Google’s Agent-to-Agent (A2A) Protocol: HTTP for AI Agents &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#googles-agent-to-agent-a2a-protocol-http-for-ai-agents&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Enter &lt;a href=&quot;https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;&lt;strong&gt;Agent-to-Agent (A2A)&lt;/strong&gt;&lt;/a&gt;, Google’s newly released open protocol that fills the gap by standardizing how AI agents &lt;strong&gt;communicate with one another&lt;/strong&gt;. A2A is exactly what it sounds like — a common language for agents to send messages, share information, and even delegate tasks amongst themselves. Just as HTTP enabled any web browser to talk to any web server, A2A promises that an agent built on Framework X can request help from an agent built on Framework Y, as long as both speak A2A.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://abhi.am/assets/img/notes/a2a-protocol/a2a_mcp_readme.png&quot; alt=&quot;Google’s A2A protocol architecture&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Image Credit: &lt;a href=&quot;https://google.github.io/A2A&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;https://google.github.io/A2A&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What A2A Does:&lt;/strong&gt; According to &lt;a href=&quot;https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Google’s announcement&lt;/a&gt;, A2A enables agents to &lt;strong&gt;discover&lt;/strong&gt; each other, &lt;strong&gt;communicate&lt;/strong&gt; securely, and &lt;strong&gt;coordinate actions&lt;/strong&gt; across different services and platforms. In practice, an agent makes itself discoverable by publishing a simple profile (a “public card”) over HTTP describing where it lives, what version it is, and what skills or APIs it offers. Think of this like an agent business card. Another agent can find this card and know how to talk to that agent – its location (URL), capabilities, and supported interaction patterns.&lt;/p&gt;
&lt;p&gt;Critically, A2A doesn’t reinvent the wheel but builds on familiar web standards. The protocol leverages HTTP for requests, Server-Sent Events (SSE) for real-time updates, and JSON-RPC for structured calls. This means developers can integrate it into existing IT stacks with relative ease – your agents communicate over the same web technologies your apps already use. A2A supports different communication modes depending on the task: for quick back-and-forth it can use request/response or SSE streaming, and for long-running tasks it allows asynchronous workflows where one agent notifies another upon completion. In essence, it’s giving agents flexible “communication etiquette” suitable for everything from a brief question to an hours-long project hand-off.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Complements, Not Competes, with MCP:&lt;/strong&gt; Google was careful to position A2A as &lt;strong&gt;complementary&lt;/strong&gt; to Anthropic’s MCP, not a competing standard. The two protocols address different layers of the agent ecosystem. Recall our paradigm: &lt;strong&gt;Model, Context, Protocol&lt;/strong&gt;. MCP standardizes how an agent (the model) fetches and leverages external tools/data (context). A2A standardizes how agents engage in dialogues and collaborations with each other (protocol). As Google’s blog put it, “A2A is an open protocol that complements Anthropic’s MCP, which provides helpful tools and context to agents”. You can imagine a future AI platform where MCP-enabled tool integrations and A2A-enabled agent conversations work in tandem to achieve complex tasks.&lt;/p&gt;
&lt;p&gt;To make this concrete, Google’s documentation gives a great example of an auto repair shop scenario. In the shop, each mechanic is assisted by an AI agent with specialized tools: one agent can control a car lift or wrench via &lt;em&gt;MCP&lt;/em&gt; (structured tool APIs). Now, when a customer arrives describing a rattle noise, multiple agents (the “employees”) need to collaborate: the diagnostics agent asks the inspection agent to take a photo of the wheel, then an ordering agent might contact a supplier agent to get a replacement part. All of this &lt;strong&gt;agent-to-agent dialogue&lt;/strong&gt; – receiving the customer’s problem, asking follow-up questions (“How long has it been leaking?”), sharing findings, dividing tasks – is handled by &lt;em&gt;A2A&lt;/em&gt;. Meanwhile, whenever an agent needs to use a specific tool (like adjusting the lift or querying inventory), that interaction runs through &lt;em&gt;MCP&lt;/em&gt;. In short, &lt;strong&gt;MCP is for plugging an agent into its tools, whereas A2A is for plugging agents into each other&lt;/strong&gt;. Together, they enable a multi-agent workflow greater than the sum of its parts.&lt;/p&gt;
&lt;h2 id=&quot;why-interoperability-is-critical-and-inevitable&quot; tabindex=&quot;-1&quot;&gt;Why Interoperability Is Critical (and Inevitable) &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#why-interoperability-is-critical-and-inevitable&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;From my perspective as a fintech technology and product architect, the rise of open agent protocols feels reminiscent of the fintech API revolution. In banking, we saw how standard interfaces (think &lt;strong&gt;open banking APIs&lt;/strong&gt; or India’s UPI) unlocked innovation by letting disparate systems work together securely. Before UPI, each bank had its own payment interface – today, any app can transact with any bank through a unified protocol, spurring an explosion of fintech creativity. &lt;strong&gt;Agentic AI is at a similar crossroads&lt;/strong&gt;: without interoperability, we’ll end up with walled gardens of AI agents that can’t leverage each other’s strengths. With interoperability, we enable an “open market” of AI services that can freely mix-and-match to solve problems.&lt;/p&gt;
&lt;p&gt;Open standards also future-proof architectures. Enterprise tech history teaches us that proprietary integrations eventually yield to standardized ones – because standards lower the integration cost for everyone. A2A’s design, in fact, was driven by enterprise needs: companies don’t want to be locked into a single vendor’s agent ecosystem. Google launched A2A with support from &lt;strong&gt;50+ tech partners across the industry&lt;/strong&gt; (from Atlassian and Salesforce to Oracle and Infosys), reflecting a broad consensus that no one company will build &lt;em&gt;all&lt;/em&gt; the best agents. Interoperability ensures you can deploy the best-in-class AI agents for each job and have them cooperate seamlessly. As the Google Cloud team put it, A2A gives your agents a “common, open language to collaborate – no matter which framework or vendor they are built on”. This universality is essential for businesses that run diverse applications across cloud environments.&lt;/p&gt;
&lt;p&gt;There’s also an open-source ecosystem angle. An open protocol like A2A means that &lt;em&gt;community-built agents&lt;/em&gt; and big enterprise agents can speak the same lingo. This breaks down the wall between proprietary enterprise AI and open-source AI projects. A startup or OSS project can focus on a niche agent (say, an expert code-debugger agent) and still plug it into a larger enterprise workflow via A2A. Likewise, an enterprise can benefit from community contributions without heavy custom integration. Open standards tend to create rich ecosystems: we saw this with HTTP (browsers, servers, RESTful APIs) and we’re likely to see it here. In the words of one analysis, protocols don’t just enable communication – &lt;strong&gt;they shape who builds what and how fast the ecosystem grows&lt;/strong&gt;. By defining a clear contract for agent interaction, A2A lowers the barrier to entry for new agents and tools to join the party, whether developed by a tech giant or a lone developer.&lt;/p&gt;
&lt;h2 id=&quot;a-quick-javascript-demo-agents-talking-via-a2a&quot; tabindex=&quot;-1&quot;&gt;A Quick JavaScript Demo: Agents Talking via A2A &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#a-quick-javascript-demo-agents-talking-via-a2a&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To illustrate how an agent might use A2A in practice, let’s consider a simplified JavaScript example. Suppose we have two agents: &lt;strong&gt;OrderAgent&lt;/strong&gt; (handles orders) and &lt;strong&gt;InventoryAgent&lt;/strong&gt; (manages stock levels). Each agent exposes an HTTP endpoint and a “card” describing its capabilities. Here’s a conceptual snippet demonstrating how one agent could discover another’s card and send a task request:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Example agent &quot;card&quot; for the InventoryAgent (discovery metadata)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; inventoryAgentCard &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;InventoryAgent&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.example.com/agents/inventory&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// base URL for agent&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;skills&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;checkStock&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;reserveItem&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;updateStock&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// capabilities offered&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Discovered agent card:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inventoryAgentCard&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// OrderAgent wants to ask InventoryAgent to reserve an item&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;requestAgentTask&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;agentCard&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; params&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;agentCard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;endpoint&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;action&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// e.g. https://.../reserveItem&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;params&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// parse the JSON result from InventoryAgent&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Usage: OrderAgent reserving a laptop through InventoryAgent&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;requestAgentTask&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inventoryAgentCard&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;reserveItem&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;itemId&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Laptop-123&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Task result:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this snippet, the &lt;strong&gt;OrderAgent&lt;/strong&gt; first retrieves the &lt;strong&gt;InventoryAgent&lt;/strong&gt;’s card (which could be via a known registry or URL). The card tells us the InventoryAgent’s endpoint and what actions (&lt;code&gt;skills&lt;/code&gt;) it supports. Then &lt;code&gt;requestAgentTask&lt;/code&gt; constructs an HTTP POST to the InventoryAgent’s &lt;code&gt;reserveItem&lt;/code&gt; action. The response (perhaps a confirmation or error) comes back as JSON.&lt;/p&gt;
&lt;p&gt;This is a simplistic view, but it aligns with A2A’s fundamentals: agents expose endpoints for their skills, accept structured requests, and return results in a standard format. In a real A2A scenario, there would likely be authentication, error handling, and possibly asynchronous patterns (e.g. the request might immediately return a task ID and the InventoryAgent later pushes the completion result via callback or webhook). The key point is that with A2A, both agents adhere to a common &lt;strong&gt;contract&lt;/strong&gt; for requests and responses. A developer could swap out either agent with a different implementation (another vendor or an open-source agent) and as long as it speaks A2A, the interaction will still work. This loose coupling is exactly what we want for scalable, modular AI systems.&lt;/p&gt;
&lt;h2 id=&quot;how-does-a2a-compare-to-other-agent-frameworks&quot; tabindex=&quot;-1&quot;&gt;How Does A2A Compare to Other Agent Frameworks? &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#how-does-a2a-compare-to-other-agent-frameworks&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It’s important to distinguish A2A – an interoperability &lt;strong&gt;protocol&lt;/strong&gt; – from the many &lt;strong&gt;frameworks&lt;/strong&gt; that help build AI agents. In recent months we’ve seen a proliferation of agent frameworks and orchestration tools: Microsoft’s &lt;strong&gt;AutoGen&lt;/strong&gt;, the open-source &lt;strong&gt;OpenAgents&lt;/strong&gt; platform, LangChain’s &lt;strong&gt;LangGraph&lt;/strong&gt;, OpenAI’s tools/plug-ins, and more.&lt;/p&gt;
&lt;p&gt;These tools often work best within their own ecosystems or within the boundaries of a single application context. &lt;strong&gt;A2A&lt;/strong&gt;, on the other hand, introduces a &lt;strong&gt;common communication layer&lt;/strong&gt; that enables &lt;strong&gt;cross-platform, cross-framework agent interaction&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AutoGen&lt;/strong&gt; provides a powerful multi-agent conversation framework in Python, but the agents typically operate within a predefined local environment. A2A allows those same agents to interface with external agents or services built using completely different tech stacks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangGraph&lt;/strong&gt; brings structured orchestration and control over agent workflows. A2A could enhance it by allowing dynamic runtime collaboration with agents outside the graph.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenAgents&lt;/strong&gt; simplifies deploying specialized agents but lacks built-in multi-agent collaboration support. With A2A, these agents can now communicate and delegate tasks to each other or external services.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In short, these frameworks are great for building agent capabilities and control flows. &lt;strong&gt;A2A is what helps those agents participate in a larger ecosystem&lt;/strong&gt;. It doesn’t replace these tools—it &lt;strong&gt;amplifies&lt;/strong&gt; them by enabling them to speak a shared protocol.&lt;/p&gt;
&lt;h2 id=&quot;from-fintech-architecture-to-ai-agents-my-take&quot; tabindex=&quot;-1&quot;&gt;From Fintech Architecture to AI Agents: My Take &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#from-fintech-architecture-to-ai-agents-my-take&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As a &lt;strong&gt;technology architect and developer&lt;/strong&gt; at Eko, where I’ve spent over a decade building low-code, extensible, and framework-driven applications &amp;amp; SaaS platforms for Fintech, we’re now applying similar architectural principles to AI. We have already been actively &lt;strong&gt;experimenting with the Model-Context-Protocol (MCP)&lt;/strong&gt; to bring agentic AI into real-world business workflows.&lt;/p&gt;
&lt;p&gt;MCP has helped us decouple tools and services from specific models or agent frameworks. Instead of binding a feature tightly to OpenAI or Anthropic or LangChain, we expose capabilities as &lt;strong&gt;reusable context interfaces&lt;/strong&gt; that any compliant agent can access. This means we can test different LLMs or orchestrators side-by-side without rewriting business logic.&lt;/p&gt;
&lt;p&gt;Interoperability protocols like MCP are helping us think beyond single-model capabilities. They’re laying the groundwork for a &lt;strong&gt;multi-agent, multi-model infrastructure&lt;/strong&gt; that’s both future-proof and enterprise-ready.&lt;/p&gt;
&lt;p&gt;From this vantage point, the emergence of open agent protocols like A2A and MCP feels very familiar. In fintech, we’ve seen how &lt;strong&gt;common protocols unlock ecosystems&lt;/strong&gt;—UPI and open banking APIs are prime examples. When standards emerge, innovation accelerates. When they don’t, systems remain isolated and integration becomes costly. We’re witnessing a similar tipping point in AI.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#conclusion&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We’re entering a new era where AI agents will become foundational to how software operates and scales. But just like APIs enabled the SaaS explosion, open protocols like &lt;strong&gt;A2A&lt;/strong&gt; and &lt;strong&gt;MCP&lt;/strong&gt; will be essential to unlock agent-driven ecosystems.&lt;/p&gt;
&lt;p&gt;These protocols make agents modular, interoperable, and composable—qualities every modern software architecture needs. They also create opportunities for businesses to innovate faster and for developers to build once and integrate everywhere.&lt;/p&gt;
&lt;p&gt;If you’re building the future of intelligent systems, now’s the time to embrace standards that ensure your agents don’t just work—they work together.&lt;/p&gt;
&lt;h2 id=&quot;references&quot; tabindex=&quot;-1&quot;&gt;References &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/#references&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/A2A&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;https://github.com/google/A2A&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.koyeb.com/blog/a2a-and-mcp-start-of-the-ai-agent-protocol-wars&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;https://www.koyeb.com/blog/a2a-and-mcp-start-of-the-ai-agent-protocol-wars&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://modelcontextprotocol.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;https://modelcontextprotocol.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/agents/model-context-protocol&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;https://developers.cloudflare.com/agents/model-context-protocol&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/a2a-protocol-and-mcp-interoperable-ai-agents/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>TanStack Router – A Routing Library for TypeScript Applications | Notes</title>
	<link href="https://abhi.am/notes/tanstack-router-intro/" length="3576"/>
	<updated>2022-12-21T07:38:37Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="typescript" scheme="https://abhi.am/notes/tags/" />
	<category term="library" scheme="https://abhi.am/notes/tags/" />
	<category term="react" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/tanstack-router-intro/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">&lt;blockquote&gt;
&lt;p&gt;A fully typesafe router with first-class search-param APIs and built-in caching, built for JS/TS, React, Preact, Solid, Vue and Svelte.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you’re a fan of TypeScript, you’ll be excited to hear about &lt;a href=&quot;https://tanstack.com/router/v1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;&lt;strong&gt;TanStack Router&lt;/strong&gt;&lt;/a&gt;, a fully type-safe routing library for TypeScript applications.&lt;/p&gt;
&lt;p&gt;Potential advantages of using TanStack Router:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Type safety&lt;/code&gt; for routes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Autocomplete&lt;/code&gt; suggestions for routes.&lt;/li&gt;
&lt;li&gt;First-class &lt;code&gt;search parameter support&lt;/code&gt;: useful for storing state in a URL and sharing links.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Improved reliability&lt;/code&gt; by ensuring that routes are correctly defined and used.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;problem-with-routing&quot; tabindex=&quot;-1&quot;&gt;Problem with routing &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/tanstack-router-intro/#problem-with-routing&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One of the challenges with routing in any language is that routes are often defined in one place (e.g. a config file or a page-based system like React Router) and used in another (e.g. links in pages, redirects). This means that if you change a route in one place, you have to manually update it in all the other places where it’s used. This can lead to bugs and broken routing if you miss a change or misspell a route.&lt;/p&gt;
&lt;h3 id=&quot;type-safety-to-the-recue&quot; tabindex=&quot;-1&quot;&gt;Type-safety to the recue! &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/tanstack-router-intro/#type-safety-to-the-recue&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;TanStack Router aims to solve this problem by providing type safety for routes. This means that the router is aware of all the different routes in your application, and it can give you &lt;strong&gt;autocomplete suggestions&lt;/strong&gt; and flag errors if you misspell or use incorrect information for a route. This makes writing routes much easier and helps prevent issues with broken routing.&lt;/p&gt;
&lt;h3 id=&quot;support-for-search-parameters&quot; tabindex=&quot;-1&quot;&gt;Support for Search Parameters &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/tanstack-router-intro/#support-for-search-parameters&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;TanStack Router also has &lt;strong&gt;first-class support for search parameters&lt;/strong&gt;, which can be used to store state in a URL and share links. This can be particularly useful if you prefer to use search params over state variables for storing application state.&lt;/p&gt;
&lt;h3 id=&quot;other-features&quot; tabindex=&quot;-1&quot;&gt;Other Features &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/tanstack-router-intro/#other-features&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;100% Typesafe&lt;/li&gt;
&lt;li&gt;Built-in Caching&lt;/li&gt;
&lt;li&gt;1st-class Search Param APIs&lt;/li&gt;
&lt;li&gt;Nested/Layout Routes&lt;/li&gt;
&lt;li&gt;Lightweight (10kb)&lt;/li&gt;
&lt;li&gt;Parallel Route Loaders&lt;/li&gt;
&lt;li&gt;Route Actions&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tanstack.com/router/v1/docs/comparison&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;&lt;em&gt;and more…&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/tanstack-router-intro/#conclusion&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While TanStack Router &lt;em&gt;&lt;strong&gt;is still in beta&lt;/strong&gt;&lt;/em&gt;, it shows a lot of promise for improving the routing process in TypeScript applications. If you’re interested in giving it a try, be aware that there are currently some missing features and documentation, and the syntax is subject to change. However, the 100% TypeScript support and type safety make it worth keeping an eye on as it continues to develop.&lt;/p&gt;
&lt;h3 id=&quot;credits&quot; tabindex=&quot;-1&quot;&gt;Credits &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/tanstack-router-intro/#credits&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Youtube video: &lt;a href=&quot;https://youtu.be/OwoZtv6u9p4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;What Is TenStack Router And Why I Love It&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/tanstack-router-intro/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>Fix WSL2 Connection Issue to Docker Daemon | Notes</title>
	<link href="https://abhi.am/notes/fix-wsl2-connection-issue-to-docker-daemon/" length="1946"/>
	<updated>2021-07-17T18:38:15Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="wsl2" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/fix-wsl2-connection-issue-to-docker-daemon/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">&lt;p&gt;Recently while setting up docker for Hyperledger in WSL2, I got the following error:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; hyperledger/fabric-peer:2.3.2&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;Cannot connect to the Docker daemon at tcp://localhost:2375. Is the &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; daemon running?&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After a quick research, it turns out that if you are upgrading from WSL1 to WSL2, Windows leaves behind a few legacy settings from WSL1 that causes this issue.&lt;/p&gt;
&lt;p&gt;Here is the fix that worked for me:&lt;/p&gt;
&lt;h3 id=&quot;step-1-check-if-you-have-the-same-issue&quot; tabindex=&quot;-1&quot;&gt;Step 1: Check if you have the same issue &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/fix-wsl2-connection-issue-to-docker-daemon/#step-1-check-if-you-have-the-same-issue&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;In WSL2 terminal, run the command: &lt;code&gt;docker info | head -15&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;You should see the following error: &lt;code&gt;ERROR: Cannot connect to the Docker daemon at tcp://localhost:2375. Is the docker daemon running?&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-2-check-if-the-fix-works-for-you&quot; tabindex=&quot;-1&quot;&gt;Step 2: Check if the fix works for you &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/fix-wsl2-connection-issue-to-docker-daemon/#step-2-check-if-the-fix-works-for-you&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Run the command: &lt;code&gt;unset DOCKER_HOST&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Follow the previous step again. The error should be gone now.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-3-make-the-fix-permanent&quot; tabindex=&quot;-1&quot;&gt;Step 3: Make the fix permanent &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/fix-wsl2-connection-issue-to-docker-daemon/#step-3-make-the-fix-permanent&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Edit the &lt;code&gt;.bashrc&lt;/code&gt; script with: &lt;code&gt;vi ~/.bashrc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Search for the line with DOCKER_HOST and comment it out like this:&lt;br /&gt;
&lt;code&gt;# export DOCKER_HOST=tcp://localhost:2375&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save the file and reload the terminal settings with: &lt;code&gt;source ~/.bashrc&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/fix-wsl2-connection-issue-to-docker-daemon/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>Set &amp; persist Google DNS server in WSL2 | Notes</title>
	<link href="https://abhi.am/notes/set-persist-google-dns-server-in-wsl2/" length="840"/>
	<updated>2021-07-10T08:15:48Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="wsl2" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/set-persist-google-dns-server-in-wsl2/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">&lt;p&gt;Here is how you setup an alternative DNS server (like. Google DNS) on WSL2 and persist it between  WSL restart:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create the WSL config file (if it does not already exist): &lt;code&gt;/etc/wsl.conf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Enter the following lines to preserve the DNS config between restarts:&lt;pre&gt;&lt;code&gt;[network]
generateResolvConf = false
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Shutdown WSL and start again by running the following command in Windows terminal: &lt;code&gt;wsl --shutdown&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Edit (or, create) the file &lt;code&gt;/etc/resolv.conf&lt;/code&gt;:
&lt;ol&gt;
&lt;li&gt;Comment any other line that starts with “nameserver”.&lt;/li&gt;
&lt;li&gt;Enter the following lines:&lt;pre&gt;&lt;code&gt;nameserver 8.8.4.4
nameserver 8.8.8.8
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Restart WSL again after running the following command in Windows terminal: &lt;code&gt;wsl --shutdown&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/set-persist-google-dns-server-in-wsl2/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>Study Notes on Ethereum Virtual Machine (EVM) - The Basics | Notes</title>
	<link href="https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/" length="17399"/>
	<updated>2021-05-29T06:24:39Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="ethereum" scheme="https://abhi.am/notes/tags/" />
	<category term="blockchain" scheme="https://abhi.am/notes/tags/" />
	<category term="solidity" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">
	&lt;blockquote&gt;&lt;strong&gt;Direct Links:&lt;/strong&gt;
	&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://docs.soliditylang.org/en/v0.8.4/introduction-to-smart-contracts.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;docs.soliditylang.org/en/v0.8.4/introduction-to-smart-contracts.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
	&lt;/blockquote&gt;&lt;nav class=&quot;table-of-contents&quot;&gt;&lt;ol&gt;&lt;li&gt;&lt;a class=&quot;toc_link&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#ethereum-accounts&quot;&gt;Ethereum Accounts &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class=&quot;toc_link&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#ethereum-transactions&quot;&gt;Ethereum Transactions &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class=&quot;toc_link&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#gas&quot;&gt;Gas &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class=&quot;toc_link&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#storage-memory-and-the-stack&quot;&gt;Storage, Memory, and the Stack &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class=&quot;toc_link&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#message-calls&quot;&gt;Message Calls &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class=&quot;toc_link&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#delegatecall-callcode-and-libraries&quot;&gt;Delegatecall / Callcode and Libraries &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class=&quot;toc_link&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#logs&quot;&gt;Logs &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class=&quot;toc_link&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#create&quot;&gt;Create &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class=&quot;toc_link&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#deactivate-and-self-destruct&quot;&gt;Deactivate and Self-destruct &lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/nav&gt;&lt;h2 id=&quot;ethereum-accounts&quot; tabindex=&quot;-1&quot;&gt;Ethereum Accounts &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#ethereum-accounts&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;There are two types of Ethereum accounts:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;External Accounts&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Users&lt;/li&gt;
&lt;li&gt;Address = public key&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contract Accounts&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Smart Contracts (code)&lt;/li&gt;
&lt;li&gt;Address generated when the contract is created (it is derived from the creator address and the number of transactions sent from that address, the so-called “nonce”).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;EVM treats both types of accounts equally.&lt;/li&gt;
&lt;li&gt;Every account has a persistent key-value store mapping 256-bit words to 256-bit words called storage.&lt;/li&gt;
&lt;li&gt;Every account has a balance in Ether (in “Wei” to be exact, 1 ether is 10**18 wei) which can be modified by sending transactions that include Ether.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ethereum-transactions&quot; tabindex=&quot;-1&quot;&gt;Ethereum Transactions &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#ethereum-transactions&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Message that is sent from one account to another account (which might be the same or empty).&lt;/li&gt;
&lt;li&gt;It can include binary data (&lt;strong&gt;payload&lt;/strong&gt;) and Ether.&lt;/li&gt;
&lt;li&gt;If the target account contains code, that code is executed and the payload is provided as input data.&lt;/li&gt;
&lt;li&gt;If the &lt;em&gt;target account is not set&lt;/em&gt; (the transaction does not have a recipient or the recipient is set to null), the transaction &lt;em&gt;&lt;strong&gt;creates a new contract&lt;/strong&gt;&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;the address of that contract is not the zero address, but an address derived from the sender and its number of transactions sent (the “nonce”).&lt;/li&gt;
&lt;li&gt;The payload of such a contract creation transaction is taken to be EVM bytecode and executed.&lt;/li&gt;
&lt;li&gt;The output data of this execution is permanently stored as the code of the contract.&lt;/li&gt;
&lt;li&gt;This means that in order to create a contract, you do not send the actual code of the contract, but in fact code that returns that code when executed.&lt;/li&gt;
&lt;li&gt;⚠ While a contract is being created, its code is still empty. Because of that, you should not call back into the contract under construction until its constructor has finished executing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;gas&quot; tabindex=&quot;-1&quot;&gt;Gas &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#gas&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Gas price is set by the creator of the transaction.
&lt;ul&gt;
&lt;li&gt;They have to pay &lt;code&gt;gas_price * gas&lt;/code&gt; upfront from the sending account.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Any remaining gas after execution is refunded back to the sender account.&lt;/li&gt;
&lt;li&gt;If all gas is used up before the transaction is complete, an &lt;em&gt;out-of-gas&lt;/em&gt; exception is triggered and all modifications to the state are reverted.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;storage-memory-and-the-stack&quot; tabindex=&quot;-1&quot;&gt;Storage, Memory, and the Stack &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#storage-memory-and-the-stack&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;nomnoml&quot;&gt;&lt;svg version=&quot;1.1&quot; baseProfile=&quot;full&quot; width=&quot;456.0&quot; height=&quot;464.0&quot; viewBox=&quot;0 0 456 464&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; xmlns:ev=&quot;http://www.w3.org/2001/xml-events&quot;&gt;
&lt;desc&gt;
#background: #FDF6E3
#stroke: #33322E
#direction: down
[EVM
[Non-Volatile
[&amp;lt;frame&amp;gt; ROM | code]
[&amp;lt;frame&amp;gt; RAM | storage]
]--[Volatile
[&amp;lt;database&amp;gt; stack]
[&amp;lt;frame&amp;gt; ROM | args]
[&amp;lt;frame&amp;gt; RAM | memory]
]
]
&lt;/desc&gt;
&lt;g stroke-width=&quot;1.0&quot; text-align=&quot;left&quot; font=&quot;12pt Helvetica, Arial, sans-serif&quot; font-size=&quot;12pt&quot; font-family=&quot;Helvetica&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot;&gt;
&lt;g font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;bold&quot; font-style=&quot;normal&quot; stroke-width=&quot;3.0&quot; stroke-linejoin=&quot;round&quot; stroke-linecap=&quot;round&quot; stroke=&quot;#33322E&quot;&gt;
&lt;g stroke=&quot;transparent&quot; fill=&quot;#FDF6E3&quot;&gt;
&lt;rect x=&quot;0.0&quot; y=&quot;0.0&quot; height=&quot;464.0&quot; width=&quot;456.0&quot; stroke=&quot;none&quot;&gt;&lt;/rect&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot;&gt;
&lt;g transform=&quot;translate(20, 20)&quot;&gt;
&lt;g data-name=&quot;EVM&quot;&gt;
&lt;g fill=&quot;#eee8d5&quot; stroke=&quot;#33322E&quot; data-name=&quot;EVM&quot;&gt;
&lt;rect x=&quot;0.0&quot; y=&quot;0.0&quot; height=&quot;408.0&quot; width=&quot;400.0&quot; data-name=&quot;EVM&quot;&gt;&lt;/rect&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(0, 0)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;bold&quot; font-style=&quot;normal&quot; data-name=&quot;EVM&quot; data-compartment=&quot;0&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;center&quot; data-name=&quot;EVM&quot; data-compartment=&quot;0&quot;&gt;
&lt;text x=&quot;192.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; text-anchor=&quot;middle&quot; data-name=&quot;EVM&quot; data-compartment=&quot;0&quot;&gt;EVM&lt;/text&gt;
&lt;g transform=&quot;translate(20, 20)&quot; fill=&quot;#33322E&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot; data-name=&quot;EVM&quot; data-compartment=&quot;0&quot;&gt;
&lt;g stroke-dasharray=&quot;6 6&quot; data-name=&quot;EVM&quot; data-compartment=&quot;0&quot;&gt;
&lt;path d=&quot;M172.0 144.0 L172 164 L172 184 L172.0 184.0 &quot; fill=&quot;none&quot; data-name=&quot;EVM&quot; data-compartment=&quot;0&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;g data-name=&quot;Non-Volatile&quot;&gt;
&lt;g fill=&quot;#fdf6e3&quot; stroke=&quot;#33322E&quot; data-name=&quot;Non-Volatile&quot;&gt;
&lt;rect x=&quot;50.5&quot; y=&quot;0.0&quot; height=&quot;144.0&quot; width=&quot;243.0&quot; data-name=&quot;Non-Volatile&quot;&gt;&lt;/rect&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(50.5, 0)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;bold&quot; font-style=&quot;normal&quot; data-name=&quot;Non-Volatile&quot; data-compartment=&quot;0&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;center&quot; data-name=&quot;Non-Volatile&quot; data-compartment=&quot;0&quot;&gt;
&lt;text x=&quot;113.5&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; text-anchor=&quot;middle&quot; data-name=&quot;Non-Volatile&quot; data-compartment=&quot;0&quot;&gt;Non-Volatile&lt;/text&gt;
&lt;g transform=&quot;translate(20, 20)&quot; data-name=&quot;Non-Volatile&quot; data-compartment=&quot;0&quot;&gt;
&lt;g data-name=&quot;ROM&quot;&gt;
&lt;g fill=&quot;#eee8d5&quot; stroke=&quot;#33322E&quot; data-name=&quot;ROM&quot;&gt;
&lt;rect x=&quot;0.0&quot; y=&quot;0.0&quot; height=&quot;64.0&quot; width=&quot;71.0&quot; data-name=&quot;ROM&quot;&gt;&lt;/rect&gt;
&lt;path d=&quot;M0.0 32.0 L47.0 32.0 L63.0 16.0 L63.0 0.0&quot; fill=&quot;none&quot; data-name=&quot;ROM&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(0, 0)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot; data-name=&quot;ROM&quot; data-compartment=&quot;0&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;left&quot; data-name=&quot;ROM&quot; data-compartment=&quot;0&quot;&gt;
&lt;text x=&quot;0.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; data-name=&quot;ROM&quot; data-compartment=&quot;0&quot;&gt;ROM&lt;/text&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(0, 32)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot; data-name=&quot;ROM&quot; data-compartment=&quot;1&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;left&quot; data-name=&quot;ROM&quot; data-compartment=&quot;1&quot;&gt;
&lt;text x=&quot;0.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; data-name=&quot;ROM&quot; data-compartment=&quot;1&quot;&gt;code&lt;/text&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g data-name=&quot;RAM&quot;&gt;
&lt;g fill=&quot;#eee8d5&quot; stroke=&quot;#33322E&quot; data-name=&quot;RAM&quot;&gt;
&lt;rect x=&quot;111.0&quot; y=&quot;0.0&quot; height=&quot;64.0&quot; width=&quot;76.0&quot; data-name=&quot;RAM&quot;&gt;&lt;/rect&gt;
&lt;path d=&quot;M111.0 32.0 L156.0 32.0 L172.0 16.0 L172.0 0.0&quot; fill=&quot;none&quot; data-name=&quot;RAM&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(111, 0)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot; data-name=&quot;RAM&quot; data-compartment=&quot;0&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;left&quot; data-name=&quot;RAM&quot; data-compartment=&quot;0&quot;&gt;
&lt;text x=&quot;0.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; data-name=&quot;RAM&quot; data-compartment=&quot;0&quot;&gt;RAM&lt;/text&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(111, 32)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot; data-name=&quot;RAM&quot; data-compartment=&quot;1&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;left&quot; data-name=&quot;RAM&quot; data-compartment=&quot;1&quot;&gt;
&lt;text x=&quot;0.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; data-name=&quot;RAM&quot; data-compartment=&quot;1&quot;&gt;storage&lt;/text&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g data-name=&quot;Volatile&quot;&gt;
&lt;g fill=&quot;#fdf6e3&quot; stroke=&quot;#33322E&quot; data-name=&quot;Volatile&quot;&gt;
&lt;rect x=&quot;0.0&quot; y=&quot;184.0&quot; height=&quot;144.0&quot; width=&quot;344.0&quot; data-name=&quot;Volatile&quot;&gt;&lt;/rect&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(0, 184)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;bold&quot; font-style=&quot;normal&quot; data-name=&quot;Volatile&quot; data-compartment=&quot;0&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;center&quot; data-name=&quot;Volatile&quot; data-compartment=&quot;0&quot;&gt;
&lt;text x=&quot;164.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; text-anchor=&quot;middle&quot; data-name=&quot;Volatile&quot; data-compartment=&quot;0&quot;&gt;Volatile&lt;/text&gt;
&lt;g transform=&quot;translate(20, 20)&quot; data-name=&quot;Volatile&quot; data-compartment=&quot;0&quot;&gt;
&lt;g data-name=&quot;stack&quot;&gt;
&lt;g fill=&quot;#eee8d5&quot; stroke=&quot;#33322E&quot; data-name=&quot;stack&quot;&gt;
&lt;rect x=&quot;0.0&quot; y=&quot;16.0&quot; height=&quot;32.0&quot; width=&quot;58.0&quot; stroke=&quot;none&quot; data-name=&quot;stack&quot;&gt;&lt;/rect&gt;
&lt;path d=&quot;M0.0 16.0 L0.0 48.0&quot; fill=&quot;none&quot; data-name=&quot;stack&quot;&gt;&lt;/path&gt;
&lt;path d=&quot;M58.0 16.0 L58.0 48.0&quot; fill=&quot;none&quot; data-name=&quot;stack&quot;&gt;&lt;/path&gt;
&lt;ellipse cx=&quot;29.0&quot; cy=&quot;16.0&quot; rx=&quot;29.0&quot; ry=&quot;6.0&quot; data-name=&quot;stack&quot;&gt;&lt;/ellipse&gt;
&lt;path d=&quot;M58.0 48.0 L58.0 48.3 L57.9 48.6 L57.7 48.9 L57.4 49.2 L57.1 49.5 L56.7 49.8 L56.3 50.1 L55.7 50.3 L55.1 50.6 L54.5 50.9 L53.7 51.1 L53.0 51.4 L52.1 51.6 L51.2 51.9 L50.3 52.1 L49.2 52.3 L48.2 52.5 L47.1 52.7 L45.9 52.9 L44.7 53.0 L43.5 53.2 L42.2 53.3 L40.9 53.5 L39.6 53.6 L38.2 53.7 L36.9 53.8 L35.5 53.8 L34.0 53.9 L32.6 54.0 L31.2 54.0 L29.7 54.0 L28.3 54.0 L26.8 54.0 L25.4 54.0 L24.0 53.9 L22.5 53.8 L21.1 53.8 L19.8 53.7 L18.4 53.6 L17.1 53.5 L15.8 53.3 L14.5 53.2 L13.3 53.0 L12.1 52.9 L10.9 52.7 L9.8 52.5 L8.8 52.3 L7.7 52.1 L6.8 51.9 L5.9 51.6 L5.0 51.4 L4.3 51.1 L3.5 50.9 L2.9 50.6 L2.3 50.3 L1.7 50.1 L1.3 49.8 L0.9 49.5 L0.6 49.2 L0.3 48.9 L0.1 48.6 L0.0 48.3 L0.0 48.0&quot; data-name=&quot;stack&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(0, 20)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;bold&quot; font-style=&quot;normal&quot; data-name=&quot;stack&quot; data-compartment=&quot;0&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;center&quot; data-name=&quot;stack&quot; data-compartment=&quot;0&quot;&gt;
&lt;text x=&quot;21.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; text-anchor=&quot;middle&quot; data-name=&quot;stack&quot; data-compartment=&quot;0&quot;&gt;stack&lt;/text&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g data-name=&quot;ROM&quot;&gt;
&lt;g fill=&quot;#eee8d5&quot; stroke=&quot;#33322E&quot; data-name=&quot;ROM&quot;&gt;
&lt;rect x=&quot;98.0&quot; y=&quot;0.0&quot; height=&quot;64.0&quot; width=&quot;71.0&quot; data-name=&quot;ROM&quot;&gt;&lt;/rect&gt;
&lt;path d=&quot;M98.0 32.0 L145.0 32.0 L161.0 16.0 L161.0 0.0&quot; fill=&quot;none&quot; data-name=&quot;ROM&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(98, 0)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot; data-name=&quot;ROM&quot; data-compartment=&quot;0&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;left&quot; data-name=&quot;ROM&quot; data-compartment=&quot;0&quot;&gt;
&lt;text x=&quot;0.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; data-name=&quot;ROM&quot; data-compartment=&quot;0&quot;&gt;ROM&lt;/text&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(98, 32)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot; data-name=&quot;ROM&quot; data-compartment=&quot;1&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;left&quot; data-name=&quot;ROM&quot; data-compartment=&quot;1&quot;&gt;
&lt;text x=&quot;0.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; data-name=&quot;ROM&quot; data-compartment=&quot;1&quot;&gt;args&lt;/text&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g data-name=&quot;RAM&quot;&gt;
&lt;g fill=&quot;#eee8d5&quot; stroke=&quot;#33322E&quot; data-name=&quot;RAM&quot;&gt;
&lt;rect x=&quot;209.0&quot; y=&quot;0.0&quot; height=&quot;64.0&quot; width=&quot;79.0&quot; data-name=&quot;RAM&quot;&gt;&lt;/rect&gt;
&lt;path d=&quot;M209.0 32.0 L254.0 32.0 L270.0 16.0 L270.0 0.0&quot; fill=&quot;none&quot; data-name=&quot;RAM&quot;&gt;&lt;/path&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(209, 0)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot; data-name=&quot;RAM&quot; data-compartment=&quot;0&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;left&quot; data-name=&quot;RAM&quot; data-compartment=&quot;0&quot;&gt;
&lt;text x=&quot;0.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; data-name=&quot;RAM&quot; data-compartment=&quot;0&quot;&gt;RAM&lt;/text&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(209, 32)&quot; font-family=&quot;Helvetica&quot; font-size=&quot;12pt&quot; font-weight=&quot;normal&quot; font-style=&quot;normal&quot; data-name=&quot;RAM&quot; data-compartment=&quot;1&quot;&gt;
&lt;g transform=&quot;translate(8, 8)&quot; fill=&quot;#33322E&quot; text-align=&quot;left&quot; data-name=&quot;RAM&quot; data-compartment=&quot;1&quot;&gt;
&lt;text x=&quot;0.0&quot; y=&quot;14.1&quot; stroke=&quot;none&quot; data-name=&quot;RAM&quot; data-compartment=&quot;1&quot;&gt;memory&lt;/text&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Storage&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Non-Volatile: persistent between function calls &amp;amp; transactions.&lt;/li&gt;
&lt;li&gt;It’s a key-value store that maps 256-bit words to 256-bit words.&lt;/li&gt;
&lt;li&gt;not possible to enumerate storage from within a contract.&lt;/li&gt;
&lt;li&gt;is comparatively &lt;strong&gt;costly to read&lt;/strong&gt;, and even more to &lt;strong&gt;initialize and modify&lt;/strong&gt; storage.&lt;/li&gt;
&lt;li&gt;Because of this cost, you should minimize what you store in persistent storage.&lt;/li&gt;
&lt;li&gt;Store data like derived calculations, caching, and aggregates outside of the contract.&lt;/li&gt;
&lt;li&gt;A contract can neither read nor write to any storage apart from its own.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Volatile: fresh instance for each message call.&lt;/li&gt;
&lt;li&gt;it is linear and can be addressed at the byte level.&lt;/li&gt;
&lt;li&gt;reads are limited to a width of 256 bits.&lt;/li&gt;
&lt;li&gt;writes can be either 8 bits or 256 bits wide.&lt;/li&gt;
&lt;li&gt;Memory is expanded by a word (256-bit) when accessing (either reading or writing) a previously untouched memory word (i.e. any offset within a word).&lt;/li&gt;
&lt;li&gt;At the time of expansion, the cost in gas must be paid.&lt;/li&gt;
&lt;li&gt;Memory is more costly the larger it grows (it scales quadratically).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stack&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;all computations are performed on the stack.&lt;/li&gt;
&lt;li&gt;maximum size of 1024 elements and contains words of 256 bits.&lt;/li&gt;
&lt;li&gt;It is possible to copy one of the &lt;strong&gt;topmost sixteen elements&lt;/strong&gt; to the top of the stack or swap the topmost element with one of the &lt;strong&gt;sixteen elements&lt;/strong&gt; below it.&lt;/li&gt;
&lt;li&gt;All other operations take the topmost two (or one, or more, depending on the operation) elements from the stack and push the result onto the stack.&lt;/li&gt;
&lt;li&gt;it is possible to move stack elements to storage or memory to get deeper access to the stack.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;message-calls&quot; tabindex=&quot;-1&quot;&gt;Message Calls &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#message-calls&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Contracts can call other contracts or send Ether to non-contract accounts by the means of message calls.&lt;/li&gt;
&lt;li&gt;Message calls are like transactions, in fact, every transaction consists of a top-level message call which in turn can create further message calls.&lt;/li&gt;
&lt;li&gt;Calls are &lt;strong&gt;limited to a depth of 1024&lt;/strong&gt;, which means that for more complex operations, loops should be preferred over recursive calls.&lt;/li&gt;
&lt;li&gt;Furthermore, only 63/64th of the gas can be forwarded in a message call, which causes a depth limit of a little less than one thousand in practice.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;delegatecall-callcode-and-libraries&quot; tabindex=&quot;-1&quot;&gt;Delegatecall / Callcode and Libraries &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#delegatecall-callcode-and-libraries&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;&lt;strong&gt;delegatecall&lt;/strong&gt;&lt;/em&gt; is a special variant of a message call.&lt;/li&gt;
&lt;li&gt;code at the target address is executed in the context of the calling contract and &lt;code&gt;msg.sender&lt;/code&gt; and &lt;code&gt;msg.value&lt;/code&gt; do not change their values.&lt;/li&gt;
&lt;li&gt;This means that a contract can dynamically load code from a different address at runtime.&lt;/li&gt;
&lt;li&gt;Storage, current address, and balance still refer to the calling contract, only the code is taken from the called address.&lt;/li&gt;
&lt;li&gt;This makes it possible to implement the “library” feature in Solidity.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;logs&quot; tabindex=&quot;-1&quot;&gt;Logs &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#logs&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Specially indexed data structure that maps all the way up to the block level.&lt;/li&gt;
&lt;li&gt;This feature called &lt;strong&gt;logs&lt;/strong&gt; is used by Solidity to implement &lt;code&gt;events&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Contracts cannot access log data after it has been created.&lt;/li&gt;
&lt;li&gt;But they can be efficiently accessed from outside the blockchain.&lt;/li&gt;
&lt;li&gt;Since some part of the log data is stored in bloom filters, it is possible to search for this data in an efficient and cryptographically secure way, so even “light clients” can still find these logs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;create&quot; tabindex=&quot;-1&quot;&gt;Create &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#create&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Contracts can even create other contracts using a special opcode (i.e. they do not simply call the zero address as a transaction would).&lt;/li&gt;
&lt;li&gt;The only difference between these create calls and the normal message calls is that the payload data is executed, and the result stored as code, and the caller/creator receives the address of the new contract on the stack.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;deactivate-and-self-destruct&quot; tabindex=&quot;-1&quot;&gt;Deactivate and Self-destruct &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/#deactivate-and-self-destruct&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The only way to remove code from the blockchain is when a contract at that address performs the &lt;code&gt;selfdestruct&lt;/code&gt; operation.&lt;/li&gt;
&lt;li&gt;Remaining Ether stored at that address is sent to a designated target and then the storage and code is removed from the state.&lt;/li&gt;
&lt;li&gt;It is potentially dangerous as if someone sends Ether to removed contracts, the Ether is forever lost.&lt;/li&gt;
&lt;li&gt;If you want to deactivate your contracts, you should instead disable them by changing some internal state which causes all functions to revert. This makes it impossible to use the contract, as it returns Ether immediately.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/study-notes-on-ethereum-virtual-machine-evm/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>Use RegEx to split a string in Javascript (preserving separators) | Notes</title>
	<link href="https://abhi.am/notes/javascript-split-string-with-separators/" length="1831"/>
	<updated>2021-02-01T10:40:00Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="regex" scheme="https://abhi.am/notes/tags/" />
	<category term="javascript" scheme="https://abhi.am/notes/tags/" />
	<category term="recipe" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/javascript-split-string-with-separators/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">&lt;p&gt;Use the Javascript split() function with a &lt;code&gt;Positive Lookbehind Regular Expression&lt;/code&gt; to split a string while preserving the separators in the sub-strings:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;(?&amp;lt;=[&amp;lt;separator characters go here&gt;])&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;what-is-lookbehind&quot; tabindex=&quot;-1&quot;&gt;What is Lookbehind? &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/javascript-split-string-with-separators/#what-is-lookbehind&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Lookbehind in regular-expression allows to match a pattern only when it follows the given lookbehind pattern (without actually matching it).&lt;/p&gt;
&lt;h3 id=&quot;syntax&quot; tabindex=&quot;-1&quot;&gt;Syntax &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/javascript-split-string-with-separators/#syntax&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Positive lookbehind: &lt;code&gt;(?&amp;lt;=Y)X&lt;/code&gt; matches X if there is Y before it.&lt;/li&gt;
&lt;li&gt;Negative lookbehind: &lt;code&gt;(?&amp;lt;!Y)X&lt;/code&gt; matches X if there is no Y before it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;One limitation&lt;/strong&gt;&lt;/em&gt; is that Javascript only supports fixed length lookbehind patterns. So, you cannot use it to split by a separator pattern with variable length.&lt;/p&gt;
&lt;h2 id=&quot;demo&quot; tabindex=&quot;-1&quot;&gt;Demo &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/javascript-split-string-with-separators/#demo&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;iframe class=&quot;codepen&quot; height=&quot;300&quot; style=&quot;width:100%;&quot; scrolling=&quot;no&quot; title=&quot;CodePen Embed&quot; src=&quot;https://codepen.io/anon/embed/MWbYPLO?height=300&amp;theme-id=dark&amp;default-tab=js,result&quot; frameborder=&quot;0&quot; loading=&quot;lazy&quot; allowtransparency=&quot;true&quot; allowfullscreen=&quot;true&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://codepen.io/abhiweb/pen/MWbYPLO&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;See the Pen&lt;/a&gt;&lt;/p&gt;&lt;/iframe&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/javascript-split-string-with-separators/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>Easily show a range/gauge with HTML &lt;meter&gt; element | Notes</title>
	<link href="https://abhi.am/notes/show-range-with-html-meter-element/" length="2406"/>
	<updated>2021-02-01T06:40:00Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="html" scheme="https://abhi.am/notes/tags/" />
	<category term="design" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/show-range-with-html-meter-element/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">
	&lt;blockquote&gt;&lt;strong&gt;Direct Links:&lt;/strong&gt;
	&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;developer.mozilla.org/en-US/docs/Web/HTML/Element/meter&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
	&lt;/blockquote&gt;&lt;p&gt;I really had no idea about the HTML &lt;code&gt;&amp;lt;meter&amp;gt;&lt;/code&gt; element that can show a range of values, until I read &lt;a href=&quot;https://twitter.com/IMAC2/status/1352603699944816645&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;this tweet&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/IMAC2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Álvaro Trigo&lt;/a&gt; 😃&lt;/p&gt;
&lt;h3 id=&quot;example&quot; tabindex=&quot;-1&quot;&gt;Example: &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/show-range-with-html-meter-element/#example&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meter&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;100&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token attr-name&quot;&gt;low&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;30&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;high&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;80&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;optimum&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;60&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;70&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;h4&gt;Result:&lt;/h4&gt;
&lt;meter min=&quot;0&quot; max=&quot;100&quot; low=&quot;30&quot; high=&quot;80&quot; optimum=&quot;60&quot; value=&quot;70&quot;&gt;
&lt;/meter&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;&amp;lt;meter&amp;gt;&lt;/code&gt; tag should not be used to show the progress of a task. Use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;&lt;code&gt;&amp;lt;progress&amp;gt;&lt;/code&gt;&lt;/a&gt; tag instead.&lt;/p&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/show-range-with-html-meter-element/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>Eleventy plugin for generating social images (using SVG) | Notes</title>
	<link href="https://abhi.am/notes/11ty-plugin-generate-social-images/" length="5233"/>
	<updated>2021-01-28T14:43:00Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="11ty" scheme="https://abhi.am/notes/tags/" />
	<category term="library" scheme="https://abhi.am/notes/tags/" />
	<category term="javascript" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/11ty-plugin-generate-social-images/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">
	&lt;blockquote&gt;&lt;strong&gt;Direct Links:&lt;/strong&gt;
	&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/manustays/eleventy-plugin-generate-social-images&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/manustays/eleventy-plugin-generate-social-images&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
	&lt;/blockquote&gt;&lt;p&gt;While porting &lt;a href=&quot;https://abhi.am/&quot;&gt;my website&lt;/a&gt; to &lt;a href=&quot;https://www.11ty.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;11ty&lt;/a&gt;, I wrote my own &lt;a href=&quot;https://github.com/manustays/eleventy-plugin-generate-social-images&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;plugin&lt;/a&gt; to automatically generated social-sharing-images for my &lt;a href=&quot;https://abhi.am/notes&quot;&gt;articles&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A social-sharing-image shows as a thumbnail for a website/blogpost when shared on social media.&lt;/p&gt;
&lt;p&gt;This plugin generates such images automatically using the title of your blogposts/pages. For a live example, share this page on a social media like &lt;a href=&quot;https://twitter.com/intent/tweet?url=https://abhi.am/notes/11ty-plugin-generate-social-images&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Twitter&lt;/a&gt; or &lt;a href=&quot;https://www.linkedin.com/shareArticle?mini=true&amp;amp;url=https://abhi.am/notes/11ty-plugin-generate-social-images&amp;amp;title=&amp;amp;summary=&amp;amp;source=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;LinkedIn&lt;/a&gt;!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Images are generated in PNG format in a standard 1200×628px size that is suitable for sharing with most social networks.&lt;/p&gt;
&lt;h2 id=&quot;why-another-plugin&quot; tabindex=&quot;-1&quot;&gt;Why another plugin? &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/11ty-plugin-generate-social-images/#why-another-plugin&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I started with using &lt;a href=&quot;https://twitter.com/5t3ph&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Stephanie Eckles&lt;/a&gt;’s excellent plugin &lt;a href=&quot;https://github.com/5t3ph/eleventy-plugin-social-images&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;@11tyrocks/eleventy-plugin-social-images&lt;/a&gt;.
&lt;ul&gt;
&lt;li&gt;She has written an excellent post about her plugin &lt;a href=&quot;https://dev.to/5t3ph/automated-social-sharing-images-with-puppeteer-11ty-and-netlify-22ln&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;It uses HTML-based templating for easily configuring the social images.&lt;/li&gt;
&lt;li&gt;It uses a Puppeteer build script to generate images from the HTML template…&lt;/li&gt;
&lt;li&gt;I would recommend this plugin for most folks!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;But, I ran into issues running Puppeteer with my WSL2 based dev setup.&lt;/li&gt;
&lt;li&gt;I also wanted to keep the build process lighter (Puppeteer uses a headless Chrome to render and generate the screenshot).&lt;/li&gt;
&lt;li&gt;Taking inspiration from another amazing plugin – &lt;a href=&quot;https://www.11ty.dev/docs/plugins/image/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;11ty’s Image Plugin&lt;/a&gt; – the idea was to efficiently generate the social images using SVG and then convert it into JPEG/PNG using &lt;a href=&quot;https://github.com/lovell/sharp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Sharp&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;who-is-this-plugin-for&quot; tabindex=&quot;-1&quot;&gt;Who is this plugin for? &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/11ty-plugin-generate-social-images/#who-is-this-plugin-for&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Want to automatically generate social-sharing-images for your Eleventy-based website (&lt;em&gt;of course!&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Don’t want Puppeteer dependency&lt;/li&gt;
&lt;li&gt;Want to use SVG to style your social images&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;demo&quot; tabindex=&quot;-1&quot;&gt;Demo &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/11ty-plugin-generate-social-images/#demo&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is how it looks like configured for one of my blogposts:&lt;br /&gt;
&lt;img src=&quot;https://abhi.am/img/preview/how-to-load-third-party-javascript-on-demand.png&quot; alt=&quot;&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;how-does-the-plugin-work&quot; tabindex=&quot;-1&quot;&gt;How does the plugin work? &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/11ty-plugin-generate-social-images/#how-does-the-plugin-work&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Image is created using an SVG template. Users can configure the design or pass custom SVG snippets to be inserted.&lt;/li&gt;
&lt;li&gt;Title text is &lt;a href=&quot;https://github.com/manustays/eleventy-plugin-generate-social-images/blob/4df9ce4ad93036bb842728f4684b12954316f5e2/utils/generateSocialImage.js#L9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;wrapped&lt;/a&gt; by breaking it into multiple lines at a pre-configured max-length-per-line. This was necessary because SVG does not support text-wrapping natively and the Sharp library does not support &lt;code&gt;&amp;lt;foreignObject&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The title lines are &lt;a href=&quot;https://github.com/manustays/eleventy-plugin-generate-social-images/blob/4df9ce4ad93036bb842728f4684b12954316f5e2/utils/generateSocialImage.js#L39&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;sanitized&lt;/a&gt; and inserted into the SVG.&lt;/li&gt;
&lt;li&gt;The SVG image is converted into PNG using the &lt;a href=&quot;https://sharp.pixelplumbing.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Sharp library&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Author image is superimposed onto the generated PNG using &lt;a href=&quot;https://sharp.pixelplumbing.com/api-composite&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Sharp’s &lt;code&gt;composite()&lt;/code&gt; function&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;installation-usage&quot; tabindex=&quot;-1&quot;&gt;Installation &amp;amp; Usage &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/11ty-plugin-generate-social-images/#installation-usage&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;See the latest &lt;a href=&quot;https://github.com/manustays/eleventy-plugin-generate-social-images&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;installation and usage guide on this plugin’s Github page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For a complete implementation example, &lt;a href=&quot;https://github.com/manustays/abhi.page.11ty&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;checkout my website on Github&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/11ty-plugin-generate-social-images/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>Eleventy plugin for efficient CodePen embeds | Notes</title>
	<link href="https://abhi.am/notes/11ty-plugin-codepen/" length="4138"/>
	<updated>2021-01-24T15:49:50Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="11ty" scheme="https://abhi.am/notes/tags/" />
	<category term="library" scheme="https://abhi.am/notes/tags/" />
	<category term="javascript" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/11ty-plugin-codepen/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">
	&lt;blockquote&gt;&lt;strong&gt;Direct Links:&lt;/strong&gt;
	&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/manustays/eleventy-plugin-codepen-iframe&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/manustays/eleventy-plugin-codepen-iframe&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
	&lt;/blockquote&gt;&lt;p&gt;Yet another 11ty plugin to embed CodePens into you pages. The other plugins that I had seen use CodePen’s preferred Javascript based embeds. It requires loading an external Javascript (though, a small one) into your page. The Codepen embed Javascript finally creates an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; anyway!&lt;/p&gt;
&lt;p&gt;I wanted a more efficient solution for my blog by directly embedding the Pen’s iFrame; therefore I wrote this plugin.&lt;/p&gt;
&lt;h2 id=&quot;usage&quot; tabindex=&quot;-1&quot;&gt;Usage &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/11ty-plugin-codepen/#usage&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;h4&gt;STEP 1: Install the plugin:&lt;/h4&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; --save-dev @manustays/eleventy-plugin-codepen-iframe&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;STEP 2: Include it in your &lt;code&gt;.eleventy.js&lt;/code&gt; config file:&lt;/h4&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; embedCodePen &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;@manustays/eleventy-plugin-codepen-iframe&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;embedCodePen&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token literal-property property&quot;&gt;tabs&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;js,result&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠ You’re only allowed one module.exports in your configuration file! If one already exists, copy the content of the above into your existing module.exports function.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;STEP 3 – Use it in your templates like this:&lt;/h4&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;{% CodePen &quot;https://codepen.io/abhiweb/pen/wvzNaQM&quot;, &quot;result&quot;, &quot;220&quot; %}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;config-options&quot; tabindex=&quot;-1&quot;&gt;Config Options &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/11ty-plugin-codepen/#config-options&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;These options set the default values for embedded Pens. They can be overridden while embedding individual Pens.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;tabs&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;“result”&lt;/td&gt;
&lt;td&gt;Default comma-separated string of the tabs of the codepen to display&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;height&lt;/td&gt;
&lt;td&gt;number&lt;/td&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;Default height of Pen iFrames&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;width&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;“100%”&lt;/td&gt;
&lt;td&gt;Default width of Pen iFrames&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;theme&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;“dark”&lt;/td&gt;
&lt;td&gt;Default theme for all Pens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;user&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;“”&lt;/td&gt;
&lt;td&gt;CodePen user-id to use if only Pen-id is provided&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;“codepen”&lt;/td&gt;
&lt;td&gt;CSS classes to add to the iFrame&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;demo&quot; tabindex=&quot;-1&quot;&gt;Demo &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/11ty-plugin-codepen/#demo&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Check it out live in my other post &lt;strong&gt;&lt;a href=&quot;https://abhi.am/notes/regex-to-validate-names/&quot;&gt;A Regular Expression to filter invalid names&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/11ty-plugin-codepen/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>How to load third-party Javascript on demand | Notes</title>
	<link href="https://abhi.am/notes/load-third-party-javascript-on-demand/" length="8635"/>
	<updated>2021-01-22T05:35:00Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="webdev" scheme="https://abhi.am/notes/tags/" />
	<category term="javascript" scheme="https://abhi.am/notes/tags/" />
	<category term="recipe" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/load-third-party-javascript-on-demand/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">&lt;p&gt;A small script to dynamically (and, asynchronously) load third-party Javascript files on demand.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It inserts a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag in the head to load the script.&lt;/li&gt;
&lt;li&gt;Checks if a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag already exists with the same source to avoid duplicate script tags.
&lt;ul&gt;
&lt;li&gt;I use it with a Web Component based library where another component may already have loaded the script.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Callbacks after successful or failed load.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt; I also use a &lt;em&gt;retry&lt;/em&gt; logic (that removes and re-attaches the script tag) to avoid temporary network failures. I have not included it here for simplicity.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt; * @param {string} src The URL of the script.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt; * @callback onLoadSuccessCallback Callback when script is loaded successfully.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt; * @callback onLoadErrorCallback Callback when the script fails to load.&lt;/span&gt;&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadScript&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;src&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; onLoadSuccessCallback&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; onLoadErrorCallback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;src&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Error: missing src&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token comment&quot;&gt;// Check if the script is already loaded&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;script[src=&quot;&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; src &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&quot;]&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token comment&quot;&gt;// Script already loaded...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Script Already Loaded. Skipping: &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; src&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token function&quot;&gt;onLoadSuccessCallback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token comment&quot;&gt;// Script not already leaded; load script...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token comment&quot;&gt;// Create script tag&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; js &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;script&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		js&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;src &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; src&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		js&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;async&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token comment&quot;&gt;// Setup success callback&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;onLoadSuccessCallback&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;			js&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onload &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; onLoadSuccessCallback&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token comment&quot;&gt;// Setup error callback&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;onLoadErrorCallback&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;			js&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onerror &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; onLoadErrorCallback&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		&lt;span class=&quot;token comment&quot;&gt;// Add the script tag to &amp;lt;head&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;		document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;head&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;js&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use it like this:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token function&quot;&gt;loadScript&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;url/or/path/to/script.js&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Script loaded&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token comment&quot;&gt;// Do something with the script.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Script load failed&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token comment&quot;&gt;// Handle error.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/load-third-party-javascript-on-demand/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>Recover anything in git with &#39;git reflog&#39; | Notes</title>
	<link href="https://abhi.am/notes/recover-anything-in-git/" length="2645"/>
	<updated>2021-01-18T13:26:00Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="git" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/recover-anything-in-git/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">
	&lt;blockquote&gt;&lt;strong&gt;Direct Links:&lt;/strong&gt;
	&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://gitready.com/intermediate/2009/02/09/reflog-your-safety-net&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;gitready.com/intermediate/2009/02/09/reflog-your-safety-net&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
	&lt;/blockquote&gt;&lt;p&gt;To recover from almost anything in git, even if you have done a &lt;code&gt;git reset --hard origin/main&lt;/code&gt; and lost all your last commits, use the following command:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; reflog&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From the &lt;a href=&quot;https://git-scm.com/docs/git-reflog&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;official documents&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Reference logs, or “reflogs”, record when the tips of branches and other references were updated in the local repository. Reflogs are useful in various Git commands, to specify the old value of a reference. For example, HEAD@{2} means “where HEAD used to be two moves ago”… This command manages the information recorded in the reflogs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It gives the historical info like this:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; reflog&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;c5f76d2 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;HEAD -&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; beta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; HEAD@&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;: pull origin main: Fast forward&lt;/span&gt;&lt;br /&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;0e373cb HEAD@&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;: commit: Updated base styles&lt;/mark&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;b7aece4 HEAD@&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;: commit: Updated README&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;eff2f57 HEAD@&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;: commit: Added shortURL filter&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first 7-characters &lt;em&gt;(sha-id)&lt;/em&gt; are the beginning of the SHA1 for that commit. You can use this to recover any lost data from that point in history.&lt;/p&gt;
&lt;p&gt;For example, to apply our last commit back into the code base &lt;em&gt;(sha-id = 0e373cb)&lt;/em&gt;, we can merge it back with the command:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge 0e373cb&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can do other stuff as well, like &lt;code&gt;checkout&lt;/code&gt;, &lt;code&gt;cherry-pick&lt;/code&gt; or use &lt;code&gt;git show&lt;/code&gt; to see the diff.&lt;/p&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/recover-anything-in-git/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>A Regular Expression to filter invalid names | Notes</title>
	<link href="https://abhi.am/notes/regex-to-validate-names/" length="8523"/>
	<updated>2021-01-17T15:38:00Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="regex" scheme="https://abhi.am/notes/tags/" />
	<category term="recipe" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/regex-to-validate-names/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">&lt;p&gt;A regular expression that can be used as a basic filter to detect invalid names.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I use it in an Indian context. May not be useful for others.&lt;/li&gt;
&lt;li&gt;Use it with an ‘i’ RegEx flag to ignore case.&lt;/li&gt;
&lt;li&gt;Filters out spelling mistakes &amp;amp; gibberish entries; &lt;em&gt;but not all invalid entries!&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Similarly useful for other English nouns as well, and not just names.&lt;/li&gt;
&lt;li&gt;Useful for quick frontend validation in scenarios where users may tap gibberish to quickly skip a mandatory ‘name’ parameter.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-regex&quot;&gt;&lt;code class=&quot;language-regex&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token anchor function&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?!&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token range&quot;&gt;a&lt;span class=&quot;token range-punctuation operator&quot;&gt;-&lt;/span&gt;z&lt;/span&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token quantifier number&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token backreference keyword&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt; &lt;span class=&quot;token quantifier number&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token backreference keyword&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token alternation keyword&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token char-set class-name&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;*?&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token anchor function&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token alternation keyword&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token char-class-negation operator&quot;&gt;^&lt;/span&gt;d&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token range&quot;&gt;a&lt;span class=&quot;token range-punctuation operator&quot;&gt;-&lt;/span&gt;z&lt;/span&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token backreference keyword&quot;&gt;\2&lt;/span&gt;&lt;span class=&quot;token backreference keyword&quot;&gt;\2&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token alternation keyword&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;d&lt;span class=&quot;token group punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token range&quot;&gt;a&lt;span class=&quot;token range-punctuation operator&quot;&gt;-&lt;/span&gt;d&lt;/span&gt;&lt;span class=&quot;token range&quot;&gt;f&lt;span class=&quot;token range-punctuation operator&quot;&gt;-&lt;/span&gt;z&lt;/span&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token backreference keyword&quot;&gt;\3&lt;/span&gt;&lt;span class=&quot;token backreference keyword&quot;&gt;\3&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token char-set class-name&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token alternation keyword&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token char-set class-name&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;*?&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token range&quot;&gt;a&lt;span class=&quot;token range-punctuation operator&quot;&gt;-&lt;/span&gt;z&lt;/span&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;{3,}&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token backreference keyword&quot;&gt;\4&lt;/span&gt;&lt;span class=&quot;token backreference keyword&quot;&gt;\4&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token char-set class-name&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token alternation keyword&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token char-set class-name&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token anchor function&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token alternation keyword&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token char-class-negation operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token range&quot;&gt;a&lt;span class=&quot;token range-punctuation operator&quot;&gt;-&lt;/span&gt;z&lt;/span&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token char-class-negation operator&quot;&gt;^&lt;/span&gt;aeiou &lt;span class=&quot;token special-escape escape&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;{4,}&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token anchor function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token alternation keyword&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token char-class-negation operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token range&quot;&gt;a&lt;span class=&quot;token range-punctuation operator&quot;&gt;-&lt;/span&gt;z&lt;/span&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token char-set class-name&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token anchor function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(?:&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token range&quot;&gt;a&lt;span class=&quot;token range-punctuation operator&quot;&gt;-&lt;/span&gt;z&lt;/span&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token special-escape escape&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;{0,2}&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token range&quot;&gt;a&lt;span class=&quot;token range-punctuation operator&quot;&gt;-&lt;/span&gt;z&lt;/span&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token anchor function&quot;&gt;$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;logic&quot; tabindex=&quot;-1&quot;&gt;Logic &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/notes/regex-to-validate-names/#logic&quot;&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Allows up to three words (first &amp;amp; last name).&lt;/li&gt;
&lt;li&gt;Allows abbreviations (ending in ‘.’) in all but the last word.&lt;/li&gt;
&lt;li&gt;Rejects repetition of any subset of characters.&lt;/li&gt;
&lt;li&gt;Uses rules of pronounceable English syllables to filter bad entries &lt;em&gt;(based on my limited research)&lt;/em&gt;:
&lt;ol&gt;
&lt;li&gt;A consonant cannot be consecutively repeated.&lt;/li&gt;
&lt;li&gt;A vowel cannot be consecutively repeated more than twice.
&lt;ol&gt;
&lt;li&gt;Exception: &lt;em&gt;e&lt;/em&gt; that can be repeated thrice for certain Indian names, for example, those ending with ‘deee’.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;… &lt;em&gt;(more to be updated soon)&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;
I had written this long back by analyzing invalid entries made in a fin-tech app used by agents to make entries on behalf of other customers. I will update the exact logic and describe parts of the regex soon!&lt;/p&gt;
&lt;p&gt;Test it here &amp;amp; get a sample code in Javascript:&lt;/p&gt;
&lt;iframe class=&quot;codepen&quot; height=&quot;220&quot; style=&quot;width:100%;&quot; scrolling=&quot;no&quot; title=&quot;CodePen Embed&quot; src=&quot;https://codepen.io/anon/embed/wvzNaQM?height=220&amp;theme-id=dark&amp;default-tab=result&quot; frameborder=&quot;0&quot; loading=&quot;lazy&quot; allowtransparency=&quot;true&quot; allowfullscreen=&quot;true&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://codepen.io/abhiweb/pen/wvzNaQM&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;See the Pen&lt;/a&gt;&lt;/p&gt;&lt;/iframe&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/regex-to-validate-names/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>Fastest Google Fonts | Notes</title>
	<link href="https://abhi.am/notes/fastest-google-fonts/" length="4867"/>
	<updated>2021-01-16T17:38:37Z</updated>
	<category term="notes" scheme="https://abhi.am/" label="Coding Notes" /><category term="webdev" scheme="https://abhi.am/notes/tags/" />
	<category term="css" scheme="https://abhi.am/notes/tags/" />
	
	<id>https://abhi.am/notes/fastest-google-fonts/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">
	&lt;blockquote&gt;&lt;strong&gt;Direct Links:&lt;/strong&gt;
	&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://csswizardry.com/2020/05/the-fastest-google-fonts/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;csswizardry.com/2020/05/the-fastest-google-fonts&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://css-tricks.com/how-to-load-fonts-in-a-way-that-fights-fout-and-makes-lighthouse-happy/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;css-tricks.com/how-to-load-fonts-in-a-way-that-fights-fout-and-makes-lighthouse-happy&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
	&lt;/blockquote&gt;&lt;ul&gt;
&lt;li&gt;Preconnect to Google Font server.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;preload&lt;/code&gt; to asynchronously load the font fast on supported browsers.&lt;/li&gt;
&lt;li&gt;In the link to the main font stylesheet:
&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;media=print&lt;/code&gt; on the stylesheet to stop loading it during page load.&lt;/li&gt;
&lt;li&gt;On page load, set &lt;code&gt;media=all&lt;/code&gt; on stylesheet (using Javascript) to load the font.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;As a fallback for browsers where Javascript is disabled, include a normal link to the stylesheet within &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt; tag.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a recommended snippet:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;preconnect&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://fonts.gstatic.com&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;crossorigin&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;preload&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token attr-name&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&amp;amp;display=swap&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&amp;amp;display=swap&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token attr-name&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;print&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onload&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;media&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;all&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;noscript&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&amp;amp;display=swap&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;noscript&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/notes/fastest-google-fonts/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry>
<entry>
	<title>How we built the Connect web app – Part 1 – Breaking from our past</title>
	<link href="https://abhi.am/blog/how-we-built-connect-web-app/" length="3233"/>
	<updated>2016-08-04T14:33:37Z</updated>
	<category term="blog" scheme="https://abhi.am/" label="Blog Post" /><category term="architecture" scheme="https://abhi.am/blog/tags/" />
	
	<id>https://abhi.am/blog/how-we-built-connect-web-app/</id>
	<author><name>Kumar Abhishek</name><uri>https://abhi.am</uri></author>
	<content type="html">&lt;p&gt;&lt;img src=&quot;https://abhi.am/assets/img/blog/connect.jpeg&quot;&gt;&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;This is a &lt;s&gt;series of&lt;/s&gt; posts about my adventure with an exciting project at Eko:  &lt;a href=&quot;https://connect.eko.in/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;connect.eko.in&lt;/a&gt;, the progressive web app enabling Eko‘s merchants to make payments and other financial transactions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;the-past&quot; tabindex=&quot;-1&quot;&gt;The Past &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/blog/how-we-built-connect-web-app/#the-past&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;About eight years ago, &lt;a href=&quot;https://eko.in/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Eko&lt;/a&gt; introduced the simplest of all interfaces to bring banking, payments and other financial transactions to the masses: by dialing numbers on a basic mobile phone. But as the smartphones and laptops grew in popularity with our merchants, we introduced other smart applications. One of them was a simple web portal for money remittance called “Connect”:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://abhi.am/assets/img/blog/old-connect.jpeg&quot; alt=&quot;Old Connect Screenshot&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The website was immediately successful with our partner merchants, thanks mostly to its simple three-pane interface for transferring money to any bank account in India.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In the three years of it’s existence, the old Connect portal had already been used to transact for more than 6 billion dollars.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But soon, money remittance service was not enough. We wanted to introduce more services. The only problem was that our engineers had to individually design and build interfaces for these new services. And we realized…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;we had to manually design and code each page/interface separately. The process was too slow!&lt;/li&gt;
&lt;li&gt;the three-pane interface was only suitable for the remittance workflow&lt;/li&gt;
&lt;li&gt;we needed a different interface for different services&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And, as a solution, us lazy folks at Eko came up again with our common mantra:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;generalize and automate!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;breaking-from-the-past&quot; tabindex=&quot;-1&quot;&gt;Breaking From The Past &lt;a class=&quot;header-anchor&quot; href=&quot;https://abhi.am/blog/how-we-built-connect-web-app/#breaking-from-the-past&quot;&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So, we came up with the following solution:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;Interaction Framework&lt;/strong&gt;: to &lt;em&gt;generalize&lt;/em&gt; all the financial services (transactions) supported by our platform into interactions that take place between two or more entities. &lt;em&gt;For example&lt;/em&gt;, a money transfer is an interaction between two bank/wallet accounts. Over this generalization, we defined requests, responses, parameters, complex validations, interaction relationships, interaction flows, dynamic behavior, etc. This became our &lt;strong&gt;Interaction Framework&lt;/strong&gt;!&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Progressive Web App&lt;/strong&gt;: to build a progressive web app and &lt;em&gt;automate&lt;/em&gt; the process of providing new services by leveraging the Interaction-Framework. We decided to use &lt;a href=&quot;https://www.polymer-project.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;ext-link&quot;&gt;Google Polymer&lt;/a&gt; (which was still in beta, back then) and build custom web components purely on the front-end web technologies.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;API Backend&lt;/strong&gt;: to design a backend service on &lt;strong&gt;Node.js&lt;/strong&gt; that would be totally &lt;em&gt;decoupled&lt;/em&gt; from the front-end app.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://abhi.am/blog/how-we-built-connect-web-app/&quot; rel=&quot;self&quot;&gt;&lt;strong&gt;Read on abhi.am&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</content>
</entry></feed>