[{"data":1,"prerenderedAt":4863},["ShallowReactive",2],{"search-de":3,"content-de-developer\u002Femail-system":4,"surround-de-\u002Fdeveloper\u002Femail-system":4856},[],{"id":5,"title":6,"body":7,"description":13,"extension":4850,"meta":4851,"navigation":346,"path":4852,"seo":4853,"stem":4854,"__hash__":4855},"content_de\u002F3.developer\u002F6.email-system.md","E-Mail-System",{"type":8,"value":9,"toc":4799},"minimark",[10,14,17,22,25,29,37,42,122,126,690,730,734,845,849,853,860,1058,1061,1247,1251,1526,1549,1553,1560,1663,1672,1676,1679,1765,1772,1776,1779,1975,1981,1985,1997,2045,2049,2068,2456,2493,2497,2507,2687,2700,2704,2715,2820,2825,2922,2925,2965,2985,2989,3042,3126,3139,3143,3163,3206,3217,3221,3246,3374,3389,3399,3403,3447,3451,3474,3498,3525,3544,3548,3581,3588,3592,3595,3633,3636,3640,3643,3672,3683,3687,3690,3723,3727,3730,3755,3759,3762,3766,3848,3852,3870,3900,3904,3915,3998,4002,4117,4121,4124,4127,4133,4274,4278,4336,4340,4383,4387,4390,4394,4397,4417,4420,4423,4427,4483,4486,4515,4530,4533,4536,4540,4631,4634,4758,4762,4765,4792,4795],[11,12,13],"p",{},"Das E-Mail-System von Owlat besteht aus einem visuellen Editor, der Template-Verwaltung und einer Versandinfrastruktur für mehrere Provider.",[15,16],"illustrations-email-pipeline-illustration",{},[18,19,21],"h2",{"id":20},"architekturüberblick","Architekturüberblick",[23,24],"email-architecture",{},[18,26,28],{"id":27},"paket-email-builder","Paket „email-builder“",[11,30,31,32,36],{},"Der E-Mail-Builder liegt in ",[33,34,35],"code",{},"packages\u002Femail-builder\u002F"," und bietet:",[38,39,41],"h3",{"id":40},"komponenten","Komponenten",[43,44,45,58],"table",{},[46,47,48],"thead",{},[49,50,51,55],"tr",{},[52,53,54],"th",{},"Komponente",[52,56,57],{},"Zweck",[59,60,61,72,82,92,102,112],"tbody",{},[49,62,63,69],{},[64,65,66],"td",{},[33,67,68],{},"EmailBuilder.vue",[64,70,71],{},"Haupt-Editorkomponente",[49,73,74,79],{},[64,75,76],{},[33,77,78],{},"DocumentCanvas.vue",[64,80,81],{},"Renderbereich für Blöcke (einspaltiges Canvas)",[49,83,84,89],{},[64,85,86],{},[33,87,88],{},"SubjectFields.vue",[64,90,91],{},"Inline-Felder für Betreff\u002FName oben im Canvas",[49,93,94,99],{},[64,95,96],{},[33,97,98],{},"UnifiedToolbar.vue",[64,100,101],{},"Kontextbezogene Block-Toolbar",[49,103,104,109],{},[64,105,106],{},[33,107,108],{},"FloatingBlockSidebar.vue",[64,110,111],{},"Seitenleiste mit Blockaktionen (verschieben, löschen usw.)",[49,113,114,119],{},[64,115,116],{},[33,117,118],{},"PreviewPanel.vue",[64,120,121],{},"Live-HTML-Vorschau",[38,123,125],{"id":124},"verwendung","Verwendung",[127,128,133],"pre",{"className":129,"code":130,"language":131,"meta":132,"style":132},"language-vue shiki shiki-themes github-light github-dark-dimmed","\u003Ctemplate>\n    \u003CEmailBuilder\n        v-model:blocks=\"blocks\"\n        v-model:subject=\"subject\"\n        v-model:name=\"name\"\n        v-model:background-color=\"backgroundColor\"\n        :variables=\"variables\"\n        :config=\"config\"\n        :is-saving=\"isSaving\"\n        @save=\"handleSave\"\n        @settings=\"handleSettings\"\n    \u002F>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nimport { provideEmailBuilderHandlers } from '@owlat\u002Femail-builder';\n\nconst blocks = ref([]);\nconst subject = ref('');\nconst name = ref('');\nconst backgroundColor = ref('#ffffff');\nconst variables = ref([]);\nconst isSaving = ref(false);\n\nconst config = {\n    hideSubject: true, \u002F\u002F Hide subject field (default: true)\n    mode: 'email', \u002F\u002F 'email' | 'block'\n};\n\n\u002F\u002F Backend integration (image upload, saved blocks, media library) is wired\n\u002F\u002F through a provide\u002Finject contract, NOT props. Call this in a parent\n\u002F\u002F component before EmailBuilder mounts.\nprovideEmailBuilderHandlers({\n    uploadImage: async (file) => ({ url: await upload(file) }),\n    savedBlocks: {\n        fetch: (params) => fetchSavedBlocks(params),\n        save: (block) => saveBlock(block),\n    },\n});\n\u003C\u002Fscript>\n","vue","",[33,134,135,151,160,185,203,221,240,257,273,290,308,325,331,341,348,361,381,386,406,427,445,464,478,497,502,515,531,545,551,556,562,568,574,583,620,626,648,669,675,681],{"__ignoreMap":132},[136,137,140,144,148],"span",{"class":138,"line":139},"line",1,[136,141,143],{"class":142},"sYgZi","\u003C",[136,145,147],{"class":146},"sIAta","template",[136,149,150],{"class":142},">\n",[136,152,154,157],{"class":138,"line":153},2,[136,155,156],{"class":142},"    \u003C",[136,158,159],{"class":146},"EmailBuilder\n",[136,161,163,167,170,173,176,180,182],{"class":138,"line":162},3,[136,164,166],{"class":165},"sMOND","        v-model",[136,168,169],{"class":142},":",[136,171,172],{"class":165},"blocks",[136,174,175],{"class":142},"=",[136,177,179],{"class":178},"s4G6O","\"",[136,181,172],{"class":142},[136,183,184],{"class":178},"\"\n",[136,186,188,190,192,195,197,199,201],{"class":138,"line":187},4,[136,189,166],{"class":165},[136,191,169],{"class":142},[136,193,194],{"class":165},"subject",[136,196,175],{"class":142},[136,198,179],{"class":178},[136,200,194],{"class":142},[136,202,184],{"class":178},[136,204,206,208,210,213,215,217,219],{"class":138,"line":205},5,[136,207,166],{"class":165},[136,209,169],{"class":142},[136,211,212],{"class":165},"name",[136,214,175],{"class":142},[136,216,179],{"class":178},[136,218,212],{"class":142},[136,220,184],{"class":178},[136,222,224,226,228,231,233,235,238],{"class":138,"line":223},6,[136,225,166],{"class":165},[136,227,169],{"class":142},[136,229,230],{"class":165},"background-color",[136,232,175],{"class":142},[136,234,179],{"class":178},[136,236,237],{"class":142},"backgroundColor",[136,239,184],{"class":178},[136,241,243,246,249,251,253,255],{"class":138,"line":242},7,[136,244,245],{"class":142},"        :",[136,247,248],{"class":165},"variables",[136,250,175],{"class":142},[136,252,179],{"class":178},[136,254,248],{"class":142},[136,256,184],{"class":178},[136,258,260,262,265,267,269,271],{"class":138,"line":259},8,[136,261,245],{"class":142},[136,263,264],{"class":165},"config",[136,266,175],{"class":142},[136,268,179],{"class":178},[136,270,264],{"class":142},[136,272,184],{"class":178},[136,274,276,278,281,283,285,288],{"class":138,"line":275},9,[136,277,245],{"class":142},[136,279,280],{"class":165},"is-saving",[136,282,175],{"class":142},[136,284,179],{"class":178},[136,286,287],{"class":142},"isSaving",[136,289,184],{"class":178},[136,291,293,296,299,301,303,306],{"class":138,"line":292},10,[136,294,295],{"class":142},"        @",[136,297,298],{"class":165},"save",[136,300,175],{"class":142},[136,302,179],{"class":178},[136,304,305],{"class":142},"handleSave",[136,307,184],{"class":178},[136,309,311,313,316,318,320,323],{"class":138,"line":310},11,[136,312,295],{"class":142},[136,314,315],{"class":165},"settings",[136,317,175],{"class":142},[136,319,179],{"class":178},[136,321,322],{"class":142},"handleSettings",[136,324,184],{"class":178},[136,326,328],{"class":138,"line":327},12,[136,329,330],{"class":142},"    \u002F>\n",[136,332,334,337,339],{"class":138,"line":333},13,[136,335,336],{"class":142},"\u003C\u002F",[136,338,147],{"class":146},[136,340,150],{"class":142},[136,342,344],{"class":138,"line":343},14,[136,345,347],{"emptyLinePlaceholder":346},true,"\n",[136,349,351,353,356,359],{"class":138,"line":350},15,[136,352,143],{"class":142},[136,354,355],{"class":146},"script",[136,357,358],{"class":165}," setup",[136,360,150],{"class":142},[136,362,364,368,371,374,378],{"class":138,"line":363},16,[136,365,367],{"class":366},"s7YZ4","import",[136,369,370],{"class":142}," { provideEmailBuilderHandlers } ",[136,372,373],{"class":366},"from",[136,375,377],{"class":376},"s-HuK"," '@owlat\u002Femail-builder'",[136,379,380],{"class":142},";\n",[136,382,384],{"class":138,"line":383},17,[136,385,347],{"emptyLinePlaceholder":346},[136,387,389,392,396,399,403],{"class":138,"line":388},18,[136,390,391],{"class":366},"const",[136,393,395],{"class":394},"sviXB"," blocks",[136,397,398],{"class":366}," =",[136,400,402],{"class":401},"sPO5f"," ref",[136,404,405],{"class":142},"([]);\n",[136,407,409,411,414,416,418,421,424],{"class":138,"line":408},19,[136,410,391],{"class":366},[136,412,413],{"class":394}," subject",[136,415,398],{"class":366},[136,417,402],{"class":401},[136,419,420],{"class":142},"(",[136,422,423],{"class":376},"''",[136,425,426],{"class":142},");\n",[136,428,430,432,435,437,439,441,443],{"class":138,"line":429},20,[136,431,391],{"class":366},[136,433,434],{"class":394}," name",[136,436,398],{"class":366},[136,438,402],{"class":401},[136,440,420],{"class":142},[136,442,423],{"class":376},[136,444,426],{"class":142},[136,446,448,450,453,455,457,459,462],{"class":138,"line":447},21,[136,449,391],{"class":366},[136,451,452],{"class":394}," backgroundColor",[136,454,398],{"class":366},[136,456,402],{"class":401},[136,458,420],{"class":142},[136,460,461],{"class":376},"'#ffffff'",[136,463,426],{"class":142},[136,465,467,469,472,474,476],{"class":138,"line":466},22,[136,468,391],{"class":366},[136,470,471],{"class":394}," variables",[136,473,398],{"class":366},[136,475,402],{"class":401},[136,477,405],{"class":142},[136,479,481,483,486,488,490,492,495],{"class":138,"line":480},23,[136,482,391],{"class":366},[136,484,485],{"class":394}," isSaving",[136,487,398],{"class":366},[136,489,402],{"class":401},[136,491,420],{"class":142},[136,493,494],{"class":394},"false",[136,496,426],{"class":142},[136,498,500],{"class":138,"line":499},24,[136,501,347],{"emptyLinePlaceholder":346},[136,503,505,507,510,512],{"class":138,"line":504},25,[136,506,391],{"class":366},[136,508,509],{"class":394}," config",[136,511,398],{"class":366},[136,513,514],{"class":142}," {\n",[136,516,518,521,524,527],{"class":138,"line":517},26,[136,519,520],{"class":142},"    hideSubject: ",[136,522,523],{"class":394},"true",[136,525,526],{"class":142},", ",[136,528,530],{"class":529},"sDN9O","\u002F\u002F Hide subject field (default: true)\n",[136,532,534,537,540,542],{"class":138,"line":533},27,[136,535,536],{"class":142},"    mode: ",[136,538,539],{"class":376},"'email'",[136,541,526],{"class":142},[136,543,544],{"class":529},"\u002F\u002F 'email' | 'block'\n",[136,546,548],{"class":138,"line":547},28,[136,549,550],{"class":142},"};\n",[136,552,554],{"class":138,"line":553},29,[136,555,347],{"emptyLinePlaceholder":346},[136,557,559],{"class":138,"line":558},30,[136,560,561],{"class":529},"\u002F\u002F Backend integration (image upload, saved blocks, media library) is wired\n",[136,563,565],{"class":138,"line":564},31,[136,566,567],{"class":529},"\u002F\u002F through a provide\u002Finject contract, NOT props. Call this in a parent\n",[136,569,571],{"class":138,"line":570},32,[136,572,573],{"class":529},"\u002F\u002F component before EmailBuilder mounts.\n",[136,575,577,580],{"class":138,"line":576},33,[136,578,579],{"class":401},"provideEmailBuilderHandlers",[136,581,582],{"class":142},"({\n",[136,584,586,589,592,595,598,602,605,608,611,614,617],{"class":138,"line":585},34,[136,587,588],{"class":401},"    uploadImage",[136,590,591],{"class":142},": ",[136,593,594],{"class":366},"async",[136,596,597],{"class":142}," (",[136,599,601],{"class":600},"stnAF","file",[136,603,604],{"class":142},") ",[136,606,607],{"class":366},"=>",[136,609,610],{"class":142}," ({ url: ",[136,612,613],{"class":366},"await",[136,615,616],{"class":401}," upload",[136,618,619],{"class":142},"(file) }),\n",[136,621,623],{"class":138,"line":622},35,[136,624,625],{"class":142},"    savedBlocks: {\n",[136,627,629,632,635,638,640,642,645],{"class":138,"line":628},36,[136,630,631],{"class":401},"        fetch",[136,633,634],{"class":142},": (",[136,636,637],{"class":600},"params",[136,639,604],{"class":142},[136,641,607],{"class":366},[136,643,644],{"class":401}," fetchSavedBlocks",[136,646,647],{"class":142},"(params),\n",[136,649,651,654,656,659,661,663,666],{"class":138,"line":650},37,[136,652,653],{"class":401},"        save",[136,655,634],{"class":142},[136,657,658],{"class":600},"block",[136,660,604],{"class":142},[136,662,607],{"class":366},[136,664,665],{"class":401}," saveBlock",[136,667,668],{"class":142},"(block),\n",[136,670,672],{"class":138,"line":671},38,[136,673,674],{"class":142},"    },\n",[136,676,678],{"class":138,"line":677},39,[136,679,680],{"class":142},"});\n",[136,682,684,686,688],{"class":138,"line":683},40,[136,685,336],{"class":142},[136,687,355],{"class":146},[136,689,150],{"class":142},[11,691,692,693,526,695,526,697,699,700,702,703,526,705,699,707,709,710,713,714,717,718,721,722,725,726,729],{},"Die erforderlichen Props sind ",[33,694,172],{},[33,696,194],{},[33,698,212],{}," und ",[33,701,248],{},"; ",[33,704,237],{},[33,706,264],{},[33,708,287],{}," sind optional (",[33,711,712],{},"EmailBuilder.vue:70-78","). Eine Prop ",[33,715,716],{},"saved-blocks"," gibt es nicht — gespeicherte Blöcke, Bild-Upload und die Auswahl aus der Medienbibliothek werden über den Provide\u002FInject-Vertrag ",[33,719,720],{},"EmailBuilderHandlers"," bereitgestellt (",[33,723,724],{},"packages\u002Femail-builder\u002Fsrc\u002Ftypes\u002Feditor.ts:44",") und innerhalb der Komponente über ",[33,727,728],{},"useEmailBuilderHandlers()"," aufgelöst.",[38,731,733],{"id":732},"konfigurationsoptionen","Konfigurationsoptionen",[43,735,736,752],{},[46,737,738],{},[49,739,740,743,746,749],{},[52,741,742],{},"Option",[52,744,745],{},"Typ",[52,747,748],{},"Standard",[52,750,751],{},"Beschreibung",[59,753,754,770,787,802,817,831],{},[49,755,756,761,764,767],{},[64,757,758],{},[33,759,760],{},"variableType",[64,762,763],{},"string",[64,765,766],{},"-",[64,768,769],{},"Rendermodus für Variablen ('personalization' oder 'data')",[49,771,772,777,782,784],{},[64,773,774],{},[33,775,776],{},"blockTypes",[64,778,779,780],{},"BlockType",[136,781],{},[64,783,766],{},[64,785,786],{},"Verfügbare Blocktypen in der Seitenleiste einschränken (Standard: alle)",[49,788,789,794,797,799],{},[64,790,791],{},[33,792,793],{},"theme",[64,795,796],{},"EmailTheme",[64,798,766],{},[64,800,801],{},"E-Mail-Theme für das Styling (Farben, Schriften, Abstände)",[49,803,804,809,812,814],{},[64,805,806],{},[33,807,808],{},"showMandatoryUnsubscribeFooter",[64,810,811],{},"boolean",[64,813,494],{},[64,815,816],{},"Verpflichtende, nicht bearbeitbare Abmelde-Fußzeile anzeigen",[49,818,819,824,826,828],{},[64,820,821],{},[33,822,823],{},"hideSubject",[64,825,811],{},[64,827,523],{},[64,829,830],{},"Eingabefeld für den Betreff ausblenden",[49,832,833,838,840,842],{},[64,834,835],{},[33,836,837],{},"mode",[64,839,763],{},[64,841,539],{},[64,843,844],{},"'email' für Templates, 'block' für gespeicherte Blöcke",[18,846,848],{"id":847},"blocksystem","Blocksystem",[38,850,852],{"id":851},"blockstruktur","Blockstruktur",[11,854,855,856,859],{},"Blöcke sind in ",[33,857,858],{},"@owlat\u002Fshared"," definiert:",[127,861,865],{"className":862,"code":863,"language":864,"meta":132,"style":132},"language-typescript shiki shiki-themes github-light github-dark-dimmed","type BlockType =\n    | 'text'\n    | 'image'\n    | 'button'\n    | 'divider'\n    | 'spacer'\n    | 'columns'\n    | 'social'\n    | 'container'\n    | 'hero'\n    | 'table'\n    | 'rawHtml'\n    | 'video'\n    | 'accordion'\n    | 'menu'\n    | 'carousel'\n    | 'list'\n    | 'progressBar';\n\ninterface EditorBlock {\n    id: string;\n    type: BlockType;\n    content: BlockContent; \u002F\u002F Discriminated union per type\n}\n","typescript",[33,866,867,879,887,894,901,908,915,922,929,936,943,950,957,964,971,978,985,992,1001,1005,1015,1027,1038,1053],{"__ignoreMap":132},[136,868,869,872,876],{"class":138,"line":139},[136,870,871],{"class":366},"type",[136,873,875],{"class":874},"sOLd2"," BlockType",[136,877,878],{"class":366}," =\n",[136,880,881,884],{"class":138,"line":153},[136,882,883],{"class":366},"    |",[136,885,886],{"class":376}," 'text'\n",[136,888,889,891],{"class":138,"line":162},[136,890,883],{"class":366},[136,892,893],{"class":376}," 'image'\n",[136,895,896,898],{"class":138,"line":187},[136,897,883],{"class":366},[136,899,900],{"class":376}," 'button'\n",[136,902,903,905],{"class":138,"line":205},[136,904,883],{"class":366},[136,906,907],{"class":376}," 'divider'\n",[136,909,910,912],{"class":138,"line":223},[136,911,883],{"class":366},[136,913,914],{"class":376}," 'spacer'\n",[136,916,917,919],{"class":138,"line":242},[136,918,883],{"class":366},[136,920,921],{"class":376}," 'columns'\n",[136,923,924,926],{"class":138,"line":259},[136,925,883],{"class":366},[136,927,928],{"class":376}," 'social'\n",[136,930,931,933],{"class":138,"line":275},[136,932,883],{"class":366},[136,934,935],{"class":376}," 'container'\n",[136,937,938,940],{"class":138,"line":292},[136,939,883],{"class":366},[136,941,942],{"class":376}," 'hero'\n",[136,944,945,947],{"class":138,"line":310},[136,946,883],{"class":366},[136,948,949],{"class":376}," 'table'\n",[136,951,952,954],{"class":138,"line":327},[136,953,883],{"class":366},[136,955,956],{"class":376}," 'rawHtml'\n",[136,958,959,961],{"class":138,"line":333},[136,960,883],{"class":366},[136,962,963],{"class":376}," 'video'\n",[136,965,966,968],{"class":138,"line":343},[136,967,883],{"class":366},[136,969,970],{"class":376}," 'accordion'\n",[136,972,973,975],{"class":138,"line":350},[136,974,883],{"class":366},[136,976,977],{"class":376}," 'menu'\n",[136,979,980,982],{"class":138,"line":363},[136,981,883],{"class":366},[136,983,984],{"class":376}," 'carousel'\n",[136,986,987,989],{"class":138,"line":383},[136,988,883],{"class":366},[136,990,991],{"class":376}," 'list'\n",[136,993,994,996,999],{"class":138,"line":388},[136,995,883],{"class":366},[136,997,998],{"class":376}," 'progressBar'",[136,1000,380],{"class":142},[136,1002,1003],{"class":138,"line":408},[136,1004,347],{"emptyLinePlaceholder":346},[136,1006,1007,1010,1013],{"class":138,"line":429},[136,1008,1009],{"class":366},"interface",[136,1011,1012],{"class":874}," EditorBlock",[136,1014,514],{"class":142},[136,1016,1017,1020,1022,1025],{"class":138,"line":447},[136,1018,1019],{"class":600},"    id",[136,1021,169],{"class":366},[136,1023,1024],{"class":394}," string",[136,1026,380],{"class":142},[136,1028,1029,1032,1034,1036],{"class":138,"line":466},[136,1030,1031],{"class":600},"    type",[136,1033,169],{"class":366},[136,1035,875],{"class":874},[136,1037,380],{"class":142},[136,1039,1040,1043,1045,1048,1050],{"class":138,"line":480},[136,1041,1042],{"class":600},"    content",[136,1044,169],{"class":366},[136,1046,1047],{"class":874}," BlockContent",[136,1049,702],{"class":142},[136,1051,1052],{"class":529},"\u002F\u002F Discriminated union per type\n",[136,1054,1055],{"class":138,"line":499},[136,1056,1057],{"class":142},"}\n",[11,1059,1060],{},"Jeder Blocktyp besitzt ein eigenes Content-Interface. Zum Beispiel:",[127,1062,1064],{"className":862,"code":1063,"language":864,"meta":132,"style":132},"\u002F\u002F Text blocks handle both paragraphs and headings\ninterface TextBlockContent {\n    html: string;\n    blockType: 'paragraph' | 'h1' | 'h2' | 'h3';\n    fontSize: number;\n    textColor: string;\n    textAlign?: 'left' | 'center' | 'right';\n    \u002F\u002F ... padding, margin, border, backgroundColor\n}\n\n\u002F\u002F Containers can nest other blocks recursively\ninterface ContainerBlockContent {\n    items: ContainerItem[];\n    maxWidth: number;\n    backgroundColor?: string;\n    borderRadius: number;\n    \u002F\u002F ... padding, margin, border\n}\n",[33,1065,1066,1071,1080,1091,1119,1131,1142,1165,1170,1174,1178,1183,1192,1205,1216,1227,1238,1243],{"__ignoreMap":132},[136,1067,1068],{"class":138,"line":139},[136,1069,1070],{"class":529},"\u002F\u002F Text blocks handle both paragraphs and headings\n",[136,1072,1073,1075,1078],{"class":138,"line":153},[136,1074,1009],{"class":366},[136,1076,1077],{"class":874}," TextBlockContent",[136,1079,514],{"class":142},[136,1081,1082,1085,1087,1089],{"class":138,"line":162},[136,1083,1084],{"class":600},"    html",[136,1086,169],{"class":366},[136,1088,1024],{"class":394},[136,1090,380],{"class":142},[136,1092,1093,1096,1098,1101,1104,1107,1109,1112,1114,1117],{"class":138,"line":187},[136,1094,1095],{"class":600},"    blockType",[136,1097,169],{"class":366},[136,1099,1100],{"class":376}," 'paragraph'",[136,1102,1103],{"class":366}," |",[136,1105,1106],{"class":376}," 'h1'",[136,1108,1103],{"class":366},[136,1110,1111],{"class":376}," 'h2'",[136,1113,1103],{"class":366},[136,1115,1116],{"class":376}," 'h3'",[136,1118,380],{"class":142},[136,1120,1121,1124,1126,1129],{"class":138,"line":205},[136,1122,1123],{"class":600},"    fontSize",[136,1125,169],{"class":366},[136,1127,1128],{"class":394}," number",[136,1130,380],{"class":142},[136,1132,1133,1136,1138,1140],{"class":138,"line":223},[136,1134,1135],{"class":600},"    textColor",[136,1137,169],{"class":366},[136,1139,1024],{"class":394},[136,1141,380],{"class":142},[136,1143,1144,1147,1150,1153,1155,1158,1160,1163],{"class":138,"line":242},[136,1145,1146],{"class":600},"    textAlign",[136,1148,1149],{"class":366},"?:",[136,1151,1152],{"class":376}," 'left'",[136,1154,1103],{"class":366},[136,1156,1157],{"class":376}," 'center'",[136,1159,1103],{"class":366},[136,1161,1162],{"class":376}," 'right'",[136,1164,380],{"class":142},[136,1166,1167],{"class":138,"line":259},[136,1168,1169],{"class":529},"    \u002F\u002F ... padding, margin, border, backgroundColor\n",[136,1171,1172],{"class":138,"line":275},[136,1173,1057],{"class":142},[136,1175,1176],{"class":138,"line":292},[136,1177,347],{"emptyLinePlaceholder":346},[136,1179,1180],{"class":138,"line":310},[136,1181,1182],{"class":529},"\u002F\u002F Containers can nest other blocks recursively\n",[136,1184,1185,1187,1190],{"class":138,"line":327},[136,1186,1009],{"class":366},[136,1188,1189],{"class":874}," ContainerBlockContent",[136,1191,514],{"class":142},[136,1193,1194,1197,1199,1202],{"class":138,"line":333},[136,1195,1196],{"class":600},"    items",[136,1198,169],{"class":366},[136,1200,1201],{"class":874}," ContainerItem",[136,1203,1204],{"class":142},"[];\n",[136,1206,1207,1210,1212,1214],{"class":138,"line":343},[136,1208,1209],{"class":600},"    maxWidth",[136,1211,169],{"class":366},[136,1213,1128],{"class":394},[136,1215,380],{"class":142},[136,1217,1218,1221,1223,1225],{"class":138,"line":350},[136,1219,1220],{"class":600},"    backgroundColor",[136,1222,1149],{"class":366},[136,1224,1024],{"class":394},[136,1226,380],{"class":142},[136,1228,1229,1232,1234,1236],{"class":138,"line":363},[136,1230,1231],{"class":600},"    borderRadius",[136,1233,169],{"class":366},[136,1235,1128],{"class":394},[136,1237,380],{"class":142},[136,1239,1240],{"class":138,"line":383},[136,1241,1242],{"class":529},"    \u002F\u002F ... padding, margin, border\n",[136,1244,1245],{"class":138,"line":388},[136,1246,1057],{"class":142},[38,1248,1250],{"id":1249},"verfügbare-blocktypen","Verfügbare Blocktypen",[43,1252,1253,1264],{},[46,1254,1255],{},[49,1256,1257,1259,1262],{},[52,1258,745],{},[52,1260,1261],{},"Slash-Befehl",[52,1263,751],{},[59,1265,1266,1287,1302,1317,1332,1347,1362,1377,1392,1407,1421,1436,1451,1466,1481,1496,1511],{},[49,1267,1268,1273,1284],{},[64,1269,1270],{},[33,1271,1272],{},"text",[64,1274,1275,526,1278,766,1281],{},[33,1276,1277],{},"\u002Ftext",[33,1279,1280],{},"\u002Fh1",[33,1282,1283],{},"\u002Fh3",[64,1285,1286],{},"Rich Text als Absatz- oder Überschriftenvariante",[49,1288,1289,1294,1299],{},[64,1290,1291],{},[33,1292,1293],{},"image",[64,1295,1296],{},[33,1297,1298],{},"\u002Fimage",[64,1300,1301],{},"Bild mit URL, Alt-Text, Link, Retina-\u002FDark-Austausch",[49,1303,1304,1309,1314],{},[64,1305,1306],{},[33,1307,1308],{},"button",[64,1310,1311],{},[33,1312,1313],{},"\u002Fbutton",[64,1315,1316],{},"CTA-Button mit kugelsicherem VML-Rendering für Outlook",[49,1318,1319,1324,1329],{},[64,1320,1321],{},[33,1322,1323],{},"divider",[64,1325,1326],{},[33,1327,1328],{},"\u002Fdivider",[64,1330,1331],{},"Horizontale Trennlinie",[49,1333,1334,1339,1344],{},[64,1335,1336],{},[33,1337,1338],{},"spacer",[64,1340,1341],{},[33,1342,1343],{},"\u002Fspacer",[64,1345,1346],{},"Vertikaler Abstand",[49,1348,1349,1354,1359],{},[64,1350,1351],{},[33,1352,1353],{},"columns",[64,1355,1356],{},[33,1357,1358],{},"\u002Fcolumns",[64,1360,1361],{},"Layout mit 1–4 Spalten, Verhältnis-Presets und Abstand",[49,1363,1364,1369,1374],{},[64,1365,1366],{},[33,1367,1368],{},"social",[64,1370,1371],{},[33,1372,1373],{},"\u002Fsocial",[64,1375,1376],{},"Icon-Links zu sozialen Netzwerken (17 Plattformen)",[49,1378,1379,1384,1389],{},[64,1380,1381],{},[33,1382,1383],{},"container",[64,1385,1386],{},[33,1387,1388],{},"\u002Fcontainer",[64,1390,1391],{},"Blöcke mit gemeinsamem Styling gruppieren",[49,1393,1394,1399,1404],{},[64,1395,1396],{},[33,1397,1398],{},"hero",[64,1400,1401],{},[33,1402,1403],{},"\u002Fhero",[64,1405,1406],{},"Vollbreiter Abschnitt mit Hintergrundbild und VML",[49,1408,1409,1413,1418],{},[64,1410,1411],{},[33,1412,43],{},[64,1414,1415],{},[33,1416,1417],{},"\u002Ftable",[64,1419,1420],{},"Datentabelle mit Rich-Zellen und responsiven Modi",[49,1422,1423,1428,1433],{},[64,1424,1425],{},[33,1426,1427],{},"rawHtml",[64,1429,1430],{},[33,1431,1432],{},"\u002FrawHtml",[64,1434,1435],{},"Einfügen von rohem HTML (Notausstieg für Fortgeschrittene)",[49,1437,1438,1443,1448],{},[64,1439,1440],{},[33,1441,1442],{},"video",[64,1444,1445],{},[33,1446,1447],{},"\u002Fvideo",[64,1449,1450],{},"Video-Thumbnail mit Play-Button-Overlay",[49,1452,1453,1458,1463],{},[64,1454,1455],{},[33,1456,1457],{},"accordion",[64,1459,1460],{},[33,1461,1462],{},"\u002Faccordion",[64,1464,1465],{},"Ausklappbare Abschnitte, nur mit CSS",[49,1467,1468,1473,1478],{},[64,1469,1470],{},[33,1471,1472],{},"menu",[64,1474,1475],{},[33,1476,1477],{},"\u002Fmenu",[64,1479,1480],{},"Horizontale Navigation mit Hamburger-Menü auf Mobilgeräten",[49,1482,1483,1488,1493],{},[64,1484,1485],{},[33,1486,1487],{},"carousel",[64,1489,1490],{},[33,1491,1492],{},"\u002Fcarousel",[64,1494,1495],{},"Bilder-Slideshow, nur mit CSS",[49,1497,1498,1503,1508],{},[64,1499,1500],{},[33,1501,1502],{},"list",[64,1504,1505],{},[33,1506,1507],{},"\u002Flist",[64,1509,1510],{},"Gestaltete Liste mit eigenen Markern (tabellenbasiert)",[49,1512,1513,1518,1523],{},[64,1514,1515],{},[33,1516,1517],{},"progressBar",[64,1519,1520],{},[33,1521,1522],{},"\u002FprogressBar",[64,1524,1525],{},"Visuelle Fortschrittsanzeige",[1527,1528,1530],"callout",{"type":1529},"tip",[11,1531,1532,1533,1535,1536,1539,1540,526,1543,1545,1546,1548],{},"Überschriften sind kein eigener Blocktyp. Sie sind ",[33,1534,1272],{},"-Blöcke, deren ",[33,1537,1538],{},"blockType"," auf ",[33,1541,1542],{},"h1",[33,1544,18],{}," oder ",[33,1547,38],{}," gesetzt ist.",[38,1550,1552],{"id":1551},"funktionen-des-renderers","Funktionen des Renderers",[11,1554,1555,1556,1559],{},"Das Paket ",[33,1557,1558],{},"@owlat\u002Femail-renderer"," leistet mehr als die Umwandlung von Blöcken in HTML. Zu den zentralen Fähigkeiten gehören:",[1561,1562,1563,1571,1581,1587,1593,1599,1605,1611,1617,1623,1629,1635,1641,1647],"ul",{},[1564,1565,1566,1570],"li",{},[1567,1568,1569],"strong",{},"CSS-Inlining"," — Styles werden inline angewendet, für Kompatibilität mit Gmail\u002FYahoo (standardmäßig aktiviert)",[1564,1572,1573,1576,1577,1580],{},[1567,1574,1575],{},"Dark Mode"," — Regeln über ",[33,1578,1579],{},"@media (prefers-color-scheme: dark)",", Bildaustausch, Overrides pro Block",[1564,1582,1583,1586],{},[1567,1584,1585],{},"Outlook-VML"," — kugelsichere Buttons, Hintergrundbilder und Tabellen mit fester Breite",[1564,1588,1589,1592],{},[1567,1590,1591],{},"Plain Text"," — Multipart-Klartextausgabe für Barrierefreiheit und Zustellbarkeit",[1564,1594,1595,1598],{},[1567,1596,1597],{},"AMP for Email"," — drittes Format für interaktive Komponenten in Gmail\u002FYahoo",[1564,1600,1601,1604],{},[1567,1602,1603],{},"Bedingte Inhalte"," — Blöcke abhängig von Variablenwerten ein-\u002Fausblenden",[1564,1606,1607,1610],{},[1567,1608,1609],{},"Wiederholungsblöcke"," — über Array-Variablen iterieren, etwa für Produktlisten oder Bestellpositionen",[1564,1612,1613,1616],{},[1567,1614,1615],{},"Blockvalidierung"," — strukturelle Prüfungen vor dem Rendern samt Barrierefreiheits-Audit",[1564,1618,1619,1622],{},[1567,1620,1621],{},"E-Mail-Analyse"," — Größenanalyse nach dem Rendern, Erkennung von Gmail-Clipping, Zählung von Bildern\u002FLinks",[1564,1624,1625,1628],{},[1567,1626,1627],{},"Template-Diff"," — struktureller Vergleich zwischen E-Mail-Versionen",[1564,1630,1631,1634],{},[1567,1632,1633],{},"Link-Transformationen"," — Umschreiben von URLs für UTM\u002FKlick-Tracking",[1564,1636,1637,1640],{},[1567,1638,1639],{},"Registry für eigene Blöcke"," — Renderer von Drittanbieterblöcken registrieren",[1564,1642,1643,1646],{},[1567,1644,1645],{},"Verlaufshintergründe"," — CSS linear-gradient mit VML-Fallback auf Buttons, Containern und Hero-Blöcken",[1564,1648,1649,1652,1653,699,1656,1659,1660],{},[1567,1650,1651],{},"CSS-Animationen"," — ",[33,1654,1655],{},"fadeIn",[33,1657,1658],{},"slideUp"," mit Unterstützung für ",[33,1661,1662],{},"prefers-reduced-motion",[11,1664,1665,1666,1671],{},"Alle Details finden Sie in der Dokumentation zum ",[1667,1668,1670],"a",{"href":1669},"\u002Fdeveloper\u002Femail-renderer","Email Renderer",".",[38,1673,1675],{"id":1674},"gespeicherte-blöcke","Gespeicherte Blöcke",[11,1677,1678],{},"Nutzerinnen und Nutzer können wiederverwendbare Inhalte speichern:",[127,1680,1682],{"className":862,"code":1681,"language":864,"meta":132,"style":132},"interface SavedBlock {\n    _id: string;\n    name: string;\n    description?: string;\n    content: string; \u002F\u002F JSON string of blocks\n    usageCount: number;\n    blockCount?: number;\n}\n",[33,1683,1684,1693,1704,1715,1726,1739,1750,1761],{"__ignoreMap":132},[136,1685,1686,1688,1691],{"class":138,"line":139},[136,1687,1009],{"class":366},[136,1689,1690],{"class":874}," SavedBlock",[136,1692,514],{"class":142},[136,1694,1695,1698,1700,1702],{"class":138,"line":153},[136,1696,1697],{"class":600},"    _id",[136,1699,169],{"class":366},[136,1701,1024],{"class":394},[136,1703,380],{"class":142},[136,1705,1706,1709,1711,1713],{"class":138,"line":162},[136,1707,1708],{"class":600},"    name",[136,1710,169],{"class":366},[136,1712,1024],{"class":394},[136,1714,380],{"class":142},[136,1716,1717,1720,1722,1724],{"class":138,"line":187},[136,1718,1719],{"class":600},"    description",[136,1721,1149],{"class":366},[136,1723,1024],{"class":394},[136,1725,380],{"class":142},[136,1727,1728,1730,1732,1734,1736],{"class":138,"line":205},[136,1729,1042],{"class":600},[136,1731,169],{"class":366},[136,1733,1024],{"class":394},[136,1735,702],{"class":142},[136,1737,1738],{"class":529},"\u002F\u002F JSON string of blocks\n",[136,1740,1741,1744,1746,1748],{"class":138,"line":223},[136,1742,1743],{"class":600},"    usageCount",[136,1745,169],{"class":366},[136,1747,1128],{"class":394},[136,1749,380],{"class":142},[136,1751,1752,1755,1757,1759],{"class":138,"line":242},[136,1753,1754],{"class":600},"    blockCount",[136,1756,1149],{"class":366},[136,1758,1128],{"class":394},[136,1760,380],{"class":142},[136,1762,1763],{"class":138,"line":259},[136,1764,1057],{"class":142},[11,1766,1767,1768,1771],{},"Gespeicherte Blöcke erscheinen im Slash-Menü (Eingabe von ",[33,1769,1770],{},"\u002F",") unter ihrem eigenen Namen; die Auswahl fügt sie ein.",[18,1773,1775],{"id":1774},"mehrsprachigkeit","Mehrsprachigkeit",[11,1777,1778],{},"Templates unterstützen Übersetzungen:",[127,1780,1782],{"className":862,"code":1781,"language":864,"meta":132,"style":132},"interface EmailTemplate {\n  \u002F\u002F Default language content\n  subject: string\n  content: string           \u002F\u002F JSON blocks\n  defaultLanguage: string   \u002F\u002F e.g., 'en'\n\n  \u002F\u002F Translations\n  supportedLanguages: string[]    \u002F\u002F ['en', 'de', 'fr']\n  translations: string            \u002F\u002F JSON of translations\n\n  \u002F\u002F Pre-rendered HTML per language\n  htmlContent: string             \u002F\u002F Default language\n  htmlTranslations: string        \u002F\u002F JSON: { \"de\": { htmlContent, subject }, ... }\n}\n\n\u002F\u002F Translations structure\n{\n  \"de\": {\n    \"subject\": \"German subject\",\n    \"previewText\": \"German preview\",\n    \"blocks\": { \u002F* text content overrides *\u002F }\n  }\n}\n",[33,1783,1784,1793,1798,1808,1820,1832,1836,1841,1856,1868,1872,1877,1889,1901,1905,1909,1914,1919,1927,1940,1952,1966,1971],{"__ignoreMap":132},[136,1785,1786,1788,1791],{"class":138,"line":139},[136,1787,1009],{"class":366},[136,1789,1790],{"class":874}," EmailTemplate",[136,1792,514],{"class":142},[136,1794,1795],{"class":138,"line":153},[136,1796,1797],{"class":529},"  \u002F\u002F Default language content\n",[136,1799,1800,1803,1805],{"class":138,"line":162},[136,1801,1802],{"class":600},"  subject",[136,1804,169],{"class":366},[136,1806,1807],{"class":394}," string\n",[136,1809,1810,1813,1815,1817],{"class":138,"line":187},[136,1811,1812],{"class":600},"  content",[136,1814,169],{"class":366},[136,1816,1024],{"class":394},[136,1818,1819],{"class":529},"           \u002F\u002F JSON blocks\n",[136,1821,1822,1825,1827,1829],{"class":138,"line":205},[136,1823,1824],{"class":600},"  defaultLanguage",[136,1826,169],{"class":366},[136,1828,1024],{"class":394},[136,1830,1831],{"class":529},"   \u002F\u002F e.g., 'en'\n",[136,1833,1834],{"class":138,"line":223},[136,1835,347],{"emptyLinePlaceholder":346},[136,1837,1838],{"class":138,"line":242},[136,1839,1840],{"class":529},"  \u002F\u002F Translations\n",[136,1842,1843,1846,1848,1850,1853],{"class":138,"line":259},[136,1844,1845],{"class":600},"  supportedLanguages",[136,1847,169],{"class":366},[136,1849,1024],{"class":394},[136,1851,1852],{"class":142},"[]    ",[136,1854,1855],{"class":529},"\u002F\u002F ['en', 'de', 'fr']\n",[136,1857,1858,1861,1863,1865],{"class":138,"line":275},[136,1859,1860],{"class":600},"  translations",[136,1862,169],{"class":366},[136,1864,1024],{"class":394},[136,1866,1867],{"class":529},"            \u002F\u002F JSON of translations\n",[136,1869,1870],{"class":138,"line":292},[136,1871,347],{"emptyLinePlaceholder":346},[136,1873,1874],{"class":138,"line":310},[136,1875,1876],{"class":529},"  \u002F\u002F Pre-rendered HTML per language\n",[136,1878,1879,1882,1884,1886],{"class":138,"line":327},[136,1880,1881],{"class":600},"  htmlContent",[136,1883,169],{"class":366},[136,1885,1024],{"class":394},[136,1887,1888],{"class":529},"             \u002F\u002F Default language\n",[136,1890,1891,1894,1896,1898],{"class":138,"line":333},[136,1892,1893],{"class":600},"  htmlTranslations",[136,1895,169],{"class":366},[136,1897,1024],{"class":394},[136,1899,1900],{"class":529},"        \u002F\u002F JSON: { \"de\": { htmlContent, subject }, ... }\n",[136,1902,1903],{"class":138,"line":343},[136,1904,1057],{"class":142},[136,1906,1907],{"class":138,"line":350},[136,1908,347],{"emptyLinePlaceholder":346},[136,1910,1911],{"class":138,"line":363},[136,1912,1913],{"class":529},"\u002F\u002F Translations structure\n",[136,1915,1916],{"class":138,"line":383},[136,1917,1918],{"class":142},"{\n",[136,1920,1921,1924],{"class":138,"line":388},[136,1922,1923],{"class":376},"  \"de\"",[136,1925,1926],{"class":142},": {\n",[136,1928,1929,1932,1934,1937],{"class":138,"line":408},[136,1930,1931],{"class":376},"    \"subject\"",[136,1933,591],{"class":142},[136,1935,1936],{"class":376},"\"German subject\"",[136,1938,1939],{"class":142},",\n",[136,1941,1942,1945,1947,1950],{"class":138,"line":429},[136,1943,1944],{"class":376},"    \"previewText\"",[136,1946,591],{"class":142},[136,1948,1949],{"class":376},"\"German preview\"",[136,1951,1939],{"class":142},[136,1953,1954,1957,1960,1963],{"class":138,"line":447},[136,1955,1956],{"class":376},"    \"blocks\"",[136,1958,1959],{"class":142},": { ",[136,1961,1962],{"class":529},"\u002F* text content overrides *\u002F",[136,1964,1965],{"class":142}," }\n",[136,1967,1968],{"class":138,"line":466},[136,1969,1970],{"class":142},"  }\n",[136,1972,1973],{"class":138,"line":480},[136,1974,1057],{"class":142},[11,1976,1977,1980],{},[1567,1978,1979],{},"Wichtig",": Das Styling (Farben, Innenabstände, Bilder) ist für alle Sprachen identisch. Nur die Textinhalte unterscheiden sich je Sprache.",[18,1982,1984],{"id":1983},"abstraktion-der-e-mail-provider","Abstraktion der E-Mail-Provider",[11,1986,1987,1988,1991,1992,1996],{},"Die versandseitige Provider-Logik liegt in ",[33,1989,1990],{},"apps\u002Fapi\u002Fconvex\u002Flib\u002FsendProviders\u002F"," und folgt ",[1667,1993,1995],{"href":1994},"\u002Fdeveloper\u002Fdecisions","ADR-0020",". Die Schicht besteht aus vier beweglichen Teilen:",[1998,1999,2000,2006,2023,2036],"ol",{},[1564,2001,2002,2005],{},[1567,2003,2004],{},"Adapter"," — ein Modul als Objektliteral je Core-Kind, das der Katalog deklariert, dazu das generierte Modul jedes mitgelieferten Plugin-Transports; jedes führt genau einen Sendeversuch durch und klassifiziert seine eigenen Fehler.",[1564,2007,2008,1652,2011,2014,2015,2018,2019,2022],{},[1567,2009,2010],{},"Registry",[33,2012,2013],{},"SEND_PROVIDERS"," bildet einen ",[33,2016,2017],{},"SendProviderKind"," auf seinen Adapter ab; ",[33,2020,2021],{},"providerFor(kind)"," schlägt einen davon nach.",[1564,2024,2025,1652,2028,2031,2032,2035],{},[1567,2026,2027],{},"Routing",[33,2029,2030],{},"resolveRoute()"," liest die ",[33,2033,2034],{},"providerRoutes","-Konfiguration einer Organisation, wählt eine Strategie und liefert den zu verwendenden Provider zurück.",[1564,2037,2038,1652,2041,2044],{},[1567,2039,2040],{},"Dispatch",[33,2042,2043],{},"sendProviderDispatch()"," besitzt die Retry-Schleife und schreibt nach jedem terminalen Ergebnis den Gesundheitszustand des jeweiligen Providers.",[38,2046,2048],{"id":2047},"adapter-interface","Adapter-Interface",[11,2050,2051,2052,2055,2056,2059,2060,2063,2064,2067],{},"Jeder Provider implementiert ",[33,2053,2054],{},"SendProviderModule\u003CK>"," aus ",[33,2057,2058],{},"lib\u002FsendProviders\u002Ftypes.ts",". Es gibt weder ",[33,2061,2062],{},"sendBatch"," noch ",[33,2065,2066],{},"getProviderName"," — das Modul ist ein einzelner Sendeversuch plus Fehlerkategorisierung, den Rest übernimmt der Dispatch-Helfer.",[127,2069,2071],{"className":862,"code":2070,"language":864,"meta":132,"style":132},"\u002F\u002F The kind union is DERIVED, not written: there is no \"declare the kind\" step.\n\u002F\u002F `lib\u002FsendProviders\u002FcatalogTypes.ts`, re-exported from `types.ts`:\ntype SendProviderKind = CoreSendProviderKind | PluginSendTransportKind;\n\u002F\u002F …and the core half is the catalog literal itself\n\u002F\u002F (`packages\u002Fshared\u002Fsrc\u002FsendProviderCatalog.ts`):\ntype CoreSendProviderKind = (typeof CORE_SEND_PROVIDER_CATALOG)[number]['kind'];\n\n\u002F\u002F lib\u002FsendProviders\u002Ftypes.ts\ninterface SendProviderModule\u003CK extends SendProviderKind> {\n    readonly kind: K;\n    \u002F** Backoff schedule consumed by the dispatch helper (the module never retries). *\u002F\n    readonly retryDelays: readonly number[];\n    \u002F** One attempt. No internal retry. *\u002F\n    sendEmail(params: EmailSendParams, extras?: ExtrasFor\u003CK>): Promise\u003CEmailSendAttempt>;\n    \u002F** Map a raw provider error string (+ optional HTTP status) to a typed code. *\u002F\n    categorizeError(message: string, httpStatus?: number): EmailErrorCode;\n}\n\ninterface EmailSendParams {\n    to: string;\n    from: string;\n    subject: string;\n    html: string;\n    replyTo?: string;\n    headers?: Record\u003Cstring, string>;\n    attachments?: EmailAttachment[];\n}\n\ninterface EmailAttachment {\n    filename: string;\n    content: Buffer; \u002F\u002F raw binary, not a base64 string or URL\n    contentType?: string; \u002F\u002F defaults to application\u002Foctet-stream\n}\n",[33,2072,2073,2078,2083,2102,2107,2112,2143,2147,2152,2172,2187,2192,2208,2213,2257,2262,2295,2299,2303,2311,2322,2333,2344,2354,2365,2385,2397,2401,2405,2413,2424,2438,2452],{"__ignoreMap":132},[136,2074,2075],{"class":138,"line":139},[136,2076,2077],{"class":529},"\u002F\u002F The kind union is DERIVED, not written: there is no \"declare the kind\" step.\n",[136,2079,2080],{"class":138,"line":153},[136,2081,2082],{"class":529},"\u002F\u002F `lib\u002FsendProviders\u002FcatalogTypes.ts`, re-exported from `types.ts`:\n",[136,2084,2085,2087,2090,2092,2095,2097,2100],{"class":138,"line":162},[136,2086,871],{"class":366},[136,2088,2089],{"class":874}," SendProviderKind",[136,2091,398],{"class":366},[136,2093,2094],{"class":874}," CoreSendProviderKind",[136,2096,1103],{"class":366},[136,2098,2099],{"class":874}," PluginSendTransportKind",[136,2101,380],{"class":142},[136,2103,2104],{"class":138,"line":187},[136,2105,2106],{"class":529},"\u002F\u002F …and the core half is the catalog literal itself\n",[136,2108,2109],{"class":138,"line":205},[136,2110,2111],{"class":529},"\u002F\u002F (`packages\u002Fshared\u002Fsrc\u002FsendProviderCatalog.ts`):\n",[136,2113,2114,2116,2118,2120,2122,2125,2128,2131,2134,2137,2140],{"class":138,"line":223},[136,2115,871],{"class":366},[136,2117,2094],{"class":874},[136,2119,398],{"class":366},[136,2121,597],{"class":142},[136,2123,2124],{"class":366},"typeof",[136,2126,2127],{"class":394}," CORE_SEND_PROVIDER_CATALOG",[136,2129,2130],{"class":142},")[",[136,2132,2133],{"class":394},"number",[136,2135,2136],{"class":142},"][",[136,2138,2139],{"class":376},"'kind'",[136,2141,2142],{"class":142},"];\n",[136,2144,2145],{"class":138,"line":242},[136,2146,347],{"emptyLinePlaceholder":346},[136,2148,2149],{"class":138,"line":259},[136,2150,2151],{"class":529},"\u002F\u002F lib\u002FsendProviders\u002Ftypes.ts\n",[136,2153,2154,2156,2159,2161,2164,2167,2169],{"class":138,"line":275},[136,2155,1009],{"class":366},[136,2157,2158],{"class":874}," SendProviderModule",[136,2160,143],{"class":142},[136,2162,2163],{"class":874},"K",[136,2165,2166],{"class":366}," extends",[136,2168,2089],{"class":874},[136,2170,2171],{"class":142},"> {\n",[136,2173,2174,2177,2180,2182,2185],{"class":138,"line":292},[136,2175,2176],{"class":366},"    readonly",[136,2178,2179],{"class":600}," kind",[136,2181,169],{"class":366},[136,2183,2184],{"class":874}," K",[136,2186,380],{"class":142},[136,2188,2189],{"class":138,"line":310},[136,2190,2191],{"class":529},"    \u002F** Backoff schedule consumed by the dispatch helper (the module never retries). *\u002F\n",[136,2193,2194,2196,2199,2201,2204,2206],{"class":138,"line":327},[136,2195,2176],{"class":366},[136,2197,2198],{"class":600}," retryDelays",[136,2200,169],{"class":366},[136,2202,2203],{"class":366}," readonly",[136,2205,1128],{"class":394},[136,2207,1204],{"class":142},[136,2209,2210],{"class":138,"line":333},[136,2211,2212],{"class":529},"    \u002F** One attempt. No internal retry. *\u002F\n",[136,2214,2215,2218,2220,2222,2224,2227,2229,2232,2234,2237,2239,2241,2244,2246,2249,2251,2254],{"class":138,"line":343},[136,2216,2217],{"class":401},"    sendEmail",[136,2219,420],{"class":142},[136,2221,637],{"class":600},[136,2223,169],{"class":366},[136,2225,2226],{"class":874}," EmailSendParams",[136,2228,526],{"class":142},[136,2230,2231],{"class":600},"extras",[136,2233,1149],{"class":366},[136,2235,2236],{"class":874}," ExtrasFor",[136,2238,143],{"class":142},[136,2240,2163],{"class":874},[136,2242,2243],{"class":142},">)",[136,2245,169],{"class":366},[136,2247,2248],{"class":874}," Promise",[136,2250,143],{"class":142},[136,2252,2253],{"class":874},"EmailSendAttempt",[136,2255,2256],{"class":142},">;\n",[136,2258,2259],{"class":138,"line":350},[136,2260,2261],{"class":529},"    \u002F** Map a raw provider error string (+ optional HTTP status) to a typed code. *\u002F\n",[136,2263,2264,2267,2269,2272,2274,2276,2278,2281,2283,2285,2288,2290,2293],{"class":138,"line":363},[136,2265,2266],{"class":401},"    categorizeError",[136,2268,420],{"class":142},[136,2270,2271],{"class":600},"message",[136,2273,169],{"class":366},[136,2275,1024],{"class":394},[136,2277,526],{"class":142},[136,2279,2280],{"class":600},"httpStatus",[136,2282,1149],{"class":366},[136,2284,1128],{"class":394},[136,2286,2287],{"class":142},")",[136,2289,169],{"class":366},[136,2291,2292],{"class":874}," EmailErrorCode",[136,2294,380],{"class":142},[136,2296,2297],{"class":138,"line":383},[136,2298,1057],{"class":142},[136,2300,2301],{"class":138,"line":388},[136,2302,347],{"emptyLinePlaceholder":346},[136,2304,2305,2307,2309],{"class":138,"line":408},[136,2306,1009],{"class":366},[136,2308,2226],{"class":874},[136,2310,514],{"class":142},[136,2312,2313,2316,2318,2320],{"class":138,"line":429},[136,2314,2315],{"class":600},"    to",[136,2317,169],{"class":366},[136,2319,1024],{"class":394},[136,2321,380],{"class":142},[136,2323,2324,2327,2329,2331],{"class":138,"line":447},[136,2325,2326],{"class":600},"    from",[136,2328,169],{"class":366},[136,2330,1024],{"class":394},[136,2332,380],{"class":142},[136,2334,2335,2338,2340,2342],{"class":138,"line":466},[136,2336,2337],{"class":600},"    subject",[136,2339,169],{"class":366},[136,2341,1024],{"class":394},[136,2343,380],{"class":142},[136,2345,2346,2348,2350,2352],{"class":138,"line":480},[136,2347,1084],{"class":600},[136,2349,169],{"class":366},[136,2351,1024],{"class":394},[136,2353,380],{"class":142},[136,2355,2356,2359,2361,2363],{"class":138,"line":499},[136,2357,2358],{"class":600},"    replyTo",[136,2360,1149],{"class":366},[136,2362,1024],{"class":394},[136,2364,380],{"class":142},[136,2366,2367,2370,2372,2375,2377,2379,2381,2383],{"class":138,"line":504},[136,2368,2369],{"class":600},"    headers",[136,2371,1149],{"class":366},[136,2373,2374],{"class":874}," Record",[136,2376,143],{"class":142},[136,2378,763],{"class":394},[136,2380,526],{"class":142},[136,2382,763],{"class":394},[136,2384,2256],{"class":142},[136,2386,2387,2390,2392,2395],{"class":138,"line":517},[136,2388,2389],{"class":600},"    attachments",[136,2391,1149],{"class":366},[136,2393,2394],{"class":874}," EmailAttachment",[136,2396,1204],{"class":142},[136,2398,2399],{"class":138,"line":533},[136,2400,1057],{"class":142},[136,2402,2403],{"class":138,"line":547},[136,2404,347],{"emptyLinePlaceholder":346},[136,2406,2407,2409,2411],{"class":138,"line":553},[136,2408,1009],{"class":366},[136,2410,2394],{"class":874},[136,2412,514],{"class":142},[136,2414,2415,2418,2420,2422],{"class":138,"line":558},[136,2416,2417],{"class":600},"    filename",[136,2419,169],{"class":366},[136,2421,1024],{"class":394},[136,2423,380],{"class":142},[136,2425,2426,2428,2430,2433,2435],{"class":138,"line":564},[136,2427,1042],{"class":600},[136,2429,169],{"class":366},[136,2431,2432],{"class":874}," Buffer",[136,2434,702],{"class":142},[136,2436,2437],{"class":529},"\u002F\u002F raw binary, not a base64 string or URL\n",[136,2439,2440,2443,2445,2447,2449],{"class":138,"line":570},[136,2441,2442],{"class":600},"    contentType",[136,2444,1149],{"class":366},[136,2446,1024],{"class":394},[136,2448,702],{"class":142},[136,2450,2451],{"class":529},"\u002F\u002F defaults to application\u002Foctet-stream\n",[136,2453,2454],{"class":138,"line":576},[136,2455,1057],{"class":142},[11,2457,2458,2459,2461,2462,2465,2466,597,2469,526,2472,526,2475,526,2478,2481,2482,597,2485,2488,2489,2492],{},"Das zweite Argument ",[33,2460,2231],{}," ist je Provider über ",[33,2463,2464],{},"ExtrasFor\u003CK>"," typisiert. Die MTA verwendet ",[33,2467,2468],{},"MtaExtras",[33,2470,2471],{},"messageId",[33,2473,2474],{},"ipPool",[33,2476,2477],{},"engagementScore",[33,2479,2480],{},"dkimDomain",", gesteuerte Organisation\u002FNachrichtentyp\u002FRouting-Lease oder den expliziten System-Intake-Pfad), Resend verwendet ",[33,2483,2484],{},"ResendExtras",[33,2486,2487],{},"idempotencyKey",", weitergereicht als Header ",[33,2490,2491],{},"Idempotency-Key","); SES nimmt keine Extras entgegen.",[38,2494,2496],{"id":2495},"sendeergebnis-fehlercodes","Sendeergebnis & Fehlercodes",[11,2498,2499,2500,2502,2503,2506],{},"Ein einzelner Versuch liefert die Discriminated Union ",[33,2501,2253],{}," zurück — die Form ",[33,2504,2505],{},"{ success, id?, error? }"," gibt es nicht mehr:",[127,2508,2510],{"className":862,"code":2509,"language":864,"meta":132,"style":132},"type EmailSendAttempt =\n    | { success: true; id: string }\n    | { success: false; errorMessage: string; errorCode: EmailErrorCode };\n\nenum EmailErrorCode {\n    RATE_LIMIT = 'RATE_LIMIT', \u002F\u002F retryable\n    SERVER_ERROR = 'SERVER_ERROR', \u002F\u002F retryable\n    INVALID_RECIPIENT = 'INVALID_RECIPIENT',\n    INVALID_SENDER = 'INVALID_SENDER',\n    AUTH_FAILED = 'AUTH_FAILED',\n    CONTENT_REJECTED = 'CONTENT_REJECTED',\n    UNKNOWN = 'UNKNOWN',\n}\n",[33,2511,2512,2521,2547,2581,2585,2594,2609,2623,2635,2647,2659,2671,2683],{"__ignoreMap":132},[136,2513,2514,2516,2519],{"class":138,"line":139},[136,2515,871],{"class":366},[136,2517,2518],{"class":874}," EmailSendAttempt",[136,2520,878],{"class":366},[136,2522,2523,2525,2528,2531,2533,2536,2538,2541,2543,2545],{"class":138,"line":153},[136,2524,883],{"class":366},[136,2526,2527],{"class":142}," { ",[136,2529,2530],{"class":600},"success",[136,2532,169],{"class":366},[136,2534,2535],{"class":394}," true",[136,2537,702],{"class":142},[136,2539,2540],{"class":600},"id",[136,2542,169],{"class":366},[136,2544,1024],{"class":394},[136,2546,1965],{"class":142},[136,2548,2549,2551,2553,2555,2557,2560,2562,2565,2567,2569,2571,2574,2576,2578],{"class":138,"line":162},[136,2550,883],{"class":366},[136,2552,2527],{"class":142},[136,2554,2530],{"class":600},[136,2556,169],{"class":366},[136,2558,2559],{"class":394}," false",[136,2561,702],{"class":142},[136,2563,2564],{"class":600},"errorMessage",[136,2566,169],{"class":366},[136,2568,1024],{"class":394},[136,2570,702],{"class":142},[136,2572,2573],{"class":600},"errorCode",[136,2575,169],{"class":366},[136,2577,2292],{"class":874},[136,2579,2580],{"class":142}," };\n",[136,2582,2583],{"class":138,"line":187},[136,2584,347],{"emptyLinePlaceholder":346},[136,2586,2587,2590,2592],{"class":138,"line":205},[136,2588,2589],{"class":366},"enum",[136,2591,2292],{"class":874},[136,2593,514],{"class":142},[136,2595,2596,2599,2601,2604,2606],{"class":138,"line":223},[136,2597,2598],{"class":394},"    RATE_LIMIT",[136,2600,398],{"class":366},[136,2602,2603],{"class":376}," 'RATE_LIMIT'",[136,2605,526],{"class":142},[136,2607,2608],{"class":529},"\u002F\u002F retryable\n",[136,2610,2611,2614,2616,2619,2621],{"class":138,"line":242},[136,2612,2613],{"class":394},"    SERVER_ERROR",[136,2615,398],{"class":366},[136,2617,2618],{"class":376}," 'SERVER_ERROR'",[136,2620,526],{"class":142},[136,2622,2608],{"class":529},[136,2624,2625,2628,2630,2633],{"class":138,"line":259},[136,2626,2627],{"class":394},"    INVALID_RECIPIENT",[136,2629,398],{"class":366},[136,2631,2632],{"class":376}," 'INVALID_RECIPIENT'",[136,2634,1939],{"class":142},[136,2636,2637,2640,2642,2645],{"class":138,"line":275},[136,2638,2639],{"class":394},"    INVALID_SENDER",[136,2641,398],{"class":366},[136,2643,2644],{"class":376}," 'INVALID_SENDER'",[136,2646,1939],{"class":142},[136,2648,2649,2652,2654,2657],{"class":138,"line":292},[136,2650,2651],{"class":394},"    AUTH_FAILED",[136,2653,398],{"class":366},[136,2655,2656],{"class":376}," 'AUTH_FAILED'",[136,2658,1939],{"class":142},[136,2660,2661,2664,2666,2669],{"class":138,"line":310},[136,2662,2663],{"class":394},"    CONTENT_REJECTED",[136,2665,398],{"class":366},[136,2667,2668],{"class":376}," 'CONTENT_REJECTED'",[136,2670,1939],{"class":142},[136,2672,2673,2676,2678,2681],{"class":138,"line":327},[136,2674,2675],{"class":394},"    UNKNOWN",[136,2677,398],{"class":366},[136,2679,2680],{"class":376}," 'UNKNOWN'",[136,2682,1939],{"class":142},[136,2684,2685],{"class":138,"line":333},[136,2686,1057],{"class":142},[11,2688,2689,2692,2693,699,2696,2699],{},[33,2690,2691],{},"isRetryableErrorCode(code)"," ist das Retry-Prädikat: Nur ",[33,2694,2695],{},"RATE_LIMIT",[33,2697,2698],{},"SERVER_ERROR"," werden wiederholt, alles andere ist terminal.",[38,2701,2703],{"id":2702},"registry-dispatch","Registry & Dispatch",[11,2705,2706,2707,2710,2711,2714],{},"Die Providerauswahl ist kein ",[33,2708,2709],{},"switch"," über eine Umgebungsvariable mehr. Die Registry bildet jedes Kind auf seinen Adapter ab, und ",[33,2712,2713],{},"providerFor()"," löst ihn auf:",[127,2716,2718],{"className":862,"code":2717,"language":864,"meta":132,"style":132},"\u002F\u002F lib\u002FsendProviders\u002Findex.ts\nexport const SEND_PROVIDERS = {\n    mta: mtaSendProvider,\n    ses: sesSendProvider,\n    resend: resendSendProvider,\n} as const;\n\nexport function providerFor\u003CK extends SendProviderKind>(kind: K): SendProviderModule\u003CK> {\n    \u002F* ... *\u002F\n}\n",[33,2719,2720,2725,2740,2745,2750,2755,2767,2771,2811,2816],{"__ignoreMap":132},[136,2721,2722],{"class":138,"line":139},[136,2723,2724],{"class":529},"\u002F\u002F lib\u002FsendProviders\u002Findex.ts\n",[136,2726,2727,2730,2733,2736,2738],{"class":138,"line":153},[136,2728,2729],{"class":366},"export",[136,2731,2732],{"class":366}," const",[136,2734,2735],{"class":394}," SEND_PROVIDERS",[136,2737,398],{"class":366},[136,2739,514],{"class":142},[136,2741,2742],{"class":138,"line":162},[136,2743,2744],{"class":142},"    mta: mtaSendProvider,\n",[136,2746,2747],{"class":138,"line":187},[136,2748,2749],{"class":142},"    ses: sesSendProvider,\n",[136,2751,2752],{"class":138,"line":205},[136,2753,2754],{"class":142},"    resend: resendSendProvider,\n",[136,2756,2757,2760,2763,2765],{"class":138,"line":223},[136,2758,2759],{"class":142},"} ",[136,2761,2762],{"class":366},"as",[136,2764,2732],{"class":366},[136,2766,380],{"class":142},[136,2768,2769],{"class":138,"line":242},[136,2770,347],{"emptyLinePlaceholder":346},[136,2772,2773,2775,2778,2781,2783,2785,2787,2789,2792,2795,2797,2799,2801,2803,2805,2807,2809],{"class":138,"line":259},[136,2774,2729],{"class":366},[136,2776,2777],{"class":366}," function",[136,2779,2780],{"class":401}," providerFor",[136,2782,143],{"class":142},[136,2784,2163],{"class":874},[136,2786,2166],{"class":366},[136,2788,2089],{"class":874},[136,2790,2791],{"class":142},">(",[136,2793,2794],{"class":600},"kind",[136,2796,169],{"class":366},[136,2798,2184],{"class":874},[136,2800,2287],{"class":142},[136,2802,169],{"class":366},[136,2804,2158],{"class":874},[136,2806,143],{"class":142},[136,2808,2163],{"class":874},[136,2810,2171],{"class":142},[136,2812,2813],{"class":138,"line":275},[136,2814,2815],{"class":529},"    \u002F* ... *\u002F\n",[136,2817,2818],{"class":138,"line":292},[136,2819,1057],{"class":142},[11,2821,2822,2823,169],{},"Alle Produzenten — der Workpool-Worker, der Testversand des Kampagnen-Orchestrators, der Nachversand nach dem Senden, der E-Mail-Schritt in Automationen und der transaktionale HTTP-Versand — laufen über einen einzigen Einstiegspunkt, ",[33,2824,2043],{},[127,2826,2828],{"className":862,"code":2827,"language":864,"meta":132,"style":132},"\u002F\u002F lib\u002FsendProviders\u002Fdispatch.ts\nexport async function sendProviderDispatch\u003CK extends SendProviderKind>(\n    ctx: ActionCtx,\n    kind: K,\n    params: EmailSendParams,\n    extras?: ExtrasFor\u003CK>\n): Promise\u003CDispatchResult>;\n",[33,2829,2830,2835,2858,2870,2881,2892,2907],{"__ignoreMap":132},[136,2831,2832],{"class":138,"line":139},[136,2833,2834],{"class":529},"\u002F\u002F lib\u002FsendProviders\u002Fdispatch.ts\n",[136,2836,2837,2839,2842,2844,2847,2849,2851,2853,2855],{"class":138,"line":153},[136,2838,2729],{"class":366},[136,2840,2841],{"class":366}," async",[136,2843,2777],{"class":366},[136,2845,2846],{"class":401}," sendProviderDispatch",[136,2848,143],{"class":142},[136,2850,2163],{"class":874},[136,2852,2166],{"class":366},[136,2854,2089],{"class":874},[136,2856,2857],{"class":142},">(\n",[136,2859,2860,2863,2865,2868],{"class":138,"line":162},[136,2861,2862],{"class":600},"    ctx",[136,2864,169],{"class":366},[136,2866,2867],{"class":874}," ActionCtx",[136,2869,1939],{"class":142},[136,2871,2872,2875,2877,2879],{"class":138,"line":187},[136,2873,2874],{"class":600},"    kind",[136,2876,169],{"class":366},[136,2878,2184],{"class":874},[136,2880,1939],{"class":142},[136,2882,2883,2886,2888,2890],{"class":138,"line":205},[136,2884,2885],{"class":600},"    params",[136,2887,169],{"class":366},[136,2889,2226],{"class":874},[136,2891,1939],{"class":142},[136,2893,2894,2897,2899,2901,2903,2905],{"class":138,"line":223},[136,2895,2896],{"class":600},"    extras",[136,2898,1149],{"class":366},[136,2900,2236],{"class":874},[136,2902,143],{"class":142},[136,2904,2163],{"class":874},[136,2906,150],{"class":142},[136,2908,2909,2911,2913,2915,2917,2920],{"class":138,"line":242},[136,2910,2287],{"class":142},[136,2912,169],{"class":366},[136,2914,2248],{"class":874},[136,2916,143],{"class":142},[136,2918,2919],{"class":874},"DispatchResult",[136,2921,2256],{"class":142},[11,2923,2924],{},"Der Dispatch-Helfer:",[1998,2926,2927,2942,2949],{},[1564,2928,2929,2930,2933,2934,2936,2937,1770,2939,2941],{},"Führt die Retry-Schleife aus, gesteuert von ",[33,2931,2932],{},"module.retryDelays"," und dem typisierten ",[33,2935,2573],{}," (wiederholt ",[33,2938,2695],{},[33,2940,2698],{},", gibt ansonsten oder beim letzten Versuch auf).",[1564,2943,2944,2945,2948],{},"Plant nach jedem terminalen Ergebnis (Erfolg oder erschöpfte Retries) ",[33,2946,2947],{},"recordSendResult"," ein, um den Gesundheitszustand dieses Providers zu aktualisieren.",[1564,2950,2951,2952,2954,2955,526,2958,699,2961,2964],{},"Liefert ein ",[33,2953,2919],{}," mit dem finalen Versuch, ",[33,2956,2957],{},"providerType",[33,2959,2960],{},"latencyMs",[33,2962,2963],{},"attempts"," zurück.",[1527,2966,2968],{"type":2967},"info",[11,2969,2970,2971,2974,2975,2977,2978,2980,2981,2984],{},"Die Umgebungsvariable ",[33,2972,2973],{},"EMAIL_PROVIDER"," ist lediglich der instanzweite Fallback und benennt selbst kein eigenes Kind: Sie wird von ",[33,2976,2030],{}," herangezogen, wenn eine Organisation keine ",[33,2979,2034],{},"-Konfiguration hat, keine Provider aktiviert sind oder die gewählte Strategie nichts zurückgibt — siehe „Routing“ weiter unten. Sie ist kein harter Schalter für die Providerauswahl mehr, und wenn auch sie nicht gesetzt ist, löst die Route zu ",[33,2982,2983],{},"null"," auf (fail-closed) statt zur MTA.",[38,2986,2988],{"id":2987},"routing-strategien","Routing-Strategien",[11,2990,2991,2994,2995,2031,2998,3000,3001,3004,3005,3008,3009,3011,3012,3014,3015,2055,3018,3021,3022,3024,3025,3008,3027,3030,3031,3034,3035,3037,3038,3041],{},[33,2992,2993],{},"resolveRoute(routeConfig, healthStatuses)"," in ",[33,2996,2997],{},"lib\u002FsendProviders\u002Frouting.ts",[33,2999,2034],{},"-Zeile einer Organisation, filtert auf aktivierte und bekannte Provider, schlägt über ",[33,3002,3003],{},"strategyFor()"," eine Strategie nach und gibt eine ",[33,3006,3007],{},"ResolvedRoute"," zurück (",[33,3010,2957],{},", optional ",[33,3013,2474],{}," und ein ",[33,3016,3017],{},"source",[33,3019,3020],{},"org_config | env_fallback | deliverability_fallback","). Löst keine ",[33,3023,2034],{},"-Konfiguration einen Provider auf, greift die Funktion auf die Umgebungsvariable ",[33,3026,2973],{},[33,3028,3029],{},"source: env_fallback","); ist die Variable nicht gesetzt oder unbekannt, liefert ",[33,3032,3033],{},"resolveRoute"," ",[33,3036,2983],{}," (fail-closed) — es gibt keinen impliziten ",[33,3039,3040],{},"mta","-Standard.",[43,3043,3044,3057],{},[46,3045,3046],{},[49,3047,3048,3051,3054],{},[52,3049,3050],{},"Strategie",[52,3052,3053],{},"Verhalten",[52,3055,3056],{},"Quelle",[59,3058,3059,3074,3093,3111],{},[49,3060,3061,3066,3069],{},[64,3062,3063],{},[33,3064,3065],{},"single",[64,3067,3068],{},"Verwendet immer den ersten aktivierten Provider; ignoriert den Gesundheitszustand.",[64,3070,3071],{},[33,3072,3073],{},"strategies\u002Fsingle\u002F",[49,3075,3076,3081,3088],{},[64,3077,3078],{},[33,3079,3080],{},"priority_failover",[64,3082,3083,3084,3087],{},"Geht die aktivierten Provider der Reihe nach durch und wählt den ersten, der aktuell nicht ",[33,3085,3086],{},"down"," ist. Fällt auf den ersten aktivierten Provider zurück, wenn alle down sind oder keine Gesundheitsdaten vorliegen.",[64,3089,3090],{},[33,3091,3092],{},"strategies\u002Fpriority_failover\u002F",[49,3094,3095,3100,3106],{},[64,3096,3097],{},[33,3098,3099],{},"workload_split",[64,3101,3102,3103,3105],{},"Gewichtet-zufällige Auswahl unter den aktivierten Providern, wobei ",[33,3104,3086],{},"-Provider ausgeschlossen werden (Gewichte standardmäßig 100). Ist jeder Provider down, wird trotzdem aus der vollen Menge gewählt, damit der Versand hinausgeht.",[64,3107,3108],{},[33,3109,3110],{},"strategies\u002Fworkload_split\u002F",[49,3112,3113,3118,3121],{},[64,3114,3115],{},[33,3116,3117],{},"adaptive_mix",[64,3119,3120],{},"Deterministische Aufteilung je Empfänger zwischen der eigenen MTA und dem Referenztransport gemäß dem Zellenanteil des Ramp-Controllers. Gehört dem Controller — wird vom Controller geschrieben und in der Strategieauswahl des Betreibers nie angeboten.",[64,3122,3123],{},[33,3124,3125],{},"strategies\u002Fadaptive_mix\u002F",[11,3127,3128,3129,3132,3133,3135,3136,1671],{},"Jede Strategie ist eine reine Funktion ",[33,3130,3131],{},"select(entries, ipPool, healthStatuses, mix)",". Das vierte Argument ist der Mix-Kontext je Empfänger; nur ",[33,3134,3117],{}," liest ihn, die drei ausgelieferten Strategien ignorieren ihn. Eine Strategie hinzuzufügen ist eine Änderung in genau einem Ordner unter ",[33,3137,3138],{},"lib\u002FsendProviders\u002Fstrategies\u002F",[38,3140,3142],{"id":3141},"provider-gesundheit","Provider-Gesundheit",[11,3144,3145,3148,3149,3152,3153,3155,3156,3158,3159,3162],{},[33,3146,3147],{},"lib\u002FsendProviders\u002Fhealth.ts"," schreibt Versandergebnisse in die Tabelle ",[33,3150,3151],{},"providerHealth"," (eine Zeile je Provider-Kind). Der Dispatch-Helfer ist der einzige Schreiber (über ",[33,3154,2947],{},"), und ",[33,3157,2030],{}," ist der einzige Leser des Snapshots über alle Provider (",[33,3160,3161],{},"getAllProviderHealth","). Jeder Datensatz führt einen abklingenden Zähler für Erfolge\u002FFehlschläge, eine gleitende Durchschnittslatenz und einen aus Schwellenwerten abgeleiteten Status:",[43,3164,3165,3175],{},[46,3166,3167],{},[49,3168,3169,3172],{},[52,3170,3171],{},"Status",[52,3173,3174],{},"Bedingung",[59,3176,3177,3187,3197],{},[49,3178,3179,3184],{},[64,3180,3181],{},[33,3182,3183],{},"healthy",[64,3185,3186],{},"Erfolgsquote ≥ 90 %",[49,3188,3189,3194],{},[64,3190,3191],{},[33,3192,3193],{},"degraded",[64,3195,3196],{},"50 % ≤ Erfolgsquote \u003C 90 %",[49,3198,3199,3203],{},[64,3200,3201],{},[33,3202,3086],{},[64,3204,3205],{},"Erfolgsquote \u003C 50 % oder ≥ 5 aufeinanderfolgende Fehlschläge",[11,3207,3208,3209,699,3211,3213,3214,3216],{},"Die Strategien ",[33,3210,3080],{},[33,3212,3099],{}," ziehen diese Status heran, um Traffic von einem ",[33,3215,3086],{},"-Provider wegzulenken.",[38,3218,3220],{"id":3219},"mta-provider","MTA-Provider",[11,3222,3223,3224,3227,3228,3231,3232,3235,3236,699,3239,3242,3243,1671],{},"Der Standardprovider versendet über den Owlat-MTA-Dienst statt über eine Drittanbieter-API: Der Adapter schickt per POST einen E-Mail-Job an den HTTP-Endpunkt ",[33,3225,3226],{},"\u002Fsend"," der MTA, die Queuing, Rate Limiting, DKIM-Signierung und MX-Zustellung übernimmt. Es handelt sich um ein einfaches Objekt, ",[33,3229,3230],{},"mtaSendProvider",", in ",[33,3233,3234],{},"lib\u002FsendProviders\u002Fmta\u002Findex.ts",". Die Konfiguration stammt aus den Umgebungsvariablen ",[33,3237,3238],{},"MTA_API_URL",[33,3240,3241],{},"MTA_API_KEY"," (nicht aus Konstruktorfeldern); eine fehlende Variable führt zu einem fehlgeschlagenen Versuch mit ",[33,3244,3245],{},"AUTH_FAILED",[127,3247,3249],{"className":862,"code":3248,"language":864,"meta":132,"style":132},"\u002F\u002F lib\u002FsendProviders\u002Fmta\u002Findex.ts\nexport const mtaSendProvider: SendProviderModule\u003C'mta'> = {\n    kind: 'mta',\n    retryDelays: [1000, 5000], \u002F\u002F consumed by the dispatch helper\n    async sendEmail(params, extras) {\n        \u002F\u002F POST { messageId, to, from, subject, html, ipPool, engagementScore,\n        \u002F\u002F        dkimDomain, ... } to `${MTA_API_URL}\u002Fsend` with a 30s timeout,\n        \u002F\u002F returning { success: true, id } or a failed EmailSendAttempt.\n    },\n    categorizeError(message, httpStatus) {\n        \u002F* 429 → RATE_LIMIT, 5xx → SERVER_ERROR, ... *\u002F\n    },\n};\n",[33,3250,3251,3256,3281,3290,3309,3328,3333,3338,3343,3347,3361,3366,3370],{"__ignoreMap":132},[136,3252,3253],{"class":138,"line":139},[136,3254,3255],{"class":529},"\u002F\u002F lib\u002FsendProviders\u002Fmta\u002Findex.ts\n",[136,3257,3258,3260,3262,3265,3267,3269,3271,3274,3277,3279],{"class":138,"line":153},[136,3259,2729],{"class":366},[136,3261,2732],{"class":366},[136,3263,3264],{"class":394}," mtaSendProvider",[136,3266,169],{"class":366},[136,3268,2158],{"class":874},[136,3270,143],{"class":142},[136,3272,3273],{"class":376},"'mta'",[136,3275,3276],{"class":142},"> ",[136,3278,175],{"class":366},[136,3280,514],{"class":142},[136,3282,3283,3286,3288],{"class":138,"line":162},[136,3284,3285],{"class":142},"    kind: ",[136,3287,3273],{"class":376},[136,3289,1939],{"class":142},[136,3291,3292,3295,3298,3300,3303,3306],{"class":138,"line":187},[136,3293,3294],{"class":142},"    retryDelays: [",[136,3296,3297],{"class":394},"1000",[136,3299,526],{"class":142},[136,3301,3302],{"class":394},"5000",[136,3304,3305],{"class":142},"], ",[136,3307,3308],{"class":529},"\u002F\u002F consumed by the dispatch helper\n",[136,3310,3311,3314,3317,3319,3321,3323,3325],{"class":138,"line":205},[136,3312,3313],{"class":366},"    async",[136,3315,3316],{"class":401}," sendEmail",[136,3318,420],{"class":142},[136,3320,637],{"class":600},[136,3322,526],{"class":142},[136,3324,2231],{"class":600},[136,3326,3327],{"class":142},") {\n",[136,3329,3330],{"class":138,"line":223},[136,3331,3332],{"class":529},"        \u002F\u002F POST { messageId, to, from, subject, html, ipPool, engagementScore,\n",[136,3334,3335],{"class":138,"line":242},[136,3336,3337],{"class":529},"        \u002F\u002F        dkimDomain, ... } to `${MTA_API_URL}\u002Fsend` with a 30s timeout,\n",[136,3339,3340],{"class":138,"line":259},[136,3341,3342],{"class":529},"        \u002F\u002F returning { success: true, id } or a failed EmailSendAttempt.\n",[136,3344,3345],{"class":138,"line":275},[136,3346,674],{"class":142},[136,3348,3349,3351,3353,3355,3357,3359],{"class":138,"line":292},[136,3350,2266],{"class":401},[136,3352,420],{"class":142},[136,3354,2271],{"class":600},[136,3356,526],{"class":142},[136,3358,2280],{"class":600},[136,3360,3327],{"class":142},[136,3362,3363],{"class":138,"line":310},[136,3364,3365],{"class":529},"        \u002F* 429 → RATE_LIMIT, 5xx → SERVER_ERROR, ... *\u002F\n",[136,3367,3368],{"class":138,"line":327},[136,3369,674],{"class":142},[136,3371,3372],{"class":138,"line":333},[136,3373,550],{"class":142},[11,3375,3376,3379,3380,3382,3383,3385,3386,3388],{},[33,3377,3378],{},"categorizeError"," bildet zuerst nach HTTP-Status ab (429 → ",[33,3381,2695],{},", 5xx → ",[33,3384,2698],{},", 401\u002F403 → ",[33,3387,3245],{},") und danach über Teilstring-Abgleiche im Body.",[1527,3390,3392],{"type":1529,"title":3391},"Vollständige MTA-Dokumentation",[11,3393,3394,3395,1671],{},"Details zur Intelligence-Pipeline, zur Bounce-Verarbeitung, zum IP-Warming und zur Konfiguration finden Sie auf der Seite ",[1667,3396,3398],{"href":3397},"\u002Fdeveloper\u002Fmta-system","MTA System",[38,3400,3402],{"id":3401},"resend-provider","Resend-Provider",[11,3404,3405,597,3408,3411,3412,3415,3416,3419,3420,1770,3423,3426,3427,3430,3431,526,3433,3430,3436,3439,3440,3443,3444,1671],{},[33,3406,3407],{},"resendSendProvider",[33,3409,3410],{},"lib\u002FsendProviders\u002Fresend\u002Findex.ts",") versendet über das Resend-SDK mit einem Timeout von 30 Sekunden und einem lazy gecachten Client, der aus ",[33,3413,3414],{},"RESEND_API_KEY"," aufgebaut wird. Anhänge werden als ",[33,3417,3418],{},"{ filename, content, content_type }"," weitergereicht. Fehler werden anhand von ",[33,3421,3422],{},"error.name",[33,3424,3425],{},"statusCode"," von Resend klassifiziert (z. B. ",[33,3428,3429],{},"rate_limit_exceeded"," → ",[33,3432,2695],{},[33,3434,3435],{},"invalid_to_field",[33,3437,3438],{},"INVALID_RECIPIENT","). ",[33,3441,3442],{},"retryDelays"," ist ",[33,3445,3446],{},"[1000, 5000, 30000]",[38,3448,3450],{"id":3449},"ses-provider","SES-Provider",[11,3452,3453,597,3456,3459,3460,3463,3464,526,3467,699,3470,3473],{},[33,3454,3455],{},"sesSendProvider",[33,3457,3458],{},"lib\u002FsendProviders\u002Fses\u002Findex.ts",") versendet über das AWS-SDK mit einem lazy gecachten ",[33,3461,3462],{},"SESClient",", der aus ",[33,3465,3466],{},"AWS_SES_REGION",[33,3468,3469],{},"AWS_SES_ACCESS_KEY_ID",[33,3471,3472],{},"AWS_SES_SECRET_ACCESS_KEY"," aufgebaut wird. Es gibt zwei Sendepfade:",[1561,3475,3476,3485],{},[1564,3477,3478,1652,3481,3484],{},[1567,3479,3480],{},"Ohne Anhänge",[33,3482,3483],{},"SendEmailCommand"," mit dem HTML-Body.",[1564,3486,3487,1652,3490,3493,3494,3497],{},[1567,3488,3489],{},"Mit Anhängen",[33,3491,3492],{},"SendRawEmailCommand"," mit einer manuell zusammengebauten ",[33,3495,3496],{},"multipart\u002Fmixed","-MIME-Nachricht (der MIME-Builder ist im Modul inline enthalten).",[11,3499,3500,3501,3503,3504,3430,3507,526,3509,3430,3512,526,3515,3430,3518,3439,3521,3443,3523,1671],{},"Fehler werden anhand des ",[33,3502,212],{}," des SDK-Fehlers klassifiziert (z. B. ",[33,3505,3506],{},"Throttling",[33,3508,2695],{},[33,3510,3511],{},"MailFromDomainNotVerified",[33,3513,3514],{},"INVALID_SENDER",[33,3516,3517],{},"MessageRejected",[33,3519,3520],{},"CONTENT_REJECTED",[33,3522,3442],{},[33,3524,3446],{},[1527,3526,3527],{"type":1529},[11,3528,3529,3530,3533,3534,3536,3537,3540,3541,3543],{},"Einen Sendeprovider hinzuzufügen ist eine Änderung in genau einem Ordner: den Eintrag in ",[33,3531,3532],{},"packages\u002Fshared\u002Fsrc\u002FsendProviderCatalog.ts"," deklarieren (dort lebt das Kind-Literal — ",[33,3535,2017],{}," im Backend ist ein Re-Export), ",[33,3538,3539],{},"lib\u002FsendProviders\u002F\u003Ckind>\u002Findex.ts"," anlegen und in ",[33,3542,2013],{}," registrieren. Eine Prüfung der Registry zur Compile-Zeit erkennt eine fehlende Methode oder ein deklariertes Kind ohne Adapter.",[18,3545,3547],{"id":3546},"sicherheitsprüfung-von-e-mails","Sicherheitsprüfung von E-Mails",[11,3549,3550,3551,3554,3555,3558,3559,3562,3563,3566,3567,3569,3570,699,3573,3576,3577,3580],{},"Sämtliche ausgehende E-Mail durchläuft vor der Zustellung eine mehrschichtige Sicherheitsprüfung. Das Paket ",[33,3552,3553],{},"@owlat\u002Femail-scanner"," stellt die gesamte Prüflogik als gemeinsam genutzte Bibliothek bereit und wird sowohl von ",[33,3556,3557],{},"apps\u002Fapi"," (Convex) als auch von ",[33,3560,3561],{},"apps\u002Fmta"," verwendet. Convex-Code importiert ",[33,3564,3565],{},"scanContent"," direkt aus ",[33,3568,3553],{}," (etwa in ",[33,3571,3572],{},"apps\u002Fapi\u002Fconvex\u002Fcampaigns\u002Fsend.ts",[33,3574,3575],{},"apps\u002Fapi\u002Fconvex\u002Ftransactional\u002Flifecycle.ts",") — einen Re-Export-Wrapper ",[33,3578,3579],{},"lib\u002FcontentScanner.ts"," gibt es nicht mehr.",[11,3582,3583,3584,1671],{},"Alle Details finden Sie auf der Seite ",[1667,3585,3587],{"href":3586},"\u002Fdeveloper\u002Femail-security","E-Mail-Sicherheit",[38,3589,3591],{"id":3590},"inhaltsprüfung","Inhaltsprüfung",[11,3593,3594],{},"Analysiert Betreff und HTML-Body einer E-Mail auf Spam, Phishing und unzulässige Inhalte:",[1561,3596,3597,3603,3609,3621,3627],{},[1564,3598,3599,3602],{},[1567,3600,3601],{},"Spam-Schlüsselwörter"," — über 40 gewichtete Muster (z. B. „free money“, „act now“, „Nigerian prince“)",[1564,3604,3605,3608],{},[1567,3606,3607],{},"Phishing-URLs"," — Erkennung von URL-Kürzern, Abweichung zwischen Anker- und href-Domain",[1564,3610,3611,3614,3615,3618,3619,2287],{},[1567,3612,3613],{},"Homoglyphen-Spoofing"," — verwechselbare Unicode-Zeichen (~50 Zuordnungen, z. B. kyrillisches ",[33,3616,3617],{},"а"," vs. lateinisches ",[33,3620,1667],{},[1564,3622,3623,3626],{},[1567,3624,3625],{},"Unzulässige Inhalte"," — Vorschussbetrug, Muster für Credential-Phishing",[1564,3628,3629,3632],{},[1567,3630,3631],{},"Betreffanalyse"," — Missbrauch von GROSSBUCHSTABEN, übermäßige Zeichensetzung",[11,3634,3635],{},"Die Ergebnisse ergeben einen Score (0–100) mit Schweregrad-Gewichtungen: hoch (20 Punkte), mittel (10 Punkte), niedrig (3 Punkte). Schwellen: sauber \u003C 15, verdächtig 15–39, blockiert ≥ 40.",[38,3637,3639],{"id":3638},"dateivalidierung","Dateivalidierung",[11,3641,3642],{},"Prüft Anhänge und Medien-Uploads vor Speicherung oder Versand:",[1561,3644,3645,3651,3660,3666],{},[1564,3646,3647,3650],{},[1567,3648,3649],{},"Magic Bytes"," — ermittelt den tatsächlichen Dateityp aus den Binärheadern (erste 16 Bytes)",[1564,3652,3653,3656,3657],{},[1567,3654,3655],{},"Doppelte Endung"," — erkennt Angriffe wie ",[33,3658,3659],{},"invoice.pdf.exe",[1564,3661,3662,3665],{},[1567,3663,3664],{},"Endungs-Allowlist"," — erlaubt Bilder, PDFs, Dokumente, Tabellen, Archive",[1564,3667,3668,3671],{},[1567,3669,3670],{},"MIME-Typ-Allowlist"," — validiert die deklarierten Content-Types",[11,3673,3674,3675,3678,3679,3682],{},"Angewendet in ",[33,3676,3677],{},"apps\u002Fapi\u002Fconvex\u002Fdelivery\u002Fworker.ts"," (Anhänge) und ",[33,3680,3681],{},"mediaAssets.ts"," (Medien-Uploads).",[38,3684,3686],{"id":3685},"url-reputation","URL-Reputation",[11,3688,3689],{},"Prüft URLs gegen die Google Safe Browsing API v4:",[1561,3691,3692,3695,3698,3704,3710,3717],{},[1564,3693,3694],{},"Batch-Prüfung von bis zu 500 URLs pro Anfrage",[1564,3696,3697],{},"Bedrohungstypen: MALWARE, SOCIAL_ENGINEERING, UNWANTED_SOFTWARE",[1564,3699,3700,3703],{},[1567,3701,3702],{},"Kampagnenversand",": blockierendes Gate — markierte URLs verhindern den Versand",[1564,3705,3706,3709],{},[1567,3707,3708],{},"Transaktionaler Versand",": tolerant — markiert zur Prüfung, ohne zu blockieren",[1564,3711,3712,3713,3716],{},"Ergebnisse werden in der Tabelle ",[33,3714,3715],{},"urlReputationCache"," zwischengespeichert (24 h sauber, 1 h markiert)",[1564,3718,3719,3720],{},"Erfordert die Umgebungsvariable ",[33,3721,3722],{},"GOOGLE_SAFE_BROWSING_API_KEY",[38,3724,3726],{"id":3725},"clamav-malware-prüfung","ClamAV-Malware-Prüfung",[11,3728,3729],{},"Prüft die Binärdaten von Anhängen auf bekannte Malware-Signaturen:",[1561,3731,3732,3735,3742,3749],{},[1564,3733,3734],{},"ClamAV läuft als Docker-Sidecar neben der MTA",[1564,3736,3737,3738,3741],{},"Die MTA stellt den Endpunkt ",[33,3739,3740],{},"POST \u002Fscan\u002Fattachment"," bereit",[1564,3743,3744,3745,3748],{},"Convex ruft in ",[33,3746,3747],{},"delivery\u002Fworker.ts"," diesen Endpunkt für jeden Anhang vor dem Versand auf",[1564,3750,3751,3754],{},[1567,3752,3753],{},"Fail-open-Design",": Ist ClamAV nicht verfügbar, blockiert das die E-Mail-Zustellung nicht",[38,3756,3758],{"id":3757},"feedback-loops","Feedback Loops",[11,3760,3761],{},"Spam-Beschwerden aus den Feedback Loops der Provider werden mit den Ergebnissen der Inhaltsprüfung der jeweiligen Kampagne verknüpft. Das ermöglicht Mustererkennung und die Verfolgung der Beschwerderate je Kampagne.",[38,3763,3765],{"id":3764},"zentrale-dateien","Zentrale Dateien",[43,3767,3768,3777],{},[46,3769,3770],{},[49,3771,3772,3775],{},[52,3773,3774],{},"Datei",[52,3776,57],{},[59,3778,3779,3789,3799,3809,3819,3828,3838],{},[49,3780,3781,3786],{},[64,3782,3783],{},[33,3784,3785],{},"packages\u002Femail-scanner\u002Fsrc\u002Fcontent\u002F",[64,3787,3788],{},"Inhaltsanalyse (Spam, Phishing, Homoglyphen)",[49,3790,3791,3796],{},[64,3792,3793],{},[33,3794,3795],{},"packages\u002Femail-scanner\u002Fsrc\u002Ffiles\u002F",[64,3797,3798],{},"Dateitypvalidierung (Magic Bytes, Endungen)",[49,3800,3801,3806],{},[64,3802,3803],{},[33,3804,3805],{},"packages\u002Femail-scanner\u002Fsrc\u002Furls\u002F",[64,3807,3808],{},"URL-Reputation (Safe-Browsing-API)",[49,3810,3811,3816],{},[64,3812,3813],{},[33,3814,3815],{},"packages\u002Femail-scanner\u002Fsrc\u002Fclamav\u002F",[64,3817,3818],{},"ClamAV-TCP-Client (nur Node.js, von der MTA verwendet)",[49,3820,3821,3825],{},[64,3822,3823],{},[33,3824,3677],{},[64,3826,3827],{},"Anhangvalidierung + Einbindung der ClamAV-Prüfung",[49,3829,3830,3835],{},[64,3831,3832],{},[33,3833,3834],{},"apps\u002Fapi\u002Fconvex\u002FmediaAssets.ts",[64,3836,3837],{},"Validierung hochgeladener Dateien",[49,3839,3840,3845],{},[64,3841,3842],{},[33,3843,3844],{},"apps\u002Fmta\u002Fsrc\u002Froutes\u002Fscan.ts",[64,3846,3847],{},"Scan-Endpunkt der MTA",[18,3849,3851],{"id":3850},"domain-verifizierung","Domain-Verifizierung",[11,3853,3854,3855,3858,3859,3862,3863,2994,3866,3869],{},"Vor dem Versand müssen Domains mit den passenden DNS-Einträgen (SPF, DKIM, DMARC) verifiziert werden. Gemäß ",[1667,3856,3857],{"href":1994},"ADR-0018"," liegt der Domain-Code in ",[33,3860,3861],{},"apps\u002Fapi\u002Fconvex\u002Fdomains\u002F",", und die Registrierung je Provider sitzt hinter einer Adapter-Naht ",[33,3864,3865],{},"SendingDomainProviderModule",[33,3867,3868],{},"domains\u002Fproviders\u002F{mta,ses}\u002F",". Die MTA übernimmt die DKIM-Signierung direkt; der SES-Adapter registriert die Domain zusätzlich über die AWS-SES-Identity-API.",[11,3871,3872,3873,3876,3877,3880,3881,526,3884,526,3887,526,3890,3893,3894,3896,3897,1671],{},"Das Modul ",[33,3874,3875],{},"domains\u002Flifecycle.ts"," ist der einzige Schreiber von ",[33,3878,3879],{},"domains.status"," und der zugehörigen Felder. Es bietet vier Einstiegspunkte — ",[33,3882,3883],{},"create",[33,3885,3886],{},"transition",[33,3888,3889],{},"recordVerification",[33,3891,3892],{},"remove"," — und verzweigt nie über ",[33,3895,2957],{},"; Providerunterschiede leben vollständig hinter ",[33,3898,3899],{},"domains\u002Fproviders\u002F",[38,3901,3903],{"id":3902},"ses-identity-verwaltung","SES-Identity-Verwaltung",[11,3905,3906,3907,3910,3911,3914],{},"Wenn der SES-Adapter (",[33,3908,3909],{},"domains\u002Fproviders\u002Fses\u002F",") eine Domain registriert, ruft er ",[33,3912,3913],{},"lib\u002FemailProviders\u002FsesIdentity.ts"," auf, das die AWS-SES-Identity-APIs kapselt:",[43,3916,3917,3929],{},[46,3918,3919],{},[49,3920,3921,3924,3927],{},[52,3922,3923],{},"Methode",[52,3925,3926],{},"SES-Befehle",[52,3928,57],{},[59,3930,3931,3950,3965,3983],{},[49,3932,3933,3938,3947],{},[64,3934,3935],{},[33,3936,3937],{},"registerDomain()",[64,3939,3940,3943,3944],{},[33,3941,3942],{},"VerifyDomainIdentity"," + ",[33,3945,3946],{},"VerifyDomainDkim",[64,3948,3949],{},"Legt die Identity an, liefert Verifizierungstoken + 3 DKIM-Token",[49,3951,3952,3957,3962],{},[64,3953,3954],{},[33,3955,3956],{},"setupMailFromDomain()",[64,3958,3959],{},[33,3960,3961],{},"SetIdentityMailFromDomain",[64,3963,3964],{},"Konfiguriert die eigene MAIL-FROM-Subdomain",[49,3966,3967,3972,3980],{},[64,3968,3969],{},[33,3970,3971],{},"getVerificationStatus()",[64,3973,3974,3943,3977],{},[33,3975,3976],{},"GetIdentityVerificationAttributes",[33,3978,3979],{},"GetIdentityDkimAttributes",[64,3981,3982],{},"Prüft den Verifizierungsstand auf SES-Seite",[49,3984,3985,3990,3995],{},[64,3986,3987],{},[33,3988,3989],{},"deleteIdentity()",[64,3991,3992],{},[33,3993,3994],{},"DeleteIdentity",[64,3996,3997],{},"Entfernt die Identity aus SES",[38,3999,4001],{"id":4000},"generierte-dns-einträge","Generierte DNS-Einträge",[43,4003,4004,4019],{},[46,4005,4006],{},[49,4007,4008,4011,4013,4016],{},[52,4009,4010],{},"Eintrag",[52,4012,745],{},[52,4014,4015],{},"Host",[52,4017,4018],{},"Wert",[59,4020,4021,4039,4057,4083,4101],{},[49,4022,4023,4026,4029,4034],{},[64,4024,4025],{},"SPF",[64,4027,4028],{},"TXT",[64,4030,4031],{},[33,4032,4033],{},"@",[64,4035,4036],{},[33,4037,4038],{},"v=spf1 include:amazonses.com -all",[49,4040,4041,4044,4047,4052],{},[64,4042,4043],{},"DKIM (x3)",[64,4045,4046],{},"CNAME",[64,4048,4049],{},[33,4050,4051],{},"{token}._domainkey",[64,4053,4054],{},[33,4055,4056],{},"{token}.dkim.amazonses.com",[49,4058,4059,4062,4064,4069],{},[64,4060,4061],{},"DMARC",[64,4063,4028],{},[64,4065,4066],{},[33,4067,4068],{},"_dmarc",[64,4070,4071,4074,4075,4078,4079,4082],{},[33,4072,4073],{},"v=DMARC1; p=none"," (das Reporting-Tag ",[33,4076,4077],{},"rua="," entfällt, sofern der Betreiber nicht ",[33,4080,4081],{},"MTA_DMARC_RUA"," setzt)",[49,4084,4085,4088,4091,4096],{},[64,4086,4087],{},"MAIL FROM MX",[64,4089,4090],{},"MX",[64,4092,4093],{},[33,4094,4095],{},"mail",[64,4097,4098],{},[33,4099,4100],{},"10 feedback-smtp.{region}.amazonses.com",[49,4102,4103,4106,4108,4112],{},[64,4104,4105],{},"MAIL FROM SPF",[64,4107,4028],{},[64,4109,4110],{},[33,4111,4095],{},[64,4113,4114],{},[33,4115,4116],{},"v=spf1 include:amazonses.com ~all",[38,4118,4120],{"id":4119},"statusablauf-einer-domain","Statusablauf einer Domain",[4122,4123],"domain-flow",{},[38,4125,3765],{"id":4126},"zentrale-dateien-1",[11,4128,4129,4130,1671],{},"Alle Pfade unten liegen unter ",[33,4131,4132],{},"apps\u002Fapi\u002Fconvex\u002F",[43,4134,4135,4143],{},[46,4136,4137],{},[49,4138,4139,4141],{},[52,4140,3774],{},[52,4142,57],{},[59,4144,4145,4169,4196,4213,4227,4243,4252,4261],{},[49,4146,4147,4152],{},[64,4148,4149],{},[33,4150,4151],{},"domains\u002Fdomains.ts",[64,4153,4154,4155,526,4157,526,4159,4162,4163,526,4166,2287],{},"Domain-CRUD (",[33,4156,3883],{},[33,4158,3892],{},[33,4160,4161],{},"regenerateDnsRecords",") + List-\u002FRead-Queries; Typdefinitionen (",[33,4164,4165],{},"DnsRecords",[33,4167,4168],{},"VerificationResults",[49,4170,4171,4175],{},[64,4172,4173],{},[33,4174,3875],{},[64,4176,4177,4178,702,4180,1770,4182,1770,4184,1770,4186,4188,4189,4192,4193],{},"Einziger Schreiber von ",[33,4179,3879],{},[33,4181,3883],{},[33,4183,3886],{},[33,4185,3889],{},[33,4187,3892],{}," sowie die Effekte ",[33,4190,4191],{},"register_with_provider"," \u002F ",[33,4194,4195],{},"delete_with_provider",[49,4197,4198,4203],{},[64,4199,4200],{},[33,4201,4202],{},"domains\u002FdnsVerification.ts",[64,4204,4205,4206,4209,4210,4212],{},"Action ",[33,4207,4208],{},"verifyDomain"," — prüft die veröffentlichten DNS-Einträge (SPF, DKIM-Array, DMARC, MAIL FROM MX\u002FSPF) plus die Prüfung des jeweiligen Providers und ruft dann ",[33,4211,3889],{}," auf",[49,4214,4215,4220],{},[64,4216,4217],{},[33,4218,4219],{},"domains\u002Fqueries.ts",[64,4221,4222,4223,4226],{},"Interne Read-Query (",[33,4224,4225],{},"getDomainForRegistration","), genutzt von der Verifizierung und den Registrierungs-Actions",[49,4228,4229,4234],{},[64,4230,4231],{},[33,4232,4233],{},"domains\u002Fproviders\u002Findex.ts",[64,4235,4236,4237,3943,4240,4242],{},"Registry ",[33,4238,4239],{},"SENDING_DOMAIN_PROVIDERS",[33,4241,2021],{}," (mta, ses)",[49,4244,4245,4249],{},[64,4246,4247],{},[33,4248,3868],{},[64,4250,4251],{},"Registrierung je Provider, Erzeugung der DNS-Einträge, Persistenz der Identity und Verifizierungsprüfungen",[49,4253,4254,4258],{},[64,4255,4256],{},[33,4257,3913],{},[64,4259,4260],{},"Wrapper um die SES-Identity-API (reine Bibliothek, aufgerufen vom SES-Domain-Adapter)",[49,4262,4263,4268],{},[64,4264,4265],{},[33,4266,4267],{},"lib\u002FemailProviders\u002FdomainVerification.ts",[64,4269,4270,4271],{},"Durchsetzung zur Sendezeit über ",[33,4272,4273],{},"validateDomainForSending",[38,4275,4277],{"id":4276},"verifizierungsablauf","Verifizierungsablauf",[1998,4279,4280,4286,4298,4307,4314,4317,4326],{},[1564,4281,4282,4283],{},"Nutzerin oder Nutzer fügt unter Einstellungen > Domains eine Domain hinzu → ",[33,4284,4285],{},"domains.create",[1564,4287,4288,4290,4291,4294,4295,4297],{},[33,4289,3875],{}," legt die Zeile mit Status ",[33,4292,4293],{},"registering"," an und stößt den Effekt ",[33,4296,4191],{}," an",[1564,4299,4300,4301,3943,4304,4212],{},"Der Provider-Adapter (MTA oder SES) registriert die Domain und baut die zu veröffentlichenden DNS-Einträge; bei SES ruft das ",[33,4302,4303],{},"registerDomain",[33,4305,4306],{},"setupMailFromDomain",[1564,4308,4309,4310,4313],{},"Der Status wechselt auf ",[33,4311,4312],{},"pending"," mit den echten DKIM-Token des Providers, und die zugehörige Identity-Zeile je Provider wird persistiert",[1564,4315,4316],{},"Nutzerin oder Nutzer legt die DNS-Einträge beim eigenen DNS-Provider an",[1564,4318,4319,4320,4323,4324,4212],{},"Klick auf „Verifizieren“ → ",[33,4321,4322],{},"dnsVerification.verifyDomain"," prüft alle DNS-Einträge sowie den Verifizierungsstatus des Providers und ruft danach ",[33,4325,3889],{},[1564,4327,4328,4329,4332,4333,2287],{},"Der Lifecycle-Reducer markiert die Domain nur dann als ",[33,4330,4331],{},"verified",", wenn die DNS-Regel erfüllt ist UND die Providerprüfung verifiziert meldet (die MTA hat keine zusätzliche Prüfung; SES verlangt ",[33,4334,4335],{},"Success",[38,4337,4339],{"id":4338},"durchsetzung","Durchsetzung",[127,4341,4343],{"className":862,"code":4342,"language":864,"meta":132,"style":132},"\u002F\u002F lib\u002FemailProviders\u002FdomainVerification.ts\n\u002F\u002F Before sending any email\nconst result = await validateDomainForSending(db, organizationId, fromEmail);\n\u002F\u002F Throws if domain is 'registering' or not verified\n\u002F\u002F Returns warning if verification is stale (>24 hours)\n",[33,4344,4345,4350,4355,4373,4378],{"__ignoreMap":132},[136,4346,4347],{"class":138,"line":139},[136,4348,4349],{"class":529},"\u002F\u002F lib\u002FemailProviders\u002FdomainVerification.ts\n",[136,4351,4352],{"class":138,"line":153},[136,4353,4354],{"class":529},"\u002F\u002F Before sending any email\n",[136,4356,4357,4359,4362,4364,4367,4370],{"class":138,"line":162},[136,4358,391],{"class":366},[136,4360,4361],{"class":394}," result",[136,4363,398],{"class":366},[136,4365,4366],{"class":366}," await",[136,4368,4369],{"class":401}," validateDomainForSending",[136,4371,4372],{"class":142},"(db, organizationId, fromEmail);\n",[136,4374,4375],{"class":138,"line":187},[136,4376,4377],{"class":529},"\u002F\u002F Throws if domain is 'registering' or not verified\n",[136,4379,4380],{"class":138,"line":205},[136,4381,4382],{"class":529},"\u002F\u002F Returns warning if verification is stale (>24 hours)\n",[38,4384,4386],{"id":4385},"aktualität-der-verifizierung","Aktualität der Verifizierung",[11,4388,4389],{},"Die Verifizierung läuft nach 24 Stunden ab und wird vor dem Versand erneut geprüft.",[18,4391,4393],{"id":4392},"steuerung-der-versandrate","Steuerung der Versandrate",[11,4395,4396],{},"Der E-Mail-Versand nutzt ein workpool-basiertes Rate Limiting, um innerhalb der Providerlimits zu bleiben:",[1561,4398,4399,4405,4411],{},[1564,4400,4401,4404],{},[1567,4402,4403],{},"Transaktionale E-Mails"," werden mit höherer Priorität und minimaler Drosselung versendet, damit zeitkritische Zustellungen (Passwort-Zurücksetzungen, Bestellbestätigungen) schnell ankommen.",[1564,4406,4407,4410],{},[1567,4408,4409],{},"Kampagnen-E-Mails"," werden in großen Batches mit workpool-basiertem Rate Limiting (20\u002FSekunde) versendet, um Rate Limits der Provider nicht zu reißen.",[1564,4412,4413,4416],{},[1567,4414,4415],{},"Providerseitige Limits"," gelten zusätzlich zur Drosselung in der Anwendung — die MTA erledigt das Rate Limiting intern (Drosselung je ISP, Obergrenzen beim IP-Warming); SES und Resend setzen jeweils eigene Sendekontingente durch.",[11,4418,4419],{},"Der Rate Limiter ist Teil der Provider-Abstraktion, sodass alle Sendevorgänge (Kampagnen, Automationen, transaktional) dieselbe Drosselungsschicht durchlaufen.",[18,4421,3702],{"id":4422},"kampagnenversand",[38,4424,4426],{"id":4425},"ablauf","Ablauf",[1998,4428,4429,4435,4441,4447,4453,4459,4465,4471,4477],{},[1564,4430,4431,4434],{},[1567,4432,4433],{},"Kampagne erstellt"," – Template ausgewählt, Zielgruppe gewählt",[1564,4436,4437,4440],{},[1567,4438,4439],{},"Domain verifiziert"," – Prüfung, ob die Absenderdomain verifiziert ist",[1564,4442,4443,4446],{},[1567,4444,4445],{},"Inhalt geprüft"," – Analyse auf Spam, Phishing, Homoglyphen und unzulässige Inhalte",[1564,4448,4449,4452],{},[1567,4450,4451],{},"URL-Reputation geprüft"," – Google Safe Browsing API (falls konfiguriert)",[1564,4454,4455,4458],{},[1567,4456,4457],{},"Zielgruppe aufgelöst"," – berechtigte Kontakte ermitteln (Themen-Zielgruppen beachten das Double Opt-in; Segment-Zielgruppen unterliegen keinem DOI-Gate)",[1564,4460,4461,4464],{},[1567,4462,4463],{},"HTML gerendert"," – Rendering je Sprache",[1564,4466,4467,4470],{},[1567,4468,4469],{},"Anhänge validiert"," – Dateitypprüfung + ClamAV-Malware-Scan (sofern Anhänge vorhanden)",[1564,4472,4473,4476],{},[1567,4474,4475],{},"Batch-Verarbeitung"," – Versand in Batches mit Rate Limiting",[1564,4478,4479,4482],{},[1567,4480,4481],{},"Statusverfolgung"," – Erfassung von gesendet, zugestellt, geöffnet, geklickt",[38,4484,4485],{"id":33},"Code",[11,4487,4488,4489,4492,4493,4496,4497,4499,4500,4503,4504,4192,4507,4510,4511,4514],{},"Der einzige aktive Einstiegspunkt ist ",[33,4490,4491],{},"internal.campaigns.send.startCampaignSend"," —\nder ",[1567,4494,4495],{},"Campaign send orchestrator (module)"," in\n",[33,4498,3572],{},". Er führt die Vorbereitungs-Pipeline aus\n(Preflight → Inhaltsprüfung → Archiv-Snapshot → Auflösung der Zielgruppe →\nFanout der A\u002FB-Varianten → Einreihen in den Workpool) und wird vom ",[1567,4501,4502],{},"Campaign lifecycle\n(module)"," bei ",[33,4505,4506],{},"→ scheduled",[33,4508,4509],{},"→ sending"," sowie vom täglichen Scheduler-Tick\n(",[33,4512,4513],{},"processScheduledCampaigns",") eingeplant.",[11,4516,4517,4518,4521,4522,4525,4526,4529],{},"Bei A\u002FB-Testkampagnen fächert der Versand der ersten Phase eine Testkohorte auf\n(2 × splitPercentage % der Zielgruppe, aufgeteilt auf A\u002FB). Der zurückgehaltene Rest\nerhält den Inhalt der Gewinnervariante über die Schwester-Action\n",[33,4519,4520],{},"internal.campaigns.send.sendCampaignWinnerToRemainder",", nachdem\n",[33,4523,4524],{},"campaigns.abTest.declareABTestWinner"," den Lebenszyklus des AB-Tests auf\n",[33,4527,4528],{},"winner_selected"," überführt hat — das vollständige Vokabular finden Sie in CONTEXT.md\nunter „Campaign send orchestrator (module)“.",[18,4531,4403],{"id":4532},"transaktionale-e-mails",[11,4534,4535],{},"Per API ausgelöste E-Mails mit Variablen:",[38,4537,4539],{"id":4538},"versand-über-die-api","Versand über die API",[127,4541,4545],{"className":4542,"code":4543,"language":4544,"meta":132,"style":132},"language-bash shiki shiki-themes github-light github-dark-dimmed","curl -X POST https:\u002F\u002Fyour-deployment.convex.site\u002Fapi\u002Fv1\u002Ftransactional \\\n  -H \"Authorization: Bearer lm_live_...\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"slug\": \"order-confirmation\",\n    \"email\": \"customer@example.com\",\n    \"dataVariables\": {\n      \"orderNumber\": \"12345\",\n      \"total\": \"$99.00\"\n    },\n    \"language\": \"en\"\n  }'\n","bash",[33,4546,4547,4565,4575,4584,4592,4597,4602,4607,4612,4617,4621,4626],{"__ignoreMap":132},[136,4548,4549,4552,4555,4558,4561],{"class":138,"line":139},[136,4550,4551],{"class":874},"curl",[136,4553,4554],{"class":394}," -X",[136,4556,4557],{"class":376}," POST",[136,4559,4560],{"class":376}," https:\u002F\u002Fyour-deployment.convex.site\u002Fapi\u002Fv1\u002Ftransactional",[136,4562,4564],{"class":4563},"s74oq"," \\\n",[136,4566,4567,4570,4573],{"class":138,"line":153},[136,4568,4569],{"class":394},"  -H",[136,4571,4572],{"class":376}," \"Authorization: Bearer lm_live_...\"",[136,4574,4564],{"class":4563},[136,4576,4577,4579,4582],{"class":138,"line":162},[136,4578,4569],{"class":394},[136,4580,4581],{"class":376}," \"Content-Type: application\u002Fjson\"",[136,4583,4564],{"class":4563},[136,4585,4586,4589],{"class":138,"line":187},[136,4587,4588],{"class":394},"  -d",[136,4590,4591],{"class":376}," '{\n",[136,4593,4594],{"class":138,"line":205},[136,4595,4596],{"class":376},"    \"slug\": \"order-confirmation\",\n",[136,4598,4599],{"class":138,"line":223},[136,4600,4601],{"class":376},"    \"email\": \"customer@example.com\",\n",[136,4603,4604],{"class":138,"line":242},[136,4605,4606],{"class":376},"    \"dataVariables\": {\n",[136,4608,4609],{"class":138,"line":259},[136,4610,4611],{"class":376},"      \"orderNumber\": \"12345\",\n",[136,4613,4614],{"class":138,"line":275},[136,4615,4616],{"class":376},"      \"total\": \"$99.00\"\n",[136,4618,4619],{"class":138,"line":292},[136,4620,674],{"class":376},[136,4622,4623],{"class":138,"line":310},[136,4624,4625],{"class":376},"    \"language\": \"en\"\n",[136,4627,4628],{"class":138,"line":327},[136,4629,4630],{"class":376},"  }'\n",[11,4632,4633],{},"Oder über das TypeScript-SDK:",[127,4635,4637],{"className":862,"code":4636,"language":864,"meta":132,"style":132},"import { Owlat } from '@owlat\u002Fsdk-js';\n\nconst owlat = new Owlat('lm_live_...');\n\nawait owlat.transactional.send({\n    slug: 'order-confirmation',\n    email: 'customer@example.com',\n    dataVariables: {\n        orderNumber: '12345',\n        total: '$99.00',\n    },\n    language: 'en',\n});\n",[33,4638,4639,4653,4657,4679,4683,4695,4705,4715,4720,4730,4740,4744,4754],{"__ignoreMap":132},[136,4640,4641,4643,4646,4648,4651],{"class":138,"line":139},[136,4642,367],{"class":366},[136,4644,4645],{"class":142}," { Owlat } ",[136,4647,373],{"class":366},[136,4649,4650],{"class":376}," '@owlat\u002Fsdk-js'",[136,4652,380],{"class":142},[136,4654,4655],{"class":138,"line":153},[136,4656,347],{"emptyLinePlaceholder":346},[136,4658,4659,4661,4664,4666,4669,4672,4674,4677],{"class":138,"line":162},[136,4660,391],{"class":366},[136,4662,4663],{"class":394}," owlat",[136,4665,398],{"class":366},[136,4667,4668],{"class":366}," new",[136,4670,4671],{"class":401}," Owlat",[136,4673,420],{"class":142},[136,4675,4676],{"class":376},"'lm_live_...'",[136,4678,426],{"class":142},[136,4680,4681],{"class":138,"line":187},[136,4682,347],{"emptyLinePlaceholder":346},[136,4684,4685,4687,4690,4693],{"class":138,"line":205},[136,4686,613],{"class":366},[136,4688,4689],{"class":142}," owlat.transactional.",[136,4691,4692],{"class":401},"send",[136,4694,582],{"class":142},[136,4696,4697,4700,4703],{"class":138,"line":223},[136,4698,4699],{"class":142},"    slug: ",[136,4701,4702],{"class":376},"'order-confirmation'",[136,4704,1939],{"class":142},[136,4706,4707,4710,4713],{"class":138,"line":242},[136,4708,4709],{"class":142},"    email: ",[136,4711,4712],{"class":376},"'customer@example.com'",[136,4714,1939],{"class":142},[136,4716,4717],{"class":138,"line":259},[136,4718,4719],{"class":142},"    dataVariables: {\n",[136,4721,4722,4725,4728],{"class":138,"line":275},[136,4723,4724],{"class":142},"        orderNumber: ",[136,4726,4727],{"class":376},"'12345'",[136,4729,1939],{"class":142},[136,4731,4732,4735,4738],{"class":138,"line":292},[136,4733,4734],{"class":142},"        total: ",[136,4736,4737],{"class":376},"'$99.00'",[136,4739,1939],{"class":142},[136,4741,4742],{"class":138,"line":310},[136,4743,674],{"class":142},[136,4745,4746,4749,4752],{"class":138,"line":327},[136,4747,4748],{"class":142},"    language: ",[136,4750,4751],{"class":376},"'en'",[136,4753,1939],{"class":142},[136,4755,4756],{"class":138,"line":333},[136,4757,680],{"class":142},[38,4759,4761],{"id":4760},"variablensystem","Variablensystem",[11,4763,4764],{},"Variablen werden über den Inline-Texteditor als Inline-Knoten eingefügt. Es gibt zwei Variablentypen:",[1561,4766,4767,4782],{},[1564,4768,4769,4772,4773,526,4776,526,4779],{},[1567,4770,4771],{},"Personalisierungsvariablen"," – Kontaktfelder wie ",[33,4774,4775],{},"firstName",[33,4777,4778],{},"lastName",[33,4780,4781],{},"email",[1564,4783,4784,4787,4788,4791],{},[1567,4785,4786],{},"Datenvariablen"," – eigene Werte, die über das API-Objekt ",[33,4789,4790],{},"dataVariables"," übergeben werden",[11,4793,4794],{},"Variablen werden beim Versand während des HTML-Renderings ersetzt.",[4796,4797,4798],"style",{},"html pre.shiki code .sYgZi, html code.shiki .sYgZi{--shiki-default:#24292E;--shiki-dark:#ADBAC7}html pre.shiki code .sIAta, html code.shiki .sIAta{--shiki-default:#22863A;--shiki-dark:#8DDB8C}html pre.shiki code .sMOND, html code.shiki .sMOND{--shiki-default:#6F42C1;--shiki-dark:#6CB6FF}html pre.shiki code .s4G6O, html code.shiki .s4G6O{--shiki-default:#032F62;--shiki-dark:#ADBAC7}html pre.shiki code .s7YZ4, html code.shiki .s7YZ4{--shiki-default:#D73A49;--shiki-dark:#F47067}html pre.shiki code .s-HuK, html code.shiki .s-HuK{--shiki-default:#032F62;--shiki-dark:#96D0FF}html pre.shiki code .sviXB, html code.shiki .sviXB{--shiki-default:#005CC5;--shiki-dark:#6CB6FF}html pre.shiki code .sPO5f, html code.shiki .sPO5f{--shiki-default:#6F42C1;--shiki-dark:#DCBDFB}html pre.shiki code .sDN9O, html code.shiki .sDN9O{--shiki-default:#6A737D;--shiki-dark:#768390}html pre.shiki code .stnAF, html code.shiki .stnAF{--shiki-default:#E36209;--shiki-dark:#F69D50}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sOLd2, html code.shiki .sOLd2{--shiki-default:#6F42C1;--shiki-dark:#F69D50}html pre.shiki code .s74oq, html code.shiki .s74oq{--shiki-default:#005CC5;--shiki-dark:#F47067}",{"title":132,"searchDepth":153,"depth":153,"links":4800},[4801,4802,4807,4813,4814,4824,4832,4841,4842,4846],{"id":20,"depth":153,"text":21},{"id":27,"depth":153,"text":28,"children":4803},[4804,4805,4806],{"id":40,"depth":162,"text":41},{"id":124,"depth":162,"text":125},{"id":732,"depth":162,"text":733},{"id":847,"depth":153,"text":848,"children":4808},[4809,4810,4811,4812],{"id":851,"depth":162,"text":852},{"id":1249,"depth":162,"text":1250},{"id":1551,"depth":162,"text":1552},{"id":1674,"depth":162,"text":1675},{"id":1774,"depth":153,"text":1775},{"id":1983,"depth":153,"text":1984,"children":4815},[4816,4817,4818,4819,4820,4821,4822,4823],{"id":2047,"depth":162,"text":2048},{"id":2495,"depth":162,"text":2496},{"id":2702,"depth":162,"text":2703},{"id":2987,"depth":162,"text":2988},{"id":3141,"depth":162,"text":3142},{"id":3219,"depth":162,"text":3220},{"id":3401,"depth":162,"text":3402},{"id":3449,"depth":162,"text":3450},{"id":3546,"depth":153,"text":3547,"children":4825},[4826,4827,4828,4829,4830,4831],{"id":3590,"depth":162,"text":3591},{"id":3638,"depth":162,"text":3639},{"id":3685,"depth":162,"text":3686},{"id":3725,"depth":162,"text":3726},{"id":3757,"depth":162,"text":3758},{"id":3764,"depth":162,"text":3765},{"id":3850,"depth":153,"text":3851,"children":4833},[4834,4835,4836,4837,4838,4839,4840],{"id":3902,"depth":162,"text":3903},{"id":4000,"depth":162,"text":4001},{"id":4119,"depth":162,"text":4120},{"id":4126,"depth":162,"text":3765},{"id":4276,"depth":162,"text":4277},{"id":4338,"depth":162,"text":4339},{"id":4385,"depth":162,"text":4386},{"id":4392,"depth":153,"text":4393},{"id":4422,"depth":153,"text":3702,"children":4843},[4844,4845],{"id":4425,"depth":162,"text":4426},{"id":33,"depth":162,"text":4485},{"id":4532,"depth":153,"text":4403,"children":4847},[4848,4849],{"id":4538,"depth":162,"text":4539},{"id":4760,"depth":162,"text":4761},"md",{},"\u002Fdeveloper\u002Femail-system",{"title":6,"description":13},"3.developer\u002F6.email-system","QNRuIcgQA5PfmYaRYEKt8jB1n30f0NA1rVYp9jfIOo4",[4857,4861],{"title":4858,"path":4859,"stem":4860,"children":-1},"Authentifizierung","\u002Fdeveloper\u002Fauthentication","3.developer\u002F5.authentication",{"title":1670,"path":1669,"stem":4862,"children":-1},"3.developer\u002F7.email-renderer",1786915108041]