<commit_before>/**
 * Get first version of this done asap to test idea
 */


const BLANK = "";
const SPACE = " ";
const DOT = ".";
const COLON = ":";
const SEMI_COLON = ";"


const Mono = {
  createStyle(element, className, styles, ...children) {
    return {
      element,
      className,
      styles,
      children
    };
  },

  createCSS(a) {
    a.forEach(b => Mono._parseCSS(b));
    Mono._parseAst();
  },

  _parseCSS(c, parentRef = null) {
    const ref = Mono._makeRef(c);
    const fullyQualifiedRef = parentRef ? `${parentRef}${SPACE}${ref}` : ref;
    Mono._saveRef(fullyQualifiedRef, c.styles);

    if (c.children.length) {
      if (parentRef) {
        parentRef += `${SPACE}${ref}`;
      } else {
        parentRef = ref;
      }

      c.children.forEach(d => Mono._parseCSS(d, parentRef));
    }
  },

  _parseAst() {
    for (var ref in Mono._AST) {
      console.log(ref);
      console.log(Mono._AST[ref]);

      ref.split(SPACE)
          .map(b => b.split(DOT))
          .forEach(c => {
            console.log(c);
          });

      console.log('------------------------');
    }
  },

  _AST: {},

  _saveRef(ref, styles) {
    if (Mono._AST[ref]) {
      try {
        Mono._stylesClash(Mono._AST[ref], styles);
        // merge styles
        Mono._AST[ref] += styles;
      } catch (e) {
        throw new e.constructor(e.message);
      }
    } else {
      Mono._AST[ref] = styles;
    }
  },

  _stylesClash(existingStyles, newStyles) {
    for (var property in Mono._stylesAsObject(newStyles)) {
      if (Mono._stylesAsObject(existingStyles)[property]) {
        throw new Error(`
          The property: '${property}' has already been defined.

          existingStyles:
            ${existingStyles}

          newStyles:
            ${newStyles}
        `);
      }
    }

    return false;
  },

  _stylesAsObject(styles) {
    const styleObj = {}

    styles.split(SEMI_COLON)
          .filter(res => res !== BLANK)
          .map(res => res.trim())
          .forEach(declaration => {
            const [property, value] = declaration.split(COLON).map(res => res.trim());
            styleObj[property] = value;
          });

    return styleObj;
  },

  _makeSelector({element, className}) {
    if (className) {
      return `${element}[class="${className.replace(DOT, SPACE)}"]`;
    } else {
      return element;
    }
  },

  _makeRef({element, className}) {
    if (className) {
      return `${element}${DOT}${className}`;
    } else {
      return element;
    }
  },

  _makeSelectorFromRef(ref) {
    console.log(`[_makeSelectorFromRef] ref: ${ref}`);
  }
}



const styles = [
  Mono.createStyle(
    "form",
    null,
    "display: block;"
  ),

  Mono.createStyle(
    "span",
    null,
    "color: blue; font-style: italic;"
  ),

  Mono.createStyle(
    "span",
    null,
    "font-size: 23px; font-weight: bold; font-style:italic;line-height: 20px;"
  ),

  Mono.createStyle(
    "form",
    "base-form",
    "padding: 20px; margin: 10px;background: ivory; border: 1px solid grey;",
    Mono.createStyle(
      "p",
      null,
      "font-size: 12px;color: #333;"
    ),
    Mono.createStyle(
      "span",
      "error-message",
      "display: none;"
    )
  ),

  Mono.createStyle(
    "form",
    "base-form.base-form--saving",
    "background: lightgrey; opacity: 0.8; pointer-events: none;"
  ),

  Mono.createStyle(
    "form",
    "base-form.base-form--error",
    "border: 1px solid red;",
    Mono.createStyle(
      "input",
      null,
      "border: 1px solid red;"
    ),
    Mono.createStyle(
      "span",
      "error-message",
      "display: block; color: red;",
      Mono.createStyle(
        "a",
        "anotherLink",
        "color: grey"
      ),
      Mono.createStyle(
        "p",
        null,
        "font-size: 20px",
        Mono.createStyle(
          "a",
          "yetAnotherLink",
          "color: RED"
        )
      )
    )
  )
];


Mono.createCSS(styles);<commit_msg>[csx] better detection of overrides among equal refs<commit_after>/**
 * Get first version of this done asap to test idea
 */


const BLANK = "";
const SPACE = " ";
const DOT = ".";
const COLON = ":";
const SEMI_COLON = ";"


