text:
/* Note: this is at the same time valid JavaScript and C++. */

WT_DECLARE_WT_MEMBER
(1, JavaScriptConstructor, "WCartesianChart",
 // target: the WPaintedWidget JavaScript obj, with:
 //   repaint
 //   canvas
 // config: the initial configuration (can be overridden with updateConfig)
 //     isHorizontal (if orientation() == Horizontal)
 //	xTransform
 //	yTransform
 //	area (WRectF describing render area)
 //	modelArea (WRectF describing model area)
 //	maxZoom
 //	rubberBand
 //	zoom (bool)
 //	pan (bool)
 //	crosshair (bool)
 //	followCurve (int, -1 for disabled)
 //	series {modelColumn: series ref,...}
 //
 function(APP, widget, target, config) {
   var ANIMATION_INTERVAL = 17;
   var rqAnimFrame = (function(){
      return window.requestAnimationFrame       ||
	     window.webkitRequestAnimationFrame ||
	     window.mozRequestAnimationFrame    ||
             function(callback) {
		window.setTimeout(callback, ANIMATION_INTERVAL);
	     };
   })();

   if (window.MSPointerEvent || window.PointerEvent) {
      widget.style.touchAction = 'none';
      target.canvas.style.msTouchAction = 'none';
      target.canvas.style.touchAction = 'none';
   }

   var MOVE_TO = 0, LINE_TO = 1, CUBIC_C1 = 2, CUBIC_C2 = 3, CUBIC_END = 4,
       QUAD_C = 5, QUAD_END = 6, ARC_C = 7, ARC_R = 8, ARC_ANGLE_SWEEP = 9;
   var NO_LIMIT = 1, DAMPEN = 2; // bit flags
   var X_ONLY = 1, Y_ONLY = 2; // bit flags
   var X = 0, Y = 1;
   var LOOK_MODE = 0, CROSSHAIR_MODE = 1;
   var WHEEL_ZOOM_X = 0, WHEEL_ZOOM_Y = 1, WHEEL_ZOOM_XY = 2,
       WHEEL_ZOOM_MATCHING = 3, WHEEL_PAN_X = 4, WHEEL_PAN_Y = 5,
       WHEEL_PAN_MATCHING = 6;

   var touchHandlers = {};

   function showCrosshair() {
      return config.crosshair || config.followCurve !== -1;
   }

   function isTouchEvent(event) {
      return event.pointerType === 2 || event.pointerType === 3 ||
	     event.pointerType === 'pen' || event.pointerType === 'touch';
   }

   var pointerActive = false;

   if (window.MSPointerEvent || window.PointerEvent) {
      (function(){
	 pointers = []

	 function updatePointerActive() {
	    if (pointers.length > 0 && !pointerActive) {
	       pointerActive = true;
	    } else if (pointers.length <= 0 && pointerActive) {
	       pointerActive = false;
	    }
	 }

	 function pointerDown(event) {
	    if (!isTouchEvent(event)) return;
	    event.preventDefault();
	    pointers.push(event);

	    updatePointerActive();
	    touchHandlers.start(widget, {touches:pointers.slice(0)});
	 }

	 function pointerUp(event) {
	    if (!pointerActive) return;
	    if (!isTouchEvent(event)) return;
	    event.preventDefault();
	    var i;
	    for (i = 0; i < pointers.length; ++i) {
	       if (pointers[i].pointerId === event.pointerId) {
		  pointers.splice(i, 1);
		  break;
	       }
	    }

	    updatePointerActive();
	    touchHandlers.end(widget, {touches:pointers.slice(0),changedTouches:[]});
	 }

	 function pointerMove(event) {
	    if (!isTouchEvent(event)) return;
	    event.preventDefault();
	    var i;
	    for (i = 0; i < pointers.length; ++i) {
	       if (pointers[i].pointerId === event.pointerId) {
		  pointers[i] = event;
		  break;
	       }
	    }

	    updatePointerActive();
	    touchHandlers.moved(widget, {touches:pointers.slice(0)});
	 }

	 var o = jQuery.data(widget, 'eobj');
	 if (o) {
	    if (!window.PointerEvent) {
	       widget.removeEventListener('MSPointerDown', o.pointerDown);
	       widget.removeEventListener('MSPointerUp', o.pointerUp);
	       widget.removeEventListener('MSPointerOut', o.pointerUp);
	       widget.removeEventListener('MSPointerMove', o.pointerMove);
	    } else {
	       widget.removeEventListener('pointerdown', o.pointerDown);
	       widget.removeEventListener('pointerup', o.pointerUp);
	       widget.removeEventListener('pointerout', o.pointerUp);
	       widget.removeEventListener('pointermove', o.pointerMove);
	    }
	 }
	 jQuery.data(widget, 'eobj', {
	    pointerDown: pointerDown,
	    pointerUp: pointerUp,
	    pointerMove: pointerMove
	 });
	 if (!window.PointerEvent) {
	    widget.addEventListener('MSPointerDown', pointerDown);
	    widget.addEventListener('MSPointerUp', pointerUp);
	    widget.addEventListener('MSPointerOut', pointerUp);
	    widget.addEventListener('MSPointerMove', pointerMove);
	 } else {
	    widget.addEventListener('pointerdown', pointerDown);
	    widget.addEventListener('pointerup', pointerUp);
	    widget.addEventListener('pointerout', pointerUp);
	    widget.addEventListener('pointermove', pointerMove);
	 }
      })();
   }

   // Constants
   var FRICTION_FACTOR = 0.003, // Determines how strongly the speed decreases, when animating
       SPRING_CONSTANT = 0.0002, // How strongly the spring pulls, relative to how extended it is
       RESISTANCE_FACTOR = 0.07, // How strongly the spring resists movement, when dragging
       BOUNDS_SLACK = 3, // The amount of slack to apply to determine whether an area is within bounds
       MIN_SPEED = 0.001, // The minimum speed that the animation should pan at when out of bounds,
			  // ensures that the animation does not stop prematurely.
       MAX_SPEED = 1.5, // The maximum speed that we should cap to, to prevent glitchy stuff
       STOPPING_SPEED = 0.02; // If the speed is below the stopping speed, and we're inside of bounds,
			      // then we can stop the animation.

   jQuery.data(widget, 'cobj', this);

   var self = this;
   var WT = APP.WT;

   self.config = config;

   var overlay = jQuery.data(widget, 'oobj');

   var crosshair = null;

   var paintEnabled = true;
   var dragPreviousXY = null;
   var touches = [];
   var singleTouch = false;
   var doubleTouch = false;
   var zoomAngle = null;
   var zoomMiddle = null;
   var zoomProjection = null;

   var v = {x: 0, y: 0};

   var lastDate = null;

   var mode = null;

   var utils = WT.gfxUtils;
   var mult = utils.transform_mult;
   var inverted = utils.transform_inverted;
   var assign = utils.transform_assign;
   var top = utils.rect_top;
   var bottom = utils.rect_bottom;
   var left = utils.rect_left;
   var right = utils.rect_right;

   var animating = false;

   function transform(ax) {
      if (ax === X) return config.xTransform;
      if (ax === Y) return config.yTransform;
   }

   function combinedTransform() {
      if (config.isHorizontal) {
	 var l = left(config.area);
	 var t = top(config.area);
	 return mult([0,1,1,0,l,t], mult(transform(X), mult(transform(Y), [0,1,1,0,-t,-l])));
      } else {
	 var l = left(config.area);
	 var b = bottom(config.area);
	 return mult([1,0,0,-1,l,b], mult(transform(X), mult(transform(Y), [1,0,0,-1,-l,b])));
      }
   }
   target.combinedTransform = combinedTransform;

   function transformedChartArea() {
      return mult(combinedTransform(), config.area);
   }

   function toModelCoord(p, noTransform) {
      if (noTransform === undefined) noTransform = false;
      var res;
      if (noTransform) {
	 res = p;
      } else {
	 res = mult(inverted(combinedTransform()), p);
      }
      var u;
      if (config.isHorizontal) {
	 u = [(res[Y] - config.area[1]) / config.area[3],
	      (res[X] - config.area[0]) / config.area[2]];
      } else {
         u = [(res[X] - config.area[0]) / config.area[2],
	       1 - (res[Y] - config.area[1]) / config.area[3]];
      }
      return [config.modelArea[0] + u[X] * config.modelArea[2],
	      config.modelArea[1] + u[Y] * config.modelArea[3]];
   }

   function toDisplayCoord(p, noTransform) {
      if (noTransform === undefined) noTransform = false;
      var u, res;
      if (config.isHorizontal) {
	 u = [(p[X] - config.modelArea[0]) / config.modelArea[2],
	      (p[Y] - config.modelArea[1]) / config.modelArea[3]];
	 res = [config.area[0] + u[Y] * config.area[2],
	        config.area[1] + u[X] * config.area[3]];
      } else {
	 u = [(p[X] - config.modelArea[0]) / config.modelArea[2],
	       1 - (p[Y] - config.modelArea[1]) / config.modelArea[3]];
	 res = [config.area[0] + u[X] * config.area[2],
	        config.area[1] + u[Y] * config.area[3]];
      }
      if (noTransform) {
	 return res;
      } else {
	 return mult(combinedTransform(), res);
      }
   }

   function findClosestPoint(x, series) {
      var axis = X;
      if (config.isHorizontal) {
	 axis = Y;
      }
      var i = binarySearch(x, series);
      if (i < 0) i = 0;
      if (i >= series.length) i = series.length - 2;
      if (series[i][axis] === x) return [series[i][X],series[i][Y]];
      var next_i = i+1;
      if (series[next_i][2] == CUBIC_C1) next_i += 2;
      var d1 = x - series[i][axis];
      var d2 = series[next_i][axis] - x;
      if (d1 < d2) {
	 return [series[i][X],series[i][Y]];
      } else {
	 return [series[next_i][X],series[next_i][Y]];
      }
   }

   // Find the anchor point (not a curve control point!)
   // with X coordinate nearest to the given x,
   // and smaller than the given x, and return
   // its index in the given series.
   function binarySearch(x, series) {
      var axis = X;
      if (config.isHorizontal) axis = Y;
      // Move back to a non-control point.
      function moveBack(i) {
	 if (series[i][2] === CUBIC_C2) --i;
	 if (series[i][2] === CUBIC_C1) --i;
	 return i;
      }
      var len = series.length;
      var i = Math.floor(len / 2);
      i = moveBack(i);
      var lower_bound = 0;
      var upper_bound = len;
      var found = false;
      if (series[0][axis] > x) return -1;
      if (series[len-1][axis] < x) return len;
      while (!found) {
	 var next_i = i + 1;
	 if (series[next_i][2] === CUBIC_C1) {
	    next_i += 2;
	 }
	 if (series[i][axis] > x) {
	    upper_bound = i;
	    i = Math.floor((upper_bound + lower_bound) / 2);
	    i = moveBack(i);
	 } else {
	    if (series[i][axis] === x) {
	       found = true;
	    } else {
	       if (series[next_i][axis] > x) {
		  found = true;
	       } else if (series[next_i][axis] === x) {
		  i = next_i;
		  found = true;
	       } else {
		  lower_bound = i;
		  i = Math.floor((upper_bound + lower_bound) / 2);
		  i = moveBack(i);
	       }
	    }
	 }
      }
      return i;
   }

   function notifyAreaChanged() {
      var u,v;
      if (config.isHorizontal) {
	 u = (toModelCoord([0, top(config.area)])[0] - config.modelArea[0]) / config.modelArea[2];
	 v = (toModelCoord([0, bottom(config.area)])[0] - config.modelArea[0]) / config.modelArea[2];
      } else {
	 u = (toModelCoord([left(config.area), 0])[0] - config.modelArea[0]) / config.modelArea[2];
	 v = (toModelCoord([right(config.area), 0])[0] - config.modelArea[0]) / config.modelArea[2];
      }
      var i;
      for (i = 0; i < config.sliders.length; ++i) {
	 var o = $('#' + config.sliders[i]);
	 if (o) {
	    var sobj = o.data('sobj');
	    if (sobj) {
	       sobj.changeRange(u, v);
	    }
	 }
      }
   }

   function repaint() {
      if (!paintEnabled) return;
      rqAnimFrame(function(){
	 target.repaint();
	 if (showCrosshair()) {
	    repaintOverlay();
	 }
      });
   }

   function repaintOverlay() {
      if (!paintEnabled) return;
      var ctx = overlay.getContext('2d');

      ctx.clearRect(0, 0, overlay.width, overlay.height);

      ctx.save();

      ctx.beginPath();
      ctx.moveTo(left(config.area), top(config.area));
      ctx.lineTo(right(config.area), top(config.area));
      ctx.lineTo(right(config.area), bottom(config.area));
      ctx.lineTo(left(config.area), bottom(config.area));
      ctx.closePath();
      ctx.clip();

      var p = mult(inverted(combinedTransform()), crosshair);
      var x = crosshair[X];
      var y = crosshair[Y];
      if (config.followCurve !== -1) {
	 p = findClosestPoint(config.isHorizontal ? p[Y] : p[X], config.series[config.followCurve]);
	 var tp = mult(combinedTransform(), p);
	 x = tp[X];
	 y = tp[Y];
	 crosshair[X] = x;
	 crosshair[Y] = y;
      }
      var u;
      if (config.isHorizontal) {
	 u = [(p[Y] - config.area[1]) / config.area[3],
	       (p[X] - config.area[0]) / config.area[2]];
      } else {
	 u = [(p[X] - config.area[0]) / config.area[2],
	       1 - (p[Y] - config.area[1]) / config.area[3]];
      }
      p = [config.modelArea[0] + u[X] * config.modelArea[2],
	   config.modelArea[1] + u[Y] * config.modelArea[3]];

      ctx.font = '16px sans-serif';
      ctx.textAlign = 'right';
      ctx.textBaseline = 'top';
      var textX = p[0].toFixed(2);
      var textY = p[1].toFixed(2);
      if (textX == '-0.00') textX = '0.00';
      if (textY == '-0.00') textY = '0.00';
      ctx.fillText("("+textX+","+textY+")", right(config.area) - config.coordinateOverlayPadding[0],
	    top(config.area) + config.coordinateOverlayPadding[1]);

      if (ctx.setLineDash) {
	 ctx.setLineDash([1,2]);
      }
      ctx.beginPath();
      ctx.moveTo(Math.floor(x) + 0.5, Math.floor(top(config.area)) + 0.5);
      ctx.lineTo(Math.floor(x) + 0.5, Math.floor(bottom(config.area)) + 0.5);
      ctx.moveTo(Math.floor(left(config.area)) + 0.5, Math.floor(y) + 0.5);
      ctx.lineTo(Math.floor(right(config.area)) + 0.5, Math.floor(y) + 0.5);
      ctx.stroke();

      ctx.restore();
   }

   // Check if a point is inside of the given rect
   function isPointInRect(point, rect) {
     var x,y;
     if (point.x !== undefined) {
       x = point.x;
       y = point.y;
     } else {
       x = point[0];
       y = point[1];
     }
     return x >= left(rect) && x <= right(rect) &&
	    y >= top(rect) && y <= bottom(rect);
   }

   // Check if the given area is within the bounds of the chart's area + some slack.
   function isWithinBounds(area) {
     return top(area) <= top(config.area) + BOUNDS_SLACK &&
	    bottom(area) >= bottom(config.area) - BOUNDS_SLACK &&
	    left(area) <= left(config.area) + BOUNDS_SLACK &&
	    right(area) >= right(config.area) - BOUNDS_SLACK;
   }

   function enforceLimits(flags) {
     var newChartArea = transformedChartArea();
     if (config.isHorizontal) {
	if (flags === X_ONLY) flags = Y_ONLY;
	else if (flags === Y_ONLY) flags = X_ONLY;
     }
     var diff;
     if (flags === undefined || flags === X_ONLY) {
	if (transform(X)[0] < 1) {
	   transform(X)[0] = 1;
	   newChartArea = transformedChartArea();
	}
     }
     if (flags === undefined || flags === Y_ONLY) {
	if (transform(Y)[3] < 1) {
	   transform(Y)[3] = 1;
	   newChartArea = transformedChartArea();
	}
     }
     if (flags === undefined || flags === X_ONLY) {
	if (left(newChartArea) > left(config.area)) {
	   diff = left(config.area) - left(newChartArea);
	   if (config.isHorizontal)
	      transform(Y)[5] = transform(Y)[5] + diff;
	   else
	      transform(X)[4] = transform(X)[4] + diff;
	   newChartArea = transformedChartArea();
	}
	if (right(newChartArea) < right(config.area)) {
	   diff = right(config.area) - right(newChartArea);
	   if (config.isHorizontal)
	      transform(Y)[5] = transform(Y)[5] + diff;
	   else
	      transform(X)[4] = transform(X)[4] + diff;
	   newChartArea = transformedChartArea();
	}
     }
     if (flags === undefined || flags === Y_ONLY) {
	if (top(newChartArea) > top(config.area)) {
	   diff = top(config.area) - top(newChartArea);
	   if (config.isHorizontal)
	      transform(X)[4] = transform(X)[4] + diff;
	   else
	      transform(Y)[5] = transform(Y)[5] - diff;
	   newChartArea = transformedChartArea();
	}
	if (bottom(newChartArea) < bottom(config.area)) {
	   diff = bottom(config.area) - bottom(newChartArea);
	   if (config.isHorizontal)
	      transform(X)[4] = transform(X)[4] + diff;
	   else
	      transform(Y)[5] = transform(Y)[5] - diff;
	   newChartArea = transformedChartArea();
	}
     }
   }

   this.mouseMove = function(o, event) {
      // Delay mouse move, because IE reacts to
      // mousemove first, but we actually want to
      // handle it after pointer events.
      setTimeout(function() {
	 if (pointerActive) return;
	 var c = WT.widgetCoordinates(target.canvas, event);
	 if (!isPointInRect(c, config.area)) return;

	 if (showCrosshair() && paintEnabled) {
	    crosshair = [c.x,c.y];
	    rqAnimFrame(repaintOverlay);
	 }
      }, 0);
   }

   this.mouseDown = function(o, event) {
      if (pointerActive) return;
      var c = WT.widgetCoordinates(target.canvas, event);
      if (!isPointInRect(c, config.area)) return;

      dragPreviousXY = c;
   };

   this.mouseUp = function(o, event) {
      if (pointerActive) return;
      dragPreviousXY = null;
   };

   this.mouseDrag = function(o, event) {
      if (pointerActive) return;
      if (dragPreviousXY === null) return;
      var c = WT.widgetCoordinates(target.canvas, event);
      if (!isPointInRect(c, config.area)) return;
      if (WT.buttons === 1) {
	 if (config.pan) {
	    translate({
	       x: c.x - dragPreviousXY.x,
	       y: c.y - dragPreviousXY.y
	    });
	 }
      }
      dragPreviousXY = c;
   };

   function init() {
      if (showCrosshair && (overlay === undefined || target.canvas.width !== overlay.width || target.canvas.height !== overlay.height)) {
	 if (overlay) {
	    overlay.parentNode.removeChild(overlay);
	    jQuery.removeData(widget, 'oobj');
	    overlay = undefined;
	 }
	 c = document.createElement("canvas");
	 c.setAttribute("width", target.canvas.width);
	 c.setAttribute("height", target.canvas.height);
	 c.style.position = 'absolute';
	 c.style.display = 'block';
	 c.style.left = '0';
	 c.style.top = '0';
	 if (window.MSPointerEvent || window.PointerEvent) {
	    c.style.msTouchAction = 'none';
	    c.style.touchAction = 'none';
	 }
	 target.canvas.parentNode.appendChild(c);
	 overlay = c;
	 jQuery.data(widget, 'oobj', overlay);
      } else if (overlay !== undefined && !showCrosshair()) {
	 // If the mouse handler is not reinitialized, we don't actually get here!
	 overlay.parentNode.removeChild(overlay);
	 jQuery.removeData(widget, 'oobj');
	 overlay = undefined;
      }

      if (crosshair === null) {
	 crosshair = toDisplayCoord([(left(config.modelArea) + right(config.modelArea)) / 2,
				     (top(config.modelArea) + bottom(config.modelArea)) / 2]);
      }
   }

   this.mouseWheel = function(o, event) {
      var modifiers = (event.metaKey << 3) + (event.altKey << 2) + (event.ctrlKey << 1) + event.shiftKey;
      var action = config.wheelActions[modifiers];
      if (action === undefined) return;

      var c = WT.widgetCoordinates(target.canvas, event);
      if (!isPointInRect(c, config.area)) return;
      var w = WT.normalizeWheel(event);
      if ((action === WHEEL_PAN_X || action === WHEEL_PAN_Y || action === WHEEL_PAN_MATCHING) && config.pan) {
	 var xBefore = transform(X)[4];
	 var yBefore = transform(Y)[5];
	 if (action === WHEEL_PAN_MATCHING)
	    translate({x:-w.pixelX,y:-w.pixelY});
	 else if (action === WHEEL_PAN_Y)
	    translate({x:0,y:-w.pixelX - w.pixelY});
	 else if (action === WHEEL_PAN_X)
	    translate({x:-w.pixelX - w.pixelY,y:0});
	 if (xBefore !== transform(X)[4] ||
	     yBefore !== transform(Y)[5]) {
	    WT.cancelEvent(event);
	 }
      } else if (config.zoom) {
	 WT.cancelEvent(event);
	 var d = -w.spinY;
	 // Some browsers scroll horizontally when shift key pressed
	 if (d === 0) d = -w.spinX;
	 if (action === WHEEL_ZOOM_Y) {
	    zoom(c, 0, d);
	 } else if (action === WHEEL_ZOOM_X) {
	    zoom(c, d, 0);
	 } else if (action === WHEEL_ZOOM_XY) {
	    zoom(c, d, d);
	 } else if (action === WHEEL_ZOOM_MATCHING) {
	    if (w.pixelX !== 0)
	       zoom(c, d, 0);
	    else
	       zoom(c, 0, d);
	 }
      }
   };

   // Get projection matrix to project any point
   // to a line through m at angle theta
   function projection(theta, m) {
      var c = Math.cos(theta);
      var s = Math.sin(theta);
      var c2 = c*c;
      var s2 = s*s;
      var cs = c*s;
      var h = -m[0]*c - m[1]*s;
      return [c2, cs, cs, s2, c*h+m[0], s*h+m[1]];
   }

   function distanceLessThanRadius(p1, p2, radius) {
      var d = [p2[X] - p1[X],
	       p2[Y] - p1[Y]];
      return radius * radius >= d[X] * d[X] + d[Y] * d[Y];
   }

   var CROSSHAIR_RADIUS = 30;

   touchHandlers.start = function(o, event) {
      singleTouch = event.touches.length === 1;
      doubleTouch = event.touches.length === 2;

      if (singleTouch) {
	 animating = false;
	 var c = WT.widgetCoordinates(target.canvas, event.touches[0]);
	 if (!isPointInRect(c, config.area)) return;
	 if (showCrosshair() && distanceLessThanRadius(crosshair, [c.x,c.y], CROSSHAIR_RADIUS)) {
	    mode = CROSSHAIR_MODE;
	 } else {
	    mode = LOOK_MODE;
	 }
	 lastDate = Date.now();
	 dragPreviousXY = c;
	 WT.capture(null);
	 WT.capture(target.canvas);
      } else if (doubleTouch && config.zoom) {
	 animating = false;
	touches = [
	   WT.widgetCoordinates(target.canvas,event.touches[0]),
	   WT.widgetCoordinates(target.canvas,event.touches[1])
	].map(function(t){return [t.x,t.y];});
	if (!touches.every(function(p){return isPointInRect(p,config.area);})) {
	   doubleTouch = null;
	   return;
	}
	WT.capture(null);
	WT.capture(target.canvas);
	zoomAngle = Math.atan2(touches[1][1] - touches[0][1], touches[1][0] - touches[0][0]);
	zoomMiddle = [
	   (touches[0][0] + touches[1][0]) / 2,
	   (touches[0][1] + touches[1][1]) / 2];
	var sin = Math.abs(Math.sin(zoomAngle));
	var cos = Math.abs(Math.cos(zoomAngle));
	if (sin < Math.sin(22.5 / 180 * Math.PI)) {
	   zoomAngle = 0;
	} else if (cos < Math.cos(67.5 / 180 * Math.PI)) {
	   zoomAngle = Math.PI / 2;
	} else if (Math.tan(zoomAngle) > 0) {
	   zoomAngle = Math.PI / 4;
	} else {
	   zoomAngle = -Math.PI / 4;
	}
	zoomProjection = projection(zoomAngle, zoomMiddle);
      } else {
	 return;
      }
      if (event.preventDefault) event.preventDefault();
   };

   function animate(ts, dt) {
      if (!animating) return;
      var now = Date.now();
      if (dt === undefined) {
	 dt = now - lastDate;
      }
      var d = {x: 0, y: 0};
      var area = transformedChartArea();
      var k = SPRING_CONSTANT;

      if (dt > 2 * ANIMATION_INTERVAL) {
	 paintEnabled = false;
	 var i = Math.floor(dt / ANIMATION_INTERVAL - 1);
	 var j;
	 for (j = 0; j < i; ++j) {
	    animate(ts, ANIMATION_INTERVAL);
	    if (!animating) {
	       paintEnabled = true;
	       repaint();
	       return;
	    }
	 }
	 dt -= i * ANIMATION_INTERVAL;
	 paintEnabled = true;
      }

      // Calculate new area position and v.x, v.y
      if (v.x === Infinity || v.x === -Infinity) {
	 if (v.x > 0) v.x = MAX_SPEED;
	 else v.x = -MAX_SPEED;
      }
      if (isFinite(v.x)) {
	 v.x = v.x / (1 + FRICTION_FACTOR * dt);
	 area[0] += v.x * dt;
	 if (left(area) > left(config.area)) {
	    v.x = v.x + (-k) * (left(area) - left(config.area)) * dt;
	    v.x *= 0.7;
	 } else if (right(area) < right(config.area)) {
	    v.x = v.x + (-k) * (right(area) - right(config.area)) * dt;
	    v.x *= 0.7;
	 }
	 if (Math.abs(v.x) < MIN_SPEED) {
	    if (left(area) > left(config.area)) {
	       v.x = MIN_SPEED;
	    } else if (right(area) < right(config.area)) {
	       v.x = -MIN_SPEED;
	    }
	 }
	 // cap speed
	 if (Math.abs(v.x) > MAX_SPEED) v.x = (v.x > 0 ? 1 : -1) * MAX_SPEED;
	 d.x = v.x * dt;
      }
      if (v.y === Infinity || v.y === -Infinity) {
	 if (v.y > 0) v.y = MAX_SPEED;
	 else v.y = -MAX_SPEED;
      }
      if (isFinite(v.y)) {
	 v.y = v.y / (1 + FRICTION_FACTOR * dt);
	 area[1] += v.y * dt;
	 if (top(area) > top(config.area)) {
	    v.y = v.y + (-k) * (top(area) - top(config.area)) * dt;
	    v.y *= 0.7;
	 } else if (bottom(area) < bottom(config.area)) {
	    v.y = v.y + (-k) * (bottom(area) - bottom(config.area)) * dt;
	    v.y *= 0.7;
	 }
	 if (Math.abs(v.y) < 0.001) {
	    if (top(area) > top(config.area)) {
	       v.y = 0.001;
	    } else if (bottom(area) < bottom(config.area)) {
	       v.y = -0.001;
	    }
	 }
	 // cap speed
	 if (Math.abs(v.y) > MAX_SPEED) v.y = (v.y > 0 ? 1 : -1) * MAX_SPEED;
	 d.y = v.y * dt;
      }

      area = transformedChartArea();
      translate(d, NO_LIMIT);
      var newArea = transformedChartArea();
      if (left(area) > left(config.area) &&
	  left(newArea) <= left(config.area)) {
	v.x = 0;
	translate({x:-d.x,y:0}, NO_LIMIT);
	enforceLimits(X_ONLY);
      }
      if (right(area) < right(config.area) &&
	  right(newArea) >= right(config.area)) {
	v.x = 0;
	translate({x:-d.x,y:0}, NO_LIMIT);
	enforceLimits(X_ONLY);
      }
      if (top(area) > top(config.area) &&
	  top(newArea) <= top(config.area)) {
	v.y = 0;
	translate({x:0,y:-d.y}, NO_LIMIT);
	enforceLimits(Y_ONLY);
      }
      if (bottom(area) < bottom(config.area) &&
	  bottom(newArea) >= bottom(config.area)) {
	v.y = 0;
	translate({x:0,y:-d.y}, NO_LIMIT);
	enforceLimits(Y_ONLY);
      }
      if (Math.abs(v.x) < STOPPING_SPEED &&
	  Math.abs(v.y) < STOPPING_SPEED &&
	  isWithinBounds(newArea)) {
	 enforceLimits();
	 animating = false;
	 dragPreviousXY = null;
	 v.x = 0;
      // Calculate new area p
	 v.y = 0;
	 lastDate = null;
	 touches = [];
      } else {
	 lastDate = now;
	 if (paintEnabled) {
	    rqAnimFrame(animate);
	 }
      }
   }

   touchHandlers.end = function(o, event) {
      var touches = Array.prototype.slice.call(event.touches);

      var noTouch = touches.length === 0;
      singleTouch = touches.length === 1;
      doubleTouch = touches.length === 2;

      if (!noTouch) {
	 (function(){
	    var i;
	    for (i = 0; i < event.changedTouches.length; ++i) {
	       (function(){
		  var id = event.changedTouches[i].identifier;
		  for (var j = 0; j < touches.length; ++j) {
		     if (touches[j].identifier === id) {
			touches.splice(j, 1);
			return;
		     }
		  }
	       })();
	    }
	 })();
      }

      noTouch = touches.length === 0;
      singleTouch = touches.length === 1;
      doubleTouch = touches.length === 2;

      if (noTouch) {
	 if (mode === LOOK_MODE && (isFinite(v.x) || isFinite(v.y)) && config.rubberBand) {
	    lastDate = Date.now();
	    animating = true;
	    rqAnimFrame(animate);
	 } else {
	    self.mouseUp(null, null);
	    touches = [];
	    zoomAngle = null;
	    zoomMiddle = null;
	    zoomProjection = null;
	    if (lastDate != null) {
	       var now = Date.now();
	       lastDate = null;
	    }
	 }
	 mode = null;
      } else if (singleTouch || doubleTouch)
	 touchHandlers.start(o, event);
   };

   touchHandlers.moved = function(o, event) {
     if ( (!singleTouch) && (!doubleTouch) ) {
       return;
     }

     if (singleTouch) {
	if (dragPreviousXY === null) return;
	var c = WT.widgetCoordinates(target.canvas, event.touches[0]);
	var now = Date.now();
	var d = {
	   x: c.x - dragPreviousXY.x,
	   y: c.y - dragPreviousXY.y
	};
	var dt = now - lastDate;
	lastDate = now;
	if (mode === CROSSHAIR_MODE) {
	   crosshair[X] += d.x;
	   crosshair[Y] += d.y;
	   if (showCrosshair() && paintEnabled) {
	      rqAnimFrame(repaintOverlay);
	   }
	} else if (config.pan) {
	   if (c.x < config.area[0] || c.x > config.area[0] + config.area[2]) {
	      v = {x:0,y:0};
	      return;
	   }
	   if (c.y < config.area[1] || c.y > config.area[1] + config.area[3]) {
	      v = {x:0,y:0};
	      return;
	   }
	   v.x = d.x / dt;
	   v.y = d.y / dt;
	   translate(d, config.rubberBand ? DAMPEN : 0);
	}
	if (event.preventDefault) event.preventDefault();
	dragPreviousXY = c;
     } else if (doubleTouch && config.zoom) {
	if (event.preventDefault) event.preventDefault();
	var crosshairBefore = toModelCoord(crosshair);
	var mxBefore = (touches[0][0] + touches[1][0]) / 2;
	var myBefore = (touches[0][1] + touches[1][1]) / 2;
	var newTouches = [
	   WT.widgetCoordinates(target.canvas,event.touches[0]),
	   WT.widgetCoordinates(target.canvas,event.touches[1])
	].map(function(t){
	   if (zoomAngle === 0) {
	      return [t.x, myBefore];
	   } else if (zoomAngle === Math.PI / 2) {
	      return [mxBefore, t.y];
	   } else {
	      return mult(zoomProjection,[t.x,t.y]);
	   }
	});

	var dxBefore = Math.abs(touches[1][0] - touches[0][0]);
	var dxAfter = Math.abs(newTouches[1][0] - newTouches[0][0]);
	var xScale = dxBefore > 0 ? dxAfter / dxBefore : 1;
	if (dxAfter === dxBefore || zoomAngle === Math.PI / 2) {
	   xScale = 1;
	}
	var mxAfter = (newTouches[0][0] + newTouches[1][0]) / 2;
	var dyBefore = Math.abs(touches[1][1] - touches[0][1]);
	var dyAfter = Math.abs(newTouches[1][1] - newTouches[0][1]);
	var yScale = dyBefore ? dyAfter / dyBefore : 1;
	if (dyAfter === dyBefore || zoomAngle === 0) {
	   yScale = 1;
	}
	var myAfter = (newTouches[0][1] + newTouches[1][1]) / 2;

	if (config.isHorizontal) {
	   (function() {
	     var tmp = xScale;
	     xScale = yScale;
	     yScale = tmp;
	     tmp = mxAfter;
	     mxAfter = myAfter;
	     myAfter = tmp;
	     tmp = mxBefore;
	     mxBefore = myBefore;
	     myBefore = tmp;
	   })();
	}

	if (transform(X)[0] * xScale > config.maxZoom[X]) {
	   xScale = config.maxZoom[X] / transform(X)[0];
	}
	if (transform(Y)[3] * yScale > config.maxZoom[Y]) {
	   yScale = config.maxZoom[Y] / transform(Y)[3];
	}
	if (xScale !== 1 &&
	      (xScale < 1.0 || transform(X)[0] !== config.maxZoom[X])) {
	   assign(transform(X),
	     mult(
		[xScale,0,0,1,-xScale*mxBefore+mxAfter,0],
		transform(X)
	      )
	   );
	}
	if (yScale !== 1 &&
	      (yScale < 1.0 || transform(Y)[3] !== config.maxZoom[Y])) {
	   assign(transform(Y),
	     mult(
		[1,0,0,yScale,0,-yScale*myBefore+myAfter],
		transform(Y)
	      )
	   );
	}
	enforceLimits();

        var crosshairAfter = toDisplayCoord(crosshairBefore);
	crosshair[X] = crosshairAfter[X];
	crosshair[Y] = crosshairAfter[Y];

	touches = newTouches;
	refreshPenColors();
	repaint();
	notifyAreaChanged();
     }
   };

   function toZoomLevel(zoomFactor) {
      return Math.floor(Math.log(zoomFactor) / Math.LN2 + 0.5) + 1;
   }

   function refreshPenColors() {
      var i, j;
      var xLevel = toZoomLevel(transform(X)[0]) - 1;
      if (xLevel >= config.pens.x.length) xLevel = config.pens.x.length - 1;
      for (i = 0; i < config.pens.x.length; ++i) {
	 if (xLevel === i) {
	    for (j = 0; j < config.pens.x[i].length; ++j) {
	       config.pens.x[i][j].color[3] = config.penAlpha.x[j];
	    }
	 } else {
	    for (j = 0; j < config.pens.x[i].length; ++j) {
	       config.pens.x[i][j].color[3] = 0;
	    }
	 }
      }
      var yLevel = toZoomLevel(transform(Y)[3]) - 1;
      if (yLevel >= config.pens.y.length) yLevel = config.pens.y.length - 1;
      for (i = 0; i < config.pens.y.length; ++i) {
	 if (yLevel === i) {
	    for (j = 0; j < config.pens.y[i].length; ++j) {
	       config.pens.y[i][j].color[3] = config.penAlpha.y[j];
	    }
	 } else {
	    for (j = 0; j < config.pens.y[i].length; ++j) {
	       config.pens.y[i][j].color[3] = 0;
	    }
	 }
      }
   }

   function translate(d, flags) {
      var crosshairBefore = toModelCoord(crosshair);

      if (config.isHorizontal) {
	 d = {x:d.y,y:-d.x};
      }

      if (flags & NO_LIMIT) {
	 transform(X)[4] = transform(X)[4] + d.x;
	 transform(Y)[5] = transform(Y)[5] - d.y;
      } else if (flags & DAMPEN) {
	 var area = transformedChartArea();
	 if (left(area) > left(config.area)) {
	    if (d.x > 0) {
	       d.x = d.x / (1 + ((left(area) - left(config.area)) * RESISTANCE_FACTOR));
	    }
	 } else if (right(area) < right(config.area)) {
	    if (d.x < 0) {
	       d.x = d.x / (1 + ((right(config.area) - right(area)) * RESISTANCE_FACTOR));
	    }
	 }
	 if (top(area) > top(config.area)) {
	    if (d.y > 0) {
	       d.y = d.y / (1 + ((top(area) - top(config.area)) * RESISTANCE_FACTOR));
	    }
	 } else if (bottom(area) < bottom(config.area)) {
	    if (d.y < 0) {
	       d.y = d.y / (1 + ((bottom(config.area) - bottom(area)) * RESISTANCE_FACTOR));
	    }
	 }
	 transform(X)[4] = transform(X)[4] + d.x;
	 transform(Y)[5] = transform(Y)[5] - d.y;
	 crosshair[X] = crosshair[X] + d.x;
	 crosshair[Y] = crosshair[Y] + d.y;
      } else {
	 transform(X)[4] = transform(X)[4] + d.x;
	 transform(Y)[5] = transform(Y)[5] - d.y;
	 crosshair[X] = crosshair[X] + d.x;
	 crosshair[Y] = crosshair[Y] + d.y;

	 enforceLimits();
      }

      var crosshairAfter = toDisplayCoord(crosshairBefore);

      crosshair[X] = crosshairAfter[X];
      crosshair[Y] = crosshairAfter[Y];

      repaint();
      notifyAreaChanged();
   }

   function zoom(coords, xDelta, yDelta) {
      var crosshairBefore = toModelCoord(crosshair);
      var xy;
      if (config.isHorizontal) {
	 xy = [coords.y - top(config.area), coords.x - left(config.area)];
      } else {
	 xy = mult(
	    inverted([1,0,0,-1,left(config.area),bottom(config.area)]), [coords.x, coords.y]);
      }
      var x = xy[0];
      var y = xy[1];
      var s_x = Math.pow(1.2, config.isHorizontal ? yDelta : xDelta);
      var s_y = Math.pow(1.2, config.isHorizontal ? xDelta : yDelta);
      if (transform(X)[0] * s_x > config.maxZoom[X]) {
	 s_x = config.maxZoom[X] / transform(X)[0];
      }
      if (s_x < 1.0 || transform(X)[0] !== config.maxZoom[X]) {
	 assign(transform(X),
	       mult(
		  [s_x,0,0,1,x-s_x*x,0],
		  transform(X)));
      }
      if (transform(Y)[3] * s_y > config.maxZoom[Y]) {
	 s_y = config.maxZoom[Y] / transform(Y)[3];
      }
      if (s_y < 1.0 || transform(Y)[3] !== config.maxZoom[Y]) {
	 assign(transform(Y),
	       mult(
		  [1,0,0,s_y,0,y-s_y*y],
		  transform(Y)));
      }

      enforceLimits();

      var crosshairAfter = toDisplayCoord(crosshairBefore);
      crosshair[X] = crosshairAfter[X];
      crosshair[Y] = crosshairAfter[Y];

      refreshPenColors();
      repaint();
      notifyAreaChanged();
   }

   this.setXRange = function(seriesNb, lowerBound, upperBound) {
      lowerBound = config.modelArea[0] + config.modelArea[2] * lowerBound;
      upperBound = config.modelArea[0] + config.modelArea[2] * upperBound;
      if (lowerBound < left(config.modelArea)) lowerBound = left(config.modelArea);
      if (upperBound > right(config.modelArea)) upperBound = right(config.modelArea);
      // Set X range, and adjust Y!
      var series = config.series[seriesNb];
      if (series.length === 0) return; // This would be weird?
      var p0 = toDisplayCoord([lowerBound, 0], true);
      var p1 = toDisplayCoord([upperBound, 0], true);
      var axis = config.isHorizontal ? Y : X;
      var otherAxis = config.isHorizontal ? X : Y;
      var i0 = binarySearch(p0[axis], series);
      if (i0 < 0) {
	 i0 = 0;
      } else {
	 i0 ++;
	 if (series[i0][2] === CUBIC_C1) i0 += 2;
      }
      var i_n = binarySearch(p1[axis], series);
      var i, u, y, before_i0, after_i_n;
      var min_y = Infinity;
      var max_y = -Infinity;
      for (i = i0; i <= i_n && i < series.length; ++i) {
	 if (series[i][2] !== CUBIC_C1 && series[i][2] !== CUBIC_C2) {
	    if (series[i][otherAxis] < min_y) min_y = series[i][otherAxis];
	    if (series[i][otherAxis] > max_y) max_y = series[i][otherAxis];
	 }
      }
      if (i0 > 0) {
	 // Interpolate on the lower X end
	 before_i0 = i0 - 1;
	 if (series[before_i0][2] === CUBIC_C2) before_i0 -= 2;
	 u = (p0[axis] - series[before_i0][axis]) / (series[i0][axis] - series[before_i0][axis]);
	 y = series[before_i0][otherAxis] + u * (series[i0][otherAxis] - series[before_i0][otherAxis]);
	 if (y < min_y) min_y = y;
	 if (y > max_y) max_y = y;
      }
      if (i_n < series.length - 1) {
	 // Interpolate on the upper X end
	 after_i_n = i_n + 1;
	 if (series[after_i_n][2] === CUBIC_C1) after_i_n += 2;
	 u = (p1[axis] - series[i_n][axis]) / (series[after_i_n][axis] - series[i_n][axis]);
	 y = series[i_n][otherAxis] + u * (series[after_i_n][otherAxis] - series[i_n][otherAxis]);
	 if (y < min_y) min_y = y;
	 if (y > max_y) max_y = y;
      }
      var xZoom = config.modelArea[2] / (upperBound - lowerBound);
      var H = config.isHorizontal ? 2 : 3;
      var yZoom = config.area[H] / (max_y - min_y);
      var yMargin = 10;
      yZoom = config.area[H] / (config.area[H] / yZoom + yMargin * 2); // Give it 10 px extra on each side
      if (yZoom > config.maxZoom[otherAxis]) yZoom = config.maxZoom[otherAxis];
      var panPoint;
      if (config.isHorizontal)
	 panPoint = [p0[Y] - top(config.area), ((min_y + max_y) / 2 - (config.area[2] / yZoom) / 2 - left(config.area))];
      else
	 panPoint = [p0[X] - left(config.area), -((min_y + max_y) / 2 + (config.area[3] / yZoom) / 2 - bottom(config.area))];

      var crosshairBefore = toModelCoord(crosshair);

      transform(X)[0] = xZoom;
      transform(Y)[3] = yZoom;
      transform(X)[4] = -panPoint[X] * xZoom;
      transform(Y)[5] = -panPoint[Y] * yZoom;

      var crosshairAfter = toDisplayCoord(crosshairBefore);
      crosshair[X] = crosshairAfter[X];
      crosshair[Y] = crosshairAfter[Y];

      enforceLimits();
      refreshPenColors();
      repaint();
      notifyAreaChanged();
   }

   this.getSeries = function(seriesNb) {
      return config.series[seriesNb];
   }

   this.rangeChangedCallbacks = [];

   this.updateConfig = function(newConfig) {
      for (var key in newConfig) {
	 if (newConfig.hasOwnProperty(key)) {
	    config[key] = newConfig[key];
	 }
      }
      init();
      refreshPenColors();
      repaint();
      notifyAreaChanged();
   }

   this.updateConfig({});

   if (window.TouchEvent && !window.MSPointerEvent && !window.PointerEvent) {
      self.touchStart = touchHandlers.start;
      self.touchEnd = touchHandlers.end;
      self.touchMoved = touchHandlers.moved;
   } else {
      var nop = function(){};
      self.touchStart = nop;
      self.touchEnd = nop;
      self.touchMoved = nop;
   }
 });


