{
  "version": "1.0.0",
  "exported_at": "2026-06-01T00:00:00.000Z",
  "project": {
    "name": "11880com Listing Scraper",
    "description": "Scrapes 11880.com business listing search results for a keyword/location pair, extracting the Octoparse-equivalent listing fields: result count, name, company URL, type/category, rating, review count, location/address, street, postal code, city, phone number, and status/opening text. Default target is the Hannover/Maschinenbau listing; edit the Navigate URL for other keyword/location pairs such as /suche/auto/berlin. The workflow waits for stable /branchenbuch/ detail links, scrolls to trigger lazy-loaded results, marks one surrounding listing card per unique company URL, exports only those marked cards, then checks for a visible Next/Weiter/Nächste/Mehr anzeigen control and loops until no navigation control remains.",
    "color": "bg-[#4589ff]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "set-window-size-1",
      "block_type": "process",
      "title": "Set Window Size",
      "description": "Set browser viewport size",
      "position_x": 100,
      "position_y": 220,
      "config": {
        "width": 1920,
        "height": 1080,
        "color": "bg-[#4589ff]"
      }
    },
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 460,
      "position_y": 220,
      "config": {
        "url": "https://www.11880.com/suche/maschinenbau/hannover",
        "color": "bg-[#4589ff]"
      }
    },
    {
      "block_id": "wait-for-page-load-1",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 820,
      "position_y": 220,
      "config": {
        "timeout": 30,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Dismiss cookie banner if present",
      "position_x": 1180,
      "position_y": 220,
      "config": {
        "jsCode": "(() => { const labels = ['Accept', 'Akzeptieren', 'Alle akzeptieren', 'Zustimmen', 'OK', 'Einverstanden']; const buttons = Array.from(document.querySelectorAll('button, a[role=button], input[type=button], input[type=submit]')); const btn = buttons.find(b => labels.some(t => ((b.innerText || b.value || b.getAttribute('aria-label') || '')).toLowerCase().includes(t.toLowerCase()))); if (btn) { btn.click(); return 'cookie button clicked'; } return 'no cookie button found'; })();",
        "waitForCompletion": true,
        "timeout": 10,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1540,
      "position_y": 220,
      "config": {
        "duration": 1,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until business detail links appear",
      "position_x": 1900,
      "position_y": 220,
      "config": {
        "selector": "a[href*='/branchenbuch/'][href$='.html']",
        "timeout": 30,
        "visible": true,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "scroll-1",
      "block_type": "process",
      "title": "Scroll",
      "description": "Scroll down to trigger lazy-loaded result cards",
      "position_x": 2260,
      "position_y": 220,
      "config": {
        "direction": "down",
        "amount": 3500,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Allow lazy-loaded content to render",
      "position_x": 2620,
      "position_y": 220,
      "config": {
        "duration": 2,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "inject-javascript-2",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Mark unique business listing cards",
      "position_x": 2980,
      "position_y": 220,
      "config": {
        "jsCode": "(() => { document.querySelectorAll('[data-uscraper-row]').forEach(e => e.removeAttribute('data-uscraper-row')); const visible = el => !!(el && (el.offsetWidth || el.offsetHeight || el.getClientRects().length)); const norm = s => (s || '').trim().replace(/\\s+/g, ' '); const detailSel = \"a[href*='/branchenbuch/'][href$='.html']\"; const bad = /Treffer|sortiert|Standard|Entfernung|Filtern|Kategorien|schließen|Datenschutz|Impressum/i; const generic = /^(Anrufen|Route|Routenplaner|Bewertung|Bewerten|Webseite|Website|Details|mehr|anzeigen|\\*)$/i; const cardFor = a => { let e = a; for (let i = 0; i < 12 && e; i++, e = e.parentElement) { const txt = norm(e.innerText || ''); const links = e.querySelectorAll ? e.querySelectorAll(detailSel).length : 0; if ((/\\b\\d{5}\\b/.test(txt) || /\\(?0\\d{2,5}\\)?[\\s\\/-]?\\d/.test(txt)) && links <= 4) return e; } return a.closest('article, li, section, div') || a; }; const byUrl = new Map(); for (const a of Array.from(document.querySelectorAll(detailSel)).filter(visible)) { const href = new URL(a.getAttribute('href'), location.href).href; const text = norm(a.textContent || a.getAttribute('title') || a.getAttribute('aria-label') || ''); const card = cardFor(a); const ctext = norm(card.innerText || ''); let score = 0; if (text.length >= 2 && text.length <= 90) score += 30; if (/GmbH|AG|KG|UG|GbR|e\\.K\\.|BVBA|Maschinenbau|Technik|Service|Firma/i.test(text)) score += 15; if (/\\b\\d{5}\\b/.test(ctext)) score += 15; if (/\\(?0\\d{2,5}\\)?[\\s\\/-]?\\d/.test(ctext)) score += 10; if (generic.test(text)) score -= 80; if (bad.test(text)) score -= 120; if (/\\b\\d{5}\\b/.test(text) || /^\\(?0\\d/.test(text)) score -= 60; const old = byUrl.get(href); if (!old || score > old.score) byUrl.set(href, { href, name: text, card, score }); } for (const item of byUrl.values()) { item.card.setAttribute('data-uscraper-row', 'true'); item.card.setAttribute('data-uscraper-url', item.href); if (item.name && !generic.test(item.name) && !bad.test(item.name)) item.card.setAttribute('data-uscraper-name', item.name); } return 'marked cards: ' + document.querySelectorAll('[data-uscraper-row=\"true\"]').length; })();",
        "waitForCompletion": true,
        "timeout": 10,
        "color": "bg-[#42be65]"
      }
    },
    {
      "block_id": "wait-for-element-2",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait for marked unique listing cards",
      "position_x": 3340,
      "position_y": 220,
      "config": {
        "selector": "[data-uscraper-row='true']",
        "timeout": 10,
        "visible": true,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export unique 11880.com listing cards",
      "position_x": 3700,
      "position_y": 220,
      "config": {
        "rowSelector": "[data-uscraper-row='true']",
        "fileName": "11880-com-listing-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "color": "bg-[#42be65]",
        "columns": [
          {
            "name": "suchergebnisse",
            "selector": "(() => { const text = (document.querySelector('h1')?.innerText || document.body.innerText || ''); const m = text.match(/(\\d+)\\s*(?:Treffer|Suchergebnisse|Ergebnisse)/i); return m ? m[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "name",
            "selector": "(() => { const stored = ROW.getAttribute('data-uscraper-name'); if (stored) return stored; const a = ROW.querySelector(\"a[href*='/branchenbuch/'][href$='.html']\"); return a ? (a.textContent || '').trim().replace(/\\s+/g, ' ') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "unternehmen_url",
            "selector": "(() => ROW.getAttribute('data-uscraper-url') || (ROW.querySelector(\"a[href*='/branchenbuch/'][href$='.html']\") ? new URL(ROW.querySelector(\"a[href*='/branchenbuch/'][href$='.html']\").getAttribute('href'), location.href).href : ''))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "art",
            "selector": "(() => { const name = ROW.getAttribute('data-uscraper-name') || ''; const direct = ROW.querySelector(`[class*='category' i], [class*='kategorie' i], [class*='branche' i], [class*='industry' i], [itemprop=additionalType]`); if (direct) return direct.textContent.trim().replace(/\\s+/g, ' '); const blacklist = /^(Anrufen|Route|Routenplaner|Bewertung|Bewerten|Webseite|Website|Details|schließen|Filtern|Kategorien|Telefon|Tel\\.?|Geöffnet|Geschlossen|keine Öffnungszeiten|\\*)$/i; const lines = (ROW.innerText || '').split(/\\n+/).map(s => s.trim().replace(/\\s+/g, ' ')).filter(Boolean); return [...new Set(lines)].filter(t => t !== name && !blacklist.test(t) && !/\\b\\d{5}\\b/.test(t) && !/^\\(?0\\d/.test(t) && !/Treffer|sortiert|Standard|Entfernung/i.test(t) && t.length > 2 && t.length < 120).slice(0, 2).join(' & '); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "kundenbewertung",
            "selector": "(() => { const nodes = Array.from(ROW.querySelectorAll(`[aria-label*='Stern' i], [title*='Stern' i], [aria-label*='Bewertung' i], [title*='Bewertung' i]`)); const text = nodes.map(e => e.getAttribute('aria-label') || e.getAttribute('title') || '').join(' '); const m = text.match(/([1-5](?:[,.]\\d)?)\\s*(?:\\/\\s*5|von\\s*5|Stern)/i); return m ? m[1].replace(',', '.') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "anzahl_der_bewertung",
            "selector": "(() => { const nodes = Array.from(ROW.querySelectorAll(`[aria-label*='Bewertung' i], [title*='Bewertung' i], a[href*='bewertung' i], [class*='bewertung' i]`)); const text = nodes.map(e => e.getAttribute('aria-label') || e.getAttribute('title') || e.textContent || '').join(' '); const m = text.match(/(?:^|\\D)(\\d+)\\s*(?:Bewertungen?|Rezensionen?)|(?:Bewertungen?|Rezensionen?)\\s*:?\\s*\\(?(\\d+)\\)?|\\((\\d+)\\)/i); return m ? (m[1] || m[2] || m[3] || '') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "standort",
            "selector": "(() => { const el = ROW.querySelector(`address, [itemprop=address], [class*='address' i], [class*='adresse' i], [class*='standort' i]`); if (el) return el.textContent.trim().replace(/\\s+/g, ' '); const lines = (ROW.innerText || '').split(/\\n+/).map(s => s.trim().replace(/\\s+/g, ' ')).filter(Boolean); const line = lines.find(l => /\\b\\d{5}\\b/.test(l) && !/^\\(?0\\d/.test(l)); return line ? line.replace(/\\s*\\(?0\\d{2,5}\\)?[\\s\\/-]?\\d[\\d\\s\\/-]{3,}.*$/, '').trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "strasse",
            "selector": "(() => { const el = ROW.querySelector(`[itemprop=streetAddress]`); if (el) return el.textContent.trim().replace(/\\s+/g, ' '); const addressEl = ROW.querySelector(`address, [itemprop=address], [class*='address' i], [class*='adresse' i]`); const lines = ((addressEl ? addressEl.innerText : ROW.innerText) || '').split(/\\n+/).map(s => s.trim().replace(/\\s+/g, ' ')).filter(Boolean); const line = lines.find(l => /\\b\\d{5}\\b/.test(l) && !/^\\(?0\\d/.test(l)) || lines.find(l => /\\d/.test(l) && !/^\\(?0\\d/.test(l) && !/Treffer|Bewertung|Telefon|Tel\\.|Anrufen/i.test(l)); return line ? line.replace(/\\b\\d{5}\\b.*$/, '').replace(/\\s*\\(?0\\d{2,5}\\)?[\\s\\/-]?\\d[\\d\\s\\/-]{3,}.*$/, '').trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "plz",
            "selector": "(() => { const el = ROW.querySelector(`[itemprop=postalCode]`); if (el) return el.textContent.trim(); const text = (ROW.querySelector(`address, [itemprop=address], [class*='address' i], [class*='adresse' i]`)?.innerText || ROW.innerText || ''); const m = text.match(/\\b(\\d{5})\\b/); return m ? m[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "stadt",
            "selector": "(() => { const el = ROW.querySelector(`[itemprop=addressLocality]`); if (el) return el.textContent.trim().replace(/\\s+/g, ' '); const text = (ROW.querySelector(`address, [itemprop=address], [class*='address' i], [class*='adresse' i]`)?.innerText || ROW.innerText || '').replace(/\\s*\\(?0\\d{2,5}\\)?[\\s\\/-]?\\d[\\d\\s\\/-]{3,}.*$/gm, ''); const m = text.match(/\\b\\d{5}\\s+([^\\n\\r,]+?)(?:\\s{2,}|$)/); return m ? m[1].trim().replace(/\\s+/g, ' ') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "telefonnummer",
            "selector": "(() => { const el = ROW.querySelector(`[itemprop=telephone], a[href^='tel:'], [class*='phone' i], [class*='telefon' i], [class*='tel' i]`); if (el) return (el.getAttribute('href') || el.textContent || '').replace(/^tel:/i, '').trim().replace(/\\s+/g, ' '); const m = (ROW.innerText || '').match(/(\\(?0\\d{2,5}\\)?[\\s\\/-]?\\d[\\d\\s\\/-]{3,})/); return m ? m[1].trim().replace(/\\s+/g, ' ') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "zustand",
            "selector": "(() => { const el = ROW.querySelector(`[class*='open' i], [class*='opening' i], [class*='status' i], time`); if (el) return el.textContent.trim().replace(/\\s+/g, ' '); const m = (ROW.innerText || '').match(/(Geschlossen|Geöffnet|keine Öffnungszeiten|öffnet[^\\n]*|schließt[^\\n]*)/i); return m ? m[1].trim().replace(/\\s+/g, ' ') : ''; })()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "scroll-2",
      "block_type": "process",
      "title": "Scroll",
      "description": "Scroll to pagination/load-more area",
      "position_x": 4060,
      "position_y": 220,
      "config": {
        "direction": "down",
        "amount": 5000,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "sleep-3",
      "block_type": "process",
      "title": "Sleep",
      "description": "Allow pagination controls to render",
      "position_x": 4420,
      "position_y": 220,
      "config": {
        "duration": 1,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "inject-javascript-3",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Mark the visible next or load-more control",
      "position_x": 4780,
      "position_y": 220,
      "config": {
        "jsCode": "(() => { document.querySelectorAll('[data-uscraper-next]').forEach(e => e.removeAttribute('data-uscraper-next')); const isVisible = el => !!(el && (el.offsetWidth || el.offsetHeight || el.getClientRects().length)); const disabled = el => el.matches('[disabled], .disabled, [aria-disabled=\"true\"]') || !!el.closest('.disabled,[aria-disabled=\"true\"]'); const candidates = Array.from(document.querySelectorAll('a, button')).filter(el => isVisible(el) && !disabled(el)); const next = candidates.find(el => { const s = ((el.innerText || '') + ' ' + (el.getAttribute('aria-label') || '') + ' ' + (el.getAttribute('title') || '') + ' ' + (el.getAttribute('rel') || '')).trim(); return /\\b(next|weiter|nächste|naechste|mehr anzeigen|mehr laden|weitere)\\b|›|»/i.test(s); }); if (next) { next.setAttribute('data-uscraper-next', 'true'); return 'marked next/load-more: ' + (next.innerText || next.getAttribute('aria-label') || next.href || next.tagName); } return 'no next/load-more found'; })();",
        "waitForCompletion": true,
        "timeout": 10,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if marked navigation control exists",
      "position_x": 5140,
      "position_y": 220,
      "config": {
        "selector": "[data-uscraper-next='true']",
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "end-1",
      "block_type": "output",
      "title": "End",
      "description": "Terminate execution flow",
      "position_x": 5140,
      "position_y": 560,
      "config": {
        "color": "bg-[#8d8d8d]"
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click marked next/load-more control",
      "position_x": 5500,
      "position_y": 560,
      "config": {
        "selector": "[data-uscraper-next='true']",
        "timeout": 10,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait after navigation click",
      "position_x": 5860,
      "position_y": 560,
      "config": {
        "timeout": 30,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-4",
      "block_type": "process",
      "title": "Sleep",
      "description": "Allow next page or appended results to render",
      "position_x": 6220,
      "position_y": 560,
      "config": {
        "duration": 2,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "wait-for-element-3",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait for business detail links after navigation",
      "position_x": 6580,
      "position_y": 560,
      "config": {
        "selector": "a[href*='/branchenbuch/'][href$='.html']",
        "timeout": 30,
        "visible": true,
        "color": "bg-[#08bdba]"
      }
    }
  ],
  "connections": [
    {
      "from_block_id": "set-window-size-1",
      "from_connector_id": "right",
      "to_block_id": "navigate-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "navigate-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-page-load-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-page-load-1",
      "from_connector_id": "right",
      "to_block_id": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-1",
      "from_connector_id": "right",
      "to_block_id": "sleep-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-1",
      "from_connector_id": "right",
      "to_block_id": "scroll-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "scroll-1",
      "from_connector_id": "right",
      "to_block_id": "sleep-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-2",
      "from_connector_id": "right",
      "to_block_id": "inject-javascript-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-2",
      "from_connector_id": "right",
      "to_block_id": "wait-for-element-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-2",
      "from_connector_id": "right",
      "to_block_id": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-1",
      "from_connector_id": "right",
      "to_block_id": "scroll-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "scroll-2",
      "from_connector_id": "right",
      "to_block_id": "sleep-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-3",
      "from_connector_id": "right",
      "to_block_id": "inject-javascript-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-3",
      "from_connector_id": "right",
      "to_block_id": "element-exists-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "end-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "true",
      "to_block_id": "click-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-page-load-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-page-load-2",
      "from_connector_id": "right",
      "to_block_id": "sleep-4",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-4",
      "from_connector_id": "right",
      "to_block_id": "wait-for-element-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-3",
      "from_connector_id": "right",
      "to_block_id": "scroll-1",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-entry",
      "element_type": "group",
      "title": "Entry & Setup",
      "color": "#4589ff",
      "position_x": 28,
      "position_y": 116,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "set-window-size-1"
        ]
      }
    },
    {
      "id": "group-load",
      "element_type": "group",
      "title": "Page Load",
      "color": "#08bdba",
      "position_x": 388,
      "position_y": 116,
      "width": 6440,
      "height": 636,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "sleep-1",
          "wait-for-element-1",
          "sleep-2",
          "wait-for-element-2",
          "sleep-3",
          "wait-for-page-load-2",
          "sleep-4",
          "wait-for-element-3"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1108,
      "position_y": 116,
      "width": 3920,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1",
          "scroll-1",
          "inject-javascript-2",
          "scroll-2",
          "inject-javascript-3"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 3628,
      "position_y": 116,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-1"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 5068,
      "position_y": 116,
      "width": 680,
      "height": 636,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "click-1"
        ]
      }
    },
    {
      "id": "group-control",
      "element_type": "group",
      "title": "Control Flow",
      "color": "#8d8d8d",
      "position_x": 5068,
      "position_y": 456,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "end-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Scrapes 11880.com business listing search results for a keyword/location pair, extracting the Octoparse-equivalent listing fields: result count, name, company URL, type/category, rating, review count, location/address, street, postal code, city, phone number, and status/opening text. Default target is the Hannover/Maschinenbau listing; edit the Navigate URL for other keyword/location pairs such as /suche/auto/berlin. The workflow waits for stable /branchenbuch/ detail links, scrolls to trigger lazy-loaded results, marks one surrounding listing card per unique company URL, exports only those marked cards, then checks for a visible Next/Weiter/Nächste/Mehr anzeigen control and loops until no navigation control remains.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-inject-javascript-1",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(() => { const labels = ['Accept', 'Akzeptieren', 'Alle akzeptieren', 'Zustimmen', 'OK', 'Einverstan...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 1380,
      "position_y": 200,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "id": "note-block-inject-javascript-2",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(() => { document.querySelectorAll('[data-uscraper-row]').forEach(e => e.removeAttribute('data-uscra...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 3180,
      "position_y": 200,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-2"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (suchergebnisse, name, unternehmen_url, art, kundenbewertung). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 3900,
      "position_y": 200,
      "width": 340,
      "height": 133,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "id": "note-block-inject-javascript-3",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(() => { document.querySelectorAll('[data-uscraper-next]').forEach(e => e.removeAttribute('data-uscr...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 4980,
      "position_y": 200,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-3"
      }
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `[data-uscraper-next='true']`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 5340,
      "position_y": 200,
      "width": 340,
      "height": 139,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    }
  ]
}