var gtp = require('./gtp')
var crypto = require('crypto')
var shell = require('shell')

var id = 0

exports.getId = function() {
    return ++id
}

exports.md5 = function(str) {
    return crypto.createHash('md5').update(str).digest('hex')
}

exports.roundEven = function(float) {
    var value = Math.round(float)
    return value % 2 == 0 ? value : value - 1
}

exports.htmlify = function(input, renderUrl, renderEmail, renderCoord, useParagraphs) {
    input = input.replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&rt;')

    if (renderUrl)
        input = input.replace(/\b((http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]+(\/\S*)?)/g, function(url) {
            return '<a href="' + url + '">' + url + '</a>'
        })

    if (renderEmail)
        input = input.replace(/\b[^\s@]+@[a-zA-Z0-9\-\.]+\.[a-zA-Z]+\b/g, function(email) {
            return '<a href="mailto:' + email + '">' + email + '</a>'
        })

    if (renderCoord)
        input = input.replace(/\b[a-hj-zA-HJ-Z][1-9][0-9]?\b/g, function(coord) {
            return '<span class="coord">' + coord + '</span>'
        })

    if (useParagraphs) {
        input = '<p>' + input.trim().split('\n').map(function(s) {
            if (s.trim() == '') return ''

            if (s.trim().split('').every(function(x) {
                return x == '-' || x == '='
            })) return '</p><hr><p>'

            return s
        }).join('<br>')
        .replace(/<br><br>/g, '</p><p>')
        .replace(/(<br>)*<p>(<br>)*/g, '<p>')
        .replace(/(<br>)*<\/p>(<br>)*/g, '</p>') + '</p>'
    }

    return input
}

exports.wireLinks = function(container) {
    container.getElements('a').addEvent('click', function() {
        shell.openExternal(this.href)
        return false
    })
    container.getElements('.coord').addEvent('mouseenter', function() {
        var v = gtp.point2vertex(this.get('text'), getBoard().size)
        showIndicator(new Tuple(v[0], v[1]))
    }).addEvent('mouseleave', function() {
        hideIndicator()
    })
}

@@ -353,24 +353,838 @@
 alue - 1%0A%7D%0A%0A
+exports.equals = function(a, b) %7B%0A    if (a === b) return true%0A    if (a == null %7C%7C b == null) return a == b%0A%0A    var t = Object.prototype.toString.call(a)%0A    if (t !== Object.prototype.toString.call(b)) return false%0A%0A    var aa = t === %22%5Bobject Array%5D%22%0A    var ao = t === %22%5Bobject Object%5D%22%0A%0A    if (aa) %7B%0A        if (a.length !== b.length) return false%0A        for (var i = 0; i %3C a.length; i++)%0A            if (!exports.equals(a%5Bi%5D, b%5Bi%5D)) return false%0A        return true%0A    %7D else if (ao) %7B%0A        var kk = Object.keys(a)%0A        if (kk.length !== Object.keys(b).length) return false%0A        for (var i = 0; i %3C kk.length; i++) %7B%0A            k = kk%5Bi%5D%0A            if (!(k in b)) return false%0A            if (!exports.equals(a%5Bk%5D, b%5Bk%5D)) return false%0A        %7D%0A        return true%0A    %7D%0A%0A    return false%0A%7D%0A%0A
 exports.html

Add helper.equals