text:
using Bytes2you.Validation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using TravelAlbum.DataServices.Contracts;
using TravelAlbum.Models;
using TravelAlbum.Web.Helpers;
using TravelAlbum.Web.Models.ImageModels;

namespace TravelAlbum.Web.Controllers
{
    public class HomeController : Controller
    {
        private readonly IImageService imageService;

        public HomeController(IImageService imageService)
        {
            Guard.WhenArgument(imageService, "imageService").IsNull().Throw();
            this.imageService = imageService;
        }

        public ActionResult Index(int pageIndex = 0)
        {
            return View();
        }

        public JsonResult GetImagesOnScroll(string url, int pageIndex = 0)
        {
            var orderedImages = this.imageService.GetLatesImages(pageIndex);

            List<ImagePreviewOutputViewModel> images = new List<ImagePreviewOutputViewModel>();
            if (orderedImages != null && orderedImages.Count() > 0)
            {
                GenerateImageModel(orderedImages, images);

                var jsonResult = Json(images, JsonRequestBehavior.AllowGet);
                jsonResult.MaxJsonLength = int.MaxValue;
                return jsonResult;
            }
            else
            {
                var jsonResult = Json(images, JsonRequestBehavior.AllowGet);
                jsonResult.MaxJsonLength = int.MaxValue;
                return jsonResult;
            }
        }

