[{"data":1,"prerenderedAt":751},["ShallowReactive",2],{"learn-doc-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002Finvalidation":3,"learn-doc-topic-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching":279,"lessons-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching":311,"sidebar-course-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching":692,"i-lucide:chevron-down":704,"i-lucide:search":708,"i-lucide:sun":710,"i-lucide:moon":712,"i-lucide:arrow-right":714,"i-lucide:menu":716,"i-lucide:panel-left":718,"i-lucide:chevron-right":720,"i-lucide:lock":722,"i-lucide:shopping-bag":724,"i-lucide:arrow-left":726,"i-lucide:corner-down-right":728,"i-lucide:mail":730,"i-simple-icons:x":732,"i-simple-icons:linkedin":734,"i-simple-icons:dribbble":736,"i-simple-icons:github":738,"sidebar-quiz-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching":740,"i-lucide:layers":741,"i-lucide:printer":743,"i-lucide:graduation-cap":745,"i-lucide:book-marked":747,"i-lucide:notebook-pen":749},{"id":4,"title":5,"access":6,"body":7,"description":269,"extension":270,"lang":271,"meta":272,"navigation":273,"order":91,"partial":274,"path":275,"seo":276,"stem":277,"__hash__":278},"lessons\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002F02.invalidation.md","Invalidation and stampedes","premium",{"type":8,"value":9,"toc":263},"minimark",[10,14,18,23,26,30,33,36,39,46,52,138,144,150,154,157,204,207,210,214,217,256,259],[11,12,5],"h1",{"id":13},"invalidation-and-stampedes",[15,16,17],"p",{},"Caching is easy. Knowing when the cached value stopped being true is the hard part.",[19,20,22],"h2",{"id":21},"ttl-is-a-guess-about-staleness","TTL is a guess about staleness",[15,24,25],{},"A TTL says \"I accept being wrong for up to this long\". Choosing one means deciding\nhow much staleness the product tolerates — a question for the product, not the\ninfrastructure.",[19,27,29],{"id":28},"the-thundering-herd","The thundering herd",[15,31,32],{},"A popular key expires. A thousand concurrent requests miss simultaneously. All\nthousand hit the database with the same query.",[15,34,35],{},"The database, sized for the cached load, falls over. Recovery repopulates the cache,\nthe key expires again, and the pattern repeats on a cycle matching the TTL.",[15,37,38],{},"Three defences:",[15,40,41,45],{},[42,43,44],"strong",{},"Locking."," The first miss takes a lock and recomputes; everyone else waits or\nserves stale. Correct, but adds a coordination point.",[15,47,48,51],{},[42,49,50],{},"Probabilistic early expiry."," Recompute before expiry with a probability that\nrises as the TTL approaches, so refreshes spread out instead of synchronising.",[53,54,59],"pre",{"className":55,"code":56,"language":57,"meta":58,"style":58},"language-python shiki shiki-themes github-dark-dimmed github-dark-dimmed","def should_refresh(computed_at, ttl, beta=1.0):\n    age = now() - computed_at\n    return age + beta * delta * math.log(random.random()) >= ttl\n","python","",[60,61,62,89,106],"code",{"__ignoreMap":58},[63,64,67,71,75,79,82,86],"span",{"class":65,"line":66},"line",1,[63,68,70],{"class":69},"sEYkB","def",[63,72,74],{"class":73},"s-wk_"," should_refresh",[63,76,78],{"class":77},"sM9_K","(computed_at, ttl, beta",[63,80,81],{"class":69},"=",[63,83,85],{"class":84},"sQdni","1.0",[63,87,88],{"class":77},"):\n",[63,90,92,95,97,100,103],{"class":65,"line":91},2,[63,93,94],{"class":77},"    age ",[63,96,81],{"class":69},[63,98,99],{"class":77}," now() ",[63,101,102],{"class":69},"-",[63,104,105],{"class":77}," computed_at\n",[63,107,109,112,115,118,121,124,127,129,132,135],{"class":65,"line":108},3,[63,110,111],{"class":69},"    return",[63,113,114],{"class":77}," age ",[63,116,117],{"class":69},"+",[63,119,120],{"class":77}," beta ",[63,122,123],{"class":69},"*",[63,125,126],{"class":77}," delta ",[63,128,123],{"class":69},[63,130,131],{"class":77}," math.log(random.random()) ",[63,133,134],{"class":69},">=",[63,136,137],{"class":77}," ttl\n",[15,139,140,143],{},[42,141,142],{},"Jitter."," Add randomness to every TTL so keys written together do not expire\ntogether. The cheapest fix and often sufficient.",[145,146,147],"danger",{},[15,148,149],{},"Populating a cache during a deploy or a warm-up script writes thousands of keys\nwithin the same second. With a fixed TTL they all expire within the same second too,\nproducing a synchronised stampede hours later that looks completely unrelated to\nthe deploy that caused it. Always jitter.",[19,151,153],{"id":152},"explicit-invalidation","Explicit invalidation",[15,155,156],{},"Delete the key on write:",[53,158,160],{"className":55,"code":159,"language":57,"meta":58,"style":58},"def update_user(user_id, data):\n    db.update(user_id, data)\n    cache.delete(f\"user:{user_id}\")\n",[60,161,162,172,177],{"__ignoreMap":58},[63,163,164,166,169],{"class":65,"line":66},[63,165,70],{"class":69},[63,167,168],{"class":73}," update_user",[63,170,171],{"class":77},"(user_id, data):\n",[63,173,174],{"class":65,"line":91},[63,175,176],{"class":77},"    db.update(user_id, data)\n",[63,178,179,182,185,189,192,195,198,201],{"class":65,"line":108},[63,180,181],{"class":77},"    cache.delete(",[63,183,184],{"class":69},"f",[63,186,188],{"class":187},"szYpP","\"user:",[63,190,191],{"class":69},"{",[63,193,194],{"class":77},"user_id",[63,196,197],{"class":69},"}",[63,199,200],{"class":187},"\"",[63,202,203],{"class":77},")\n",[15,205,206],{},"Delete rather than overwrite. Overwriting introduces a race where two concurrent\nwriters leave the cache holding the older value.",[15,208,209],{},"The ordering matters too — database first, then cache. Reversed, a concurrent read\nbetween the two steps repopulates the cache with the old row and the stale value\nsurvives its TTL.",[19,211,213],{"id":212},"cached-nothing","Cached nothing",[15,215,216],{},"The failure mode nobody instruments: a cache that works perfectly and is never hit,\nbecause keys are built from something that varies per request.",[53,218,220],{"className":55,"code":219,"language":57,"meta":58,"style":58},"cache.set(f\"user:{user_id}:{request_id}\", user)  # unique every time\n",[60,221,222],{"__ignoreMap":58},[63,223,224,227,229,231,233,235,237,240,242,245,247,249,252],{"class":65,"line":66},[63,225,226],{"class":77},"cache.set(",[63,228,184],{"class":69},[63,230,188],{"class":187},[63,232,191],{"class":69},[63,234,194],{"class":77},[63,236,197],{"class":69},[63,238,239],{"class":187},":",[63,241,191],{"class":69},[63,243,244],{"class":77},"request_id",[63,246,197],{"class":69},[63,248,200],{"class":187},[63,250,251],{"class":77},", user)  ",[63,253,255],{"class":254},"s0RzX","# unique every time\n",[15,257,258],{},"Hit rate is zero. Latency is unchanged. Nothing errors. Monitor hit rate as a first\nclass metric, and alert when it drops — a cache silently doing nothing is a cost with\nno benefit.",[260,261,262],"style",{},"html pre.shiki code .sEYkB, html code.shiki .sEYkB{--shiki-default:#F47067;--shiki-dark:#F47067}html pre.shiki code .s-wk_, html code.shiki .s-wk_{--shiki-default:#DCBDFB;--shiki-dark:#DCBDFB}html pre.shiki code .sM9_K, html code.shiki .sM9_K{--shiki-default:#ADBAC7;--shiki-dark:#ADBAC7}html pre.shiki code .sQdni, html code.shiki .sQdni{--shiki-default:#6CB6FF;--shiki-dark:#6CB6FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szYpP, html code.shiki .szYpP{--shiki-default:#96D0FF;--shiki-dark:#96D0FF}html pre.shiki code .s0RzX, html code.shiki .s0RzX{--shiki-default:#768390;--shiki-dark:#768390}",{"title":58,"searchDepth":108,"depth":108,"links":264},[265,266,267,268],{"id":21,"depth":91,"text":22},{"id":28,"depth":91,"text":29},{"id":152,"depth":91,"text":153},{"id":212,"depth":91,"text":213},"TTLs, explicit invalidation, and what happens when a hot key expires.","md","en",{},true,false,"\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002Finvalidation",{"title":5,"description":269},"learn\u002Fen\u002Fcourses\u002Fcaching\u002F02.invalidation","fahMLdo2hiDD5K_BQHGZCeYMOkIquLGdRIDAy0WkguI",{"id":280,"title":281,"access":6,"body":282,"description":286,"draft":274,"estimatedMinutes":287,"extension":270,"featured":274,"icon":288,"lang":271,"level":289,"meta":290,"navigation":273,"order":66,"path":291,"prerequisites":292,"resources":293,"seo":299,"sku":297,"stem":300,"subjects":301,"summary":303,"tags":304,"updated":309,"__hash__":310},"courses\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002Findex.md","Caching strategies",{"type":8,"value":283,"toc":284},[],{"title":58,"searchDepth":108,"depth":108,"links":285},[],"Read-through, write-behind, invalidation and the failure modes each one buys.",40,"lucide:layers","advanced",{},"\u002Flearn\u002Fen\u002Fcourses\u002Fcaching",[],[294],{"label":295,"file":296,"access":6,"sku":297,"size":298},"Caching decision matrix","caching-decision-matrix.pdf","topic-caching-strategies","310 KB",{"title":281,"description":286},"learn\u002Fen\u002Fcourses\u002Fcaching\u002Findex",[302],"system-design","A cache is a bet that reading stale data is cheaper than reading correct data.\nThe strategies differ in who writes to the cache, when, and what happens when\nthe cache and the source disagree. Cache-aside is the default because it fails\nsafely. Write-behind is the fastest and loses data on a crash. Almost every\nproduction incident involving a cache comes down to invalidation, stampedes, or\na cache that was quietly doing nothing at all.\n",[305,306,307,308],"caching","performance","consistency","redis","2026-08-06","mqYWifp5mzccLyzSY681N-Yn1wymognvHpRRfhOtFBI",[312,515],{"id":313,"title":314,"access":315,"body":316,"description":509,"extension":270,"lang":271,"meta":510,"navigation":273,"order":66,"partial":273,"path":511,"seo":512,"stem":513,"__hash__":514},"lessons\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002F01.strategies.md","The four strategies","free",{"type":8,"value":317,"toc":503},[318,321,324,328,331,461,464,468,471,474,478,481,484,488,491,494,500],[11,319,314],{"id":320},"the-four-strategies",[15,322,323],{},"Every caching pattern answers two questions: who populates the cache, and when is\nthe source of truth updated relative to it.",[19,325,327],{"id":326},"cache-aside","Cache-aside",[15,329,330],{},"The application checks the cache, and on a miss reads the database and populates\nthe cache itself. The cache has no knowledge of the database.",[53,332,334],{"className":55,"code":333,"language":57,"meta":58,"style":58},"def get_user(user_id):\n    cached = cache.get(f\"user:{user_id}\")\n    if cached is not None:\n        return cached\n    user = db.query(\"SELECT * FROM users WHERE id = %s\", user_id)\n    cache.set(f\"user:{user_id}\", user, ttl=300)\n    return user\n",[60,335,336,346,370,390,399,421,453],{"__ignoreMap":58},[63,337,338,340,343],{"class":65,"line":66},[63,339,70],{"class":69},[63,341,342],{"class":73}," get_user",[63,344,345],{"class":77},"(user_id):\n",[63,347,348,351,353,356,358,360,362,364,366,368],{"class":65,"line":91},[63,349,350],{"class":77},"    cached ",[63,352,81],{"class":69},[63,354,355],{"class":77}," cache.get(",[63,357,184],{"class":69},[63,359,188],{"class":187},[63,361,191],{"class":69},[63,363,194],{"class":77},[63,365,197],{"class":69},[63,367,200],{"class":187},[63,369,203],{"class":77},[63,371,372,375,378,381,384,387],{"class":65,"line":108},[63,373,374],{"class":69},"    if",[63,376,377],{"class":77}," cached ",[63,379,380],{"class":69},"is",[63,382,383],{"class":69}," not",[63,385,386],{"class":84}," None",[63,388,389],{"class":77},":\n",[63,391,393,396],{"class":65,"line":392},4,[63,394,395],{"class":69},"        return",[63,397,398],{"class":77}," cached\n",[63,400,402,405,407,410,413,416,418],{"class":65,"line":401},5,[63,403,404],{"class":77},"    user ",[63,406,81],{"class":69},[63,408,409],{"class":77}," db.query(",[63,411,412],{"class":187},"\"SELECT * FROM users WHERE id = ",[63,414,415],{"class":69},"%s",[63,417,200],{"class":187},[63,419,420],{"class":77},", user_id)\n",[63,422,424,427,429,431,433,435,437,439,442,446,448,451],{"class":65,"line":423},6,[63,425,426],{"class":77},"    cache.set(",[63,428,184],{"class":69},[63,430,188],{"class":187},[63,432,191],{"class":69},[63,434,194],{"class":77},[63,436,197],{"class":69},[63,438,200],{"class":187},[63,440,441],{"class":77},", user, ",[63,443,445],{"class":444},"siJwO","ttl",[63,447,81],{"class":69},[63,449,450],{"class":84},"300",[63,452,203],{"class":77},[63,454,456,458],{"class":65,"line":455},7,[63,457,111],{"class":69},[63,459,460],{"class":77}," user\n",[15,462,463],{},"This is the default for a reason: if the cache is down, every request simply\nbecomes a database read. Degraded, not broken.",[19,465,467],{"id":466},"read-through","Read-through",[15,469,470],{},"The cache sits inline. The application only talks to the cache, which fetches from\nthe database on a miss. Logic moves out of the application and into the cache layer.",[15,472,473],{},"Cleaner call sites, but the cache is now on the critical path — if it is unavailable,\nreads fail entirely rather than falling back.",[19,475,477],{"id":476},"write-through","Write-through",[15,479,480],{},"Writes go to the cache, which synchronously writes to the database before\nacknowledging. The cache is never stale.",[15,482,483],{},"The cost is write latency: every write pays for both hops. Worth it when reads\nvastly outnumber writes and stale reads are unacceptable.",[19,485,487],{"id":486},"write-behind","Write-behind",[15,489,490],{},"Writes land in the cache and are flushed to the database asynchronously.",[15,492,493],{},"Fastest writes available, and the only strategy that can lose acknowledged data. A\ncrash between acknowledgement and flush loses whatever was buffered.",[495,496,497],"warning",{},[15,498,499],{},"Write-behind is appropriate for metrics, view counts and analytics events. It is not\nappropriate for anything a user would notice going missing — orders, payments,\nmessages. The performance gain is real, and so is the data loss.",[260,501,502],{},"html pre.shiki code .sEYkB, html code.shiki .sEYkB{--shiki-default:#F47067;--shiki-dark:#F47067}html pre.shiki code .s-wk_, html code.shiki .s-wk_{--shiki-default:#DCBDFB;--shiki-dark:#DCBDFB}html pre.shiki code .sM9_K, html code.shiki .sM9_K{--shiki-default:#ADBAC7;--shiki-dark:#ADBAC7}html pre.shiki code .szYpP, html code.shiki .szYpP{--shiki-default:#96D0FF;--shiki-dark:#96D0FF}html pre.shiki code .sQdni, html code.shiki .sQdni{--shiki-default:#6CB6FF;--shiki-dark:#6CB6FF}html pre.shiki code .siJwO, html code.shiki .siJwO{--shiki-default:#F69D50;--shiki-dark:#F69D50}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":58,"searchDepth":108,"depth":108,"links":504},[505,506,507,508],{"id":326,"depth":91,"text":327},{"id":466,"depth":91,"text":467},{"id":476,"depth":91,"text":477},{"id":486,"depth":91,"text":487},"Cache-aside, read-through, write-through and write-behind compared.",{},"\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002Fstrategies",{"title":314,"description":509},"learn\u002Fen\u002Fcourses\u002Fcaching\u002F01.strategies","sh2NUIv6r7JjhJWD_OzLrfaRSj7urg2L7nJtqWFgm04",{"id":4,"title":5,"access":6,"body":516,"description":269,"extension":270,"lang":271,"meta":690,"navigation":273,"order":91,"partial":274,"path":275,"seo":691,"stem":277,"__hash__":278},{"type":8,"value":517,"toc":684},[518,520,522,524,526,528,530,532,534,538,542,594,598,602,604,606,640,642,644,646,648,680,682],[11,519,5],{"id":13},[15,521,17],{},[19,523,22],{"id":21},[15,525,25],{},[19,527,29],{"id":28},[15,529,32],{},[15,531,35],{},[15,533,38],{},[15,535,536,45],{},[42,537,44],{},[15,539,540,51],{},[42,541,50],{},[53,543,544],{"className":55,"code":56,"language":57,"meta":58,"style":58},[60,545,546,560,572],{"__ignoreMap":58},[63,547,548,550,552,554,556,558],{"class":65,"line":66},[63,549,70],{"class":69},[63,551,74],{"class":73},[63,553,78],{"class":77},[63,555,81],{"class":69},[63,557,85],{"class":84},[63,559,88],{"class":77},[63,561,562,564,566,568,570],{"class":65,"line":91},[63,563,94],{"class":77},[63,565,81],{"class":69},[63,567,99],{"class":77},[63,569,102],{"class":69},[63,571,105],{"class":77},[63,573,574,576,578,580,582,584,586,588,590,592],{"class":65,"line":108},[63,575,111],{"class":69},[63,577,114],{"class":77},[63,579,117],{"class":69},[63,581,120],{"class":77},[63,583,123],{"class":69},[63,585,126],{"class":77},[63,587,123],{"class":69},[63,589,131],{"class":77},[63,591,134],{"class":69},[63,593,137],{"class":77},[15,595,596,143],{},[42,597,142],{},[145,599,600],{},[15,601,149],{},[19,603,153],{"id":152},[15,605,156],{},[53,607,608],{"className":55,"code":159,"language":57,"meta":58,"style":58},[60,609,610,618,622],{"__ignoreMap":58},[63,611,612,614,616],{"class":65,"line":66},[63,613,70],{"class":69},[63,615,168],{"class":73},[63,617,171],{"class":77},[63,619,620],{"class":65,"line":91},[63,621,176],{"class":77},[63,623,624,626,628,630,632,634,636,638],{"class":65,"line":108},[63,625,181],{"class":77},[63,627,184],{"class":69},[63,629,188],{"class":187},[63,631,191],{"class":69},[63,633,194],{"class":77},[63,635,197],{"class":69},[63,637,200],{"class":187},[63,639,203],{"class":77},[15,641,206],{},[15,643,209],{},[19,645,213],{"id":212},[15,647,216],{},[53,649,650],{"className":55,"code":219,"language":57,"meta":58,"style":58},[60,651,652],{"__ignoreMap":58},[63,653,654,656,658,660,662,664,666,668,670,672,674,676,678],{"class":65,"line":66},[63,655,226],{"class":77},[63,657,184],{"class":69},[63,659,188],{"class":187},[63,661,191],{"class":69},[63,663,194],{"class":77},[63,665,197],{"class":69},[63,667,239],{"class":187},[63,669,191],{"class":69},[63,671,244],{"class":77},[63,673,197],{"class":69},[63,675,200],{"class":187},[63,677,251],{"class":77},[63,679,255],{"class":254},[15,681,258],{},[260,683,262],{},{"title":58,"searchDepth":108,"depth":108,"links":685},[686,687,688,689],{"id":21,"depth":91,"text":22},{"id":28,"depth":91,"text":29},{"id":152,"depth":91,"text":153},{"id":212,"depth":91,"text":213},{},{"title":5,"description":269},{"id":280,"title":281,"access":6,"body":693,"description":286,"draft":274,"estimatedMinutes":287,"extension":270,"featured":274,"icon":288,"lang":271,"level":289,"meta":697,"navigation":273,"order":66,"path":291,"prerequisites":698,"resources":699,"seo":701,"sku":297,"stem":300,"subjects":702,"summary":303,"tags":703,"updated":309,"__hash__":310},{"type":8,"value":694,"toc":695},[],{"title":58,"searchDepth":108,"depth":108,"links":696},[],{},[],[700],{"label":295,"file":296,"access":6,"sku":297,"size":298},{"title":281,"description":286},[302],[305,306,307,308],{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":707},0,24,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"\u002F>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":709},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":711},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":713},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\u002F>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":715},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":717},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"\u002F>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":719},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M9 3v18\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":721},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":723},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\"\u002F>\u003Cpath d=\"M7 11V7a5 5 0 0 1 10 0v4\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":725},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M16 10a4 4 0 0 1-8 0M3.103 6.034h17.794\"\u002F>\u003Cpath d=\"M3.4 5.467a2 2 0 0 0-.4 1.2V20a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.667a2 2 0 0 0-.4-1.2l-2-2.667A2 2 0 0 0 17 2H7a2 2 0 0 0-1.6.8z\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":727},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m12 19l-7-7l7-7m7 7H5\"\u002F>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":729},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m15 10l5 5l-5 5\"\u002F>\u003Cpath d=\"M4 4v7a4 4 0 0 0 4 4h12\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":731},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m22 7l-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":733},"\u003Cpath fill=\"currentColor\" d=\"M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z\"\u002F>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":735,"hidden":273},"\u003Cpath fill=\"currentColor\" d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z\"\u002F>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":737},"\u003Cpath fill=\"currentColor\" d=\"M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12s-5.385 12-12 12m10.12-10.358c-.35-.11-3.17-.953-6.384-.438c1.34 3.684 1.887 6.684 1.992 7.308a10.28 10.28 0 0 0 4.395-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4a10.16 10.16 0 0 0 6.29 2.166c1.42 0 2.77-.29 4-.814zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765q.202-.067.405-.12q-.392-.879-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248a66 66 0 0 0-3.8-5.928a10.28 10.28 0 0 0-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6c3.645-1.365 5.19-3.44 5.373-3.702A10.2 10.2 0 0 0 12 1.764c-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04c.24.49.47.985.68 1.486c.08.18.15.36.22.53c3.41-.43 6.8.26 7.14.33c-.02-2.42-.88-4.64-2.31-6.38z\"\u002F>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":739},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",null,{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":742},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z\"\u002F>\u003Cpath d=\"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12\"\u002F>\u003Cpath d=\"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":744},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6\"\u002F>\u003Crect width=\"12\" height=\"8\" x=\"6\" y=\"14\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":746},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M21.42 10.922a1 1 0 0 0-.019-1.838L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.832l8.57 3.908a2 2 0 0 0 1.66 0zM22 10v6\"\u002F>\u003Cpath d=\"M6 12.5V16a6 3 0 0 0 12 0v-3.5\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":748},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 2v8l3-3l3 3V2\"\u002F>\u003Cpath d=\"M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20\"\u002F>\u003C\u002Fg>",{"left":705,"top":705,"width":706,"height":706,"rotate":705,"vFlip":274,"hFlip":274,"body":750},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4M2 6h4m-4 4h4m-4 4h4m-4 4h4\"\u002F>\u003Cpath d=\"M21.378 5.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z\"\u002F>\u003C\u002Fg>",1787597895508]