const Mono = {
  createStyle(element, className, styles, ...children) {
    return {
      element,
      className,
      styles,
      children
    };
  },

  createCSS(styles) {
    styles.forEach(block => Mono._parseStyles(block));
    Mono._parseAst();
  },

  _parseStyles(block, parentRef = null) {
    const ref = Mono._makeRef(block);
    const fullyQualifiedRef = parentRef ? `${parentRef}${SPACE}${ref}` : ref;
    Mono._saveRef(fullyQualifiedRef, block.styles);

    if (block.children.length) {
      if (parentRef) {
        parentRef += `${SPACE}${ref}`;
      } else {
        parentRef = ref;
      }

      block.children.forEach(child => Mono._parseStyles(child, parentRef));
    }
  },

  _parseAst() {
    for (var ref in Mono._AST) {
      console.log(ref);
      console.log(Mono._AST[ref]);

      ref.split(SPACE)
          .map(b => b.split(DOT))
          .forEach(c => {
            console.log(c);
          });

      console.log('------------------------');
    }
  },

  _AST: {},

  _saveRef(ref, styles) {
    if (Mono._AST[ref]) {
      // ref already exists, merge styles with existing styles if no overrides exist.
      try {
        Mono._stylesUnique(Mono._AST[ref], styles);
        Mono._AST[ref] += styles; // merge styles
      } catch (e) {
        throw new e.constructor(e.message);
      }
    } else {
      Mono._AST[ref] = styles;
    }
  },

  // unique in terms of CSS property (not including CSS value)
  // would need to handle short-hands (margin vs margin-top)
  _stylesUnique(existingStyles, newStyles) {
    for (var property in Mono._stylesAsObject(newStyles)) {
      if (Mono._stylesAsObject(existingStyles)[property]) {
        throw new Error(`
          The property: '${property}' has already been defined.

          existingStyles:
            ${existingStyles}

          newStyles:
            ${newStyles}
        `);
      }
    }

    return true;
  },

  _stylesAsObject(styles) {
    const styleObj = {}

    styles.split(SEMI_COLON)
          .filter(res => res !== BLANK)
          .map(res => res.trim())
          .forEach(declaration => {
            const [property, value] = declaration.split(COLON).map(res => res.trim());
            styleObj[property.toLowerCase()] = value;
          });

    return styleObj;
  },

  _makeSelector({element, className}) {
    if (className) {
      return `${element}[class="${className.replace(DOT, SPACE)}"]`;
    } else {
      return element;
    }
  },

  _makeRef({element, className}) {
    if (className) {
      return `${element}${DOT}${className}`;
    } else {
      return element;
    }
  },

  _makeSelectorFromRef(ref) {
    console.log(`[_makeSelectorFromRef] ref: ${ref}`);
  }
}



const styles = [
  Mono.createStyle(
    "form",
    null,
    "display: block;"
  ),

  Mono.createStyle(
    "span",
    null,
    "color: blue; font-style: italic;"
  ),

  Mono.createStyle(
    "span",
    null,
    "font-size: 23px; font-weight: bold; line-height: 20px;"
  ),

  Mono.createStyle(
    "span",
    "error-message",
    "color: red; font-weight: bold;"
  ),

  Mono.createStyle(
    "form",
    "base-form",
    "padding: 20px; margin: 10px;background: ivory; border: 1px solid grey;",
    Mono.createStyle(
      "p",
      null,
      "font-size: 12px;color: #333;"
    ),
    Mono.createStyle(
      "span",
      "error-message",
      "display: none;"
    )
  ),

  Mono.createStyle(
    "form",
    "base-form.base-form--saving",
    "background: lightgrey; opacity: 0.8; pointer-events: none;"
  ),

  Mono.createStyle(
    "form",
    "base-form.base-form--error",
    "border: 1px solid red;",
    Mono.createStyle(
      "input",
      null,
      "border: 1px solid red;"
    ),
    Mono.createStyle(
      "span",
      "error-message",
      "display: block;",
      Mono.createStyle(
        "a",
        "anotherLink",
        "color: grey"
      ),
      Mono.createStyle(
        "p",
        null,
        "font-size: 20px",
        Mono.createStyle(
          "a",
          "yetAnotherLink",
          "color: RED"
        )
      )
    )
  )
];


Mono.createCSS(styles);
{'fraction_non_alphanumeric': 0.16141024103609544, 'fraction_numerical': 0.004796738218011752, 'mean_word_length': 2.0415754923413565, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4718568', 'n_tokens_mistral': 2815, 'n_tokens_neox': 2782, 'n_words': 549}