        public void GenerateImageModel(IEnumerable<Image> orderedImages, List<ImagePreviewOutputViewModel> images)
        {
            foreach (var image in orderedImages)
            {
                ImagePreviewOutputViewModel imagePreviewOutputViewModel = new ImagePreviewOutputViewModel();
                // string query = Request.Url.PathAndQuery;

                //TODO: fix en and bg string conditions
                // if (!(url.Contains("/en")))
                // {
                //     description = SetDescription(singleImage, Language.Bulgarian);
                // }
                // else
                // {
                //     description = SetDescription(singleImage, Language.English);
                // }

                string imagePreviewData = Convert.ToBase64String(image.PreviewContent);

                imagePreviewOutputViewModel.ImageId = image.TravelObjectId;
                imagePreviewOutputViewModel.ImageData = imagePreviewData;
                imagePreviewOutputViewModel.CreatedOn = image.CreatedOn;
                images.Add(imagePreviewOutputViewModel);
            }
        }

        public ActionResult About()
        {
            ViewBag.Message = "TEST!2Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
<?php

final class PhabricatorCalendarExportDisableController
  extends PhabricatorCalendarController {

  public function handleRequest(AphrontRequest $request) {
    $viewer = $request->getViewer();

    $export = id(new PhabricatorCalendarExportQuery())
      ->setViewer($viewer)
      ->withIDs(array($request->getURIData('id')))
      ->requireCapabilities(
        array(
          PhabricatorPolicyCapability::CAN_VIEW,
          PhabricatorPolicyCapability::CAN_EDIT,
        ))
      ->executeOne();
    if (!$export) {
      return new Aphront404Response();
    }

    $export_uri = $export->getURI();
    $is_disable = !$export->getIsDisabled();

    if ($request->isFormPost()) {
      $xactions = array();
      $xactions[] = id(new PhabricatorCalendarExportTransaction())
        ->setTransactionType(
          PhabricatorCalendarExportDisableTransaction::TRANSACTIONTYPE)
        ->setNewValue($is_disable ? 1 : 0);

      $editor = id(new PhabricatorCalendarExportEditor())
        ->setActor($viewer)
        ->setContinueOnNoEffect(true)
        ->setContinueOnMissingFields(true)
        ->setContentSourceFromRequest($request);

      $editor->applyTransactions($export, $xactions);

      return id(new AphrontRedirectResponse())->setURI($export_uri);
    }

    if ($is_disable) {
      $title = pht('Disable Export');
      $body = pht(
        'Disable this export? The export URI will no longer function.');
      $button = pht('Disable Export');
    } else {
      $title = pht('Enable Export');
      $body = pht(
        'Enable this export? Anyone who knows the export URI will be able '.
        'to export the data.');
      $button = pht('Enable Export');
    }

    return $this->newDialog()
      ->setTitle($title)
      ->appendParagraph($body)
      ->addCancelButton($export_uri)
      ->addSubmitButton($button);
  }

}


text:
export * from './dom.module'
export * from './window.service'


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

namespace RingtoneComposer.WindowsPhone.Views.Controls
{
    public partial class PhoneKeyboardControl : UserControl
    {
        public PhoneKeyboardControl()
        {
            InitializeComponent();
        }

        #region DP KeyOne
        public Button KeyOne
        {
            get { return (Button)GetValue(KeyOneProperty); }
            set { SetValue(KeyOneProperty, value); }
        }

        // Using a DependencyProperty as the backing store for KeyOne.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty KeyOneProperty =
            DependencyProperty.Register("KeyOne", typeof(Button), typeof(PhoneKeyboardControl), new PropertyMetadata("1"));
        #endregion

        #region DP KeyTwo
        public Button KeyTwo
        {
            get { return (Button)GetValue(KeyTwoProperty); }
            set { SetValue(KeyTwoProperty, value); }
        }

        // Using a DependencyProperty as the backing store for KeyTwo.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty KeyTwoProperty =
            DependencyProperty.Register("KeyTwo", typeof(Button), typeof(PhoneKeyboardControl), new PropertyMetadata("2"));
        #endregion

    }
}


text:
<md-content class="md-padding" layout-xs="column" layout="row">

        <ui-view/>

    <md-card class="cardHeight">
        <md-card-content>
            <md-button class="md-primary md-raised white-font metabuttons" ui-sref="requiredMetadata">Required metadata</md-button>
            <md-button class="md-primary md-raised white-font metabuttons" ui-sref="optionalMetadata">Optional metadata</md-button>
            <md-button class="md-primary md-raised white-font metabuttons" ui-sref="spacetimeMetadata">Space-time metadata</md-button>
            <md-button class="md-primary md-raised white-font metabuttons" ui-sref="uibindings">UI bindings</md-button>
            <md-button class="md-primary md-raised white-font metabuttons" ng-click="cpctrl.updateMetadata()" style = "position: relative; margin-top:130%;">Save</md-button>
        </md-card-content>
    </md-card>

</md-content>


text:
iOSWebserviceTemplate
=====================

A template for binding to webservices using NSOperation and NSOperationQueue. Simply subclass Webservice to get started on your own webservice

###Installation

#####Cocoa Pods
```Ruby
pod 'iOSWebserviceTemplate'
```
##### Manual Installation
Copy the following files into your project:
- WebOperation{.h,.m}
- WebOperationHeaders{.h}
- WebService{.h,.m}


text:
var MIN_NODE_VER = "0.9.9";

function isNodeNewerThanMin () {
    //Current version is stored as a String in format "X.X.X"
    //Must be newer than "0.9.9"
    var currentVer = process.versions.node.split(".").map(function (verNumStr) { return parseInt(verNumStr, 10);});
    return (currentVer[0] > 0 || currentVer[1] > 9 || currentVer[1] === 9 && currentVer[2] >= 9);
}

if (!isNodeNewerThanMin()) {
    console.log("Node version '" + process.versions.node + "' is not new enough. Please upgrade to " + MIN_NODE_VER + " or newer. Aborting.");
    process.exit(1);
}

process.exit(0);


text:
class CreateCatwalks < ActiveRecord::Migration
  def self.up
    create_table :catwalks do |t|
      t.string :catname

      t.timestamps
    end
  end

  def self.down
    drop_table :catwalks
  end
end


text: Login Users


text:
package org.lobobrowser.primary.gui;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.border.EmptyBorder;

import org.eclipse.jdt.annotation.Nullable;

public class ItemEditorDialog<T> extends JDialog {
  private static final long serialVersionUID = -5624516092024297352L;
  private final JLabel captionLabel = new JLabel();
  private final JButton okButton = new JButton();
  private final JButton cancelButton = new JButton();
  private final AbstractItemEditor<T> editor;

  public ItemEditorDialog(final Dialog owner, final ItemEditorFactory<T> factory) throws HeadlessException {
    super(owner);
    this.editor = factory.createItemEditor();
    this.init();
  }

  public ItemEditorDialog(final Frame owner, final ItemEditorFactory<T> factory) throws HeadlessException {
    super(owner);
    this.editor = factory.createItemEditor();
    this.init();
  }

  private void init() {
    this.captionLabel.setPreferredSize(new Dimension(Short.MAX_VALUE, 32));
    this.captionLabel.setAlignmentX(0.0f);
    this.captionLabel.setBorder(new EmptyBorder(8, 0, 8, 0));
    this.okButton.setAction(new OkAction());
    this.okButton.setText("OK");
    this.cancelButton.setAction(new CancelAction());
    this.cancelButton.setText("Cancel");

    // this.editor.setBorder(new BevelBorder(BevelBorder.RAISED));

    final Box rootBox = new Box(BoxLayout.Y_AXIS);
    rootBox.setBorder(new EmptyBorder(4, 4, 4, 4));
    rootBox.add(this.captionLabel);
    rootBox.add(this.editor);
    rootBox.add(this.createButtonPanel());

    final Container contentPane = this.getContentPane();
    contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
    contentPane.add(rootBox);
  }

  public void setCaption(final String caption) {
    this.captionLabel.setText(caption);
  }

  public void setItem(final T item) {
    this.editor.setItem(item);
  }

  private Component createButtonPanel() {
    final Box panel = new Box(BoxLayout.X_AXIS);
    // panel.setBorder(new BevelBorder(BevelBorder.LOWERED));
    panel.setBorder(new EmptyBorder(4, 4, 4, 4));
    panel.add(Box.createGlue());
    panel.add(this.okButton);
    panel.add(Box.createRigidArea(new Dimension(4, 1)));
    panel.add(this.cancelButton);
    panel.add(Box.createGlue());
    return panel;
  }

  private @Nullable T resultingItem;

  public @Nullable T getResultingItem() {
    return this.resultingItem;
  }

  private class OkAction extends AbstractAction {
    private static final long serialVersionUID = -4808011697369530582L;

    public void actionPerformed(final ActionEvent e) {
      try {
        editor.validateItem();
      } catch (final ValidationException ve) {
        JOptionPane.showMessageDialog(ItemEditorDialog.this, ve.getMessage());
        return;
      }
      resultingItem = editor.getItem();
      ItemEditorDialog.this.dispose();
    }
  }

  private class CancelAction extends AbstractAction {
    private static final long serialVersionUID = 3129498045750775250L;

    public void actionPerformed(final ActionEvent e) {
      resultingItem = null;
      ItemEditorDialog.this.dispose();
    }
  }
}


text:
package com.vladkel.dametenebra.ihm;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

import com.google.common.reflect.TypeToken;
import com.vladkel.dametenebra.DameTenebra;
import com.vladkel.dametenebra.model.Category;
import com.vladkel.dametenebra.model.Photo;
import com.vladkel.dametenebra.persistence.dao.DAO;
import com.vladkel.dametenebra.persistence.dao.IDAO;
import com.vladkel.dametenebra.utils.ftp.FtpClient;
import com.vladkel.dametenebra.utils.ftp.threads.Retrieve;
import com.vladkel.dametenebra.utils.ftp.threads.Store;
import com.vladkel.dametenebra.utils.listeners.photo.ChooseFileListener;
import com.vladkel.dametenebra.utils.listeners.photo.DeleteListener;
import com.vladkel.dametenebra.utils.listeners.photo.OnOverListener;
import com.vladkel.dametenebra.utils.listeners.photo.SaveListener;
import com.vladkel.dametenebra.utils.properties.Property;

/**
 * @author eliott
 *
 */
public class IhmPhoto implements IHM {

	private IDAO<Photo> dao;
	private IDAO<Category> categoryDao;
	private List<Category> categories;

	/* ihm */
	private JFrame jf_photo;
	private JPanel p_photo;
	private JButton modif;
	private GridBagLayout bl;
	private JLabel title_name_photo;
	private JTextField text_name_photo;
	private JLabel title_desc_photo;
	private JTextField text_desc_photo;
	private JLabel title_link_photo;
	private JTextField text_link_photo;
	private JLabel title_category_photo;
	private JComboBox<Category> text_category_photo;
	private JButton add_photo;
	private JCheckBox is_active;

	private JFrame modify;

	private JButton save;
	private JButton delete;
	private JButton img_mini;

	@SuppressWarnings("serial")
	public IhmPhoto() {
		super();
		dao = new DAO<Photo>(Photo.class, new TypeToken<List<Photo>>() {
		}.getType());
		categoryDao = new DAO<Category>(Category.class, new TypeToken<List<Category>>() {
		}.getType());
	}

	/**
	 * (non-Javadoc)
	 *
	 * @see com.vladkel.dametenebra.ihm.IHM#init()
	 */
	@Override
	public void init() {
		empty();
		fill();
		p_photo.removeAll();
		p_photo.repaint();

		jf_photo.setSize(800, 600);
		jf_photo.setLocationRelativeTo(null);
		jf_photo.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		p_photo.setLayout(bl);
		jf_photo.setContentPane(p_photo);
	}

	/**
	 * (non-Javadoc)
	 *
	 * @see com.vladkel.dametenebra.ihm.IHM#empty()
	 */
	@Override
	public void empty() {
		jf_photo = null;
		p_photo = null;
		bl = null;

		title_name_photo = null;
		text_name_photo = null;
		title_desc_photo = null;
		text_desc_photo = null;
		title_link_photo = null;
		text_link_photo = null;
		title_category_photo = null;
		text_category_photo = null;
		add_photo = null;
		img_mini = null;
		is_active = null;

		modif = null;

		save = null;
		delete = null;
	}

	/**
	 * (non-Javadoc)
	 *
	 * @see com.vladkel.dametenebra.ihm.IHM#fill()
	 */
	@Override
	public void fill() {
		jf_photo = new JFrame();
		p_photo = new JPanel();
		bl = new GridBagLayout();

		title_name_photo = new JLabel("Nom");
		text_name_photo = new JTextField();
		title_desc_photo = new JLabel("Description");
		text_desc_photo = new JTextField();
		title_link_photo = new JLabel("Nom du fichier");
		text_link_photo = new JTextField();
		title_category_photo = new JLabel("Categorie concernée");
		categories = categoryDao.select();
		text_category_photo = new JComboBox<Category>(categories.toArray(new Category[categories.size()]));
		add_photo = new JButton("Ajouter");
		is_active = new JCheckBox("Rendre visible sur le site ?");

		modif = new JButton("Détail");

		save = new JButton("Sauvegarder");
		delete = new JButton("Supprimer");
	}

	/**
	 * (non-Javadoc)
	 *
	 * @see com.vladkel.dametenebra.ihm.IHM#displayAll()
	 */
	@Override
	public void displayAll() {
		init();
		jf_photo.setTitle("Consulter les photos");
		jf_photo.setResizable(false);

		final List<Photo> photos = dao.select();
		Object[][] data = new Object[photos.size()][6];

		for (int i = 0; i < photos.size(); i++) {
			data[i][0] = photos.get(i).getPhoto_id();
			data[i][1] = photos.get(i).getPhoto_name();
			data[i][2] = photos.get(i).getPhoto_description();
			data[i][3] = photos.get(i).getPhoto_date();

			for (Category category : categories) {
				if (category.getCategory_id() == photos.get(i).getCategory_photo()) {
					data[i][4] = category.getCategory_name();
					break;
				}
			}

			data[i][5] = photos.get(i).getActive() == 1 ? "oui" : "non";
		}

		String[] entete = { "Id", "Nom", "Description", "Date d'Ajout", "Categorie", "Visible" };
		final JTable tab = new JTable(data, entete);

		modif.addMouseListener(new MouseAdapter() {

			public void mouseClicked(MouseEvent e) {
				if (tab.getSelectedRow() != -1) {
					modify(photos.get(tab.getSelectedRow()));
				}
			}
		});

		p_photo.add(new JScrollPane(tab));
		p_photo.add(modif);
		jf_photo.setVisible(true);
		p_photo.repaint();
	}

	/**
	 * (non-Javadoc)
	 *
	 * @see com.vladkel.dametenebra.ihm.IHM#create()
	 */
	@Override
	public void create() {
		init();
		modify = new JFrame();
		modify.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		modify.setTitle("Ajouter une photo");
		modify.setSize(new Dimension(380, 450));
		modify.setLocationRelativeTo(null);
		modify.setResizable(false);

		JPanel mp = new JPanel();
		modify.setContentPane(mp);
		mp.setLayout(new FlowLayout());

		Dimension d = new Dimension(350, 20);

		text_name_photo.setPreferredSize(d);
		text_desc_photo.setPreferredSize(d);
		text_link_photo.setPreferredSize(d);
		text_category_photo.setPreferredSize(d);
		title_category_photo.setPreferredSize(d);
		is_active.setPreferredSize(d);

		img_mini = new JButton(new ImageIcon());
		img_mini.setBorder(BorderFactory.createEmptyBorder());
		img_mini.setContentAreaFilled(false);

		mp.add(title_name_photo);
		mp.add(text_name_photo);
		mp.add(title_desc_photo);
		mp.add(text_desc_photo);
		mp.add(title_link_photo);
		mp.add(text_link_photo);
		mp.add(img_mini);
		mp.add(title_category_photo);
		mp.add(text_category_photo);
		mp.add(is_active);

		mp.add(add_photo);

		final Date date = new Date();
		final DateFormat formate = new SimpleDateFormat("yyyy-MM-dd");

		text_category_photo.setSelectedIndex(0);

		Photo photo = new Photo();
		photo.setPhoto_id(0);
		photo.setPhoto_date(formate.format(date));

		/**
		 * Listeners
		 */

		text_link_photo.addMouseListener(new ChooseFileListener(this));

		img_mini.addMouseListener(new OnOverListener(text_link_photo));

		add_photo.addMouseListener(new SaveListener(this, photo));

		modify.setVisible(true);

	}

	/**
	 * (non-Javadoc)
	 *
	 * @see com.vladkel.dametenebra.ihm.IHM#modify(java.lang.Object)
	 */
	@Override
	public void modify(Object object) {
		final Photo photo = (Photo) object;
		modify = new JFrame();

		modify.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		modify.setTitle("Modifier la photo : " + photo.getPhoto_name());
		modify.setSize(new Dimension(380, 450));
		modify.setLocationRelativeTo(null);
		modify.setResizable(false);

		JPanel mp = new JPanel();
		modify.setContentPane(mp);
		mp.setLayout(new FlowLayout());

		Dimension d = new Dimension(350, 20);

		text_name_photo.setPreferredSize(d);
		text_desc_photo.setPreferredSize(d);
		text_link_photo.setPreferredSize(d);
		text_category_photo.setPreferredSize(d);
		title_category_photo.setPreferredSize(d);
		is_active.setPreferredSize(d);

		File mini = new File("data/img/mini/" + photo.getPhoto_mini_link());
		img_mini = new JButton(new ImageIcon(mini.getAbsolutePath()));
		img_mini.setBorder(BorderFactory.createEmptyBorder());
		img_mini.setContentAreaFilled(false);

		mp.add(title_name_photo);
		mp.add(text_name_photo);
		mp.add(title_desc_photo);
		mp.add(text_desc_photo);
		mp.add(title_link_photo);
		mp.add(text_link_photo);
		mp.add(img_mini);
		mp.add(title_category_photo);
		mp.add(text_category_photo);
		mp.add(is_active);

		mp.add(save);
		mp.add(delete);

		text_name_photo.setText(photo.getPhoto_name());
		text_desc_photo.setText(photo.getPhoto_description());
		text_link_photo.setText(photo.getPhoto_link());
		is_active.setSelected(photo.getActive() == 1 ? true : false);

		for (int i = 0; i < categories.size(); i++) {
			if (categories.get(i).getCategory_id() == photo.getCategory_photo()) {
				text_category_photo.setSelectedIndex(i);
				break;
			}
		}

		/**
		 * Listeners
		 */

		text_link_photo.addMouseListener(new ChooseFileListener(this));

		img_mini.addMouseListener(new OnOverListener(text_link_photo));

		save.addMouseListener(new SaveListener(this, photo));

		delete.addMouseListener(new DeleteListener(this, photo));

		downloadFiles("img/full/" + photo.getPhoto_link(), "img/mini/" + photo.getPhoto_mini_link());

		modify.setVisible(true);
	}

	public void setIcon(ImageIcon icon) {
		img_mini.setIcon(icon);
		modify.repaint();
	}

	public void store() {

		storeOnline();
	}

	public void storeOnline() {
		FtpClient client = null;

		if (DameTenebra.server.equalsIgnoreCase("local")) {
			client = new FtpClient("localhost", Property.getInstance().get("ftp.user"),
					Property.getInstance().get("ftp.pwd"));
		} else if (DameTenebra.server.equalsIgnoreCase("prod")) {
			client = new FtpClient(Property.getInstance().get("ftp.url"), Property.getInstance().get("ftp.user"),
					Property.getInstance().get("ftp.pwd"));
		}

		File img = new File(new File(text_link_photo.getText()).getName());
		File img_mini = new File(new File(text_link_photo.getText()).getName());

		Thread mini = new Thread(
				new Store(client, new File("data/img/mini/" + text_link_photo.getText()), img_mini, "/www/img/mini"));
		Thread full = new Thread(
				new Store(client, new File("data/img/full/" + text_link_photo.getText()), img, "/www/img/full", mini));
		full.start();

	}

	public void downloadFiles(String src_full, String src_mini) {
		File file_mini = new File("data/" + src_mini);
		File file_full = new File("data/" + src_full);
		FtpClient client = null;
		if (!file_mini.exists()) {
			if (DameTenebra.server.equalsIgnoreCase("local")) {
				client = new FtpClient("localhost", Property.getInstance().get("ftp.user"),
						Property.getInstance().get("ftp.pwd"));
			}
			if (DameTenebra.server.equalsIgnoreCase("prod")) {
				client = new FtpClient(Property.getInstance().get("ftp.url"), Property.getInstance().get("ftp.user"),
						Property.getInstance().get("ftp.pwd"));
			}

			Thread mini = new Thread(
					new Retrieve(client, file_mini, "www/" + src_mini.substring(0, src_full.lastIndexOf("/")), this));
			Thread full = new Thread(
					new Retrieve(client, file_full, "www/" + src_full.substring(0, src_full.lastIndexOf("/")), mini));
			full.start();
		} else {
			System.out.println("Files are already in cache, great !");
			setIcon(new ImageIcon("data/img/mini/" + file_mini.getName()));
		}
	}

	public IDAO<Photo> getDao() {
		return dao;
	}

	public String getPhotoName() {
		return text_name_photo.getText();
	}

	public String getPhotoDescription() {
		return text_desc_photo.getText();
	}

	public String getPhotoLink() {
		return text_link_photo.getText().substring(text_link_photo.getText().lastIndexOf("\\") + 1);
	}

	public int getPhotoCategory() {
		return categories.get(text_category_photo.getSelectedIndex()).getCategory_id();
	}

	public int getActive() {
		return is_active.isSelected() ? 1 : 0;
	}

	public JFrame getMainFrame() {
		return jf_photo;
	}

	public JFrame getModifyFrame() {
		return modify;
	}

	public JTextField getTextLinkPhoto() {
		return text_link_photo;
	}
}


text:
namespace
{
bool IsSpecialDirName(string const & dirName)
{
  return dirName == "." || dirName == "..";
}
} // namespace

// static
Platform::EError Platform::ErrnoToError()
{
  switch (errno)
  {
    case ENOENT:
      return ERR_FILE_DOES_NOT_EXIST;
    case EACCES:
      return ERR_ACCESS_FAILED;
    case ENOTEMPTY:
      return ERR_DIRECTORY_NOT_EMPTY;
    case EEXIST:
      return ERR_FILE_ALREADY_EXISTS;
    case ENAMETOOLONG:
      return ERR_NAME_TOO_LONG;
    case ENOTDIR:
      return ERR_NOT_A_DIRECTORY;
    case ELOOP:
      return ERR_SYMLINK_LOOP;
    case EIO:
      return ERR_IO_ERROR;
    default:
      return ERR_UNKNOWN;
  }
}

// static
bool Platform::RmDirRecursively(string const & dirName)
{
  if (dirName.empty() || IsSpecialDirName(dirName))
    return false;

  bool res = true;

  FilesList allFiles;
  GetFilesByRegExp(dirName, ".*", allFiles);
  for (string const & file : allFiles)
  {
    string const path = my::JoinFoldersToPath(dirName, file);

    EFileType type;
    if (GetFileType(path, type) != ERR_OK)
      continue;

    if (type == FILE_TYPE_DIRECTORY)
    {
      if (!IsSpecialDirName(file) && !RmDirRecursively(path))
        res = false;
    }
    else
    {
      if (!my::DeleteFileX(path))
        res = false;
    }
  }

  if (RmDir(dirName) != ERR_OK)
    res = false;

  return res;
}

void Platform::SetSettingsDirForTests(string const & path)
{
  m_settingsDir = my::AddSlashIfNeeded(path);
}

string Platform::ReadPathForFile(string const & file, string searchScope) const
{
  if (searchScope.empty())
    searchScope = "wrf";

  string fullPath;
  for (size_t i = 0; i < searchScope.size(); ++i)
  {
    switch (searchScope[i])
    {
    case 'w': fullPath = m_writableDir + file; break;
    case 'r': fullPath = m_resourcesDir + file; break;
    case 's': fullPath = m_settingsDir + file; break;
    case 'f': fullPath = file; break;
    default : CHECK(false, ("Unsupported searchScope:", searchScope)); break;
    }
    if (IsFileExistsByFullPath(fullPath))
      return fullPath;
  }

  string const possiblePaths = m_writableDir  + "\n" + m_resourcesDir + "\n" + m_settingsDir;
  MYTHROW(FileAbsentException, ("File", file, "doesn't exist in the scope", searchScope,
                                "Have been looking in:\n", possiblePaths));
}

string Platform::ResourcesMetaServerUrl() const
{
  return RESOURCES_METASERVER_URL;
}

string Platform::MetaServerUrl() const
{
  return METASERVER_URL;
}

string Platform::DefaultUrlsJSON() const
{
  return DEFAULT_URLS_JSON;
}

void Platform::GetFontNames(FilesList & res) const
{
  ASSERT(res.empty(), ());

  /// @todo Actually, this list should present once in all our code.
  /// We can take it from data/external_resources.txt
  char const * arrDef[] = {
    "01_dejavusans.ttf",
    "02_droidsans-fallback.ttf",
    "03_jomolhari-id-a3d.ttf",
    "04_padauk.ttf",
    "05_khmeros.ttf",
    "06_code2000.ttf",
    "07_roboto_medium.ttf"
  };
  res.insert(res.end(), arrDef, arrDef + ARRAY_SIZE(arrDef));

  GetSystemFontNames(res);

  LOG(LINFO, ("Available font files:", (res)));
}

void Platform::GetFilesByExt(string const & directory, string const & ext, FilesList & outFiles)
{
  // Transform extension mask to regexp (.mwm -> \.mwm$)
  ASSERT ( !ext.empty(), () );
  ASSERT_EQUAL ( ext[0], '.' , () );

  GetFilesByRegExp(directory, '\\' + ext + '$', outFiles);
}

// static
void Platform::GetFilesByType(string const & directory, unsigned typeMask,
                              TFilesWithType & outFiles)
{
  FilesList allFiles;
  GetFilesByRegExp(directory, ".*", allFiles);
  for (string const & file : allFiles)
  {
    EFileType type;
    if (GetFileType(my::JoinFoldersToPath(directory, file), type) != ERR_OK)
      continue;
    if (typeMask & type)
      outFiles.emplace_back(file, type);
  }
}

// static
bool Platform::IsDirectory(string const & path)
{
  EFileType fileType;
  if (GetFileType(path, fileType) != ERR_OK)
    return false;
  return fileType == FILE_TYPE_DIRECTORY;
}

string Platform::DeviceName() const
{
  return OMIM_OS_NAME;
}

// static
void Platform::GetFilesRecursively(string const & directory, FilesList & filesList)
{
  TFilesWithType files;

  GetFilesByType(directory, Platform::FILE_TYPE_REGULAR, files);
  for (auto const & p : files)
  {
    auto const & file = p.first;
    CHECK_EQUAL(p.second, Platform::FILE_TYPE_REGULAR, ("dir:", directory, "file:", file));
    filesList.push_back(my::JoinPath(directory, file));
  }

  TFilesWithType subdirs;
  GetFilesByType(directory, Platform::FILE_TYPE_DIRECTORY, subdirs);

  for (auto const & p : subdirs)
  {
    auto const & subdir = p.first;
    CHECK_EQUAL(p.second, Platform::FILE_TYPE_DIRECTORY, ("dir:", directory, "subdir:", subdir));
    if (subdir == "." || subdir == "..")
      continue;

    GetFilesRecursively(my::JoinPath(directory, subdir), filesList);
  }
}

void Platform::SetWritableDirForTests(string const & path)
{
  m_writableDir = my::AddSlashIfNeeded(path);
}

void Platform::SetResourceDir(string const & path)
{
  m_resourcesDir = my::AddSlashIfNeeded(path);
}

unsigned Platform::CpuCores() const
{
  unsigned const cores = thread::hardware_concurrency();
  return cores > 0 ? cores : 1;
}

string DebugPrint(Platform::EError err)
{
  switch (err)
  {
  case Platform::ERR_OK: return "Ok";
  case Platform::ERR_FILE_DOES_NOT_EXIST: return "File does not exist.";
  case Platform::ERR_ACCESS_FAILED: return "Access failed.";
  case Platform::ERR_DIRECTORY_NOT_EMPTY: return "Directory not empty.";
  case Platform::ERR_FILE_ALREADY_EXISTS: return "File already exists.";
  case Platform::ERR_NAME_TOO_LONG:
    return "The length of a component of path exceeds {NAME_MAX} characters.";
  case Platform::ERR_NOT_A_DIRECTORY:
    return "A component of the path prefix of Path is not a directory.";
  case Platform::ERR_SYMLINK_LOOP:
    return "Too many symbolic links were encountered in translating path.";
  case Platform::ERR_IO_ERROR: return "An I/O error occurred.";
  case Platform::ERR_UNKNOWN: return "Unknown";
  }
}

string DebugPrint(Platform::ChargingStatus status)
{
  switch (status)
  {
  case Platform::ChargingStatus::Unknown: return "Unknown";
  case Platform::ChargingStatus::Plugged: return "Plugged";
  case Platform::ChargingStatus::Unplugged: return "Unplugged";
  }
}


text:
package org.asynchttpclient.async;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.fail;

import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.AsyncHttpClientConfig;
import org.asynchttpclient.AsyncHttpClientConfigDefaults;
import org.asynchttpclient.ProxyServer;
import org.asynchttpclient.Response;
import org.asynchttpclient.util.AsyncPropertiesHelper;
import org.asynchttpclient.util.ProxyUtils;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.testng.annotations.Test;

/**
 * Proxy usage tests.
 *
 * @author Hubert Iwaniuk
 */
public abstract class ProxyTest extends AbstractBasicTest {
    private class ProxyHandler extends AbstractHandler {
        public void handle(String s, Request r, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
            if ("GET".equalsIgnoreCase(request.getMethod())) {
                response.addHeader("target", r.getUri().getPath());
                response.setStatus(HttpServletResponse.SC_OK);
            } else {
                // this handler is to handle POST request
                response.sendError(HttpServletResponse.SC_FORBIDDEN);
            }
            r.setHandled(true);
        }
    }

    @Override
    public AbstractHandler configureHandler() throws Exception {
        return new ProxyHandler();
    }

    @Test(groups = { "standalone", "default_provider" })
    public void testRequestLevelProxy() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        try (AsyncHttpClient client = getAsyncHttpClient(null)) {
            String target = "http://127.0.0.1:1234/";
            Future<Response> f = client.prepareGet(target).setProxyServer(new ProxyServer("127.0.0.1", port1)).execute();
            Response resp = f.get(3, TimeUnit.SECONDS);
            assertNotNull(resp);
            assertEquals(resp.getStatusCode(), HttpServletResponse.SC_OK);
            assertEquals(resp.getHeader("target"), "/");
        }
    }

    @Test(groups = { "standalone", "default_provider" })
    public void testGlobalProxy() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        AsyncHttpClientConfig cfg = new AsyncHttpClientConfig.Builder().setProxyServer(new ProxyServer("127.0.0.1", port1)).build();
        try (AsyncHttpClient client = getAsyncHttpClient(cfg)) {
            String target = "http://127.0.0.1:1234/";
            Future<Response> f = client.prepareGet(target).execute();
            Response resp = f.get(3, TimeUnit.SECONDS);
            assertNotNull(resp);
            assertEquals(resp.getStatusCode(), HttpServletResponse.SC_OK);
            assertEquals(resp.getHeader("target"), "/");
        }
    }

