<commit_before>const defaultDom = {
  tag: null,
  attributes: {},
  children: []
}

module.exports = (target) => {
  let previous

  return (next) => {
    let result = morph(target, next, previous)

    previous = next

    return result
  }
}

function morph (target, next, previous) {
  const document = target.ownerDocument

  if (!previous) {
    previous = defaultDom
  }

  const usedAttributes = []

  const nextAttrs = Object.keys(next.attributes)

  for (let i = 0; i < nextAttrs.length; i++) {
    const key = nextAttrs[i]

    usedAttributes.push(key)

    const val = next.attributes[key]

    if (['selected', 'checked', 'disabled'].includes(key)) {
      target[key] = val

      if (val) {
        target.setAttribute(key, '')
      } else {
        target.removeAttribute(key)
      }
    } else if (key === 'value') {
      target.value = val

      target.setAttribute('value', val)
    } else if (val !== previous.attributes[key]) {
      if (key.startsWith('on')) {
        target[key] = val
      } else {
        target.setAttribute(key, val)
      }
    }
  }

  const unusedAttrs = Object.keys(previous.attributes).filter((key) => !usedAttributes.includes(key))

  for (let i = 0; i < unusedAttrs.length; i++) {
    const key = unusedAttrs[i]

    if (key.startsWith('on')) {
      delete target[key]
    } else {
      if (key === 'value') {
        target.value = ''
      } else if (['selected', 'checked', 'disabled'].includes(key)) {
        target[key] = false
      }

      target.removeAttribute(key)
    }
  }

  let i = 0

  for (; i < next.children.length; i++) {
    let el
    const nextChild = next.children[i]
    const previousChild = previous.children[i]
    const childNode = target.childNodes[i]

    if (typeof nextChild !== 'object') {
      el = document.createTextNode(nextChild)

      if (childNode == null) {
        target.appendChild(el)
      } else if (nextChild !== previousChild) {
        target.replaceChild(el, childNode)
      }
    } else if (childNode == null) {
      el = document.createElement(nextChild.tag)

      el = morph(el, nextChild, previousChild)

      target.appendChild(el)

      if (nextChild.hooks.onmount) {
        nextChild.hooks.onmount(el)
      }
    } else if (childNode.nodeType !== 1 || childNode.nodeName.toLowerCase() !== nextChild.tag) {
      el = document.createElement(nextChild.tag)

      el = morph(el, nextChild, previousChild)

      target.replaceChild(el, childNode)

      if (nextChild.hooks.onmount) {
        nextChild.hooks.onmount(el)
      }
    } else {
      el = childNode

      morph(el, nextChild, previousChild)
    }

    if (nextChild != null && typeof nextChild === 'object' && nextChild.hooks.onupdate) {
      nextChild.hooks.onupdate(el)
    }
  }

  while (target.childNodes.length > i) {
    target.removeChild(target.childNodes[i])
  }

  return target
}
<commit_msg>Finish update<commit_after>
const assert = require('assert')

const defaultDom = {
  tag: null,
  attributes: {},
  children: []
}

module.exports = (target) => {
  let previous

  return (next) => {
    assert.strictEqual(target.nodeName.toLowerCase(), next.tag, 'unsupported node replacement')

    let result = morph(target, next, previous)

    previous = next

    return result
  }
}

function morph (target, next, previous) {
  const targetNamespace = target.namespaceURI
  const document = target.ownerDocument

  if (!previous) {
    previous = defaultDom
  }

  const usedAttributes = []

  const nextAttrs = Object.keys(next.attributes)

  for (let i = 0; i < nextAttrs.length; i++) {
    const key = nextAttrs[i]

    usedAttributes.push(key)

    const val = next.attributes[key]

    if (['selected', 'checked', 'disabled'].includes(key)) {
      target[key] = val

      if (val) {
        target.setAttribute(key, '')
      } else {
        target.removeAttribute(key)
      }
    } else if (key === 'value') {
      target.value = val

      target.setAttribute('value', val)
    } else if (val !== previous.attributes[key]) {
      if (key.startsWith('on')) {
        target[key] = val
      } else {
        target.setAttribute(key, val)
      }
    }
  }

  const unusedAttrs = Object.keys(previous.attributes).filter((key) => !usedAttributes.includes(key))

  for (let i = 0; i < unusedAttrs.length; i++) {
    const key = unusedAttrs[i]

    if (key.startsWith('on')) {
      delete target[key]
    } else {
      if (key === 'value') {
        target.value = ''
      } else if (['selected', 'checked', 'disabled'].includes(key)) {
        target[key] = false
      }

      target.removeAttribute(key)
    }
  }

  let i = 0

  for (; i < next.children.length; i++) {
    const nextChild = next.children[i]
    const previousChild = previous.children[i]
    const childNode = target.childNodes[i]
    const shouldAppendChild = childNode == null

    if (typeof nextChild !== 'object') {
      const el = document.createTextNode(nextChild)

      if (shouldAppendChild) {
        target.appendChild(el)
      } else if (nextChild !== previousChild) {
        target.replaceChild(el, childNode)
      }

      continue
    }

    let nextNamespace

    if (typeof nextChild === 'object') {
      nextNamespace = nextChild.attributes.xmlns != null ? nextChild.attributes.xmlns : targetNamespace
    }

    const shouldReplaceChild = !shouldAppendChild && (childNode.nodeType !== 1 || childNode.nodeName.toLowerCase() !== nextChild.tag)
    let el

    if (shouldAppendChild || shouldReplaceChild) {
      el = nextNamespace ? document.createElementNS(nextNamespace, nextChild.tag) : document.createElement(nextChild.tag)

      el = morph(el, nextChild)

      if (shouldAppendChild) {
        target.appendChild(el)
      } else if (shouldReplaceChild) {
        target.replaceChild(el, childNode)
      }

      if (nextChild.hooks.onmount) {
        nextChild.hooks.onmount(el)
      }
    } else {
      el = childNode

      morph(el, nextChild, previousChild)
    }

    if (nextChild.hooks.onupdate) {
      nextChild.hooks.onupdate(el)
    }
  }

  while (target.childNodes.length > i) {
    target.removeChild(target.childNodes[i])
  }

  return target
}

{'fraction_non_alphanumeric': 0.13509140915709433, 'fraction_numerical': 0.0012942889500080893, 'mean_word_length': 2.61943793911007, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '7602108', 'n_tokens_mistral': 1950, 'n_tokens_neox': 1903, 'n_words': 418}