function findDuplicateRulestype4(records) {
  const seenRules = new Map();
  const duplicateRecords = [];

  const stripHTML4 = (htmlString) => {
  if (typeof htmlString !== "string") {
    htmlString = String(htmlString || "");
  }

  const div = document.createElement("div");
  div.innerHTML = htmlString.replace(/&nbsp;/gi, " "); // Convert &nbsp; to space for safe parsing

  function walkAndClean(node) {
    let result = "";
    for (const child of node.childNodes) {
      if (child.nodeType === Node.TEXT_NODE) {
        result += child.nodeValue;
      } else if (child.nodeType === Node.ELEMENT_NODE) {
        result += walkAndClean(child);
      }
    }
    return result;
  }

  return walkAndClean(div)
    .replace(/\u200B|\uFEFF|\u00A0/g, "")  // Remove hidden/unicode spaces
    .replace(/\./g, "")                   // Remove full stops
    .replace(/\s+/g, "")                  // 🔥 Remove ALL spaces
    .toLowerCase();                       // Normalize case
};

  // ✅ Updated HTML stripper to preserve word separation
  // function stripHTML4(htmlString) {
  //   if (typeof htmlString !== 'string') {
  //     htmlString = String(htmlString || '');
  //   }

  //   const div = document.createElement('div');
  //   div.innerHTML = htmlString.replace(/&nbsp;/gi, '');

  //   function walkAndClean(node) {
  //     let result = '';
  //     for (const child of node.childNodes) {
  //       if (child.nodeType === Node.TEXT_NODE) {
  //         result += ' ' + child.nodeValue;
  //       } else if (child.nodeType === Node.ELEMENT_NODE) {
  //         result += ' ' + walkAndClean(child);  // 👈 preserve space between tags
  //       }
  //     }
  //     return result;
  //   }

  //   return walkAndClean(div)
  //     .replace(/\u200B|\uFEFF|\u00A0/g, '')   // Remove hidden Unicode & non-breaking spaces
  //     .replace(/[.]/g, '')                    // Remove full stops
  //     .replace(/\s*,\s*/g, ',')               // Normalize space around commas
  //     .replace(/\s+/g, ' ')                   // Collapse multiple spaces
  //     .trim()
  //     .toLowerCase();
  // }

  const normalizeConditionParts = (rawConditions) => {
    const parts = rawConditions?.split(",") || [];
    const set1 = [], set2 = [];
    let currentSet = null;
    window.tempClause = [];

    const pushClause = (targetSet, includeOperator = null) => {
      if (window.tempClause.length && targetSet) {
        const joinedClause = window.tempClause.join(",").trim();
        const cleaned = stripHTML4(joinedClause);
        if (cleaned) targetSet.push(cleaned);
        window.tempClause = [];

        if (includeOperator) {
          targetSet.push(includeOperator);
        }
      }
    };

    const isSetMarker = (part) =>
      part.includes("condition_set_1") || part.includes("condition_set_2");

    const handleSetSwitch = (rawPart) => {
      pushClause(currentSet);
      if (rawPart.includes("condition_set_1")) return set1;
      if (rawPart.includes("condition_set_2")) return set2;
      return currentSet;
    };

    const isLogicalOperator = (part) => part === "any" || part === "all";

    for (let i = 0; i < parts.length; i++) {
      const rawPart = parts[i].trim();

      if (isSetMarker(rawPart)) {
        currentSet = handleSetSwitch(rawPart);
      } else if (isLogicalOperator(rawPart.toLowerCase())) {
        pushClause(currentSet, rawPart.toLowerCase());
      } else if (currentSet) {
        window.tempClause.push(rawPart);
      }
    }

    pushClause(currentSet);
    set1.sort();
    set2.sort();

    console.log("🔹 Sorted Set1:", set1);
    console.log("🔸 Sorted Set2:", set2);

    return { set1, set2 };
  };

  const normalizeField = (value) => {
    if (Array.isArray(value)) {
      return value
        .map((item) =>
          Object.values(item)
            .map((v) => stripHTML4(v))
            .join(" ")
        )
        .sort()
        .join(",");
    } else if (typeof value === "string") {
      return value
        .split(",")
        .map((item) => stripHTML4(item))
        .sort()
        .join(",");
    }
    return "";
  };

  const normalizeEvents = (eventString) => {
    if (typeof eventString !== "string") return "";
    return eventString
      .split(/\s+or\s+/i)
      .map((item) => stripHTML4(item))
      .sort()
      .join(" or ");
  };

  const normalizeActions = (rawActions) => {
    const parts = rawActions?.split("&?") || [];
    const normalizedClauses = [];

    for (const part of parts) {
      const items = part.split(",").map((v) => stripHTML4(v));
      const clause = items.sort().join(" ").trim();  // ✅ joins with space after sorting
      if (clause) normalizedClauses.push(clause);
    }

    normalizedClauses.sort((a, b) => a.localeCompare(b));
    return normalizedClauses.join(" | ");
  };

  records.forEach((record, index) => {
    const { conditions, actions, operator, events, performer } = record.data;

    const { set1, set2 } = normalizeConditionParts(conditions);
    const normalizedActions = normalizeActions(actions);
    const normalizedEvents = normalizeEvents(events);
    const normalizedPerformer = normalizeField(performer);
    const normalizedOperator = operator ? stripHTML4(operator) : "";

    const key1 = `${set1.join("|")}|${set2.join("|")}|${normalizedActions}|${normalizedOperator}|${normalizedEvents}|${normalizedPerformer}`;
    const key2 = `${set2.join("|")}|${set1.join("|")}|${normalizedActions}|${normalizedOperator}|${normalizedEvents}|${normalizedPerformer}`;

    console.log(`\n=== Record ${index + 1} ===`);
    console.log("Condition Set 1:", set1);
    console.log("Condition Set 2:", set2);
    console.log("Actions:", normalizedActions);
    console.log("Operator:", normalizedOperator);
    console.log("Events:", normalizedEvents);
    console.log("Performer:", normalizedPerformer);
    console.log("Key 1:", key1);
    console.log("Key 2:", key2);

    if (seenRules.has(key1) || seenRules.has(key2)) {
      console.log(`🔁 Duplicate found for Record ${index + 1}`);
      const existing = seenRules.get(key1) || seenRules.get(key2);
      if (!duplicateRecords.includes(existing)) {
        duplicateRecords.push(existing);
      }
      duplicateRecords.push(record);
    } else {
      seenRules.set(key1, record);
      console.log(`🆕 First time seen for Record ${index + 1}`);
    }
  });

  return duplicateRecords;
}



add this code for type4