    @Test(groups = { "standalone", "default_provider" })
    public void testBothProxies() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        AsyncHttpClientConfig cfg = new AsyncHttpClientConfig.Builder().setProxyServer(new ProxyServer("127.0.0.1", port1 - 1)).build();
        try (AsyncHttpClient client = getAsyncHttpClient(cfg)) {
            String target = "http://127.0.0.1:1234/";
            Future<Response> f = client.prepareGet(target).setProxyServer(new ProxyServer("127.0.0.1", port1)).execute();
            Response resp = f.get(3, TimeUnit.SECONDS);
            assertNotNull(resp);
            assertEquals(resp.getStatusCode(), HttpServletResponse.SC_OK);
            assertEquals(resp.getHeader("target"), "/");
        }
    }

    @Test(groups = { "standalone", "default_provider" })
    public void testNonProxyHosts() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        AsyncHttpClientConfig cfg = new AsyncHttpClientConfig.Builder().setProxyServer(new ProxyServer("127.0.0.1", port1 - 1)).build();
        try (AsyncHttpClient client = getAsyncHttpClient(cfg)) {
            String target = "http://127.0.0.1:1234/";
            client.prepareGet(target).setProxyServer(new ProxyServer("127.0.0.1", port1).addNonProxyHost("127.0.0.1")).execute().get();
            assertFalse(true);
        } catch (Throwable e) {
            assertNotNull(e.getCause());
            assertEquals(e.getCause().getClass(), ConnectException.class);
        }
    }

    @Test(groups = { "standalone", "default_provider" })
    public void testNonProxyHostIssue202() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        try (AsyncHttpClient client = getAsyncHttpClient(null)) {
            String target = "http://127.0.0.1:" + port1 + "/";
            Future<Response> f = client.prepareGet(target).setProxyServer(new ProxyServer("127.0.0.1", port1 - 1).addNonProxyHost("127.0.0.1")).execute();
            Response resp = f.get(3, TimeUnit.SECONDS);
            assertNotNull(resp);
            assertEquals(resp.getStatusCode(), HttpServletResponse.SC_OK);
            assertEquals(resp.getHeader("target"), "/");
        }
    }

    @Test(groups = { "standalone", "default_provider" })
    public void runSequentiallyBecauseNotThreadSafe() throws Exception {
        testProxyProperties();
        testIgnoreProxyPropertiesByDefault();
        testProxyActivationProperty();
        testWildcardNonProxyHosts();
        testUseProxySelector();
    }

    // @Test(groups = { "standalone", "default_provider" })
    public void testProxyProperties() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        // FIXME not threadsafe!
        Properties originalProps = new Properties();
        originalProps.putAll(System.getProperties());
        System.setProperty(ProxyUtils.PROXY_HOST, "127.0.0.1");
        System.setProperty(ProxyUtils.PROXY_PORT, String.valueOf(port1));
        System.setProperty(ProxyUtils.PROXY_NONPROXYHOSTS, "localhost");
        AsyncPropertiesHelper.reloadProperties();

        AsyncHttpClientConfig cfg = new AsyncHttpClientConfig.Builder().setUseProxyProperties(true).build();

        try (AsyncHttpClient client = getAsyncHttpClient(cfg)) {
            String target = "http://127.0.0.1:1234/";
            Future<Response> f = client.prepareGet(target).execute();
            Response resp = f.get(3, TimeUnit.SECONDS);
            assertNotNull(resp);
            assertEquals(resp.getStatusCode(), HttpServletResponse.SC_OK);
            assertEquals(resp.getHeader("target"), "/");

            target = "http://localhost:1234/";
            f = client.prepareGet(target).execute();
            try {
                resp = f.get(3, TimeUnit.SECONDS);
                fail("should not be able to connect");
            } catch (ExecutionException e) {
                // ok, no proxy used
            }
        } finally {
            System.setProperties(originalProps);
        }
    }

    // @Test(groups = { "standalone", "default_provider" })
    public void testIgnoreProxyPropertiesByDefault() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        // FIXME not threadsafe!
        Properties originalProps = new Properties();
        originalProps.putAll(System.getProperties());
        System.setProperty(ProxyUtils.PROXY_HOST, "127.0.0.1");
        System.setProperty(ProxyUtils.PROXY_PORT, String.valueOf(port1));
        System.setProperty(ProxyUtils.PROXY_NONPROXYHOSTS, "localhost");
        AsyncPropertiesHelper.reloadProperties();

        try (AsyncHttpClient client = getAsyncHttpClient(null)) {
            String target = "http://127.0.0.1:1234/";
            Future<Response> f = client.prepareGet(target).execute();
            try {
                f.get(3, TimeUnit.SECONDS);
                fail("should not be able to connect");
            } catch (ExecutionException e) {
                // ok, no proxy used
            }
        } finally {
            System.setProperties(originalProps);
        }
    }

    // @Test(groups = { "standalone", "default_provider" })
    public void testProxyActivationProperty() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        // FIXME not threadsafe!
        Properties originalProps = new Properties();
        originalProps.putAll(System.getProperties());
        System.setProperty(ProxyUtils.PROXY_HOST, "127.0.0.1");
        System.setProperty(ProxyUtils.PROXY_PORT, String.valueOf(port1));
        System.setProperty(ProxyUtils.PROXY_NONPROXYHOSTS, "localhost");
        System.setProperty(AsyncHttpClientConfigDefaults.ASYNC_CLIENT + "useProxyProperties", "true");
        AsyncPropertiesHelper.reloadProperties();

        try (AsyncHttpClient client = getAsyncHttpClient(null)) {
            String target = "http://127.0.0.1:1234/";
            Future<Response> f = client.prepareGet(target).execute();
            Response resp = f.get(3, TimeUnit.SECONDS);
            assertNotNull(resp);
            assertEquals(resp.getStatusCode(), HttpServletResponse.SC_OK);
            assertEquals(resp.getHeader("target"), "/");

            target = "http://localhost:1234/";
            f = client.prepareGet(target).execute();
            try {
                resp = f.get(3, TimeUnit.SECONDS);
                fail("should not be able to connect");
            } catch (ExecutionException e) {
                // ok, no proxy used
            }
        } finally {
            System.setProperties(originalProps);
        }
    }

    // @Test(groups = { "standalone", "default_provider" })
    public void testWildcardNonProxyHosts() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        // FIXME not threadsafe!
        Properties originalProps = new Properties();
        originalProps.putAll(System.getProperties());
        System.setProperty(ProxyUtils.PROXY_HOST, "127.0.0.1");
        System.setProperty(ProxyUtils.PROXY_PORT, String.valueOf(port1));
        System.setProperty(ProxyUtils.PROXY_NONPROXYHOSTS, "127.*");
        AsyncPropertiesHelper.reloadProperties();

        AsyncHttpClientConfig cfg = new AsyncHttpClientConfig.Builder().setUseProxyProperties(true).build();
        try (AsyncHttpClient client = getAsyncHttpClient(cfg)) {
            String target = "http://127.0.0.1:1234/";
            Future<Response> f = client.prepareGet(target).execute();
            try {
                f.get(3, TimeUnit.SECONDS);
                fail("should not be able to connect");
            } catch (ExecutionException e) {
                // ok, no proxy used
            }
        } finally {
            System.setProperties(originalProps);
        }
    }

    // @Test(groups = { "standalone", "default_provider" })
    public void testUseProxySelector() throws IOException, ExecutionException, TimeoutException, InterruptedException {
        ProxySelector originalProxySelector = ProxySelector.getDefault();
            ProxySelector.setDefault(new ProxySelector() {
                public List<Proxy> select(URI uri) {
                    if (uri.getHost().equals("127.0.0.1")) {
                        return Arrays.asList(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", port1)));
                    } else {
                        return Arrays.asList(Proxy.NO_PROXY);
                    }
                }

                public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
                }
            });

        AsyncHttpClientConfig cfg = new AsyncHttpClientConfig.Builder().setUseProxySelector(true).build();
        try (AsyncHttpClient client = getAsyncHttpClient(cfg)) {
            String target = "http://127.0.0.1:1234/";
            Future<Response> f = client.prepareGet(target).execute();
            Response resp = f.get(3, TimeUnit.SECONDS);
            assertNotNull(resp);
            assertEquals(resp.getStatusCode(), HttpServletResponse.SC_OK);
            assertEquals(resp.getHeader("target"), "/");

            target = "http://localhost:1234/";
            f = client.prepareGet(target).execute();
            try {
                f.get(3, TimeUnit.SECONDS);
                fail("should not be able to connect");
            } catch (ExecutionException e) {
                // ok, no proxy used
            }
        } finally {
            // FIXME not threadsafe
            ProxySelector.setDefault(originalProxySelector);
        }
    }
}


