{
  "version": "1.0.0",
  "exported_at": "2026-05-31T14:50:00.000Z",
  "project": {
    "name": "Google Shopping Price Monitor by Keyword",
    "description": "Best-effort Google Shopping keyword price monitor equivalent to the Octoparse template. Uses Google Shopping for the default keyword iPad and extracts keyword, product name, product URL, rating, review count, tags, price, original price, discount information, store, product source URL, delivery/returns, and product image when Google Shopping product cards are accessible. Pagination is handled by clicking the Google Shopping Next link until no further page exists; append mode is used across pages. Autonomous testing showed Google blocks this browser profile with unsupported-browser / CAPTCHA / anti-bot pages, so a diagnostic fallback row is exported when no product rows are available. In a non-blocked browser profile or with an appropriate proxy/user environment, the product extraction branch is used.",
    "color": "bg-[#4589ff]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "set-window-size-1",
      "block_type": "process",
      "title": "Set Window Size",
      "description": "Set browser window dimensions",
      "position_x": 120,
      "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": 456,
      "position_y": 220,
      "config": {
        "urls": [
          "https://www.google.com/search?igu=1&hl=en&gl=us&pws=0&tbm=shop&q=iPad"
        ],
        "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": 792,
      "position_y": 220,
      "config": {
        "timeout": 30,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 1128,
      "position_y": 220,
      "config": {
        "selector": "//button[contains(., 'Accept all') or contains(., 'I agree') or contains(., 'Accept')]",
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 1464,
      "position_y": 520,
      "config": {
        "selector": "//button[contains(., 'Accept all') or contains(., 'I agree') or contains(., 'Accept')]",
        "timeout": 10,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1800,
      "position_y": 520,
      "config": {
        "duration": 3,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-3",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1128,
      "position_y": 520,
      "config": {
        "duration": 4,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "element-exists-2",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 2136,
      "position_y": 520,
      "config": {
        "selector": "div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id], a[href*='/shopping/product/']",
        "color": "bg-[#42be65]"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 2472,
      "position_y": 520,
      "config": {
        "rowSelector": "div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id], a[href*='/shopping/product/']",
        "fileName": "google-shopping-price-monitor-by-keyword.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "color": "bg-[#42be65]",
        "columns": [
          {
            "name": "Keyword",
            "selector": "(() => { const p = new URLSearchParams(location.search); const direct = p.get('q') || p.get('oq'); if (direct && !/^EgQ/i.test(direct)) return direct; const cont = p.get('continue'); if (cont) { try { const cp = new URLSearchParams(new URL(cont).search); return cp.get('q') || cp.get('oq') || 'iPad'; } catch(e) {} } return 'iPad'; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ProductName",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const candidates = ['h3.tAxDx','h3','h4','[role=\"heading\"]','.Xjkr3b','.EI11Pd','.rgHvZc']; for (const s of candidates) { const t = CARD.querySelector(s)?.textContent?.trim(); if (t && !/sponsored|google shopping|shop on google/i.test(t)) return t; } if (ROW.matches && ROW.matches('a')) { const at = ROW.textContent.trim(); if (at && at.length > 5) return at; } const anchors = Array.from(CARD.querySelectorAll('a')).map(a => a.textContent.trim()).filter(Boolean); const anchorTitle = anchors.find(x => x.length > 8 && !/^\\$/.test(x)); if (anchorTitle) return anchorTitle; const lines = (CARD.textContent || '').split('\\n').map(x => x.trim()).filter(Boolean); return lines.find(x => !/^\\$/.test(x) && x.length > 8 && !/rating|review|delivery|shipping/i.test(x)) || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ProductURL",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const direct = (ROW.matches && ROW.matches('a[href]')) ? ROW : null; const anchors = Array.from(CARD.querySelectorAll('a[href]')); const a = direct || anchors.find(x => (x.getAttribute('href') || '').includes('/shopping/product/')) || anchors.find(x => /shopping\\/product/i.test(x.href)) || anchors[0]; if (!a) return ''; return new URL(a.getAttribute('href'), location.origin).href; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Rating",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const text = Array.from(CARD.querySelectorAll('[aria-label]')).map(e => e.getAttribute('aria-label')).join(' ') + ' ' + (CARD.textContent || ''); const m = text.match(/([0-5](?:\\.\\d)?)\\s*(?:out of 5|stars?)/i) || text.match(/Rated\\s+([0-5](?:\\.\\d)?)/i); return m ? m[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ReviewCount",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const text = Array.from(CARD.querySelectorAll('[aria-label]')).map(e => e.getAttribute('aria-label')).join(' ') + ' ' + (CARD.textContent || ''); const m = text.match(/([\\d,]+)\\s*(?:product\\s*)?reviews?/i) || text.match(/\\(([\\d,]+)\\)/); return m ? m[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Tags",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const labels = Array.from(CARD.querySelectorAll('[aria-label*=\"star\"], [aria-label*=\"review\"], .NzUzee, .QIrs8')).map(e => (e.getAttribute('aria-label') || e.textContent || '').trim()).filter(Boolean); if (labels.length) return labels.join(' | '); const text = CARD.textContent || ''; const m = text.match(/[0-5](?:\\.\\d)?\\s*(?:out of 5|stars?).*?(?:[\\d,]+\\s*reviews?)?/i); return m ? m[0] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Price",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const direct = CARD.querySelector('.a8Pemb, .HRLxBb, .T14wmb, .e10twf, [aria-label*=\"$\"]')?.textContent?.trim(); const txt = direct || CARD.textContent || ''; const m = txt.match(/\\$\\s?\\d[\\d,]*(?:\\.\\d{2})?/); return m ? m[0] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "OriginalPrice",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const el = CARD.querySelector('del, s, .SUZt4c, .F7Kwhf, [aria-label*=\"original\"]'); if (el && el.textContent.trim()) return el.textContent.trim(); const prices = (CARD.textContent || '').match(/\\$\\s?\\d[\\d,]*(?:\\.\\d{2})?/g) || []; return prices.length > 1 ? prices[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "DiscountInfomation",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const lines = (CARD.textContent || '').split('\\n').map(s => s.trim()).filter(Boolean); return lines.find(s => /apply|coupon|save|discount|off|sale|deal/i.test(s)) || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Store",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const direct = CARD.querySelector('.aULzUe, .IuHnof, .E5ocAb, .zPEcBd, [data-merchant-name]')?.textContent?.trim() || CARD.getAttribute('data-merchant-name') || ''; if (direct) return direct.trim(); const lines = (CARD.textContent || '').split('\\n').map(s => s.trim()).filter(Boolean); const storeLine = lines.find(s => /best buy|walmart|ebay|amazon|target|back market|newegg|b&h|costco|club|store|seller|wholesale|market/i.test(s)); if (storeLine) return storeLine; const priceIndex = lines.findIndex(s => /\\$\\s?\\d/.test(s)); return priceIndex >= 0 && lines[priceIndex + 1] ? lines[priceIndex + 1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ProductSourceURL",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const anchors = Array.from(CARD.querySelectorAll('a[href]')); const a = anchors.find(x => { const h = x.getAttribute('href') || ''; return h && !h.includes('/shopping/product/') && !h.startsWith('#'); }); if (!a) return ''; const u = new URL(a.getAttribute('href'), location.href); return u.searchParams.get('q') || u.searchParams.get('url') || u.searchParams.get('adurl') || u.href; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "DeliveryAndRerurns",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const lines = (CARD.textContent || '').split('\\n').map(s => s.trim()).filter(Boolean); return lines.find(s => /delivery|shipping|return|returns|pickup/i.test(s)) || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ProductImage",
            "selector": "(() => { const CARD = ROW.closest('div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]') || ROW; const img = CARD.querySelector('img[src], img[data-src]'); return img ? (img.getAttribute('data-src') || img.currentSrc || img.src || '') : ''; })()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "element-exists-3",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 2808,
      "position_y": 520,
      "config": {
        "selector": "a#pnnext, a[aria-label='Next page'], a[aria-label='Next']",
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "click-2",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 3144,
      "position_y": 520,
      "config": {
        "selector": "a#pnnext, a[aria-label='Next page'], a[aria-label='Next']",
        "timeout": 10,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 3480,
      "position_y": 520,
      "config": {
        "timeout": 30,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 3816,
      "position_y": 758,
      "config": {
        "duration": 4,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "structured-export-2",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 2136,
      "position_y": 520,
      "config": {
        "rowSelector": "body",
        "fileName": "google-shopping-price-monitor-by-keyword.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "color": "bg-[#f1c21b]",
        "columns": [
          {
            "name": "Keyword",
            "selector": "(() => { const p = new URLSearchParams(location.search); const direct = p.get('q'); if (direct && !/^EgQ/i.test(direct)) return direct; const cont = p.get('continue'); if (cont) { try { const cp = new URLSearchParams(new URL(cont).search); return cp.get('q') || cp.get('oq') || 'iPad'; } catch(e) {} } return 'iPad'; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ProductName",
            "selector": "(() => 'NO_PRODUCT_ROWS_FOUND_OR_GOOGLE_BLOCKED')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ProductURL",
            "selector": "(() => location.href)()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Rating",
            "selector": "''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ReviewCount",
            "selector": "''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Tags",
            "selector": "(() => { const h = document.querySelector('h1,h2')?.textContent?.trim() || document.title || ''; return 'Blocked or unsupported page: ' + h; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Price",
            "selector": "''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "OriginalPrice",
            "selector": "''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "DiscountInfomation",
            "selector": "''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Store",
            "selector": "'Google Shopping'",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ProductSourceURL",
            "selector": "(() => location.href)()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "DeliveryAndRerurns",
            "selector": "''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ProductImage",
            "selector": "''",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 1632,
      "position_y": 800,
      "config": {
        "color": "bg-[#8d8d8d]"
      }
    },
    {
      "block_id": "loop-continue-2",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 2808,
      "position_y": 520,
      "config": {
        "color": "bg-[#8d8d8d]"
      }
    }
  ],
  "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": "element-exists-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": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "sleep-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-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": "element-exists-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-3",
      "from_connector_id": "right",
      "to_block_id": "element-exists-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-2",
      "from_connector_id": "true",
      "to_block_id": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-2",
      "from_connector_id": "false",
      "to_block_id": "structured-export-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-1",
      "from_connector_id": "right",
      "to_block_id": "element-exists-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-3",
      "from_connector_id": "true",
      "to_block_id": "click-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-3",
      "from_connector_id": "false",
      "to_block_id": "loop-continue-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-2",
      "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-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-2",
      "from_connector_id": "right",
      "to_block_id": "element-exists-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-2",
      "from_connector_id": "right",
      "to_block_id": "loop-continue-1",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-entry",
      "element_type": "group",
      "title": "Entry & Setup",
      "color": "#4589ff",
      "position_x": 48,
      "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": 384,
      "position_y": 116,
      "width": 3680,
      "height": 834,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "sleep-1",
          "sleep-3",
          "wait-for-page-load-2",
          "sleep-2"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 1056,
      "position_y": 116,
      "width": 2336,
      "height": 876,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "click-1",
          "element-exists-2",
          "element-exists-3",
          "click-2",
          "loop-continue-1",
          "loop-continue-2"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 2064,
      "position_y": 416,
      "width": 656,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-1",
          "structured-export-2"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Best-effort Google Shopping keyword price monitor equivalent to the Octoparse template. Uses Google Shopping for the default keyword iPad and extracts keyword, product name, product URL, rating, review count, tags, price, original price, discount information, store, product source URL, delivery/returns, and product image when Google Shopping product cards are accessible. Pagination is handled by clicking the Google Shopping Next link until no further page exists; append mode is used across pages. Autonomous testing showed Google blocks this browser profile with unsupported-browser / CAPTCHA / anti-bot pages, so a diagnostic fallback row is exported when no product rows are available. In a non-blocked browser profile or with an appropriate proxy/user environment, the product extraction branch is used.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `//button[contains(., 'Accept all') or contains(., 'I agree') or contains(., 'Accept')]`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 1328,
      "position_y": 200,
      "width": 340,
      "height": 159,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    },
    {
      "id": "note-block-element-exists-2",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `div.sh-dgr__grid-result, div.sh-dlr__list-result, div.i0X6df, div[data-docid], div[data-merchant-id], [data-merchant-id]`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 2336,
      "position_y": 500,
      "width": 340,
      "height": 170,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-2"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (Keyword, ProductName, ProductURL, Rating, ReviewCount). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 2672,
      "position_y": 500,
      "width": 340,
      "height": 131,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "id": "note-block-element-exists-3",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `a#pnnext, a[aria-label='Next page'], a[aria-label='Next']`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 3008,
      "position_y": 500,
      "width": 340,
      "height": 149,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-3"
      }
    },
    {
      "id": "note-block-click-2",
      "element_type": "note",
      "title": "Note: Click",
      "content": "Pagination click — add waits after this block; the page reloads asynchronously.",
      "color": "#ee5396",
      "position_x": 3344,
      "position_y": 500,
      "width": 316,
      "height": 106,
      "z_index": 22,
      "data": {
        "block_id": "click-2"
      }
    },
    {
      "id": "note-block-structured-export-2",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (Keyword, ProductName, ProductURL, Rating, ReviewCount). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 2336,
      "position_y": 500,
      "width": 340,
      "height": 131,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-2"
      }
    },
    {
      "id": "note-block-loop-continue-1",
      "element_type": "note",
      "title": "Note: Loop Continue",
      "content": "Loop Continue advances a multi-URL or multi-text loop. Place at the end of the loop body with a clear back-edge to the loop start.",
      "color": "#ee5396",
      "position_x": 1832,
      "position_y": 780,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    },
    {
      "id": "note-block-loop-continue-2",
      "element_type": "note",
      "title": "Note: Loop Continue",
      "content": "Loop Continue advances a multi-URL or multi-text loop. Place at the end of the loop body with a clear back-edge to the loop start.",
      "color": "#ee5396",
      "position_x": 3008,
      "position_y": 500,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-2"
      }
    }
  ]
}