function findDuplicateRulestype1and3(records = [], { flat = false } = {}) {
    const seenKeys = new Map();  // key -> group key or representative record
    const groupsMap = new Map(); // group key -> array of rules
    const duplicateRecords = []; // for flat mode
  
    const 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);
          }
        }
        return result;
      }
  
      return walkAndClean(div)
        .replace(/\u200B|\uFEFF|\u00A0/g, "")
        .replace(/\./g, "")
        .replace(/\s+/g, "")
        .toLowerCase();
    };
  
    const normalizeConditionParts = (rawConditions) => {
      console.log("✅ [normalizeConditionParts] rawConditions:", rawConditions);
      console.log("ℹ️ Type of rawConditions:", typeof rawConditions);
    
      const parts = typeof rawConditions === "string" ? rawConditions.split(",") : [];
    
      if (typeof rawConditions !== "string") {
        console.warn("⚠️ [normalizeConditionParts] Expected string but got:", typeof rawConditions, rawConditions);
      }
    
      const set1 = [], set2 = [];
      let currentSet = null;
      let tempClause = [];
    
      const stripHTML4 = (htmlString) => {
        if (typeof htmlString !== "string") htmlString = String(htmlString || "");
        const div = document.createElement("div");
        div.innerHTML = htmlString.replace(/&nbsp;/gi, " ");
        return div.textContent || div.innerText || "";
      };
    
      const pushClause = (targetSet, includeOperator = null) => {
        if (tempClause.length && targetSet) {
          const joinedClause = tempClause.join(",").trim();
          const cleaned = stripHTML4(joinedClause);
          console.log("📦 [pushClause] Cleaned clause:", cleaned);
          if (cleaned) targetSet.push(cleaned);
          tempClause = [];
    
          if (includeOperator) {
            console.log("➕ [pushClause] Operator pushed:", 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) => {
        const op = part.toLowerCase();
        return op === "any" || op === "all";
      };
    
      for (let i = 0; i < parts.length; i++) {
        const rawPart = parts[i].trim();
        if (isSetMarker(rawPart)) {
          console.log("🔀 [Set Switch] Switching set for part:", rawPart);
          currentSet = handleSetSwitch(rawPart);
        } else if (isLogicalOperator(rawPart)) {
          console.log("⚙️ [Operator] Found logical operator:", rawPart);
          pushClause(currentSet, rawPart.toLowerCase());
        } else if (currentSet) {
          tempClause.push(rawPart);
        }
      }
    
      pushClause(currentSet);
      set1.sort();
      set2.sort();
    
      console.log("✅ Final set1:", set1);
      console.log("✅ Final set2:", set2);
    
      return { set1, set2 };
    };
    
  
    const normalizeActions = (rawActions) => {
      if (typeof rawActions !== 'string' || !rawActions) {
        return '';
      }
    
      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();
        if (clause) normalizedClauses.push(clause);
      }
    
      normalizedClauses.sort((a, b) => a.localeCompare(b));
    
      return normalizedClauses.join(" | ");
    };
  
    for (const record of records) {
      const data = record.data ?? record;
      const { conditions = "", actions = "", operator = "", active } = data;
  
      if (!(active === true || active === "true")) continue;
  
      const { set1, set2 } = normalizeConditionParts(conditions);
      const normalizedActions = normalizeActions(actions);
      const normalizedOperator = stripHTML4(operator);
  
      const key1 = `${set1.join("|")}|${set2.join("|")}|${normalizedActions}|${normalizedOperator}`;
      const key2 = `${set2.join("|")}|${set1.join("|")}|${normalizedActions}|${normalizedOperator}`;
  
      if (flat) {
        // Flat duplicate logic
        if (seenKeys.has(key1) || seenKeys.has(key2)) {
          const existing = seenKeys.get(key1) || seenKeys.get(key2);
          if (!duplicateRecords.includes(existing)) {
            duplicateRecords.push(existing);
          }
          duplicateRecords.push(record);
        } else {
          seenKeys.set(key1, record);
        }
      } else {
        // Grouped duplicate logic
        if (seenKeys.has(key1)) {
          const groupKey = seenKeys.get(key1);
          groupsMap.get(groupKey).push(record);
        } else if (seenKeys.has(key2)) {
          const groupKey = seenKeys.get(key2);
          groupsMap.get(groupKey).push(record);
        } else {
          seenKeys.set(key1, key1);
          groupsMap.set(key1, [record]);
        }
      }
    }
  
    return flat
      ? duplicateRecords
      : Array.from(groupsMap.values()).filter(group => group.length > 1);
  }



in this, how did you fixed for conditoins and actions 

function findDuplicateRulestype4(records = []) {
  const seenRules = new Map(); // key => array of records with that key
  const duplicateGroups = [];

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

    if (typeof document === "undefined") return 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);
        }
      }
      return result;
    }

    return walkAndClean(div)
      .replace(/\u200B|\uFEFF|\u00A0/g, "")
      .replace(/\./g, "")
      .replace(/\s+/g, "")
      .toLowerCase();
  };

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

    const pushClause = (targetSet, includeOperator = null) => {
      if (tempClause.length && targetSet) {
        const joinedClause = tempClause.join(",").trim();
        const cleaned = stripHTML4(joinedClause);
        if (cleaned) targetSet.push(cleaned);
        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) {
        tempClause.push(rawPart);
      }
    }

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

    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();
      if (clause) normalizedClauses.push(clause);
    }

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

  // ✅ Filter only active records
  const activeRecords = records.filter(
    (record) => record?.active === true || record?.active === "true"
  );

  activeRecords.forEach((record, index) => {
    if (!record || typeof record !== "object") {
      console.warn(`⚠️ Skipping invalid record at index ${index}`, record);
      return;
    }

    const {
      conditions = "",
      actions = "",
      operator = "",
      events = "",
      performer = "",
    } = record;

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

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

    let groupKey = null;
    if (seenRules.has(key1)) {
      groupKey = key1;
    } else if (seenRules.has(key2)) {
      groupKey = key2;
    }

    if (groupKey) {
      seenRules.get(groupKey).push(record);
    } else {
      seenRules.set(key1, [record]);
    }
  });

  for (const group of seenRules.values()) {
    if (group.length > 1) {
      duplicateGroups.push(group);
    }
  }

  return duplicateGroups;
}


same way fix in this too