text:
.class public Lcom/google/ads/r;
.super Ljava/lang/Object;
.source "SourceFile"

# interfaces
.implements Lcom/google/ads/n;

# direct methods
.method public constructor <init>()V
    .registers 1

    .prologue
    .line 19
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

# virtual methods
.method public a(Lcom/google/ads/internal/d;Ljava/util/HashMap;Landroid/webkit/WebView;)V
    .registers 5
    .parameter
    .parameter
    .parameter
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "(",
            "Lcom/google/ads/internal/d;",
            "Ljava/util/HashMap",
            "<",
            "Ljava/lang/String;",
            "Ljava/lang/String;",
            ">;",
            "Landroid/webkit/WebView;",
            ")V"
        }
    .end annotation

    .prologue
    .line 28
    instance-of v0, p3, Lcom/google/ads/internal/AdWebView;

    if-eqz v0, :cond_a

    .line 29
    check-cast p3, Lcom/google/ads/internal/AdWebView;

    .line 30
    invoke-virtual {p3}, Lcom/google/ads/internal/AdWebView;->a()V

    .line 34
    :goto_9
    return-void

    .line 32
    :cond_a
    const-string v0, "Trying to close WebView that isn\'t an AdWebView"

    invoke-static {v0}, Lcom/google/ads/util/b;->b(Ljava/lang/String;)V

    goto :goto_9
