{
  "createdAt": "2025-05-01T14:25:34.686Z",
  "updatedAt": "2025-05-21T08:31:27.000Z",
  "id": "4knuqjqMJ0PLaqoY",
  "name": "YouTube AI analys",
  "active": false,
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ],
      "id": "542dc144-25f4-47a2-9087-b1cfac13077e",
      "name": "Schedule Trigger"
    },
    {
      "parameters": {
        "resource": "playlistItem",
        "operation": "getAll",
        "playlistId": "=UUPjNBjflYl0-HQtUvOx0Ibw",
        "part": [
          "snippet",
          "contentDetails"
        ],
        "options": {}
      },
      "type": "n8n-nodes-base.youTube",
      "typeVersion": 1,
      "position": [
        220,
        -500
      ],
      "id": "1a068f33-e325-47d8-8f29-c6dc7793defc",
      "name": "Greg Isenberg",
      "credentials": {
        "youTubeOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "playlistItem",
        "operation": "getAll",
        "playlistId": "=UUbo-KbSjJDG6JWQ_MTZ_rNA",
        "part": [
          "snippet",
          "contentDetails"
        ],
        "options": {}
      },
      "type": "n8n-nodes-base.youTube",
      "typeVersion": 1,
      "position": [
        220,
        -300
      ],
      "id": "900640c4-c00f-49f5-8cd7-9d3829aac422",
      "name": "Nick Saraev",
      "credentials": {
        "youTubeOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "playlistItem",
        "operation": "getAll",
        "playlistId": "=UU08Fah8EIryeOZRkjBRohcQ",
        "part": [
          "snippet",
          "contentDetails"
        ],
        "options": {}
      },
      "type": "n8n-nodes-base.youTube",
      "typeVersion": 1,
      "position": [
        220,
        -120
      ],
      "id": "40ca1cbc-5aef-48d0-aea3-089d799f6825",
      "name": "Creator Magic",
      "credentials": {
        "youTubeOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "playlistItem",
        "operation": "getAll",
        "playlistId": "=UUMwVTLZIRRUyyVrkjDpn4pA",
        "part": [
          "snippet",
          "contentDetails"
        ],
        "options": {}
      },
      "type": "n8n-nodes-base.youTube",
      "typeVersion": 1,
      "position": [
        220,
        120
      ],
      "id": "3d5d3f74-d3e1-4b12-a8d6-3696dbbdfa84",
      "name": "Cole Medin",
      "credentials": {
        "youTubeOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "playlistItem",
        "operation": "getAll",
        "playlistId": "=UUI4xxi0p97BghIqgEPYx6sw",
        "part": [
          "snippet",
          "contentDetails"
        ],
        "options": {}
      },
      "type": "n8n-nodes-base.youTube",
      "typeVersion": 1,
      "position": [
        220,
        320
      ],
      "id": "4d90034a-3366-42fd-8209-6bba486affdf",
      "name": "Your AI Workflow",
      "credentials": {
        "youTubeOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "playlistItem",
        "operation": "getAll",
        "playlistId": "=UUc-FovAyBAQDw2Y7PQ_v0Zw",
        "part": [
          "snippet",
          "contentDetails"
        ],
        "options": {}
      },
      "type": "n8n-nodes-base.youTube",
      "typeVersion": 1,
      "position": [
        220,
        520
      ],
      "id": "57e2f9c8-48e9-4e6f-b229-b6ce5b8f9539",
      "name": "Julian Goldie SEO",
      "credentials": {
        "youTubeOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u043c transcript\nreturn items.filter(item => {\n  // \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435 error \u0438\u043b\u0438 transcript === undefined, \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c\n  if (item.json.error) return false;\n  if (item.json.transcript === undefined) return false;\n  return true;\n});\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2400,
        -1380
      ],
      "id": "bb78f923-8449-4bf6-88ff-f1028cb00ebf",
      "name": "Error Filter"
    },
    {
      "parameters": {
        "url": "https://youtube-transcript3.p.rapidapi.com/api/transcript",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "videoId",
              "value": "={{ $json.videoId }}"
            },
            {
              "name": "Title",
              "value": "={{ $json.title }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "=X-RapidAPI-Host",
              "value": "=youtube-transcript3.p.rapidapi.com"
            },
            {
              "name": "=X-RapidAPI-Key",
              "value": "=f7f02f04f5mshc37f3e7eedb6f29p111f4djsn60e622f16916"
            }
          ]
        },
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 100000
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1900,
        -1540
      ],
      "id": "7ffd3eee-efff-4825-809b-33d7e0aa1757",
      "name": "youtube video parser"
    },
    {
      "parameters": {
        "jsCode": "// \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u00ab\u043d\u0435\u0434\u0435\u043b\u044e \u043d\u0430\u0437\u0430\u0434\u00bb\nconst oneWeekAgo = Date.now() - 1 * 48 * 60 * 60 * 1000;\n\n// \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u043e \u0434\u0430\u0442\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0438\u0437 snippet.publishedAt\nconst recentItems = items.filter(item => {\n  const pubDate = new Date(item.json.snippet.publishedAt).getTime();\n  return pubDate >= oneWeekAgo;\n});\n\nreturn recentItems;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1000,
        -20
      ],
      "id": "25249b4c-315f-4cc3-96fc-91e00a76a907",
      "name": "24 hours"
    },
    {
      "parameters": {
        "jsCode": "// \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043c \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b transcript \u0432 \u043e\u0434\u0438\u043d \u0442\u0435\u043a\u0441\u0442\nconst segs = $json.transcript || [];\nconst fullText = segs.map(s => s.text).join(' ');\n// \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0434\u0430\u043b\u044c\u0448\u0435 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f + \u043d\u043e\u0432\u043e\u0435\nreturn [{\n  json: {\n    ...$json,\n    transcript_original: fullText\n  }\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2620,
        -1380
      ],
      "id": "11690ba9-a3f8-4925-9fd4-b52ca86461dc",
      "name": "add transcript_original"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://openrouter.ai/api/v1/chat/completions",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{\n  JSON.stringify({\n    model: \"google/gemini-2.5-pro-exp-03-25\",\n    messages: [\n      {\n        role: \"system\",\n        content: \"You are an instructional designer. Given the user\u2019s transcript text, identify the 4\u20136 major topics covered and for each provide a concise, detailed description (2\u20133 sentences). Output the result as a JSON array of objects with the schema [{\\\"topic\\\":\\\"...\\\",\\\"detail\\\":\\\"...\\\"}, \u2026]. Do not add any extra commentary.\"\n      },\n      {\n        role: \"user\",\n        content: $json.chunk\n      }\n    ]\n  })\n}}\n",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 10000
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        3600,
        -1520
      ],
      "id": "a4dd0a31-cf26-4290-bde5-defe8016e61e",
      "name": "Chat Completion"
    },
    {
      "parameters": {
        "jsCode": "// \u0411\u0435\u0440\u0451\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\nconst input = items[0].json;\nconst fullText = input.choices[0].message.content;\nconst { title, url, publishedAt, videoId } = input;\n\n// \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0447\u0430\u043d\u043a\u0430\nconst maxLen = 3000;\n\n// \u0420\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u0447\u043a\u0438, \u0432\u043e\u0441\u043a\u043b. \u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u0438\u0442. \u0437\u043d\u0430\u043a\u0438)\nconst sentences = fullText.match(/[^\\.!\\?]+[\\.!\\?]+/g) || [fullText];\n\n// \u041d\u0430\u043a\u043e\u043f\u0438\u0442\u0435\u043b\u044c\nlet chunks = [];\nlet current = '';\n\n// \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044e\nfor (const sentence of sentences) {\n  if ((current + sentence).length <= maxLen) {\n    current += sentence + ' ';\n  } else {\n    if (current) chunks.push(current.trim());\n    current = sentence + ' ';\n  }\n}\n// \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0447\u0430\u043d\u043a\nif (current) chunks.push(current.trim());\n\n// \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0432 items, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043f\u0435\u0440\u0432\u044b\u0439\nreturn chunks.map((textChunk, index) => {\n  const base = { chunk: textChunk };\n  if (index === 0) {\n    // \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\n    return {\n      json: {\n        ...base,\n        title,\n        url,\n        publishedAt,\n        videoId,\n      },\n    };\n  }\n  // \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u2014 \u0442\u043e\u043b\u044c\u043a\u043e chunk\n  return { json: base };\n});\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3380,
        -1380
      ],
      "id": "cfbef56e-90f4-4384-a1b4-3390054695a7",
      "name": "Split to Chunks"
    },
    {
      "parameters": {
        "jsCode": "// \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438\u0437 \u0432\u0441\u0435\u0445 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0430\u0439\u0442\u0435\u043c\u043e\u0432\nlet allFullText = '';\n\n// \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445, \u0431\u0435\u0440\u0435\u043c \u0438\u0445 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430\nlet title, url, publishedAt, videoId;\n\n// \u0411\u0435\u0440\u0435\u043c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\nif (items.length > 0 && items[0].json) {\n  const firstItemJson = items[0].json;\n  title = firstItemJson.title;\n  url = firstItemJson.url;\n  publishedAt = firstItemJson.publishedAt;\n  videoId = firstItemJson.videoId;\n}\n\n\n// \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u0430\u0439\u0442\u0435\u043c\u0430\u043c \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\nfor (const item of items) {\n  // \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u043f\u043e\u043b\u0435 \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0430\u0439\u0442\u0435\u043c\u0435\n  if (item.json && item.json.choices && item.json.choices[0] && item.json.choices[0].message && item.json.choices[0].message.content) {\n    // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430 \u043a \u043e\u0431\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0435.\n    // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u0442\u0435\u043a\u0441\u0442\u0430\u043c\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u0430\u0439\u0442\u0435\u043c\u043e\u0432 \u0434\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f.\n    allFullText += item.json.choices[0].message.content + '\\n';\n  }\n}\n\n// \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0447\u0430\u043d\u043a\u0430 (\u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0435\u0439)\nconst maxLen = 3000;\n\n// \u0420\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u043d\u0430 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\n// \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 allFullText \u043f\u0443\u0441\u0442\u043e\u0439\nconst sentences = allFullText.match(/[^\\.!\\?]+[\\.!\\?]+/g) || (allFullText ? [allFullText] : []);\n\n\n// \u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0447\u0430\u043d\u043a\u0438 \u0438\u0437 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0435\u0439)\nlet chunks = [];\nlet current = '';\nfor (const sentence of sentences) {\n  // \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u0438\u0437 \u043d\u0430\u0447\u0430\u043b\u0430/\u043a\u043e\u043d\u0446\u0430 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u0434\u043b\u0438\u043d\u044b\n  const trimmedSentence = sentence.trim();\n  if (!trimmedSentence) continue; // \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0443\u0441\u0442\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u043e\u0441\u043b\u0435 trim\n\n  // \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u0441\u044f \u043b\u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0447\u0430\u043d\u043a\n  // \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0431\u0435\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\n  if ((current + trimmedSentence).length + (current ? 1 : 0) <= maxLen) {\n    current += trimmedSentence + ' ';\n  } else {\n    // \u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0447\u0430\u043d\u043a \u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0439, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0447\u0430\u043d\u043a\u043e\u0432\n    if (current) chunks.push(current.trim());\n    // \u041d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0447\u0430\u043d\u043a \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\n    current = trimmedSentence + ' ';\n  }\n}\n// \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0447\u0430\u043d\u043a, \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0439\nif (current) chunks.push(current.trim());\n\n\n// \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0447\u0430\u043d\u043a\u0438 \u0432 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0430\u0439\u0442\u0435\u043c\u044b.\n// \u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043f\u0435\u0440\u0432\u043e\u043c\u0443 \u0447\u0430\u043d\u043a\u0443 \u043e\u0431\u0449\u0435\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430.\nreturn chunks.map((text, idx) => {\n  const base = { summary_points: text };\n  if (idx === 0) {\n    // \u0422\u043e\u043b\u044c\u043a\u043e \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u043c \u0430\u0439\u0442\u0435\u043c\u0435 (\u043f\u0435\u0440\u0432\u043e\u043c \u0447\u0430\u043d\u043a\u0435) \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430\n    return {\n      json: {\n        ...base,\n        title, // \u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430\n        url,\n        publishedAt,\n        videoId,\n      }\n    };\n  }\n  // \u0414\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0447\u0430\u043d\u043a\u043e\u0432 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043a\u0441\u0442\n  return { json: base };\n});"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4060,
        -1380
      ],
      "id": "de080fd8-d7aa-4c0c-b76b-4634851217df",
      "name": "Summarizer"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "60d0d292-7f04-40b4-acf3-8a64c13acd26",
              "name": "title",
              "value": "={{ $json.snippet.title }}",
              "type": "string"
            },
            {
              "id": "753c7ef6-4008-4b16-81f0-7fbe291f015a",
              "name": "url",
              "value": "=https://youtube.com/watch?v={{ $json.snippet.resourceId.videoId }}",
              "type": "string"
            },
            {
              "id": "b51008a2-7ca7-408c-b212-f8a441d7c3e5",
              "name": "publishedAt",
              "value": "={{ $json.snippet.publishedAt }}",
              "type": "string"
            },
            {
              "id": "32915e1e-22a5-452f-a234-8371d3993da3",
              "name": "videoId",
              "value": "={{ $json.snippet.resourceId.videoId }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1680,
        -1380
      ],
      "id": "d0e6b142-8d7d-4a02-af47-6f6dbc0be845",
      "name": "Parse title ulr and publishedAt"
    },
    {
      "parameters": {
        "jsCode": "// Node 1: Clean the raw string containing the JSON array\n\n// \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u0432\u0441\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0441\u044b\u0440\u043e\u0439 JSON \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0430\u0439\u0442\u0435\u043c\u043e\u0432\nlet combinedRawJsonString = '';\n\n// \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445, \u0431\u0435\u0440\u0435\u043c \u0438\u0445 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430\nlet title, url;\n\n// \u0411\u0435\u0440\u0435\u043c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 (title, url) \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\nif (items.length > 0 && items[0].json) {\n    const firstInputItemJson = items[0].json;\n    title = firstInputItemJson.title;\n    url = firstInputItemJson.url;\n    // publishedAt \u0438 videoId \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b, \u043d\u043e \u0432 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0432 \u0432\u044b\u0445\u043e\u0434\u0435 \u044d\u0442\u043e\u0433\u043e \u0443\u0437\u043b\u0430.\n}\n\n// \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u0430\u0439\u0442\u0435\u043c\u0430\u043c \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u043e\u043b\u044f summary_points\nfor (const item of items) {\n    // \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u043f\u043e\u043b\u0435 summary_points \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0430\u0439\u0442\u0435\u043c\u0435\n    if (item.json && item.json.summary_points) {\n        // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 summary_points \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430 \u043a \u043e\u0431\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0435\n        // \u041f\u0440\u043e\u0441\u0442\u043e \u043a\u043e\u043d\u043a\u0430\u0442\u0435\u043d\u0438\u0440\u0443\u0435\u043c, \u0442.\u043a. \u0447\u0438\u0441\u0442\u043a\u0430 \u043d\u0438\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c\u0438 \u0440\u0430\u0437\u0440\u044b\u0432\u0430\u043c\u0438\n        combinedRawJsonString += item.json.summary_points;\n    }\n}\n\n// \u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u043e\u0439 \u0441\u044b\u0440\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439\nlet cleanedJsonString = combinedRawJsonString;\n\n// --- Cleaning Steps ---\n\n// 1. Remove potential leading 'json' marker and surrounding whitespace/newlines.\ncleanedJsonString = cleanedJsonString.replace(/^\\s*```?\\s*json\\s*\\n*/, '');\n\n// 2. Remove potential trailing backticks (``` or `) and surrounding whitespace/newlines.\ncleanedJsonString = cleanedJsonString.replace(/\\s*```?\\s*$/, '');\n\n// 3. Trim any remaining leading/trailing whitespace.\ncleanedJsonString = cleanedJsonString.trim();\n\n// --- !!! WARNING !!! ---\n// The following step removes JSON structure characters ([ ] { }).\n// As noted in the original code, this makes the string invalid JSON and JSON.parse() in the next node WILL FAIL\n// if the next node expects valid JSON. This logic is kept as per your original code.\n\n// 4. Remove square brackets ([ ]) and curly braces ({ }) using a regex\ncleanedJsonString = cleanedJsonString.replace(/[\\[\\]\\{\\}]/g, '');\n\n// --- Prepare Output for the next node ---\n// \u041c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0434\u0438\u043d \u0430\u0439\u0442\u0435\u043c, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u0443\u044e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430.\nreturn [{\n    json: {\n        cleanedJsonString: cleanedJsonString, // \u041e\u0447\u0438\u0449\u0435\u043d\u043d\u0430\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430\n        title: title,                         // \u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 title \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430\n        url: url                              // \u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 URL \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0439\u0442\u0435\u043c\u0430\n    }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4320,
        -1380
      ],
      "id": "1e5cc7c5-6547-44ce-b307-46945c4372ae",
      "name": "remove json"
    },
    {
      "parameters": {
        "jsCode": "// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0443\u0437\u043b\u0430\nconst cleanedJsonString = items[0].json.cleanedJsonString;\n\n// \u0428\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u2014 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f topic \u0438 detail\nconst regex = /\"topic\":\\s*\"([^\"\\\\]*(\\\\.[^\"\\\\]*)*)\"\\s*,\\s*\"detail\":\\s*\"([^\"\\\\]*(\\\\.[^\"\\\\]*)*)\"/gs;\n\n// \u041c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\nlet result = [];\nlet match;\n\n// \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\nconst title = items[0].json.title;\nconst url = items[0].json.url;\n\n// \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c \u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f topic \u0438 description\nlet isFirstRow = true; // \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438\nwhile ((match = regex.exec(cleanedJsonString)) !== null) {\n    // match[1] \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 'topic'\n    // match[3] \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 'detail'\n    let row = {\n        json: {\n            Topic: match[1],       // \u0422\u0435\u043c\u0430\n            Description: match[3]  // \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\n        }\n    };\n\n    // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c title \u0438 url \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438\n    if (isFirstRow) {\n        row.json.title = title;\n        row.json.url = url;\n        isFirstRow = false; // \u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u043b\u0430\u0433 \u0432 false\n    }\n\n    result.push(row);\n}\n\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 Topic, Description, title \u0438 url (\u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438)\nreturn result;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4540,
        -1380
      ],
      "id": "a4710b64-f678-422a-b41b-9cb0433a109b",
      "name": "Code"
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "https://docs.google.com/spreadsheets/d/1pongTk5EFZI1D6RRpYwz_Ex_Tt3lsHfD0jHcGgnAq0k/edit?usp=sharing",
          "mode": "url"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Parsing",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1pongTk5EFZI1D6RRpYwz_Ex_Tt3lsHfD0jHcGgnAq0k/edit#gid=0"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Title": "={{ $json.title }}",
            "Topic": "={{ $json.Topic }}",
            "Description": "={{ $json.Description }}",
            "Link": "={{ $json.url }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "Title",
              "displayName": "Title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Topic",
              "displayName": "Topic",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Description",
              "displayName": "Description",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Link",
              "displayName": "Link",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        4580,
        100
      ],
      "id": "dfcc26a9-bcdd-4d32-9476-f205b0fe0c31",
      "name": "Google Sheets",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "google/gemma-3-27b-it",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        4180,
        -960
      ],
      "id": "ddbacad6-ee9f-4226-a888-5082dd83c405",
      "name": "OpenRouter Chat Model",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "openai/gpt-4.1",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        4140,
        -660
      ],
      "id": "ffd44774-8420-4578-b69b-ec3e33f4f469",
      "name": "OpenRouter Chat Model1",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://openrouter.ai/api/v1/chat/completions",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "=Authorization",
              "value": "=<redacted-credential>"
            },
            {
              "name": "=Content-Type",
              "value": "=application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={\n  \"model\": \"google/gemini-2.5-pro-exp-03-25\",\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"You are a translator. Your only task is to take the user\u2019s input and output its English translation \u2014 nothing more. Do not add any commentary, explanations, apologies or extra sentences. If the input is already English, return it verbatim.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"{{ $json.transcript_original }}\"\n    }\n  ]\n}\n",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2840,
        -1520
      ],
      "id": "b8257f31-848d-430b-ba31-9362ca99fd9d",
      "name": "HTTP OpenRouter Request"
    },
    {
      "parameters": {
        "numberInputs": 6
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        720,
        -80
      ],
      "id": "c0794ac1-4a45-48bf-b6e2-71624e0e41a5",
      "name": "Merge YouTube videos"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        2120,
        -1400
      ],
      "id": "72845b20-1e57-4adb-98f1-da266ced7ca4",
      "name": "Merge transcribation and title, url,  etc"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        3120,
        -1380
      ],
      "id": "6b565cff-30ed-4ca2-ae86-a18d07ecb4e4",
      "name": "Merge OpenRouter and transcript"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        3840,
        -1380
      ],
      "id": "d175c838-8fff-4687-8af1-03fd4f0a33f0",
      "name": "Merge Chunks and title, url, etc"
    },
    {
      "parameters": {
        "jsCode": "// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\nconst inputData = items;  // \u042d\u0442\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043a\u043e\u043b\u043e\u043d\u043a\u0430\u043c\u0438 Topic, Description \u0438 Title\n\n// \u041c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\nlet result = [];\n\n// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c title \u0438 url \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\nconst title = inputData[0].json.title;\nconst url = inputData[0].json.url;\n\n// \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438\nlet isFirstRow = true;\n\n// \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c title \u0438 url \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438\ninputData.forEach(item => {\n    // \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438\n    const row = {\n        json: {\n            Topic: item.json.Topic,          // \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c Topic\n            Description: item.json.Description,  // \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c Description\n            title: title  // \u0414\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u043c Title \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\n        }\n    };\n\n    // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c url \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438\n    if (isFirstRow) {\n        row.json.url = url;\n        isFirstRow = false; // \u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u043b\u0430\u0433 \u0432 false\n    }\n\n    result.push(row);\n});\n\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\nreturn result;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3860,
        -1100
      ],
      "id": "47088f8f-6f3c-4c8c-a225-7fd9b4946038",
      "name": "Add Titles to rows"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Generate a lesson theory without bullet points and description what students will be able to..., This project/learning centers/module... Write text like guide, not water AI answer using this materials:\nTitle: {{ $json.title }}\nTopic: {{ $json.Topic }}\nDescription: {{ $json.Description }}\n\nU need to write 2-3 paragraphs about Description that i gave you\n\nStart output from \"Lesson Description:\" \n\nDo not add any extra commentary\n"
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.5,
      "position": [
        4080,
        -1100
      ],
      "id": "2df03b0a-ea95-463b-aeda-af0ecfd917ff",
      "name": "Theory Generator"
    },
    {
      "parameters": {
        "jsCode": "// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 (input items)\nconst inputItems = items;\n\n// \u041c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\nlet mergedResult = [];\nlet fullText = '';  // \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0448 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\n\n// \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\ninputItems.forEach(item => {\n    const lessonText = item.json.text;  // \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0438\u0437 \u043a\u0430\u0436\u0434\u043e\u0433\u043e input\n\n    // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u0440\u044b\u0432 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u0435\u0440\u0435\u0434 \"Lesson Description\", \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e\n    const formattedText = lessonText.replace(/(Lesson Description)/g, '\\n$1');\n    \n    // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a \u043f\u043e\u043b\u043d\u043e\u043c\u0443 \u0442\u0435\u043a\u0441\u0442\u0443\n    fullText += formattedText + ' ';\n});\n\n// \u0424\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442\nmergedResult.push({\n    json: {\n        lessonText: fullText.trim()  // \u0421\u043a\u043b\u0435\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0435 Lesson Description \u0432 \u043e\u0434\u0438\u043d \u0431\u043b\u043e\u043a\n    }\n});\n\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\nreturn mergedResult;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4440,
        -1100
      ],
      "id": "514c7f49-e326-45ec-b777-898d810593ed",
      "name": "Theory Merger"
    },
    {
      "parameters": {
        "jsCode": "// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0435\u043a\u0441\u0442 \u0438\u0437 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445\nconst inputString = $input.first().json.lessonText;\n\n// \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0445 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \"Lesson Description:\"\nconst addLessonNumber = (input) => {\n  let count = 1;\n  // \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0432\u0441\u0435\u0445 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0439 \"Lesson Description:\"\n  return input.replace(/(Lesson Description:)/g, () => {\n    return `Lesson Description ${count++}:`;  // \u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u043c\u0435\u0440 \u0443\u0440\u043e\u043a\u0430 \u043f\u0435\u0440\u0435\u0434 \"Lesson Description:\"\n  });\n};\n\n// \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u043c\u0435\u0440\u043e\u0432 \u0443\u0440\u043e\u043a\u043e\u0432\nconst updatedString = addLessonNumber(inputString);\n\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\nreturn [{ json: { updatedText: updatedString } }];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3860,
        -820
      ],
      "id": "54831ec2-5b87-4a7a-86ca-ecd9418a8c13",
      "name": "Add nums to Lesson Description"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=\u041d\u0435 \u043f\u0438\u0448\u0438 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043e\u0442 \u0441\u0435\u0431\u044f\n\n\u042f \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u0435\u043a\u0441\u0442 \u0432 JSON-\u0444\u043e\u0440\u043c\u0430\u0442 \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u043d\u043b\u0430\u0439\u043d-\u043a\u0443\u0440\u0441\u0430.\n\u041e\u0431\u0449\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043a\u0443\u0440\u0441\u0435:\n\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 \u043e\u0431\u0449\u0435\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0443\u0440\u0441\u0430 (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u0434\u043b\u0438\u043d\u043d\u044b\u043c, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u043e\u0432).\n\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 \u043e\u0431\u0449\u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0443\u0440\u0441\u0430.\n\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u043a\u0443\u0440\u0441\u0430: 680f332a16f8bb2b6ce9e71d\n\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438: beginner\n\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u0430: (\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c)\n\u041f\u0440\u0435\u0432\u044c\u044e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0443\u0440\u0441\u0430: (\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c)\n\u041c\u043e\u0434\u0443\u043b\u0438 \u043a\u0443\u0440\u0441\u0430:\n\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0442\u0435\u043a\u0441\u0442\u0430, \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0441 \"Lesson Description\" \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \"Lesson Description\" (\u0438\u043b\u0438 \u043a\u043e\u043d\u0446\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u0430), \u0441\u043e\u0437\u0434\u0430\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \"modules\".\n\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f:\n\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u044f: \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 \u043a\u0440\u0430\u0442\u043a\u0438\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a, \u043e\u0431\u043e\u0431\u0449\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\".\n\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f: \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u043e\u0431\u043e\u0431\u0449\u0430\u044e\u0449\u0435\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\".\n\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f (\"content\"): \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0442\u0435\u043a\u0441\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\".\n\u0423\u0440\u043e\u043a\u0438 \u043c\u043e\u0434\u0443\u043b\u044f (\"lessons\"): \u0421\u043e\u0437\u0434\u0430\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043e\u0434\u0438\u043d \u043e\u0431\u044a\u0435\u043a\u0442 \u0443\u0440\u043e\u043a\u0430.\n\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0443\u0440\u043e\u043a\u0430 (\"title\"): \u0421\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043a\u0430\u043a \"Module \u2116X\", \u0433\u0434\u0435 X - \u043f\u043e\u0440\u044f\u0434\u043a\u043e\u0432\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\".\n\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0443\u0440\u043e\u043a\u0430 (\"content\"): \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0442\u0435\u043a\u0441\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\".\n\u0414\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0443\u0440\u043e\u043a\u0430 (\"duration\"): 15\n\u0422\u0438\u043f \u0443\u0440\u043e\u043a\u0430 (\"type\"): text\n\u0422\u0438\u043f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 (\"contentType\"): standard\n\u0420\u0435\u0441\u0443\u0440\u0441\u044b \u0443\u0440\u043e\u043a\u0430 (\"resources\"): []\n\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u043a\u0430 (\"practiceExercises\"): []\n\u0411\u043b\u043e\u043a\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0443\u0440\u043e\u043a\u0430 (\"contentBlock\"): []\n\u0422\u0435\u0441\u0442\u044b \u043c\u043e\u0434\u0443\u043b\u044f (\"tests\"): []\n\u0412\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442:\n{{ $json.updatedText }}\nJSON Structure:\n{\n\"title\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u0430)\",\n\"description\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u0430)\",\n\"category\": \"680f332a16f8bb2b6ce9e71d\",\n\"difficulty\": \"beginner\",\n\"image\": \"\",\n\"imagePreview\": \"\",\n\"modules\": [\n{\n\"title\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u044f 1)\",\n\"description\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f 1)\",\n\"content\": \"(\u0442\u0435\u043a\u0441\u0442 Lesson Description 1)\",\n\"lessons\": [\n{\n\"title\": \"Module \u21161\",\n\"content\": \"(\u0442\u0435\u043a\u0441\u0442 Lesson Description 1)\",\n\"duration\": 15,\n\"type\": \"text\",\n\"contentType\": \"standard\",\n\"resources\": [],\n\"practiceExercises\": [],\n\"contentBlocks\": []\n}\n],\n\"tests\": []\n},\n{\n\"title\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u044f 2)\",\n\"description\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f 2)\",\n\"content\": \"(\u0442\u0435\u043a\u0441\u0442 Lesson Description 2)\",\n\"lessons\": [\n{\n\"title\": \"Module \u21162\",\n\"content\": \"(\u0442\u0435\u043a\u0441\u0442 Lesson Description 2)\",\n\"duration\": 15,\n\"type\": \"text\",\n\"contentType\": \"standard\",\n\"resources\": [],\n\"practiceExercises\": [],\n\"contentBlocks\": []\n}\n],\n\"tests\": []\n},\n// ... \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e Lesson Description \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043c\u043e\u0434\u0443\u043b\u044c\n]\n}\n\u0412\u0430\u0436\u043d\u043e: \u041e\u0431\u0440\u0430\u0442\u0438 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043e\u0431\u0449\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043a\u0443\u0440\u0441\u0435 (title, description, category, difficulty, image, imagePreview) \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 JSON. \u041c\u0430\u0441\u0441\u0438\u0432 \"modules\" \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \"Lesson Description\". \u0438 \u041f\u0438\u0448\u0438 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c"
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.5,
      "position": [
        4080,
        -820
      ],
      "id": "285282a8-0eea-4415-a72b-48978fbee0cc",
      "name": "JSON generator"
    },
    {
      "parameters": {
        "jsCode": "// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0435\u043a\u0441\u0442 \u0438\u0437 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445\nconst inputString = $input.first().json.text;\n\n// \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043b\u0438\u0448\u043d\u0438\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\nconst cleanString = (input) => {\n  return input\n    .replace(/```json\\n/g, '') // \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u043e \u0431\u043b\u043e\u043a\u0430 json\n    .replace(/```/g, '') // \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430 json\n    .replace(/\\n/g, ' ') // \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u0432\u0441\u0435 \\n \u043d\u0430 \u043f\u0440\u043e\u0431\u0435\u043b\u044b\n    .replace(/\\s+/g, ' ') // \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b (\u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432 \u043d\u0430 \u043e\u0434\u0438\u043d)\n    .trim(); // \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0438 \u0432 \u043a\u043e\u043d\u0446\u0435\n};\n\n// \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0447\u0438\u0441\u0442\u043a\u0438\nconst cleanedString = cleanString(inputString);\n\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443\nreturn [{ json: { cleanedText: cleanedString } }];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4440,
        -820
      ],
      "id": "a0e348b8-e19b-4181-a19c-045bffd036c7",
      "name": "Delete trash"
    },
    {
      "parameters": {
        "url": "https://youtube-transcript3.p.rapidapi.com/api/transcript",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "videoId",
              "value": "={{ $json.videoId }}"
            },
            {
              "name": "Title",
              "value": "={{ $json.title }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "=X-RapidAPI-Host",
              "value": "=youtube-transcript3.p.rapidapi.com"
            },
            {
              "name": "=X-RapidAPI-Key",
              "value": "=4ebd2c4b95mshc8ab3534e42bb1ep1d463fjsn32e3de965ce5"
            }
          ]
        },
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 61000
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1600,
        -180
      ],
      "id": "c1b6b6fe-f502-4dd9-ac0c-c9a2f24d796b",
      "name": "youtube video parser1"
    },
    {
      "parameters": {
        "jsCode": "// \u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0443\u0437\u043b\u0435 \"Code\" \u0432 n8n.\n// \u0412\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0437\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 'items' \u043a\u0430\u043a \u043c\u0430\u0441\u0441\u0438\u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.\n\n// \u041c\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\n// \u0441 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u043f\u0446\u0438\u0438 \u0412\u041d\u0423\u0422\u0420\u0418 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 'json'.\n\nconst outputItems = items.map(item => {\n  let concatenatedText = '';\n  let transcript = null;\n\n  // \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043c\u0430\u0441\u0441\u0438\u0432\u0443 \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u043f\u0446\u0438\u0438,\n  // \u043e\u0436\u0438\u0434\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 item.json.transcript.\n  // \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 (?.) \u0434\u043b\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430.\n  transcript = item?.json?.transcript;\n\n  // \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c\n  if (Array.isArray(transcript)) {\n    // \u0424\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438\n    // \u0438\u043b\u0438 \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 'text'.\n    // \u0417\u0430\u0442\u0435\u043c \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043a\u0441\u0442 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u043c.\n    const textSegments = transcript\n      .filter(entry => entry && typeof entry === 'object' && typeof entry.text === 'string')\n      .map(entry => entry.text);\n\n    concatenatedText = textSegments.join(' ');\n  } else {\n    // \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0438, \u043a\u043e\u0433\u0434\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u043f\u0446\u0438\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043b\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c\n    console.warn(\"\u042d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 'json.transcript' \u0438\u043b\u0438 \u043f\u0443\u0442\u044c \u043a \u043d\u0435\u043c\u0443:\", item);\n    // \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 concatenatedText \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 ('').\n    // \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.\n  }\n\n  // \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442.\n  // \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430.\n  // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u043b\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e 'json', \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0432\u043d\u0443\u0442\u0440\u044c \u043d\u0435\u0433\u043e.\n  return {\n    ...item, // \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0430 \u0432\u0435\u0440\u0445\u043d\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c\n    json: { // \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043b\u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 'json'\n      ...(item.json || {}), // \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0437 item.json (\u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0441\u0442\u044c)\n      concatenatedTranscript: concatenatedText // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u044e\u0434\u0430 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\n    }\n  };\n});\n\n// \u0423\u0437\u0435\u043b \"Code\" \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.\nreturn outputItems;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2140,
        -40
      ],
      "id": "583ffc51-b7cc-4ba7-b308-3cef031a1c42",
      "name": "Code5"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        1500,
        1260
      ],
      "id": "35a0c4da-e112-4b4b-bd3b-39995cad6839",
      "name": "Merge"
    },
    {
      "parameters": {
        "operation": "appendOrUpdate",
        "documentId": {
          "__rl": true,
          "value": "https://docs.google.com/spreadsheets/d/1pongTk5EFZI1D6RRpYwz_Ex_Tt3lsHfD0jHcGgnAq0k/edit?gid=0#gid=0",
          "mode": "url"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Parsing",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1pongTk5EFZI1D6RRpYwz_Ex_Tt3lsHfD0jHcGgnAq0k/edit#gid=0"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Title": "={{ $json.title }}",
            "Link": "={{ $json.url }}",
            "channelLink": "={{ $json.channel_id }}",
            "videoLink": "={{ $json.videoId }}",
            "json": "={{ $json.cleanedText }}"
          },
          "matchingColumns": [
            "Title"
          ],
          "schema": [
            {
              "id": "Title",
              "displayName": "Title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Link",
              "displayName": "Link",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "json",
              "displayName": "json",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "videoLink",
              "displayName": "videoLink",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "channelLink",
              "displayName": "channelLink",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Topic",
              "displayName": "Topic",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Description",
              "displayName": "Description",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1720,
        1260
      ],
      "id": "f4b86897-b155-451c-9761-e2217ad3759d",
      "name": "Google Sheets2",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 `items`, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u043f\u043e\u043b\u0435\u043c mergedChunk (\u0441\u0442\u0440\u043e\u043a\u0430 \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0438 topic/detail)\nconst output = [];\nfor (let i = 0; i < items.length; i++) {\n    const current = items[i].json;\n    const chunk = current.mergedChunk;\n    if (typeof chunk !== 'string') {\n        // \u0415\u0441\u043b\u0438 mergedChunk \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043b\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\n        continue;\n    }\n\n    // \u0420\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044f\u043c \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438\n    const lines = chunk.split(/[\\r\\n]+/);\n    for (let j = 0; j < lines.length; j++) {\n        const topicLine = lines[j].trim();\n        if (topicLine === '') {\n            continue; // \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0443\u0441\u0442\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c\n        }\n        if (!topicLine.startsWith('\"topic\":')) {\n            continue; // \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0441 \"topic\":\n        }\n        // \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \"detail\":\n        if (j + 1 >= lines.length) {\n            break; // \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 \u043a\u043e\u043d\u0435\u0446 \u0431\u0435\u0437 \u043f\u0430\u0440\u044b \"detail\"\n        }\n        const detailLine = lines[j + 1].trim();\n        if (!detailLine.startsWith('\"detail\":')) {\n            continue; // \u0435\u0441\u043b\u0438 \u043f\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0435 detail, \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c\n        }\n\n        // \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f topic \u0438 detail, \u0443\u0431\u0438\u0440\u0430\u044f \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u044b \u0438 \u043a\u0430\u0432\u044b\u0447\u043a\u0438 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0439 \u0437\u0430\u043f\u044f\u0442\u043e\u0439\n        const topicValue = topicLine.replace(/^\"topic\":\\s*\"/, '').replace(/\",?\\s*$/, '');\n        const detailValue = detailLine.replace(/^\"detail\":\\s*\"/, '').replace(/\",?\\s*$/, '');\n\n        // \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438, \u043a\u043e\u043f\u0438\u0440\u0443\u044f \u043f\u043e\u043b\u044f \u0438\u0437 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044f topic \u0438 description\n        output.push({\n            json: {\n                title: current.title,\n                url: current.url,\n                channel_id: current.channel_id,\n                videoId: current.videoId,\n                topic: topicValue,\n                description: detailValue\n            }\n        });\n\n        j++; // \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 (detail) \u0432 \u0446\u0438\u043a\u043b\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0430 \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430\n    }\n}\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043d\u043e\u0432\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432\nreturn output;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1540,
        740
      ],
      "id": "8023a46d-75d4-48e3-a3f2-6854931fbb8d",
      "name": "Add Columns"
    },
    {
      "parameters": {
        "jsCode": "// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\nconst inputItems = $input.all();\n\n// \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442\nconst processedItems = inputItems.map(item => {\n  const inputText = item.json.text;\n  const processedText = inputText.replace(/- \\n\\n.*?Title:/s, 'Title:');\n  return {\n    json: {\n      processedText: processedText\n    }\n  };\n});\n\nreturn processedItems;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2140,
        740
      ],
      "id": "bee8eb19-f5b9-4f63-b280-31762b50b204",
      "name": "Code1"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://openrouter.ai/api/v1/chat/completions",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{\n  JSON.stringify({\n    model: \"google/gemma-3-27b-it\",\n    messages: [\n      {\n        role: \"system\",\n        content: \"You are an instructional designer. Given the user\u2019s transcript text, identify the 4\u20136 major topics covered and for each provide a concise, detailed description (2\u20133 sentences). Output the result as a JSON array of objects with the schema [{\\\"topic\\\":\\\"...\\\",\\\"detail\\\":\\\"...\\\"}, \u2026]. Do not add any extra commentary.\"\n      },\n      {\n        role: \"user\",\n        content: $json.chunk\n      }\n    ]\n  })\n}}\n",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 10000
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1660,
        160
      ],
      "id": "f65bbee8-2ee7-482b-8c8b-344b9ae961df",
      "name": "Chat Completion1"
    },
    {
      "parameters": {
        "jsCode": "// \u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043d\u043e\u0434\u0435 \"Function\" \u0432 n8n.\n// \u041e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 JSON \u0441 \u043f\u043e\u043b\u0435\u043c\n// 'concatenatedTranscript' \u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438.\n// \u041a\u043e\u0434 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 'concatenatedTranscript' \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043b\u043a\u0438\u0435 \u0447\u0430\u043d\u043a\u0438,\n// \u0441\u0442\u0440\u0435\u043c\u044f\u0441\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0447\u0430\u043d\u043a\u0438 \u0434\u043e maxLen \u0438 \u0438\u0449\u0430 \u0442\u043e\u0447\u043a\u0443 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f (\u043a\u043e\u043d\u0435\u0446 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f)\n// \u0432 \"\u043e\u043a\u043d\u0435\" \u043f\u0435\u0440\u0435\u0434 \u043a\u043e\u043d\u0446\u043e\u043c \u0447\u0430\u043d\u043a\u0430.\n// \u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u043c \u0447\u0430\u043d\u043a\u0435\n// \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0435\u0445 \u0436\u0435 \u0438\u043c\u0435\u043d \u043f\u043e\u043b\u0435\u0439, \u0447\u0442\u043e \u0438 \u0432\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445:\n// title, video_url, video_id, channel_url.\n\n// \u041c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u0432\u0441\u0435\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u0447\u0430\u043d\u043a\u043e\u0432 \u0438\u0437 \u0432\u0441\u0435\u0445 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.\n// \u041a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441\u0442\u0430\u043d\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u0438\u0437 \u043d\u043e\u0434\u044b Function.\nconst outputItems = [];\n\n// \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0447\u0430\u043d\u043a\u0430 \u0432 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u0445.\nconst maxLen = 3000;\n\n// \u0420\u0430\u0437\u043c\u0435\u0440 \"\u043e\u043a\u043d\u0430\" \u0432 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u0445 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0447\u0430\u043d\u043a\u0430,\n// \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f (\u043a\u043e\u043d\u0435\u0446 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f).\nconst splitWindow = 300; // \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0449\u0435\u043c \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 300 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u0445 \u043f\u0435\u0440\u0435\u0434 \u043b\u0438\u043c\u0438\u0442\u043e\u043c\n\n// \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043b \u0432 \u044d\u0442\u0443 \u043d\u043e\u0434\u0443.\nfor (const item of items) {\n\n    // --- \u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 ---\n\n    // \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u0438\u0432\u043a\u0438. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 item.json.concatenatedTranscript.\n    const fullText = item.json.concatenatedTranscript;\n\n    // \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u043c\u0435\u043d\u0430 \u043f\u043e\u043b\u0435\u0439, \u043a\u0430\u043a \u0432 \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 ($input.first().json....).\n    // !!! \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u0438 \u043f\u043e\u043b\u044f (title, video_url, video_id, channel_url)\n    // !!! \u0442\u043e\u0447\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c \u043f\u043e\u043b\u0435\u0439 \u0432 \u0432\u0430\u0448\u0435\u043c \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u043c JSON.\n    const { title, url, videoId, channel_id } = item.json;\n\n    // --- \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 ---\n\n    // \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442, \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442.\n    if (!fullText) {\n        console.warn('Skipping item with missing or empty concatenatedTranscript:', item);\n        continue; // \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443\n    }\n\n    const itemChunksText = []; // \u041c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0445 \u0447\u0430\u043d\u043a\u043e\u0432, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 *\u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e* \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\n    let currentIndex = 0; // \u0422\u0435\u043a\u0443\u0449\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u0435\n\n    // \u0426\u0438\u043a\u043b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442\u0441\u044f, \u043f\u043e\u043a\u0430 \u043c\u044b \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0432\u0435\u0441\u044c \u0442\u0435\u043a\u0441\u0442\n    while (currentIndex < fullText.length) {\n\n        // \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0439 \u043a\u043e\u043d\u0435\u0446 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0447\u0430\u043d\u043a\u0430 ( currentIndex + maxLen )\n        let potentialChunkEndIndex = Math.min(currentIndex + maxLen, fullText.length);\n\n         // \u0415\u0441\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0439\u0441\u044f \u0442\u0435\u043a\u0441\u0442 \u043c\u0435\u043d\u044c\u0448\u0435 \u0438\u043b\u0438 \u0440\u0430\u0432\u0435\u043d maxLen (\u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u0437\u0430\u043f\u0430\u0441\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0438\u0441\u043a\u0430\u0442\u044c \u043e\u043a\u043d\u043e \u0432 \u043a\u043e\u043d\u0446\u0435),\n        // \u0438\u043b\u0438 \u043c\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 \u0442\u0435\u043a\u0441\u0442\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0435\u0440\u0435\u043c \u0432\u0435\u0441\u044c \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0439\u0441\u044f \u0442\u0435\u043a\u0441\u0442 \u043a\u0430\u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0447\u0430\u043d\u043a.\n        // \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u0435: \u0435\u0441\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0439\u0441\u044f \u0442\u0435\u043a\u0441\u0442 \u043c\u0435\u043d\u044c\u0448\u0435 \u043e\u043a\u043d\u0430 + \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0431\u0443\u0444\u0435\u0440, \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0435\u0440\u0435\u043c \u043e\u0441\u0442\u0430\u0442\u043e\u043a.\n        if (fullText.length - currentIndex <= splitWindow * 1.5 || potentialChunkEndIndex === fullText.length) {\n             itemChunksText.push(fullText.substring(currentIndex).trim());\n             currentIndex = fullText.length; // \u0421\u0434\u0432\u0438\u0433\u0430\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441 \u043d\u0430 \u043a\u043e\u043d\u0435\u0446, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430\n             break; // \u0412\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u0430 \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\n        }\n\n        // --- \u041f\u043e\u0438\u0441\u043a \u0442\u043e\u0447\u043a\u0438 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f \u0432 \"\u043e\u043a\u043d\u0435\" ---\n\n        // \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u043e \u043e\u043a\u043d\u0430 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u043e\u0447\u043a\u0438 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f.\n        // \u0418\u0449\u0435\u043c \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 'splitWindow' \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u0445 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0447\u0430\u043d\u043a\u0430,\n        // \u043d\u043e \u043d\u0435 \u0440\u0430\u043d\u044c\u0448\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 (currentIndex).\n        const searchStart = Math.max(currentIndex, potentialChunkEndIndex - splitWindow);\n\n        let bestSplitIndex = -1; // \u0418\u043d\u0434\u0435\u043a\u0441 \u043d\u0430\u0438\u043b\u0443\u0447\u0448\u0435\u0439 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f (\u043f\u043e\u0441\u043b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u0430)\n\n        // \u0418\u0434\u0435\u043c \u043d\u0430\u0437\u0430\u0434 \u043e\u0442 \u043a\u043e\u043d\u0446\u0430 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0447\u0430\u043d\u043a\u0430 \u043a \u043d\u0430\u0447\u0430\u043b\u0443 \u043e\u043a\u043d\u0430 \u043f\u043e\u0438\u0441\u043a\u0430\n        for (let i = potentialChunkEndIndex - 1; i >= searchStart; i--) {\n            const char = fullText[i];\n\n            // \u0418\u0449\u0435\u043c \u043a\u043e\u043d\u0435\u0446 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u0442\u043e\u0447\u043a\u0430, \u0432\u043e\u0441\u043a\u043b\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u043b\u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0437\u043d\u0430\u043a\n            if (char === '.' || char === '!' || char === '?') {\n                 // \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0437\u0430 \u0437\u043d\u0430\u043a\u043e\u043c \u043f\u0440\u0435\u043f\u0438\u043d\u0430\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0440\u043e\u0431\u0435\u043b \u0418\u041b\u0418 \u044d\u0442\u043e \u043a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0447\u0430\u043d\u043a\u0430\n                 // /\\s/.test(fullText[i + 1]) \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u043f\u0440\u043e\u0431\u0435\u043b\u044c\u043d\u044b\u043c (\u043f\u0440\u043e\u0431\u0435\u043b, \u0442\u0430\u0431\u0443\u043b\u044f\u0446\u0438\u044f, \u043d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430)\n                 if (i + 1 < fullText.length && /\\s/.test(fullText[i + 1]) || i + 1 === potentialChunkEndIndex) {\n                     bestSplitIndex = i + 1; // \u0422\u043e\u0447\u043a\u0430 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f - \u0441\u0440\u0430\u0437\u0443 \u041f\u041e\u0421\u041b\u0415 \u0437\u043d\u0430\u043a\u0430 \u043f\u0440\u0435\u043f\u0438\u043d\u0430\u043d\u0438\u044f (\u0438 \u043f\u0440\u043e\u0431\u0435\u043b\u0430, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c)\n                     break; // \u041d\u0430\u0448\u043b\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0432 \u043e\u043a\u043d\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0435\u0435\n                 }\n            }\n        }\n\n        // --- \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f \u0447\u0430\u043d\u043a\u0430 ---\n\n        let finalSplitIndex;\n\n        if (bestSplitIndex !== -1) {\n            // \u0415\u0441\u043b\u0438 \u043d\u0430\u0448\u043b\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f \u0432 \u043e\u043a\u043d\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0435\u0435.\n            // \u0423\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0442\u043e\u0447\u043a\u0430 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0447\u0430\u043d\u043a\u0430.\n             if (bestSplitIndex > currentIndex) {\n                finalSplitIndex = bestSplitIndex;\n            } else {\n                 // \u0415\u0441\u043b\u0438 bestSplitIndex <= currentIndex, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0430\u044f \u0442\u043e\u0447\u043a\u0430\n                 // \u043f\u0440\u0435\u043f\u0438\u043d\u0430\u043d\u0438\u044f \u0441 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0414\u041e \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0447\u0430\u043d\u043a\u0430 \u0438\u043b\u0438 \u043f\u0440\u044f\u043c\u043e \u0432 \u043d\u0430\u0447\u0430\u043b\u0435.\n                 // \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u0435 \u043f\u043e maxLen \u043a\u0430\u043a \u0437\u0430\u043f\u0430\u0441\u043d\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442.\n                 finalSplitIndex = potentialChunkEndIndex;\n            }\n\n        } else {\n            // \u0415\u0441\u043b\u0438 \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f \u0432 \u043e\u043a\u043d\u0435,\n            // \u0434\u0435\u043b\u0430\u0435\u043c \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u0435 \u043f\u043e maxLen. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0437\u043e\u0440\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435.\n            finalSplitIndex = potentialChunkEndIndex;\n        }\n\n        // --- \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0447\u0430\u043d\u043a\u0430 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 ---\n\n        // \u0412\u044b\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0447\u0430\u043d\u043a\u0430 \u043e\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0434\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f.\n        const chunkText = fullText.substring(currentIndex, finalSplitIndex).trim();\n\n        // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0447\u0430\u043d\u043a \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u0447\u0430\u043d\u043a\u043e\u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u043f\u0443\u0441\u0442.\n        if (chunkText.length > 0) {\n            itemChunksText.push(chunkText);\n        } else {\n             // \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043f\u0443\u0441\u0442\u043e\u0439 \u0447\u0430\u043d\u043a (\u043e\u0447\u0435\u043d\u044c \u0440\u0435\u0434\u043a\u043e, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c), \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u043c currentIndex\n             // \u0445\u043e\u0442\u044f \u0431\u044b \u043d\u0430 1, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430.\n             console.warn(`Created an empty chunk for item ${item.id || 'N/A'} starting at index ${currentIndex}. Adjusting index.`);\n             currentIndex++; // \u0421\u0434\u0432\u0438\u0433\u0430\u0435\u043c \u0432\u043f\u0435\u0440\u0435\u0434, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u043d\u0443\u0442\u044c\n             continue; // \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0443\u0441\u0442\u043e\u0433\u043e \u0447\u0430\u043d\u043a\u0430 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438\n        }\n\n\n        // \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043d\u0430 \u043a\u043e\u043d\u0435\u0446 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0447\u0430\u043d\u043a\u0430.\n        currentIndex = finalSplitIndex;\n\n        // \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043b\u044e\u0431\u044b\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u0438\u043b\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0447\u043a\u0438 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f,\n        // \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0447\u0430\u043d\u043a \u043d\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u0441\u044f \u0441 \u043d\u0438\u0445.\n         while (currentIndex < fullText.length && /\\s/.test(fullText[currentIndex])) {\n            currentIndex++;\n        }\n\n\n    } // \u041a\u043e\u043d\u0435\u0446 while \u0446\u0438\u043a\u043b\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u0430 \u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\n\n\n    // --- \u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 ---\n\n    // \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u0447\u0430\u043d\u043a\u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 n8n\n    // \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u041a \u041a\u0410\u0416\u0414\u041e\u041c\u0423 \u0447\u0430\u043d\u043a\u0443.\n    // \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u043c\u0435\u043d\u0430 \u043f\u043e\u043b\u0435\u0439, \u043a\u0430\u043a \u0432 \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 ($input.first().json....).\n    const outputItemChunks = itemChunksText.map(textChunk => {\n        return {\n            json: {\n                chunk: textChunk,       // \u0421\u0430\u043c \u0442\u0435\u043a\u0441\u0442 \u0447\u0430\u043d\u043a\u0430\n                title: title,           // \u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435: title\n                url: url,   // \u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435: video_url\n                videoId: videoId,     // \u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435: video_id\n                channel_id: channel_id, // \u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435: channel_url\n                // \u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0438\u0445 \u0437\u0434\u0435\u0441\u044c.\n            },\n        };\n    });\n\n    // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f *\u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e* \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0447\u0430\u043d\u043a\u0438\n    // \u0432 \u043e\u0431\u0449\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d \u043d\u043e\u0434\u043e\u0439.\n    outputItems.push(...outputItemChunks);\n\n} // \u041a\u043e\u043d\u0435\u0446 for \u0446\u0438\u043a\u043b\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0435\u0445 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432\n\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0431\u0449\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u0441\u0435\u0445 \u0447\u0430\u043d\u043a\u043e\u0432, \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0432\u0441\u0435\u0445 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.\n// \u041a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u044d\u0442\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u0441\u0442\u0430\u043d\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u0438\u0437 \u044d\u0442\u043e\u0439 \u043d\u043e\u0434\u044b.\nreturn outputItems;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1400,
        260
      ],
      "id": "6f73922d-a565-4b1e-ac9f-9142c7f15f03",
      "name": "Split to Chunks1"
    },
    {
      "parameters": {
        "jsCode": "// \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e $input.all() \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432\nconst items = $input.all();\n\nif (!items || items.length === 0) {\n  return [];\n}\n\nconst mergedData = {}; // \u041e\u0431\u044a\u0435\u043a\u0442 \u0434\u043b\u044f \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445\n// \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 (\u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0446\u0435\u043b\u0435\u0439, \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c)\n// let processedItemsCount = 0;\n// let skippedItemsCount = 0;\n// let skippedContentCount = 0;\n\nfor (const item of items) {\n  // processedItemsCount++; // \u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0443\u0436\u043d\u0430\n\n  // \u0412\u0430\u0436\u043d\u043e: \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 item.json.\n  // \u0415\u0441\u043b\u0438 title, video_url, choices \u0438 \u0442.\u0434. \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 'item',\n  // \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c 'const jsonData = item;'\n  const jsonData = item.json;\n\n  if (!jsonData || typeof jsonData !== 'object') {\n    // skippedItemsCount++; // \u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0443\u0436\u043d\u0430\n    continue; // \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 jsonData \u0438\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\n  }\n\n  const title = jsonData.title;\n  const url = jsonData.url;\n  const choices = jsonData.choices;\n  const channel_id = jsonData.channel_id;\n  const videoId = jsonData.videoId;\n  const userId = jsonData.userId; // user_id \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u043b\u044e\u0447\u0430 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438\n\n  // \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c title \u0438 videoUrl \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043b\u044e\u0447\u0430\n  if (typeof title !== 'string' || title.trim().length === 0) {\n    // skippedItemsCount++; // \u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0443\u0436\u043d\u0430\n    continue;\n  }\n  if (typeof url !== 'string' || url.trim().length === 0) {\n    // skippedItemsCount++; // \u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0443\u0436\u043d\u0430\n    continue;\n  }\n\n  // \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u0434\u043b\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438\n  const uniqueKey = `${title}_${url}`;\n\n  if (!mergedData[uniqueKey]) {\n    mergedData[uniqueKey] = {\n      title: title,\n      url: url,\n      allContents: [],\n      user_id: userId,\n      channel_id: channel_id,\n      videoId: videoId,\n    };\n  }\n\n  let contentFoundInChoices = false;\n  if (Array.isArray(choices)) {\n    for (const choice of choices) {\n      // \u041e\u0436\u0438\u0434\u0430\u0435\u043c\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430: choice.message.content\n      const content = choice?.message?.content;\n\n      if (typeof content === 'string' && content.trim().length > 0) {\n        mergedData[uniqueKey].allContents.push(content.trim());\n        contentFoundInChoices = true;\n      }\n    }\n  }\n\n  // \u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u0432 'choices', \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u0435\u0433\u043e \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044f\u0445.\n  // \u0410\u0434\u0430\u043f\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u0431\u043b\u043e\u043a, \u0435\u0441\u043b\u0438 \u0432\u0430\u0448 \u0442\u0435\u043a\u0441\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u043e\u043b\u044f\u0445 jsonData.\n  // \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, jsonData.text_content, jsonData.full_text \u0438 \u0442.\u0434.\n  if (!contentFoundInChoices) {\n    const alternativeTextSourceFields = [\n        jsonData.description,\n        jsonData.text,\n        jsonData.transcript,\n        jsonData.content, // \u0415\u0449\u0435 \u043e\u0434\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043f\u043e\u043b\u0435\n        // \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u044e\u0434\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u043c\u0435\u043d\u0430 \u043f\u043e\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\n    ];\n\n    for (const sourceField of alternativeTextSourceFields) {\n        if (typeof sourceField === 'string' && sourceField.trim().length > 0) {\n            mergedData[uniqueKey].allContents.push(sourceField.trim());\n            // \u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u043d\u0430\u0439\u0434\u0435\u043d \u0445\u043e\u0442\u044f \u0431\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a\n            // \u0438\u043b\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u043e\u043b\u0435\u0439.\n            // \u0414\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u0435\u0441\u043b\u0438 \u043d\u0430\u0448\u043b\u0438, \u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u043f\u043e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u043f\u043e\u043b\u044f\u043c:\n            break; \n        }\n    }\n  }\n  // \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u0441\u0435\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a allContents \u0432\u0441\u0435 \u0435\u0449\u0435 \u043f\u0443\u0441\u0442, \u0437\u043d\u0430\u0447\u0438\u0442 \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0431\u044b\u043b \u043d\u0430\u0439\u0434\u0435\u043d\n  // \u0432 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e uniqueKey.\n  // if (mergedData[uniqueKey].allContents.length === 0) {\n  //   skippedContentCount++; // \u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0443\u0436\u043d\u0430\n  // }\n}\n\nconst outputItems = [];\n\nfor (const key in mergedData) {\n  if (Object.prototype.hasOwnProperty.call(mergedData, key)) {\n    const dataEntry = mergedData[key];\n\n    // \u0415\u0441\u043b\u0438 dataEntry.allContents \u043f\u0443\u0441\u0442, mergedChunk \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439.\n    // \u042d\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u043d\u0435 \u0431\u044b\u043b \u043d\u0430\u0439\u0434\u0435\u043d.\n    const mergedChunk = dataEntry.allContents.join(\"\\n\\n\");\n\n    outputItems.push({\n      json: {\n        title: dataEntry.title,\n        mergedChunk: mergedChunk,\n        user_id: dataEntry.user_id,\n        url: dataEntry.url,\n        channel_id: dataEntry.channel_id,\n        videoId: dataEntry.videoId,\n      },\n    });\n  }\n}\n\nreturn outputItems;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1440,
        460
      ],
      "id": "dafe9b64-9670-40f4-9491-8b6f6585e6cf",
      "name": "Summarizer1"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "60d0d292-7f04-40b4-acf3-8a64c13acd26",
              "name": "title",
              "value": "={{ $json.snippet.title }}",
              "type": "string"
            },
            {
              "id": "753c7ef6-4008-4b16-81f0-7fbe291f015a",
              "name": "video_url",
              "value": "={{ $json['Full Video Link'] }}",
              "type": "string"
            },
            {
              "id": "b51008a2-7ca7-408c-b212-f8a441d7c3e5",
              "name": "video_id",
              "value": "={{ $json['Video ID'] }}",
              "type": "string"
            },
            {
              "id": "79809b76-8c3c-4c95-ab49-6da5319bf6dc",
              "name": "channel_url",
              "value": "={{ $json['Full Channel Link'] }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3740,
        -260
      ],
      "id": "ca68f367-5e39-4310-b6ec-0e4a04cbceb0",
      "name": "Parse title ulr and publishedAt1"
    },
    {
      "parameters": {
        "jsCode": "// \u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0443\u0437\u043b\u0430 Code \u0432 n8n.\n// \u041e\u043d \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (items).\n// \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043e\u043d \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0432\u0441\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c \u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 'json'.\n// \u0415\u0441\u043b\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0448\u0430\u0433\u0438 \u043e\u0447\u0438\u0441\u0442\u043a\u0438\n// \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u0445\u043e\u0436\u0435\u0433\u043e \u043d\u0430 JSON.\n\n// \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0441\u0442\u0440\u043e\u043a\u0438\nfunction cleanString(inputString) {\n    // \u0415\u0441\u043b\u0438 \u0432\u0445\u043e\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0433\u043e \u043a\u0430\u043a \u0435\u0441\u0442\u044c.\n    if (typeof inputString !== 'string') {\n        return inputString;\n    }\n\n    let cleanedJsonString = inputString;\n\n    // --- \u0428\u0430\u0433\u0438 \u043e\u0447\u0438\u0441\u0442\u043a\u0438 ---\n\n    // 1. \u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0435\u0434\u0443\u0449\u0438\u0439 \u043c\u0430\u0440\u043a\u0435\u0440 'json' (```json \u0438\u043b\u0438 ``json) \u0438 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b/\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044b \u0441\u0442\u0440\u043e\u043a.\n    // \u0424\u043b\u0430\u0433 'i' \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0434\u043b\u044f \u043d\u0435\u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0443 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f 'json'.\n    // (?:```|``) \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0440\u0435\u043c \u0438\u043b\u0438 \u0434\u0432\u0443\u043c \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u043c \u043a\u0430\u0432\u044b\u0447\u043a\u0430\u043c.\n    cleanedJsonString = cleanedJsonString.replace(/^\\s*(?:```|``)\\s*json\\s*\\n*/i, '');\n\n    // 2. \u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u043c\u044b\u043a\u0430\u044e\u0449\u0438\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u043a\u0430\u0432\u044b\u0447\u043a\u0438 (``` \u0438\u043b\u0438 ``) \u0438 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b/\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044b \u0441\u0442\u0440\u043e\u043a.\n    cleanedJsonString = cleanedJsonString.replace(/\\s*(?:```|``)\\s*$/, '');\n\n    // 3. \u041e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0432\u0435\u0434\u0443\u0449\u0438\u0435/\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b.\n    cleanedJsonString = cleanedJsonString.trim();\n\n    // --- !!! \u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415 !!! ---\n    // \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0430\u0436\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b JSON: \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0435 \u0441\u043a\u043e\u0431\u043a\u0438 ([ ]) \u0438 \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0435 \u0441\u043a\u043e\u0431\u043a\u0438 ({ }).\n    // \u041a\u0430\u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c JSON.\n    // \u0415\u0441\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0443\u0437\u0435\u043b n8n \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c JSON.parse() \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0432\u043e\u0434\u0430, \u043e\u043d \u041e\u0411\u042f\u0417\u0410\u0422\u0415\u041b\u042c\u041d\u041e \u0412\u042b\u0414\u0410\u0421\u0422 \u041e\u0428\u0418\u0411\u041a\u0423,\n    // \u0435\u0441\u043b\u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 JSON-\u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432. \u042d\u0442\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0437\u0430\u0434\u0430\u043d\u0438\u044e.\n    cleanedJsonString = cleanedJsonString.replace(/[\\[\\]\\{\\}]/g, '');\n\n    return cleanedJsonString;\n}\n\n// \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435 'items'\nconst outputItems = items.map(item => {\n    const newItem = {\n        json: {},\n        // \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0435\u0441\u0442\u044c\n        ...(item.binary && { binary: item.binary })\n    };\n\n    // \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 item.json\n    if (item.json && typeof item.json === 'object' && item.json !== null) {\n        // \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u043a\u043b\u044e\u0447\u0430\u043c \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 item.json\n        for (const key in item.json) {\n            if (Object.prototype.hasOwnProperty.call(item.json, key)) {\n                // \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\n                newItem.json[key] = cleanString(item.json[key]);\n            }\n        }\n    } else if (item.json) {\n        // \u0415\u0441\u043b\u0438 item.json \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c, \u043d\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0442\u0440\u043e\u043a\u0430, \u0447\u0438\u0441\u043b\u043e),\n        // \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.\n        // \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0447\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u0430\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.\n        console.warn(`Warning: item.json for an item was not an object. Attempting to clean it directly. Value: ${item.json}`);\n        newItem.json.unknownProcessedValue = cleanString(item.json);\n    }\n\n\n    return newItem;\n});\n\n// --- \u0412\u044b\u0432\u043e\u0434 ---\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.\nreturn outputItems;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1680,
        460
      ],
      "id": "377ca244-6ad5-4bb2-8852-25041747953c",
      "name": "remove json1"
    },
    {
      "parameters": {
        "model": "google/gemma-3-27b-it",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        1680,
        820
      ],
      "id": "93a734ce-6ccb-4eac-bbb8-25cb387f30e7",
      "name": "OpenRouter Chat Model2",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "openai/gpt-4.1",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        1680,
        1100
      ],
      "id": "357ac6e8-5010-423b-8794-5574f63b7db3",
      "name": "OpenRouter Chat Model3",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        1940,
        240
      ],
      "id": "ee637d34-4422-4c47-9c48-e7210fbb6414",
      "name": "Merge Chunks and title, url, etc1"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Generate a lesson theory without bullet points and description what students will be able to..., This project/learning centers/module... Write text like guide, not water AI answer using this materials:\nTitle: {{ $json.title }}\nTopic: {{ $json.topic }}\nDescription: {{ $json.description }}\n\nU need to write 2-3 paragraphs about Description that i gave you\n\nStart output from \"Title: \"{{ $json.title }} \\n\"Lesson Description:\" (each item need \"Title: \" without ## )\n\nDo not add any extra commentary\n"
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.5,
      "position": [
        1780,
        740
      ],
      "id": "8261817e-19cb-4e94-a4dd-a632b75b4770",
      "name": "Theory Generator1"
    },
    {
      "parameters": {
        "jsCode": "// \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e 'items' - \u044d\u0442\u043e \u0432\u0430\u0448 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432.\n// const items = [\n// /* \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0432\u0430\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445:\n// { json: { text: \"\\n\\nTitle: \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 Python\\nLesson Description:\\nPython \u044d\u0442\u043e \u0432\u0435\u0441\u0435\u043b\u043e.\" } },\n// { json: { text: \"Title: \u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 JS\\nLesson Description:\\nJS \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u043e.\" } },\n// { json: { text: \"Title: \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 Python\\nLesson Description:\\n\u0418\u0437\u0443\u0447\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435.\" } }\n// */\n// ];\n\n// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 (input items)\nconst inputItems = items; // \u0417\u0430\u043c\u0435\u043d\u0438\u0442\u0435 'items' \u043d\u0430 \u0432\u0430\u0448\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438\n\n// \u041e\u0431\u044a\u0435\u043a\u0442 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439, \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c\nconst groupedByTitle = {};\n\ninputItems.forEach(item => {\n    const fullTextFromItem = item.json.processedText;\n\n    // 1. \u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 (Title)\n    let title = \"Untitled\"; // \u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\n    // \u0418\u0449\u0435\u043c \"Title:\" \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 (\u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u043c\u043d\u043e\u0433\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u043e\u0441\u0442\u0438) \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \"Title:\"\n    const titleMatchStrict = fullTextFromItem.match(/^Title:([^\\n]+)/m);\n    const titleMatchGeneral = fullTextFromItem.match(/Title:([^\\n]+)/);\n\n    if (titleMatchStrict && titleMatchStrict[1]) {\n        title = titleMatchStrict[1].trim();\n    } else if (titleMatchGeneral && titleMatchGeneral[1]) {\n        title = titleMatchGeneral[1].trim();\n    }\n    // \u0415\u0441\u043b\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d, \u043e\u043d \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \"Untitled\"\n\n    // 2. \u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0443\u0440\u043e\u043a\u0430 (Lesson Description)\n    let description = \"\";\n    const lessonDescMarker = \"Lesson Description:\";\n    const lessonDescStartIndex = fullTextFromItem.indexOf(lessonDescMarker);\n\n    if (lessonDescStartIndex !== -1) {\n        // \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u0441\u043b\u0435 \"Lesson Description:\" \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b/\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044b \u0441\u0442\u0440\u043e\u043a \u043f\u043e \u043a\u0440\u0430\u044f\u043c\n        description = fullTextFromItem.substring(lessonDescStartIndex + lessonDescMarker.length).trim();\n    } else {\n        // \u0415\u0441\u043b\u0438 \"Lesson Description:\" \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e, \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0432\u0437\u044f\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 (\u0435\u0441\u043b\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0431\u044b\u043b \u043d\u0430\u0439\u0434\u0435\u043d)\n        const titlePatternMatch = titleMatchStrict || titleMatchGeneral;\n        if (titlePatternMatch && titlePatternMatch[0]) {\n            const textAfterTitleLine = fullTextFromItem.substring(fullTextFromItem.indexOf(titlePatternMatch[0]) + titlePatternMatch[0].length);\n            description = textAfterTitleLine.trim();\n        } else {\n            // \u0415\u0441\u043b\u0438 \u043d\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a, \u043d\u0438 \u043c\u0430\u0440\u043a\u0435\u0440 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b,\n            // \u0438 \u0442\u0435\u043a\u0441\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0439, \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0432\u0435\u0441\u044c \u0442\u0435\u043a\u0441\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0434\u043b\u044f \"Untitled\"\n            if (title === \"Untitled\" && fullTextFromItem.trim().length > 0) {\n                description = fullTextFromItem.trim();\n            }\n        }\n    }\n\n    // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432 \u0433\u0440\u0443\u043f\u043f\u0443, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0435\n    if (description) {\n        if (!groupedByTitle[title]) {\n            groupedByTitle[title] = []; // \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\n        }\n        groupedByTitle[title].push(description);\n    }\n});\n\n// \u0424\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445\nconst mergedResult = [];\nfor (const title in groupedByTitle) {\n    if (groupedByTitle.hasOwnProperty(title)) {\n        const descriptionsArray = groupedByTitle[title];\n        let combinedLessonText = \"\";\n\n        if (descriptionsArray.length > 0) {\n            // \u041f\u0435\u0440\u0432\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\n            // \u0424\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u0443\u0435\u043c \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u043d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043f\u0435\u0440\u0435\u0434 \"Lesson Description\")\n            combinedLessonText = '\\nLesson Description:\\n' + descriptionsArray[0];\n\n            // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0436\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\n            for (let i = 1; i < descriptionsArray.length; i++) {\n                // \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u0432\u0435 \u043d\u043e\u0432\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439\n                combinedLessonText += '\\n\\nLesson Description:\\n' + descriptionsArray[i];\n            }\n        }\n\n        // \u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442: \u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a + \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f\n        let finalOutputText = `Title: ${title}`;\n        if (combinedLessonText) { // \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u043f\u0443\u0441\u0442\n            finalOutputText += combinedLessonText;\n        }\n\n        mergedResult.push({\n            json: {\n                lessonText: finalOutputText.trim() // \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u043f\u043e \u043a\u0440\u0430\u044f\u043c \u0432\u0441\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430\n            }\n        });\n    }\n}\n\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\nreturn mergedResult;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2360,
        740
      ],
      "id": "412ca9ba-2c6f-4916-9a92-e441c5cd0d18",
      "name": "Theory Merger1"
    },
    {
      "parameters": {
        "jsCode": "// --- \u041d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0443\u0437\u043b\u0430 \"Code\" \u0432 n8n ---\n\n// \u0412\u0430\u0448\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u043c\u0435\u0440\u043e\u0432 \u0443\u0440\u043e\u043a\u043e\u0432 (\u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439)\nconst addLessonNumber = (inputText) => {\n  if (typeof inputText !== 'string') {\n    // \u042d\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u0430\u0436\u043d\u0430, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0439\n    // console.warn(\"\u0412\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439:\", inputText);\n    return inputText; // \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043a\u0430\u043a \u0435\u0441\u0442\u044c, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0441\u0442\u0440\u043e\u043a\u0430\n  }\n  let lessonCounter = 1;\n  // \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c \"Lesson Description:\" \u043d\u0430 \"Lesson Description X:\"\n  return inputText.replace(/Lesson Description:/g, () => {\n    return `Lesson Description ${lessonCounter++}:`;\n  });\n};\n\n// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b (items)\nconst items = $input.all(); // \u0438\u043b\u0438 items = $items \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a/\u0432\u0435\u0440\u0441\u0438\u0438\nconst outputItems = []; // \u0411\u0443\u0434\u0435\u043c \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u044e\u0434\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 items\n\n// \u041f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 (item)\nfor (const item of items) {\n  const newItem = { ...item }; // \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043f\u0438\u044e item, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 \u0446\u0438\u043a\u043b\u0435 (\u0445\u043e\u0440\u043e\u0448\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430)\n\n  // --- \u041e\u0422\u041b\u0410\u0414\u041a\u0410 ---\n  // \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0438 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0443\u0437\u043b\u0430\n  // newItem.json.debug_input_lessonText_exists = newItem.json.hasOwnProperty('lessonText');\n  // newItem.json.debug_input_lessonText_value = newItem.json.lessonText;\n  // ---------------\n\n  // \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0438\u0437 \u043f\u043e\u043b\u044f lessonText\n  const originalText = newItem.json.lessonText;\n\n  if (originalText && typeof originalText === 'string') {\n    // \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0432\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e\n    const modifiedText = addLessonNumber(originalText);\n    \n    // \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u0418\u041b\u0418 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u0442\u0430\u0440\u043e\u0435.\n    // \u0412\u0430\u0440\u0438\u0430\u043d\u0442 1: \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438)\n    newItem.json.processedLessonText = modifiedText;\n    \n    // \u0412\u0430\u0440\u0438\u0430\u043d\u0442 2: \u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 lessonText\n    // newItem.json.lessonText = modifiedText; \n\n    // --- \u041e\u0422\u041b\u0410\u0414\u041a\u0410 ---\n    // newItem.json.debug_output_modifiedText = modifiedText;\n    // ---------------\n\n  } else {\n    // \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0435 lessonText \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \u043f\u0443\u0441\u0442\u043e\u0435 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0442\u0440\u043e\u043a\u0430,\n    // \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043d\u0435\u0433\u043e null/\u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.\n    // \u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438 \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 processedLessonText:\n    newItem.json.processedLessonText = originalText; // \u0438\u043b\u0438 null, \u0438\u043b\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\n    //newItem.json.debug_skipped_processing = true;\n  }\n  \n  outputItems.push(newItem);\n}\n\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432\nreturn outputItems;\n\n// --- \u041a\u043e\u043d\u0435\u0446 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0443\u0437\u043b\u0430 \"Code\" \u0432 n8n ---"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1540,
        980
      ],
      "id": "ddb1420f-cff2-49c1-b70b-cc64e62879da",
      "name": "Add nums to Lesson Description1"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 \u041e\u0414\u0418\u041d \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 JSON-\u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u043d\u0430 \u043e\u0431\u0443\u0447\u0430\u044e\u0449\u0443\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u043f\u043e \u0414\u0410\u041d\u041d\u042b\u041c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u043f\u0440\u0438\u0448\u043b\u044e \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0438. \u0421\u043e\u0431\u043b\u044e\u0434\u0430\u0439 \u0412\u0421\u0415 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044c \u0441\u0435\u0431\u044f \u043f\u043e \u0447\u0435\u043a-\u043b\u0438\u0441\u0442\u0443 \u0438 \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0432\u0435\u0434\u0438 \u0442\u043e\u043b\u044c\u043a\u043e JSON. \u0415\u0441\u043b\u0438 \u043f\u043e\u043d\u044f\u043b \u2014 \u043e\u0442\u0432\u0435\u0442\u044c:  \u0414\u0430, \u0436\u0434\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.   \u2e3b  1\u2003\u0428\u0430\u0431\u043b\u043e\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u041e\u0411\u042f\u0417\u0410\u0422\u0415\u041b\u042c\u041d\u041e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c  {   \"title\": \"\",   \"description\": \"\",   \"category\": \"681dfaab642ad2b18ee6e8d3\",   \"difficulty\": \"beginner\",   \"image\": \"\",   \"imagePreview\": \"\",   \"modules\": [     {       \"title\": \"\",       \"description\": \"\",       \"content\": \"\",       \"lessons\": [         {           \"title\": \"\",           \"content\": \"\",           \"duration\": 15,           \"type\": \"text\",           \"contentType\": \"standard\"         }       ],       \"tests\": []     }   ] }  \u041d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043b\u0438\u0448\u043d\u0435\u0433\u043e \u0438\u043b\u0438 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0439.  \u2e3b  2\u2003\u041a\u0430\u043a \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u044f  \u0423\u0440\u043e\u0432\u0435\u043d\u044c\t\u041f\u043e\u043b\u0435\t\u0427\u0442\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u041a\u0443\u0440\u0441\ttitle, description\t\u0411\u0435\u0440\u0438 \u0434\u043e\u0441\u043b\u043e\u0432\u043d\u043e \u0438\u0437 \u043c\u043e\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u041a\u0443\u0440\u0441\timage, imagePreview\t\u041e\u0441\u0442\u0430\u0432\u044c \"\", \u0435\u0441\u043b\u0438 \u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435\u0442 \u0441\u0441\u044b\u043b\u043e\u043a. \u041c\u043e\u0434\u0443\u043b\u044c\ttitle, description\t\u041a\u043e\u043f\u0438\u0440\u0443\u0439 \u0434\u043e\u0441\u043b\u043e\u0432\u043d\u043e. \u041c\u043e\u0434\u0443\u043b\u044c\tcontent\t\u0420\u043e\u0432\u043d\u043e \u043e\u0434\u043d\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435-\u0441\u0430\u043c\u043c\u0430\u0440\u0438 \u043e \u0441\u0443\u0442\u0438 \u043c\u043e\u0434\u0443\u043b\u044f. \u0423\u0440\u043e\u043a\ttitle\t\u041a\u043e\u043f\u0438\u0440\u0443\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0443\u0440\u043e\u043a\u0430. \u0423\u0440\u043e\u043a\tcontent\t\u041d\u0443\u043c\u0435\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a: 1. \u2026 \\\\n2. \u2026 \u0431\u0435\u0437 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0439. \u0423\u0440\u043e\u043a\tduration\t\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u0447\u0438\u0441\u043b\u043e \u0438\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 15. \u0423\u0440\u043e\u043a\ttype, contentType\t\u0412\u0441\u0435\u0433\u0434\u0430 \"text\" \u0438 \"standard\". \u041c\u043e\u0434\u0443\u043b\u044c\ttests\t\u0412\u0441\u0435\u0433\u0434\u0430 [].   \u2e3b  3\u2003\u0424\u043e\u0440\u043c\u0430\u0442 \u043e\u0442\u0432\u0435\u0442\u0430 \t\u2022\t\u0412\u0435\u0440\u043d\u0438 \u0442\u043e\u043b\u044c\u043a\u043e JSON \u0431\u0435\u0437 Markdown-\u0431\u043b\u043e\u043a\u043e\u0432, \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u0438 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0439. \t\u2022\t\u041e\u0442\u0432\u0435\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 { \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f }. \t\u2022\t\u0412\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043a\u0430\u0432\u044b\u0447\u043a\u0430\u0445 \", \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b \u0432 content \u2014 \u0447\u0435\u0440\u0435\u0437 \\\\n.  \u2e3b  4\u2003\u0427\u0435\u043a-\u043b\u0438\u0441\u0442 \u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439 \t\u2022\t\u041a\u043e\u043b-\u0432\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0438 \u0443\u0440\u043e\u043a\u043e\u0432 \u0442\u043e\u0447\u043d\u043e \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 (\u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u043e). \t\u2022\t\u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0435\u0441\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0434\u0438\u043d \u0443\u0440\u043e\u043a. \t\u2022\tcontent \u043c\u043e\u0434\u0443\u043b\u044f = 1 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \t\u2022\tcontent \u0443\u0440\u043e\u043a\u0430 = \u043d\u0443\u043c\u0435\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0431\u0435\u0437 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0439. \t\u2022\t\u0412\u0435\u0441\u044c JSON \u0432\u0430\u043b\u0438\u0434\u0435\u043d (\u0441\u043a\u043e\u0431\u043a\u0438, \u0437\u0430\u043f\u044f\u0442\u044b\u0435, \u043a\u0430\u0432\u044b\u0447\u043a\u0438).  \u2e3b  5\u2003\u0422\u0438\u043f\u0438\u0447\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e  \u041e\u0448\u0438\u0431\u043a\u0430\t\u041f\u043e\u0447\u0435\u043c\u0443 \u043f\u043b\u043e\u0445\u043e\t\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u041f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u0448\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f { \"modules\":[ {\u2026} ] }\t\u041f\u043e\u0442\u0435\u0440\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439.\t\u0412\u044b\u0432\u0435\u0434\u0438 \u0432\u0441\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0438\u0437 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0438\u043c\u0435\u0440 \u2193 \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0448\u044c \u0443\u0440\u043e\u043a\u0438 \u041c\u043e\u0434\u0443\u043b\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 1 \u0443\u0440\u043e\u043a \u0432\u043c\u0435\u0441\u0442\u043e 3.\t\u041d\u0430\u0440\u0443\u0448\u0435\u043d\u0430 \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c \u043a\u0443\u0440\u0441\u0430.\t\u0412\u043a\u043b\u044e\u0447\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0440\u043e\u043a \u0438\u0437 \u0434\u0430\u043d\u043d\u044b\u0445. content \u043c\u043e\u0434\u0443\u043b\u044f = \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u043e\u043a\t\u0414\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c 1 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435.\tcontent : \u201cSummarise whole module in one sentence.\u201d content \u0443\u0440\u043e\u043a\u0430 = \u043e\u0434\u043d\u043e \u0441\u043b\u043e\u0432\u043e\t\u0414\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a 1., 2. \u2026\tcontent : \u201c1. Step one\u2026\\n2. Step two\u2026\u201d \u0414\u043e\u0431\u0430\u0432\u0438\u043b \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 // TODO \u0438\u043b\u0438 <!-- -->\tJSON \u0441\u0442\u0430\u043d\u0435\u0442 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c.\t\u0423\u0431\u0435\u0440\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438, \u043e\u0441\u0442\u0430\u0432\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0430\u043d\u043d\u044b\u0435. \u0412\u044b\u0432\u0435\u043b Markdown  ```json \u2026\t\u041f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u043d\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442.\t\u041f\u0440\u043e\u0441\u0442\u043e JSON \u0431\u0435\u0437 \u043e\u0431\u0451\u0440\u0442\u043a\u0438.   \u2e3b  6\u2003\u0414\u0432\u0430 \u0443\u0447\u0435\u0431\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 (\u041d\u0415 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435)  \u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430  {   \"title\": \"Demo\",   \"modules\": [     { \"title\": \"Only module\" }   ] }  \u041e\u0448\u0438\u0431\u043a\u0438: \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f, content \u043d\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d, \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u044b \u0443\u0440\u043e\u043a\u0438, JSON \u0443\u0441\u0435\u0447\u0451\u043d.  \u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430  {   \"title\": \"Demo Course\",   \"description\": \"Quick demo.\",   \"category\": \"681dfaab642ad2b18ee6e8d3\",   \"difficulty\": \"beginner\",   \"image\": \"\",   \"imagePreview\": \"\",   \"modules\": [     {       \"title\": \"Module A\",       \"description\": \"Intro module.\",       \"content\": \"This module gives an overview of the whole course.\",       \"lessons\": [         {           \"title\": \"Lesson 1\",           \"content\": \"1. Do X\\\\n2. Do Y\",           \"duration\": 15,           \"type\": \"text\",           \"contentType\": \"standard\"         }       ],       \"tests\": []     }   ] }  \u0412\u0441\u0435 \u043a\u043b\u044e\u0447\u0438 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435, content \u043c\u043e\u0434\u0443\u043b\u044f = 1 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435, content \u0443\u0440\u043e\u043a\u0430 = \u0441\u043f\u0438\u0441\u043e\u043a.  \u2e3b  \u0415\u0441\u043b\u0438 \u0432\u0441\u0451 \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u2014 \u043e\u0442\u0432\u0435\u0442\u044c \u0440\u043e\u0432\u043d\u043e:  \u0414\u0430, \u0436\u0434\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.\n\n\u0412\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442:\n{{ $json.processedLessonText }}"
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.5,
      "position": [
        1780,
        1000
      ],
      "id": "ebf436fd-3a0f-4910-ab26-ed367db4393d",
      "name": "JSON generator1"
    },
    {
      "parameters": {
        "jsCode": "// \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043b\u0438\u0448\u043d\u0438\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438\nconst cleanString = (inputText) => {\n  let text = inputText;\n  // \u0423\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u0442\u0440\u043e\u043a\u0430\n  if (typeof text !== 'string') {\n    // \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u0441\u0442\u0440\u043e\u043a\u0430, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0435\u0435 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435.\n    // \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439, \u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0442\u0430\u043a\u0436\u0435 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u0443\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0443.\n    text = String(text);\n  }\n  return text\n    .replace(/```json\\n/g, '') // \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0431\u043b\u043e\u043a\u0430 json-\u043a\u043e\u0434\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0435\u0441\u0442\u044c\n    .replace(/```/g, '')       // \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u043a\u043e\u0434\u0430\n    .replace(/\\n/g, ' ')      // \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u0432\u0441\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430 \u043f\u0440\u043e\u0431\u0435\u043b\u044b\n    .replace(/\\s+/g, ' ')    // \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0430 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0431\u0435\u043b\n    .trim();                   // \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0438 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0440\u043e\u043a\u0438\n};\n\n// \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.\nlet allInputItems = [];\n\n// \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b.\n// \u0412 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u043c\u0435\u0442\u043e\u0434 $input.first(), \u0447\u0442\u043e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u043e \u0434\u043b\u044f \u0441\u0440\u0435\u0434,\n// \u0433\u0434\u0435 $input \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c-\u0445\u0435\u043b\u043f\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c.\n// \u0412 \u0442\u0430\u043a\u0438\u0445 \u0441\u0440\u0435\u0434\u0430\u0445 \u043e\u0431\u044b\u0447\u043d\u043e \u0435\u0441\u0442\u044c \u0438 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.\n\nif (typeof $input.all === 'function') {\n  // \u042d\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u0445 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, n8n) \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0432\u0441\u0435\u0445 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.\n  allInputItems = $input.all();\n} else if (Array.isArray($input)) {\n  // \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f $input \u0441\u0430\u043c\u0430 \u043f\u043e \u0441\u0435\u0431\u0435 \u0443\u0436\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.\n  allInputItems = $input;\n} else if ($input && Array.isArray($input.items)) {\n  // \u0415\u0441\u043b\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 'items' \u043e\u0431\u044a\u0435\u043a\u0442\u0430 $input (\u0434\u0440\u0443\u0433\u043e\u0439 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d).\n  allInputItems = $input.items;\n} else if ($input && typeof $input.first === 'function') {\n  // \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434 .first(), \u043d\u043e \u043d\u0435\u0442 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b (\u0442\u0438\u043f\u0430 .all() \u0438\u043b\u0438 .items).\n  // \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u0432\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0441\u0440\u0430\u0437\u0443 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c,\n  // \u0438\u043b\u0438 \u0447\u0442\u043e \u043a\u043e\u0434 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u0431\u044b\u043b \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d \u043d\u0430 \u043f\u0430\u043a\u0435\u0442\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443.\n  // \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \"\u0432\u0441\u0435\" \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 .first() \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u0442\n  // \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u043c, \u0435\u0441\u043b\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0432\u0445\u043e\u0434\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0434\u043d\u043e\u0433\u043e.\n  console.warn(\"\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d \u043c\u0435\u0442\u043e\u0434 $input.first(), \u043d\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, $input.all() \u0438\u043b\u0438 $input.items). \u0411\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u0442\u0430 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c $input \u043a\u0430\u043a \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u0435\u0441\u043b\u0438 \u043e\u043d \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435.\");\n  // \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c $input \u043a\u0430\u043a \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u0435\u0441\u043b\u0438 \u043e\u043d \u0438\u043c\u0435\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 item.json.text\n  if ($input && $input.json && typeof $input.json.text === 'string') {\n     allInputItems = [$input]; // \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u0430\u043c $input \u043a\u0430\u043a \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\n  } else {\n      // \u0415\u0441\u043b\u0438 $input.first() \u0435\u0441\u0442\u044c, \u043d\u043e $input \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u043d\u0443\u0436\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b,\n      // \u0438 \u043d\u0435\u0442 $input.all(), \u0442\u043e \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0434\u0435\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \"\u0432\u0441\u0435\" \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b.\n      console.error(\"\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438\u0437 $input. $input \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c, \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u0430 .all() \u0438\u043b\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 .items, \u0438 \u0441\u0430\u043c \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u043d\u0443\u0436\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c $input.first() \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442.\");\n      try {\n        const firstItem = $input.first();\n        if (firstItem && firstItem.json && typeof firstItem.json.text === 'string') {\n            allInputItems = [firstItem]; // \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u044b\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b\n        } else {\n            allInputItems = []; // \u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u0436\u0435 \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435\n        }\n      } catch(e) {\n        console.error(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a $input.first() \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0445 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b:\", e);\n        allInputItems = [];\n      }\n  }\n} else if ($input && $input.json && typeof $input.json.text === 'string') {\n  // \u0415\u0441\u043b\u0438 $input \u2014 \u044d\u0442\u043e \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 (\u043d\u0435 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438 \u043d\u0435 \u0445\u0435\u043b\u043f\u0435\u0440),\n  // \u043d\u043e \u043e\u043d \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 { json: { text: \"...\" } }.\n  allInputItems = [$input];\n} else {\n  // \u0415\u0441\u043b\u0438 \u043d\u0438 \u043e\u0434\u0438\u043d \u0438\u0437 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u0435\u043b.\n  console.error(\"\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 $input. \u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. $input:\", $input);\n  allInputItems = []; // \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0441\u0442\u044b\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043e\u043a \u0434\u0430\u043b\u0435\u0435\n}\n\n// \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430: \u0443\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e allInputItems \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c.\nif (!Array.isArray(allInputItems)) {\n  console.error(\"\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f allInputItems \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0435\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f. \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 allInputItems:\", allInputItems);\n  // \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u043e\u0448\u0438\u0431\u043a\u043e\u0439,\n  // \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435 \u0432 \u043b\u043e\u0433\u0430\u0445.\n  return [];\n}\n\n// \u0415\u0441\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432 allInputItems \u043f\u0443\u0441\u0442 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e \u0438\u043b\u0438 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443),\n// \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443.\nif (allInputItems.length === 0) {\n    console.log(\"\u0412\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438\u043b\u0438 \u043d\u0435 \u0431\u044b\u043b\u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u044b.\");\n    return []; // \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432\n}\n\n// \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435 allInputItems\nconst results = allInputItems.map((item, index) => {\n  // \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 'item' \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043b\u044e\u0447 'json',\n  // \u0438 'item.json' \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043b\u044e\u0447 'text' \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c.\n  // \u042d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b $input.first() \u0432 \u0432\u0430\u0448\u0435\u043c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u0434\u0435.\n  if (item && item.json && typeof item.json.text === 'string') {\n    const inputString = item.json.text;\n    // \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043a \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c\u0443 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u043c\u0443\n    const cleanedString = cleanString(inputString);\n    // \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435\n    return { json: { cleanedText: cleanedString } };\n  } else {\n    // \u0415\u0441\u043b\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u0432\u0435\u0440\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435,\n    // \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435.\n    // \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438\u0437-\u0437\u0430 \u043e\u0434\u043d\u043e\u0433\u043e \"\u043f\u043b\u043e\u0445\u043e\u0433\u043e\" \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430.\n    console.warn(`\u042d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c ${index} \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u0432\u0435\u0440\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 'item.json.text'. \u042d\u043b\u0435\u043c\u0435\u043d\u0442:`, item);\n    return { json: { error: \"\u041d\u0435\u0432\u0435\u0440\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043b\u0435 'json.text'\", originalItem: item } };\n  }\n});\n\n// \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.\n// \u041a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u0432\u0438\u0434\u0430 { json: { cleanedText: \"...\" } }\n// \u0438\u043b\u0438 { json: { error: \"...\", originalItem: ... } } \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c.\nreturn results;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2160,
        1000
      ],
      "id": "56870e14-2cfa-4a91-be64-97c5142c1549",
      "name": "Delete trash1"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        1920,
        -40
      ],
      "id": "d6facbc7-040f-4e24-a13f-a5bb3ad062da",
      "name": "Merge transcribation and title, url,  etc1"
    },
    {
      "parameters": {
        "operation": "appendOrUpdate",
        "documentId": {
          "__rl": true,
          "value": "https://docs.google.com/spreadsheets/d/12taRIjIV0oAO9yn1B-LfwZXGAqz4I6mG1zm1UZ3SOUA/edit?usp=sharing",
          "mode": "url"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Part1",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/12taRIjIV0oAO9yn1B-LfwZXGAqz4I6mG1zm1UZ3SOUA/edit#gid=0"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Title": "={{ $json.title }}",
            "Topic and Detail": "={{ $json.mergedChunk }}",
            "UserId": "={{ $json.user_id }}",
            "VideoURL": "={{ $json.video_url }}",
            "ChannelURL": "={{ $json.channel_url }}",
            "VideoID": "={{ $json.video_id }}"
          },
          "matchingColumns": [
            "Title"
          ],
          "schema": [
            {
              "id": "Title",
              "displayName": "Title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Topic and Detail",
              "displayName": "Topic and Detail",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "UserId",
              "displayName": "UserId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "VideoURL",
              "displayName": "VideoURL",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "ChannelURL",
              "displayName": "ChannelURL",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "VideoID",
              "displayName": "VideoID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1880,
        460
      ],
      "id": "14cb3cd2-db4c-42d0-987a-91aefb7414cb",
      "name": "Google Sheets1",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "60d0d292-7f04-40b4-acf3-8a64c13acd26",
              "name": "title",
              "value": "={{ $json.snippet.title }}",
              "type": "string"
            },
            {
              "id": "753c7ef6-4008-4b16-81f0-7fbe291f015a",
              "name": "url",
              "value": "=https://youtube.com/watch?v={{ $json.snippet.resourceId.videoId }}",
              "type": "string"
            },
            {
              "id": "b51008a2-7ca7-408c-b212-f8a441d7c3e5",
              "name": "publishedAt",
              "value": "={{ $json.snippet.publishedAt }}",
              "type": "string"
            },
            {
              "id": "32915e1e-22a5-452f-a234-8371d3993da3",
              "name": "videoId",
              "value": "={{ $json.snippet.resourceId.videoId }}",
              "type": "string"
            },
            {
              "id": "081f3dd5-08ce-455f-9275-e10a8078a5b5",
              "name": "channel_id",
              "value": "=https://www.youtube.com/channel/{{ $json.snippet.channelId }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1260,
        -20
      ],
      "id": "00c3761b-fc66-418b-a18f-e6e3400cdc8e",
      "name": "Parse title ulr and publishedAt2"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "7f472442-7031-477a-91e5-7c4c1f395342",
              "name": "transcript",
              "value": "={{ $json.transcript }}",
              "type": "array"
            },
            {
              "id": "a31a1ac5-1b68-4555-a3b2-185871443971",
              "name": "title",
              "value": "={{ $json.title }}",
              "type": "string"
            },
            {
              "id": "9a348f4d-6993-4c14-8843-0f8526b66538",
              "name": "url",
              "value": "={{ $json.url }}",
              "type": "string"
            },
            {
              "id": "8cb5f6fc-103c-4632-be0f-bd20d2a871bd",
              "name": "videoId",
              "value": "={{ $json.videoId }}",
              "type": "string"
            },
            {
              "id": "8bf407f6-c4ca-42c1-b0d1-a870f4d533a5",
              "name": "concatenatedTranscript",
              "value": "={{ $json.concatenatedTranscript }}",
              "type": "string"
            },
            {
              "id": "148d1f7d-10dc-448a-960b-533f4113ee53",
              "name": "channel_id",
              "value": "={{ $json.channel_id }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2360,
        -40
      ],
      "id": "c03734b2-b626-4dc0-93f9-494794bf8303",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=\u041d\u0435 \u043f\u0438\u0448\u0438 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043e\u0442 \u0441\u0435\u0431\u044f\n\n\u042f \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u0435\u043a\u0441\u0442 \u0432 JSON-\u0444\u043e\u0440\u043c\u0430\u0442 \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u043d\u043b\u0430\u0439\u043d-\u043a\u0443\u0440\u0441\u0430(\u043a\u0443\u0440\u0441\u043e\u0432, \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u044f\u0434\u043e\u0432).\n\u041e\u0431\u0449\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043a\u0443\u0440\u0441\u0435:\n\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 \u043e\u0431\u0449\u0435\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0443\u0440\u0441\u0430 (\u043e\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0442\u0435\u043a\u0441\u0442\u0430, \u0434\u043e Lesson Description).\n\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 \u043e\u0431\u0449\u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0443\u0440\u0441\u0430.\n\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u043a\u0443\u0440\u0441\u0430: 680f332a16f8bb2b6ce9e71d\n\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438: beginner\n\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u0430: (\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c)\n\u041f\u0440\u0435\u0432\u044c\u044e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0443\u0440\u0441\u0430: (\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c)\n\u041c\u043e\u0434\u0443\u043b\u0438 \u043a\u0443\u0440\u0441\u0430:\n\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0442\u0435\u043a\u0441\u0442\u0430, \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0441 \"Lesson Description\" \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \"Lesson Description\" (\u0438\u043b\u0438 \u043a\u043e\u043d\u0446\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u0430), \u0441\u043e\u0437\u0434\u0430\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \"modules\".\n\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f:\n\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u044f: \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 **\u043a\u0440\u0430\u0442\u043a\u0438\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a**, \u043e\u0431\u043e\u0431\u0449\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\".\n\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f: \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 **\u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435**, \u043e\u0431\u043e\u0431\u0449\u0430\u044e\u0449\u0435\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\".\n\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f (\"content\"): \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0442\u0435\u043a\u0441\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\".\n\u0423\u0440\u043e\u043a\u0438 \u043c\u043e\u0434\u0443\u043b\u044f (\"lessons\"): \u0421\u043e\u0437\u0434\u0430\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043e\u0434\u0438\u043d \u043e\u0431\u044a\u0435\u043a\u0442 \u0443\u0440\u043e\u043a\u0430.\n\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0443\u0440\u043e\u043a\u0430 (\"title\"): \u0421\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043a\u0430\u043a \"Module \u2116X\", \u0433\u0434\u0435 X - \u043f\u043e\u0440\u044f\u0434\u043a\u043e\u0432\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\".\n\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0443\u0440\u043e\u043a\u0430 (\"content\"): \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0442\u0435\u043a\u0441\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \"Lesson Description\", \u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0443\u043d\u043a\u0442\u0430\u043c\u0438, \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0438 \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0442\u0435\u043e\u0440\u0438\u044f, \u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u0442\u0430\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e\n\u0414\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0443\u0440\u043e\u043a\u0430 (\"duration\"): 15\n\u0422\u0438\u043f \u0443\u0440\u043e\u043a\u0430 (\"type\"): text\n\u0422\u0438\u043f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 (\"contentType\"): standard\n\u0420\u0435\u0441\u0443\u0440\u0441\u044b \u0443\u0440\u043e\u043a\u0430 (\"resources\"): []\n\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u043a\u0430 (\"practiceExercises\"): []\n\u0411\u043b\u043e\u043a\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0443\u0440\u043e\u043a\u0430 (\"contentBlock\"): []\n\u0422\u0435\u0441\u0442\u044b \u043c\u043e\u0434\u0443\u043b\u044f (\"tests\"): []\n\u0412\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442:\n{{ $json.processedLessonText }}\nJSON Structure:\n{\n\"title\": \"(\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u0434\u043e Lesson Description 1)\",\n\"description\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u0430)\",\n\"category\": \"680f332a16f8bb2b6ce9e71d\",\n\"difficulty\": \"beginner\",\n\"image\": \"\",\n\"imagePreview\": \"\",\n\"modules\": [\n{\n\"title\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u044f 1)\",\n\"description\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f 1)\",\n\"content\": \"(\u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0442\u0435\u043a\u0441\u0442 Lesson Description 1)\",\n\"lessons\": [\n{\n\"title\": \"Module \u21161\",\n\"content\": \"(\u0442\u0435\u043a\u0441\u0442 Lesson Description 1 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434 \u043f\u043b\u0430\u043d, \u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0443\u043d\u043a\u0442\u0430\u043c\u0438, \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0438 \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0442\u0435\u043e\u0440\u0438\u044f, \u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u0442\u0430\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e)\",\n\"duration\": 15,\n\"type\": \"text\",\n\"contentType\": \"standard\",\n\"resources\": [],\n\"practiceExercises\": [],\n\"contentBlocks\": []\n}\n],\n\"tests\": []\n},\n{\n\"title\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u044f 2)\",\n\"description\": \"(\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f 2)\",\n\"content\": \"(\u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0442\u0435\u043a\u0441\u0442 Lesson Description 2)\",\n\"lessons\": [\n{\n\"title\": \"Module \u21162\",\n\"content\": \"(\u0442\u0435\u043a\u0441\u0442 Lesson Description 2 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434 \u043f\u043b\u0430\u043d \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e)\",\n\"duration\": 15,\n\"type\": \"text\",\n\"contentType\": \"standard\",\n\"resources\": [],\n\"practiceExercises\": [],\n\"contentBlocks\": []\n}\n],\n\"tests\": []\n},\n// ... \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e Lesson Description \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043c\u043e\u0434\u0443\u043b\u044c\n]\n}\n\u0412\u0430\u0436\u043d\u043e: \u041e\u0431\u0440\u0430\u0442\u0438 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043e\u0431\u0449\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043a\u0443\u0440\u0441\u0435(\u043a\u0443\u0440\u0441\u0430\u0445) (title, description, category, difficulty, image, imagePreview) \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 JSON. \u041c\u0430\u0441\u0441\u0438\u0432 \"modules\" \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \"Lesson Description\". \u041f\u0440\u043e\u0432\u0435\u0440\u044c, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \",\" \u0438 {} \u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0438 \u041f\u0438\u0448\u0438 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c"
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.5,
      "position": [
        2440,
        1000
      ],
      "id": "bdded2e2-b7ed-4cf2-af69-b6505600a0cb",
      "name": "JSON generator2"
    }
  ],
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Greg Isenberg",
            "type": "main",
            "index": 0
          },
          {
            "node": "Nick Saraev",
            "type": "main",
            "index": 0
          },
          {
            "node": "Creator Magic",
            "type": "main",
            "index": 0
          },
          {
            "node": "Cole Medin",
            "type": "main",
            "index": 0
          },
          {
            "node": "Your AI Workflow",
            "type": "main",
            "index": 0
          },
          {
            "node": "Julian Goldie SEO",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Greg Isenberg": {
      "main": [
        [
          {
            "node": "Merge YouTube videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Nick Saraev": {
      "main": [
        [
          {
            "node": "Merge YouTube videos",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Creator Magic": {
      "main": [
        [
          {
            "node": "Merge YouTube videos",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Cole Medin": {
      "main": [
        [
          {
            "node": "Merge YouTube videos",
            "type": "main",
            "index": 3
          }
        ]
      ]
    },
    "Your AI Workflow": {
      "main": [
        [
          {
            "node": "Merge YouTube videos",
            "type": "main",
            "index": 4
          }
        ]
      ]
    },
    "Julian Goldie SEO": {
      "main": [
        [
          {
            "node": "Merge YouTube videos",
            "type": "main",
            "index": 5
          }
        ]
      ]
    },
    "youtube video parser": {
      "main": [
        [
          {
            "node": "Merge transcribation and title, url,  etc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "24 hours": {
      "main": [
        [
          {
            "node": "Parse title ulr and publishedAt2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Filter": {
      "main": [
        [
          {
            "node": "add transcript_original",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "add transcript_original": {
      "main": [
        [
          {
            "node": "HTTP OpenRouter Request",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge OpenRouter and transcript",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Split to Chunks": {
      "main": [
        [
          {
            "node": "Chat Completion",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Chunks and title, url, etc",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Chat Completion": {
      "main": [
        [
          {
            "node": "Merge Chunks and title, url, etc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Summarizer": {
      "main": [
        [
          {
            "node": "remove json",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse title ulr and publishedAt": {
      "main": [
        [
          {
            "node": "youtube video parser",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge transcribation and title, url,  etc",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "remove json": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "Add Titles to rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Theory Generator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "JSON generator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "HTTP OpenRouter Request": {
      "main": [
        [
          {
            "node": "Merge OpenRouter and transcript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge YouTube videos": {
      "main": [
        [
          {
            "node": "24 hours",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge transcribation and title, url,  etc": {
      "main": [
        [
          {
            "node": "Error Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge OpenRouter and transcript": {
      "main": [
        [
          {
            "node": "Split to Chunks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Chunks and title, url, etc": {
      "main": [
        [
          {
            "node": "Summarizer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Titles to rows": {
      "main": [
        [
          {
            "node": "Theory Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Theory Generator": {
      "main": [
        [
          {
            "node": "Theory Merger",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Theory Merger": {
      "main": [
        [
          {
            "node": "Add nums to Lesson Description",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add nums to Lesson Description": {
      "main": [
        [
          {
            "node": "JSON generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JSON generator": {
      "main": [
        [
          {
            "node": "Delete trash",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "youtube video parser1": {
      "main": [
        [
          {
            "node": "Merge transcribation and title, url,  etc1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code5": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Google Sheets2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Columns": {
      "main": [
        [
          {
            "node": "Theory Generator1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "Theory Merger1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Chat Completion1": {
      "main": [
        [
          {
            "node": "Merge Chunks and title, url, etc1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split to Chunks1": {
      "main": [
        [
          {
            "node": "Chat Completion1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Chunks and title, url, etc1",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Summarizer1": {
      "main": [
        [
          {
            "node": "remove json1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse title ulr and publishedAt1": {
      "main": [
        []
      ]
    },
    "remove json1": {
      "main": [
        [
          {
            "node": "Add Columns",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "OpenRouter Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "Theory Generator1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model3": {
      "ai_languageModel": [
        [
          {
            "node": "JSON generator1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Merge Chunks and title, url, etc1": {
      "main": [
        [
          {
            "node": "Summarizer1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Theory Generator1": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Theory Merger1": {
      "main": [
        [
          {
            "node": "Add nums to Lesson Description1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add nums to Lesson Description1": {
      "main": [
        [
          {
            "node": "JSON generator1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JSON generator1": {
      "main": [
        [
          {
            "node": "Delete trash1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete trash1": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge transcribation and title, url,  etc1": {
      "main": [
        [
          {
            "node": "Code5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse title ulr and publishedAt2": {
      "main": [
        [
          {
            "node": "Merge transcribation and title, url,  etc1",
            "type": "main",
            "index": 1
          },
          {
            "node": "youtube video parser1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Split to Chunks1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": {
    "node:Schedule Trigger": {
      "recurrenceRules": []
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "versionId": "61e111ef-8047-4d70-b276-ae5904250baf",
  "triggerCount": 1,
  "tags": []
}