<commit_before>
//render
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

window.cancelRequestAnimFrame = ( function() {
    return window.cancelAnimationFrame          ||
        window.webkitCancelRequestAnimationFrame    ||
        window.mozCancelRequestAnimationFrame       ||
        window.oCancelRequestAnimationFrame     ||
        window.msCancelRequestAnimationFrame        ||
        clearTimeout
})();

//line 

var Polyline = function(editor) {
    this.e = editor;
    this.points = [];
    this.highlighted = -1;
}

Polyline.prototype.Draw = function(ctx) {



    for (var i = this.points.length - 1; i > 0; i--) {
        var sx = this.e.timestampToX(this.points[i-1].x);
        var sy = this.e.valueToY(this.points[i-1].y);
        var ex = this.e.timestampToX(this.points[i].x);
        var ey = this.e.valueToY(this.points[i].y);

        if (this.highlighted == i)
            ctx.fillStyle = 'darkorange';

        this.e.DrawAnchoredLine(ctx, sx, sy, ex, ey);
        ctx.fillStyle = '#000';
    };

    if (this.highlighted == 0)
        ctx.fillStyle = 'darkorange';

    this.e.DrawAnchor(ctx,
        this.e.timestampToX(this.points[0].x), 
        this.e.valueToY(this.points[0].y)
    );
} 

Polyline.prototype.push = function(point) {
    this.points.push(point);
} 

Polyline.prototype.highlight = function(x, y) {
    this.highlighted = this.findPointAt(x, y);
}

Polyline.prototype.findPointAt = function(x, y) {
    for (var i = this.points.length - 1; i >= 0; i--) {
        var px = this.e.timestampToX(this.points[i].x);
        var py = this.e.valueToY(this.points[i].y);
        var delta = 5;
        if (Math.abs(px - x) < delta && Math.abs(py - y))
            return i;
    }
    return -1;
}

Polyline.prototype.movePoint = function(i, x, y) {
    this.points[i].x = x;
    this.points[i].y = y;
}


//mouse tools
var Mouse = function(element) {
    this.pressed = false;
    this.startTime = null;
    this.endTime = null;
    this.time = null;
    this.element = element;
    this.cursor = 'auto';
}

Mouse.prototype.set = function(obj2) {
    for (var attrname in obj2) { this[attrname] = obj2[attrname]; }
    if (obj2.cursor) {
        this.element.style.cursor = obj2.cursor;
    }
}


//editor
var LineEditor = function(element, data, options) {

    this.options = options;
    var canvas = document.createElement("canvas");
    canvas.width = 800;
    canvas.height = 250;
    element.appendChild(canvas)
    this.ctx = canvas.getContext("2d");
    this.width = canvas.width;
    this.height = canvas.height;
    this.data = data;
    this.mouse = new Mouse(element);
    this.line = new Polyline(this);

    this.line.push({x: 0, y : 7000});
    this.line.push({x: 96000, y: 65535})

    this.options = {
        min : 0,
        max : 60 * 48000,
        marginTop : 5,
        marginBottom : 15,
        marginLeft : 40,
        marginRight : 10,
        fontSize : 12,
        gridVSubdiv : 8
    }

    this.options.gridHeight = this.height - this.options.marginTop - this.options.marginBottom;
    this.options.gridWidth = this.width - this.options.marginLeft - this.options.marginRight;

    this.startTime = 0;
    this.endTime = 48000 * 10 * 1;

    element.onmousemove = this.onmousemove();
    element.onmousedown = this.onmousedown();
    element.onmouseup = this.onmouseup();
    if ('onwheel' in document) {
        element.onwheel = this.onmousewheel();
    } else {
        element.onmousewheel = this.onmousewheel();
    }
    element.onclick = this.onclick();
    element.ondblclick = this.ondblclick(); 
    element.oncontextmenu = this.oncontextmenu();

    this.animLastFrameTimestamp = 0;
    this.animForceUpdate = 0;
    this.frameRequest = requestAnimFrame(this.updateAnimationFunc(this));
    this.Draw();
}

LineEditor.prototype.destroy = function() {
    cancelRequestAnimFrame(this.frameRequest);
}