.end method


text:
```
npm install
```

### Compiles and hot-reloads for development
```
npm run serve
```

### Compiles and minifies for production
```
npm run build
```

### Lints and fixes files
```
npm run lint
```

### Run your unit tests
```
npm run test:unit
```


text:
namespace sober {
namespace network {
namespace http {
namespace response {
namespace attribute {

std::ostream& operator<< (std::ostream& stream, StatusCode status_code) {
  switch (status_code) {
    case StatusCode::CONTINUE:
      stream << "Continue";
      break;
    case StatusCode::SWITCHING_PROTOCOLS:
      stream << "Switching Protocols";
      break;
    case StatusCode::PROCESSING:
      stream << "Processing";
      break;
    case StatusCode::OK:
      stream << "OK";
      break;
    case StatusCode::CREATED:
      stream << "Created";
      break;
    case StatusCode::ACCEPTED:
      stream << "Accepted";
      break;
    case StatusCode::NON_AUTHORITATIVE_INFORMATION:
      stream << "Non-Authoritative Information";
      break;
    case StatusCode::NO_CONTENT:
      stream << "No Content";
      break;
    case StatusCode::RESET_CONTENT:
      stream << "Reset Content";
      break;
    case StatusCode::PARTIAL_CONTENT:
      stream << "Partial Content";
      break;
    case StatusCode::MULTI_STATUS:
      stream << "Multi-Status";
      break;
    case StatusCode::ALREADY_REPORTED:
      stream << "Already Reported";
      break;
    case StatusCode::IM_USED:
      stream << "IM Used";
      break;
    case StatusCode::MULTIPLE_CHOICES:
      stream << "Multiple Choices";
      break;
    case StatusCode::MOVED_PERMANENTLY:
      stream << "Moved Permanently";
      break;
    case StatusCode::FOUND:
      stream << "Found";
      break;
    case StatusCode::SEE_OTHER:
      stream << "See Other";
      break;
    case StatusCode::NOT_MODIFIED:
      stream << "Not Modified";
      break;
    case StatusCode::USE_PROXY:
      stream << "Use Proxy";
      break;
    case StatusCode::SWITCH_PROXY:
      stream << "Switch Proxy";
      break;
    case StatusCode::TEMPORARY_REDIRECT:
      stream << "Temporary Redirect";
      break;
    case StatusCode::PERMANENT_REDIRECT:
      stream << "Permanent Redirect";
      break;
    case StatusCode::BAD_REQUEST:
      stream << "Bad Request";
      break;
    case StatusCode::UNAUTHORIZED:
      stream << "Unauthorized";
      break;
    case StatusCode::PAYMENT_REQUIRED:
      stream << "Payment Required";
      break;
    case StatusCode::FORBIDDEN:
      stream << "Forbidden";
      break;
    case StatusCode::NOT_FOUND:
      stream << "Not Found";
      break;
    case StatusCode::METHOD_NOT_ALLOWED:
      stream << "Method Not Allowed";
      break;
    case StatusCode::NOT_ACCEPTABLE:
      stream << "Not Acceptable";
      break;
    case StatusCode::PROXY_AUTHENTICATION_REQUIRED:
      stream << "Proxy Authentication Required";
      break;
    case StatusCode::REQUEST_TIME_OUT:
      stream << "Request Time-out";
      break;
    case StatusCode::CONFLICT:
      stream << "Conflict";
      break;
    case StatusCode::GONE:
      stream << "Gone";
      break;
    case StatusCode::LENGTH_REQUIRED:
      stream << "Length Required";
      break;
    case StatusCode::PRECONDITION_FAILED:
      stream << "Precondition Failed";
      break;
    case StatusCode::REQUEST_ENTITY_TOO_LARGE:
      stream << "Request Entity Too Large";
      break;
    case StatusCode::REQUEST_URI_TOO_LARGE:
      stream << "Request-URI Too Large";
      break;
    case StatusCode::UNSUPPORTED_MEDIA_TYPE:
      stream << "Unsupported Media Type";
      break;
    case StatusCode::REQUESTED_RANGE_NOT_SATISFIABLE:
      stream << "Requested range not satisfiable";
      break;
    case StatusCode::EXPECTATION_FAILED:
      stream << "Expectation Failed";
      break;
    case StatusCode::IM_A_TEAPOT:
      stream << "I'm a teapot (:";
      break;
    case StatusCode::AUTHENTICATION_TIMEOUT:
      stream << "Authentication Timeout";
      break;
    case StatusCode::METHOD_FAILURE:
      static_assert(
          StatusCode::METHOD_FAILURE == StatusCode::ENHANCE_YOUR_CALM,
          "Please, fix operator<< method"
      );
      stream << "Method Failure/Enhance Your Calm";
      break;
    case StatusCode::UNPROCESSABLE_ENTITY:
      stream << "Unprocessable Entity";
      break;
    case StatusCode::LOCKED:
      stream << "Locked";
      break;
    case StatusCode::FAILED_DEPENDENCY:
      stream << "Failed Dependency";
      break;
    case StatusCode::UNORDERED_COLLECTION:
      stream << "Unordered Collection";
      break;
    case StatusCode::UPGRADE_REQUIRED:
      stream << "Upgrade Required";
      break;
    case StatusCode::PRECONDITION_REQUIRED:
      stream << "Precondition Required";
      break;
    case StatusCode::TOO_MANY_REQUESTS:
      stream << "Too Many Requests";
      break;
    case StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE:
      stream << "Request Header Fields Too Large";
      break;
    case StatusCode::LOGIN_TIMEOUT:
      stream << "Login Timeout";
      break;
    case StatusCode::NO_RESPONSE:
      stream << "No response";
      break;
    case StatusCode::RETRY_WITH:
      stream << "Retry With";
      break;
    case StatusCode::BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS:
      stream << "Blocked by Windows Parental Control";
      break;
    case StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS:
      static_assert(
          StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS == StatusCode::REDIRECT,
          "Please, fix operator<< method"
      );
      stream << "Unavailable For Legal Reasons/Redirect";
      break;
    case StatusCode::REQUEST_HEADER_TOO_LARGE:
      stream << "Request Header Too Large";
      break;
    case StatusCode::CERT_ERROR:
      stream << "Cert Error";
      break;
    case StatusCode::NO_CERT:
      stream << "No Cert";
      break;
    case StatusCode::HTTP_TO_HTTPS:
      stream << "HTTP to HTTPS";
      break;
    case StatusCode::CLIENT_CLOSED_REQUEST:
      stream << "Client Closed Request";
      break;
    case StatusCode::INTERNAL_SERVER_ERROR:
      stream << "Internal Server Error";
      break;
    case StatusCode::NOT_IMPLEMENTED:
      stream << "Not Implemented";
      break;
    case StatusCode::BAD_GATEWAY:
      stream << "Bad Gateway";
      break;
    case StatusCode::SERVICE_UNAVAILABLE:
      stream << "Service Unavailable";
      break;
    case StatusCode::GATEWAY_TIME_OUT:
      stream << "Gateway Time-out";
      break;
    case StatusCode::HTTP_VERSION_NOT_SUPPORTED:
      stream << "HTTP Version not supported";
      break;
    case StatusCode::VARIANT_ALSO_NEGOTIATES:
      stream << "Variant Also Negotiates";
      break;
    case StatusCode::INSUFFICIENT_STORAGE:
      stream << "Insufficient Storage";
      break;
    case StatusCode::LOOP_DETECTED:
      stream << "Loop Detected";
      break;
    case StatusCode::BANDWIDTH_LIMIT_EXCEEDED:
      stream << "Bandwidth Limit Exceeded";
      break;
    case StatusCode::NOT_EXTENDED:
      stream << "Not Extended";
      break;
    case StatusCode::NETWORK_AUTHENTICATION_REQUIRED:
      stream << "Network Authentication Required";
      break;
    case StatusCode::ORIGIN_ERROR:
      stream << "Origin Error";
      break;
    case StatusCode::WEB_SERVER_IS_DOWN:
      stream << "Web server is down";
      break;
    case StatusCode::CONNECTION_TIMED_OUT:
      stream << "Connection timed out";
      break;
    case StatusCode::PROXY_DECLINED_REQUEST:
      stream << "Proxy Declined Request";
      break;
    case StatusCode::A_TIMEOUT_OCCURRED:
      stream << "A timeout occurred";
      break;
    case StatusCode::NETWORK_READ_TIMEOUT_ERROR:
      stream << "Network read timeout error";
      break;
    case StatusCode::NETWORK_CONNECT_TIMEOUT_ERROR:
      stream << "Network connect timeout error";
      break;
#include <leathers/push>
#include <leathers/unreachable-code>
    default:
      stream << "!UNKNOWN!";
      break;
#include <leathers/pop>
  }
  stream << "(" << static_cast<int>(status_code) << ")";
  return stream;
}

} // namespace attribute
} // namespace response
} // namespace http
} // namespace network
} // namespace sober


