[{"data":1,"prerenderedAt":8076},["ShallowReactive",2],{"page-\u002Fdart\u002F19-exercises-and-projects":3},{"id":4,"title":5,"body":6,"description":8069,"extension":8070,"meta":8071,"navigation":71,"path":8072,"seo":8073,"stem":8074,"__hash__":8075},"content\u002Fdart\u002F19-exercises-and-projects.md","Dart — Production Projects & Capstone Architecture",{"type":7,"value":8,"toc":8055},"minimark",[9,13,18,27,1757,1761,1772,2806,2810,2813,4496,4500,4503,4513,4518,4738,4742,6787,6791,7450,7454,7542,7546,7692,7696,7710,7819,7826,8051],[10,11,5],"h1",{"id":12},"dart-production-projects-capstone-architecture",[14,15,17],"h2",{"id":16},"project-1-production-cli-argument-parser","Project 1 — Production CLI Argument Parser",[19,20,21,22,26],"p",{},"A CLI tool with subcommands, validation, and exit codes. Demonstrates ",[23,24,25],"code",{},"args"," package, exhaustive switches, and error handling.",[28,29,31],"code-wrapper",{"language":30},"dart",[32,33,37],"pre",{"className":34,"code":35,"language":30,"meta":36,"style":36},"language-dart shiki shiki-themes github-light github-dark","import 'package:args\u002Fargs.dart';\nimport 'dart:io';\n\n\u002F\u002F ── Subcommand definitions (exhaustive enum) ──\nenum Command { convert, info, version }\n\n\u002F\u002F ── Temperature units (enhanced enum with conversion logic) ──\nenum Unit {\n  celsius('°C', 'Celsius'),\n  fahrenheit('°F', 'Fahrenheit'),\n  kelvin('K', 'Kelvin');\n\n  final String symbol;\n  final String name;\n  const Unit(this.symbol, this.name);\n\n  \u002F\u002F\u002F Convert FROM this unit TO Celsius.\n  double toCelsius(double value) => switch (this) {\n    Unit.celsius => value,\n    Unit.fahrenheit => (value - 32) * 5 \u002F 9,\n    Unit.kelvin => value - 273.15,\n  };\n\n  \u002F\u002F\u002F Convert FROM Celsius TO this unit.\n  double fromCelsius(double celsius) => switch (this) {\n    Unit.celsius => celsius,\n    Unit.fahrenheit => celsius * 9 \u002F 5 + 32,\n    Unit.kelvin => celsius + 273.15,\n  };\n\n  static Unit parse(String s) => switch (s.toLowerCase()) {\n    'c' || 'celsius' => Unit.celsius,\n    'f' || 'fahrenheit' => Unit.fahrenheit,\n    'k' || 'kelvin' => Unit.kelvin,\n    _ => throw UsageException('Unknown unit: $s', 'Use c, f, or k'),\n  };\n\n  double convertTo(double value, Unit target) =>\n      target.fromCelsius(toCelsius(value));\n}\n\n\u002F\u002F ── The parser (top-level, reusable) ──\nArgParser buildParser() {\n  return ArgParser()\n    ..addCommand('convert')\n    ..addCommand('info')\n    ..addCommand('version');\n}\n\n\u002F\u002F ── Entry point — thin, delegates to handlers ──\nvoid main(List\u003CString> arguments) {\n  try {\n    final parser = buildParser();\n    final results = parser.parse(arguments);\n\n    final command = results.command;\n    if (command == null) {\n      printUsage(parser);\n      exit(64);  \u002F\u002F EX_USAGE\n    }\n\n    final cmd = Command.values.firstWhere(\n      (c) => c.name == command.name,\n      orElse: () => throw UsageException('Unknown command', ''),\n    );\n\n    final exitCode = switch (cmd) {\n      Command.convert => handleConvert(command),\n      Command.info => handleInfo(command),\n      Command.version => handleVersion(),\n    };\n    exit(exitCode);\n  } on UsageException catch (e) {\n    stderr.writeln('Error: ${e.message}');\n    stderr.writeln(e.usage);\n    exit(64);\n  } catch (e, stack) {\n    stderr.writeln('Unexpected error: $e\\n$stack');\n    exit(70);  \u002F\u002F EX_SOFTWARE\n  }\n}\n\nint handleConvert(ArgResults args) {\n  if (args.rest.length != 3) {\n    throw UsageException(\n      'convert requires 3 arguments',\n      'convert \u003Cvalue> \u003Cfrom> \u003Cto>',\n    );\n  }\n\n  final value = double.tryParse(args.rest[0]);\n  if (value == null) {\n    throw UsageException('Invalid value: ${args.rest[0]}', 'Value must be a number');\n  }\n\n  final from = Unit.parse(args.rest[1]);\n  final to = Unit.parse(args.rest[2]);\n  final result = from.convertTo(value, to);\n\n  print('${value.toStringAsFixed(2)}${from.symbol} = '\n      '${result.toStringAsFixed(2)}${to.symbol}');\n  return 0;\n}\n\nint handleInfo(ArgResults args) {\n  for (final unit in Unit.values) {\n    print('${unit.name}: ${unit.symbol} (${unit.name})');\n  }\n  return 0;\n}\n\nint handleVersion() {\n  print('tempc v1.0.0');\n  return 0;\n}\n\nvoid printUsage(ArgParser parser) {\n  print('Usage: tempc \u003Ccommand> [arguments]');\n  print(parser.usage);\n}\n\nclass UsageException implements Exception {\n  final String message;\n  final String usage;\n  UsageException(this.message, this.usage);\n  @override\n  String toString() => message;\n}\n","",[23,38,39,56,66,73,80,93,98,104,115,137,155,174,179,191,201,222,227,233,264,278,315,335,341,346,352,377,389,416,434,439,444,476,496,514,532,567,572,577,601,618,624,629,635,647,659,676,690,704,709,714,720,742,750,767,786,791,804,821,830,847,853,858,879,895,925,931,936,951,968,983,999,1005,1014,1031,1064,1074,1085,1096,1124,1139,1145,1150,1155,1171,1188,1198,1206,1214,1219,1224,1229,1255,1268,1306,1311,1316,1339,1362,1381,1386,1426,1460,1470,1475,1480,1493,1515,1567,1572,1581,1586,1591,1600,1612,1621,1626,1631,1646,1658,1666,1671,1676,1692,1702,1712,1730,1736,1752],{"__ignoreMap":36},[40,41,44,48,52],"span",{"class":42,"line":43},"line",1,[40,45,47],{"class":46},"svdQ7","import",[40,49,51],{"class":50},"sJ6F3"," 'package:args\u002Fargs.dart'",[40,53,55],{"class":54},"ssxIu",";\n",[40,57,59,61,64],{"class":42,"line":58},2,[40,60,47],{"class":46},[40,62,63],{"class":50}," 'dart:io'",[40,65,55],{"class":54},[40,67,69],{"class":42,"line":68},3,[40,70,72],{"emptyLinePlaceholder":71},true,"\n",[40,74,76],{"class":42,"line":75},4,[40,77,79],{"class":78},"sdCPZ","\u002F\u002F ── Subcommand definitions (exhaustive enum) ──\n",[40,81,83,86,90],{"class":42,"line":82},5,[40,84,85],{"class":46},"enum",[40,87,89],{"class":88},"snvgF"," Command",[40,91,92],{"class":54}," { convert, info, version }\n",[40,94,96],{"class":42,"line":95},6,[40,97,72],{"emptyLinePlaceholder":71},[40,99,101],{"class":42,"line":100},7,[40,102,103],{"class":78},"\u002F\u002F ── Temperature units (enhanced enum with conversion logic) ──\n",[40,105,107,109,112],{"class":42,"line":106},8,[40,108,85],{"class":46},[40,110,111],{"class":88}," Unit",[40,113,114],{"class":54}," {\n",[40,116,118,122,125,128,131,134],{"class":42,"line":117},9,[40,119,121],{"class":120},"sIsaT","  celsius",[40,123,124],{"class":54},"(",[40,126,127],{"class":50},"'°C'",[40,129,130],{"class":54},", ",[40,132,133],{"class":50},"'Celsius'",[40,135,136],{"class":54},"),\n",[40,138,140,143,145,148,150,153],{"class":42,"line":139},10,[40,141,142],{"class":120},"  fahrenheit",[40,144,124],{"class":54},[40,146,147],{"class":50},"'°F'",[40,149,130],{"class":54},[40,151,152],{"class":50},"'Fahrenheit'",[40,154,136],{"class":54},[40,156,158,161,163,166,168,171],{"class":42,"line":157},11,[40,159,160],{"class":120},"  kelvin",[40,162,124],{"class":54},[40,164,165],{"class":50},"'K'",[40,167,130],{"class":54},[40,169,170],{"class":50},"'Kelvin'",[40,172,173],{"class":54},");\n",[40,175,177],{"class":42,"line":176},12,[40,178,72],{"emptyLinePlaceholder":71},[40,180,182,185,188],{"class":42,"line":181},13,[40,183,184],{"class":46},"  final",[40,186,187],{"class":88}," String",[40,189,190],{"class":54}," symbol;\n",[40,192,194,196,198],{"class":42,"line":193},14,[40,195,184],{"class":46},[40,197,187],{"class":88},[40,199,200],{"class":54}," name;\n",[40,202,204,207,209,211,214,217,219],{"class":42,"line":203},15,[40,205,206],{"class":46},"  const",[40,208,111],{"class":88},[40,210,124],{"class":54},[40,212,213],{"class":88},"this",[40,215,216],{"class":54},".symbol, ",[40,218,213],{"class":88},[40,220,221],{"class":54},".name);\n",[40,223,225],{"class":42,"line":224},16,[40,226,72],{"emptyLinePlaceholder":71},[40,228,230],{"class":42,"line":229},17,[40,231,232],{"class":78},"  \u002F\u002F\u002F Convert FROM this unit TO Celsius.\n",[40,234,236,239,242,244,247,250,253,256,259,261],{"class":42,"line":235},18,[40,237,238],{"class":88},"  double",[40,240,241],{"class":120}," toCelsius",[40,243,124],{"class":54},[40,245,246],{"class":88},"double",[40,248,249],{"class":54}," value) ",[40,251,252],{"class":46},"=>",[40,254,255],{"class":46}," switch",[40,257,258],{"class":54}," (",[40,260,213],{"class":88},[40,262,263],{"class":54},") {\n",[40,265,267,270,273,275],{"class":42,"line":266},19,[40,268,269],{"class":88},"    Unit",[40,271,272],{"class":54},".celsius ",[40,274,252],{"class":46},[40,276,277],{"class":54}," value,\n",[40,279,281,283,286,288,291,294,297,300,303,306,309,312],{"class":42,"line":280},20,[40,282,269],{"class":88},[40,284,285],{"class":54},".fahrenheit ",[40,287,252],{"class":46},[40,289,290],{"class":54}," (value ",[40,292,293],{"class":46},"-",[40,295,296],{"class":88}," 32",[40,298,299],{"class":54},") ",[40,301,302],{"class":46},"*",[40,304,305],{"class":88}," 5",[40,307,308],{"class":46}," \u002F",[40,310,311],{"class":88}," 9",[40,313,314],{"class":54},",\n",[40,316,318,320,323,325,328,330,333],{"class":42,"line":317},21,[40,319,269],{"class":88},[40,321,322],{"class":54},".kelvin ",[40,324,252],{"class":46},[40,326,327],{"class":54}," value ",[40,329,293],{"class":46},[40,331,332],{"class":88}," 273.15",[40,334,314],{"class":54},[40,336,338],{"class":42,"line":337},22,[40,339,340],{"class":54},"  };\n",[40,342,344],{"class":42,"line":343},23,[40,345,72],{"emptyLinePlaceholder":71},[40,347,349],{"class":42,"line":348},24,[40,350,351],{"class":78},"  \u002F\u002F\u002F Convert FROM Celsius TO this unit.\n",[40,353,355,357,360,362,364,367,369,371,373,375],{"class":42,"line":354},25,[40,356,238],{"class":88},[40,358,359],{"class":120}," fromCelsius",[40,361,124],{"class":54},[40,363,246],{"class":88},[40,365,366],{"class":54}," celsius) ",[40,368,252],{"class":46},[40,370,255],{"class":46},[40,372,258],{"class":54},[40,374,213],{"class":88},[40,376,263],{"class":54},[40,378,380,382,384,386],{"class":42,"line":379},26,[40,381,269],{"class":88},[40,383,272],{"class":54},[40,385,252],{"class":46},[40,387,388],{"class":54}," celsius,\n",[40,390,392,394,396,398,401,403,405,407,409,412,414],{"class":42,"line":391},27,[40,393,269],{"class":88},[40,395,285],{"class":54},[40,397,252],{"class":46},[40,399,400],{"class":54}," celsius ",[40,402,302],{"class":46},[40,404,311],{"class":88},[40,406,308],{"class":46},[40,408,305],{"class":88},[40,410,411],{"class":46}," +",[40,413,296],{"class":88},[40,415,314],{"class":54},[40,417,419,421,423,425,427,430,432],{"class":42,"line":418},28,[40,420,269],{"class":88},[40,422,322],{"class":54},[40,424,252],{"class":46},[40,426,400],{"class":54},[40,428,429],{"class":46},"+",[40,431,332],{"class":88},[40,433,314],{"class":54},[40,435,437],{"class":42,"line":436},29,[40,438,340],{"class":54},[40,440,442],{"class":42,"line":441},30,[40,443,72],{"emptyLinePlaceholder":71},[40,445,447,450,452,455,457,460,463,465,467,470,473],{"class":42,"line":446},31,[40,448,449],{"class":46},"  static",[40,451,111],{"class":88},[40,453,454],{"class":120}," parse",[40,456,124],{"class":54},[40,458,459],{"class":88},"String",[40,461,462],{"class":54}," s) ",[40,464,252],{"class":46},[40,466,255],{"class":46},[40,468,469],{"class":54}," (s.",[40,471,472],{"class":120},"toLowerCase",[40,474,475],{"class":54},"()) {\n",[40,477,479,482,485,488,491,493],{"class":42,"line":478},32,[40,480,481],{"class":50},"    'c'",[40,483,484],{"class":46}," ||",[40,486,487],{"class":50}," 'celsius'",[40,489,490],{"class":46}," =>",[40,492,111],{"class":88},[40,494,495],{"class":54},".celsius,\n",[40,497,499,502,504,507,509,511],{"class":42,"line":498},33,[40,500,501],{"class":50},"    'f'",[40,503,484],{"class":46},[40,505,506],{"class":50}," 'fahrenheit'",[40,508,490],{"class":46},[40,510,111],{"class":88},[40,512,513],{"class":54},".fahrenheit,\n",[40,515,517,520,522,525,527,529],{"class":42,"line":516},34,[40,518,519],{"class":50},"    'k'",[40,521,484],{"class":46},[40,523,524],{"class":50}," 'kelvin'",[40,526,490],{"class":46},[40,528,111],{"class":88},[40,530,531],{"class":54},".kelvin,\n",[40,533,535,538,540,543,546,548,551,554,557,560,562,565],{"class":42,"line":534},35,[40,536,537],{"class":54},"    _ ",[40,539,252],{"class":46},[40,541,542],{"class":46}," throw",[40,544,545],{"class":88}," UsageException",[40,547,124],{"class":54},[40,549,550],{"class":50},"'Unknown unit: ",[40,552,553],{"class":50},"$",[40,555,556],{"class":88},"s",[40,558,559],{"class":50},"'",[40,561,130],{"class":54},[40,563,564],{"class":50},"'Use c, f, or k'",[40,566,136],{"class":54},[40,568,570],{"class":42,"line":569},36,[40,571,340],{"class":54},[40,573,575],{"class":42,"line":574},37,[40,576,72],{"emptyLinePlaceholder":71},[40,578,580,582,585,587,589,592,595,598],{"class":42,"line":579},38,[40,581,238],{"class":88},[40,583,584],{"class":120}," convertTo",[40,586,124],{"class":54},[40,588,246],{"class":88},[40,590,591],{"class":54}," value, ",[40,593,594],{"class":88},"Unit",[40,596,597],{"class":54}," target) ",[40,599,600],{"class":46},"=>\n",[40,602,604,607,610,612,615],{"class":42,"line":603},39,[40,605,606],{"class":54},"      target.",[40,608,609],{"class":120},"fromCelsius",[40,611,124],{"class":54},[40,613,614],{"class":120},"toCelsius",[40,616,617],{"class":54},"(value));\n",[40,619,621],{"class":42,"line":620},40,[40,622,623],{"class":54},"}\n",[40,625,627],{"class":42,"line":626},41,[40,628,72],{"emptyLinePlaceholder":71},[40,630,632],{"class":42,"line":631},42,[40,633,634],{"class":78},"\u002F\u002F ── The parser (top-level, reusable) ──\n",[40,636,638,641,644],{"class":42,"line":637},43,[40,639,640],{"class":88},"ArgParser",[40,642,643],{"class":120}," buildParser",[40,645,646],{"class":54},"() {\n",[40,648,650,653,656],{"class":42,"line":649},44,[40,651,652],{"class":46},"  return",[40,654,655],{"class":88}," ArgParser",[40,657,658],{"class":54},"()\n",[40,660,662,665,668,670,673],{"class":42,"line":661},45,[40,663,664],{"class":54},"    ..",[40,666,667],{"class":120},"addCommand",[40,669,124],{"class":54},[40,671,672],{"class":50},"'convert'",[40,674,675],{"class":54},")\n",[40,677,679,681,683,685,688],{"class":42,"line":678},46,[40,680,664],{"class":54},[40,682,667],{"class":120},[40,684,124],{"class":54},[40,686,687],{"class":50},"'info'",[40,689,675],{"class":54},[40,691,693,695,697,699,702],{"class":42,"line":692},47,[40,694,664],{"class":54},[40,696,667],{"class":120},[40,698,124],{"class":54},[40,700,701],{"class":50},"'version'",[40,703,173],{"class":54},[40,705,707],{"class":42,"line":706},48,[40,708,623],{"class":54},[40,710,712],{"class":42,"line":711},49,[40,713,72],{"emptyLinePlaceholder":71},[40,715,717],{"class":42,"line":716},50,[40,718,719],{"class":78},"\u002F\u002F ── Entry point — thin, delegates to handlers ──\n",[40,721,723,726,729,731,734,737,739],{"class":42,"line":722},51,[40,724,725],{"class":46},"void",[40,727,728],{"class":120}," main",[40,730,124],{"class":54},[40,732,733],{"class":88},"List",[40,735,736],{"class":54},"\u003C",[40,738,459],{"class":88},[40,740,741],{"class":54},"> arguments) {\n",[40,743,745,748],{"class":42,"line":744},52,[40,746,747],{"class":46},"  try",[40,749,114],{"class":54},[40,751,753,756,759,762,764],{"class":42,"line":752},53,[40,754,755],{"class":46},"    final",[40,757,758],{"class":54}," parser ",[40,760,761],{"class":46},"=",[40,763,643],{"class":120},[40,765,766],{"class":54},"();\n",[40,768,770,772,775,777,780,783],{"class":42,"line":769},54,[40,771,755],{"class":46},[40,773,774],{"class":54}," results ",[40,776,761],{"class":46},[40,778,779],{"class":54}," parser.",[40,781,782],{"class":120},"parse",[40,784,785],{"class":54},"(arguments);\n",[40,787,789],{"class":42,"line":788},55,[40,790,72],{"emptyLinePlaceholder":71},[40,792,794,796,799,801],{"class":42,"line":793},56,[40,795,755],{"class":46},[40,797,798],{"class":54}," command ",[40,800,761],{"class":46},[40,802,803],{"class":54}," results.command;\n",[40,805,807,810,813,816,819],{"class":42,"line":806},57,[40,808,809],{"class":46},"    if",[40,811,812],{"class":54}," (command ",[40,814,815],{"class":46},"==",[40,817,818],{"class":88}," null",[40,820,263],{"class":54},[40,822,824,827],{"class":42,"line":823},58,[40,825,826],{"class":120},"      printUsage",[40,828,829],{"class":54},"(parser);\n",[40,831,833,836,838,841,844],{"class":42,"line":832},59,[40,834,835],{"class":120},"      exit",[40,837,124],{"class":54},[40,839,840],{"class":88},"64",[40,842,843],{"class":54},");  ",[40,845,846],{"class":78},"\u002F\u002F EX_USAGE\n",[40,848,850],{"class":42,"line":849},60,[40,851,852],{"class":54},"    }\n",[40,854,856],{"class":42,"line":855},61,[40,857,72],{"emptyLinePlaceholder":71},[40,859,861,863,866,868,870,873,876],{"class":42,"line":860},62,[40,862,755],{"class":46},[40,864,865],{"class":54}," cmd ",[40,867,761],{"class":46},[40,869,89],{"class":88},[40,871,872],{"class":54},".values.",[40,874,875],{"class":120},"firstWhere",[40,877,878],{"class":54},"(\n",[40,880,882,885,887,890,892],{"class":42,"line":881},63,[40,883,884],{"class":54},"      (c) ",[40,886,252],{"class":46},[40,888,889],{"class":54}," c.name ",[40,891,815],{"class":46},[40,893,894],{"class":54}," command.name,\n",[40,896,898,901,904,907,909,911,913,915,918,920,923],{"class":42,"line":897},64,[40,899,900],{"class":54},"      orElse",[40,902,903],{"class":46},":",[40,905,906],{"class":54}," () ",[40,908,252],{"class":46},[40,910,542],{"class":46},[40,912,545],{"class":88},[40,914,124],{"class":54},[40,916,917],{"class":50},"'Unknown command'",[40,919,130],{"class":54},[40,921,922],{"class":50},"''",[40,924,136],{"class":54},[40,926,928],{"class":42,"line":927},65,[40,929,930],{"class":54},"    );\n",[40,932,934],{"class":42,"line":933},66,[40,935,72],{"emptyLinePlaceholder":71},[40,937,939,941,944,946,948],{"class":42,"line":938},67,[40,940,755],{"class":46},[40,942,943],{"class":54}," exitCode ",[40,945,761],{"class":46},[40,947,255],{"class":46},[40,949,950],{"class":54}," (cmd) {\n",[40,952,954,957,960,962,965],{"class":42,"line":953},68,[40,955,956],{"class":88},"      Command",[40,958,959],{"class":54},".convert ",[40,961,252],{"class":46},[40,963,964],{"class":120}," handleConvert",[40,966,967],{"class":54},"(command),\n",[40,969,971,973,976,978,981],{"class":42,"line":970},69,[40,972,956],{"class":88},[40,974,975],{"class":54},".info ",[40,977,252],{"class":46},[40,979,980],{"class":120}," handleInfo",[40,982,967],{"class":54},[40,984,986,988,991,993,996],{"class":42,"line":985},70,[40,987,956],{"class":88},[40,989,990],{"class":54},".version ",[40,992,252],{"class":46},[40,994,995],{"class":120}," handleVersion",[40,997,998],{"class":54},"(),\n",[40,1000,1002],{"class":42,"line":1001},71,[40,1003,1004],{"class":54},"    };\n",[40,1006,1008,1011],{"class":42,"line":1007},72,[40,1009,1010],{"class":120},"    exit",[40,1012,1013],{"class":54},"(exitCode);\n",[40,1015,1017,1020,1023,1025,1028],{"class":42,"line":1016},73,[40,1018,1019],{"class":54},"  } ",[40,1021,1022],{"class":46},"on",[40,1024,545],{"class":88},[40,1026,1027],{"class":46}," catch",[40,1029,1030],{"class":54}," (e) {\n",[40,1032,1034,1037,1040,1042,1045,1048,1051,1054,1057,1060,1062],{"class":42,"line":1033},74,[40,1035,1036],{"class":54},"    stderr.",[40,1038,1039],{"class":120},"writeln",[40,1041,124],{"class":54},[40,1043,1044],{"class":50},"'Error: ",[40,1046,1047],{"class":50},"${",[40,1049,1050],{"class":88},"e",[40,1052,1053],{"class":50},".",[40,1055,1056],{"class":88},"message",[40,1058,1059],{"class":50},"}",[40,1061,559],{"class":50},[40,1063,173],{"class":54},[40,1065,1067,1069,1071],{"class":42,"line":1066},75,[40,1068,1036],{"class":54},[40,1070,1039],{"class":120},[40,1072,1073],{"class":54},"(e.usage);\n",[40,1075,1077,1079,1081,1083],{"class":42,"line":1076},76,[40,1078,1010],{"class":120},[40,1080,124],{"class":54},[40,1082,840],{"class":88},[40,1084,173],{"class":54},[40,1086,1088,1090,1093],{"class":42,"line":1087},77,[40,1089,1019],{"class":54},[40,1091,1092],{"class":46},"catch",[40,1094,1095],{"class":54}," (e, stack) {\n",[40,1097,1099,1101,1103,1105,1108,1110,1112,1115,1117,1120,1122],{"class":42,"line":1098},78,[40,1100,1036],{"class":54},[40,1102,1039],{"class":120},[40,1104,124],{"class":54},[40,1106,1107],{"class":50},"'Unexpected error: ",[40,1109,553],{"class":50},[40,1111,1050],{"class":88},[40,1113,1114],{"class":88},"\\n",[40,1116,553],{"class":50},[40,1118,1119],{"class":88},"stack",[40,1121,559],{"class":50},[40,1123,173],{"class":54},[40,1125,1127,1129,1131,1134,1136],{"class":42,"line":1126},79,[40,1128,1010],{"class":120},[40,1130,124],{"class":54},[40,1132,1133],{"class":88},"70",[40,1135,843],{"class":54},[40,1137,1138],{"class":78},"\u002F\u002F EX_SOFTWARE\n",[40,1140,1142],{"class":42,"line":1141},80,[40,1143,1144],{"class":54},"  }\n",[40,1146,1148],{"class":42,"line":1147},81,[40,1149,623],{"class":54},[40,1151,1153],{"class":42,"line":1152},82,[40,1154,72],{"emptyLinePlaceholder":71},[40,1156,1158,1161,1163,1165,1168],{"class":42,"line":1157},83,[40,1159,1160],{"class":88},"int",[40,1162,964],{"class":120},[40,1164,124],{"class":54},[40,1166,1167],{"class":88},"ArgResults",[40,1169,1170],{"class":54}," args) {\n",[40,1172,1174,1177,1180,1183,1186],{"class":42,"line":1173},84,[40,1175,1176],{"class":46},"  if",[40,1178,1179],{"class":54}," (args.rest.length ",[40,1181,1182],{"class":46},"!=",[40,1184,1185],{"class":88}," 3",[40,1187,263],{"class":54},[40,1189,1191,1194,1196],{"class":42,"line":1190},85,[40,1192,1193],{"class":46},"    throw",[40,1195,545],{"class":88},[40,1197,878],{"class":54},[40,1199,1201,1204],{"class":42,"line":1200},86,[40,1202,1203],{"class":50},"      'convert requires 3 arguments'",[40,1205,314],{"class":54},[40,1207,1209,1212],{"class":42,"line":1208},87,[40,1210,1211],{"class":50},"      'convert \u003Cvalue> \u003Cfrom> \u003Cto>'",[40,1213,314],{"class":54},[40,1215,1217],{"class":42,"line":1216},88,[40,1218,930],{"class":54},[40,1220,1222],{"class":42,"line":1221},89,[40,1223,1144],{"class":54},[40,1225,1227],{"class":42,"line":1226},90,[40,1228,72],{"emptyLinePlaceholder":71},[40,1230,1232,1234,1236,1238,1241,1243,1246,1249,1252],{"class":42,"line":1231},91,[40,1233,184],{"class":46},[40,1235,327],{"class":54},[40,1237,761],{"class":46},[40,1239,1240],{"class":88}," double",[40,1242,1053],{"class":54},[40,1244,1245],{"class":120},"tryParse",[40,1247,1248],{"class":54},"(args.rest[",[40,1250,1251],{"class":88},"0",[40,1253,1254],{"class":54},"]);\n",[40,1256,1258,1260,1262,1264,1266],{"class":42,"line":1257},92,[40,1259,1176],{"class":46},[40,1261,290],{"class":54},[40,1263,815],{"class":46},[40,1265,818],{"class":88},[40,1267,263],{"class":54},[40,1269,1271,1273,1275,1277,1280,1282,1284,1286,1289,1292,1294,1297,1299,1301,1304],{"class":42,"line":1270},93,[40,1272,1193],{"class":46},[40,1274,545],{"class":88},[40,1276,124],{"class":54},[40,1278,1279],{"class":50},"'Invalid value: ",[40,1281,1047],{"class":50},[40,1283,25],{"class":88},[40,1285,1053],{"class":50},[40,1287,1288],{"class":88},"rest",[40,1290,1291],{"class":50},"[",[40,1293,1251],{"class":88},[40,1295,1296],{"class":50},"]}",[40,1298,559],{"class":50},[40,1300,130],{"class":54},[40,1302,1303],{"class":50},"'Value must be a number'",[40,1305,173],{"class":54},[40,1307,1309],{"class":42,"line":1308},94,[40,1310,1144],{"class":54},[40,1312,1314],{"class":42,"line":1313},95,[40,1315,72],{"emptyLinePlaceholder":71},[40,1317,1319,1321,1324,1326,1328,1330,1332,1334,1337],{"class":42,"line":1318},96,[40,1320,184],{"class":46},[40,1322,1323],{"class":54}," from ",[40,1325,761],{"class":46},[40,1327,111],{"class":88},[40,1329,1053],{"class":54},[40,1331,782],{"class":120},[40,1333,1248],{"class":54},[40,1335,1336],{"class":88},"1",[40,1338,1254],{"class":54},[40,1340,1342,1344,1347,1349,1351,1353,1355,1357,1360],{"class":42,"line":1341},97,[40,1343,184],{"class":46},[40,1345,1346],{"class":54}," to ",[40,1348,761],{"class":46},[40,1350,111],{"class":88},[40,1352,1053],{"class":54},[40,1354,782],{"class":120},[40,1356,1248],{"class":54},[40,1358,1359],{"class":88},"2",[40,1361,1254],{"class":54},[40,1363,1365,1367,1370,1372,1375,1378],{"class":42,"line":1364},98,[40,1366,184],{"class":46},[40,1368,1369],{"class":54}," result ",[40,1371,761],{"class":46},[40,1373,1374],{"class":54}," from.",[40,1376,1377],{"class":120},"convertTo",[40,1379,1380],{"class":54},"(value, to);\n",[40,1382,1384],{"class":42,"line":1383},99,[40,1385,72],{"emptyLinePlaceholder":71},[40,1387,1389,1392,1394,1396,1398,1401,1403,1406,1408,1410,1413,1416,1418,1421,1423],{"class":42,"line":1388},100,[40,1390,1391],{"class":120},"  print",[40,1393,124],{"class":54},[40,1395,559],{"class":50},[40,1397,1047],{"class":50},[40,1399,1400],{"class":88},"value",[40,1402,1053],{"class":50},[40,1404,1405],{"class":120},"toStringAsFixed",[40,1407,124],{"class":50},[40,1409,1359],{"class":88},[40,1411,1412],{"class":50},")}${",[40,1414,1415],{"class":88},"from",[40,1417,1053],{"class":50},[40,1419,1420],{"class":88},"symbol",[40,1422,1059],{"class":50},[40,1424,1425],{"class":50}," = '\n",[40,1427,1429,1432,1434,1437,1439,1441,1443,1445,1447,1450,1452,1454,1456,1458],{"class":42,"line":1428},101,[40,1430,1431],{"class":50},"      '",[40,1433,1047],{"class":50},[40,1435,1436],{"class":88},"result",[40,1438,1053],{"class":50},[40,1440,1405],{"class":120},[40,1442,124],{"class":50},[40,1444,1359],{"class":88},[40,1446,1412],{"class":50},[40,1448,1449],{"class":88},"to",[40,1451,1053],{"class":50},[40,1453,1420],{"class":88},[40,1455,1059],{"class":50},[40,1457,559],{"class":50},[40,1459,173],{"class":54},[40,1461,1463,1465,1468],{"class":42,"line":1462},102,[40,1464,652],{"class":46},[40,1466,1467],{"class":88}," 0",[40,1469,55],{"class":54},[40,1471,1473],{"class":42,"line":1472},103,[40,1474,623],{"class":54},[40,1476,1478],{"class":42,"line":1477},104,[40,1479,72],{"emptyLinePlaceholder":71},[40,1481,1483,1485,1487,1489,1491],{"class":42,"line":1482},105,[40,1484,1160],{"class":88},[40,1486,980],{"class":120},[40,1488,124],{"class":54},[40,1490,1167],{"class":88},[40,1492,1170],{"class":54},[40,1494,1496,1499,1501,1504,1507,1510,1512],{"class":42,"line":1495},106,[40,1497,1498],{"class":46},"  for",[40,1500,258],{"class":54},[40,1502,1503],{"class":46},"final",[40,1505,1506],{"class":54}," unit ",[40,1508,1509],{"class":46},"in",[40,1511,111],{"class":88},[40,1513,1514],{"class":54},".values) {\n",[40,1516,1518,1521,1523,1525,1527,1530,1532,1535,1537,1540,1542,1544,1546,1548,1550,1552,1554,1556,1558,1560,1562,1565],{"class":42,"line":1517},107,[40,1519,1520],{"class":120},"    print",[40,1522,124],{"class":54},[40,1524,559],{"class":50},[40,1526,1047],{"class":50},[40,1528,1529],{"class":88},"unit",[40,1531,1053],{"class":50},[40,1533,1534],{"class":88},"name",[40,1536,1059],{"class":50},[40,1538,1539],{"class":50},": ",[40,1541,1047],{"class":50},[40,1543,1529],{"class":88},[40,1545,1053],{"class":50},[40,1547,1420],{"class":88},[40,1549,1059],{"class":50},[40,1551,258],{"class":50},[40,1553,1047],{"class":50},[40,1555,1529],{"class":88},[40,1557,1053],{"class":50},[40,1559,1534],{"class":88},[40,1561,1059],{"class":50},[40,1563,1564],{"class":50},")'",[40,1566,173],{"class":54},[40,1568,1570],{"class":42,"line":1569},108,[40,1571,1144],{"class":54},[40,1573,1575,1577,1579],{"class":42,"line":1574},109,[40,1576,652],{"class":46},[40,1578,1467],{"class":88},[40,1580,55],{"class":54},[40,1582,1584],{"class":42,"line":1583},110,[40,1585,623],{"class":54},[40,1587,1589],{"class":42,"line":1588},111,[40,1590,72],{"emptyLinePlaceholder":71},[40,1592,1594,1596,1598],{"class":42,"line":1593},112,[40,1595,1160],{"class":88},[40,1597,995],{"class":120},[40,1599,646],{"class":54},[40,1601,1603,1605,1607,1610],{"class":42,"line":1602},113,[40,1604,1391],{"class":120},[40,1606,124],{"class":54},[40,1608,1609],{"class":50},"'tempc v1.0.0'",[40,1611,173],{"class":54},[40,1613,1615,1617,1619],{"class":42,"line":1614},114,[40,1616,652],{"class":46},[40,1618,1467],{"class":88},[40,1620,55],{"class":54},[40,1622,1624],{"class":42,"line":1623},115,[40,1625,623],{"class":54},[40,1627,1629],{"class":42,"line":1628},116,[40,1630,72],{"emptyLinePlaceholder":71},[40,1632,1634,1636,1639,1641,1643],{"class":42,"line":1633},117,[40,1635,725],{"class":46},[40,1637,1638],{"class":120}," printUsage",[40,1640,124],{"class":54},[40,1642,640],{"class":88},[40,1644,1645],{"class":54}," parser) {\n",[40,1647,1649,1651,1653,1656],{"class":42,"line":1648},118,[40,1650,1391],{"class":120},[40,1652,124],{"class":54},[40,1654,1655],{"class":50},"'Usage: tempc \u003Ccommand> [arguments]'",[40,1657,173],{"class":54},[40,1659,1661,1663],{"class":42,"line":1660},119,[40,1662,1391],{"class":120},[40,1664,1665],{"class":54},"(parser.usage);\n",[40,1667,1669],{"class":42,"line":1668},120,[40,1670,623],{"class":54},[40,1672,1674],{"class":42,"line":1673},121,[40,1675,72],{"emptyLinePlaceholder":71},[40,1677,1679,1682,1684,1687,1690],{"class":42,"line":1678},122,[40,1680,1681],{"class":46},"class",[40,1683,545],{"class":88},[40,1685,1686],{"class":46}," implements",[40,1688,1689],{"class":88}," Exception",[40,1691,114],{"class":54},[40,1693,1695,1697,1699],{"class":42,"line":1694},123,[40,1696,184],{"class":46},[40,1698,187],{"class":88},[40,1700,1701],{"class":54}," message;\n",[40,1703,1705,1707,1709],{"class":42,"line":1704},124,[40,1706,184],{"class":46},[40,1708,187],{"class":88},[40,1710,1711],{"class":54}," usage;\n",[40,1713,1715,1718,1720,1722,1725,1727],{"class":42,"line":1714},125,[40,1716,1717],{"class":88},"  UsageException",[40,1719,124],{"class":54},[40,1721,213],{"class":88},[40,1723,1724],{"class":54},".message, ",[40,1726,213],{"class":88},[40,1728,1729],{"class":54},".usage);\n",[40,1731,1733],{"class":42,"line":1732},126,[40,1734,1735],{"class":46},"  @override\n",[40,1737,1739,1742,1745,1748,1750],{"class":42,"line":1738},127,[40,1740,1741],{"class":88},"  String",[40,1743,1744],{"class":120}," toString",[40,1746,1747],{"class":54},"() ",[40,1749,252],{"class":46},[40,1751,1701],{"class":54},[40,1753,1755],{"class":42,"line":1754},128,[40,1756,623],{"class":54},[14,1758,1760],{"id":1759},"project-2-zero-copy-stream-pipeline","Project 2 — Zero-Copy Stream Pipeline",[19,1762,1763,1764,1767,1768,1771],{},"A data processing pipeline using lazy ",[23,1765,1766],{},"Iterable","s, ",[23,1769,1770],{},"async*"," generators, and backpressure-aware streams. Zero intermediate allocations.",[28,1773,1774],{"language":30},[32,1775,1777],{"className":34,"code":1776,"language":30,"meta":36,"style":36},"import 'dart:async';\nimport 'dart:convert';\nimport 'dart:io';\n\n\u002F\u002F ── A lazy pipeline: read → parse → filter → transform → aggregate ──\n\u002F\u002F Each stage is lazy (Iterable or Stream) — no intermediate lists allocated.\n\u002F\u002F Data flows element-by-element through the pipeline.\n\nclass LogEntry {\n  final DateTime timestamp;\n  final String level;\n  final String message;\n  const LogEntry(this.timestamp, this.level, this.message);\n\n  factory LogEntry.fromJson(Map\u003CString, dynamic> json) => LogEntry(\n    DateTime.parse(json['timestamp'] as String),\n    json['level'] as String,\n    json['message'] as String,\n  );\n}\n\n\u002F\u002F ── Stage 1: read lines lazily (streaming — constant memory) ──\nStream\u003CString> readLines(String path) {\n  return File(path)\n      .openRead()\n      .transform(utf8.decoder)\n      .transform(const LineSplitter());\n}\n\n\u002F\u002F ── Stage 2: parse JSON lazily (sync* — pull-based) ──\nIterable\u003CLogEntry> parseEntries(Iterable\u003CString> lines) sync* {\n  for (final line in lines) {\n    try {\n      yield LogEntry.fromJson(jsonDecode(line) as Map\u003CString, dynamic>);\n    } on FormatException {\n      \u002F\u002F skip invalid lines (don't crash on bad data)\n      continue;\n    }\n  }\n}\n\n\u002F\u002F ── Stage 3: filter by level (lazy Iterable) ──\nIterable\u003CLogEntry> filterByLevel(Iterable\u003CLogEntry> entries, String level) {\n  return entries.where((e) => e.level == level);\n}\n\n\u002F\u002F ── Stage 4: group by hour (async* — push-based with backpressure) ──\nStream\u003CMapEntry\u003CDateTime, List\u003CLogEntry>>> groupByHour(\n  Stream\u003CLogEntry> entries,\n) async* {\n  var currentHour = \u003CDateTime, List\u003CLogEntry>>{};\n  LogEntry? last;\n\n  await for (final entry in entries) {\n    final hour = DateTime(\n      entry.timestamp.year,\n      entry.timestamp.month,\n      entry.timestamp.day,\n      entry.timestamp.hour,\n    );\n    currentHour.putIfAbsent(hour, () => []).add(entry);\n    last = entry;\n  }\n  for (final entry in currentHour.entries) {\n    yield entry;\n  }\n}\n\n\u002F\u002F ── Stage 5: aggregate — count errors per hour ──\nFuture\u003CMap\u003CDateTime, int>> errorCountPerHour(String logPath) async {\n  final lines = readLines(logPath);                    \u002F\u002F lazy stream\n  final entries = parseEntries(lines);                \u002F\u002F lazy iterable\n  final errors = filterByLevel(entries, 'ERROR');     \u002F\u002F lazy filter\n\n  \u002F\u002F Convert to stream for async grouping:\n  final grouped = groupByHour(Stream.fromIterable(errors));\n\n  final result = \u003CDateTime, int>{};\n  await for (final hourEntries in grouped) {\n    result[hourEntries.key] = hourEntries.value.length;\n  }\n  return result;\n}\n\n\u002F\u002F ── Usage — the pipeline processes a 1GB log file with constant memory ──\nvoid main() async {\n  final counts = await errorCountPerHour('app.log');\n  for (final entry in counts.entries) {\n    print('${entry.key}: ${entry.value} errors');\n  }\n}\n",[23,1778,1779,1788,1797,1805,1809,1814,1819,1824,1828,1837,1847,1856,1864,1887,1891,1926,1951,1967,1982,1987,1991,1995,2000,2022,2032,2042,2052,2069,2073,2077,2082,2112,2128,2135,2170,2182,2187,2194,2198,2202,2206,2210,2215,2244,2267,2271,2275,2280,2310,2322,2330,2361,2372,2376,2396,2409,2414,2419,2424,2429,2433,2455,2465,2469,2484,2491,2495,2499,2503,2508,2543,2561,2579,2603,2607,2612,2636,2640,2660,2678,2688,2692,2699,2703,2707,2712,2724,2746,2761,2798,2802],{"__ignoreMap":36},[40,1780,1781,1783,1786],{"class":42,"line":43},[40,1782,47],{"class":46},[40,1784,1785],{"class":50}," 'dart:async'",[40,1787,55],{"class":54},[40,1789,1790,1792,1795],{"class":42,"line":58},[40,1791,47],{"class":46},[40,1793,1794],{"class":50}," 'dart:convert'",[40,1796,55],{"class":54},[40,1798,1799,1801,1803],{"class":42,"line":68},[40,1800,47],{"class":46},[40,1802,63],{"class":50},[40,1804,55],{"class":54},[40,1806,1807],{"class":42,"line":75},[40,1808,72],{"emptyLinePlaceholder":71},[40,1810,1811],{"class":42,"line":82},[40,1812,1813],{"class":78},"\u002F\u002F ── A lazy pipeline: read → parse → filter → transform → aggregate ──\n",[40,1815,1816],{"class":42,"line":95},[40,1817,1818],{"class":78},"\u002F\u002F Each stage is lazy (Iterable or Stream) — no intermediate lists allocated.\n",[40,1820,1821],{"class":42,"line":100},[40,1822,1823],{"class":78},"\u002F\u002F Data flows element-by-element through the pipeline.\n",[40,1825,1826],{"class":42,"line":106},[40,1827,72],{"emptyLinePlaceholder":71},[40,1829,1830,1832,1835],{"class":42,"line":117},[40,1831,1681],{"class":46},[40,1833,1834],{"class":88}," LogEntry",[40,1836,114],{"class":54},[40,1838,1839,1841,1844],{"class":42,"line":139},[40,1840,184],{"class":46},[40,1842,1843],{"class":88}," DateTime",[40,1845,1846],{"class":54}," timestamp;\n",[40,1848,1849,1851,1853],{"class":42,"line":157},[40,1850,184],{"class":46},[40,1852,187],{"class":88},[40,1854,1855],{"class":54}," level;\n",[40,1857,1858,1860,1862],{"class":42,"line":176},[40,1859,184],{"class":46},[40,1861,187],{"class":88},[40,1863,1701],{"class":54},[40,1865,1866,1868,1870,1872,1874,1877,1879,1882,1884],{"class":42,"line":181},[40,1867,206],{"class":46},[40,1869,1834],{"class":88},[40,1871,124],{"class":54},[40,1873,213],{"class":88},[40,1875,1876],{"class":54},".timestamp, ",[40,1878,213],{"class":88},[40,1880,1881],{"class":54},".level, ",[40,1883,213],{"class":88},[40,1885,1886],{"class":54},".message);\n",[40,1888,1889],{"class":42,"line":193},[40,1890,72],{"emptyLinePlaceholder":71},[40,1892,1893,1896,1898,1900,1903,1905,1908,1910,1912,1914,1917,1920,1922,1924],{"class":42,"line":203},[40,1894,1895],{"class":46},"  factory",[40,1897,1834],{"class":88},[40,1899,1053],{"class":54},[40,1901,1902],{"class":120},"fromJson",[40,1904,124],{"class":54},[40,1906,1907],{"class":88},"Map",[40,1909,736],{"class":54},[40,1911,459],{"class":88},[40,1913,130],{"class":54},[40,1915,1916],{"class":88},"dynamic",[40,1918,1919],{"class":54},"> json) ",[40,1921,252],{"class":46},[40,1923,1834],{"class":88},[40,1925,878],{"class":54},[40,1927,1928,1931,1933,1935,1938,1941,1944,1947,1949],{"class":42,"line":224},[40,1929,1930],{"class":88},"    DateTime",[40,1932,1053],{"class":54},[40,1934,782],{"class":120},[40,1936,1937],{"class":54},"(json[",[40,1939,1940],{"class":50},"'timestamp'",[40,1942,1943],{"class":54},"] ",[40,1945,1946],{"class":46},"as",[40,1948,187],{"class":88},[40,1950,136],{"class":54},[40,1952,1953,1956,1959,1961,1963,1965],{"class":42,"line":229},[40,1954,1955],{"class":54},"    json[",[40,1957,1958],{"class":50},"'level'",[40,1960,1943],{"class":54},[40,1962,1946],{"class":46},[40,1964,187],{"class":88},[40,1966,314],{"class":54},[40,1968,1969,1971,1974,1976,1978,1980],{"class":42,"line":235},[40,1970,1955],{"class":54},[40,1972,1973],{"class":50},"'message'",[40,1975,1943],{"class":54},[40,1977,1946],{"class":46},[40,1979,187],{"class":88},[40,1981,314],{"class":54},[40,1983,1984],{"class":42,"line":266},[40,1985,1986],{"class":54},"  );\n",[40,1988,1989],{"class":42,"line":280},[40,1990,623],{"class":54},[40,1992,1993],{"class":42,"line":317},[40,1994,72],{"emptyLinePlaceholder":71},[40,1996,1997],{"class":42,"line":337},[40,1998,1999],{"class":78},"\u002F\u002F ── Stage 1: read lines lazily (streaming — constant memory) ──\n",[40,2001,2002,2005,2007,2009,2012,2015,2017,2019],{"class":42,"line":343},[40,2003,2004],{"class":88},"Stream",[40,2006,736],{"class":54},[40,2008,459],{"class":88},[40,2010,2011],{"class":54},"> ",[40,2013,2014],{"class":120},"readLines",[40,2016,124],{"class":54},[40,2018,459],{"class":88},[40,2020,2021],{"class":54}," path) {\n",[40,2023,2024,2026,2029],{"class":42,"line":348},[40,2025,652],{"class":46},[40,2027,2028],{"class":88}," File",[40,2030,2031],{"class":54},"(path)\n",[40,2033,2034,2037,2040],{"class":42,"line":354},[40,2035,2036],{"class":54},"      .",[40,2038,2039],{"class":120},"openRead",[40,2041,658],{"class":54},[40,2043,2044,2046,2049],{"class":42,"line":379},[40,2045,2036],{"class":54},[40,2047,2048],{"class":120},"transform",[40,2050,2051],{"class":54},"(utf8.decoder)\n",[40,2053,2054,2056,2058,2060,2063,2066],{"class":42,"line":391},[40,2055,2036],{"class":54},[40,2057,2048],{"class":120},[40,2059,124],{"class":54},[40,2061,2062],{"class":46},"const",[40,2064,2065],{"class":88}," LineSplitter",[40,2067,2068],{"class":54},"());\n",[40,2070,2071],{"class":42,"line":418},[40,2072,623],{"class":54},[40,2074,2075],{"class":42,"line":436},[40,2076,72],{"emptyLinePlaceholder":71},[40,2078,2079],{"class":42,"line":441},[40,2080,2081],{"class":78},"\u002F\u002F ── Stage 2: parse JSON lazily (sync* — pull-based) ──\n",[40,2083,2084,2086,2088,2091,2093,2096,2098,2100,2102,2104,2107,2110],{"class":42,"line":446},[40,2085,1766],{"class":88},[40,2087,736],{"class":54},[40,2089,2090],{"class":88},"LogEntry",[40,2092,2011],{"class":54},[40,2094,2095],{"class":120},"parseEntries",[40,2097,124],{"class":54},[40,2099,1766],{"class":88},[40,2101,736],{"class":54},[40,2103,459],{"class":88},[40,2105,2106],{"class":54},"> lines) ",[40,2108,2109],{"class":46},"sync*",[40,2111,114],{"class":54},[40,2113,2114,2116,2118,2120,2123,2125],{"class":42,"line":478},[40,2115,1498],{"class":46},[40,2117,258],{"class":54},[40,2119,1503],{"class":46},[40,2121,2122],{"class":54}," line ",[40,2124,1509],{"class":46},[40,2126,2127],{"class":54}," lines) {\n",[40,2129,2130,2133],{"class":42,"line":498},[40,2131,2132],{"class":46},"    try",[40,2134,114],{"class":54},[40,2136,2137,2140,2142,2144,2146,2148,2151,2154,2156,2159,2161,2163,2165,2167],{"class":42,"line":516},[40,2138,2139],{"class":46},"      yield",[40,2141,1834],{"class":88},[40,2143,1053],{"class":54},[40,2145,1902],{"class":120},[40,2147,124],{"class":54},[40,2149,2150],{"class":120},"jsonDecode",[40,2152,2153],{"class":54},"(line) ",[40,2155,1946],{"class":46},[40,2157,2158],{"class":88}," Map",[40,2160,736],{"class":54},[40,2162,459],{"class":88},[40,2164,130],{"class":54},[40,2166,1916],{"class":88},[40,2168,2169],{"class":54},">);\n",[40,2171,2172,2175,2177,2180],{"class":42,"line":534},[40,2173,2174],{"class":54},"    } ",[40,2176,1022],{"class":46},[40,2178,2179],{"class":88}," FormatException",[40,2181,114],{"class":54},[40,2183,2184],{"class":42,"line":569},[40,2185,2186],{"class":78},"      \u002F\u002F skip invalid lines (don't crash on bad data)\n",[40,2188,2189,2192],{"class":42,"line":574},[40,2190,2191],{"class":46},"      continue",[40,2193,55],{"class":54},[40,2195,2196],{"class":42,"line":579},[40,2197,852],{"class":54},[40,2199,2200],{"class":42,"line":603},[40,2201,1144],{"class":54},[40,2203,2204],{"class":42,"line":620},[40,2205,623],{"class":54},[40,2207,2208],{"class":42,"line":626},[40,2209,72],{"emptyLinePlaceholder":71},[40,2211,2212],{"class":42,"line":631},[40,2213,2214],{"class":78},"\u002F\u002F ── Stage 3: filter by level (lazy Iterable) ──\n",[40,2216,2217,2219,2221,2223,2225,2228,2230,2232,2234,2236,2239,2241],{"class":42,"line":637},[40,2218,1766],{"class":88},[40,2220,736],{"class":54},[40,2222,2090],{"class":88},[40,2224,2011],{"class":54},[40,2226,2227],{"class":120},"filterByLevel",[40,2229,124],{"class":54},[40,2231,1766],{"class":88},[40,2233,736],{"class":54},[40,2235,2090],{"class":88},[40,2237,2238],{"class":54},"> entries, ",[40,2240,459],{"class":88},[40,2242,2243],{"class":54}," level) {\n",[40,2245,2246,2248,2251,2254,2257,2259,2262,2264],{"class":42,"line":649},[40,2247,652],{"class":46},[40,2249,2250],{"class":54}," entries.",[40,2252,2253],{"class":120},"where",[40,2255,2256],{"class":54},"((e) ",[40,2258,252],{"class":46},[40,2260,2261],{"class":54}," e.level ",[40,2263,815],{"class":46},[40,2265,2266],{"class":54}," level);\n",[40,2268,2269],{"class":42,"line":661},[40,2270,623],{"class":54},[40,2272,2273],{"class":42,"line":678},[40,2274,72],{"emptyLinePlaceholder":71},[40,2276,2277],{"class":42,"line":692},[40,2278,2279],{"class":78},"\u002F\u002F ── Stage 4: group by hour (async* — push-based with backpressure) ──\n",[40,2281,2282,2284,2286,2289,2291,2294,2296,2298,2300,2302,2305,2308],{"class":42,"line":706},[40,2283,2004],{"class":88},[40,2285,736],{"class":54},[40,2287,2288],{"class":88},"MapEntry",[40,2290,736],{"class":54},[40,2292,2293],{"class":88},"DateTime",[40,2295,130],{"class":54},[40,2297,733],{"class":88},[40,2299,736],{"class":54},[40,2301,2090],{"class":88},[40,2303,2304],{"class":54},">>> ",[40,2306,2307],{"class":120},"groupByHour",[40,2309,878],{"class":54},[40,2311,2312,2315,2317,2319],{"class":42,"line":711},[40,2313,2314],{"class":88},"  Stream",[40,2316,736],{"class":54},[40,2318,2090],{"class":88},[40,2320,2321],{"class":54},"> entries,\n",[40,2323,2324,2326,2328],{"class":42,"line":716},[40,2325,299],{"class":54},[40,2327,1770],{"class":46},[40,2329,114],{"class":54},[40,2331,2332,2335,2338,2340,2343,2345,2347,2349,2351,2353,2356,2358],{"class":42,"line":722},[40,2333,2334],{"class":46},"  var",[40,2336,2337],{"class":54}," currentHour ",[40,2339,761],{"class":46},[40,2341,2342],{"class":46}," \u003C",[40,2344,2293],{"class":88},[40,2346,130],{"class":54},[40,2348,733],{"class":88},[40,2350,736],{"class":54},[40,2352,2090],{"class":88},[40,2354,2355],{"class":54},">",[40,2357,2355],{"class":46},[40,2359,2360],{"class":54},"{};\n",[40,2362,2363,2366,2369],{"class":42,"line":744},[40,2364,2365],{"class":88},"  LogEntry",[40,2367,2368],{"class":46},"?",[40,2370,2371],{"class":54}," last;\n",[40,2373,2374],{"class":42,"line":752},[40,2375,72],{"emptyLinePlaceholder":71},[40,2377,2378,2381,2384,2386,2388,2391,2393],{"class":42,"line":769},[40,2379,2380],{"class":46},"  await",[40,2382,2383],{"class":46}," for",[40,2385,258],{"class":54},[40,2387,1503],{"class":46},[40,2389,2390],{"class":54}," entry ",[40,2392,1509],{"class":46},[40,2394,2395],{"class":54}," entries) {\n",[40,2397,2398,2400,2403,2405,2407],{"class":42,"line":788},[40,2399,755],{"class":46},[40,2401,2402],{"class":54}," hour ",[40,2404,761],{"class":46},[40,2406,1843],{"class":88},[40,2408,878],{"class":54},[40,2410,2411],{"class":42,"line":793},[40,2412,2413],{"class":54},"      entry.timestamp.year,\n",[40,2415,2416],{"class":42,"line":806},[40,2417,2418],{"class":54},"      entry.timestamp.month,\n",[40,2420,2421],{"class":42,"line":823},[40,2422,2423],{"class":54},"      entry.timestamp.day,\n",[40,2425,2426],{"class":42,"line":832},[40,2427,2428],{"class":54},"      entry.timestamp.hour,\n",[40,2430,2431],{"class":42,"line":849},[40,2432,930],{"class":54},[40,2434,2435,2438,2441,2444,2446,2449,2452],{"class":42,"line":855},[40,2436,2437],{"class":54},"    currentHour.",[40,2439,2440],{"class":120},"putIfAbsent",[40,2442,2443],{"class":54},"(hour, () ",[40,2445,252],{"class":46},[40,2447,2448],{"class":54}," []).",[40,2450,2451],{"class":120},"add",[40,2453,2454],{"class":54},"(entry);\n",[40,2456,2457,2460,2462],{"class":42,"line":860},[40,2458,2459],{"class":54},"    last ",[40,2461,761],{"class":46},[40,2463,2464],{"class":54}," entry;\n",[40,2466,2467],{"class":42,"line":881},[40,2468,1144],{"class":54},[40,2470,2471,2473,2475,2477,2479,2481],{"class":42,"line":897},[40,2472,1498],{"class":46},[40,2474,258],{"class":54},[40,2476,1503],{"class":46},[40,2478,2390],{"class":54},[40,2480,1509],{"class":46},[40,2482,2483],{"class":54}," currentHour.entries) {\n",[40,2485,2486,2489],{"class":42,"line":927},[40,2487,2488],{"class":46},"    yield",[40,2490,2464],{"class":54},[40,2492,2493],{"class":42,"line":933},[40,2494,1144],{"class":54},[40,2496,2497],{"class":42,"line":938},[40,2498,623],{"class":54},[40,2500,2501],{"class":42,"line":953},[40,2502,72],{"emptyLinePlaceholder":71},[40,2504,2505],{"class":42,"line":970},[40,2506,2507],{"class":78},"\u002F\u002F ── Stage 5: aggregate — count errors per hour ──\n",[40,2509,2510,2513,2515,2517,2519,2521,2523,2525,2528,2531,2533,2535,2538,2541],{"class":42,"line":985},[40,2511,2512],{"class":88},"Future",[40,2514,736],{"class":54},[40,2516,1907],{"class":88},[40,2518,736],{"class":54},[40,2520,2293],{"class":88},[40,2522,130],{"class":54},[40,2524,1160],{"class":88},[40,2526,2527],{"class":54},">> ",[40,2529,2530],{"class":120},"errorCountPerHour",[40,2532,124],{"class":54},[40,2534,459],{"class":88},[40,2536,2537],{"class":54}," logPath) ",[40,2539,2540],{"class":46},"async",[40,2542,114],{"class":54},[40,2544,2545,2547,2550,2552,2555,2558],{"class":42,"line":1001},[40,2546,184],{"class":46},[40,2548,2549],{"class":54}," lines ",[40,2551,761],{"class":46},[40,2553,2554],{"class":120}," readLines",[40,2556,2557],{"class":54},"(logPath);                    ",[40,2559,2560],{"class":78},"\u002F\u002F lazy stream\n",[40,2562,2563,2565,2568,2570,2573,2576],{"class":42,"line":1007},[40,2564,184],{"class":46},[40,2566,2567],{"class":54}," entries ",[40,2569,761],{"class":46},[40,2571,2572],{"class":120}," parseEntries",[40,2574,2575],{"class":54},"(lines);                ",[40,2577,2578],{"class":78},"\u002F\u002F lazy iterable\n",[40,2580,2581,2583,2586,2588,2591,2594,2597,2600],{"class":42,"line":1016},[40,2582,184],{"class":46},[40,2584,2585],{"class":54}," errors ",[40,2587,761],{"class":46},[40,2589,2590],{"class":120}," filterByLevel",[40,2592,2593],{"class":54},"(entries, ",[40,2595,2596],{"class":50},"'ERROR'",[40,2598,2599],{"class":54},");     ",[40,2601,2602],{"class":78},"\u002F\u002F lazy filter\n",[40,2604,2605],{"class":42,"line":1033},[40,2606,72],{"emptyLinePlaceholder":71},[40,2608,2609],{"class":42,"line":1066},[40,2610,2611],{"class":78},"  \u002F\u002F Convert to stream for async grouping:\n",[40,2613,2614,2616,2619,2621,2624,2626,2628,2630,2633],{"class":42,"line":1076},[40,2615,184],{"class":46},[40,2617,2618],{"class":54}," grouped ",[40,2620,761],{"class":46},[40,2622,2623],{"class":120}," groupByHour",[40,2625,124],{"class":54},[40,2627,2004],{"class":88},[40,2629,1053],{"class":54},[40,2631,2632],{"class":120},"fromIterable",[40,2634,2635],{"class":54},"(errors));\n",[40,2637,2638],{"class":42,"line":1087},[40,2639,72],{"emptyLinePlaceholder":71},[40,2641,2642,2644,2646,2648,2650,2652,2654,2656,2658],{"class":42,"line":1098},[40,2643,184],{"class":46},[40,2645,1369],{"class":54},[40,2647,761],{"class":46},[40,2649,2342],{"class":46},[40,2651,2293],{"class":88},[40,2653,130],{"class":54},[40,2655,1160],{"class":88},[40,2657,2355],{"class":46},[40,2659,2360],{"class":54},[40,2661,2662,2664,2666,2668,2670,2673,2675],{"class":42,"line":1126},[40,2663,2380],{"class":46},[40,2665,2383],{"class":46},[40,2667,258],{"class":54},[40,2669,1503],{"class":46},[40,2671,2672],{"class":54}," hourEntries ",[40,2674,1509],{"class":46},[40,2676,2677],{"class":54}," grouped) {\n",[40,2679,2680,2683,2685],{"class":42,"line":1141},[40,2681,2682],{"class":54},"    result[hourEntries.key] ",[40,2684,761],{"class":46},[40,2686,2687],{"class":54}," hourEntries.value.length;\n",[40,2689,2690],{"class":42,"line":1147},[40,2691,1144],{"class":54},[40,2693,2694,2696],{"class":42,"line":1152},[40,2695,652],{"class":46},[40,2697,2698],{"class":54}," result;\n",[40,2700,2701],{"class":42,"line":1157},[40,2702,623],{"class":54},[40,2704,2705],{"class":42,"line":1173},[40,2706,72],{"emptyLinePlaceholder":71},[40,2708,2709],{"class":42,"line":1190},[40,2710,2711],{"class":78},"\u002F\u002F ── Usage — the pipeline processes a 1GB log file with constant memory ──\n",[40,2713,2714,2716,2718,2720,2722],{"class":42,"line":1200},[40,2715,725],{"class":46},[40,2717,728],{"class":120},[40,2719,1747],{"class":54},[40,2721,2540],{"class":46},[40,2723,114],{"class":54},[40,2725,2726,2728,2731,2733,2736,2739,2741,2744],{"class":42,"line":1208},[40,2727,184],{"class":46},[40,2729,2730],{"class":54}," counts ",[40,2732,761],{"class":46},[40,2734,2735],{"class":46}," await",[40,2737,2738],{"class":120}," errorCountPerHour",[40,2740,124],{"class":54},[40,2742,2743],{"class":50},"'app.log'",[40,2745,173],{"class":54},[40,2747,2748,2750,2752,2754,2756,2758],{"class":42,"line":1216},[40,2749,1498],{"class":46},[40,2751,258],{"class":54},[40,2753,1503],{"class":46},[40,2755,2390],{"class":54},[40,2757,1509],{"class":46},[40,2759,2760],{"class":54}," counts.entries) {\n",[40,2762,2763,2765,2767,2769,2771,2774,2776,2779,2781,2783,2785,2787,2789,2791,2793,2796],{"class":42,"line":1221},[40,2764,1520],{"class":120},[40,2766,124],{"class":54},[40,2768,559],{"class":50},[40,2770,1047],{"class":50},[40,2772,2773],{"class":88},"entry",[40,2775,1053],{"class":50},[40,2777,2778],{"class":88},"key",[40,2780,1059],{"class":50},[40,2782,1539],{"class":50},[40,2784,1047],{"class":50},[40,2786,2773],{"class":88},[40,2788,1053],{"class":50},[40,2790,1400],{"class":88},[40,2792,1059],{"class":50},[40,2794,2795],{"class":50}," errors'",[40,2797,173],{"class":54},[40,2799,2800],{"class":42,"line":1226},[40,2801,1144],{"class":54},[40,2803,2804],{"class":42,"line":1231},[40,2805,623],{"class":54},[14,2807,2809],{"id":2808},"project-3-isolate-based-image-processor","Project 3 — Isolate-Based Image Processor",[19,2811,2812],{},"A worker pool that distributes image processing across isolates with zero-copy transfer.",[28,2814,2815],{"language":30},[32,2816,2818],{"className":34,"code":2817,"language":30,"meta":36,"style":36},"import 'dart:isolate';\nimport 'dart:typed_data';\nimport 'dart:async';\n\n\u002F\u002F ── Task definition (sent to workers) ──\nclass ImageTask {\n  final int id;\n  final TransferableTypedData pixels;  \u002F\u002F zero-copy transfer of pixel data\n  final int width;\n  final int height;\n  final String operation;  \u002F\u002F 'grayscale', 'invert', 'blur'\n\n  const ImageTask(this.id, this.pixels, this.width, this.height, this.operation);\n}\n\n\u002F\u002F ── Worker pool — reusable isolates for parallel processing ──\nclass ImageProcessor {\n  final int _poolSize;\n  final List\u003C_ImageWorker> _workers = [];\n  final _available = \u003C_ImageWorker>[];\n  final _pending = \u003CCompleter\u003CUint8List>, _ImageWorker>{};\n  final _queue = \u003C(ImageTask, Completer\u003CUint8List>)>[];\n\n  ImageProcessor(this._poolSize);\n\n  Future\u003Cvoid> start() async {\n    for (var i = 0; i \u003C _poolSize; i++) {\n      final worker = await _ImageWorker.spawn();\n      worker.onResult = _handleResult;\n      _workers.add(worker);\n      _available.add(worker);\n    }\n  }\n\n  Future\u003CUint8List> process(Uint8List pixels, int w, int h, String op) {\n    final completer = Completer\u003CUint8List>();\n    final task = ImageTask(\n      _queue.length,\n      TransferableTypedData.fromList([pixels]),  \u002F\u002F wrap for zero-copy\n      w, h, op,\n    );\n    _queue.add((task, completer));\n    _processQueue();\n    return completer.future;\n  }\n\n  void _processQueue() {\n    while (_available.isNotEmpty && _queue.isNotEmpty) {\n      final worker = _available.removeLast();\n      final (task, completer) = _queue.removeAt(0);\n      _pending[completer] = worker;\n      worker.process(task, completer);\n    }\n  }\n\n  void _handleResult(_ImageWorker worker) {\n    _available.add(worker);\n    _processQueue();\n  }\n\n  void dispose() {\n    for (var w in _workers) w.kill();\n  }\n}\n\nclass _ImageWorker {\n  late final Isolate _isolate;\n  late final SendPort _sendPort;\n  final _receivePort = ReceivePort();\n  late void Function(_ImageWorker) onResult;\n  Completer\u003CUint8List>? _current;\n\n  static Future\u003C_ImageWorker> spawn() async {\n    final worker = _ImageWorker();\n    worker._isolate = await Isolate.spawn(_entry, worker._receivePort.sendPort);\n    worker._sendPort = await worker._receivePort.first as SendPort;\n    worker._receivePort.listen(worker._handleMessage);\n    return worker;\n  }\n\n  void process(ImageTask task, Completer\u003CUint8List> completer) {\n    _current = completer;\n    _sendPort.send(task);\n  }\n\n  void _handleMessage(dynamic message) {\n    if (message is Uint8List && _current != null) {\n      _current!.complete(message);\n      _current = null;\n      onResult(this);\n    }\n  }\n\n  void kill() {\n    _isolate.kill(priority: Isolate.immediate);\n    _receivePort.close();\n  }\n\n  static void _entry(SendPort mainPort) {\n    final receivePort = ReceivePort();\n    mainPort.send(receivePort.sendPort);\n\n    receivePort.listen((task) {\n      if (task is ImageTask) {\n        \u002F\u002F Materialize the transferred data (zero-copy — moved, not copied):\n        final data = task.pixels.materialize().asUint8List();\n        final result = _processImage(data, task.width, task.height, task.operation);\n        \u002F\u002F Transfer the result back (zero-copy):\n        mainPort.send(TransferableTypedData.fromList([result]).materialize().asUint8List());\n      }\n    });\n  }\n\n  static Uint8List _processImage(Uint8List pixels, int w, int h, String op) {\n    \u002F\u002F Image processing — grayscale, invert, etc.\n    return switch (op) {\n      'grayscale' => _grayscale(pixels),\n      'invert' => _invert(pixels),\n      _ => pixels,\n    };\n  }\n\n  static Uint8List _grayscale(Uint8List pixels) {\n    final result = Uint8List(pixels.length);\n    for (var i = 0; i \u003C pixels.length; i += 4) {\n      final gray = (pixels[i] * 0.299 + pixels[i + 1] * 0.587 + pixels[i + 2] * 0.114).toInt();\n      result[i] = gray;\n      result[i + 1] = gray;\n      result[i + 2] = gray;\n      result[i + 3] = pixels[i + 3];  \u002F\u002F alpha unchanged\n    }\n    return result;\n  }\n\n  static Uint8List _invert(Uint8List pixels) {\n    final result = Uint8List(pixels.length);\n    for (var i = 0; i \u003C pixels.length; i += 4) {\n      result[i] = 255 - pixels[i];\n      result[i + 1] = 255 - pixels[i + 1];\n      result[i + 2] = 255 - pixels[i + 2];\n      result[i + 3] = pixels[i + 3];\n    }\n    return result;\n  }\n}\n",[23,2819,2820,2829,2838,2846,2850,2855,2864,2874,2887,2896,2905,2917,2921,2954,2958,2962,2967,2976,2985,3005,3023,3051,3082,3086,3098,3102,3122,3152,3174,3184,3194,3203,3207,3211,3215,3250,3269,3282,3287,3303,3308,3312,3322,3329,3337,3341,3345,3355,3369,3385,3406,3416,3426,3430,3434,3438,3452,3461,3467,3471,3475,3484,3505,3509,3513,3517,3525,3539,3551,3565,3582,3598,3602,3623,3635,3653,3671,3682,3688,3692,3696,3719,3729,3740,3744,3748,3762,3787,3803,3814,3825,3829,3833,3837,3846,3863,3873,3877,3881,3898,3911,3921,3925,3935,3949,3954,3978,3992,3997,4024,4029,4034,4038,4042,4068,4073,4082,4095,4107,4117,4121,4125,4129,4144,4157,4186,4244,4254,4269,4284,4309,4314,4321,4326,4331,4346,4359,4386,4402,4428,4453,4474,4479,4486,4491],{"__ignoreMap":36},[40,2821,2822,2824,2827],{"class":42,"line":43},[40,2823,47],{"class":46},[40,2825,2826],{"class":50}," 'dart:isolate'",[40,2828,55],{"class":54},[40,2830,2831,2833,2836],{"class":42,"line":58},[40,2832,47],{"class":46},[40,2834,2835],{"class":50}," 'dart:typed_data'",[40,2837,55],{"class":54},[40,2839,2840,2842,2844],{"class":42,"line":68},[40,2841,47],{"class":46},[40,2843,1785],{"class":50},[40,2845,55],{"class":54},[40,2847,2848],{"class":42,"line":75},[40,2849,72],{"emptyLinePlaceholder":71},[40,2851,2852],{"class":42,"line":82},[40,2853,2854],{"class":78},"\u002F\u002F ── Task definition (sent to workers) ──\n",[40,2856,2857,2859,2862],{"class":42,"line":95},[40,2858,1681],{"class":46},[40,2860,2861],{"class":88}," ImageTask",[40,2863,114],{"class":54},[40,2865,2866,2868,2871],{"class":42,"line":100},[40,2867,184],{"class":46},[40,2869,2870],{"class":88}," int",[40,2872,2873],{"class":54}," id;\n",[40,2875,2876,2878,2881,2884],{"class":42,"line":106},[40,2877,184],{"class":46},[40,2879,2880],{"class":88}," TransferableTypedData",[40,2882,2883],{"class":54}," pixels;  ",[40,2885,2886],{"class":78},"\u002F\u002F zero-copy transfer of pixel data\n",[40,2888,2889,2891,2893],{"class":42,"line":117},[40,2890,184],{"class":46},[40,2892,2870],{"class":88},[40,2894,2895],{"class":54}," width;\n",[40,2897,2898,2900,2902],{"class":42,"line":139},[40,2899,184],{"class":46},[40,2901,2870],{"class":88},[40,2903,2904],{"class":54}," height;\n",[40,2906,2907,2909,2911,2914],{"class":42,"line":157},[40,2908,184],{"class":46},[40,2910,187],{"class":88},[40,2912,2913],{"class":54}," operation;  ",[40,2915,2916],{"class":78},"\u002F\u002F 'grayscale', 'invert', 'blur'\n",[40,2918,2919],{"class":42,"line":176},[40,2920,72],{"emptyLinePlaceholder":71},[40,2922,2923,2925,2927,2929,2931,2934,2936,2939,2941,2944,2946,2949,2951],{"class":42,"line":181},[40,2924,206],{"class":46},[40,2926,2861],{"class":88},[40,2928,124],{"class":54},[40,2930,213],{"class":88},[40,2932,2933],{"class":54},".id, ",[40,2935,213],{"class":88},[40,2937,2938],{"class":54},".pixels, ",[40,2940,213],{"class":88},[40,2942,2943],{"class":54},".width, ",[40,2945,213],{"class":88},[40,2947,2948],{"class":54},".height, ",[40,2950,213],{"class":88},[40,2952,2953],{"class":54},".operation);\n",[40,2955,2956],{"class":42,"line":193},[40,2957,623],{"class":54},[40,2959,2960],{"class":42,"line":203},[40,2961,72],{"emptyLinePlaceholder":71},[40,2963,2964],{"class":42,"line":224},[40,2965,2966],{"class":78},"\u002F\u002F ── Worker pool — reusable isolates for parallel processing ──\n",[40,2968,2969,2971,2974],{"class":42,"line":229},[40,2970,1681],{"class":46},[40,2972,2973],{"class":88}," ImageProcessor",[40,2975,114],{"class":54},[40,2977,2978,2980,2982],{"class":42,"line":235},[40,2979,184],{"class":46},[40,2981,2870],{"class":88},[40,2983,2984],{"class":54}," _poolSize;\n",[40,2986,2987,2989,2992,2994,2997,3000,3002],{"class":42,"line":266},[40,2988,184],{"class":46},[40,2990,2991],{"class":88}," List",[40,2993,736],{"class":54},[40,2995,2996],{"class":88},"_ImageWorker",[40,2998,2999],{"class":54},"> _workers ",[40,3001,761],{"class":46},[40,3003,3004],{"class":54}," [];\n",[40,3006,3007,3009,3012,3014,3016,3018,3020],{"class":42,"line":280},[40,3008,184],{"class":46},[40,3010,3011],{"class":54}," _available ",[40,3013,761],{"class":46},[40,3015,2342],{"class":46},[40,3017,2996],{"class":88},[40,3019,2355],{"class":46},[40,3021,3022],{"class":54},"[];\n",[40,3024,3025,3027,3030,3032,3034,3037,3039,3042,3045,3047,3049],{"class":42,"line":317},[40,3026,184],{"class":46},[40,3028,3029],{"class":54}," _pending ",[40,3031,761],{"class":46},[40,3033,2342],{"class":46},[40,3035,3036],{"class":88},"Completer",[40,3038,736],{"class":54},[40,3040,3041],{"class":88},"Uint8List",[40,3043,3044],{"class":54},">, ",[40,3046,2996],{"class":88},[40,3048,2355],{"class":46},[40,3050,2360],{"class":54},[40,3052,3053,3055,3058,3060,3062,3064,3067,3069,3071,3073,3075,3078,3080],{"class":42,"line":337},[40,3054,184],{"class":46},[40,3056,3057],{"class":54}," _queue ",[40,3059,761],{"class":46},[40,3061,2342],{"class":46},[40,3063,124],{"class":54},[40,3065,3066],{"class":88},"ImageTask",[40,3068,130],{"class":54},[40,3070,3036],{"class":88},[40,3072,736],{"class":54},[40,3074,3041],{"class":88},[40,3076,3077],{"class":54},">)",[40,3079,2355],{"class":46},[40,3081,3022],{"class":54},[40,3083,3084],{"class":42,"line":343},[40,3085,72],{"emptyLinePlaceholder":71},[40,3087,3088,3091,3093,3095],{"class":42,"line":348},[40,3089,3090],{"class":88},"  ImageProcessor",[40,3092,124],{"class":54},[40,3094,213],{"class":88},[40,3096,3097],{"class":54},"._poolSize);\n",[40,3099,3100],{"class":42,"line":354},[40,3101,72],{"emptyLinePlaceholder":71},[40,3103,3104,3107,3109,3111,3113,3116,3118,3120],{"class":42,"line":379},[40,3105,3106],{"class":88},"  Future",[40,3108,736],{"class":54},[40,3110,725],{"class":46},[40,3112,2011],{"class":54},[40,3114,3115],{"class":120},"start",[40,3117,1747],{"class":54},[40,3119,2540],{"class":46},[40,3121,114],{"class":54},[40,3123,3124,3127,3129,3132,3135,3137,3139,3142,3144,3147,3150],{"class":42,"line":391},[40,3125,3126],{"class":46},"    for",[40,3128,258],{"class":54},[40,3130,3131],{"class":46},"var",[40,3133,3134],{"class":54}," i ",[40,3136,761],{"class":46},[40,3138,1467],{"class":88},[40,3140,3141],{"class":54},"; i ",[40,3143,736],{"class":46},[40,3145,3146],{"class":54}," _poolSize; i",[40,3148,3149],{"class":46},"++",[40,3151,263],{"class":54},[40,3153,3154,3157,3160,3162,3164,3167,3169,3172],{"class":42,"line":418},[40,3155,3156],{"class":46},"      final",[40,3158,3159],{"class":54}," worker ",[40,3161,761],{"class":46},[40,3163,2735],{"class":46},[40,3165,3166],{"class":88}," _ImageWorker",[40,3168,1053],{"class":54},[40,3170,3171],{"class":120},"spawn",[40,3173,766],{"class":54},[40,3175,3176,3179,3181],{"class":42,"line":436},[40,3177,3178],{"class":54},"      worker.onResult ",[40,3180,761],{"class":46},[40,3182,3183],{"class":54}," _handleResult;\n",[40,3185,3186,3189,3191],{"class":42,"line":441},[40,3187,3188],{"class":54},"      _workers.",[40,3190,2451],{"class":120},[40,3192,3193],{"class":54},"(worker);\n",[40,3195,3196,3199,3201],{"class":42,"line":446},[40,3197,3198],{"class":54},"      _available.",[40,3200,2451],{"class":120},[40,3202,3193],{"class":54},[40,3204,3205],{"class":42,"line":478},[40,3206,852],{"class":54},[40,3208,3209],{"class":42,"line":498},[40,3210,1144],{"class":54},[40,3212,3213],{"class":42,"line":516},[40,3214,72],{"emptyLinePlaceholder":71},[40,3216,3217,3219,3221,3223,3225,3228,3230,3232,3235,3237,3240,3242,3245,3247],{"class":42,"line":534},[40,3218,3106],{"class":88},[40,3220,736],{"class":54},[40,3222,3041],{"class":88},[40,3224,2011],{"class":54},[40,3226,3227],{"class":120},"process",[40,3229,124],{"class":54},[40,3231,3041],{"class":88},[40,3233,3234],{"class":54}," pixels, ",[40,3236,1160],{"class":88},[40,3238,3239],{"class":54}," w, ",[40,3241,1160],{"class":88},[40,3243,3244],{"class":54}," h, ",[40,3246,459],{"class":88},[40,3248,3249],{"class":54}," op) {\n",[40,3251,3252,3254,3257,3259,3262,3264,3266],{"class":42,"line":569},[40,3253,755],{"class":46},[40,3255,3256],{"class":54}," completer ",[40,3258,761],{"class":46},[40,3260,3261],{"class":88}," Completer",[40,3263,736],{"class":54},[40,3265,3041],{"class":88},[40,3267,3268],{"class":54},">();\n",[40,3270,3271,3273,3276,3278,3280],{"class":42,"line":574},[40,3272,755],{"class":46},[40,3274,3275],{"class":54}," task ",[40,3277,761],{"class":46},[40,3279,2861],{"class":88},[40,3281,878],{"class":54},[40,3283,3284],{"class":42,"line":579},[40,3285,3286],{"class":54},"      _queue.length,\n",[40,3288,3289,3292,3294,3297,3300],{"class":42,"line":603},[40,3290,3291],{"class":88},"      TransferableTypedData",[40,3293,1053],{"class":54},[40,3295,3296],{"class":120},"fromList",[40,3298,3299],{"class":54},"([pixels]),  ",[40,3301,3302],{"class":78},"\u002F\u002F wrap for zero-copy\n",[40,3304,3305],{"class":42,"line":620},[40,3306,3307],{"class":54},"      w, h, op,\n",[40,3309,3310],{"class":42,"line":626},[40,3311,930],{"class":54},[40,3313,3314,3317,3319],{"class":42,"line":631},[40,3315,3316],{"class":54},"    _queue.",[40,3318,2451],{"class":120},[40,3320,3321],{"class":54},"((task, completer));\n",[40,3323,3324,3327],{"class":42,"line":637},[40,3325,3326],{"class":120},"    _processQueue",[40,3328,766],{"class":54},[40,3330,3331,3334],{"class":42,"line":649},[40,3332,3333],{"class":46},"    return",[40,3335,3336],{"class":54}," completer.future;\n",[40,3338,3339],{"class":42,"line":661},[40,3340,1144],{"class":54},[40,3342,3343],{"class":42,"line":678},[40,3344,72],{"emptyLinePlaceholder":71},[40,3346,3347,3350,3353],{"class":42,"line":692},[40,3348,3349],{"class":46},"  void",[40,3351,3352],{"class":120}," _processQueue",[40,3354,646],{"class":54},[40,3356,3357,3360,3363,3366],{"class":42,"line":706},[40,3358,3359],{"class":46},"    while",[40,3361,3362],{"class":54}," (_available.isNotEmpty ",[40,3364,3365],{"class":46},"&&",[40,3367,3368],{"class":54}," _queue.isNotEmpty) {\n",[40,3370,3371,3373,3375,3377,3380,3383],{"class":42,"line":711},[40,3372,3156],{"class":46},[40,3374,3159],{"class":54},[40,3376,761],{"class":46},[40,3378,3379],{"class":54}," _available.",[40,3381,3382],{"class":120},"removeLast",[40,3384,766],{"class":54},[40,3386,3387,3389,3392,3394,3397,3400,3402,3404],{"class":42,"line":716},[40,3388,3156],{"class":46},[40,3390,3391],{"class":54}," (task, completer) ",[40,3393,761],{"class":46},[40,3395,3396],{"class":54}," _queue.",[40,3398,3399],{"class":120},"removeAt",[40,3401,124],{"class":54},[40,3403,1251],{"class":88},[40,3405,173],{"class":54},[40,3407,3408,3411,3413],{"class":42,"line":722},[40,3409,3410],{"class":54},"      _pending[completer] ",[40,3412,761],{"class":46},[40,3414,3415],{"class":54}," worker;\n",[40,3417,3418,3421,3423],{"class":42,"line":744},[40,3419,3420],{"class":54},"      worker.",[40,3422,3227],{"class":120},[40,3424,3425],{"class":54},"(task, completer);\n",[40,3427,3428],{"class":42,"line":752},[40,3429,852],{"class":54},[40,3431,3432],{"class":42,"line":769},[40,3433,1144],{"class":54},[40,3435,3436],{"class":42,"line":788},[40,3437,72],{"emptyLinePlaceholder":71},[40,3439,3440,3442,3445,3447,3449],{"class":42,"line":793},[40,3441,3349],{"class":46},[40,3443,3444],{"class":120}," _handleResult",[40,3446,124],{"class":54},[40,3448,2996],{"class":88},[40,3450,3451],{"class":54}," worker) {\n",[40,3453,3454,3457,3459],{"class":42,"line":806},[40,3455,3456],{"class":54},"    _available.",[40,3458,2451],{"class":120},[40,3460,3193],{"class":54},[40,3462,3463,3465],{"class":42,"line":823},[40,3464,3326],{"class":120},[40,3466,766],{"class":54},[40,3468,3469],{"class":42,"line":832},[40,3470,1144],{"class":54},[40,3472,3473],{"class":42,"line":849},[40,3474,72],{"emptyLinePlaceholder":71},[40,3476,3477,3479,3482],{"class":42,"line":855},[40,3478,3349],{"class":46},[40,3480,3481],{"class":120}," dispose",[40,3483,646],{"class":54},[40,3485,3486,3488,3490,3492,3495,3497,3500,3503],{"class":42,"line":860},[40,3487,3126],{"class":46},[40,3489,258],{"class":54},[40,3491,3131],{"class":46},[40,3493,3494],{"class":54}," w ",[40,3496,1509],{"class":46},[40,3498,3499],{"class":54}," _workers) w.",[40,3501,3502],{"class":120},"kill",[40,3504,766],{"class":54},[40,3506,3507],{"class":42,"line":881},[40,3508,1144],{"class":54},[40,3510,3511],{"class":42,"line":897},[40,3512,623],{"class":54},[40,3514,3515],{"class":42,"line":927},[40,3516,72],{"emptyLinePlaceholder":71},[40,3518,3519,3521,3523],{"class":42,"line":933},[40,3520,1681],{"class":46},[40,3522,3166],{"class":88},[40,3524,114],{"class":54},[40,3526,3527,3530,3533,3536],{"class":42,"line":938},[40,3528,3529],{"class":46},"  late",[40,3531,3532],{"class":46}," final",[40,3534,3535],{"class":88}," Isolate",[40,3537,3538],{"class":54}," _isolate;\n",[40,3540,3541,3543,3545,3548],{"class":42,"line":953},[40,3542,3529],{"class":46},[40,3544,3532],{"class":46},[40,3546,3547],{"class":88}," SendPort",[40,3549,3550],{"class":54}," _sendPort;\n",[40,3552,3553,3555,3558,3560,3563],{"class":42,"line":970},[40,3554,184],{"class":46},[40,3556,3557],{"class":54}," _receivePort ",[40,3559,761],{"class":46},[40,3561,3562],{"class":88}," ReceivePort",[40,3564,766],{"class":54},[40,3566,3567,3569,3572,3575,3577,3579],{"class":42,"line":985},[40,3568,3529],{"class":46},[40,3570,3571],{"class":46}," void",[40,3573,3574],{"class":88}," Function",[40,3576,124],{"class":54},[40,3578,2996],{"class":88},[40,3580,3581],{"class":54},") onResult;\n",[40,3583,3584,3587,3589,3591,3593,3595],{"class":42,"line":1001},[40,3585,3586],{"class":88},"  Completer",[40,3588,736],{"class":54},[40,3590,3041],{"class":88},[40,3592,2355],{"class":54},[40,3594,2368],{"class":46},[40,3596,3597],{"class":54}," _current;\n",[40,3599,3600],{"class":42,"line":1007},[40,3601,72],{"emptyLinePlaceholder":71},[40,3603,3604,3606,3609,3611,3613,3615,3617,3619,3621],{"class":42,"line":1016},[40,3605,449],{"class":46},[40,3607,3608],{"class":88}," Future",[40,3610,736],{"class":54},[40,3612,2996],{"class":88},[40,3614,2011],{"class":54},[40,3616,3171],{"class":120},[40,3618,1747],{"class":54},[40,3620,2540],{"class":46},[40,3622,114],{"class":54},[40,3624,3625,3627,3629,3631,3633],{"class":42,"line":1033},[40,3626,755],{"class":46},[40,3628,3159],{"class":54},[40,3630,761],{"class":46},[40,3632,3166],{"class":88},[40,3634,766],{"class":54},[40,3636,3637,3640,3642,3644,3646,3648,3650],{"class":42,"line":1066},[40,3638,3639],{"class":54},"    worker._isolate ",[40,3641,761],{"class":46},[40,3643,2735],{"class":46},[40,3645,3535],{"class":88},[40,3647,1053],{"class":54},[40,3649,3171],{"class":120},[40,3651,3652],{"class":54},"(_entry, worker._receivePort.sendPort);\n",[40,3654,3655,3658,3660,3662,3665,3667,3669],{"class":42,"line":1076},[40,3656,3657],{"class":54},"    worker._sendPort ",[40,3659,761],{"class":46},[40,3661,2735],{"class":46},[40,3663,3664],{"class":54}," worker._receivePort.first ",[40,3666,1946],{"class":46},[40,3668,3547],{"class":88},[40,3670,55],{"class":54},[40,3672,3673,3676,3679],{"class":42,"line":1087},[40,3674,3675],{"class":54},"    worker._receivePort.",[40,3677,3678],{"class":120},"listen",[40,3680,3681],{"class":54},"(worker._handleMessage);\n",[40,3683,3684,3686],{"class":42,"line":1098},[40,3685,3333],{"class":46},[40,3687,3415],{"class":54},[40,3689,3690],{"class":42,"line":1126},[40,3691,1144],{"class":54},[40,3693,3694],{"class":42,"line":1141},[40,3695,72],{"emptyLinePlaceholder":71},[40,3697,3698,3700,3703,3705,3707,3710,3712,3714,3716],{"class":42,"line":1147},[40,3699,3349],{"class":46},[40,3701,3702],{"class":120}," process",[40,3704,124],{"class":54},[40,3706,3066],{"class":88},[40,3708,3709],{"class":54}," task, ",[40,3711,3036],{"class":88},[40,3713,736],{"class":54},[40,3715,3041],{"class":88},[40,3717,3718],{"class":54},"> completer) {\n",[40,3720,3721,3724,3726],{"class":42,"line":1152},[40,3722,3723],{"class":54},"    _current ",[40,3725,761],{"class":46},[40,3727,3728],{"class":54}," completer;\n",[40,3730,3731,3734,3737],{"class":42,"line":1157},[40,3732,3733],{"class":54},"    _sendPort.",[40,3735,3736],{"class":120},"send",[40,3738,3739],{"class":54},"(task);\n",[40,3741,3742],{"class":42,"line":1173},[40,3743,1144],{"class":54},[40,3745,3746],{"class":42,"line":1190},[40,3747,72],{"emptyLinePlaceholder":71},[40,3749,3750,3752,3755,3757,3759],{"class":42,"line":1200},[40,3751,3349],{"class":46},[40,3753,3754],{"class":120}," _handleMessage",[40,3756,124],{"class":54},[40,3758,1916],{"class":88},[40,3760,3761],{"class":54}," message) {\n",[40,3763,3764,3766,3769,3772,3775,3778,3781,3783,3785],{"class":42,"line":1208},[40,3765,809],{"class":46},[40,3767,3768],{"class":54}," (message ",[40,3770,3771],{"class":46},"is",[40,3773,3774],{"class":88}," Uint8List",[40,3776,3777],{"class":46}," &&",[40,3779,3780],{"class":54}," _current ",[40,3782,1182],{"class":46},[40,3784,818],{"class":88},[40,3786,263],{"class":54},[40,3788,3789,3792,3795,3797,3800],{"class":42,"line":1216},[40,3790,3791],{"class":54},"      _current",[40,3793,3794],{"class":46},"!",[40,3796,1053],{"class":54},[40,3798,3799],{"class":120},"complete",[40,3801,3802],{"class":54},"(message);\n",[40,3804,3805,3808,3810,3812],{"class":42,"line":1221},[40,3806,3807],{"class":54},"      _current ",[40,3809,761],{"class":46},[40,3811,818],{"class":88},[40,3813,55],{"class":54},[40,3815,3816,3819,3821,3823],{"class":42,"line":1226},[40,3817,3818],{"class":120},"      onResult",[40,3820,124],{"class":54},[40,3822,213],{"class":88},[40,3824,173],{"class":54},[40,3826,3827],{"class":42,"line":1231},[40,3828,852],{"class":54},[40,3830,3831],{"class":42,"line":1257},[40,3832,1144],{"class":54},[40,3834,3835],{"class":42,"line":1270},[40,3836,72],{"emptyLinePlaceholder":71},[40,3838,3839,3841,3844],{"class":42,"line":1308},[40,3840,3349],{"class":46},[40,3842,3843],{"class":120}," kill",[40,3845,646],{"class":54},[40,3847,3848,3851,3853,3856,3858,3860],{"class":42,"line":1313},[40,3849,3850],{"class":54},"    _isolate.",[40,3852,3502],{"class":120},[40,3854,3855],{"class":54},"(priority",[40,3857,903],{"class":46},[40,3859,3535],{"class":88},[40,3861,3862],{"class":54},".immediate);\n",[40,3864,3865,3868,3871],{"class":42,"line":1318},[40,3866,3867],{"class":54},"    _receivePort.",[40,3869,3870],{"class":120},"close",[40,3872,766],{"class":54},[40,3874,3875],{"class":42,"line":1341},[40,3876,1144],{"class":54},[40,3878,3879],{"class":42,"line":1364},[40,3880,72],{"emptyLinePlaceholder":71},[40,3882,3883,3885,3887,3890,3892,3895],{"class":42,"line":1383},[40,3884,449],{"class":46},[40,3886,3571],{"class":46},[40,3888,3889],{"class":120}," _entry",[40,3891,124],{"class":54},[40,3893,3894],{"class":88},"SendPort",[40,3896,3897],{"class":54}," mainPort) {\n",[40,3899,3900,3902,3905,3907,3909],{"class":42,"line":1388},[40,3901,755],{"class":46},[40,3903,3904],{"class":54}," receivePort ",[40,3906,761],{"class":46},[40,3908,3562],{"class":88},[40,3910,766],{"class":54},[40,3912,3913,3916,3918],{"class":42,"line":1428},[40,3914,3915],{"class":54},"    mainPort.",[40,3917,3736],{"class":120},[40,3919,3920],{"class":54},"(receivePort.sendPort);\n",[40,3922,3923],{"class":42,"line":1462},[40,3924,72],{"emptyLinePlaceholder":71},[40,3926,3927,3930,3932],{"class":42,"line":1472},[40,3928,3929],{"class":54},"    receivePort.",[40,3931,3678],{"class":120},[40,3933,3934],{"class":54},"((task) {\n",[40,3936,3937,3940,3943,3945,3947],{"class":42,"line":1477},[40,3938,3939],{"class":46},"      if",[40,3941,3942],{"class":54}," (task ",[40,3944,3771],{"class":46},[40,3946,2861],{"class":88},[40,3948,263],{"class":54},[40,3950,3951],{"class":42,"line":1482},[40,3952,3953],{"class":78},"        \u002F\u002F Materialize the transferred data (zero-copy — moved, not copied):\n",[40,3955,3956,3959,3962,3964,3967,3970,3973,3976],{"class":42,"line":1495},[40,3957,3958],{"class":46},"        final",[40,3960,3961],{"class":54}," data ",[40,3963,761],{"class":46},[40,3965,3966],{"class":54}," task.pixels.",[40,3968,3969],{"class":120},"materialize",[40,3971,3972],{"class":54},"().",[40,3974,3975],{"class":120},"asUint8List",[40,3977,766],{"class":54},[40,3979,3980,3982,3984,3986,3989],{"class":42,"line":1517},[40,3981,3958],{"class":46},[40,3983,1369],{"class":54},[40,3985,761],{"class":46},[40,3987,3988],{"class":120}," _processImage",[40,3990,3991],{"class":54},"(data, task.width, task.height, task.operation);\n",[40,3993,3994],{"class":42,"line":1569},[40,3995,3996],{"class":78},"        \u002F\u002F Transfer the result back (zero-copy):\n",[40,3998,3999,4002,4004,4006,4009,4011,4013,4016,4018,4020,4022],{"class":42,"line":1574},[40,4000,4001],{"class":54},"        mainPort.",[40,4003,3736],{"class":120},[40,4005,124],{"class":54},[40,4007,4008],{"class":88},"TransferableTypedData",[40,4010,1053],{"class":54},[40,4012,3296],{"class":120},[40,4014,4015],{"class":54},"([result]).",[40,4017,3969],{"class":120},[40,4019,3972],{"class":54},[40,4021,3975],{"class":120},[40,4023,2068],{"class":54},[40,4025,4026],{"class":42,"line":1583},[40,4027,4028],{"class":54},"      }\n",[40,4030,4031],{"class":42,"line":1588},[40,4032,4033],{"class":54},"    });\n",[40,4035,4036],{"class":42,"line":1593},[40,4037,1144],{"class":54},[40,4039,4040],{"class":42,"line":1602},[40,4041,72],{"emptyLinePlaceholder":71},[40,4043,4044,4046,4048,4050,4052,4054,4056,4058,4060,4062,4064,4066],{"class":42,"line":1614},[40,4045,449],{"class":46},[40,4047,3774],{"class":88},[40,4049,3988],{"class":120},[40,4051,124],{"class":54},[40,4053,3041],{"class":88},[40,4055,3234],{"class":54},[40,4057,1160],{"class":88},[40,4059,3239],{"class":54},[40,4061,1160],{"class":88},[40,4063,3244],{"class":54},[40,4065,459],{"class":88},[40,4067,3249],{"class":54},[40,4069,4070],{"class":42,"line":1623},[40,4071,4072],{"class":78},"    \u002F\u002F Image processing — grayscale, invert, etc.\n",[40,4074,4075,4077,4079],{"class":42,"line":1628},[40,4076,3333],{"class":46},[40,4078,255],{"class":46},[40,4080,4081],{"class":54}," (op) {\n",[40,4083,4084,4087,4089,4092],{"class":42,"line":1633},[40,4085,4086],{"class":50},"      'grayscale'",[40,4088,490],{"class":46},[40,4090,4091],{"class":120}," _grayscale",[40,4093,4094],{"class":54},"(pixels),\n",[40,4096,4097,4100,4102,4105],{"class":42,"line":1648},[40,4098,4099],{"class":50},"      'invert'",[40,4101,490],{"class":46},[40,4103,4104],{"class":120}," _invert",[40,4106,4094],{"class":54},[40,4108,4109,4112,4114],{"class":42,"line":1660},[40,4110,4111],{"class":54},"      _ ",[40,4113,252],{"class":46},[40,4115,4116],{"class":54}," pixels,\n",[40,4118,4119],{"class":42,"line":1668},[40,4120,1004],{"class":54},[40,4122,4123],{"class":42,"line":1673},[40,4124,1144],{"class":54},[40,4126,4127],{"class":42,"line":1678},[40,4128,72],{"emptyLinePlaceholder":71},[40,4130,4131,4133,4135,4137,4139,4141],{"class":42,"line":1694},[40,4132,449],{"class":46},[40,4134,3774],{"class":88},[40,4136,4091],{"class":120},[40,4138,124],{"class":54},[40,4140,3041],{"class":88},[40,4142,4143],{"class":54}," pixels) {\n",[40,4145,4146,4148,4150,4152,4154],{"class":42,"line":1704},[40,4147,755],{"class":46},[40,4149,1369],{"class":54},[40,4151,761],{"class":46},[40,4153,3774],{"class":88},[40,4155,4156],{"class":54},"(pixels.length);\n",[40,4158,4159,4161,4163,4165,4167,4169,4171,4173,4175,4178,4181,4184],{"class":42,"line":1714},[40,4160,3126],{"class":46},[40,4162,258],{"class":54},[40,4164,3131],{"class":46},[40,4166,3134],{"class":54},[40,4168,761],{"class":46},[40,4170,1467],{"class":88},[40,4172,3141],{"class":54},[40,4174,736],{"class":46},[40,4176,4177],{"class":54}," pixels.length; i ",[40,4179,4180],{"class":46},"+=",[40,4182,4183],{"class":88}," 4",[40,4185,263],{"class":54},[40,4187,4188,4190,4193,4195,4198,4200,4203,4205,4208,4210,4213,4215,4217,4220,4222,4224,4226,4229,4231,4233,4236,4239,4242],{"class":42,"line":1732},[40,4189,3156],{"class":46},[40,4191,4192],{"class":54}," gray ",[40,4194,761],{"class":46},[40,4196,4197],{"class":54}," (pixels[i] ",[40,4199,302],{"class":46},[40,4201,4202],{"class":88}," 0.299",[40,4204,411],{"class":46},[40,4206,4207],{"class":54}," pixels[i ",[40,4209,429],{"class":46},[40,4211,4212],{"class":88}," 1",[40,4214,1943],{"class":54},[40,4216,302],{"class":46},[40,4218,4219],{"class":88}," 0.587",[40,4221,411],{"class":46},[40,4223,4207],{"class":54},[40,4225,429],{"class":46},[40,4227,4228],{"class":88}," 2",[40,4230,1943],{"class":54},[40,4232,302],{"class":46},[40,4234,4235],{"class":88}," 0.114",[40,4237,4238],{"class":54},").",[40,4240,4241],{"class":120},"toInt",[40,4243,766],{"class":54},[40,4245,4246,4249,4251],{"class":42,"line":1738},[40,4247,4248],{"class":54},"      result[i] ",[40,4250,761],{"class":46},[40,4252,4253],{"class":54}," gray;\n",[40,4255,4256,4259,4261,4263,4265,4267],{"class":42,"line":1754},[40,4257,4258],{"class":54},"      result[i ",[40,4260,429],{"class":46},[40,4262,4212],{"class":88},[40,4264,1943],{"class":54},[40,4266,761],{"class":46},[40,4268,4253],{"class":54},[40,4270,4272,4274,4276,4278,4280,4282],{"class":42,"line":4271},129,[40,4273,4258],{"class":54},[40,4275,429],{"class":46},[40,4277,4228],{"class":88},[40,4279,1943],{"class":54},[40,4281,761],{"class":46},[40,4283,4253],{"class":54},[40,4285,4287,4289,4291,4293,4295,4297,4299,4301,4303,4306],{"class":42,"line":4286},130,[40,4288,4258],{"class":54},[40,4290,429],{"class":46},[40,4292,1185],{"class":88},[40,4294,1943],{"class":54},[40,4296,761],{"class":46},[40,4298,4207],{"class":54},[40,4300,429],{"class":46},[40,4302,1185],{"class":88},[40,4304,4305],{"class":54},"];  ",[40,4307,4308],{"class":78},"\u002F\u002F alpha unchanged\n",[40,4310,4312],{"class":42,"line":4311},131,[40,4313,852],{"class":54},[40,4315,4317,4319],{"class":42,"line":4316},132,[40,4318,3333],{"class":46},[40,4320,2698],{"class":54},[40,4322,4324],{"class":42,"line":4323},133,[40,4325,1144],{"class":54},[40,4327,4329],{"class":42,"line":4328},134,[40,4330,72],{"emptyLinePlaceholder":71},[40,4332,4334,4336,4338,4340,4342,4344],{"class":42,"line":4333},135,[40,4335,449],{"class":46},[40,4337,3774],{"class":88},[40,4339,4104],{"class":120},[40,4341,124],{"class":54},[40,4343,3041],{"class":88},[40,4345,4143],{"class":54},[40,4347,4349,4351,4353,4355,4357],{"class":42,"line":4348},136,[40,4350,755],{"class":46},[40,4352,1369],{"class":54},[40,4354,761],{"class":46},[40,4356,3774],{"class":88},[40,4358,4156],{"class":54},[40,4360,4362,4364,4366,4368,4370,4372,4374,4376,4378,4380,4382,4384],{"class":42,"line":4361},137,[40,4363,3126],{"class":46},[40,4365,258],{"class":54},[40,4367,3131],{"class":46},[40,4369,3134],{"class":54},[40,4371,761],{"class":46},[40,4373,1467],{"class":88},[40,4375,3141],{"class":54},[40,4377,736],{"class":46},[40,4379,4177],{"class":54},[40,4381,4180],{"class":46},[40,4383,4183],{"class":88},[40,4385,263],{"class":54},[40,4387,4389,4391,4393,4396,4399],{"class":42,"line":4388},138,[40,4390,4248],{"class":54},[40,4392,761],{"class":46},[40,4394,4395],{"class":88}," 255",[40,4397,4398],{"class":46}," -",[40,4400,4401],{"class":54}," pixels[i];\n",[40,4403,4405,4407,4409,4411,4413,4415,4417,4419,4421,4423,4425],{"class":42,"line":4404},139,[40,4406,4258],{"class":54},[40,4408,429],{"class":46},[40,4410,4212],{"class":88},[40,4412,1943],{"class":54},[40,4414,761],{"class":46},[40,4416,4395],{"class":88},[40,4418,4398],{"class":46},[40,4420,4207],{"class":54},[40,4422,429],{"class":46},[40,4424,4212],{"class":88},[40,4426,4427],{"class":54},"];\n",[40,4429,4431,4433,4435,4437,4439,4441,4443,4445,4447,4449,4451],{"class":42,"line":4430},140,[40,4432,4258],{"class":54},[40,4434,429],{"class":46},[40,4436,4228],{"class":88},[40,4438,1943],{"class":54},[40,4440,761],{"class":46},[40,4442,4395],{"class":88},[40,4444,4398],{"class":46},[40,4446,4207],{"class":54},[40,4448,429],{"class":46},[40,4450,4228],{"class":88},[40,4452,4427],{"class":54},[40,4454,4456,4458,4460,4462,4464,4466,4468,4470,4472],{"class":42,"line":4455},141,[40,4457,4258],{"class":54},[40,4459,429],{"class":46},[40,4461,1185],{"class":88},[40,4463,1943],{"class":54},[40,4465,761],{"class":46},[40,4467,4207],{"class":54},[40,4469,429],{"class":46},[40,4471,1185],{"class":88},[40,4473,4427],{"class":54},[40,4475,4477],{"class":42,"line":4476},142,[40,4478,852],{"class":54},[40,4480,4482,4484],{"class":42,"line":4481},143,[40,4483,3333],{"class":46},[40,4485,2698],{"class":54},[40,4487,4489],{"class":42,"line":4488},144,[40,4490,1144],{"class":54},[40,4492,4494],{"class":42,"line":4493},145,[40,4495,623],{"class":54},[14,4497,4499],{"id":4498},"project-4-full-stack-capstone-flutter-dart_frog-shared-models","Project 4 — Full-Stack Capstone (Flutter + dart_frog + Shared Models)",[19,4501,4502],{},"A production full-stack app with shared data models, a REST API, and a Flutter client. Demonstrates monorepo structure, shared packages, and end-to-end types.",[28,4504,4506],{"language":4505},"text",[32,4507,4511],{"className":4508,"code":4510,"language":4505,"meta":36},[4509],"language-text","capstone\u002F\n├── packages\u002F\n│   └── models\u002F              # shared data models (freezed + json_serializable)\n│       ├── lib\u002F\n│       │   ├── models.dart   # public API barrel\n│       │   └── src\u002F\n│       │       ├── task.dart\n│       │       └── user.dart\n│       ├── pubspec.yaml\n│       └── analysis_options.yaml\n├── server\u002F                  # dart_frog REST API\n│   ├── routes\u002F\n│   │   ├── index.dart\n│   │   ├── tasks\u002F\n│   │   │   ├── index.dart\n│   │   │   └── [id].dart\n│   │   └── _middleware.dart\n│   ├── lib\u002F\n│   │   └── db.dart           # database layer\n│   ├── test\u002F\n│   │   └── tasks_test.dart\n│   ├── pubspec.yaml\n│   └── Dockerfile\n├── client\u002F                  # Flutter app\n│   ├── lib\u002F\n│   │   ├── main.dart\n│   │   ├── api\u002F\n│   │   │   └── api_client.dart\n│   │   ├── state\u002F\n│   │   │   └── task_provider.dart\n│   │   └── screens\u002F\n│   │       ├── task_list_screen.dart\n│   │       └── task_detail_screen.dart\n│   ├── pubspec.yaml\n│   └── analysis_options.yaml\n└── melos.yaml               # monorepo management\n",[23,4512,4510],{"__ignoreMap":36},[4514,4515,4517],"h3",{"id":4516},"shared-models-package","Shared Models Package",[28,4519,4520],{"language":30},[32,4521,4523],{"className":34,"code":4522,"language":30,"meta":36,"style":36},"\u002F\u002F packages\u002Fmodels\u002Flib\u002Fsrc\u002Ftask.dart\nimport 'package:freezed_annotation\u002Ffreezed_annotation.dart';\npart 'task.freezed.dart';\npart 'task.g.dart';\n\n@freezed\nclass Task with _$Task {\n  const factory Task({\n    required String id,\n    required String title,\n    required String description,\n    @Default(false) bool completed,\n    required DateTime createdAt,\n    DateTime? completedAt,\n  }) = _Task;\n\n  factory Task.fromJson(Map\u003CString, dynamic> json) => _$TaskFromJson(json);\n}\n\n\u002F\u002F packages\u002Fmodels\u002Flib\u002Fmodels.dart — barrel file\nexport 'src\u002Ftask.dart';\nexport 'src\u002Fuser.dart';\n",[23,4524,4525,4530,4539,4549,4558,4562,4567,4582,4594,4604,4613,4622,4640,4649,4658,4670,4674,4706,4710,4714,4719,4729],{"__ignoreMap":36},[40,4526,4527],{"class":42,"line":43},[40,4528,4529],{"class":78},"\u002F\u002F packages\u002Fmodels\u002Flib\u002Fsrc\u002Ftask.dart\n",[40,4531,4532,4534,4537],{"class":42,"line":58},[40,4533,47],{"class":46},[40,4535,4536],{"class":50}," 'package:freezed_annotation\u002Ffreezed_annotation.dart'",[40,4538,55],{"class":54},[40,4540,4541,4544,4547],{"class":42,"line":68},[40,4542,4543],{"class":46},"part",[40,4545,4546],{"class":50}," 'task.freezed.dart'",[40,4548,55],{"class":54},[40,4550,4551,4553,4556],{"class":42,"line":75},[40,4552,4543],{"class":46},[40,4554,4555],{"class":50}," 'task.g.dart'",[40,4557,55],{"class":54},[40,4559,4560],{"class":42,"line":82},[40,4561,72],{"emptyLinePlaceholder":71},[40,4563,4564],{"class":42,"line":95},[40,4565,4566],{"class":46},"@freezed\n",[40,4568,4569,4571,4574,4577,4580],{"class":42,"line":100},[40,4570,1681],{"class":46},[40,4572,4573],{"class":88}," Task",[40,4575,4576],{"class":46}," with",[40,4578,4579],{"class":88}," _$Task",[40,4581,114],{"class":54},[40,4583,4584,4586,4589,4591],{"class":42,"line":106},[40,4585,206],{"class":46},[40,4587,4588],{"class":46}," factory",[40,4590,4573],{"class":88},[40,4592,4593],{"class":54},"({\n",[40,4595,4596,4599,4601],{"class":42,"line":117},[40,4597,4598],{"class":46},"    required",[40,4600,187],{"class":88},[40,4602,4603],{"class":54}," id,\n",[40,4605,4606,4608,4610],{"class":42,"line":139},[40,4607,4598],{"class":46},[40,4609,187],{"class":88},[40,4611,4612],{"class":54}," title,\n",[40,4614,4615,4617,4619],{"class":42,"line":157},[40,4616,4598],{"class":46},[40,4618,187],{"class":88},[40,4620,4621],{"class":54}," description,\n",[40,4623,4624,4627,4629,4632,4634,4637],{"class":42,"line":176},[40,4625,4626],{"class":46},"    @Default",[40,4628,124],{"class":54},[40,4630,4631],{"class":88},"false",[40,4633,299],{"class":54},[40,4635,4636],{"class":88},"bool",[40,4638,4639],{"class":54}," completed,\n",[40,4641,4642,4644,4646],{"class":42,"line":181},[40,4643,4598],{"class":46},[40,4645,1843],{"class":88},[40,4647,4648],{"class":54}," createdAt,\n",[40,4650,4651,4653,4655],{"class":42,"line":193},[40,4652,1930],{"class":88},[40,4654,2368],{"class":46},[40,4656,4657],{"class":54}," completedAt,\n",[40,4659,4660,4663,4665,4668],{"class":42,"line":203},[40,4661,4662],{"class":54},"  }) ",[40,4664,761],{"class":46},[40,4666,4667],{"class":88}," _Task",[40,4669,55],{"class":54},[40,4671,4672],{"class":42,"line":224},[40,4673,72],{"emptyLinePlaceholder":71},[40,4675,4676,4678,4680,4682,4684,4686,4688,4690,4692,4694,4696,4698,4700,4703],{"class":42,"line":229},[40,4677,1895],{"class":46},[40,4679,4573],{"class":88},[40,4681,1053],{"class":54},[40,4683,1902],{"class":120},[40,4685,124],{"class":54},[40,4687,1907],{"class":88},[40,4689,736],{"class":54},[40,4691,459],{"class":88},[40,4693,130],{"class":54},[40,4695,1916],{"class":88},[40,4697,1919],{"class":54},[40,4699,252],{"class":46},[40,4701,4702],{"class":88}," _$TaskFromJson",[40,4704,4705],{"class":54},"(json);\n",[40,4707,4708],{"class":42,"line":235},[40,4709,623],{"class":54},[40,4711,4712],{"class":42,"line":266},[40,4713,72],{"emptyLinePlaceholder":71},[40,4715,4716],{"class":42,"line":280},[40,4717,4718],{"class":78},"\u002F\u002F packages\u002Fmodels\u002Flib\u002Fmodels.dart — barrel file\n",[40,4720,4721,4724,4727],{"class":42,"line":317},[40,4722,4723],{"class":46},"export",[40,4725,4726],{"class":50}," 'src\u002Ftask.dart'",[40,4728,55],{"class":54},[40,4730,4731,4733,4736],{"class":42,"line":337},[40,4732,4723],{"class":46},[40,4734,4735],{"class":50}," 'src\u002Fuser.dart'",[40,4737,55],{"class":54},[4514,4739,4741],{"id":4740},"server-dart_frog-rest-api","Server — dart_frog REST API",[28,4743,4744,5211,5825,5829],{"language":30},[32,4745,4747],{"className":34,"code":4746,"language":30,"meta":36,"style":36},"\u002F\u002F server\u002Froutes\u002Ftasks\u002Findex.dart\nimport 'package:dart_frog\u002Fdart_frog.dart';\nimport 'package:models\u002Fmodels.dart';\nimport '..\u002F..\u002Flib\u002Fdb.dart';\n\nFuture\u003CResponse> onRequest(RequestContext context) async {\n  final db = context.read\u003CTaskDatabase>();\n\n  return switch (context.request.method) {\n    HttpMethod.get => Response.json(body: await db.all()),\n    HttpMethod.post => _createTask(context, db),\n    _ => Response(statusCode: HttpStatus.methodNotAllowed),\n  };\n}\n\nFuture\u003CResponse> _createTask(RequestContext context, TaskDatabase db) async {\n  final body = await context.request.json() as Map\u003CString, dynamic>;\n  final title = body['title'] as String?;\n  if (title == null || title.isEmpty) {\n    return Response(statusCode: 400, body: 'Title is required');\n  }\n  final task = Task(\n    id: _generateId(),\n    title: title,\n    description: body['description'] as String? ?? '',\n    createdAt: DateTime.now(),\n  );\n  await db.insert(task);\n  return Response.json(statusCode: 201, body: task.toJson());\n}\n\nString _generateId() => DateTime.now().microsecondsSinceEpoch.toString();\n",[23,4748,4749,4754,4763,4772,4781,4785,4811,4833,4837,4846,4882,4897,4916,4920,4924,4928,4957,4990,5015,5031,5054,5058,5070,5082,5091,5119,5135,5139,5150,5179,5183,5187],{"__ignoreMap":36},[40,4750,4751],{"class":42,"line":43},[40,4752,4753],{"class":78},"\u002F\u002F server\u002Froutes\u002Ftasks\u002Findex.dart\n",[40,4755,4756,4758,4761],{"class":42,"line":58},[40,4757,47],{"class":46},[40,4759,4760],{"class":50}," 'package:dart_frog\u002Fdart_frog.dart'",[40,4762,55],{"class":54},[40,4764,4765,4767,4770],{"class":42,"line":68},[40,4766,47],{"class":46},[40,4768,4769],{"class":50}," 'package:models\u002Fmodels.dart'",[40,4771,55],{"class":54},[40,4773,4774,4776,4779],{"class":42,"line":75},[40,4775,47],{"class":46},[40,4777,4778],{"class":50}," '..\u002F..\u002Flib\u002Fdb.dart'",[40,4780,55],{"class":54},[40,4782,4783],{"class":42,"line":82},[40,4784,72],{"emptyLinePlaceholder":71},[40,4786,4787,4789,4791,4794,4796,4799,4801,4804,4807,4809],{"class":42,"line":95},[40,4788,2512],{"class":88},[40,4790,736],{"class":54},[40,4792,4793],{"class":88},"Response",[40,4795,2011],{"class":54},[40,4797,4798],{"class":120},"onRequest",[40,4800,124],{"class":54},[40,4802,4803],{"class":88},"RequestContext",[40,4805,4806],{"class":54}," context) ",[40,4808,2540],{"class":46},[40,4810,114],{"class":54},[40,4812,4813,4815,4818,4820,4823,4826,4828,4831],{"class":42,"line":100},[40,4814,184],{"class":46},[40,4816,4817],{"class":54}," db ",[40,4819,761],{"class":46},[40,4821,4822],{"class":54}," context.",[40,4824,4825],{"class":120},"read",[40,4827,736],{"class":54},[40,4829,4830],{"class":88},"TaskDatabase",[40,4832,3268],{"class":54},[40,4834,4835],{"class":42,"line":106},[40,4836,72],{"emptyLinePlaceholder":71},[40,4838,4839,4841,4843],{"class":42,"line":117},[40,4840,652],{"class":46},[40,4842,255],{"class":46},[40,4844,4845],{"class":54}," (context.request.method) {\n",[40,4847,4848,4851,4853,4856,4858,4861,4863,4866,4869,4871,4873,4876,4879],{"class":42,"line":139},[40,4849,4850],{"class":88},"    HttpMethod",[40,4852,1053],{"class":54},[40,4854,4855],{"class":46},"get",[40,4857,490],{"class":46},[40,4859,4860],{"class":88}," Response",[40,4862,1053],{"class":54},[40,4864,4865],{"class":120},"json",[40,4867,4868],{"class":54},"(body",[40,4870,903],{"class":46},[40,4872,2735],{"class":46},[40,4874,4875],{"class":54}," db.",[40,4877,4878],{"class":120},"all",[40,4880,4881],{"class":54},"()),\n",[40,4883,4884,4886,4889,4891,4894],{"class":42,"line":157},[40,4885,4850],{"class":88},[40,4887,4888],{"class":54},".post ",[40,4890,252],{"class":46},[40,4892,4893],{"class":120}," _createTask",[40,4895,4896],{"class":54},"(context, db),\n",[40,4898,4899,4901,4903,4905,4908,4910,4913],{"class":42,"line":176},[40,4900,537],{"class":54},[40,4902,252],{"class":46},[40,4904,4860],{"class":88},[40,4906,4907],{"class":54},"(statusCode",[40,4909,903],{"class":46},[40,4911,4912],{"class":88}," HttpStatus",[40,4914,4915],{"class":54},".methodNotAllowed),\n",[40,4917,4918],{"class":42,"line":181},[40,4919,340],{"class":54},[40,4921,4922],{"class":42,"line":193},[40,4923,623],{"class":54},[40,4925,4926],{"class":42,"line":203},[40,4927,72],{"emptyLinePlaceholder":71},[40,4929,4930,4932,4934,4936,4938,4941,4943,4945,4948,4950,4953,4955],{"class":42,"line":224},[40,4931,2512],{"class":88},[40,4933,736],{"class":54},[40,4935,4793],{"class":88},[40,4937,2011],{"class":54},[40,4939,4940],{"class":120},"_createTask",[40,4942,124],{"class":54},[40,4944,4803],{"class":88},[40,4946,4947],{"class":54}," context, ",[40,4949,4830],{"class":88},[40,4951,4952],{"class":54}," db) ",[40,4954,2540],{"class":46},[40,4956,114],{"class":54},[40,4958,4959,4961,4964,4966,4968,4971,4973,4975,4977,4979,4981,4983,4985,4987],{"class":42,"line":229},[40,4960,184],{"class":46},[40,4962,4963],{"class":54}," body ",[40,4965,761],{"class":46},[40,4967,2735],{"class":46},[40,4969,4970],{"class":54}," context.request.",[40,4972,4865],{"class":120},[40,4974,1747],{"class":54},[40,4976,1946],{"class":46},[40,4978,2158],{"class":88},[40,4980,736],{"class":54},[40,4982,459],{"class":88},[40,4984,130],{"class":54},[40,4986,1916],{"class":88},[40,4988,4989],{"class":54},">;\n",[40,4991,4992,4994,4997,4999,5002,5005,5007,5009,5011,5013],{"class":42,"line":235},[40,4993,184],{"class":46},[40,4995,4996],{"class":54}," title ",[40,4998,761],{"class":46},[40,5000,5001],{"class":54}," body[",[40,5003,5004],{"class":50},"'title'",[40,5006,1943],{"class":54},[40,5008,1946],{"class":46},[40,5010,187],{"class":88},[40,5012,2368],{"class":46},[40,5014,55],{"class":54},[40,5016,5017,5019,5022,5024,5026,5028],{"class":42,"line":266},[40,5018,1176],{"class":46},[40,5020,5021],{"class":54}," (title ",[40,5023,815],{"class":46},[40,5025,818],{"class":88},[40,5027,484],{"class":46},[40,5029,5030],{"class":54}," title.isEmpty) {\n",[40,5032,5033,5035,5037,5039,5041,5044,5047,5049,5052],{"class":42,"line":280},[40,5034,3333],{"class":46},[40,5036,4860],{"class":88},[40,5038,4907],{"class":54},[40,5040,903],{"class":46},[40,5042,5043],{"class":88}," 400",[40,5045,5046],{"class":54},", body",[40,5048,903],{"class":46},[40,5050,5051],{"class":50}," 'Title is required'",[40,5053,173],{"class":54},[40,5055,5056],{"class":42,"line":317},[40,5057,1144],{"class":54},[40,5059,5060,5062,5064,5066,5068],{"class":42,"line":337},[40,5061,184],{"class":46},[40,5063,3275],{"class":54},[40,5065,761],{"class":46},[40,5067,4573],{"class":88},[40,5069,878],{"class":54},[40,5071,5072,5075,5077,5080],{"class":42,"line":343},[40,5073,5074],{"class":54},"    id",[40,5076,903],{"class":46},[40,5078,5079],{"class":120}," _generateId",[40,5081,998],{"class":54},[40,5083,5084,5087,5089],{"class":42,"line":348},[40,5085,5086],{"class":54},"    title",[40,5088,903],{"class":46},[40,5090,4612],{"class":54},[40,5092,5093,5096,5098,5100,5103,5105,5107,5109,5111,5114,5117],{"class":42,"line":354},[40,5094,5095],{"class":54},"    description",[40,5097,903],{"class":46},[40,5099,5001],{"class":54},[40,5101,5102],{"class":50},"'description'",[40,5104,1943],{"class":54},[40,5106,1946],{"class":46},[40,5108,187],{"class":88},[40,5110,2368],{"class":46},[40,5112,5113],{"class":46}," ??",[40,5115,5116],{"class":50}," ''",[40,5118,314],{"class":54},[40,5120,5121,5124,5126,5128,5130,5133],{"class":42,"line":379},[40,5122,5123],{"class":54},"    createdAt",[40,5125,903],{"class":46},[40,5127,1843],{"class":88},[40,5129,1053],{"class":54},[40,5131,5132],{"class":120},"now",[40,5134,998],{"class":54},[40,5136,5137],{"class":42,"line":391},[40,5138,1986],{"class":54},[40,5140,5141,5143,5145,5148],{"class":42,"line":418},[40,5142,2380],{"class":46},[40,5144,4875],{"class":54},[40,5146,5147],{"class":120},"insert",[40,5149,3739],{"class":54},[40,5151,5152,5154,5156,5158,5160,5162,5164,5167,5169,5171,5174,5177],{"class":42,"line":436},[40,5153,652],{"class":46},[40,5155,4860],{"class":88},[40,5157,1053],{"class":54},[40,5159,4865],{"class":120},[40,5161,4907],{"class":54},[40,5163,903],{"class":46},[40,5165,5166],{"class":88}," 201",[40,5168,5046],{"class":54},[40,5170,903],{"class":46},[40,5172,5173],{"class":54}," task.",[40,5175,5176],{"class":120},"toJson",[40,5178,2068],{"class":54},[40,5180,5181],{"class":42,"line":441},[40,5182,623],{"class":54},[40,5184,5185],{"class":42,"line":446},[40,5186,72],{"emptyLinePlaceholder":71},[40,5188,5189,5191,5193,5195,5197,5199,5201,5203,5206,5209],{"class":42,"line":478},[40,5190,459],{"class":88},[40,5192,5079],{"class":120},[40,5194,1747],{"class":54},[40,5196,252],{"class":46},[40,5198,1843],{"class":88},[40,5200,1053],{"class":54},[40,5202,5132],{"class":120},[40,5204,5205],{"class":54},"().microsecondsSinceEpoch.",[40,5207,5208],{"class":120},"toString",[40,5210,766],{"class":54},[28,5212,5213],{"language":30},[32,5214,5216],{"className":34,"code":5215,"language":30,"meta":36,"style":36},"\u002F\u002F server\u002Froutes\u002Ftasks\u002F[id].dart\nimport 'package:dart_frog\u002Fdart_frog.dart';\nimport 'package:models\u002Fmodels.dart';\nimport '..\u002F..\u002Flib\u002Fdb.dart';\n\nFuture\u003CResponse> onRequest(RequestContext context, String id) async {\n  final db = context.read\u003CTaskDatabase>();\n\n  return switch (context.request.method) {\n    HttpMethod.get => _getTask(db, id),\n    HttpMethod.put => _updateTask(context, db, id),\n    HttpMethod.delete => _deleteTask(db, id),\n    _ => Response(statusCode: HttpStatus.methodNotAllowed),\n  };\n}\n\nFuture\u003CResponse> _getTask(TaskDatabase db, String id) async {\n  final task = await db.findById(id);\n  if (task == null) return Response(statusCode: 404, body: 'Not found');\n  return Response.json(body: task.toJson());\n}\n\nFuture\u003CResponse> _updateTask(RequestContext context, TaskDatabase db, String id) async {\n  final task = await db.findById(id);\n  if (task == null) return Response(statusCode: 404);\n\n  final body = await context.request.json() as Map\u003CString, dynamic>;\n  final updated = task.copyWith(\n    title: body['title'] as String? ?? task.title,\n    completed: body['completed'] as bool? ?? task.completed,\n    completedAt: body['completed'] == true ? DateTime.now() : null,\n  );\n  await db.update(updated);\n  return Response.json(body: updated.toJson());\n}\n\nFuture\u003CResponse> _deleteTask(TaskDatabase db, String id) async {\n  final deleted = await db.delete(id);\n  if (!deleted) return Response(statusCode: 404);\n  return Response(statusCode: 204);\n}\n",[23,5217,5218,5223,5231,5239,5247,5251,5278,5296,5300,5308,5324,5339,5353,5369,5373,5377,5381,5409,5427,5460,5480,5484,5488,5519,5535,5559,5563,5593,5609,5632,5658,5693,5697,5709,5730,5734,5738,5765,5783,5806,5821],{"__ignoreMap":36},[40,5219,5220],{"class":42,"line":43},[40,5221,5222],{"class":78},"\u002F\u002F server\u002Froutes\u002Ftasks\u002F[id].dart\n",[40,5224,5225,5227,5229],{"class":42,"line":58},[40,5226,47],{"class":46},[40,5228,4760],{"class":50},[40,5230,55],{"class":54},[40,5232,5233,5235,5237],{"class":42,"line":68},[40,5234,47],{"class":46},[40,5236,4769],{"class":50},[40,5238,55],{"class":54},[40,5240,5241,5243,5245],{"class":42,"line":75},[40,5242,47],{"class":46},[40,5244,4778],{"class":50},[40,5246,55],{"class":54},[40,5248,5249],{"class":42,"line":82},[40,5250,72],{"emptyLinePlaceholder":71},[40,5252,5253,5255,5257,5259,5261,5263,5265,5267,5269,5271,5274,5276],{"class":42,"line":95},[40,5254,2512],{"class":88},[40,5256,736],{"class":54},[40,5258,4793],{"class":88},[40,5260,2011],{"class":54},[40,5262,4798],{"class":120},[40,5264,124],{"class":54},[40,5266,4803],{"class":88},[40,5268,4947],{"class":54},[40,5270,459],{"class":88},[40,5272,5273],{"class":54}," id) ",[40,5275,2540],{"class":46},[40,5277,114],{"class":54},[40,5279,5280,5282,5284,5286,5288,5290,5292,5294],{"class":42,"line":100},[40,5281,184],{"class":46},[40,5283,4817],{"class":54},[40,5285,761],{"class":46},[40,5287,4822],{"class":54},[40,5289,4825],{"class":120},[40,5291,736],{"class":54},[40,5293,4830],{"class":88},[40,5295,3268],{"class":54},[40,5297,5298],{"class":42,"line":106},[40,5299,72],{"emptyLinePlaceholder":71},[40,5301,5302,5304,5306],{"class":42,"line":117},[40,5303,652],{"class":46},[40,5305,255],{"class":46},[40,5307,4845],{"class":54},[40,5309,5310,5312,5314,5316,5318,5321],{"class":42,"line":139},[40,5311,4850],{"class":88},[40,5313,1053],{"class":54},[40,5315,4855],{"class":46},[40,5317,490],{"class":46},[40,5319,5320],{"class":120}," _getTask",[40,5322,5323],{"class":54},"(db, id),\n",[40,5325,5326,5328,5331,5333,5336],{"class":42,"line":157},[40,5327,4850],{"class":88},[40,5329,5330],{"class":54},".put ",[40,5332,252],{"class":46},[40,5334,5335],{"class":120}," _updateTask",[40,5337,5338],{"class":54},"(context, db, id),\n",[40,5340,5341,5343,5346,5348,5351],{"class":42,"line":176},[40,5342,4850],{"class":88},[40,5344,5345],{"class":54},".delete ",[40,5347,252],{"class":46},[40,5349,5350],{"class":120}," _deleteTask",[40,5352,5323],{"class":54},[40,5354,5355,5357,5359,5361,5363,5365,5367],{"class":42,"line":181},[40,5356,537],{"class":54},[40,5358,252],{"class":46},[40,5360,4860],{"class":88},[40,5362,4907],{"class":54},[40,5364,903],{"class":46},[40,5366,4912],{"class":88},[40,5368,4915],{"class":54},[40,5370,5371],{"class":42,"line":193},[40,5372,340],{"class":54},[40,5374,5375],{"class":42,"line":203},[40,5376,623],{"class":54},[40,5378,5379],{"class":42,"line":224},[40,5380,72],{"emptyLinePlaceholder":71},[40,5382,5383,5385,5387,5389,5391,5394,5396,5398,5401,5403,5405,5407],{"class":42,"line":229},[40,5384,2512],{"class":88},[40,5386,736],{"class":54},[40,5388,4793],{"class":88},[40,5390,2011],{"class":54},[40,5392,5393],{"class":120},"_getTask",[40,5395,124],{"class":54},[40,5397,4830],{"class":88},[40,5399,5400],{"class":54}," db, ",[40,5402,459],{"class":88},[40,5404,5273],{"class":54},[40,5406,2540],{"class":46},[40,5408,114],{"class":54},[40,5410,5411,5413,5415,5417,5419,5421,5424],{"class":42,"line":235},[40,5412,184],{"class":46},[40,5414,3275],{"class":54},[40,5416,761],{"class":46},[40,5418,2735],{"class":46},[40,5420,4875],{"class":54},[40,5422,5423],{"class":120},"findById",[40,5425,5426],{"class":54},"(id);\n",[40,5428,5429,5431,5433,5435,5437,5439,5442,5444,5446,5448,5451,5453,5455,5458],{"class":42,"line":266},[40,5430,1176],{"class":46},[40,5432,3942],{"class":54},[40,5434,815],{"class":46},[40,5436,818],{"class":88},[40,5438,299],{"class":54},[40,5440,5441],{"class":46},"return",[40,5443,4860],{"class":88},[40,5445,4907],{"class":54},[40,5447,903],{"class":46},[40,5449,5450],{"class":88}," 404",[40,5452,5046],{"class":54},[40,5454,903],{"class":46},[40,5456,5457],{"class":50}," 'Not found'",[40,5459,173],{"class":54},[40,5461,5462,5464,5466,5468,5470,5472,5474,5476,5478],{"class":42,"line":280},[40,5463,652],{"class":46},[40,5465,4860],{"class":88},[40,5467,1053],{"class":54},[40,5469,4865],{"class":120},[40,5471,4868],{"class":54},[40,5473,903],{"class":46},[40,5475,5173],{"class":54},[40,5477,5176],{"class":120},[40,5479,2068],{"class":54},[40,5481,5482],{"class":42,"line":317},[40,5483,623],{"class":54},[40,5485,5486],{"class":42,"line":337},[40,5487,72],{"emptyLinePlaceholder":71},[40,5489,5490,5492,5494,5496,5498,5501,5503,5505,5507,5509,5511,5513,5515,5517],{"class":42,"line":343},[40,5491,2512],{"class":88},[40,5493,736],{"class":54},[40,5495,4793],{"class":88},[40,5497,2011],{"class":54},[40,5499,5500],{"class":120},"_updateTask",[40,5502,124],{"class":54},[40,5504,4803],{"class":88},[40,5506,4947],{"class":54},[40,5508,4830],{"class":88},[40,5510,5400],{"class":54},[40,5512,459],{"class":88},[40,5514,5273],{"class":54},[40,5516,2540],{"class":46},[40,5518,114],{"class":54},[40,5520,5521,5523,5525,5527,5529,5531,5533],{"class":42,"line":348},[40,5522,184],{"class":46},[40,5524,3275],{"class":54},[40,5526,761],{"class":46},[40,5528,2735],{"class":46},[40,5530,4875],{"class":54},[40,5532,5423],{"class":120},[40,5534,5426],{"class":54},[40,5536,5537,5539,5541,5543,5545,5547,5549,5551,5553,5555,5557],{"class":42,"line":354},[40,5538,1176],{"class":46},[40,5540,3942],{"class":54},[40,5542,815],{"class":46},[40,5544,818],{"class":88},[40,5546,299],{"class":54},[40,5548,5441],{"class":46},[40,5550,4860],{"class":88},[40,5552,4907],{"class":54},[40,5554,903],{"class":46},[40,5556,5450],{"class":88},[40,5558,173],{"class":54},[40,5560,5561],{"class":42,"line":379},[40,5562,72],{"emptyLinePlaceholder":71},[40,5564,5565,5567,5569,5571,5573,5575,5577,5579,5581,5583,5585,5587,5589,5591],{"class":42,"line":391},[40,5566,184],{"class":46},[40,5568,4963],{"class":54},[40,5570,761],{"class":46},[40,5572,2735],{"class":46},[40,5574,4970],{"class":54},[40,5576,4865],{"class":120},[40,5578,1747],{"class":54},[40,5580,1946],{"class":46},[40,5582,2158],{"class":88},[40,5584,736],{"class":54},[40,5586,459],{"class":88},[40,5588,130],{"class":54},[40,5590,1916],{"class":88},[40,5592,4989],{"class":54},[40,5594,5595,5597,5600,5602,5604,5607],{"class":42,"line":418},[40,5596,184],{"class":46},[40,5598,5599],{"class":54}," updated ",[40,5601,761],{"class":46},[40,5603,5173],{"class":54},[40,5605,5606],{"class":120},"copyWith",[40,5608,878],{"class":54},[40,5610,5611,5613,5615,5617,5619,5621,5623,5625,5627,5629],{"class":42,"line":436},[40,5612,5086],{"class":54},[40,5614,903],{"class":46},[40,5616,5001],{"class":54},[40,5618,5004],{"class":50},[40,5620,1943],{"class":54},[40,5622,1946],{"class":46},[40,5624,187],{"class":88},[40,5626,2368],{"class":46},[40,5628,5113],{"class":46},[40,5630,5631],{"class":54}," task.title,\n",[40,5633,5634,5637,5639,5641,5644,5646,5648,5651,5653,5655],{"class":42,"line":441},[40,5635,5636],{"class":54},"    completed",[40,5638,903],{"class":46},[40,5640,5001],{"class":54},[40,5642,5643],{"class":50},"'completed'",[40,5645,1943],{"class":54},[40,5647,1946],{"class":46},[40,5649,5650],{"class":88}," bool",[40,5652,2368],{"class":46},[40,5654,5113],{"class":46},[40,5656,5657],{"class":54}," task.completed,\n",[40,5659,5660,5663,5665,5667,5669,5671,5673,5676,5679,5681,5683,5685,5687,5689,5691],{"class":42,"line":446},[40,5661,5662],{"class":54},"    completedAt",[40,5664,903],{"class":46},[40,5666,5001],{"class":54},[40,5668,5643],{"class":50},[40,5670,1943],{"class":54},[40,5672,815],{"class":46},[40,5674,5675],{"class":88}," true",[40,5677,5678],{"class":46}," ?",[40,5680,1843],{"class":88},[40,5682,1053],{"class":54},[40,5684,5132],{"class":120},[40,5686,1747],{"class":54},[40,5688,903],{"class":46},[40,5690,818],{"class":88},[40,5692,314],{"class":54},[40,5694,5695],{"class":42,"line":478},[40,5696,1986],{"class":54},[40,5698,5699,5701,5703,5706],{"class":42,"line":498},[40,5700,2380],{"class":46},[40,5702,4875],{"class":54},[40,5704,5705],{"class":120},"update",[40,5707,5708],{"class":54},"(updated);\n",[40,5710,5711,5713,5715,5717,5719,5721,5723,5726,5728],{"class":42,"line":516},[40,5712,652],{"class":46},[40,5714,4860],{"class":88},[40,5716,1053],{"class":54},[40,5718,4865],{"class":120},[40,5720,4868],{"class":54},[40,5722,903],{"class":46},[40,5724,5725],{"class":54}," updated.",[40,5727,5176],{"class":120},[40,5729,2068],{"class":54},[40,5731,5732],{"class":42,"line":534},[40,5733,623],{"class":54},[40,5735,5736],{"class":42,"line":569},[40,5737,72],{"emptyLinePlaceholder":71},[40,5739,5740,5742,5744,5746,5748,5751,5753,5755,5757,5759,5761,5763],{"class":42,"line":574},[40,5741,2512],{"class":88},[40,5743,736],{"class":54},[40,5745,4793],{"class":88},[40,5747,2011],{"class":54},[40,5749,5750],{"class":120},"_deleteTask",[40,5752,124],{"class":54},[40,5754,4830],{"class":88},[40,5756,5400],{"class":54},[40,5758,459],{"class":88},[40,5760,5273],{"class":54},[40,5762,2540],{"class":46},[40,5764,114],{"class":54},[40,5766,5767,5769,5772,5774,5776,5778,5781],{"class":42,"line":579},[40,5768,184],{"class":46},[40,5770,5771],{"class":54}," deleted ",[40,5773,761],{"class":46},[40,5775,2735],{"class":46},[40,5777,4875],{"class":54},[40,5779,5780],{"class":120},"delete",[40,5782,5426],{"class":54},[40,5784,5785,5787,5789,5791,5794,5796,5798,5800,5802,5804],{"class":42,"line":603},[40,5786,1176],{"class":46},[40,5788,258],{"class":54},[40,5790,3794],{"class":46},[40,5792,5793],{"class":54},"deleted) ",[40,5795,5441],{"class":46},[40,5797,4860],{"class":88},[40,5799,4907],{"class":54},[40,5801,903],{"class":46},[40,5803,5450],{"class":88},[40,5805,173],{"class":54},[40,5807,5808,5810,5812,5814,5816,5819],{"class":42,"line":620},[40,5809,652],{"class":46},[40,5811,4860],{"class":88},[40,5813,4907],{"class":54},[40,5815,903],{"class":46},[40,5817,5818],{"class":88}," 204",[40,5820,173],{"class":54},[40,5822,5823],{"class":42,"line":626},[40,5824,623],{"class":54},[4514,5826,5828],{"id":5827},"client-flutter-app-with-riverpod","Client — Flutter App with Riverpod",[28,5830,5831,6449],{"language":30},[32,5832,5834],{"className":34,"code":5833,"language":30,"meta":36,"style":36},"\u002F\u002F client\u002Flib\u002Fapi\u002Fapi_client.dart\nimport 'package:http\u002Fhttp.dart' as http;\nimport 'package:models\u002Fmodels.dart';\nimport 'dart:convert';\n\nclass ApiClient {\n  final String baseUrl;\n  final http.Client _client;\n\n  ApiClient({required this.baseUrl, http.Client? client})\n      : _client = client ?? http.Client();\n\n  Future\u003CList\u003CTask>> getTasks() async {\n    final response = await _client.get(Uri.parse('$baseUrl\u002Ftasks'));\n    if (response.statusCode != 200) throw ApiException(response.statusCode);\n    final list = jsonDecode(response.body) as List;\n    return list.map((e) => Task.fromJson(e as Map\u003CString, dynamic>)).toList();\n  }\n\n  Future\u003CTask> createTask(String title, String description) async {\n    final response = await _client.post(\n      Uri.parse('$baseUrl\u002Ftasks'),\n      headers: {'Content-Type': 'application\u002Fjson'},\n      body: jsonEncode({'title': title, 'description': description}),\n    );\n    if (response.statusCode != 201) throw ApiException(response.statusCode);\n    return Task.fromJson(jsonDecode(response.body) as Map\u003CString, dynamic>);\n  }\n\n  Future\u003Cvoid> deleteTask(String id) async {\n    final response = await _client.delete(Uri.parse('$baseUrl\u002Ftasks\u002F$id'));\n    if (response.statusCode != 204) throw ApiException(response.statusCode);\n  }\n}\n\nclass ApiException implements Exception {\n  final int statusCode;\n  ApiException(this.statusCode);\n  @override\n  String toString() => 'ApiException: $statusCode';\n}\n",[23,5835,5836,5841,5854,5862,5870,5874,5883,5892,5905,5909,5933,5955,5959,5983,6023,6046,6067,6110,6114,6118,6147,6164,6185,6206,6231,6235,6253,6283,6287,6291,6314,6356,6374,6378,6382,6386,6398,6407,6419,6423,6445],{"__ignoreMap":36},[40,5837,5838],{"class":42,"line":43},[40,5839,5840],{"class":78},"\u002F\u002F client\u002Flib\u002Fapi\u002Fapi_client.dart\n",[40,5842,5843,5845,5848,5851],{"class":42,"line":58},[40,5844,47],{"class":46},[40,5846,5847],{"class":50}," 'package:http\u002Fhttp.dart'",[40,5849,5850],{"class":46}," as",[40,5852,5853],{"class":54}," http;\n",[40,5855,5856,5858,5860],{"class":42,"line":68},[40,5857,47],{"class":46},[40,5859,4769],{"class":50},[40,5861,55],{"class":54},[40,5863,5864,5866,5868],{"class":42,"line":75},[40,5865,47],{"class":46},[40,5867,1794],{"class":50},[40,5869,55],{"class":54},[40,5871,5872],{"class":42,"line":82},[40,5873,72],{"emptyLinePlaceholder":71},[40,5875,5876,5878,5881],{"class":42,"line":95},[40,5877,1681],{"class":46},[40,5879,5880],{"class":88}," ApiClient",[40,5882,114],{"class":54},[40,5884,5885,5887,5889],{"class":42,"line":100},[40,5886,184],{"class":46},[40,5888,187],{"class":88},[40,5890,5891],{"class":54}," baseUrl;\n",[40,5893,5894,5896,5899,5902],{"class":42,"line":106},[40,5895,184],{"class":46},[40,5897,5898],{"class":54}," http.",[40,5900,5901],{"class":88},"Client",[40,5903,5904],{"class":54}," _client;\n",[40,5906,5907],{"class":42,"line":117},[40,5908,72],{"emptyLinePlaceholder":71},[40,5910,5911,5914,5917,5920,5923,5926,5928,5930],{"class":42,"line":139},[40,5912,5913],{"class":88},"  ApiClient",[40,5915,5916],{"class":54},"({",[40,5918,5919],{"class":46},"required",[40,5921,5922],{"class":88}," this",[40,5924,5925],{"class":54},".baseUrl, http.",[40,5927,5901],{"class":88},[40,5929,2368],{"class":46},[40,5931,5932],{"class":54}," client})\n",[40,5934,5935,5938,5941,5943,5946,5949,5951,5953],{"class":42,"line":157},[40,5936,5937],{"class":46},"      :",[40,5939,5940],{"class":54}," _client ",[40,5942,761],{"class":46},[40,5944,5945],{"class":54}," client ",[40,5947,5948],{"class":46},"??",[40,5950,5898],{"class":54},[40,5952,5901],{"class":88},[40,5954,766],{"class":54},[40,5956,5957],{"class":42,"line":176},[40,5958,72],{"emptyLinePlaceholder":71},[40,5960,5961,5963,5965,5967,5969,5972,5974,5977,5979,5981],{"class":42,"line":181},[40,5962,3106],{"class":88},[40,5964,736],{"class":54},[40,5966,733],{"class":88},[40,5968,736],{"class":54},[40,5970,5971],{"class":88},"Task",[40,5973,2527],{"class":54},[40,5975,5976],{"class":120},"getTasks",[40,5978,1747],{"class":54},[40,5980,2540],{"class":46},[40,5982,114],{"class":54},[40,5984,5985,5987,5990,5992,5994,5997,5999,6001,6004,6006,6008,6010,6012,6014,6017,6020],{"class":42,"line":193},[40,5986,755],{"class":46},[40,5988,5989],{"class":54}," response ",[40,5991,761],{"class":46},[40,5993,2735],{"class":46},[40,5995,5996],{"class":54}," _client.",[40,5998,4855],{"class":120},[40,6000,124],{"class":54},[40,6002,6003],{"class":88},"Uri",[40,6005,1053],{"class":54},[40,6007,782],{"class":120},[40,6009,124],{"class":54},[40,6011,559],{"class":50},[40,6013,553],{"class":50},[40,6015,6016],{"class":88},"baseUrl",[40,6018,6019],{"class":50},"\u002Ftasks'",[40,6021,6022],{"class":54},"));\n",[40,6024,6025,6027,6030,6032,6035,6037,6040,6043],{"class":42,"line":203},[40,6026,809],{"class":46},[40,6028,6029],{"class":54}," (response.statusCode ",[40,6031,1182],{"class":46},[40,6033,6034],{"class":88}," 200",[40,6036,299],{"class":54},[40,6038,6039],{"class":46},"throw",[40,6041,6042],{"class":88}," ApiException",[40,6044,6045],{"class":54},"(response.statusCode);\n",[40,6047,6048,6050,6053,6055,6058,6061,6063,6065],{"class":42,"line":224},[40,6049,755],{"class":46},[40,6051,6052],{"class":54}," list ",[40,6054,761],{"class":46},[40,6056,6057],{"class":120}," jsonDecode",[40,6059,6060],{"class":54},"(response.body) ",[40,6062,1946],{"class":46},[40,6064,2991],{"class":88},[40,6066,55],{"class":54},[40,6068,6069,6071,6074,6077,6079,6081,6083,6085,6087,6090,6092,6094,6096,6098,6100,6102,6105,6108],{"class":42,"line":229},[40,6070,3333],{"class":46},[40,6072,6073],{"class":54}," list.",[40,6075,6076],{"class":120},"map",[40,6078,2256],{"class":54},[40,6080,252],{"class":46},[40,6082,4573],{"class":88},[40,6084,1053],{"class":54},[40,6086,1902],{"class":120},[40,6088,6089],{"class":54},"(e ",[40,6091,1946],{"class":46},[40,6093,2158],{"class":88},[40,6095,736],{"class":54},[40,6097,459],{"class":88},[40,6099,130],{"class":54},[40,6101,1916],{"class":88},[40,6103,6104],{"class":54},">)).",[40,6106,6107],{"class":120},"toList",[40,6109,766],{"class":54},[40,6111,6112],{"class":42,"line":235},[40,6113,1144],{"class":54},[40,6115,6116],{"class":42,"line":266},[40,6117,72],{"emptyLinePlaceholder":71},[40,6119,6120,6122,6124,6126,6128,6131,6133,6135,6138,6140,6143,6145],{"class":42,"line":280},[40,6121,3106],{"class":88},[40,6123,736],{"class":54},[40,6125,5971],{"class":88},[40,6127,2011],{"class":54},[40,6129,6130],{"class":120},"createTask",[40,6132,124],{"class":54},[40,6134,459],{"class":88},[40,6136,6137],{"class":54}," title, ",[40,6139,459],{"class":88},[40,6141,6142],{"class":54}," description) ",[40,6144,2540],{"class":46},[40,6146,114],{"class":54},[40,6148,6149,6151,6153,6155,6157,6159,6162],{"class":42,"line":317},[40,6150,755],{"class":46},[40,6152,5989],{"class":54},[40,6154,761],{"class":46},[40,6156,2735],{"class":46},[40,6158,5996],{"class":54},[40,6160,6161],{"class":120},"post",[40,6163,878],{"class":54},[40,6165,6166,6169,6171,6173,6175,6177,6179,6181,6183],{"class":42,"line":337},[40,6167,6168],{"class":88},"      Uri",[40,6170,1053],{"class":54},[40,6172,782],{"class":120},[40,6174,124],{"class":54},[40,6176,559],{"class":50},[40,6178,553],{"class":50},[40,6180,6016],{"class":88},[40,6182,6019],{"class":50},[40,6184,136],{"class":54},[40,6186,6187,6190,6192,6195,6198,6200,6203],{"class":42,"line":343},[40,6188,6189],{"class":54},"      headers",[40,6191,903],{"class":46},[40,6193,6194],{"class":54}," {",[40,6196,6197],{"class":50},"'Content-Type'",[40,6199,903],{"class":46},[40,6201,6202],{"class":50}," 'application\u002Fjson'",[40,6204,6205],{"class":54},"},\n",[40,6207,6208,6211,6213,6216,6218,6220,6222,6224,6226,6228],{"class":42,"line":348},[40,6209,6210],{"class":54},"      body",[40,6212,903],{"class":46},[40,6214,6215],{"class":120}," jsonEncode",[40,6217,5916],{"class":54},[40,6219,5004],{"class":50},[40,6221,903],{"class":46},[40,6223,6137],{"class":54},[40,6225,5102],{"class":50},[40,6227,903],{"class":46},[40,6229,6230],{"class":54}," description}),\n",[40,6232,6233],{"class":42,"line":354},[40,6234,930],{"class":54},[40,6236,6237,6239,6241,6243,6245,6247,6249,6251],{"class":42,"line":379},[40,6238,809],{"class":46},[40,6240,6029],{"class":54},[40,6242,1182],{"class":46},[40,6244,5166],{"class":88},[40,6246,299],{"class":54},[40,6248,6039],{"class":46},[40,6250,6042],{"class":88},[40,6252,6045],{"class":54},[40,6254,6255,6257,6259,6261,6263,6265,6267,6269,6271,6273,6275,6277,6279,6281],{"class":42,"line":391},[40,6256,3333],{"class":46},[40,6258,4573],{"class":88},[40,6260,1053],{"class":54},[40,6262,1902],{"class":120},[40,6264,124],{"class":54},[40,6266,2150],{"class":120},[40,6268,6060],{"class":54},[40,6270,1946],{"class":46},[40,6272,2158],{"class":88},[40,6274,736],{"class":54},[40,6276,459],{"class":88},[40,6278,130],{"class":54},[40,6280,1916],{"class":88},[40,6282,2169],{"class":54},[40,6284,6285],{"class":42,"line":418},[40,6286,1144],{"class":54},[40,6288,6289],{"class":42,"line":436},[40,6290,72],{"emptyLinePlaceholder":71},[40,6292,6293,6295,6297,6299,6301,6304,6306,6308,6310,6312],{"class":42,"line":441},[40,6294,3106],{"class":88},[40,6296,736],{"class":54},[40,6298,725],{"class":46},[40,6300,2011],{"class":54},[40,6302,6303],{"class":120},"deleteTask",[40,6305,124],{"class":54},[40,6307,459],{"class":88},[40,6309,5273],{"class":54},[40,6311,2540],{"class":46},[40,6313,114],{"class":54},[40,6315,6316,6318,6320,6322,6324,6326,6328,6330,6332,6334,6336,6338,6340,6342,6344,6347,6349,6352,6354],{"class":42,"line":446},[40,6317,755],{"class":46},[40,6319,5989],{"class":54},[40,6321,761],{"class":46},[40,6323,2735],{"class":46},[40,6325,5996],{"class":54},[40,6327,5780],{"class":120},[40,6329,124],{"class":54},[40,6331,6003],{"class":88},[40,6333,1053],{"class":54},[40,6335,782],{"class":120},[40,6337,124],{"class":54},[40,6339,559],{"class":50},[40,6341,553],{"class":50},[40,6343,6016],{"class":88},[40,6345,6346],{"class":50},"\u002Ftasks\u002F",[40,6348,553],{"class":50},[40,6350,6351],{"class":88},"id",[40,6353,559],{"class":50},[40,6355,6022],{"class":54},[40,6357,6358,6360,6362,6364,6366,6368,6370,6372],{"class":42,"line":478},[40,6359,809],{"class":46},[40,6361,6029],{"class":54},[40,6363,1182],{"class":46},[40,6365,5818],{"class":88},[40,6367,299],{"class":54},[40,6369,6039],{"class":46},[40,6371,6042],{"class":88},[40,6373,6045],{"class":54},[40,6375,6376],{"class":42,"line":498},[40,6377,1144],{"class":54},[40,6379,6380],{"class":42,"line":516},[40,6381,623],{"class":54},[40,6383,6384],{"class":42,"line":534},[40,6385,72],{"emptyLinePlaceholder":71},[40,6387,6388,6390,6392,6394,6396],{"class":42,"line":569},[40,6389,1681],{"class":46},[40,6391,6042],{"class":88},[40,6393,1686],{"class":46},[40,6395,1689],{"class":88},[40,6397,114],{"class":54},[40,6399,6400,6402,6404],{"class":42,"line":574},[40,6401,184],{"class":46},[40,6403,2870],{"class":88},[40,6405,6406],{"class":54}," statusCode;\n",[40,6408,6409,6412,6414,6416],{"class":42,"line":579},[40,6410,6411],{"class":88},"  ApiException",[40,6413,124],{"class":54},[40,6415,213],{"class":88},[40,6417,6418],{"class":54},".statusCode);\n",[40,6420,6421],{"class":42,"line":603},[40,6422,1735],{"class":46},[40,6424,6425,6427,6429,6431,6433,6436,6438,6441,6443],{"class":42,"line":620},[40,6426,1741],{"class":88},[40,6428,1744],{"class":120},[40,6430,1747],{"class":54},[40,6432,252],{"class":46},[40,6434,6435],{"class":50}," 'ApiException: ",[40,6437,553],{"class":50},[40,6439,6440],{"class":88},"statusCode",[40,6442,559],{"class":50},[40,6444,55],{"class":54},[40,6446,6447],{"class":42,"line":626},[40,6448,623],{"class":54},[28,6450,6451],{"language":30},[32,6452,6454],{"className":34,"code":6453,"language":30,"meta":36,"style":36},"\u002F\u002F client\u002Flib\u002Fstate\u002Ftask_provider.dart\nimport 'package:flutter_riverpod\u002Fflutter_riverpod.dart';\nimport '..\u002Fapi\u002Fapi_client.dart';\nimport 'package:models\u002Fmodels.dart';\n\nfinal apiClientProvider = Provider\u003CApiClient>((ref) {\n  return ApiClient(baseUrl: 'http:\u002F\u002Flocalhost:8080');\n});\n\nfinal taskListProvider = FutureProvider\u003CList\u003CTask>>((ref) async {\n  return ref.read(apiClientProvider).getTasks();\n});\n\nfinal taskActionsProvider = Provider\u003CTaskActions>((ref) {\n  return TaskActions(ref.read(apiClientProvider), ref);\n});\n\nclass TaskActions {\n  final ApiClient api;\n  final Ref ref;\n  TaskActions(this.api, this.ref);\n\n  Future\u003Cvoid> create(String title, String description) async {\n    await api.createTask(title, description);\n    ref.invalidate(taskListProvider);  \u002F\u002F refresh the list\n  }\n\n  Future\u003Cvoid> delete(String id) async {\n    await api.deleteTask(id);\n    ref.invalidate(taskListProvider);\n  }\n}\n",[23,6455,6456,6461,6470,6479,6487,6491,6511,6527,6532,6536,6563,6579,6583,6587,6605,6620,6624,6628,6636,6645,6655,6672,6676,6703,6716,6730,6734,6738,6760,6770,6779,6783],{"__ignoreMap":36},[40,6457,6458],{"class":42,"line":43},[40,6459,6460],{"class":78},"\u002F\u002F client\u002Flib\u002Fstate\u002Ftask_provider.dart\n",[40,6462,6463,6465,6468],{"class":42,"line":58},[40,6464,47],{"class":46},[40,6466,6467],{"class":50}," 'package:flutter_riverpod\u002Fflutter_riverpod.dart'",[40,6469,55],{"class":54},[40,6471,6472,6474,6477],{"class":42,"line":68},[40,6473,47],{"class":46},[40,6475,6476],{"class":50}," '..\u002Fapi\u002Fapi_client.dart'",[40,6478,55],{"class":54},[40,6480,6481,6483,6485],{"class":42,"line":75},[40,6482,47],{"class":46},[40,6484,4769],{"class":50},[40,6486,55],{"class":54},[40,6488,6489],{"class":42,"line":82},[40,6490,72],{"emptyLinePlaceholder":71},[40,6492,6493,6495,6498,6500,6503,6505,6508],{"class":42,"line":95},[40,6494,1503],{"class":46},[40,6496,6497],{"class":54}," apiClientProvider ",[40,6499,761],{"class":46},[40,6501,6502],{"class":88}," Provider",[40,6504,736],{"class":54},[40,6506,6507],{"class":88},"ApiClient",[40,6509,6510],{"class":54},">((ref) {\n",[40,6512,6513,6515,6517,6520,6522,6525],{"class":42,"line":100},[40,6514,652],{"class":46},[40,6516,5880],{"class":88},[40,6518,6519],{"class":54},"(baseUrl",[40,6521,903],{"class":46},[40,6523,6524],{"class":50}," 'http:\u002F\u002Flocalhost:8080'",[40,6526,173],{"class":54},[40,6528,6529],{"class":42,"line":106},[40,6530,6531],{"class":54},"});\n",[40,6533,6534],{"class":42,"line":117},[40,6535,72],{"emptyLinePlaceholder":71},[40,6537,6538,6540,6543,6545,6548,6550,6552,6554,6556,6559,6561],{"class":42,"line":139},[40,6539,1503],{"class":46},[40,6541,6542],{"class":54}," taskListProvider ",[40,6544,761],{"class":46},[40,6546,6547],{"class":88}," FutureProvider",[40,6549,736],{"class":54},[40,6551,733],{"class":88},[40,6553,736],{"class":54},[40,6555,5971],{"class":88},[40,6557,6558],{"class":54},">>((ref) ",[40,6560,2540],{"class":46},[40,6562,114],{"class":54},[40,6564,6565,6567,6570,6572,6575,6577],{"class":42,"line":157},[40,6566,652],{"class":46},[40,6568,6569],{"class":54}," ref.",[40,6571,4825],{"class":120},[40,6573,6574],{"class":54},"(apiClientProvider).",[40,6576,5976],{"class":120},[40,6578,766],{"class":54},[40,6580,6581],{"class":42,"line":176},[40,6582,6531],{"class":54},[40,6584,6585],{"class":42,"line":181},[40,6586,72],{"emptyLinePlaceholder":71},[40,6588,6589,6591,6594,6596,6598,6600,6603],{"class":42,"line":193},[40,6590,1503],{"class":46},[40,6592,6593],{"class":54}," taskActionsProvider ",[40,6595,761],{"class":46},[40,6597,6502],{"class":88},[40,6599,736],{"class":54},[40,6601,6602],{"class":88},"TaskActions",[40,6604,6510],{"class":54},[40,6606,6607,6609,6612,6615,6617],{"class":42,"line":203},[40,6608,652],{"class":46},[40,6610,6611],{"class":88}," TaskActions",[40,6613,6614],{"class":54},"(ref.",[40,6616,4825],{"class":120},[40,6618,6619],{"class":54},"(apiClientProvider), ref);\n",[40,6621,6622],{"class":42,"line":224},[40,6623,6531],{"class":54},[40,6625,6626],{"class":42,"line":229},[40,6627,72],{"emptyLinePlaceholder":71},[40,6629,6630,6632,6634],{"class":42,"line":235},[40,6631,1681],{"class":46},[40,6633,6611],{"class":88},[40,6635,114],{"class":54},[40,6637,6638,6640,6642],{"class":42,"line":266},[40,6639,184],{"class":46},[40,6641,5880],{"class":88},[40,6643,6644],{"class":54}," api;\n",[40,6646,6647,6649,6652],{"class":42,"line":280},[40,6648,184],{"class":46},[40,6650,6651],{"class":88}," Ref",[40,6653,6654],{"class":54}," ref;\n",[40,6656,6657,6660,6662,6664,6667,6669],{"class":42,"line":317},[40,6658,6659],{"class":88},"  TaskActions",[40,6661,124],{"class":54},[40,6663,213],{"class":88},[40,6665,6666],{"class":54},".api, ",[40,6668,213],{"class":88},[40,6670,6671],{"class":54},".ref);\n",[40,6673,6674],{"class":42,"line":337},[40,6675,72],{"emptyLinePlaceholder":71},[40,6677,6678,6680,6682,6684,6686,6689,6691,6693,6695,6697,6699,6701],{"class":42,"line":343},[40,6679,3106],{"class":88},[40,6681,736],{"class":54},[40,6683,725],{"class":46},[40,6685,2011],{"class":54},[40,6687,6688],{"class":120},"create",[40,6690,124],{"class":54},[40,6692,459],{"class":88},[40,6694,6137],{"class":54},[40,6696,459],{"class":88},[40,6698,6142],{"class":54},[40,6700,2540],{"class":46},[40,6702,114],{"class":54},[40,6704,6705,6708,6711,6713],{"class":42,"line":348},[40,6706,6707],{"class":46},"    await",[40,6709,6710],{"class":54}," api.",[40,6712,6130],{"class":120},[40,6714,6715],{"class":54},"(title, description);\n",[40,6717,6718,6721,6724,6727],{"class":42,"line":354},[40,6719,6720],{"class":54},"    ref.",[40,6722,6723],{"class":120},"invalidate",[40,6725,6726],{"class":54},"(taskListProvider);  ",[40,6728,6729],{"class":78},"\u002F\u002F refresh the list\n",[40,6731,6732],{"class":42,"line":379},[40,6733,1144],{"class":54},[40,6735,6736],{"class":42,"line":391},[40,6737,72],{"emptyLinePlaceholder":71},[40,6739,6740,6742,6744,6746,6748,6750,6752,6754,6756,6758],{"class":42,"line":418},[40,6741,3106],{"class":88},[40,6743,736],{"class":54},[40,6745,725],{"class":46},[40,6747,2011],{"class":54},[40,6749,5780],{"class":120},[40,6751,124],{"class":54},[40,6753,459],{"class":88},[40,6755,5273],{"class":54},[40,6757,2540],{"class":46},[40,6759,114],{"class":54},[40,6761,6762,6764,6766,6768],{"class":42,"line":436},[40,6763,6707],{"class":46},[40,6765,6710],{"class":54},[40,6767,6303],{"class":120},[40,6769,5426],{"class":54},[40,6771,6772,6774,6776],{"class":42,"line":441},[40,6773,6720],{"class":54},[40,6775,6723],{"class":120},[40,6777,6778],{"class":54},"(taskListProvider);\n",[40,6780,6781],{"class":42,"line":446},[40,6782,1144],{"class":54},[40,6784,6785],{"class":42,"line":478},[40,6786,623],{"class":54},[14,6788,6790],{"id":6789},"production-checklist","Production Checklist",[28,6792,6794],{"language":6793},"markdown",[32,6795,6798],{"className":6796,"code":6797,"language":6793,"meta":36,"style":36},"language-markdown shiki shiki-themes github-light github-dark","## Null Safety & Types\n- [ ] Sound null safety (no `!` abuse, proper `?`\u002F`??`\u002F`?.`)\n- [ ] `Object?` over `dynamic` for \"any value\" (preserve type checking)\n- [ ] `late final x = initializer` for lazy fields (not bare `late`)\n\n## Control Flow & Patterns\n- [ ] Exhaustive switches (no `default`\u002F`_` for enums\u002Fsealed types)\n- [ ] Pattern matching with destructuring (no manual casts)\n- [ ] `assert` only for debug invariants (stripped in AOT)\n\n## Error Handling\n- [ ] Specific `on Type catch` (not broad `catch (e)`)\n- [ ] `rethrow` (not `throw e`) to preserve stack traces\n- [ ] `Exception` subtypes for recoverable, `Error` subtypes for bugs\n- [ ] `runZonedGuarded` for uncaught async errors\n\n## Async & Concurrency\n- [ ] `async`\u002F`await` (no unawaited futures — use `unawaited()`)\n- [ ] `Future.wait` for parallel independent operations\n- [ ] `mounted` check after `await` (before `setState`\u002F`context`)\n- [ ] `TransferableTypedData` for large buffers between isolates\n- [ ] Isolates for CPU-heavy, `await` for I\u002FO\n\n## Classes & Generics\n- [ ] `sealed` for closed hierarchies (exhaustive switches)\n- [ ] `const` constructors for immutable value types\n- [ ] `==`\u002F`hashCode` override for value classes (or use records)\n- [ ] `is T` (not `as T`) for generic cache retrieval\n\n## Collections\n- [ ] `fold` (not `reduce`) for possibly-empty collections\n- [ ] `[...list]..sort()` for sorted copies (sort is in-place, void)\n- [ ] Chain lazy `Iterable` ops, `.toList()` once at the end\n- [ ] `List.unmodifiable([...source])` for immutable copies\n\n## Security\n- [ ] Parameterized SQL queries (never string interpolation)\n- [ ] Input validation (server-side, before processing)\n- [ ] No secrets in code (use env vars \u002F secret managers)\n\n## Cross-Platform\n- [ ] `dart:io` not used on web (conditional imports)\n- [ ] `BigInt` for large integers on web (int precision above 2^53)\n- [ ] `http` package for cross-platform HTTP\n\n## Flutter\n- [ ] `const` widgets where possible (canonicalization, zero rebuild)\n- [ ] `build()` is pure (no side effects, no setState)\n- [ ] `initState` for async work, `mounted` check before setState\n- [ ] `ListView.builder` for long lists (lazy building)\n- [ ] `ValueKey` for items that can reorder\n\n## Tooling & CI\n- [ ] `dart format` applied (CI: `--set-exit-if-changed`)\n- [ ] `dart analyze` clean (CI: `--fatal-infos`)\n- [ ] `dart test` in CI (tests for all logic)\n- [ ] `build_runner` generated files not edited (regenerate from source)\n- [ ] `pubspec.lock` committed for apps (reproducible builds)\n",[23,6799,6800,6806,6836,6855,6872,6876,6881,6899,6906,6918,6922,6927,6945,6963,6981,6993,6997,7002,7024,7036,7063,7075,7087,7091,7096,7108,7120,7137,7154,7158,7163,7180,7192,7211,7223,7227,7232,7239,7246,7253,7257,7262,7274,7286,7298,7302,7307,7318,7330,7347,7359,7371,7375,7380,7397,7414,7426,7438],{"__ignoreMap":36},[40,6801,6802],{"class":42,"line":43},[40,6803,6805],{"class":6804},"sXvq9","## Null Safety & Types\n",[40,6807,6808,6811,6814,6817,6820,6823,6826,6829,6831,6834],{"class":42,"line":58},[40,6809,293],{"class":6810},"sCrzJ",[40,6812,6813],{"class":54}," [ ] Sound null safety (no ",[40,6815,6816],{"class":88},"`!`",[40,6818,6819],{"class":54}," abuse, proper ",[40,6821,6822],{"class":88},"`?`",[40,6824,6825],{"class":54},"\u002F",[40,6827,6828],{"class":88},"`??`",[40,6830,6825],{"class":54},[40,6832,6833],{"class":88},"`?.`",[40,6835,675],{"class":54},[40,6837,6838,6840,6843,6846,6849,6852],{"class":42,"line":68},[40,6839,293],{"class":6810},[40,6841,6842],{"class":54}," [ ] ",[40,6844,6845],{"class":88},"`Object?`",[40,6847,6848],{"class":54}," over ",[40,6850,6851],{"class":88},"`dynamic`",[40,6853,6854],{"class":54}," for \"any value\" (preserve type checking)\n",[40,6856,6857,6859,6861,6864,6867,6870],{"class":42,"line":75},[40,6858,293],{"class":6810},[40,6860,6842],{"class":54},[40,6862,6863],{"class":88},"`late final x = initializer`",[40,6865,6866],{"class":54}," for lazy fields (not bare ",[40,6868,6869],{"class":88},"`late`",[40,6871,675],{"class":54},[40,6873,6874],{"class":42,"line":82},[40,6875,72],{"emptyLinePlaceholder":71},[40,6877,6878],{"class":42,"line":95},[40,6879,6880],{"class":6804},"## Control Flow & Patterns\n",[40,6882,6883,6885,6888,6891,6893,6896],{"class":42,"line":100},[40,6884,293],{"class":6810},[40,6886,6887],{"class":54}," [ ] Exhaustive switches (no ",[40,6889,6890],{"class":88},"`default`",[40,6892,6825],{"class":54},[40,6894,6895],{"class":88},"`_`",[40,6897,6898],{"class":54}," for enums\u002Fsealed types)\n",[40,6900,6901,6903],{"class":42,"line":106},[40,6902,293],{"class":6810},[40,6904,6905],{"class":54}," [ ] Pattern matching with destructuring (no manual casts)\n",[40,6907,6908,6910,6912,6915],{"class":42,"line":117},[40,6909,293],{"class":6810},[40,6911,6842],{"class":54},[40,6913,6914],{"class":88},"`assert`",[40,6916,6917],{"class":54}," only for debug invariants (stripped in AOT)\n",[40,6919,6920],{"class":42,"line":139},[40,6921,72],{"emptyLinePlaceholder":71},[40,6923,6924],{"class":42,"line":157},[40,6925,6926],{"class":6804},"## Error Handling\n",[40,6928,6929,6931,6934,6937,6940,6943],{"class":42,"line":176},[40,6930,293],{"class":6810},[40,6932,6933],{"class":54}," [ ] Specific ",[40,6935,6936],{"class":88},"`on Type catch`",[40,6938,6939],{"class":54}," (not broad ",[40,6941,6942],{"class":88},"`catch (e)`",[40,6944,675],{"class":54},[40,6946,6947,6949,6951,6954,6957,6960],{"class":42,"line":181},[40,6948,293],{"class":6810},[40,6950,6842],{"class":54},[40,6952,6953],{"class":88},"`rethrow`",[40,6955,6956],{"class":54}," (not ",[40,6958,6959],{"class":88},"`throw e`",[40,6961,6962],{"class":54},") to preserve stack traces\n",[40,6964,6965,6967,6969,6972,6975,6978],{"class":42,"line":193},[40,6966,293],{"class":6810},[40,6968,6842],{"class":54},[40,6970,6971],{"class":88},"`Exception`",[40,6973,6974],{"class":54}," subtypes for recoverable, ",[40,6976,6977],{"class":88},"`Error`",[40,6979,6980],{"class":54}," subtypes for bugs\n",[40,6982,6983,6985,6987,6990],{"class":42,"line":203},[40,6984,293],{"class":6810},[40,6986,6842],{"class":54},[40,6988,6989],{"class":88},"`runZonedGuarded`",[40,6991,6992],{"class":54}," for uncaught async errors\n",[40,6994,6995],{"class":42,"line":224},[40,6996,72],{"emptyLinePlaceholder":71},[40,6998,6999],{"class":42,"line":229},[40,7000,7001],{"class":6804},"## Async & Concurrency\n",[40,7003,7004,7006,7008,7011,7013,7016,7019,7022],{"class":42,"line":235},[40,7005,293],{"class":6810},[40,7007,6842],{"class":54},[40,7009,7010],{"class":88},"`async`",[40,7012,6825],{"class":54},[40,7014,7015],{"class":88},"`await`",[40,7017,7018],{"class":54}," (no unawaited futures — use ",[40,7020,7021],{"class":88},"`unawaited()`",[40,7023,675],{"class":54},[40,7025,7026,7028,7030,7033],{"class":42,"line":266},[40,7027,293],{"class":6810},[40,7029,6842],{"class":54},[40,7031,7032],{"class":88},"`Future.wait`",[40,7034,7035],{"class":54}," for parallel independent operations\n",[40,7037,7038,7040,7042,7045,7048,7050,7053,7056,7058,7061],{"class":42,"line":280},[40,7039,293],{"class":6810},[40,7041,6842],{"class":54},[40,7043,7044],{"class":88},"`mounted`",[40,7046,7047],{"class":54}," check after ",[40,7049,7015],{"class":88},[40,7051,7052],{"class":54}," (before ",[40,7054,7055],{"class":88},"`setState`",[40,7057,6825],{"class":54},[40,7059,7060],{"class":88},"`context`",[40,7062,675],{"class":54},[40,7064,7065,7067,7069,7072],{"class":42,"line":317},[40,7066,293],{"class":6810},[40,7068,6842],{"class":54},[40,7070,7071],{"class":88},"`TransferableTypedData`",[40,7073,7074],{"class":54}," for large buffers between isolates\n",[40,7076,7077,7079,7082,7084],{"class":42,"line":337},[40,7078,293],{"class":6810},[40,7080,7081],{"class":54}," [ ] Isolates for CPU-heavy, ",[40,7083,7015],{"class":88},[40,7085,7086],{"class":54}," for I\u002FO\n",[40,7088,7089],{"class":42,"line":343},[40,7090,72],{"emptyLinePlaceholder":71},[40,7092,7093],{"class":42,"line":348},[40,7094,7095],{"class":6804},"## Classes & Generics\n",[40,7097,7098,7100,7102,7105],{"class":42,"line":354},[40,7099,293],{"class":6810},[40,7101,6842],{"class":54},[40,7103,7104],{"class":88},"`sealed`",[40,7106,7107],{"class":54}," for closed hierarchies (exhaustive switches)\n",[40,7109,7110,7112,7114,7117],{"class":42,"line":379},[40,7111,293],{"class":6810},[40,7113,6842],{"class":54},[40,7115,7116],{"class":88},"`const`",[40,7118,7119],{"class":54}," constructors for immutable value types\n",[40,7121,7122,7124,7126,7129,7131,7134],{"class":42,"line":391},[40,7123,293],{"class":6810},[40,7125,6842],{"class":54},[40,7127,7128],{"class":88},"`==`",[40,7130,6825],{"class":54},[40,7132,7133],{"class":88},"`hashCode`",[40,7135,7136],{"class":54}," override for value classes (or use records)\n",[40,7138,7139,7141,7143,7146,7148,7151],{"class":42,"line":418},[40,7140,293],{"class":6810},[40,7142,6842],{"class":54},[40,7144,7145],{"class":88},"`is T`",[40,7147,6956],{"class":54},[40,7149,7150],{"class":88},"`as T`",[40,7152,7153],{"class":54},") for generic cache retrieval\n",[40,7155,7156],{"class":42,"line":436},[40,7157,72],{"emptyLinePlaceholder":71},[40,7159,7160],{"class":42,"line":441},[40,7161,7162],{"class":6804},"## Collections\n",[40,7164,7165,7167,7169,7172,7174,7177],{"class":42,"line":446},[40,7166,293],{"class":6810},[40,7168,6842],{"class":54},[40,7170,7171],{"class":88},"`fold`",[40,7173,6956],{"class":54},[40,7175,7176],{"class":88},"`reduce`",[40,7178,7179],{"class":54},") for possibly-empty collections\n",[40,7181,7182,7184,7186,7189],{"class":42,"line":478},[40,7183,293],{"class":6810},[40,7185,6842],{"class":54},[40,7187,7188],{"class":88},"`[...list]..sort()`",[40,7190,7191],{"class":54}," for sorted copies (sort is in-place, void)\n",[40,7193,7194,7196,7199,7202,7205,7208],{"class":42,"line":498},[40,7195,293],{"class":6810},[40,7197,7198],{"class":54}," [ ] Chain lazy ",[40,7200,7201],{"class":88},"`Iterable`",[40,7203,7204],{"class":54}," ops, ",[40,7206,7207],{"class":88},"`.toList()`",[40,7209,7210],{"class":54}," once at the end\n",[40,7212,7213,7215,7217,7220],{"class":42,"line":516},[40,7214,293],{"class":6810},[40,7216,6842],{"class":54},[40,7218,7219],{"class":88},"`List.unmodifiable([...source])`",[40,7221,7222],{"class":54}," for immutable copies\n",[40,7224,7225],{"class":42,"line":534},[40,7226,72],{"emptyLinePlaceholder":71},[40,7228,7229],{"class":42,"line":569},[40,7230,7231],{"class":6804},"## Security\n",[40,7233,7234,7236],{"class":42,"line":574},[40,7235,293],{"class":6810},[40,7237,7238],{"class":54}," [ ] Parameterized SQL queries (never string interpolation)\n",[40,7240,7241,7243],{"class":42,"line":579},[40,7242,293],{"class":6810},[40,7244,7245],{"class":54}," [ ] Input validation (server-side, before processing)\n",[40,7247,7248,7250],{"class":42,"line":603},[40,7249,293],{"class":6810},[40,7251,7252],{"class":54}," [ ] No secrets in code (use env vars \u002F secret managers)\n",[40,7254,7255],{"class":42,"line":620},[40,7256,72],{"emptyLinePlaceholder":71},[40,7258,7259],{"class":42,"line":626},[40,7260,7261],{"class":6804},"## Cross-Platform\n",[40,7263,7264,7266,7268,7271],{"class":42,"line":631},[40,7265,293],{"class":6810},[40,7267,6842],{"class":54},[40,7269,7270],{"class":88},"`dart:io`",[40,7272,7273],{"class":54}," not used on web (conditional imports)\n",[40,7275,7276,7278,7280,7283],{"class":42,"line":637},[40,7277,293],{"class":6810},[40,7279,6842],{"class":54},[40,7281,7282],{"class":88},"`BigInt`",[40,7284,7285],{"class":54}," for large integers on web (int precision above 2^53)\n",[40,7287,7288,7290,7292,7295],{"class":42,"line":649},[40,7289,293],{"class":6810},[40,7291,6842],{"class":54},[40,7293,7294],{"class":88},"`http`",[40,7296,7297],{"class":54}," package for cross-platform HTTP\n",[40,7299,7300],{"class":42,"line":661},[40,7301,72],{"emptyLinePlaceholder":71},[40,7303,7304],{"class":42,"line":678},[40,7305,7306],{"class":6804},"## Flutter\n",[40,7308,7309,7311,7313,7315],{"class":42,"line":692},[40,7310,293],{"class":6810},[40,7312,6842],{"class":54},[40,7314,7116],{"class":88},[40,7316,7317],{"class":54}," widgets where possible (canonicalization, zero rebuild)\n",[40,7319,7320,7322,7324,7327],{"class":42,"line":706},[40,7321,293],{"class":6810},[40,7323,6842],{"class":54},[40,7325,7326],{"class":88},"`build()`",[40,7328,7329],{"class":54}," is pure (no side effects, no setState)\n",[40,7331,7332,7334,7336,7339,7342,7344],{"class":42,"line":711},[40,7333,293],{"class":6810},[40,7335,6842],{"class":54},[40,7337,7338],{"class":88},"`initState`",[40,7340,7341],{"class":54}," for async work, ",[40,7343,7044],{"class":88},[40,7345,7346],{"class":54}," check before setState\n",[40,7348,7349,7351,7353,7356],{"class":42,"line":716},[40,7350,293],{"class":6810},[40,7352,6842],{"class":54},[40,7354,7355],{"class":88},"`ListView.builder`",[40,7357,7358],{"class":54}," for long lists (lazy building)\n",[40,7360,7361,7363,7365,7368],{"class":42,"line":722},[40,7362,293],{"class":6810},[40,7364,6842],{"class":54},[40,7366,7367],{"class":88},"`ValueKey`",[40,7369,7370],{"class":54}," for items that can reorder\n",[40,7372,7373],{"class":42,"line":744},[40,7374,72],{"emptyLinePlaceholder":71},[40,7376,7377],{"class":42,"line":752},[40,7378,7379],{"class":6804},"## Tooling & CI\n",[40,7381,7382,7384,7386,7389,7392,7395],{"class":42,"line":769},[40,7383,293],{"class":6810},[40,7385,6842],{"class":54},[40,7387,7388],{"class":88},"`dart format`",[40,7390,7391],{"class":54}," applied (CI: ",[40,7393,7394],{"class":88},"`--set-exit-if-changed`",[40,7396,675],{"class":54},[40,7398,7399,7401,7403,7406,7409,7412],{"class":42,"line":788},[40,7400,293],{"class":6810},[40,7402,6842],{"class":54},[40,7404,7405],{"class":88},"`dart analyze`",[40,7407,7408],{"class":54}," clean (CI: ",[40,7410,7411],{"class":88},"`--fatal-infos`",[40,7413,675],{"class":54},[40,7415,7416,7418,7420,7423],{"class":42,"line":793},[40,7417,293],{"class":6810},[40,7419,6842],{"class":54},[40,7421,7422],{"class":88},"`dart test`",[40,7424,7425],{"class":54}," in CI (tests for all logic)\n",[40,7427,7428,7430,7432,7435],{"class":42,"line":806},[40,7429,293],{"class":6810},[40,7431,6842],{"class":54},[40,7433,7434],{"class":88},"`build_runner`",[40,7436,7437],{"class":54}," generated files not edited (regenerate from source)\n",[40,7439,7440,7442,7444,7447],{"class":42,"line":823},[40,7441,293],{"class":6810},[40,7443,6842],{"class":54},[40,7445,7446],{"class":88},"`pubspec.lock`",[40,7448,7449],{"class":54}," committed for apps (reproducible builds)\n",[14,7451,7453],{"id":7452},"tips-tricks","💡 Tips & Tricks",[7455,7456,7457,7468,7491,7511,7519],"ul",{},[7458,7459,7460,7464,7465,7467],"li",{},[7461,7462,7463],"strong",{},"Performance",": use ",[23,7466,4008],{}," for large byte buffers between isolates — zero-copy transfer (O(1)) instead of deep copy (O(n)). The original buffer is invalidated after transfer. Use for images, audio, large arrays.",[7458,7469,7470,7473,7474,6825,7476,7478,7479,6825,7481,6825,7483,7486,7487,7490],{},[7461,7471,7472],{},"Idiom",": use lazy ",[23,7475,1766],{},[23,7477,2004],{}," pipelines — chain ",[23,7480,6076],{},[23,7482,2253],{},[23,7484,7485],{},"asyncMap"," and materialize once at the end. Processes data element-by-element with constant memory. Avoid intermediate ",[23,7488,7489],{},".toList()"," calls.",[7458,7492,7493,7495,7496,7499,7500,7503,7504,7507,7508,7510],{},[7461,7494,7472],{},": monorepo with shared models package — ",[23,7497,7498],{},"freezed"," + ",[23,7501,7502],{},"json_serializable"," models in ",[23,7505,7506],{},"packages\u002Fmodels\u002F",", imported by both server and client. End-to-end type safety — the server and client use the same ",[23,7509,5971],{}," type.",[7458,7512,7513,1539,7515,7518],{},[7461,7514,7472],{},[23,7516,7517],{},"dart compile exe"," for native server binaries — AOT-compiled, fast cold start, no runtime needed. Perfect for Docker containers. Cross-compile per-platform.",[7458,7520,7521,7464,7523,7526,7527,7530,7531,7534,7535,7499,7538,7541],{},[7461,7522,7472],{},[23,7524,7525],{},"melos"," for monorepo management — ",[23,7528,7529],{},"melos bootstrap"," installs deps for all packages, ",[23,7532,7533],{},"melos exec -- dart test"," runs tests across packages. Avoids manual ",[23,7536,7537],{},"cd",[23,7539,7540],{},"pub get"," for each package.",[14,7543,7545],{"id":7544},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[7455,7547,7548,7564,7590,7609,7619,7627,7648,7658,7674],{},[7458,7549,7550,1539,7553,7556,7557,7559,7560,7563],{},[7461,7551,7552],{},"Monorepo path dependencies",[23,7554,7555],{},"shared_models: path: ..\u002Fshared_models"," — changes to the shared package require ",[23,7558,7529],{}," (or ",[23,7561,7562],{},"dart pub get"," in each consumer) to propagate.",[7458,7565,7566,7574,7575,7578,7579,7582,7583,7586,7587,1053],{},[7461,7567,7568,7570,7571],{},[23,7569,7498],{}," requires ",[23,7572,7573],{},"build_runner",": after changing a ",[23,7576,7577],{},"@freezed"," class, run ",[23,7580,7581],{},"dart run build_runner build"," to regenerate ",[23,7584,7585],{},".freezed.dart"," and ",[23,7588,7589],{},".g.dart",[7458,7591,7592,7598,7599,7601,7602,7604,7605,7608],{},[7461,7593,7594,7595,7597],{},"Web ",[23,7596,1160],{}," precision",": in the Flutter client, ",[23,7600,1160],{}," above 2^53 loses precision on web. If the server sends large IDs (e.g., snowflake IDs), use ",[23,7603,459],{}," or ",[23,7606,7607],{},"BigInt"," for the ID type.",[7458,7610,7611,7614,7615,7618],{},[7461,7612,7613],{},"CORS in development",": the Flutter web client needs CORS headers from the server. Use the ",[23,7616,7617],{},"corsMiddleware"," in shelf\u002Fdart_frog for development. In production, serve the client and API from the same origin (or configure CORS).",[7458,7620,7621,7626],{},[7461,7622,7623,7625],{},[23,7624,7517],{}," is platform-specific",": a macOS binary doesn't run on Linux. Build per-platform (use Docker for cross-compilation or CI runners per platform).",[7458,7628,7629,7632,7633,7636,7637,7559,7640,7643,7644,7647],{},[7461,7630,7631],{},"Async gaps in Flutter",": after ",[23,7634,7635],{},"await"," in a widget, check ",[23,7638,7639],{},"mounted",[23,7641,7642],{},"context.mounted",") before ",[23,7645,7646],{},"setState"," or navigation. The widget may have been disposed during the await.",[7458,7649,7650,7653,7654,7657],{},[7461,7651,7652],{},"Isolate spawn overhead (~50ms)",": for many small tasks, use a worker pool (reuse isolates). For one-shot heavy work, ",[23,7655,7656],{},"Isolate.run"," is fine.",[7458,7659,7660,7666,7667,7604,7670,7673],{},[7461,7661,7662,7665],{},[23,7663,7664],{},"Stream.toList()"," on infinite streams",": never completes. Use ",[23,7668,7669],{},".take(n).toList()",[23,7671,7672],{},".listen()"," for infinite streams.",[7458,7675,7676,7679,7680,6825,7682,7684,7685,7688,7689,7691],{},[7461,7677,7678],{},"Generated files and git",": either commit ",[23,7681,7589],{},[23,7683,7585],{}," (avoids build step for consumers) or ",[23,7686,7687],{},".gitignore"," them (cleaner diffs, but consumers must run ",[23,7690,7573],{},"). Be consistent.",[14,7693,7695],{"id":7694},"spot-the-bug","🧠 Spot the Bug",[19,7697,7698,7699,7701,7702,7705,7706,7709],{},"A full-stack app shares a ",[23,7700,5971],{}," model between server and client. The server returns ",[23,7703,7704],{},"created_at"," (snake_case), but the client model expects ",[23,7707,7708],{},"createdAt"," (camelCase):",[28,7711,7712],{"language":30},[32,7713,7715],{"className":34,"code":7714,"language":30,"meta":36,"style":36},"@freezed\nclass Task with _$Task {\n  const factory Task({\n    required String id,\n    required String title,\n    required DateTime createdAt,  \u002F\u002F expects \"createdAt\" in JSON\n  }) = _Task;\n\n  factory Task.fromJson(Map\u003CString, dynamic> json) => _$TaskFromJson(json);\n}\n",[23,7716,7717,7721,7733,7743,7751,7759,7771,7781,7785,7815],{"__ignoreMap":36},[40,7718,7719],{"class":42,"line":43},[40,7720,4566],{"class":46},[40,7722,7723,7725,7727,7729,7731],{"class":42,"line":58},[40,7724,1681],{"class":46},[40,7726,4573],{"class":88},[40,7728,4576],{"class":46},[40,7730,4579],{"class":88},[40,7732,114],{"class":54},[40,7734,7735,7737,7739,7741],{"class":42,"line":68},[40,7736,206],{"class":46},[40,7738,4588],{"class":46},[40,7740,4573],{"class":88},[40,7742,4593],{"class":54},[40,7744,7745,7747,7749],{"class":42,"line":75},[40,7746,4598],{"class":46},[40,7748,187],{"class":88},[40,7750,4603],{"class":54},[40,7752,7753,7755,7757],{"class":42,"line":82},[40,7754,4598],{"class":46},[40,7756,187],{"class":88},[40,7758,4612],{"class":54},[40,7760,7761,7763,7765,7768],{"class":42,"line":95},[40,7762,4598],{"class":46},[40,7764,1843],{"class":88},[40,7766,7767],{"class":54}," createdAt,  ",[40,7769,7770],{"class":78},"\u002F\u002F expects \"createdAt\" in JSON\n",[40,7772,7773,7775,7777,7779],{"class":42,"line":100},[40,7774,4662],{"class":54},[40,7776,761],{"class":46},[40,7778,4667],{"class":88},[40,7780,55],{"class":54},[40,7782,7783],{"class":42,"line":106},[40,7784,72],{"emptyLinePlaceholder":71},[40,7786,7787,7789,7791,7793,7795,7797,7799,7801,7803,7805,7807,7809,7811,7813],{"class":42,"line":117},[40,7788,1895],{"class":46},[40,7790,4573],{"class":88},[40,7792,1053],{"class":54},[40,7794,1902],{"class":120},[40,7796,124],{"class":54},[40,7798,1907],{"class":88},[40,7800,736],{"class":54},[40,7802,459],{"class":88},[40,7804,130],{"class":54},[40,7806,1916],{"class":88},[40,7808,1919],{"class":54},[40,7810,252],{"class":46},[40,7812,4702],{"class":88},[40,7814,4705],{"class":54},[40,7816,7817],{"class":42,"line":139},[40,7818,623],{"class":54},[19,7820,7821,7822,7825],{},"The server sends ",[23,7823,7824],{},"{\"id\": \"1\", \"title\": \"Test\", \"created_at\": \"2026-01-01T00:00:00\"}",". What happens?",[7827,7828,7829,7833,7860,7867,7986,8003,8009,8048],"details",{},[7830,7831,7832],"summary",{},"Answer",[19,7834,7835,7838,7839,7842,7843,7845,7846,7848,7849,7852,7853,7856,7857,1053],{},[23,7836,7837],{},"_$TaskFromJson"," looks for ",[23,7840,7841],{},"json['createdAt']"," (camelCase, matching the field name). The server sends ",[23,7844,7704],{}," (snake_case). ",[23,7847,7841],{}," is ",[23,7850,7851],{},"null"," — ",[23,7854,7855],{},"DateTime.parse(null)"," throws ",[23,7858,7859],{},"FormatException",[19,7861,7862,7863,7866],{},"The fix — use ",[23,7864,7865],{},"@JsonKey"," to map the JSON key to the Dart field name:",[32,7868,7870],{"className":34,"code":7869,"language":30,"meta":36,"style":36},"@freezed\nclass Task with _$Task {\n  const factory Task({\n    required String id,\n    required String title,\n    @JsonKey(name: 'created_at') required DateTime createdAt,  \u002F\u002F ← map JSON key\n  }) = _Task;\n\n  factory Task.fromJson(Map\u003CString, dynamic> json) => _$TaskFromJson(json);\n}\n",[23,7871,7872,7876,7888,7898,7906,7914,7938,7948,7952,7982],{"__ignoreMap":36},[40,7873,7874],{"class":42,"line":43},[40,7875,4566],{"class":46},[40,7877,7878,7880,7882,7884,7886],{"class":42,"line":58},[40,7879,1681],{"class":46},[40,7881,4573],{"class":88},[40,7883,4576],{"class":46},[40,7885,4579],{"class":88},[40,7887,114],{"class":54},[40,7889,7890,7892,7894,7896],{"class":42,"line":68},[40,7891,206],{"class":46},[40,7893,4588],{"class":46},[40,7895,4573],{"class":88},[40,7897,4593],{"class":54},[40,7899,7900,7902,7904],{"class":42,"line":75},[40,7901,4598],{"class":46},[40,7903,187],{"class":88},[40,7905,4603],{"class":54},[40,7907,7908,7910,7912],{"class":42,"line":82},[40,7909,4598],{"class":46},[40,7911,187],{"class":88},[40,7913,4612],{"class":54},[40,7915,7916,7919,7922,7924,7927,7929,7931,7933,7935],{"class":42,"line":95},[40,7917,7918],{"class":46},"    @JsonKey",[40,7920,7921],{"class":54},"(name",[40,7923,903],{"class":46},[40,7925,7926],{"class":50}," 'created_at'",[40,7928,299],{"class":54},[40,7930,5919],{"class":46},[40,7932,1843],{"class":88},[40,7934,7767],{"class":54},[40,7936,7937],{"class":78},"\u002F\u002F ← map JSON key\n",[40,7939,7940,7942,7944,7946],{"class":42,"line":100},[40,7941,4662],{"class":54},[40,7943,761],{"class":46},[40,7945,4667],{"class":88},[40,7947,55],{"class":54},[40,7949,7950],{"class":42,"line":106},[40,7951,72],{"emptyLinePlaceholder":71},[40,7953,7954,7956,7958,7960,7962,7964,7966,7968,7970,7972,7974,7976,7978,7980],{"class":42,"line":117},[40,7955,1895],{"class":46},[40,7957,4573],{"class":88},[40,7959,1053],{"class":54},[40,7961,1902],{"class":120},[40,7963,124],{"class":54},[40,7965,1907],{"class":88},[40,7967,736],{"class":54},[40,7969,459],{"class":88},[40,7971,130],{"class":54},[40,7973,1916],{"class":88},[40,7975,1919],{"class":54},[40,7977,252],{"class":46},[40,7979,4702],{"class":88},[40,7981,4705],{"class":54},[40,7983,7984],{"class":42,"line":139},[40,7985,623],{"class":54},[19,7987,7988,7989,7991,7992,7995,7996,7998,7999,8002],{},"Now ",[23,7990,7837],{}," reads ",[23,7993,7994],{},"json['created_at']"," and maps it to ",[23,7997,7708],{},". The generated code (after ",[23,8000,8001],{},"build_runner build",") handles the key mapping.",[19,8004,8005,8006,8008],{},"Or, configure ",[23,8007,7502],{}," globally to use snake_case:",[32,8010,8012],{"className":34,"code":8011,"language":30,"meta":36,"style":36},"@JsonSerializable(fieldRename: FieldRename.snake)\n\u002F\u002F or on freezed:\n@Freezed(fieldRename: FieldRename.snake)\n",[23,8013,8014,8030,8035],{"__ignoreMap":36},[40,8015,8016,8019,8022,8024,8027],{"class":42,"line":43},[40,8017,8018],{"class":46},"@JsonSerializable",[40,8020,8021],{"class":54},"(fieldRename",[40,8023,903],{"class":46},[40,8025,8026],{"class":88}," FieldRename",[40,8028,8029],{"class":54},".snake)\n",[40,8031,8032],{"class":42,"line":58},[40,8033,8034],{"class":78},"\u002F\u002F or on freezed:\n",[40,8036,8037,8040,8042,8044,8046],{"class":42,"line":68},[40,8038,8039],{"class":46},"@Freezed",[40,8041,8021],{"class":54},[40,8043,903],{"class":46},[40,8045,8026],{"class":88},[40,8047,8029],{"class":54},[19,8049,8050],{},"This maps ALL fields to snake_case in JSON. Use when the entire API uses snake_case (common in Go\u002FPython backends).",[8052,8053,8054],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}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 .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sXvq9, html code.shiki .sXvq9{--shiki-default:#005CC5;--shiki-default-font-weight:bold;--shiki-github-dark:#79B8FF;--shiki-github-dark-font-weight:bold}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":36,"searchDepth":58,"depth":58,"links":8056},[8057,8058,8059,8060,8065,8066,8067,8068],{"id":16,"depth":58,"text":17},{"id":1759,"depth":58,"text":1760},{"id":2808,"depth":58,"text":2809},{"id":4498,"depth":58,"text":4499,"children":8061},[8062,8063,8064],{"id":4516,"depth":68,"text":4517},{"id":4740,"depth":68,"text":4741},{"id":5827,"depth":68,"text":5828},{"id":6789,"depth":58,"text":6790},{"id":7452,"depth":58,"text":7453},{"id":7544,"depth":58,"text":7545},{"id":7694,"depth":58,"text":7695},"Deep-dive into real-world Dart projects — a production CLI parser, a zero-allocation data pipeline, an isolate-based image processor, a full-stack Flutter + dart_frog capstone with shared models, and a production checklist. Code-first engineering reference.","md",{},"\u002Fdart\u002F19-exercises-and-projects",{"title":5,"description":8069},"dart\u002F19-exercises-and-projects","K3jNxRORbDhul8HIOfzLWwvZfNhVjooAMC3bTi-GWVQ",1789924648019]