     onScrollXY: (x,y)->
 
     setScrollXY: (x,y)->
-        x = Math.max(x,0)
-        x = Math.min(x,@maxScrollHorizontal)
-        y = Math.max(y,0)
-        y = Math.min(y,@maxScrollVertical)
+        x = bound(x, 0, @maxScrollHorizontal)
+        y = bound(y, 0, @maxScrollVertical)
         @scrollLeft = x
         @scrollTop = y
         @horizontalScrollbar.scrollLeft = x

document.addEventListener "DOMContentLoaded", =>
    document.removeEventListener "DOMContentLoaded", arguments.callee


class Promise


    visible: (x,y)->
        # returns the square
        #   [ i_a -> i_b ]  x  [ j_a, j_b ]
        i = bound (y / @rowHeight | 0), 0, (@nbRows - @nbRowsVisible)
        j = bound binary_search(@columnOffset, x), 0, (@nbCols - @nbColsVisible)
        [i, j]

    setup: ->