text:
const path = require('path');
const webpack = require('webpack');
const pkg = require('./package.json');

const joinRoot = path.join.bind(path, __dirname);

module.exports = {
  entry: joinRoot('src/index.ts'),
  resolve: {
    extensions: ['.js', '.ts', '.css'],
  },
  output: {
    path: joinRoot('dist/'),
    filename: 'tweet2gif.user.js',
  },
  module: {
    rules: [{
      test: /\.ts$/,
      use: [ 'ts-loader' ],
      include: [
        joinRoot('src'),
      ],
    }],
  },
  plugins: [
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.optimize.UglifyJsPlugin(),
    new webpack.BannerPlugin({
      raw: true,
      banner:
`// ==UserScript==
// @name         tweet2gif
// @namespace    http://tampermonkey.net/
// @version      ${pkg.version}
// @description  ${pkg.description}
// @author       ${pkg.author}
// @match        https://twitter.com/**
// @grant        none
// @run-at       document-end
// @noframes
// ==/UserScript==
`
    })
  ],
}


text:
class Tile
	attr_reader :tileset
	attr_reader :bitmap
	attr_reader :x, :y

	def initialize(tileset, bitmap, x, y)
		@tileset = tileset
		@bitmap = bitmap
		@x = x
		@y = y
	end
end