LineEditor.prototype.updateAnimationFunc = function(self) {
    var result = function(timestamp) {
        //var delta = timestamp - self.animLastFrameTimestamp;
        if (self.animForceUpdate) {
            self.animLastFrameTimestamp = timestamp;
            self.animForceUpdate = 0;
            self.Draw();
        }
        self.frameRequest = requestAnimFrame(self.updateAnimationFunc(self));
    }
    return result;
}

//tools

LineEditor.prototype.formatTs = function(ts) {
    var pad = "00000";
    var str = Math.floor(ts%48000)+"";
    var samples = pad.substring(0, pad.length - str.length) + str;
    return Math.floor(ts/48000) + '.'+ samples + 's';
}

LineEditor.prototype.comment = function(str) {
    var el = document.getElementById('comment');
    el.innerHTML = str;
}

//handlers
LineEditor.prototype.onmousewheel = function() {
    var self = this;
    return function(e) {
        e.preventDefault();
        self.Zoom(e);
    }
}

LineEditor.prototype.onmousemove = function() {
    var self = this;
    var handler = function(e) {
        var x = e.offsetX ? e.offsetX : e.layerX;
        var y = e.offsetY ? e.offsetY : e.layerY;
        var ts = self.xToTimestamp(x);
        self.comment( self.formatTs(ts)  + '&emsp;' 
            + self.formatTs(self.startTime) + '&emsp;' 
            + self.formatTs(self.endTime) + '&emsp;' 
         );

        self.animForceUpdate = 1;
        self.mouse.set({ x : x, y : y});
        if (!self.mouse.pointDrag)
            self.line.highlight(x, y);

        if (self.mouse.pressed) {
            
            if (Math.abs(self.mouse.originalX - x) < 3 && !self.mouse.drag)
                return; //antijitter 5px;

            if (self.line.highlighted != -1) {  //point dragging
                var px = self.xToTimestamp(x);
                var py = self.yToValue(y);
                self.line.movePoint(self.line.highlighted, px, py);
                self.mouse.set({ 
                    pointDrag : true,
                    cursor : 'move',
                });
                return;
            }

            var t = self.xToTimestamp(x);
            var delta = self.mouse.time - t;
            self.startTime =  self.mouse.startTime + delta;
            self.endTime = self.mouse.endTime + delta;
            self.mouse.set({ 
                startTime : self.startTime,
                endTime : self.endTime,
                cursor : 'move',
                drag : true
            });
        }
    }
    return handler;
}

LineEditor.prototype.onmousedown = function() {
    var self = this;
    var handler = function(e) {
        e.preventDefault();
        var x = e.offsetX ? e.offsetX : e.layerX;
        var t = self.xToTimestamp(x);
        self.mouse.set({ 
            pressed : true,
            time : t,
            originalX : x,
            startTime : self.startTime,
            endTime : self.endTime
        });
    }

    return handler;
}

LineEditor.prototype.onmouseup = function() {
    var self = this;
    var handler = function(e) {
        self.mouse.set({ 
            pressed : false,
            cursor : 'auto'
        });
        event.preventDefault();
    }
    return handler;
}

LineEditor.prototype.onclick = function() {
    var self = this;
    var handler = function(e) {

        if (self.mouse.drag || self.mouse.pointDrag) {  //last event was drag
            self.mouse.set({ drag : false, pointDrag : false });
            return;
        }

        var x = e.offsetX ? e.offsetX : e.layerX;
        var y = e.offsetY ? e.offsetY : e.layerY;
        x = self.xToTimestamp(x);
        y = self.yToValue(y);
        self.line.push({x : x, y : y});
        self.animForceUpdate = 1; 
    }
    return handler;
}

LineEditor.prototype.oncontextmenu = function() {
    var self = this;
    var handler = function(e) {
        e.preventDefault();
        console.log('rightclick');
    }
    return handler;
} 

