<commit_before>{ /* global localStorage rilti */
  const {throttle, dom, domfn: {attr, emit, mutate}, on, model, component} = rilti
  const {span, aside, button, header, input} = dom

  const todos = model(localStorage.getItem('todos'))

  const todoCount = () => {
    const all = todos.size
    let done = 0
    todos.each(val => val && done++)
    return {all, done, undone: all - done || 0}
  }

  const updateStorage = () => {
    localStorage.setItem('todos', todos.toJSONArray())
    todos.emit.update(todoCount())
  }
  todos.on.set(updateStorage)
  todos.on.delete(updateStorage)

  const tickBox = component('tick-box', {
    create (el) {
      on.click(el, e => {
        el.ticked = !el.ticked
      })
    },
    attr: {
      ticked: {
        prop: { bool: true },
        update (el) { emit(el, 'ticked', el.ticked) }
      }
    }
  })

  component('todo-list', {
    create (el) {
      const tdMaker = header({render: el})

      const todoSubmit = (txt = tdInput.value.trim(), state = false) => {
        if (!(txt && txt.length)) return
        dom['todo-item']({render: el, attr: {state}}, txt)
        todos.emit.newTodo()
      }

      todos.each((val, key) => todoSubmit(key, val))

      const tdInput = input({
        render: tdMaker,
        attr: {type: 'text'},
        on_keydown: ({keyCode}) => keyCode === 13 && todoSubmit()
      })

      todos.on.newTodo(() => {
        tdInput.value = ''
      })

      button({
        render: tdMaker,
        class: 'green-btn',
        on_click: e => todoSubmit()
      },
        'add todo'
      )

      const setMode = mode => () => {
        attr(el, {mode})
        localStorage.setItem('todo-mode', mode)
      }

      const [allCount, doneCount, undoneCount] = ['all', 'done', 'undone']
      .map(mode => span({ on_click: setMode(mode) }))

      const populateCounts = ({all, done, undone} = todoCount()) => {
        allCount.textContent = 'all: ' + all
        doneCount.textContent = 'done: ' + done
        undoneCount.textContent = 'undone: ' + undone
      }

      setMode(localStorage.getItem('todo-mode') || 'all')()
      populateCounts()
      todos.on.update(populateCounts)

      aside({renderAfter: tdMaker}, allCount, doneCount, undoneCount)
    }
  })

  component('todo-item', {
    props: {
      accessors: {
        txt (el, val) {
          if (val === undefined) return el.txt_el ? el.txt_el.textContent.trim() : ''
          if (val !== el.txt) {
            if (el.txt_el) {
              el.txt_el.textContent = val = ('' + val).trim()
              el.update()
            } else {
              on.mount(el, e => { el.txt = val })
            }
          }
        }
      }
    },
    methods: {
      del (el) {
        el.remove()
        todos.del([el.txt, el.oldtxt], true)
        updateStorage()
      },
      update (el) {
        const {txt, state, oldtxt} = el
        if (txt && txt !== 'add todo text') {
          if (txt !== oldtxt) {
            todos.del(oldtxt)
            el.oldtxt = txt
          }
          todos(txt, state)
        }
        el.tick_el.ticked = state
      }
    },
    create (el) {
      el.del_el = span({class: 'delete-todo', on_click: el.del}, '✕')

      el.txt_el = span({
        class: 'txt',
        attr: {contenteditable: true},
        on_input: throttle(el.update, 20)
      })

      el.tick_el = tickBox({
        on_ticked (e, {ticked}) { el.state = ticked }
      })
    },
    mount (el) {
      el.oldtxt = el.textContent || 'add todo text'
      if (!el.txt) {
        el.txt_el.textContent = el.oldtxt
      }
      mutate(el, {children: [el.del_el, el.txt_el, el.tick_el]})
    },
    unmount (el) { el.del() },
    attr: {
      state: {<commit_msg>-throttle<commit_after>{ /* global localStorage rilti */
  const {dom, domfn: {attr, emit, mutate}, on, model, component} = rilti
  const {span, aside, button, header, input} = dom

  const todos = model(localStorage.getItem('todos'))

  const todoCount = () => {
    const all = todos.size
    let done = 0
    todos.each(val => val && done++)
    return {all, done, undone: all - done || 0}
  }

  const updateStorage = () => {
    localStorage.setItem('todos', todos.toJSONArray())
    todos.emit.update(todoCount())
  }
  todos.on.set(updateStorage)
  todos.on.delete(updateStorage)

  const tickBox = component('tick-box', {
    create (el) {
      on.click(el, e => {
        el.ticked = !el.ticked
      })
    },
    attr: {
      ticked: {
        prop: { bool: true },
        update (el) { emit(el, 'ticked', el.ticked) }
      }
    }
  })

  component('todo-list', {
    create (el) {
      const tdMaker = header({render: el})

      const todoSubmit = (txt = tdInput.value.trim(), state = false) => {
        if (!(txt && txt.length)) return
        dom['todo-item']({render: el, attr: {state}}, txt)
        todos.emit.newTodo()
      }

      todos.each((val, key) => todoSubmit(key, val))

      const tdInput = input({
        render: tdMaker,
        attr: {type: 'text'},
        on_keydown: ({keyCode}) => keyCode === 13 && todoSubmit()
      })

      todos.on.newTodo(() => {
        tdInput.value = ''
      })

      button({
        render: tdMaker,
        class: 'green-btn',
        on_click: e => todoSubmit()
      },
        'add todo'
      )

      const setMode = mode => () => {
        attr(el, {mode})
        localStorage.setItem('todo-mode', mode)
      }

      const [allCount, doneCount, undoneCount] = ['all', 'done', 'undone']
      .map(mode => span({ on_click: setMode(mode) }))

      const populateCounts = ({all, done, undone} = todoCount()) => {
        allCount.textContent = 'all: ' + all
        doneCount.textContent = 'done: ' + done
        undoneCount.textContent = 'undone: ' + undone
      }

      setMode(localStorage.getItem('todo-mode') || 'all')()
      populateCounts()
      todos.on.update(populateCounts)

      aside({renderAfter: tdMaker}, allCount, doneCount, undoneCount)
    }
  })

  component('todo-item', {
    props: {
      accessors: {
        txt (el, val) {
          if (val === undefined) return el.txt_el ? el.txt_el.textContent.trim() : ''
          if (val !== el.txt) {
            if (el.txt_el) {
              el.txt_el.textContent = val = ('' + val).trim()
              el.update()
            } else {
              on.mount(el, e => { el.txt = val })
            }
          }
        }
      }
    },
    methods: {
      del (el) {
        el.remove()
        todos.del([el.txt, el.oldtxt], true)
        updateStorage()
      },
      update (el) {
        const {txt, state, oldtxt} = el
        if (txt && txt !== 'add todo text') {
          if (txt !== oldtxt) {
            todos.del(oldtxt)
            el.oldtxt = txt
          }
          todos(txt, state)
        }
        el.tick_el.ticked = state
      }
    },
    create (el) {
      el.del_el = span({class: 'delete-todo', on_click: el.del}, '✕')

      el.txt_el = span({
        class: 'txt',
        attr: {contenteditable: true},
        on_input: el.update
      })

      el.tick_el = tickBox({
        on_ticked (e, {ticked}) { el.state = ticked }
      })
    },
    mount (el) {
      el.oldtxt = el.textContent || 'add todo text'
      if (!el.txt) {
        el.txt_el.textContent = el.oldtxt
      }
      mutate(el, {children: [el.del_el, el.txt_el, el.tick_el]})
    },
    unmount (el) { el.del() },
    attr: {
      state: {
{'fraction_non_alphanumeric': 0.16581495427649273, 'fraction_numerical': 0.0013448090371167294, 'mean_word_length': 1.8581860107609531, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 31, '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': '6778963', 'n_tokens_mistral': 2553, 'n_tokens_neox': 2551, 'n_words': 530}