code: function parseLines (src) {
    const lines = []
    for (i = 0; i < src.length; ++i) {
      if (src[i] === '\n' && src[i - 1] === '\r') i += 1
      if (!src[i]) break
      const keyStart = endOfIndent(src, i)
      if (atLineEnd(src, keyStart)) {
        lines.push('')
        i = keyStart
        continue
      }
      if (atComment(src, keyStart)) {
        const commentEnd = endOfComment(src, keyStart)
        lines.push(src.slice(keyStart, commentEnd))
        i = commentEnd
        continue
      }
      const keyEnd = endOfKey(src, keyStart)
      const key = unescape(src.slice(keyStart, keyEnd))
      const valueStart = endOfSeparator(src, keyEnd)
      if (atLineEnd(src, valueStart)) {
        lines.push([key, ''])
        i = valueStart
        continue
      }
      const valueEnd = endOfValue(src, valueStart)
      const value = unescape(src.slice(valueStart, valueEnd))
      lines.push([key, value])
      i = valueEnd
    }
    return lines
  }
docs: Splits the input string into an array of logical lines
  
  Key-value pairs are [key, value] arrays with string values. Escape sequences
  in keys and values are parsed. Empty lines are included as empty strings, and
  comments as strings that start with '#' or '! characters. Leading whitespace
  is not included.
  
  @see https://docs.oracle.com/javase/9/docs/api/java/util/Properties.html#load(java.io.Reader)
  
  @param {string} src
  @returns Array<string | string[]]>