LineEditor.prototype.ondblclick = function() {
    var self = this;<commit_msg>point adding, deleting and line division<commit_after>
//render
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

window.cancelRequestAnimFrame = ( function() {
    return window.cancelAnimationFrame          ||
        window.webkitCancelRequestAnimationFrame    ||
        window.mozCancelRequestAnimationFrame       ||
        window.oCancelRequestAnimationFrame     ||
        window.msCancelRequestAnimationFrame        ||
        clearTimeout
})();

//line 

var Polyline = function(editor) {
    this.e = editor;
    this.points = [];
    this.highlighted = -1;
}

Polyline.prototype.Draw = function(ctx) {



    for (var i = this.points.length - 1; i > 0; i--) {
        var sx = this.e.timestampToX(this.points[i-1].x);
        var sy = this.e.valueToY(this.points[i-1].y);
        var ex = this.e.timestampToX(this.points[i].x);
        var ey = this.e.valueToY(this.points[i].y);

        if (this.highlighted == i)
            ctx.fillStyle = 'red';

        this.e.DrawAnchoredLine(ctx, sx, sy, ex, ey);
        ctx.fillStyle = '#000';
    };

    if (this.highlighted == 0)
        ctx.fillStyle = 'darkorange';

    this.e.DrawAnchor(ctx,
        this.e.timestampToX(this.points[0].x), 
        this.e.valueToY(this.points[0].y)
    );
} 

Polyline.prototype.push = function(point) {
    this.points.push(point);
} 

Polyline.prototype.highlight = function(x, y) {
    this.highlighted = this.findPointAt(x, y);
}

Polyline.prototype.findPointAt = function(x, y) {
    for (var i = this.points.length - 1; i >= 0; i--) {
        var px = this.e.timestampToX(this.points[i].x);
        var py = this.e.valueToY(this.points[i].y);
        var delta = 5;
        if (Math.abs(px - x) < delta && Math.abs(py - y))
            return i;
    }
    return -1;
}

Polyline.prototype.movePoint = function(i, x, y) {
    this.points[i].y = y;
    if (i != 0)
        this.points[i].x = x;
}

Polyline.prototype.deletePoint = function(i) {
    if (i > 0)
        this.points.splice(i, 1);
}

Polyline.prototype.addPoint = function(x, y) {
    var l = this.points.length - 1;
    if (x > this.points[l].x) {
        this.points.push({x : x, y : y});
    } else {
        for (var i = this.points.length - 1; i > 0; i--)
            if (this.points[i-1].x < x && this.points[i].x > x) {
                this.points.splice(i, 0, {x : x, y : y});
                return;
            }
    }
}



//mouse tools
var Mouse = function(element) {
    this.pressed = false;
    this.startTime = null;
    this.endTime = null;
    this.time = null;
    this.element = element;
    this.cursor = 'auto';
}

Mouse.prototype.set = function(obj2) {
    for (var attrname in obj2) { this[attrname] = obj2[attrname]; }
    if (obj2.cursor) {
        this.element.style.cursor = obj2.cursor;
    }
}


//editor
var LineEditor = function(element, data, options) {

    this.options = options;
    var canvas = document.createElement("canvas");
    canvas.width = 800;
    canvas.height = 250;
    element.appendChild(canvas)
    this.ctx = canvas.getContext("2d");
    this.width = canvas.width;
    this.height = canvas.height;
    this.data = data;
    this.mouse = new Mouse(element);
    this.line = new Polyline(this);

    this.line.push({x: 0, y : 7000});
    this.line.push({x: 96000, y: 65535})

    this.options = {
        min : 0,
        max : 60 * 48000,
        marginTop : 5,
        marginBottom : 15,
        marginLeft : 40,
        marginRight : 10,
        fontSize : 12,
        gridVSubdiv : 8
    }

    this.options.gridHeight = this.height - this.options.marginTop - this.options.marginBottom;
    this.options.gridWidth = this.width - this.options.marginLeft - this.options.marginRight;

    this.startTime = 0;
    this.endTime = 48000 * 10 * 1;

    element.onmousemove = this.onmousemove();
    element.onmousedown = this.onmousedown();
    element.onmouseup = this.onmouseup();
    if ('onwheel' in document) {
        element.onwheel = this.onmousewheel();
    } else {
        element.onmousewheel = this.onmousewheel();
    }
    element.onclick = this.onclick();
    element.ondblclick = this.ondblclick(); 
    element.oncontextmenu = this.oncontextmenu();

    this.animLastFrameTimestamp = 0;
    this.animForceUpdate = 0;
    this.frameRequest = requestAnimFrame(this.updateAnimationFunc(this));
    this.Draw();
}

LineEditor.prototype.destroy = function() {
    cancelRequestAnimFrame(this.frameRequest);
}

LineEditor.prototype.updateAnimationFunc = function(self) {
    var result = function(timestamp) {
        //var delta = timestamp - self.animLastFrameTimestamp;
        if (self.animForceUpdate) {
            self.animLastFrameTimestamp = timestamp;
            self.animForceUpdate = 0;
            self.Draw();
        }
        self.frameRequest = requestAnimFrame(self.updateAnimationFunc(self));
    }
    return result;
}

//tools

LineEditor.prototype.formatTs = function(ts) {
    var pad = "00000";
    var str = Math.floor(ts%48000)+"";
    var samples = pad.substring(0, pad.length - str.length) + str;
    return Math.floor(ts/48000) + '.'+ samples + 's';
}

LineEditor.prototype.comment = function(str) {
    var el = document.getElementById('comment');
    el.innerHTML = str;
}

//handlers
LineEditor.prototype.onmousewheel = function() {
    var self = this;
    return function(e) {
        e.preventDefault();
        self.Zoom(e);
    }
}

LineEditor.prototype.onmousemove = function() {
    var self = this;
    var handler = function(e) {
        var x = e.offsetX ? e.offsetX : e.layerX;
        var y = e.offsetY ? e.offsetY : e.layerY;
        var ts = self.xToTimestamp(x);
        self.comment( self.formatTs(ts)  + '&emsp;' 
            + self.formatTs(self.startTime) + '&emsp;' 
            + self.formatTs(self.endTime) + '&emsp;' 
         );

        self.animForceUpdate = 1;
        self.mouse.set({ x : x, y : y});
        if (!self.mouse.pointDrag)
            self.line.highlight(x, y);

        if (self.mouse.pressed) {
            
            if (Math.abs(self.mouse.originalX - x) < 5 && !self.mouse.drag)
                return; //antijitter 5px;

            if (self.line.highlighted != -1) {  //point dragging
                var px = self.xToTimestamp(x);
                var py = self.yToValue(y);
                self.line.movePoint(self.line.highlighted, px, py);
                self.mouse.set({ 
                    pointDrag : true,
                    cursor : 'move',
                });
                return;
            }

            var t = self.xToTimestamp(x);
            var delta = self.mouse.time - t;
            self.startTime =  self.mouse.startTime + delta;
            self.endTime = self.mouse.endTime + delta;
            self.mouse.set({ 
                startTime : self.startTime,
                endTime : self.endTime,
                cursor : 'move',
                drag : true
            });
        }
    }
    return handler;
}

LineEditor.prototype.onmousedown = function() {
    var self = this;
    var handler = function(e) {
        e.preventDefault();
        var x = e.offsetX ? e.offsetX : e.layerX;
        var t = self.xToTimestamp(x);
        self.mouse.set({ 
            pressed : true,
            time : t,
            originalX : x,
            startTime : self.startTime,
            endTime : self.endTime
        });
    }

    return handler;
}

LineEditor.prototype.onmouseup = function() {
    var self = this;
    var handler = function(e) {
        self.mouse.set({ 
            pressed : false,
            cursor : 'auto'
        });
        event.preventDefault();
    }
    return handler;
}

LineEditor.prototype.onclick = function() {
    var self = this;
    var handler = function(e) {

        if (self.mouse.drag || self.mouse.pointDrag) {  //last event was drag
            self.mouse.set({ drag : false, pointDrag : false });
            return;
        }

        var x = e.offsetX ? e.offsetX : e.layerX;
        var y = e.offsetY ? e.offsetY : e.layerY;
        x = self.xToTimestamp(x);
        y = self.yToValue(y);

        self.line.addPoint(x, y);
        self.animForceUpdate = 1; 
    }
    return handler;
}

LineEditor.prototype.oncontextmenu = function() {
    var self = this;
    var handler = function(e) {
        e.preventDefault();
        if (self.line.highlighted) {
            self.line.deletePoint(self.line.highlighted);
            self.animForceUpdate = 1;
        }
    }
    return handler;
} 

LineEditor.prototype.ondblclick = function() {
    var self = this;
{'fraction_non_alphanumeric': 0.13379253984005604, 'fraction_numerical': 0.012083357655711868, 'mean_word_length': 2.010896309314587, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 11, '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': '6358467', 'n_tokens_mistral': 5641, 'n_tokens_neox': 5348, 'n_words': 1067}