)]}'
{"app/js/directives/timeline-dstat.js":[{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    // selection and hover variables"},{"line_number":116,"context_line":"    var mousePoint \u003d null;"},{"line_number":117,"context_line":"    var selection \u003d null;"},{"line_number":118,"context_line":"    var hover \u003d null;"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    // canvases and layers"},{"line_number":121,"context_line":"    var regions \u003d [];"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_a84a11a9","line":118,"range":{"start_line":117,"start_character":4,"end_line":118,"end_character":21},"updated":"2017-03-26 22:42:19.000000000","message":"No need for selection and hover if rect-related code is removed","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":123,"context_line":"    var main \u003d timelineController.createCanvas(null, height, false);"},{"line_number":124,"context_line":"    el.append(main.canvas);"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    /**"},{"line_number":127,"context_line":"     * Initializes rects from a list of parsed subunit log entries, setting"},{"line_number":128,"context_line":"     * initial sizes and positions based on the current view extents."},{"line_number":129,"context_line":"     * @param {Array} data A list of parsed subunit log entries"},{"line_number":130,"context_line":"     */"},{"line_number":131,"context_line":"    function createRects(data) {"},{"line_number":132,"context_line":"      var rects \u003d [];"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"      var h \u003d 0.8 * y(1);"},{"line_number":135,"context_line":"      for (var i \u003d 0; i \u003c data.length; i++) {"},{"line_number":136,"context_line":"        var entry \u003d data[i];"},{"line_number":137,"context_line":"        var start \u003d absolute(+entry.startDate);"},{"line_number":138,"context_line":"        rects.push({"},{"line_number":139,"context_line":"          x: start,"},{"line_number":140,"context_line":"          y: y(entry.worker),"},{"line_number":141,"context_line":"          width: absolute(+entry.endDate) - start,"},{"line_number":142,"context_line":"          height: h,"},{"line_number":143,"context_line":"          entry: entry"},{"line_number":144,"context_line":"        });"},{"line_number":145,"context_line":"      }"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"      return rects;"},{"line_number":148,"context_line":"    }"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    /**"},{"line_number":151,"context_line":"     * Generate the list of active regions or \"chunks\". These regions span a"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_e8501961","line":148,"range":{"start_line":126,"start_character":4,"end_line":148,"end_character":5},"updated":"2017-03-26 22:42:19.000000000","message":"We shouldn\u0027t need to worry about createRects at all, it looks like a lot of rect-related functionality got pulled in with some of the event handlers, but we can slice all that out.","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":195,"context_line":"        var min \u003d absolute.invert(offset);"},{"line_number":196,"context_line":"        var max \u003d absolute.invert(offset + w);"},{"line_number":197,"context_line":"        var data \u003d timelineController.dstatInBounds(min, max);"},{"line_number":198,"context_line":"        var rects \u003d createRects(data);"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"        regions.push({"},{"line_number":201,"context_line":"          x: offset, width: w, min: min, max: max,"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_485ca57d","line":198,"range":{"start_line":198,"start_character":8,"end_line":198,"end_character":38},"updated":"2017-03-26 22:42:19.000000000","message":"This call / var isn\u0027t needed","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":222,"context_line":"      });"},{"line_number":223,"context_line":"    }"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    /**"},{"line_number":226,"context_line":"     * Find the region managing the given canvas-local X coordinate. If the x"},{"line_number":227,"context_line":"     * value is outside of the actual canvas area where regions are rendered,"},{"line_number":228,"context_line":"     * this may return null. Rarely, null may also be returned if, while"},{"line_number":229,"context_line":"     * animating, the view moves to a position outside of capped view bounds"},{"line_number":230,"context_line":"     * (i.e. when the view extents are small); if this happens, it can be"},{"line_number":231,"context_line":"     * ignored and createRegions() will generate the necessary area when the"},{"line_number":232,"context_line":"     * animation finishes."},{"line_number":233,"context_line":"     * @param  {number} screenX the canvas-local x coordinate"},{"line_number":234,"context_line":"     * @return {object|null}    the matching region or null"},{"line_number":235,"context_line":"     */"},{"line_number":236,"context_line":"    function getRegionAt(screenX) {"},{"line_number":237,"context_line":"      if (screenX \u003c margin.left || screenX \u003e main.canvas.width - margin.right) {"},{"line_number":238,"context_line":"        return null;"},{"line_number":239,"context_line":"      }"},{"line_number":240,"context_line":"      var absX \u003d absolute(currentViewExtents[0]) + (screenX - margin.left);"},{"line_number":241,"context_line":"      return regions.find(function(r) {"},{"line_number":242,"context_line":"        return absX \u003e\u003d r.x \u0026\u0026 absX \u003c\u003d (r.x + r.width);"},{"line_number":243,"context_line":"      });"},{"line_number":244,"context_line":"    }"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    /**"},{"line_number":247,"context_line":"     * Get the rect at the given canvas-local coordinates, if any exists. This"},{"line_number":248,"context_line":"     * function has the same limitations as getRegionAt() and will return null"},{"line_number":249,"context_line":"     * when the coordinates are out of bounds or rarely when animating, but also"},{"line_number":250,"context_line":"     * returns null when no rect exists at the given coords."},{"line_number":251,"context_line":"     *"},{"line_number":252,"context_line":"     * Note that this will only search within the region containing the"},{"line_number":253,"context_line":"     * coordinates so it should be fairly performant, though it will only return"},{"line_number":254,"context_line":"     * one of possibly many matching rects."},{"line_number":255,"context_line":"     * @param  {number} screenX the canvas-local x coordinate"},{"line_number":256,"context_line":"     * @param  {number} screenY the canvas-local y coordinate"},{"line_number":257,"context_line":"     * @return {object|null}    the matching rect in the region or null"},{"line_number":258,"context_line":"     */"},{"line_number":259,"context_line":"    function getRectAt(screenX, screenY) {"},{"line_number":260,"context_line":"      if (screenY \u003c margin.top || screenY \u003e main.canvas.height - margin.bottom) {"},{"line_number":261,"context_line":"        return null;"},{"line_number":262,"context_line":"      }"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"      var region \u003d getRegionAt(screenX);"},{"line_number":265,"context_line":"      if (!region) {"},{"line_number":266,"context_line":"        return null;"},{"line_number":267,"context_line":"      }"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"      // find the absolute coords in rect-space"},{"line_number":270,"context_line":"      var absX \u003d absolute(currentViewExtents[0]) + (screenX - margin.left);"},{"line_number":271,"context_line":"      var absY \u003d screenY - margin.top;"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"      for (var i \u003d 0; i \u003c region.rects.length; i++) {"},{"line_number":274,"context_line":"        var rect \u003d region.rects[i];"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"        if (absX \u003e\u003d rect.x \u0026\u0026 absX \u003c\u003d (rect.x + rect.width) \u0026\u0026"},{"line_number":277,"context_line":"            absY \u003e\u003d rect.y \u0026\u0026 absY \u003c\u003d (rect.y + rect.height)) {"},{"line_number":278,"context_line":"          // make sure the point is contained inside the rect"},{"line_number":279,"context_line":"          return rect;"},{"line_number":280,"context_line":"        }"},{"line_number":281,"context_line":"      }"},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"      return null;"},{"line_number":284,"context_line":"    }"},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"    /**"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_68652945","line":283,"range":{"start_line":225,"start_character":4,"end_line":283,"end_character":18},"updated":"2017-03-26 22:42:19.000000000","message":"These functions aren\u0027t needed if we clean up the mousemove handler","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":321,"context_line":"      }"},{"line_number":322,"context_line":"    }"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"    /**"},{"line_number":325,"context_line":"     * Draw a single rect within a region. This may be called independently of"},{"line_number":326,"context_line":"     * drawRegion() to update only a single rect, if needed."},{"line_number":327,"context_line":"     * @param {object}  region  the region to draw within"},{"line_number":328,"context_line":"     * @param {object}  rect    the rect to draw"},{"line_number":329,"context_line":"     * @param {boolean} [clear] if true, clear the rect first (default: false)"},{"line_number":330,"context_line":"     */"},{"line_number":331,"context_line":"    function drawSingleRect(region, rect, clear) {"},{"line_number":332,"context_line":"      var ctx \u003d region.c.ctx;"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"      if (rect.entry \u003d\u003d\u003d selection) {"},{"line_number":335,"context_line":"        ctx.fillStyle \u003d statusColorMap.selected;"},{"line_number":336,"context_line":"      } else if (rect.entry \u003d\u003d\u003d hover) {"},{"line_number":337,"context_line":"        ctx.fillStyle \u003d statusColorMap.hover;"},{"line_number":338,"context_line":"      } else {"},{"line_number":339,"context_line":"        ctx.fillStyle \u003d statusColorMap[rect.entry.status];"},{"line_number":340,"context_line":"      }"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"      if (clear) {"},{"line_number":343,"context_line":"        ctx.clearRect(rect.x - region.x, rect.y, rect.width, rect.height);"},{"line_number":344,"context_line":"      }"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"      var filter \u003d timelineController.filterFunction;"},{"line_number":347,"context_line":"      if (!filter || filter(rect.entry)) {"},{"line_number":348,"context_line":"        ctx.globalAlpha \u003d 1.0;"},{"line_number":349,"context_line":"      } else {"},{"line_number":350,"context_line":"        ctx.globalAlpha \u003d 0.15;"},{"line_number":351,"context_line":"      }"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"      ctx.fillRect(rect.x - region.x, rect.y, rect.width, rect.height);"},{"line_number":354,"context_line":"      ctx.strokeRect(rect.x - region.x, rect.y, rect.width, rect.height);"},{"line_number":355,"context_line":"    }"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    /**"},{"line_number":358,"context_line":"     * Redraw all matching rects among all regions that contain this entry."},{"line_number":359,"context_line":"     * @param  {object} entry the entry to redraw"},{"line_number":360,"context_line":"     */"},{"line_number":361,"context_line":"    function drawAllForEntry(entry) {"},{"line_number":362,"context_line":"      getRegionsForEntry(entry).forEach(function(region) {"},{"line_number":363,"context_line":"        if (!region.c) {"},{"line_number":364,"context_line":"          return;"},{"line_number":365,"context_line":"        }"},{"line_number":366,"context_line":""},{"line_number":367,"context_line":"        var r \u003d getRectForEntry(region, entry);"},{"line_number":368,"context_line":"        if (r) {"},{"line_number":369,"context_line":"          drawSingleRect(region, r, true);"},{"line_number":370,"context_line":"        }"},{"line_number":371,"context_line":"      });"},{"line_number":372,"context_line":"    }"},{"line_number":373,"context_line":""},{"line_number":374,"context_line":"    /**"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_8862ad3d","line":371,"range":{"start_line":324,"start_character":4,"end_line":371,"end_character":9},"updated":"2017-03-26 22:42:19.000000000","message":"This can be removed along with the rect drawing code in the mousemove handler","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":475,"context_line":"        ctx.font \u003d \u0027bold 12px sans-serif\u0027;"},{"line_number":476,"context_line":"        ctx.fillText(cursorTimeFormat(date), mousePoint.x, y + 16 * i++);"},{"line_number":477,"context_line":"        ctx.font \u003d \u00279px sans-serif\u0027;"},{"line_number":478,"context_line":"        ctx.textAlign \u003d \u0027left\u0027;"},{"line_number":479,"context_line":"        ctx.fillText(\u0027cpu(usr):\u0027, x - 140, y + 16 * i);"},{"line_number":480,"context_line":"        ctx.textAlign \u003d \u0027right\u0027;"},{"line_number":481,"context_line":"        ctx.fillText(dstat.total_cpu_usage_usr, x, y + 16 * i++);"},{"line_number":482,"context_line":"        ctx.textAlign \u003d \u0027left\u0027;"},{"line_number":483,"context_line":"        ctx.fillText(\u0027cpu(wai):\u0027, x - 140, y + 16 * i);"},{"line_number":484,"context_line":"        ctx.textAlign \u003d \u0027right\u0027;"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_c880b58e","line":481,"range":{"start_line":478,"start_character":8,"end_line":481,"end_character":65},"updated":"2017-03-26 22:42:19.000000000","message":"It might be a good idea to factor out of the drawing logic into a new function or a loop so we don\u0027t have as much code duplication.\n\nIt should be possible to use the dstat lane definitions to get the ordering, labels, and values we need. It would be nice if we didn\u0027t need to hard-code all the text and vars a second time here.","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"af502649fcc907e6063349db2cd0aa2157eb7288","unresolved":false,"context_lines":[{"line_number":478,"context_line":"        ctx.textAlign \u003d \u0027left\u0027;"},{"line_number":479,"context_line":"        ctx.fillText(\u0027cpu(usr):\u0027, x - 140, y + 16 * i);"},{"line_number":480,"context_line":"        ctx.textAlign \u003d \u0027right\u0027;"},{"line_number":481,"context_line":"        ctx.fillText(dstat.total_cpu_usage_usr, x, y + 16 * i++);"},{"line_number":482,"context_line":"        ctx.textAlign \u003d \u0027left\u0027;"},{"line_number":483,"context_line":"        ctx.fillText(\u0027cpu(wai):\u0027, x - 140, y + 16 * i);"},{"line_number":484,"context_line":"        ctx.textAlign \u003d \u0027right\u0027;"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_d9807e8e","line":481,"updated":"2017-03-27 09:16:47.000000000","message":"heh, yeah, this is really ugly :-p I\u0027ll fix this later.","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":629,"context_line":""},{"line_number":630,"context_line":"      ret.inBounds \u003d ret.x \u003e margin.left \u0026\u0026"},{"line_number":631,"context_line":"          ret.x \u003c (margin.left + timelineController.width) \u0026\u0026"},{"line_number":632,"context_line":"          ret.y \u003e margin.top \u0026\u0026 ret.y \u003c (margin.top + height);"},{"line_number":633,"context_line":""},{"line_number":634,"context_line":"      return ret;"},{"line_number":635,"context_line":"    }"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_e87139e0","line":632,"range":{"start_line":632,"start_character":10,"end_line":632,"end_character":62},"updated":"2017-03-26 22:42:19.000000000","message":"The dstat canvas is aligned a bit differently than the main viewport. It doesn\u0027t make use of the top/bottom margins, so we should rewrite the y comparison a bit:\n\n    ret.y \u003e 0 \u0026\u0026 ret.y \u003c height;\n\nThis should make hovering work on the top lane.","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":637,"context_line":"    main.canvas.addEventListener(\u0027mousedown\u0027, function(evt) {"},{"line_number":638,"context_line":"      evt.preventDefault();"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"      mousePoint \u003d getMousePoint(evt);"},{"line_number":641,"context_line":"      var rect \u003d getRectAt(mousePoint.x, mousePoint.y);"},{"line_number":642,"context_line":"      if (rect) {"},{"line_number":643,"context_line":"        timelineController.selectItem(rect.entry);"},{"line_number":644,"context_line":"        scope.$apply();"},{"line_number":645,"context_line":"      }"},{"line_number":646,"context_line":"    });"},{"line_number":647,"context_line":""},{"line_number":648,"context_line":"    main.canvas.addEventListener(\u0027mousemove\u0027, function(evt) {"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_68f3e974","line":645,"range":{"start_line":640,"start_character":6,"end_line":645,"end_character":7},"updated":"2017-03-26 22:42:19.000000000","message":"We only need a call to evt.preventDefault() here","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":647,"context_line":""},{"line_number":648,"context_line":"    main.canvas.addEventListener(\u0027mousemove\u0027, function(evt) {"},{"line_number":649,"context_line":"      mousePoint \u003d getMousePoint(evt);"},{"line_number":650,"context_line":"      var rect \u003d getRectAt(mousePoint.x, mousePoint.y);"},{"line_number":651,"context_line":"      var oldHover \u003d hover;"},{"line_number":652,"context_line":"      if (rect \u0026\u0026 rect.entry !\u003d\u003d hover) {"},{"line_number":653,"context_line":"        main.canvas.style.cursor \u003d \u0027pointer\u0027;"},{"line_number":654,"context_line":"        hover \u003d rect.entry;"},{"line_number":655,"context_line":""},{"line_number":656,"context_line":"        drawAllForEntry(rect.entry);"},{"line_number":657,"context_line":"        if (oldHover) {"},{"line_number":658,"context_line":"          drawAllForEntry(oldHover);"},{"line_number":659,"context_line":"        }"},{"line_number":660,"context_line":"      } else if (!rect \u0026\u0026 hover) {"},{"line_number":661,"context_line":"        main.canvas.style.cursor \u003d \u0027default\u0027;"},{"line_number":662,"context_line":"        hover \u003d null;"},{"line_number":663,"context_line":"        drawAllForEntry(oldHover);"},{"line_number":664,"context_line":"      }"},{"line_number":665,"context_line":""},{"line_number":666,"context_line":"      timelineController.animate();"},{"line_number":667,"context_line":"    });"}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_086d7d31","line":664,"range":{"start_line":650,"start_character":6,"end_line":664,"end_character":7},"updated":"2017-03-26 22:42:19.000000000","message":"We shouldn\u0027t need any rect-related code here","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"},{"author":{"_account_id":17001,"name":"Tim Buckley","email":"timothy.jas.buckley@hpe.com","username":"timothy.jas.buckley"},"change_message_id":"dacb0b125c6bfb024414d8f79d0fc1f5618b6ea0","unresolved":false,"context_lines":[{"line_number":668,"context_line":""},{"line_number":669,"context_line":"    main.canvas.addEventListener(\u0027mouseout\u0027, function(evt) {"},{"line_number":670,"context_line":"      mousePoint \u003d null;"},{"line_number":671,"context_line":"      main.canvas.style.cursor \u003d \u0027default\u0027;"},{"line_number":672,"context_line":"      timelineController.animate();"},{"line_number":673,"context_line":"    });"},{"line_number":674,"context_line":""}],"source_content_type":"text/javascript","patch_set":3,"id":"ffe62b97_c8fd553b","line":671,"range":{"start_line":671,"start_character":6,"end_line":671,"end_character":43},"updated":"2017-03-26 22:42:19.000000000","message":"Minor, but this line won\u0027t be necessary with changes in mousemove above","commit_id":"b37e7ae222c9fe75927b5ad6be7ed0497e7df530"}]}
