{
  "version": "1.0.0",
  "exported_at": "2026-05-31T05:45:00.000Z",
  "project": {
    "name": "Google Maps Email Finder",
    "description": "Best-effort Google Maps business contact scraper for Google Maps place detail pages. Extracts business name, rating, reviews, address, phone, true website/domain when Google Maps exposes one, hours, category, images, coordinates, Google IDs, plus code, emails/social links visible on the loaded page, and current URL. This template is configured with the provided El Recuerdo place URL and uses navigate.urls[] + loop-continue so more Google Maps place URLs can be added for bulk scraping. The supplied target is a place detail page, not a paginated listing; Google Maps may block automation, require consent, change selectors, or omit emails unless they are visible on the Maps page.",
    "color": "bg-[#4589ff]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 120,
      "position_y": 200,
      "config": {
        "urls": [
          "https://www.google.com/maps/place/El+Recuerdo/data=!4m5!3m4!1s0x89c2601f25c8df45:0x9e5eefa7c3455897!8m2!3d40.7674865!4d-73.8209192?authuser=0&hl=en&rclk=1"
        ],
        "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": 480,
      "position_y": 200,
      "config": {
        "timeout": 45
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 840,
      "position_y": 200,
      "config": {
        "selector": "h1",
        "timeout": 45,
        "visible": true
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1200,
      "position_y": 200,
      "config": {
        "duration": 3
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1560,
      "position_y": 200,
      "config": {
        "rowSelector": "body",
        "fileName": "google-maps-contact-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "keyword",
            "selector": "(() => { const cat = ROW.querySelector('button[jsaction*=\"category\"], button.DkEaL'); return (cat?.innerText || '').trim().toLowerCase(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Title",
            "selector": "(ROW.querySelector('h1')?.innerText || '').trim()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Review_Count",
            "selector": "(() => { const txt = ROW.innerText; const m = txt.match(/\\(([\\d,]+)\\)\\s*·/) || txt.match(/([\\d,]+)\\s+reviews/i); return m ? m[1].replace(/,/g, '') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Rating",
            "selector": "(() => { const txt = ROW.innerText; const m = txt.match(/\\b([0-5]\\.\\d)\\s*\\([\\d,]+\\)/); if (m) return m[1]; const e = ROW.querySelector('.F7nice span[aria-hidden=\"true\"]'); return (e?.innerText || '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Address",
            "selector": "(() => { const b = ROW.querySelector('[data-item-id=\"address\"]'); return (b?.getAttribute('aria-label') || b?.innerText || '').replace(/^Address:\\s*/i, '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Country",
            "selector": "(() => { const b = ROW.querySelector('[data-item-id=\"address\"]'); const addr = (b?.getAttribute('aria-label') || b?.innerText || '').replace(/^Address:\\s*/i, ''); return /United States|,\\s*[A-Z]{2}\\s+\\d{5}/.test(addr) ? 'US' : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "City",
            "selector": "(() => { const b = ROW.querySelector('[data-item-id=\"address\"]'); const addr = (b?.getAttribute('aria-label') || b?.innerText || '').replace(/^Address:\\s*/i, ''); const p = addr.split(',').map(s => s.trim()).filter(Boolean); return p.length >= 2 ? p[p.length - 2] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "State",
            "selector": "(() => { const states = {AL:'Alabama',AK:'Alaska',AZ:'Arizona',AR:'Arkansas',CA:'California',CO:'Colorado',CT:'Connecticut',DE:'Delaware',FL:'Florida',GA:'Georgia',HI:'Hawaii',ID:'Idaho',IL:'Illinois',IN:'Indiana',IA:'Iowa',KS:'Kansas',KY:'Kentucky',LA:'Louisiana',ME:'Maine',MD:'Maryland',MA:'Massachusetts',MI:'Michigan',MN:'Minnesota',MS:'Mississippi',MO:'Missouri',MT:'Montana',NE:'Nebraska',NV:'Nevada',NH:'New Hampshire',NJ:'New Jersey',NM:'New Mexico',NY:'New York',NC:'North Carolina',ND:'North Dakota',OH:'Ohio',OK:'Oklahoma',OR:'Oregon',PA:'Pennsylvania',RI:'Rhode Island',SC:'South Carolina',SD:'South Dakota',TN:'Tennessee',TX:'Texas',UT:'Utah',VT:'Vermont',VA:'Virginia',WA:'Washington',WV:'West Virginia',WI:'Wisconsin',WY:'Wyoming'}; const b = ROW.querySelector('[data-item-id=\"address\"]'); const addr = (b?.getAttribute('aria-label') || b?.innerText || '').replace(/^Address:\\s*/i, ''); const m = addr.match(/,\\s*([A-Z]{2})\\s+\\d{5}/); return m ? (states[m[1]] || m[1]) : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Website",
            "selector": "(() => { const a = ROW.querySelector('a[data-item-id=\"authority\"], a[data-item-id*=\"authority\"], a[aria-label^=\"Website:\"]'); let href = a?.href || ''; if (href.includes('/url?q=')) { try { href = new URL(href).searchParams.get('q') || href; } catch(e) {} } return href; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Phone",
            "selector": "(() => { const tel = ROW.querySelector('a[href^=\"tel:\"]')?.getAttribute('href'); if (tel) return tel.replace(/^tel:/, '').trim(); const b = ROW.querySelector('[data-item-id^=\"phone\"]'); return (b?.getAttribute('aria-label') || b?.innerText || '').replace(/^Phone:\\s*/i, '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Open_Time",
            "selector": "(() => Array.from(ROW.querySelectorAll('table.eK4R0e tr')).map(tr => { const day = tr.querySelector('td:first-child')?.innerText.trim() || ''; const hoursCell = tr.querySelector('td:nth-child(2)'); const hours = (hoursCell?.getAttribute('aria-label') || hoursCell?.innerText || '').replace(/\\s+/g, ' ').trim(); return day && hours ? day + ' ' + hours : ''; }).filter(Boolean).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Page_URL",
            "selector": "location.href",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Google_id",
            "selector": "(() => { const m = location.href.match(/(0x[0-9a-f]+:0x[0-9a-f]+)/i); return m ? m[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Place_id",
            "selector": "(() => { const m = ROW.innerText.match(/ChIJ[\\w-]+/); return m ? m[0] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Additional_info",
            "selector": "(() => Array.from(ROW.querySelectorAll('[aria-label^=\"Offers\"], [aria-label^=\"Serves\"]')).map(e => e.getAttribute('aria-label').replace(/^(Offers|Serves)\\s+/i, '').trim()).filter(Boolean).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Latitude",
            "selector": "(() => { let m = location.href.match(/@(-?\\d+\\.\\d+),(-?\\d+\\.\\d+)/); if (!m) m = location.href.match(/!3d(-?\\d+\\.\\d+)!4d(-?\\d+\\.\\d+)/); return m ? m[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Longitude",
            "selector": "(() => { let m = location.href.match(/@(-?\\d+\\.\\d+),(-?\\d+\\.\\d+)/); if (!m) m = location.href.match(/!3d(-?\\d+\\.\\d+)!4d(-?\\d+\\.\\d+)/); return m ? m[2] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Category",
            "selector": "(() => { const b = ROW.querySelector('button[jsaction*=\"category\"], button.DkEaL'); return (b?.innerText || '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Main_image",
            "selector": "(() => Array.from(new Set(Array.from(ROW.querySelectorAll('img[src*=\"googleusercontent.com\"]')).map(i => i.src).filter(src => !/w32-h32|=s32|=w32|w64-h64/i.test(src)))).filter(Boolean)[0] || '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Image_1",
            "selector": "(() => Array.from(new Set(Array.from(ROW.querySelectorAll('img[src*=\"googleusercontent.com\"]')).map(i => i.src).filter(src => !/w32-h32|=s32|=w32|w64-h64/i.test(src)))).filter(Boolean)[1] || '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Image_2",
            "selector": "(() => Array.from(new Set(Array.from(ROW.querySelectorAll('img[src*=\"googleusercontent.com\"]')).map(i => i.src).filter(src => !/w32-h32|=s32|=w32|w64-h64/i.test(src)))).filter(Boolean)[2] || '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Image_3",
            "selector": "(() => Array.from(new Set(Array.from(ROW.querySelectorAll('img[src*=\"googleusercontent.com\"]')).map(i => i.src).filter(src => !/w32-h32|=s32|=w32|w64-h64/i.test(src)))).filter(Boolean)[3] || '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Description",
            "selector": "(() => { const candidates = Array.from(ROW.querySelectorAll('.PYvSYb, [data-attrid=\"description\"], .WeS02d')).map(e => e.innerText.replace(/\\s+/g, ' ').trim()).filter(t => t.length > 40 && !/(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday|Popular times|Directions|Save|Nearby|Reviews|Copy open hours)/i.test(t)); return candidates[0] || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Price_Range",
            "selector": "(() => { const m = ROW.innerText.match(/(?:US)?\\$\\d+\\s*[–-]\\s*\\d+/); return m ? m[0] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Current_Status",
            "selector": "(() => { const txt = ROW.innerText.replace(/\\s+/g, ' '); const m = txt.match(/(Open 24 hours|Open\\s*·\\s*Closes\\s*[^$]{1,30}?M|Closed\\s*·\\s*Opens\\s*[^$]{1,30}?M|Temporarily closed|Permanently closed)/i); return m ? m[1].trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Plus_code_URL",
            "selector": "(() => { const el = ROW.querySelector('[data-item-id*=\"oloc\"], [aria-label*=\"Plus code\"]'); const pc = (el?.getAttribute('aria-label') || el?.innerText || '').replace(/^Plus code:\\s*/i, '').trim(); return pc ? 'https://plus.codes/' + encodeURIComponent(pc) : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Plus_code",
            "selector": "(() => { const el = ROW.querySelector('[data-item-id*=\"oloc\"], [aria-label*=\"Plus code\"]'); return (el?.getAttribute('aria-label') || el?.innerText || '').replace(/^Plus code:\\s*/i, '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Delivery",
            "selector": "(() => Array.from(ROW.querySelectorAll('[aria-label^=\"Offers\"], [aria-label^=\"Serves\"]')).map(e => e.getAttribute('aria-label').replace(/^(Offers|Serves)\\s+/i, '').trim()).filter(Boolean).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Open_Time_Monday",
            "selector": "(() => { const tr = Array.from(ROW.querySelectorAll('table.eK4R0e tr')).find(r => /Monday/i.test(r.innerText)); if (!tr) return ''; const hoursCell = tr.querySelector('td:nth-child(2)'); return 'Monday ' + ((hoursCell?.getAttribute('aria-label') || hoursCell?.innerText || '').replace(/\\s+/g, ' ').trim()); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Open_Time_Tuesday",
            "selector": "(() => { const tr = Array.from(ROW.querySelectorAll('table.eK4R0e tr')).find(r => /Tuesday/i.test(r.innerText)); if (!tr) return ''; const hoursCell = tr.querySelector('td:nth-child(2)'); return 'Tuesday ' + ((hoursCell?.getAttribute('aria-label') || hoursCell?.innerText || '').replace(/\\s+/g, ' ').trim()); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Open_Time_Wednesday",
            "selector": "(() => { const tr = Array.from(ROW.querySelectorAll('table.eK4R0e tr')).find(r => /Wednesday/i.test(r.innerText)); if (!tr) return ''; const hoursCell = tr.querySelector('td:nth-child(2)'); return 'Wednesday ' + ((hoursCell?.getAttribute('aria-label') || hoursCell?.innerText || '').replace(/\\s+/g, ' ').trim()); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Open_Time_Thursday",
            "selector": "(() => { const tr = Array.from(ROW.querySelectorAll('table.eK4R0e tr')).find(r => /Thursday/i.test(r.innerText)); if (!tr) return ''; const hoursCell = tr.querySelector('td:nth-child(2)'); return 'Thursday ' + ((hoursCell?.getAttribute('aria-label') || hoursCell?.innerText || '').replace(/\\s+/g, ' ').trim()); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Open_Time_Friday",
            "selector": "(() => { const tr = Array.from(ROW.querySelectorAll('table.eK4R0e tr')).find(r => /Friday/i.test(r.innerText)); if (!tr) return ''; const hoursCell = tr.querySelector('td:nth-child(2)'); return 'Friday ' + ((hoursCell?.getAttribute('aria-label') || hoursCell?.innerText || '').replace(/\\s+/g, ' ').trim()); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Open_Time_Saturday",
            "selector": "(() => { const tr = Array.from(ROW.querySelectorAll('table.eK4R0e tr')).find(r => /Saturday/i.test(r.innerText)); if (!tr) return ''; const hoursCell = tr.querySelector('td:nth-child(2)'); return 'Saturday ' + ((hoursCell?.getAttribute('aria-label') || hoursCell?.innerText || '').replace(/\\s+/g, ' ').trim()); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Open_Time_Sunday",
            "selector": "(() => { const tr = Array.from(ROW.querySelectorAll('table.eK4R0e tr')).find(r => /Sunday/i.test(r.innerText)); if (!tr) return ''; const hoursCell = tr.querySelector('td:nth-child(2)'); return 'Sunday ' + ((hoursCell?.getAttribute('aria-label') || hoursCell?.innerText || '').replace(/\\s+/g, ' ').trim()); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Popular_times_All",
            "selector": "(() => Array.from(ROW.querySelectorAll('.dpoVLd[aria-label]')).map(e => e.getAttribute('aria-label')).filter(Boolean).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Start_URL",
            "selector": "location.href",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Domain",
            "selector": "(() => { const a = ROW.querySelector('a[data-item-id=\"authority\"], a[data-item-id*=\"authority\"], a[aria-label^=\"Website:\"]'); let href = a?.href || ''; if (href.includes('/url?q=')) { try { href = new URL(href).searchParams.get('q') || href; } catch(e) {} } try { return href ? new URL(href).hostname.replace(/^www\\./, '') : ''; } catch(e) { return ''; } })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Depth",
            "selector": "'0'",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Referrer_URL",
            "selector": "document.referrer || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Current_URL",
            "selector": "location.href",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Emails",
            "selector": "(() => Array.from(new Set((ROW.innerText.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi) || []))).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Phones",
            "selector": "(() => { const values = []; const tel = ROW.querySelector('a[href^=\"tel:\"]')?.getAttribute('href'); if (tel) values.push(tel.replace(/^tel:/, '').trim()); const textPhones = ROW.innerText.match(/\\+?1?[\\s.-]?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}/g) || []; values.push(...textPhones); return Array.from(new Set(values.map(v => v.trim()).filter(Boolean))).join('; '); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Uncertain_Phones",
            "selector": "(() => Array.from(new Set((ROW.innerText.match(/\\b\\d{3}[\\s.-]\\d{3}[\\s.-]\\d{4}\\b/g) || []))).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Twitter",
            "selector": "(() => Array.from(ROW.querySelectorAll('a[href*=\"twitter.com\"], a[href*=\"x.com\"]')).map(a => a.href).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "YouTube",
            "selector": "(() => Array.from(ROW.querySelectorAll('a[href*=\"youtube.com\"], a[href*=\"youtu.be\"]')).map(a => a.href).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Facebook",
            "selector": "(() => Array.from(ROW.querySelectorAll('a[href*=\"facebook.com\"]')).map(a => a.href).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "LinkedIn",
            "selector": "(() => Array.from(ROW.querySelectorAll('a[href*=\"linkedin.com\"]')).map(a => a.href).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Instagram",
            "selector": "(() => Array.from(ROW.querySelectorAll('a[href*=\"instagram.com\"]')).map(a => a.href).join('; '))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Tiktok",
            "selector": "(() => Array.from(ROW.querySelectorAll('a[href*=\"tiktok.com\"]')).map(a => a.href).join('; '))()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 1920,
      "position_y": 200,
      "config": {}
    }
  ],
  "connections": [
    {
      "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": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-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": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-1",
      "from_connector_id": "right",
      "to_block_id": "loop-continue-1",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-load",
      "element_type": "group",
      "title": "Page Load",
      "color": "#08bdba",
      "position_x": 48,
      "position_y": 96,
      "width": 1400,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1",
          "sleep-1"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 1488,
      "position_y": 96,
      "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": 1848,
      "position_y": 96,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Best-effort Google Maps business contact scraper for Google Maps place detail pages. Extracts business name, rating, reviews, address, phone, true website/domain when Google Maps exposes one, hours, category, images, coordinates, Google IDs, plus code, emails/social links visible on the loaded page, and current URL. This template is configured with the provided El Recuerdo place URL and uses navigate.urls[] + loop-continue so more Google Maps place URLs can be added for bulk scraping. The supplied target is a place detail page, not a paginated listing; Google Maps may block automation, require consent, change selectors, or omit emails unless they are visible on the Maps page.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (keyword, Title, Review_Count, Rating, Address). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 1760,
      "position_y": 180,
      "width": 340,
      "height": 129,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "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": 2120,
      "position_y": 180,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}