<commit_before>function highlightSkillsTableRows(skillsSections) {
	if (skillsSections) {
		var length = skillsSections.length;
		for (var i = 1; i < length ; i+=2) {
			skillsSections[i].className = "highlighted";
		}
	}
}

function countMonths(from, to) {
	if (!(!!from && !!to)) {
		return "";
	}

	var dateFrom = new Date(from);
	var dateTo = new Date(to);

	if (dateFrom == "Invalid Date" && to == "Invalid Date") {
		return "";
	}

	var yearDiff = dateTo.getFullYear() - dateFrom.getFullYear();
	var monthDiff = dateTo.getMonth() - dateFrom.getMonth();
	if (monthDiff < 0) {
		yearDiff--;
		monthDiff += 12;
	}

	var yearPart = getFormatedPart(yearDiff, "year");
	var monthPart = getFormatedPart(monthDiff, "month");
	var text;
	if (yearPart.length > 0 && monthPart.length > 0) {
		text = "(" + yearPart + " and " + monthPart + ")";
	} else if (yearPart.length > 0 || monthPart.length > 0) {
		text = "(" + yearPart + monthPart + ")";
	} else {
		text = "";
	}
	return text;
}

function getFormatedPart(number, type) {
	switch (number) {
		case 0:
			return "";
		case 1:
			return "1 " + type;
		default:
			return number + " " + type +"s";
	}
}<commit_msg>Non-breaking space between number and year/month in formatter<commit_after>function highlightSkillsTableRows(skillsSections) {
	if (skillsSections) {
		var length = skillsSections.length;
		for (var i = 1; i < length ; i+=2) {
			skillsSections[i].className = "highlighted";
		}
	}
}

function countMonths(from, to) {
	if (!(!!from && !!to)) {
		return "";
	}

	var dateFrom = new Date(from);
	var dateTo = new Date(to);

	if (dateFrom == "Invalid Date" && to == "Invalid Date") {
		return "";
	}

	var yearDiff = dateTo.getFullYear() - dateFrom.getFullYear();
	var monthDiff = dateTo.getMonth() - dateFrom.getMonth();
	if (monthDiff < 0) {
		yearDiff--;
		monthDiff += 12;
	}

	var yearPart = getFormatedPart(yearDiff, "year");
	var monthPart = getFormatedPart(monthDiff, "month");
	var text;
	if (yearPart.length > 0 && monthPart.length > 0) {
		text = "(" + yearPart + " and " + monthPart + ")";
	} else if (yearPart.length > 0 || monthPart.length > 0) {
		text = "(" + yearPart + monthPart + ")";
	} else {
		text = "";
	}
	return text;
}

function getFormatedPart(number, type) {
	switch (number) {
		case 0:
			return "";
		case 1:
			return "1 " + type;
		default:
			return number + " " + type +"s";
	}
}<|endoftext|>


<commit_before>const riotcontrol = require('riotcontrol');

const router = function() {

    let script = document.createElement('script');

    // function addBundle(route) {
    //     if (route) {
    //         script.src = 'build/Page.js'
    //     } else {
    //         script.src = 'build/Index.js'
    //     }
    //     document.body.appendChild(script);
    // }

    function onRoute(route, id, action) {
        riotcontrol.trigger('ROUTE', route);
        // addBundle(route);
    }

    riot.route(onRoute);
    riot.route.base('/#');
    riot.route.stop();
    riot.route.start(true);
};

module.exports = router();
<commit_msg>Send route to Google Analytics<commit_after>const riotcontrol = require('riotcontrol');

function Router() {

    function setPageToTrack(route, subroute) {
        let page = '/';
        page += route ? (subroute ? route + '/' + subroute : route) : 'index';

        if (ga) {
            ga('set', 'page', page);
            ga('send', 'pageview');
        }
    }

    function onRoute(route, subroute) {
        riotcontrol.trigger('ROUTE', route);
        setPageToTrack(route, subroute);
    }

    riot.route(onRoute);
    riot.route.base('/#');
    riot.route.stop();
    riot.route.start(true);
};

module.exports = Router();
<|endoftext|>


<commit_before>$(document).ready(function() {
    "use strict";
    // --------------Newsletter-----------------------

    $(".newsletter-signup").ajaxChimp({
        callback: mailchimpResponse,
        url: "//learningwellness.us8.list-manage.com/subscribe/post?u=b9328d99f806177af525f7cde&id=289ade4d78" // Replace your mailchimp post url inside double quote "".
    });

    function mailchimpResponse(resp) {
        if(resp.result === 'success') {

            $('.alert-success').html(resp.msg).fadeIn().delay(3000).fadeOut();

        } else if(resp.result === 'error') {
            $('.alert-warning').html(resp.msg).fadeIn().delay(3000).fadeOut();
        }
    };
});
<commit_msg>Form integration v0.49.10<commit_after>$(document).ready(function() {
    "use strict";
    // --------------Newsletter-----------------------

    $(".newsletter-signup").ajaxChimp({
        callback: mailchimpResponse,
        url: "http://learningwellness.us8.list-manage.com/subscribe/post?u=b9328d99f806177af525f7cde&id=289ade4d78" // Replace your mailchimp post url inside double quote "".
    });

    function mailchimpResponse(resp) {
        if(resp.result === 'success') {

            $('.alert-success').html(resp.msg).fadeIn().delay(3000).fadeOut();

        } else if(resp.result === 'error') {
            $('.alert-warning').html(resp.msg).fadeIn().delay(3000).fadeOut();
        }
    };
});
<|endoftext|>


<commit_before>
/*!--------------------------------*\
   3-Jekyll Theme
   @author Peiwen Lu (P233)
   https://github.com/P233/3-Jekyll
\*---------------------------------*/

// Detect window size, if less than 1280px add class 'mobile' to sidebar therefore it will be auto hide when trigger the pjax request in small screen devices.
if ($(window).width() <= 1280) {
  $('#sidebar').addClass('mobile')
}

// Variables
//    tag1       = $('.pl__all'),
//    tag2       = $('js-label2'),
//    tag3       = $('js-label3'),
//    tag4       = $('js-label4'),
var sidebar    = $('#sidebar'),
    container  = $('#post'),
    content    = $('#pjax'),
    button     = $('#icon-arrow');

// Tags switcher
//var clickHandler = function(k) {
//  return function() {
//    $(this).addClass('active').siblings().removeClass('active');
//    tag1.hide();
//    window['tag'+k].delay(50).fadeIn(350);
//  }
//};
//for (var i = 1; i <= 4; i++) {
//  $('#js-label' + i).on('click', clickHandler(i));
//}
var clickHandler = function(id) {
  return function() {
    $(this).addClass('active').siblings().removeClass('active');  //相当于$('#tags__ul li').removeClass('active');
                                                                  //$(this).addClass('active');
    $('.pl__all').hide();
    $('.' + id).delay(50).fadeIn(350);
  }
};

$('#tags__ul li').each(function(index){
  $('#' + $(this).attr('id')).on('click', clickHandler($(this).attr('id')));
});

// If sidebar has class 'mobile', hide it after clicking.
//tag1.on('click', function() {
//  $(this).addClass('active').siblings().removeClass('active');
//  if (sidebar.hasClass('mobile')) {
//    $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
//  }
//});

$('.pl__all').on('click', function() {
  $(this).addClass('active').siblings().removeClass('active');
  if (sidebar.hasClass('mobile')) {
    $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
  }
});

// Enable fullscreen.
$('#js-fullscreen').on('click', function() {
  if (button.hasClass('fullscreen')) {
    sidebar.removeClass('fullscreen');
    button.removeClass('fullscreen');
    content.delay(300).queue(function(){
      $(this).removeClass('fullscreen').dequeue();
    });
  } else {
    sidebar.addClass('fullscreen');
    button.addClass('fullscreen');
    content.delay(200).queue(function(){
      $(this).addClass('fullscreen').dequeue();
    });
  }
});

$('#mobile-avatar').on('click', function(){
  $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
});

// Pjax
$(document).pjax('#avatar, #mobile-avatar, .pl__all', '#pjax', { fragment: '#pjax', timeout: 10000 });
$(document).on({
  'pjax:click': function() {
    content.removeClass('fadeIn').addClass('fadeOut');
    NProgress.start();
  },
  'pjax:start': function() {
    content.css({'opacity':0});
  },
  'pjax:end': function() {
    NProgress.done();
    container.scrollTop(0);
    content.css({'opacity':1}).removeClass('fadeOut').addClass('fadeIn');
    afterPjax();
  }
});

// Codepen embed js
// http://codepen.io/assets/embed/ei.js
// Added on 17 Nov 2013
var CodePenEmbed={width:"100%",init:function(){this.showCodePenEmbeds(),this.listenToParentPostMessages()},showCodePenEmbeds:function(){var e=document.getElementsByClassName("codepen");for(var t=e.length-1;t>-1;t--){var n=this._getParamsFromAttributes(e[t]);n=this._convertOldDataAttributesToNewDataAttributes(n);var r=this._buildURL(n),i=this._buildIFrame(n,r);this._addIFrameToPage(e[t],i)}},_getParamsFromAttributes:function(e){var t={},n=e.attributes;for(var r=0,i=n.length;r<i;r++)name=n[r].name,name.indexOf("data-")===0&&(t[name.replace("data-","")]=n[r].value);return t},_convertOldDataAttributesToNewDataAttributes:function(e){return e.href&&(e["slug-hash"]=e.href),e.type&&(e["default-tab"]=e.type),e.safe&&(e["safe"]=="true"?e.animations="run":e.animations="stop-after-5"),e},_buildURL:function(e){var t=this._getHost(e),n=e.user?e.user:"anon",r="?"+this._getGetParams(e),i=[t,n,"embed",e["slug-hash"]+r].join("/");return i.replace(/\/\//g,"//")},_getHost:function(e){return e.host?e.host:document.location.protocol=="file:"?"http://codepen.io":"//codepen.io"},_getGetParams:function(e){var t="",n=0;for(var r in e)t!==""&&(t+="&"),t+=r+"="+encodeURIComponent(e[r]);return t},_buildIFrame:function(e,t){var n={id:"cp_embed_"+e["slug-hash"].replace("/","_"),src:t,scrolling:"no",frameborder:"0",height:this._getHeight(e),allowTransparency:"true","class":"cp_embed_iframe",style:"width: "+this.width+"; overflow: hidden;"},r="",r},_getHeight:function(e){return e.height?e["height"]=="auto"?300:e.height:300},_addIFrameToPage:function(e,t){if(e.parentNode){var n=document.createElement("div");n.innerHTML=t,e.parentNode.replaceChild(n,e)}else e.innerHTML=t},listenToParentPostMessages:function(){var eventMethod=window.addEventListener?"addEventListener":"attachEvent",eventListener=window[eventMethod],messageEvent=eventMethod=="attachEvent"?"onmessage":"message";eventListener(messageEvent,function(e){try{var dataObj=eval("("+e.data+")"),iframe=document.getElementById("cp_embed_"+dataObj.hash);iframe&&(iframe.height=dataObj.height)}catch(err){}},!1)}};

// Re-run scripts for post content after pjax
function afterPjax() {
  // Open links in new tab
  $('#post__content a').attr('target','_blank');

  // Embed codepen after pjax
  CodePenEmbed.init();

  // Generate post TOC for h1 h2 and h3
  var toc = $('#post__toc-ul');
  // Empty TOC and generate an entry for h1
  toc.empty().append('
' + $('#post__title').text() + '
');

  // Generate entries for h2 and h3
  $('#post__content').children('h2,h3').each(function() {
    // Generate random ID for each heading
    $(this).attr('id', function() {
      var ID = "",
          alphabet = "abcdefghijklmnopqrstuvwxyz";

      for(var i=0; i < 5; i++) {
        ID += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
      }
      return ID;
    });

    if ($(this).prop("tagName") == 'H2') {
      toc.append('
' + $(this).text() + '
');
    } else {
      toc.append('
' + $(this).text() + '
');
    }
  });

  // Smooth scrolling
  $('.js-anchor-link').on('click', function() {
    var target = $(this.hash);
    container.animate({scrollTop: target.offset().top + container.scrollTop() }, 500, function() {
      target.addClass('flash').delay(0).queue(function() {
        $(this).removeClass('flash').dequeue();
      });
    });
  });

  // Lazy Loading Disqus
  // http://jsfiddle.net/dragoncrew/SHGwe/1/
  var ds_loaded = false,
      top = $('#disqus_thread').offset().top;
      //identifier = $('#post__title').data('identifier');
  window.disqus_shortname = $('#disqus_thread').attr('name');
  //window.disqus_shortname = 'coffeechou';
  //window.disqus_identifier = identifier;

  function check() {
    if ( !ds_loaded && container.scrollTop() + container.height() > top ) {
      $.ajax({
        type: 'GET',
        url: 'http://' + disqus_shortname + '.disqus.com/embed.js',
        dataType: 'script',
        cache: true
      });
      ds_loaded = true;
    }
  }check();
  container.scroll(check);
}afterPjax();

!function() {
  function o(w, v, i) {
    return w.getAttribute(v) || i
  }
  function j(i) {
    return document.getElementsByTagName(i)
  }
  function l() {
    var i = j("script")
    , w = i.length
    , v = i[w - 1];
    return {
      l: w,
      z: o(v, "zIndex", -1),
      o: o(v, "opacity", 1),
      c: o(v, "color", "255,255,153"),
      n: o(v, "count", 49)
    }
  }
  function k() {
    r = u.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
    n = u.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
  }
  function b() {
    e.clearRect(0, 0, r, n);
    var w = [f].concat(t);
    var x, v, A, B, z, y;
    t.forEach(function(i) {
      i.x += i.xa,
      i.y += i.ya,
      i.xa *= i.x > r || i.x < 0 ? -1 : 1,
      i.ya *= i.y > n || i.y < 0 ? -1 : 1,
      e.fillRect(i.x - 0.5, i.y - 0.5, 1, 1);
      for (v = 0; v < w.length; v++) {
        x = w[v];
        if (i !== x && null !== x.x && null !== x.y) {
          B = i.x - x.x,
          z = i.y - x.y,
          y = B * B + z * z;
          y < x.max && (x === f && y >= x.max / 2 && (i.x -= 0.03 * B,
            i.y -= 0.03 * z),
          A = (x.max - y) / x.max,
          e.beginPath(),
          e.lineWidth = A / 2,
          e.strokeStyle = "rgba(" + s.c + "," + (A + 0.2) + ")",
          e.moveTo(i.x, i.y),
          e.lineTo(x.x, x.y),
          e.stroke())
        }
      }
      w.splice(w.indexOf(i), 1)
    }),
    m(b)
  }
  var u = document.createElement("canvas"), s = l(), c = "c_n" + s.l, e = u.getContext("2d"), r, n, m = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(i) {
    window.setTimeout(i, 1000 / 45)
  }
  , a = Math.random, f = {
    x: null,
    y: null,
    max: 20000
  };
  u.id = c;
  u.style.cssText = "position:fixed;top:0;left:0;z-index:" + s.z + ";opacity:" + s.o;
  j("body")[0].appendChild(u);
  k(),
  window.onresize = k;
  window.onmousemove = function(i) {
    i = i || window.event,
    f.x = i.clientX,
    f.y = i.clientY
  }
  ,
  window.onmouseout = function() {
    f.x = null,
    f.y = null
  }
  ;
  for (var t = [], p = 0; s.n > p; p++) {
    var h = a() * r
    , g = a() * n
    , q = 2 * a() - 1
    , d = 2 * a() - 1;
    t.push({
      x: h,
      y: g,
      xa: q,
      ya: d,
      max: 6000
    })
  }
  setTimeout(function() {
    b()
  }, 100)
}();

<commit_msg>embed.js<commit_after>
/*!--------------------------------*\
   3-Jekyll Theme
   @author Peiwen Lu (P233)
   https://github.com/P233/3-Jekyll
\*---------------------------------*/

// Detect window size, if less than 1280px add class 'mobile' to sidebar therefore it will be auto hide when trigger the pjax request in small screen devices.
if ($(window).width() <= 1280) {
  $('#sidebar').addClass('mobile')
}

// Variables
//    tag1       = $('.pl__all'),
//    tag2       = $('js-label2'),
//    tag3       = $('js-label3'),
//    tag4       = $('js-label4'),
var sidebar    = $('#sidebar'),
    container  = $('#post'),
    content    = $('#pjax'),
    button     = $('#icon-arrow');

// Tags switcher
//var clickHandler = function(k) {
//  return function() {
//    $(this).addClass('active').siblings().removeClass('active');
//    tag1.hide();
//    window['tag'+k].delay(50).fadeIn(350);
//  }
//};
//for (var i = 1; i <= 4; i++) {
//  $('#js-label' + i).on('click', clickHandler(i));
//}
var clickHandler = function(id) {
  return function() {
    $(this).addClass('active').siblings().removeClass('active');  //相当于$('#tags__ul li').removeClass('active');
                                                                  //$(this).addClass('active');
    $('.pl__all').hide();
    $('.' + id).delay(50).fadeIn(350);
  }
};

$('#tags__ul li').each(function(index){
  $('#' + $(this).attr('id')).on('click', clickHandler($(this).attr('id')));
});

// If sidebar has class 'mobile', hide it after clicking.
//tag1.on('click', function() {
//  $(this).addClass('active').siblings().removeClass('active');
//  if (sidebar.hasClass('mobile')) {
//    $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
//  }
//});

$('.pl__all').on('click', function() {
  $(this).addClass('active').siblings().removeClass('active');
  if (sidebar.hasClass('mobile')) {
    $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
  }
});

// Enable fullscreen.
$('#js-fullscreen').on('click', function() {
  if (button.hasClass('fullscreen')) {
    sidebar.removeClass('fullscreen');
    button.removeClass('fullscreen');
    content.delay(300).queue(function(){
      $(this).removeClass('fullscreen').dequeue();
    });
  } else {
    sidebar.addClass('fullscreen');
    button.addClass('fullscreen');
    content.delay(200).queue(function(){
      $(this).addClass('fullscreen').dequeue();
    });
  }
});

$('#mobile-avatar').on('click', function(){
  $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
});

// Pjax
$(document).pjax('#avatar, #mobile-avatar, .pl__all', '#pjax', { fragment: '#pjax', timeout: 10000 });
$(document).on({
  'pjax:click': function() {
    content.removeClass('fadeIn').addClass('fadeOut');
    NProgress.start();
  },
  'pjax:start': function() {
    content.css({'opacity':0});
  },
  'pjax:end': function() {
    NProgress.done();
    container.scrollTop(0);
    content.css({'opacity':1}).removeClass('fadeOut').addClass('fadeIn');
    afterPjax();
  }
});

// Codepen embed js
// http://codepen.io/assets/embed/ei.js
// Added on 17 Nov 2013
var CodePenEmbed={width:"100%",init:function(){this.showCodePenEmbeds(),this.listenToParentPostMessages()},showCodePenEmbeds:function(){var e=document.getElementsByClassName("codepen");for(var t=e.length-1;t>-1;t--){var n=this._getParamsFromAttributes(e[t]);n=this._convertOldDataAttributesToNewDataAttributes(n);var r=this._buildURL(n),i=this._buildIFrame(n,r);this._addIFrameToPage(e[t],i)}},_getParamsFromAttributes:function(e){var t={},n=e.attributes;for(var r=0,i=n.length;r<i;r++)name=n[r].name,name.indexOf("data-")===0&&(t[name.replace("data-","")]=n[r].value);return t},_convertOldDataAttributesToNewDataAttributes:function(e){return e.href&&(e["slug-hash"]=e.href),e.type&&(e["default-tab"]=e.type),e.safe&&(e["safe"]=="true"?e.animations="run":e.animations="stop-after-5"),e},_buildURL:function(e){var t=this._getHost(e),n=e.user?e.user:"anon",r="?"+this._getGetParams(e),i=[t,n,"embed",e["slug-hash"]+r].join("/");return i.replace(/\/\//g,"//")},_getHost:function(e){return e.host?e.host:document.location.protocol=="file:"?"http://codepen.io":"//codepen.io"},_getGetParams:function(e){var t="",n=0;for(var r in e)t!==""&&(t+="&"),t+=r+"="+encodeURIComponent(e[r]);return t},_buildIFrame:function(e,t){var n={id:"cp_embed_"+e["slug-hash"].replace("/","_"),src:t,scrolling:"no",frameborder:"0",height:this._getHeight(e),allowTransparency:"true","class":"cp_embed_iframe",style:"width: "+this.width+"; overflow: hidden;"},r="",r},_getHeight:function(e){return e.height?e["height"]=="auto"?300:e.height:300},_addIFrameToPage:function(e,t){if(e.parentNode){var n=document.createElement("div");n.innerHTML=t,e.parentNode.replaceChild(n,e)}else e.innerHTML=t},listenToParentPostMessages:function(){var eventMethod=window.addEventListener?"addEventListener":"attachEvent",eventListener=window[eventMethod],messageEvent=eventMethod=="attachEvent"?"onmessage":"message";eventListener(messageEvent,function(e){try{var dataObj=eval("("+e.data+")"),iframe=document.getElementById("cp_embed_"+dataObj.hash);iframe&&(iframe.height=dataObj.height)}catch(err){}},!1)}};

// Re-run scripts for post content after pjax
function afterPjax() {
  // Open links in new tab
  $('#post__content a').attr('target','_blank');

  // Embed codepen after pjax
  CodePenEmbed.init();

  // Generate post TOC for h1 h2 and h3
  var toc = $('#post__toc-ul');
  // Empty TOC and generate an entry for h1
  toc.empty().append('
' + $('#post__title').text() + '
');

  // Generate entries for h2 and h3
  $('#post__content').children('h2,h3').each(function() {
    // Generate random ID for each heading
    $(this).attr('id', function() {
      var ID = "",
          alphabet = "abcdefghijklmnopqrstuvwxyz";

      for(var i=0; i < 5; i++) {
        ID += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
      }
      return ID;
    });

    if ($(this).prop("tagName") == 'H2') {
      toc.append('
' + $(this).text() + '
');
    } else {
      toc.append('
' + $(this).text() + '
');
    }
  });

  // Smooth scrolling
  $('.js-anchor-link').on('click', function() {
    var target = $(this.hash);
    container.animate({scrollTop: target.offset().top + container.scrollTop() }, 500, function() {
      target.addClass('flash').delay(0).queue(function() {
        $(this).removeClass('flash').dequeue();
      });
    });
  });

  // Lazy Loading Disqus
  // http://jsfiddle.net/dragoncrew/SHGwe/1/
  var ds_loaded = false,
      top = $('#disqus_thread').offset().top;
      //identifier = $('#post__title').data('identifier');
  window.disqus_shortname = $('#disqus_thread').attr('name');
  //window.disqus_shortname = 'coffeechou';
  //window.disqus_identifier = identifier;

  // function check() {
  //   if ( !ds_loaded && container.scrollTop() + container.height() > top ) {
  //     $.ajax({
  //       type: 'GET',
  //       url: 'http://' + disqus_shortname + '.disqus.com/embed.js',
  //       dataType: 'script',
  //       cache: true
  //     });
  //     ds_loaded = true;
  //   }
  // }check();
  // container.scroll(check);
}afterPjax();

!function() {
  function o(w, v, i) {
    return w.getAttribute(v) || i
  }
  function j(i) {
    return document.getElementsByTagName(i)
  }
  function l() {
    var i = j("script")
    , w = i.length
    , v = i[w - 1];
    return {
      l: w,
      z: o(v, "zIndex", -1),
      o: o(v, "opacity", 1),
      c: o(v, "color", "255,255,153"),
      n: o(v, "count", 49)
    }
  }
  function k() {
    r = u.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
    n = u.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
  }
  function b() {
    e.clearRect(0, 0, r, n);
    var w = [f].concat(t);
    var x, v, A, B, z, y;
    t.forEach(function(i) {
      i.x += i.xa,
      i.y += i.ya,
      i.xa *= i.x > r || i.x < 0 ? -1 : 1,
      i.ya *= i.y > n || i.y < 0 ? -1 : 1,
      e.fillRect(i.x - 0.5, i.y - 0.5, 1, 1);
      for (v = 0; v < w.length; v++) {
        x = w[v];
        if (i !== x && null !== x.x && null !== x.y) {
          B = i.x - x.x,
          z = i.y - x.y,
          y = B * B + z * z;
          y < x.max && (x === f && y >= x.max / 2 && (i.x -= 0.03 * B,
            i.y -= 0.03 * z),
          A = (x.max - y) / x.max,
          e.beginPath(),
          e.lineWidth = A / 2,
          e.strokeStyle = "rgba(" + s.c + "," + (A + 0.2) + ")",
          e.moveTo(i.x, i.y),
          e.lineTo(x.x, x.y),
          e.stroke())
        }
      }
      w.splice(w.indexOf(i), 1)
    }),
    m(b)
  }
  var u = document.createElement("canvas"), s = l(), c = "c_n" + s.l, e = u.getContext("2d"), r, n, m = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(i) {
    window.setTimeout(i, 1000 / 45)
  }
  , a = Math.random, f = {
    x: null,
    y: null,
    max: 20000
  };
  u.id = c;
  u.style.cssText = "position:fixed;top:0;left:0;z-index:" + s.z + ";opacity:" + s.o;
  j("body")[0].appendChild(u);
  k(),
  window.onresize = k;
  window.onmousemove = function(i) {
    i = i || window.event,
    f.x = i.clientX,
    f.y = i.clientY
  }
  ,
  window.onmouseout = function() {
    f.x = null,
    f.y = null
  }
  ;
  for (var t = [], p = 0; s.n > p; p++) {
    var h = a() * r
    , g = a() * n
    , q = 2 * a() - 1
    , d = 2 * a() - 1;
    t.push({
      x: h,
      y: g,
      xa: q,
      ya: d,
      max: 6000
    })
  }
  setTimeout(function() {
    b()
  }, 100)
}();

<|endoftext|>


<commit_before>!(function() {

	var parseQueryFromURL = function() {

		var searchQuery = window.location.search;
		if (!searchQuery) {
			return null;
		}

		var regex = /[?&]([^=#]+)=([^&#]*)/g,
			params = {},
			match;
		while (match = regex.exec(searchQuery)) {
			params[match[1]] = match[2];
		}

		if (!params.hasOwnProperty("query")) {
			return null;
		}

		return decodeURIComponent(params.query);

	};

	var scanPosts = function(posts, properties, query) {

		var results = [];
		posts.forEach(function(post) {
			var textToScan = "",
				regex = new RegExp(query, "ig");

			properties.forEach(function(property) {
				if (post.hasOwnProperty(property)) {
					textToScan += post[property];
				}
			});

			if (regex.test(textToScan)) {
				results.push(post);
			}
		});

		return results;

	};

	var outputResults = function(results, el) {

		var frag = document.createDocumentFragment();
		results.forEach(function(result) {

			var div = document.createElement("div");
			div.className = "search-result";

			var title = document.createElement("h2");
			var link = document.createElement("a");
			link.href = result.link;
			link.innerHTML = result.title;
			title.appendChild(link);

			div.appendChild(title);

			frag.appendChild(div);

		});

		el.appendChild(frag);

	};

	var Search = function(options) {

		options = options || {};

		if (!options.selector) {
			throw new Error("We need a selector to find");
		}

		this.el = document.querySelector(options.selector);
		if (!this.el) {
			throw new Error("We need a HTML element to output to");
		}

		this.posts = JEKYLL_POSTS;
		if (!this.posts) {
			return this.el.innerHTML = this.noResultsMessage;
		}

		var defaultMessage = "No results found";
		this.noResultsMessage = options.noResultsMessage || defaultMessage;

		var defaultProperties = ["title"];
		this.properties = options.properties || defaultProperties;

		this.query = parseQueryFromURL();
		if (!this.query) {
			return this.el.innerHTML = this.noResultsMessage;
		}

		this.results = scanPosts(this.posts, this.properties, this.query);
		if (!this.results.length) {
			return this.el.innerHTML = this.noResultsMessage;
		}

		outputResults(this.results, this.el);

	};

	window.jekyllSearch = Search;

})();
<commit_msg>Add blurb to each post.<commit_after>// Documentation: http://benhowdle.im/creating-a-dynamic-search-page-for-your-jekyll-blog.html

// TODO: Move to autocomplete approach: http://danreev.es/posts/jekyll-search-with-typeahead/

!(function() {

	var parseQueryFromURL = function() {

		var searchQuery = window.location.search;
		if (!searchQuery) {
			return null;
		}

		var regex = /[?&]([^=#]+)=([^&#]*)/g,
			params = {},
			match;
		while (match = regex.exec(searchQuery)) {
			params[match[1]] = match[2];
		}

		if (!params.hasOwnProperty("query")) {
			return null;
		}

		return decodeURIComponent(params.query);

	};

	var scanPosts = function(posts, properties, query) {

		var results = [];
		posts.forEach(function(post) {
			var textToScan = "",
				regex = new RegExp(query, "ig");

			properties.forEach(function(property) {
				if (post.hasOwnProperty(property)) {
					textToScan += post[property];
				}
			});

			if (regex.test(textToScan)) {
				results.push(post);
			}
		});

		return results;

	};

	var outputResults = function(results, el) {

		var frag = document.createDocumentFragment();
		results.forEach(function(result) {

			var div = document.createElement("div");
			div.className = "search-result";

			var title = document.createElement("h2");
			var link = document.createElement("a");
            var excerpt = document.createElement("p");

			link.href = result.link;
			link.innerHTML = result.title;
            excerpt.innerHTML = result.content;
			title.appendChild(link);

			div.appendChild(title);
            div.appendChild(excerpt);

			frag.appendChild(div);

		});

		el.appendChild(frag);

	};

	var Search = function(options) {

		options = options || {};

		if (!options.selector) {
			throw new Error("We need a selector to find");
		}

		this.el = document.querySelector(options.selector);
		if (!this.el) {
			throw new Error("We need a HTML element to output to");
		}

		this.posts = JEKYLL_POSTS;
		if (!this.posts) {
			return this.el.innerHTML = this.noResultsMessage;
		}

		var defaultMessage = "No results found";
		this.noResultsMessage = options.noResultsMessage || defaultMessage;

		var defaultProperties = ["title"];
		this.properties = options.properties || defaultProperties;

		this.query = parseQueryFromURL();
		if (!this.query) {
			return this.el.innerHTML = this.noResultsMessage;
		}

		this.results = scanPosts(this.posts, this.properties, this.query);
		if (!this.results.length) {
			return this.el.innerHTML = this.noResultsMessage;
		}

		outputResults(this.results, this.el);

	};

	window.jekyllSearch = Search;

})();
<|endoftext|>


<commit_before>/** @jsx React.DOM */
var React = require('react'),
    Select;

Select = React.createClass({
    handleOnChange: function(event) {
        var items = this.props.items
        for (var i=0; i<items.length; i++) {
            var item = items[i];
            if (item.name == event.target.value) {
                this.props.onChange(item);
                return;
            }
        }
        this.props.onChange(null);
    },
    selectItem: function(event) {
        this.props.onChange(null);
    },
    render: function () {
        var options = this.props.items.map(function(item) {
            return <option key={item.name} value={item.name}>{item.name}</option>
        });
        var value = "";
        if (this.props.item != null) {
            value = this.props.item.name;
        }
        var content = null;
        if (this.props.item == null) {
            content = <form className="form" role="form">
                        <select id="item" className="form-control" value={value} onChange={this.handleOnChange}>
                          <option value="--">select a {this.props.type}</option>
                          {options}
                        </select>
                      </form>;
        } else {
            content = <button type="button" className="btn btn-default navbar-btn" onClick={this.selectItem}>{this.props.item.name}</button>;
        }
        return content;
    }

});

module.exports = Select;
<commit_msg>Fixed key (name isn't always unique)<commit_after>/** @jsx React.DOM */
var React = require('react'),
    Select;

Select = React.createClass({
    handleOnChange: function(event) {
        var items = this.props.items
        for (var i=0; i<items.length; i++) {
            var item = items[i];
            if (item.name == event.target.value) {
                this.props.onChange(item);
                return;
            }
        }
        this.props.onChange(null);
    },
    selectItem: function(event) {
        this.props.onChange(null);
    },
    render: function () {
        var options = this.props.items.map(function(item) {
            return <option key={item["@id"]} value={item.name}>{item.name}</option>
        });
        var value = "";
        if (this.props.item != null) {
            value = this.props.item.name;
        }
        var content = null;
        if (this.props.item == null) {
            content = <form className="form" role="form">
                        <select id="item" className="form-control" value={value} onChange={this.handleOnChange}>
                          <option value="--">select a {this.props.type}</option>
                          {options}
                        </select>
                      </form>;
        } else {
            content = <button type="button" className="btn btn-default navbar-btn" onClick={this.selectItem}>{this.props.item.name}</button>;
        }
        return content;
    }

});

module.exports = Select;
<|endoftext|>


<commit_before>/*
 * Slurve | slurve.js: Beautiful Slants and Curves in Web UIs
 * MIT license https://opensource.org/licenses/MIT
 * Copyright (c) 2016 Derek Knox | Braindrop Labs
 * Version: 0.9 (beta)
 * @author Derek Knox http://derekknox.com
 */

;(function() {

  /******************************************************************
  API
  ******************************************************************/

  this.slurve = {
    update: update
  };

  /******************************************************************
  Init
  ******************************************************************/

  //cache
  var $slurves;

  //listeners
  this.addEventListener('resize', updateSlurves);

  //init
  window.onload = function() { update(); }
  update();

  /******************************************************************
  Methods
  ******************************************************************/

  function extractPoints($el) {
    var pointValues = $el.attributes['data-slurve'].value.split(' '),
        point,
        points = [];

    for(var i = 0, len = pointValues.length; i < len; i++) {
      point = pointValues[i].split(',');
      points.push({ 'x': +point[0], 'y': +point[1], 'r': +point[2] || 0 });
    }

    return points;
  }

  function getWidth(width, extractedPoints) {
    var totalWidth = 0;

    for(var i = 0, len = extractedPoints.length; i < len; i++) {
      totalWidth += Math.abs(extractedPoints[i].x);
    }

    return totalWidth + width;
  }

  function getHeight(height, extractedPoints) {
    var totalHeight = 0;

    for(var i = 0, len = extractedPoints.length; i < len; i++) {
      totalHeight += Math.abs(extractedPoints[i].y);
    }

    return totalHeight + height;
  }

  function getViewBox(extractedPoints, width, height) {
    var x = Math.min.apply(Math, extractedPoints.map( function(o) { return o.x; } )),
        y = Math.min.apply(Math, extractedPoints.map( function(o) { return o.y; } )),
        w = width,
        h = height;
    return { 'x': x, 'y': y, 'w': w, 'h': h, 'rect': x + ' ' + y + ' ' + w + ' ' + h };
  }

  function trace(extractedPoints, bounds) {
    var a = extractedPoints[0],
        b = extractedPoints[1],
        c = extractedPoints[2],
        d = extractedPoints[3],
        points = 'M';

    points += a.x + ',' + (a.y + a.r) + ' Q';
    points += a.x + ',' + a.y + ' ';
    points += (a.x + a.r) + ',' + a.y + ' L';
    points += (bounds.width + b.x - b.r) + ',' + (b.y) + ' Q';
    points += (bounds.width + b.x) + ',' + b.y + ' ';
    points += (bounds.width + b.x) + ',' + (b.y + b.r) + ' L';
    points += (bounds.width + c.x) + ',' + (bounds.height + c.y - c.r) + ' Q';
    points += (bounds.width + c.x) + ',' + (bounds.height + c.y) + ' ';
    points += (bounds.width + c.x - c.r) + ',' + (bounds.height + c.y) + ' L';
    points += (d.x + d.r) + ',' + (bounds.height + d.y) + ' Q';
    points += d.x + ',' + (bounds.height + d.y) + ' ';
    points += d.x + ',' + (bounds.height + d.y - d.r);

    return points;
  }

  //clear
  function clear($el) {
    var $svg = $el.getElementsByClassName('slurve-svg')[0];
    if($svg) {
      $svg.parentNode.removeChild($svg);
    }
  }

  //update individual slurve
  function updateSlurve($el) {

    //helpers
    var extractedPoints = extractPoints($el),
        bounds = {
          top: $el.offsetTop,
          left: $el.offsetLeft,
          width: $el.offsetWidth,
          height: $el.offsetHeight
        },
        svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
        poly = document.createElementNS('http://www.w3.org/2000/svg', 'path'),
        width = getWidth(bounds.width, extractedPoints),
        height = getHeight(bounds.height, extractedPoints),
        viewBox = getViewBox(extractedPoints, width, height),
        pointsStr = trace(extractedPoints, bounds),
        svgClasses =  $el.attributes['data-slurve-classes'];

    //attrs
    svg.setAttribute('class', svgClasses ? 'slurve-svg ' + svgClasses.value : 'slurve-svg');
    svg.setAttribute('top', viewBox.y + 'px');
    svg.setAttribute('left', viewBox.x + 'px');
    svg.setAttribute('width', width);
    svg.setAttribute('height', height);
    svg.setAttribute('viewBox', viewBox.rect);
    poly.setAttribute('d', pointsStr);

    //style
    svg.style.top = viewBox.y + 'px';
    svg.style.left = viewBox.x + 'px';

    //update DOM
    svg.appendChild(poly);
    $el.insertBefore(svg, $el.firstChild);
  }

  //update all slurve instances
  function updateSlurves() {
    for(var i = 0, len = $slurves.length; i < len; i++) {
      clear($slurves[i]);
      updateSlurve($slurves[i]);
    }
  }

  //update all slurve instances after updated query
  function update() {
    $slurves = document.querySelectorAll('[data-slurve]');
    updateSlurves();
  }

}.call(this));<commit_msg>1.0<commit_after>/*
 * Slurve | slurve.js: Beautiful Slants and Curves in Web UIs
 * MIT license https://opensource.org/licenses/MIT
 * Copyright (c) 2016 Derek Knox | Braindrop Labs
 * Version: 1.0
 * @author Derek Knox http://derekknox.com @derekknox
 */

;(function() {

  /******************************************************************
  API
  ******************************************************************/

  this.slurve = {
    update: update
  };

  /******************************************************************
  Init
  ******************************************************************/

  //cache
  var $slurves;

  //listeners
  this.addEventListener('resize', updateSlurves);

  //init
  window.onload = function() { update(); }
  update();

  /******************************************************************
  Methods
  ******************************************************************/

  function extractPoints($el) {
    var pointValues = $el.attributes['data-slurve'].value.split(' '),
        point,
        points = [];

    for(var i = 0, len = pointValues.length; i < len; i++) {
      point = pointValues[i].split(',');
      points.push({ 'x': +point[0], 'y': +point[1], 'r': +point[2] || 0 });
    }

    return points;
  }

  function getWidth(width, extractedPoints) {
    var totalWidth = 0;

    for(var i = 0, len = extractedPoints.length; i < len; i++) {
      totalWidth += Math.abs(extractedPoints[i].x);
    }

    return totalWidth + width;
  }

  function getHeight(height, extractedPoints) {
    var totalHeight = 0;

    for(var i = 0, len = extractedPoints.length; i < len; i++) {
      totalHeight += Math.abs(extractedPoints[i].y);
    }

    return totalHeight + height;
  }

  function getViewBox(extractedPoints, width, height) {
    var x = Math.min.apply(Math, extractedPoints.map( function(o) { return o.x; } )),
        y = Math.min.apply(Math, extractedPoints.map( function(o) { return o.y; } )),
        w = width,
        h = height;
    return { 'x': x, 'y': y, 'w': w, 'h': h, 'rect': x + ' ' + y + ' ' + w + ' ' + h };
  }

  function trace(extractedPoints, bounds) {
    var a = extractedPoints[0],
        b = extractedPoints[1],
        c = extractedPoints[2],
        d = extractedPoints[3],
        points = 'M';

    points += a.x + ',' + (a.y + a.r) + ' Q';
    points += a.x + ',' + a.y + ' ';
    points += (a.x + a.r) + ',' + a.y + ' L';
    points += (bounds.width + b.x - b.r) + ',' + (b.y) + ' Q';
    points += (bounds.width + b.x) + ',' + b.y + ' ';
    points += (bounds.width + b.x) + ',' + (b.y + b.r) + ' L';
    points += (bounds.width + c.x) + ',' + (bounds.height + c.y - c.r) + ' Q';
    points += (bounds.width + c.x) + ',' + (bounds.height + c.y) + ' ';
    points += (bounds.width + c.x - c.r) + ',' + (bounds.height + c.y) + ' L';
    points += (d.x + d.r) + ',' + (bounds.height + d.y) + ' Q';
    points += d.x + ',' + (bounds.height + d.y) + ' ';
    points += d.x + ',' + (bounds.height + d.y - d.r);

    return points;
  }

  //clear
  function clear($el) {
    var $svg = $el.getElementsByClassName('slurve-svg')[0];
    if($svg) {
      $svg.parentNode.removeChild($svg);
    }
  }

  //update individual slurve
  function updateSlurve($el) {

    //helpers
    var extractedPoints = extractPoints($el),
        bounds = {
          top: $el.offsetTop,
          left: $el.offsetLeft,
          width: $el.offsetWidth,
          height: $el.offsetHeight
        },
        svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
        poly = document.createElementNS('http://www.w3.org/2000/svg', 'path'),
        width = getWidth(bounds.width, extractedPoints),
        height = getHeight(bounds.height, extractedPoints),
        viewBox = getViewBox(extractedPoints, width, height),
        pointsStr = trace(extractedPoints, bounds),
        svgClasses =  $el.attributes['data-slurve-classes'];

    //attrs
    svg.setAttribute('class', svgClasses ? 'slurve-svg ' + svgClasses.value : 'slurve-svg');
    svg.setAttribute('top', viewBox.y + 'px');
    svg.setAttribute('left', viewBox.x + 'px');
    svg.setAttribute('width', width);
    svg.setAttribute('height', height);
    svg.setAttribute('viewBox', viewBox.rect);
    poly.setAttribute('d', pointsStr);

    //style
    svg.style.top = viewBox.y + 'px';
    svg.style.left = viewBox.x + 'px';

    //update DOM
    svg.appendChild(poly);
    $el.insertBefore(svg, $el.firstChild);
  }

  //update all slurve instances
  function updateSlurves() {
    for(var i = 0, len = $slurves.length; i < len; i++) {
      clear($slurves[i]);
      updateSlurve($slurves[i]);
    }
  }

  //update all slurve instances after updated query
  function update() {
    $slurves = document.querySelectorAll('[data-slurve]');
    updateSlurves();
  }

}.call(this));<|endoftext|>


<commit_before>ngDefine('cockpit.directives', [ 'angular' ], function(module, angular) {
  'use strict';

  module.directive('viewPills', [ '$location', 'Views', function($location, Views) {

    var ViewPillsController = [ '$scope', 'Views', '$location', function($scope, Views, $location) {
      var providers = Views.getProviders({ component: $scope.id });
      $scope.providers = providers;

      $scope.isActive = function(provider) {
        return $location.path().indexOf('/' + provider.id) != -1;
      };

      $scope.getUrl = function(provider) {
        return '#' + $location.path().replace(/[^\/]*$/, provider.id);
      };
    }];

    return {
      restrict: 'EAC',
      scope: {
        id: '@'
      },
      template:
'
' +
'
{{ provider.label }}
' +
'
',
      replace: true,
      controller: ViewPillsController
    };
  }]);
});<commit_msg>improve(cockpit/views): add a css class to the view pills<commit_after>/* global ngDefine: false */
ngDefine('cockpit.directives', [], function(module) {
  'use strict';

  module.directive('viewPills', [
  function() {
    var ViewPillsController = [
      '$scope',
      'Views',
      '$location',
    function($scope, Views, $location) {
      var providers = Views.getProviders({ component: $scope.id });
      $scope.providers = providers;

      $scope.isActive = function(provider) {
        return $location.path().indexOf('/' + provider.id) != -1;
      };

      $scope.getUrl = function(provider) {
        return '#' + $location.path().replace(/[^\/]*$/, provider.id);
      };
    }];

    return {
      restrict: 'EAC',
      scope: {
        id: '@'
      },
      template:
'
' +
'
' +
'    {{ provider.label }}' +
'
' +
'
',
      replace: true,
      controller: ViewPillsController
    };
  }]);
});
<|endoftext|>


<commit_before>if (!Spaz.dock) Spaz.dock = {};

/***********
Spaz.dock takes care of the docking
***********/

Spaz.dock.init = function() {

   // Only on OSX
   Spaz.dock.active = air.NativeApplication.supportsDockIcon;

   //
   if (!Spaz.dock.active)
   {
      return;
   }

   // Create the text format
   var format = new window.runtime.flash.text.TextFormat();
   format.size = 30;
   format.color = 0xFFFFFF;
   format.bold = true;
   format.font = 'Arial';
   air.trace("Dock text format created");

   // Load the image async
   var imageURL = 'images/spaz-icon-alpha.png';
   air.trace("Want to load image " + imageURL);
   var loader = new air.Loader();
   loader.contentLoaderInfo.addEventListener(air.Event.COMPLETE, function(event)
   {
      air.trace("Loaded image " + imageURL);
      Spaz.dock.bitmapData = event.target.content.bitmapData;
   }, false, 0, true);
   loader.load(new air.URLRequest(imageURL));

   // Save for later use
   Spaz.dock.icon = air.NativeApplication.nativeApplication.icon;
   Spaz.dock.textFormat = format;
   Spaz.dock.padding = 4;
   Spaz.dock.border = 5;
}

Spaz.dock.refresh = function(unreadCount)
{
   if (!Spaz.dock.active)
   {
      return;
   }

   //
   var tf = new window.runtime.flash.text.TextField();
   tf.defaultTextFormat = Spaz.dock.textFormat;
   tf.text = "" + unreadCount;
   tf.wordWrap = true;

   // Clone the bitmap
   var clone = Spaz.dock.bitmapData.clone();

   // Draw the text in a buffer
   var buffer = new window.runtime.flash.display.BitmapData(
      256,
      256,
      true,
      0);
   buffer.draw(tf);

   // Compute the bounding box, we cannot use TextField.textWidth and TextField.textHeight as
   // they return approximation which results into incorrect display
   var xmin = buffer.width;
   var ymin = buffer.height;
   var xmax = 0;
   var ymax = 0;
   for (var x = 0;x < buffer.width;x++)
   {
      for (var y = 0;y < buffer.height;y++)
      {
         if (buffer.getPixel(x, y) != 0)
         {
            if (x < xmin)
            {
               xmin = x;
            }
            else if (x > xmax)
            {
               xmax = x;
            }
            if (y < ymin)
            {
               ymin = y;
            }
            else if (y > ymax)
            {
               ymax = y;
            }
         }
      }
   }
   var width = xmax - xmin;
   var height = ymax - ymin;

   // Compute the ellipse dimensions
   var eH = (width / (Math.sqrt(2)));
   var eY = (height / (Math.sqrt(2)));

   // Correct the dimension if the ellipse width is lesser than the ellipse height
   if (eH < eY)
   {
      eH = eY;
   }

   // Compute the inner and outter ellipses
   var innerW = eH + Spaz.dock.padding;
   var innerH = eY + Spaz.dock.padding;
   var outterW = eH + Spaz.dock.padding + Spaz.dock.border;
   var outterH = eY + Spaz.dock.padding + Spaz.dock.border;

   // Draw the shape
   var shape = new window.runtime.flash.display.Shape();
   Spaz.dock.drawPolygon(
      shape.graphics,
      outterW,
      outterH,
      innerW,
      innerH,
      outterW,
      outterH,
      30);
   clone.draw(shape);

   // Copy the text on top of the shape
   clone.copyPixels(
      buffer,
      new window.runtime.flash.geom.Rectangle(xmin, ymin, width, height),
      new window.runtime.flash.geom.Point(outterW - width / 2, outterH - height / 2),
      null,
      null,
      true);

   // Update icon
   Spaz.dock.icon.bitmaps = [clone];
}

Spaz.dock.drawPolygon = function(graphics, centerX, centerY, innerW, innerH, outterW, outterH, size)
{
   var delta = (Math.PI * 2) / size;
   var angle = 0;
   var xs = [];
   var ys = [];
   for (var i = 0;i < size;i++)
   {
      angle = delta * i + (Math.PI / 2);
      var x1 = centerX + outterW * Math.cos(angle) + 0.5;
      var y1 = centerY - outterH * Math.sin(angle) + 0.5;
      angle += delta / 2;
      var x2 = centerX + innerW * Math.cos(angle) + 0.5;
      var y2 = centerY - innerH * Math.sin(angle) + 0.5;

      //
      xs.push(x1);
      ys.push(y1);
      xs.push(x2);
      ys.push(y2);
   }

   // Draw the inner
   var fillType = window.runtime.flash.display.GradientType.LINEAR;
   var colors = [0xFF0000, 0xAA0000];
   var alphas = [1, 1];
   var ratios = [0x00, 0xFF];
   var matr = new window.runtime.flash.geom.Matrix();
   matr.createGradientBox(outterW * 2, 0, 0, 0, 0);
   var spreadMethod = window.runtime.flash.display.SpreadMethod.PAD;
   graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod);

   //
   graphics.lineStyle(
      2,
      0x660000,
      1,
      false,
      window.runtime.flash.display.LineScaleMode.NORMAL,
      window.runtime.flash.display.CapsStyle.NONE,
      window.runtime.flash.display.JointStyle.MITER,
      3);

   //
   for (var j in xs)
   {
      if (j == 0)
      {
         graphics.moveTo(xs[j], ys[j]);
      }
      else
      {
         graphics.lineTo(xs[j], ys[j]);
      }
   }

   //
   graphics.endFill();

   // Draw the perimeter
//   graphics.lineStyle(
//      3,
//      0xFF,
//      1,
//      false,
//      window.runtime.flash.display.LineScaleMode.NORMAL,
//      window.runtime.flash.display.CapsStyle.NONE,
//      window.runtime.flash.display.JointStyle.MITER,
//      3);
//   for (var j in xs)
//   {
//      if (j == 0)
//      {
//         graphics.moveTo(xs[j], ys[j]);
//      }
//      else
//      {
//         graphics.lineTo(xs[j], ys[j]);
//      }
//   }
//   graphics.lineTo(xs[0], ys[0]);
}
<commit_msg>make the unread count to be periodically refreshed<commit_after>if (!Spaz.dock) Spaz.dock = {};

/***********
Spaz.dock takes care of the docking
***********/

Spaz.dock.init = function() {

   // Only on OSX
   Spaz.dock.active = air.NativeApplication.supportsDockIcon;

   //
   if (!Spaz.dock.active)
   {
      return;
   }

   // Create the text format
   var format = new window.runtime.flash.text.TextFormat();
   format.size = 30;
   format.color = 0xFFFFFF;
   format.bold = true;
   format.font = 'Arial';
   air.trace("Dock text format created");

   // Load the image async
   var imageURL = 'images/spaz-icon-alpha.png';
   air.trace("Want to load image " + imageURL);
   var loader = new air.Loader();
   loader.contentLoaderInfo.addEventListener(air.Event.COMPLETE, function(event)
   {
      air.trace("Loaded image " + imageURL);
      Spaz.dock.bitmapData = event.target.content.bitmapData;
   }, false, 0, true);
   loader.load(new air.URLRequest(imageURL));

   // Save for later use
   Spaz.dock.icon = air.NativeApplication.nativeApplication.icon;
   Spaz.dock.textFormat = format;
   Spaz.dock.padding = 4;
   Spaz.dock.border = 5;

   // Install the refresh timer to 1/2 second which seems a reasonable value
   window.setInterval(Spaz.dock.refresh, 500);
}

Spaz.dock.refresh = function(unreadCount)
{
   if (!Spaz.dock.active)
   {
      return;
   }

   //
   if (typeof unreadCount == 'undefined')
   {
      unreadCount = $("#timeline-friends div.timeline-entry").size() - $("#timeline-friends div.timeline-entry.read").size();
   }

   //
   if (unreadCount == Spaz.dock.lastUnreadCount)
   {
      return;
   }

   // Use the original icon if count is zero
   if (unreadCount == 0)
   {
      // Update state
      Spaz.dock.icon.bitmaps = [Spaz.dock.bitmapData];
      Spaz.dock.lastUnreadCount = 0;
      return;
   }

   //
   var tf = new window.runtime.flash.text.TextField();
   tf.defaultTextFormat = Spaz.dock.textFormat;
   tf.text = "" + unreadCount;
   tf.wordWrap = true;

   // Clone the bitmap
   var clone = Spaz.dock.bitmapData.clone();

   // Draw the text in a buffer
   var buffer = new window.runtime.flash.display.BitmapData(
      256,
      256,
      true,
      0);
   buffer.draw(tf);

   // Compute the bounding box, we cannot use TextField.textWidth and TextField.textHeight as
   // they return approximation which results into incorrect display
   var xmin = 0;
   var ymin = 0;
   var xmax = tf.textWidth;
   var ymax = tf.textHeight;
   var width = xmax - xmin;
   var height = ymax - ymin;

   // Compute the ellipse dimensions
   var eH = (width / (Math.sqrt(2)));
   var eY = (height / (Math.sqrt(2)));

   // Correct the dimension if the ellipse width is lesser than the ellipse height
   if (eH < eY)
   {
      eH = eY;
   }

   // Compute the inner and outter ellipses
   var innerW = eH + Spaz.dock.padding;
   var innerH = eY + Spaz.dock.padding;
   var outterW = eH + Spaz.dock.padding + Spaz.dock.border;
   var outterH = eY + Spaz.dock.padding + Spaz.dock.border;

   // Draw the shape
   var shape = new window.runtime.flash.display.Shape();
   Spaz.dock.drawPolygon(
      shape.graphics,
      outterW,
      outterH,
      innerW,
      innerH,
      outterW,
      outterH,
      30);
   clone.draw(shape);

   // Copy the text on top of the shape
   clone.copyPixels(
      buffer,
      new window.runtime.flash.geom.Rectangle(xmin, ymin, width, height),
      new window.runtime.flash.geom.Point(outterW - width / 2, outterH - height / 2),
      null,
      null,
      true);

   // Update state
   Spaz.dock.icon.bitmaps = [clone];
   Spaz.dock.lastUnreadCount = unreadCount;
}

Spaz.dock.drawPolygon = function(graphics, centerX, centerY, innerW, innerH, outterW, outterH, size)
{
   var delta = (Math.PI * 2) / size;
   var angle = 0;
   var xs = [];
   var ys = [];
   for (var i = 0;i < size;i++)
   {
      angle = delta * i + (Math.PI / 2);
      var x1 = centerX + outterW * Math.cos(angle) + 0.5;
      var y1 = centerY - outterH * Math.sin(angle) + 0.5;
      angle += delta / 2;
      var x2 = centerX + innerW * Math.cos(angle) + 0.5;
      var y2 = centerY - innerH * Math.sin(angle) + 0.5;

      //
      xs.push(x1);
      ys.push(y1);
      xs.push(x2);
      ys.push(y2);
   }

   // Draw the inner
   var fillType = window.runtime.flash.display.GradientType.LINEAR;
   var colors = [0xFF0000, 0xAA0000];
   var alphas = [1, 1];
   var ratios = [0x00, 0xFF];
   var matr = new window.runtime.flash.geom.Matrix();
   matr.createGradientBox(outterW * 2, 0, 0, 0, 0);
   var spreadMethod = window.runtime.flash.display.SpreadMethod.PAD;
   graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod);

   //
   graphics.lineStyle(
      2,
      0x660000,
      1,
      false,
      window.runtime.flash.display.LineScaleMode.NORMAL,
      window.runtime.flash.display.CapsStyle.NONE,
      window.runtime.flash.display.JointStyle.MITER,
      3);

   //
   for (var j in xs)
   {
      if (j == 0)
      {
         graphics.moveTo(xs[j], ys[j]);
      }
      else
      {
         graphics.lineTo(xs[j], ys[j]);
      }
   }

   //
   graphics.endFill();

   // Draw the perimeter
//   graphics.lineStyle(
//      3,
//      0xFF,
//      1,
//      false,
//      window.runtime.flash.display.LineScaleMode.NORMAL,
//      window.runtime.flash.display.CapsStyle.NONE,
//      window.runtime.flash.display.JointStyle.MITER,
//      3);
//   for (var j in xs)
//   {
//      if (j == 0)
//      {
//         graphics.moveTo(xs[j], ys[j]);
//      }
//      else
//      {
//         graphics.lineTo(xs[j], ys[j]);
//      }
//   }
//   graphics.lineTo(xs[0], ys[0]);
}
<|endoftext|>


<commit_before>'use strict';

// Move these to a directive
//var authorizationUrl = 'https://localhost:44313/identity/connect/authorize';
//var client_id = 'implicit';
//var redirect_uri = 'http://localhost:37045/';
//var response_type = "token";
//var scope = "extracurricular";
//var state = Date.now() + "" + Math.random();

angular.module('oauth2.accessToken', ['ngStorage']).factory('AccessToken', ['$rootScope', '$location', '$sessionStorage', function($rootScope, $location, $sessionStorage) {
	var service = {
		token: null
	};
	var oAuth2HashParams = ['access_token', 'token_type', 'expires_in', 'scope', 'state', 'error', 'error_description'];

	function setExpiresAt(token) {
		if(token){
            var expires_at = new Date();
            expires_at.setSeconds(expires_at.getSeconds()+parseInt(token.expires_in)-60); // 60 seconds less to secure browser and response latency
            token.expires_at = expires_at;
        }
	}

	function setTokenFromHashParams(hash) {
		var token = getTokenFromHashParams(hash);
		if (token !== null) {
			setExpiresAt(token);
			$sessionStorage.token = token;
		}
		return token;
	}

	function getTokenFromHashParams(hash) {
		var token = {};
        var regex = /([^&=]+)=([^&]*)/g;
        var m;

        while (m = regex.exec(hash)) {
            var param = decodeURIComponent(m[1]);
            var value = decodeURIComponent(m[2]);

            if (oAuth2HashParams.indexOf(param) >= 0) {
              token[param] = value;
            }
        }

        if((token.access_token && token.expires_in) || token.error){
            return token;
        }
        return null;
	}

	service.get = function() {
		return this.token;
	};
	service.set = function() {
		// Try and get the token from the hash params on the URL
		var hashValues = window.location.hash;
		if (hashValues.length > 0) {
			if (hashValues.indexOf('#/') == 0) {
				hashValues = hashValues.substring(2);
			}
			service.token = setTokenFromHashParams(hashValues);
		}

		if (service.token === null) {
			service.token = $sessionStorage.token;
			if (service.token === undefined) {
				service.token = null;
			}
		}

		if (service.token && service.token.error) {
			var error = service.token.error;
			service.destroy();
			$rootScope.$broadcast('oauth2:authError', error);
		}

		if (service.token !== null) {
			$rootScope.$broadcast('oauth2:authSuccess');
			if ($sessionStorage.oauthRedirectRoute) {
				var path = $sessionStorage.oauthRedirectRoute;
				$sessionStorage.oauthRedirectRoute = null;
				$location.path(path);
			}
		}

		return service.token;
	};
	service.destroy = function() {
		$sessionStorage.token = null;
		delete $sessionStorage.token;
        service.token = null;
	};

	return service;
}]);

// Auth interceptor - if token is missing or has expired this broadcasts an authRequired event
angular.module('oauth2.interceptor', []).factory('OAuth2Interceptor', ['$rootScope', '$q', '$sessionStorage', function ($rootScope, $q, $sessionStorage) {
	var expired = function(token) {
    	return (token && token.expires_at && new Date(token.expires_at) < new Date());
  	};

	var service = {
		request: function(config) {
			var token = $sessionStorage.token;
			if (expired(token)) {
				$rootScope.$broadcast('oauth2:authExpired', token);
			}
			else if (token) {
                config.headers.Authorization = 'Bearer ' + token.access_token;
                return config;
			}
    		return config;
  		}
	};
  	return service;
}]);

// Endpoint wrapper
angular.module('oauth2.endpoint', []).factory('Endpoint', ['AccessToken', function(accessToken) {
	var service = {
		authorize: function() { window.location.replace(service.url); },
		appendSignoutToken: false
	};

	service.signOut = function(token) {
		if (service.signOutUrl && service.signOutUrl.length > 0) {
			var url = service.signOutUrl;
			if (service.appendSignoutToken) {
				url = url + token;
			}
			window.location.replace(url);
		}
	};

	service.init = function(params) {
		service.url = params.authorizationUrl + '?' +
				  	  'client_id=' + encodeURI(params.clientId) + '&' +
				  	  'redirect_uri=' + encodeURI(params.redirectUrl) + '&' +
				  	  'response_type=' + encodeURI(params.responseType) + '&' +
				  	  'scope=' + encodeURI(params.scope) + '&' +
				  	  'state=' + encodeURI(params.state);
		service.signOutUrl = params.signOutUrl;
		if (params.signOutAppendToken == 'true') {
			service.appendSignoutToken = true;
		}
		if (params.signOutRedirectUrl.length > 0) {
			service.signOutUrl = service.signOutUrl+ '?post_logout_redirect_uri=' + encodeURI(params.signOutRedirectUrl);
		}
	};

	return service;
}]);

// Open ID directive
angular.module('oauth2.directive', []).directive('oauth2', ['$rootScope', '$http', '$templateCache', '$compile', '$sessionStorage', 'AccessToken', 'Endpoint', function($rootScope, $http,$templateCache, $compile, $sessionStorage, accessToken, endpoint) {
	var definition = {
	    restrict: 'E',
	    replace: true,
	    scope: {
			authorizationUrl: '@',          // authorization server url
			clientId: '@',       			// client ID
			redirectUrl: '@',   			// uri th auth server should redirect to (cannot contain #)
			responseType: '@',  			// defaults to token
			scope: '@',						// scopes required (not the Angular scope - the auth server scopes)
			state: '@',						// state to use for CSRF protection
			template: '@',					// path to a replace template for the button, defaults to the one supplied by bower
			buttonClass: '@',				// the class to use for the sign in / out button - defaults to btn btn-primary
			signInText: '@',				// text for the sign in button
			signOutText: '@',				// text for the sign out button
			signOutUrl: '@',				// url on the authorization server for logging out. Local token is deleted even if no URL is given but that will leave user logged in against STS
			signOutAppendToken: '@',		// defaults to 'false', set to 'true' to append the token to the sign out url
			signOutRedirectUrl: '@'			// url to redirect to after sign out on the STS has completed
	    }
	};

	definition.link = function(scope, element, attrs) {
		function compile() {
			var tpl = '
{{signInText}}{{signOutText}}
';
			if (scope.template) {
				$http.get(scope.template, { cache: $templateCache }).success(function(html) {
		        element.html(html);
		        $compile(element.contents())(scope);
		      });
			} else {
				element.html(tpl);
				$compile(element.contents())(scope);
			}
	    };

	    function routeChangeHandler(event, nextRoute) {
	    	if (nextRoute.$$route && nextRoute.$$route.requireToken) {
                if (!accessToken.get()) {
                	$sessionStorage.oauthRedirectRoute = nextRoute.$$route.originalPath;
                    endpoint.authorize();
                }
            }
	    };

		function init() {
			scope.buttonClass = scope.buttonClass || 'btn btn-primary';
			scope.signInText = scope.signInText || 'Sign In';
			scope.signOutText = scope.signOutText || 'Sign Out';
			scope.responseType = scope.responseType || 'token';
			scope.signOutUrl = scope.signOutUrl || '';
			scope.signOutRedirectUrl = scope.signOutRedirectUrl || '';
			scope.unauthorizedAccessUrl = scope.unauthorizedAccessUrl || '';

			compile();

			endpoint.init(scope);
			scope.signedIn = accessToken.set() !== null;
			scope.$on('oauth2:authRequired', function() {
				endpoint.authorize();
			});
			scope.$on('oauth2:authError', function() {
				if (scope.unauthorizedAccessUrl.length > 0) {
					$location.path(scope.unauthorizedAccessUrl);
				}
			});
			$rootScope.$on('$routeChangeStart', routeChangeHandler);
		}

		scope.$watch('clientId', function(value) { init(); });

		scope.signedIn = false;

		scope.signIn = function() {
			endpoint.authorize();
		}

		scope.signOut = function() {
			var token = accessToken.get().access_token;
			accessToken.destroy();
			endpoint.signOut(token);
		};
	};

	return definition;
}]);

// App libraries
angular.module('afOAuth2', [
  'oauth2.directive',      // login directive
  'oauth2.accessToken',    // access token service
  'oauth2.endpoint',       // oauth endpoint service
  'oauth2.interceptor'     // bearer token interceptor
]).config(['$locationProvider','$httpProvider',
	function($locationProvider, $httpProvider) {
		$httpProvider.interceptors.push('OAuth2Interceptor');
	}
]);<commit_msg>Added 401 and 500 status code handling to the http interceptor<commit_after>'use strict';

// Move these to a directive
//var authorizationUrl = 'https://localhost:44313/identity/connect/authorize';
//var client_id = 'implicit';
//var redirect_uri = 'http://localhost:37045/';
//var response_type = "token";
//var scope = "extracurricular";
//var state = Date.now() + "" + Math.random();

angular.module('oauth2.accessToken', ['ngStorage']).factory('AccessToken', ['$rootScope', '$location', '$sessionStorage', function($rootScope, $location, $sessionStorage) {
	var service = {
		token: null
	};
	var oAuth2HashParams = ['access_token', 'token_type', 'expires_in', 'scope', 'state', 'error', 'error_description'];

	function setExpiresAt(token) {
		if(token){
            var expires_at = new Date();
            expires_at.setSeconds(expires_at.getSeconds()+parseInt(token.expires_in)-60); // 60 seconds less to secure browser and response latency
            token.expires_at = expires_at;
        }
	}

	function setTokenFromHashParams(hash) {
		var token = getTokenFromHashParams(hash);
		if (token !== null) {
			setExpiresAt(token);
			$sessionStorage.token = token;
		}
		return token;
	}

	function getTokenFromHashParams(hash) {
		var token = {};
        var regex = /([^&=]+)=([^&]*)/g;
        var m;

        while (m = regex.exec(hash)) {
            var param = decodeURIComponent(m[1]);
            var value = decodeURIComponent(m[2]);

            if (oAuth2HashParams.indexOf(param) >= 0) {
              token[param] = value;
            }
        }

        if((token.access_token && token.expires_in) || token.error){
            return token;
        }
        return null;
	}

	service.get = function() {
		return this.token;
	};
	service.set = function() {
		// Try and get the token from the hash params on the URL
		var hashValues = window.location.hash;
		if (hashValues.length > 0) {
			if (hashValues.indexOf('#/') == 0) {
				hashValues = hashValues.substring(2);
			}
			service.token = setTokenFromHashParams(hashValues);
		}

		if (service.token === null) {
			service.token = $sessionStorage.token;
			if (service.token === undefined) {
				service.token = null;
			}
		}

		if (service.token && service.token.error) {
			var error = service.token.error;
			service.destroy();
			$rootScope.$broadcast('oauth2:authError', error);
		}

		if (service.token !== null) {
			$rootScope.$broadcast('oauth2:authSuccess');
			if ($sessionStorage.oauthRedirectRoute) {
				var path = $sessionStorage.oauthRedirectRoute;
				$sessionStorage.oauthRedirectRoute = null;
				$location.path(path);
			}
		}

		return service.token;
	};
	service.destroy = function() {
		$sessionStorage.token = null;
		delete $sessionStorage.token;
        service.token = null;
	};

	return service;
}]);

// Auth interceptor - if token is missing or has expired this broadcasts an authRequired event
angular.module('oauth2.interceptor', []).factory('OAuth2Interceptor', ['$rootScope', '$q', '$sessionStorage', function ($rootScope, $q, $sessionStorage) {
	var expired = function(token) {
    	return (token && token.expires_at && new Date(token.expires_at) < new Date());
  	};

	var service = {
		request: function(config) {
			var token = $sessionStorage.token;
			if (expired(token)) {
				$rootScope.$broadcast('oauth2:authExpired', token);
			}
			else if (token) {
                config.headers.Authorization = 'Bearer ' + token.access_token;
                return config;
			}
    		return config;
  		},
  		response: function(response) {
  			if (response.status === 401) {
  				$rootScope.$broadcast('oauth2:unauthorized', token);
  			}
  			else if (response.status === 500) {
  				$rootScope.$broadcast('oauth2:internalservererror', token);
  			}
  			return response;
  		},
  		responseError: function(response) {
  			if (response.status === 401) {
  				$rootScope.$broadcast('oauth2:unauthorized', token);
  			}
  			else if (response.status === 500) {
  				$rootScope.$broadcast('oauth2:internalservererror', token);
  			}
  			return response;
  		}
	};
  	return service;
}]);

// Endpoint wrapper
angular.module('oauth2.endpoint', []).factory('Endpoint', ['AccessToken', function(accessToken) {
	var service = {
		authorize: function() { window.location.replace(service.url); },
		appendSignoutToken: false
	};

	service.signOut = function(token) {
		if (service.signOutUrl && service.signOutUrl.length > 0) {
			var url = service.signOutUrl;
			if (service.appendSignoutToken) {
				url = url + token;
			}
			window.location.replace(url);
		}
	};

	service.init = function(params) {
		service.url = params.authorizationUrl + '?' +
				  	  'client_id=' + encodeURI(params.clientId) + '&' +
				  	  'redirect_uri=' + encodeURI(params.redirectUrl) + '&' +
				  	  'response_type=' + encodeURI(params.responseType) + '&' +
				  	  'scope=' + encodeURI(params.scope) + '&' +
				  	  'state=' + encodeURI(params.state);
		service.signOutUrl = params.signOutUrl;
		if (params.signOutAppendToken == 'true') {
			service.appendSignoutToken = true;
		}
		if (params.signOutRedirectUrl.length > 0) {
			service.signOutUrl = service.signOutUrl+ '?post_logout_redirect_uri=' + encodeURI(params.signOutRedirectUrl);
		}
	};

	return service;
}]);

// Open ID directive
angular.module('oauth2.directive', []).directive('oauth2', ['$rootScope', '$http', '$templateCache', '$compile', '$sessionStorage', 'AccessToken', 'Endpoint', function($rootScope, $http,$templateCache, $compile, $sessionStorage, accessToken, endpoint) {
	var definition = {
	    restrict: 'E',
	    replace: true,
	    scope: {
			authorizationUrl: '@',          // authorization server url
			clientId: '@',       			// client ID
			redirectUrl: '@',   			// uri th auth server should redirect to (cannot contain #)
			responseType: '@',  			// defaults to token
			scope: '@',						// scopes required (not the Angular scope - the auth server scopes)
			state: '@',						// state to use for CSRF protection
			template: '@',					// path to a replace template for the button, defaults to the one supplied by bower
			buttonClass: '@',				// the class to use for the sign in / out button - defaults to btn btn-primary
			signInText: '@',				// text for the sign in button
			signOutText: '@',				// text for the sign out button
			signOutUrl: '@',				// url on the authorization server for logging out. Local token is deleted even if no URL is given but that will leave user logged in against STS
			signOutAppendToken: '@',		// defaults to 'false', set to 'true' to append the token to the sign out url
			signOutRedirectUrl: '@'			// url to redirect to after sign out on the STS has completed
	    }
	};

	definition.link = function(scope, element, attrs) {
		function compile() {
			var tpl = '
{{signInText}}{{signOutText}}
';
			if (scope.template) {
				$http.get(scope.template, { cache: $templateCache }).success(function(html) {
		        element.html(html);
		        $compile(element.contents())(scope);
		      });
			} else {
				element.html(tpl);
				$compile(element.contents())(scope);
			}
	    };

	    function routeChangeHandler(event, nextRoute) {
	    	if (nextRoute.$$route && nextRoute.$$route.requireToken) {
                if (!accessToken.get()) {
                	$sessionStorage.oauthRedirectRoute = nextRoute.$$route.originalPath;
                    endpoint.authorize();
                }
            }
	    };

		function init() {
			scope.buttonClass = scope.buttonClass || 'btn btn-primary';
			scope.signInText = scope.signInText || 'Sign In';
			scope.signOutText = scope.signOutText || 'Sign Out';
			scope.responseType = scope.responseType || 'token';
			scope.signOutUrl = scope.signOutUrl || '';
			scope.signOutRedirectUrl = scope.signOutRedirectUrl || '';
			scope.unauthorizedAccessUrl = scope.unauthorizedAccessUrl || '';

			compile();

			endpoint.init(scope);
			scope.signedIn = accessToken.set() !== null;
			scope.$on('oauth2:authRequired', function() {
				endpoint.authorize();
			});
			scope.$on('oauth2:authError', function() {
				if (scope.unauthorizedAccessUrl.length > 0) {
					$location.path(scope.unauthorizedAccessUrl);
				}
			});
			$rootScope.$on('$routeChangeStart', routeChangeHandler);
		}

		scope.$watch('clientId', function(value) { init(); });

		scope.signedIn = false;

		scope.signIn = function() {
			endpoint.authorize();
		}

		scope.signOut = function() {
			var token = accessToken.get().access_token;
			accessToken.destroy();
			endpoint.signOut(token);
		};
	};

	return definition;
}]);

// App libraries
angular.module('afOAuth2', [
  'oauth2.directive',      // login directive
  'oauth2.accessToken',    // access token service
  'oauth2.endpoint',       // oauth endpoint service
  'oauth2.interceptor'     // bearer token interceptor
]).config(['$locationProvider','$httpProvider',
	function($locationProvider, $httpProvider) {
		$httpProvider.interceptors.push('OAuth2Interceptor');
	}
]);<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _yupValidationStrategy = require('yup-validation-strategy');

var _yupValidationStrategy2 = _interopRequireDefault(_yupValidationStrategy);

var _baobabPropTypes = require('baobab-prop-types');

var _baobabPropTypes2 = _interopRequireDefault(_baobabPropTypes);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.default = _react2.default.createClass({
    displayName: 'form',

    propTypes: {
        onSubmit: _react2.default.PropTypes.func,
        onInvalidSubmit: _react2.default.PropTypes.func,
        cursor: _baobabPropTypes2.default.cursor.isRequired,

        // TODO: concretize type
        validationSchema: _react2.default.PropTypes.any.isRequired,
        formStateCursor: _baobabPropTypes2.default.cursor,
        validateOnFly: _react2.default.PropTypes.bool,
        useHtmlForm: _react2.default.PropTypes.bool
    },

    childContextTypes: {
        form: _react2.default.PropTypes.object
    },

    contextTypes: {
        form: _react2.default.PropTypes.object
    },

    subscribers: [],
    _isHtmlForm: null,

    getDefaultProps: function getDefaultProps() {
        return {
            validateOnFly: true,
            strategy: (0, _yupValidationStrategy2.default)(),
            onSubmit: _lodash2.default.identity,
            onInvalidSubmit: _lodash2.default.identity,
            useHtmlForm: true
        };
    },
    getChildContext: function getChildContext() {
        return {
            form: {
                parentForm: this.context.form,
                isHtmlForm: this.isHtmlForm,

                cursor: this.props.cursor,
                isValid: this.isValid,
                isDirty: this.isDirty,
                getValidationErrors: this.getValidationErrors,
                setDirtyState: this.setDirtyState,
                setPristineState: this.setPristineState,

                submit: this.submit,
                validate: this.validate,

                subscribe: this.subscribe,
                unsubscribe: this.unsubscribe
            }
        };
    },
    getInitialState: function getInitialState() {
        if (this.props.formStateCursor) {
            return {};
        }

        return {
            errors: {},
            dirtyStates: {},
            isFormDirty: false
        };
    },
    componentDidMount: function componentDidMount() {
        if (this.props.validateOnFly) {
            this.props.cursor.on('update', this.onUpdate);
        }

        this.validate();
    },
    componentWillUnmount: function componentWillUnmount() {
        if (this.props.validateOnFly) {
            this.props.cursor.off('update', this.onUpdate);
        }
    },
    render: function render() {
        if (this.isHtmlForm()) {
            return _react2.default.createElement(
                'form',
                _extends({ noValidate: true }, this.props, { onSubmit: this.onFormSubmit }),
                this.props.children
            );
        }

        return _react2.default.createElement(
            'div',
            this.props,
            this.props.children
        );
    },
    hasParentHtmlForm: function hasParentHtmlForm() {
        var parentForm = this.context.form;

        while (parentForm) {
            if (parentForm.isHtmlForm()) {
                return true;
            }

            parentForm = parentForm.parentForm;
        }
    },
    isHtmlForm: function isHtmlForm() {
        if (this._isHtmlForm === null) {
            this._isHtmlForm = this.props.useHtmlForm && !this.hasParentHtmlForm();
        }

        return this._isHtmlForm;
    },
    publish: function publish() {
        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
        }

        _lodash2.default.each(this.subscribers, function (subscriber) {
            return subscriber.apply(undefined, args);
        });
    },
    subscribe: function subscribe(subscriber) {
        this.subscribers = _lodash2.default.concat(this.subscribers, subscriber);

        // Notify new subscriber about initial form state
        subscriber(this.getFormState(), null);
    },
    unsubscribe: function unsubscribe(subscriber) {
        this.subscribers = _lodash2.default.without(this.subscribers, subscriber);
    },
    onFormStateUpdate: function onFormStateUpdate(data, previousData) {
        // Notify subscribers about changed data only
        if (_lodash2.default.isEqual(data, previousData)) {
            return;
        }

        this.publish(data, previousData);
    },
    setFormState: function setFormState(nextState) {
        var _this = this;

        var prevState = this.getFormState();

        if (this.props.formStateCursor) {
            this.props.formStateCursor.once('update', function (_ref) {
                var data = _ref.data;
                return _this.onFormStateUpdate(data.currentData, prevState);
            });
            this.props.formStateCursor.merge(nextState);
        } else {
            this.setState(nextState, function () {
                return _this.onFormStateUpdate(_this.state, prevState);
            });
        }
    },
    getFormState: function getFormState() {
        if (this.props.formStateCursor) {
            return this.props.formStateCursor.get();
        }

        return this.state;
    },
    onFormSubmit: function onFormSubmit(event) {
        event.preventDefault();
        event.stopPropagation();

        return this.submit();
    },
    onUpdate: function onUpdate() {
        this.validate();
    },
    submit: function submit() {
        return this.validate(this.props.onSubmit, this.props.onInvalidSubmit);
    },
    getFormData: function getFormData() {
        return this.props.cursor.get();
    },
    validate: function validate(successCallback, errorCallback) {
        var _this2 = this;

        var data = this.getFormData();
        var schema = _lodash2.default.isFunction(this.props.validationSchema) ? this.props.validationSchema(data) : this.props.validationSchema;

        this.props.strategy.validate(data, schema, {}, function (errors) {
            _this2.setFormState({ errors: errors });

            if (_lodash2.default.isEmpty(errors)) {
                if (successCallback) {
                    return successCallback(data);
                }
            } else {
                if (errorCallback) {
                    return errorCallback(errors);
                }
            }
        });
    },
    getValidationErrors: function getValidationErrors(fieldPath) {
        var formState = this.getFormState();
        if (fieldPath) {
            return _lodash2.default.get(formState.errors, fieldPath);
        }

        return formState.errors;
    },
    isValid: function isValid(fieldPath) {
        var formState = this.getFormState();

        if (fieldPath) {
            return !_lodash2.default.get(formState.errors, fieldPath);
        }

        return _lodash2.default.isEmpty(formState.errors);
    },
    isDirty: function isDirty(fieldPath) {
        var formState = this.getFormState();
        var isFormDirty = formState.isFormDirty;

        if (isFormDirty) {
            return true;
        }

        if (!fieldPath) {
            return !_lodash2.default.isEmpty(formState.dirtyStates);
        }

        return !!_lodash2.default.get(formState.dirtyStates, fieldPath);
    },
    resetValidationErrors: function resetValidationErrors() {
        this.setValidationErrors({});
    },
    setValidationErrors: function setValidationErrors(errors) {
        this.setFormState({
            errors: errors
        });
    },
    setDirtyState: function setDirtyState(fieldPath) {
        if (!fieldPath) {
            this.setFormState({
                dirtyStates: {},
                isFormDirty: true
            });
            return;
        }

        this.updateDirtyState(fieldPath, true);
    },
    setPristineState: function setPristineState(fieldPath) {
        if (!fieldPath) {
            this.setFormState({
                dirtyStates: {},
                isFormDirty: false
            });
            return;
        }

        this.updateDirtyState(fieldPath, false);
    },
    updateDirtyState: function updateDirtyState(fieldPath, dirtyState) {
        if (this.isDirty(fieldPath) === dirtyState) {
            return;
        }

        var _getFormState = this.getFormState();

        var dirtyStates = _getFormState.dirtyStates;

        dirtyStates = _lodash2.default.cloneDeep(dirtyStates || {});
        _lodash2.default.set(dirtyStates, fieldPath, dirtyState);

        this.setFormState({
            dirtyStates: dirtyStates
        });
    }
});<commit_msg>Build<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _yupValidationStrategy = require('yup-validation-strategy');

var _yupValidationStrategy2 = _interopRequireDefault(_yupValidationStrategy);

var _baobabPropTypes = require('baobab-prop-types');

var _baobabPropTypes2 = _interopRequireDefault(_baobabPropTypes);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.default = _react2.default.createClass({
    displayName: 'form',

    propTypes: {
        onSubmit: _react2.default.PropTypes.func,
        onInvalidSubmit: _react2.default.PropTypes.func,
        cursor: _baobabPropTypes2.default.cursor.isRequired,

        // TODO: concretize type
        validationSchema: _react2.default.PropTypes.any.isRequired,
        formStateCursor: _baobabPropTypes2.default.cursor,
        validateOnFly: _react2.default.PropTypes.bool,
        useHtmlForm: _react2.default.PropTypes.bool
    },

    childContextTypes: {
        form: _react2.default.PropTypes.object
    },

    contextTypes: {
        form: _react2.default.PropTypes.object
    },

    subscribers: [],
    _isHtmlForm: null,

    getDefaultProps: function getDefaultProps() {
        return {
            validateOnFly: true,
            strategy: (0, _yupValidationStrategy2.default)(),
            onSubmit: _lodash2.default.identity,
            onInvalidSubmit: _lodash2.default.identity,
            useHtmlForm: true
        };
    },
    getChildContext: function getChildContext() {
        return {
            form: {
                parentForm: this.context.form,
                isHtmlForm: this.isHtmlForm,

                cursor: this.props.cursor,
                isValid: this.isValid,
                isDirty: this.isDirty,
                getValidationErrors: this.getValidationErrors,
                setDirtyState: this.setDirtyState,
                setPristineState: this.setPristineState,

                submit: this.submit,
                validate: this.validate,

                subscribe: this.subscribe,
                unsubscribe: this.unsubscribe
            }
        };
    },
    getInitialState: function getInitialState() {
        if (this.props.formStateCursor) {
            return {};
        }

        return {
            errors: {},
            dirtyStates: {},
            isFormDirty: false
        };
    },
    componentDidMount: function componentDidMount() {
        if (this.props.validateOnFly) {
            this.props.cursor.on('update', this.onUpdate);
        }

        this.validate();
    },
    componentWillUnmount: function componentWillUnmount() {
        if (this.props.validateOnFly) {
            this.props.cursor.off('update', this.onUpdate);
        }
    },
    render: function render() {
        if (this.isHtmlForm()) {
            return _react2.default.createElement(
                'form',
                _extends({ noValidate: true }, this.props, { onSubmit: this.onFormSubmit }),
                this.props.children
            );
        }

        return _react2.default.createElement(
            'div',
            this.props,
            this.props.children
        );
    },
    hasParentHtmlForm: function hasParentHtmlForm() {
        var parentForm = this.context.form;

        while (parentForm) {
            if (parentForm.isHtmlForm()) {
                return true;
            }

            parentForm = parentForm.parentForm;
        }
    },
    isHtmlForm: function isHtmlForm() {
        if (this._isHtmlForm === null) {
            this._isHtmlForm = this.props.useHtmlForm && !this.hasParentHtmlForm();
        }

        return this._isHtmlForm;
    },
    publish: function publish() {
        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
        }

        _lodash2.default.each(this.subscribers, function (subscriber) {
            return subscriber.apply(undefined, args);
        });
    },
    subscribe: function subscribe(subscriber) {
        this.subscribers = _lodash2.default.concat(this.subscribers, subscriber);

        // Notify new subscriber about initial form state
        subscriber(this.getFormState(), null);
    },
    unsubscribe: function unsubscribe(subscriber) {
        this.subscribers = _lodash2.default.without(this.subscribers, subscriber);
    },
    onFormStateUpdate: function onFormStateUpdate(data, previousData) {
        // Notify subscribers about changed data only
        if (_lodash2.default.isEqual(data, previousData)) {
            return;
        }

        this.publish(data, previousData);
    },
    setFormState: function setFormState(nextState) {
        var _this = this;

        // It is necessary because validation strategy is asynchronous and validation's
        // callback might be called after component unmount
        if (!this.isMounted()) {
            return;
        }

        var prevState = this.getFormState();

        if (this.props.formStateCursor) {
            this.props.formStateCursor.once('update', function (_ref) {
                var data = _ref.data;
                return _this.onFormStateUpdate(data.currentData, prevState);
            });
            this.props.formStateCursor.merge(nextState);
        } else {
            this.setState(nextState, function () {
                return _this.onFormStateUpdate(_this.state, prevState);
            });
        }
    },
    getFormState: function getFormState() {
        if (this.props.formStateCursor) {
            return this.props.formStateCursor.get();
        }

        return this.state;
    },
    onFormSubmit: function onFormSubmit(event) {
        event.preventDefault();
        event.stopPropagation();

        return this.submit();
    },
    onUpdate: function onUpdate() {
        this.validate();
    },
    submit: function submit() {
        return this.validate(this.props.onSubmit, this.props.onInvalidSubmit);
    },
    getFormData: function getFormData() {
        return this.props.cursor.get();
    },
    validate: function validate(successCallback, errorCallback) {
        var _this2 = this;

        var data = this.getFormData();
        var schema = _lodash2.default.isFunction(this.props.validationSchema) ? this.props.validationSchema(data) : this.props.validationSchema;

        this.props.strategy.validate(data, schema, {}, function (errors) {
            _this2.setFormState({ errors: errors });

            if (_lodash2.default.isEmpty(errors)) {
                if (successCallback) {
                    return successCallback(data);
                }
            } else {
                if (errorCallback) {
                    return errorCallback(errors);
                }
            }
        });
    },
    getValidationErrors: function getValidationErrors(fieldPath) {
        var formState = this.getFormState();
        if (fieldPath) {
            return _lodash2.default.get(formState.errors, fieldPath);
        }

        return formState.errors;
    },
    isValid: function isValid(fieldPath) {
        var formState = this.getFormState();

        if (fieldPath) {
            return !_lodash2.default.get(formState.errors, fieldPath);
        }

        return _lodash2.default.isEmpty(formState.errors);
    },
    isDirty: function isDirty(fieldPath) {
        var formState = this.getFormState();
        var isFormDirty = formState.isFormDirty;

        if (isFormDirty) {
            return true;
        }

        if (!fieldPath) {
            return !_lodash2.default.isEmpty(formState.dirtyStates);
        }

        return !!_lodash2.default.get(formState.dirtyStates, fieldPath);
    },
    resetValidationErrors: function resetValidationErrors() {
        this.setValidationErrors({});
    },
    setValidationErrors: function setValidationErrors(errors) {
        this.setFormState({
            errors: errors
        });
    },
    setDirtyState: function setDirtyState(fieldPath) {
        if (!fieldPath) {
            this.setFormState({
                dirtyStates: {},
                isFormDirty: true
            });
            return;
        }

        this.updateDirtyState(fieldPath, true);
    },
    setPristineState: function setPristineState(fieldPath) {
        if (!fieldPath) {
            this.setFormState({
                dirtyStates: {},
                isFormDirty: false
            });
            return;
        }

        this.updateDirtyState(fieldPath, false);
    },
    updateDirtyState: function updateDirtyState(fieldPath, dirtyState) {
        if (this.isDirty(fieldPath) === dirtyState) {
            return;
        }

        var _getFormState = this.getFormState();

        var dirtyStates = _getFormState.dirtyStates;

        dirtyStates = _lodash2.default.cloneDeep(dirtyStates || {});
        _lodash2.default.set(dirtyStates, fieldPath, dirtyState);

        this.setFormState({
            dirtyStates: dirtyStates
        });
    }
});<|endoftext|>


<commit_before>;(function () {
    function initWatch (vm, watch) {
        vm._watchers || (vm._watchers = []);
        for (var key in watch) {
            var handler = watch[key];
            if (BI.isArray(handler)) {
                for (var i = 0; i < handler.length; i++) {
                    vm._watchers.push(createWatcher(vm, key, handler[i]));
                }
            } else {
                vm._watchers.push(createWatcher(vm, key, handler));
            }
        }
    }

    function createWatcher (vm, keyOrFn, handler) {
        return Fix.watch(vm.model, keyOrFn, _.bind(handler, vm), {
            store: vm.store
        });
    }

    var target = null;
    const targetStack = [];

    function pushTarget (_target) {
        if (target) targetStack.push(target);
        Fix.Model.target = target = _target;
    }

    function popTarget () {
        Fix.Model.target = target = targetStack.pop();
    }

    var oldWatch = Fix.watch;
    Fix.watch = function (model, expOrFn, cb, options) {
        if (BI.isPlainObject(cb)) {
            options = cb;
            cb = cb.handler;
        }
        if (typeof cb === "string") {
            cb = model[cb];
        }
        return oldWatch.call(this, model, expOrFn, function () {
            pushTarget(options.store);
            var res = cb.apply(this, arguments);
            popTarget();
            return res;
        }, options);
    };

    function findStore (widget) {
        var p = widget;
        while (p) {
            if (p.store || p.__cacheStore) {
                break;
            }
            p = p._parent || (p.options && p.options.element);
        }
        if (p) {
            widget.__cacheStore = p.store;
            return p.__cacheStore || p.store;
        }
        throw new Error("找不到store");
    }

    var _init = BI.Widget.prototype._init;
    BI.Widget.prototype._init = function () {
        var needPop = false;
        if (window.Fix && this._store) {
            this.store = this._store();
            pushTarget(this.store);
            if (this.store instanceof Fix.Model) {
                this.model = this.store.model;
            } else {
                this.model = this.store;
            }
            initWatch(this, this.watch);
            needPop = true;
        }
        _init.apply(this, arguments);
        needPop && popTarget();
    };

    var unMount = BI.Widget.prototype.__d;
    BI.Widget.prototype.__d = function () {
        unMount.apply(this, arguments);
        this.store && BI.isFunction(this.store.destroy) && this.store.destroy();
        BI.each(this._watchers, function (i, unwatches) {
            unwatches = BI.isArray(unwatches) ? unwatches : [unwatches];
            BI.each(unwatches, function (j, unwatch) {
                unwatch();
            });
        });
        this._watchers && (this._watchers = []);
        this.store && (this.store._parent = null, this.store = null);
    };

    _.each(["_mount", "populate"], function (name) {
        var old = BI.Widget.prototype[name];
        old && (BI.Widget.prototype[name] = function () {
            var store = findStore(this);
            store && pushTarget(store);
            var res = old.apply(this, arguments);
            store && popTarget();
            return res;
        });
    });

    _.each(["each", "map", "reduce", "reduceRight", "find", "filter", "reject", "every", "all", "some", "any", "max", "min",
        "sortBy", "groupBy", "indexBy", "countBy", "partition",
        "keys", "allKeys", "values", "pairs", "invert",
        "mapObject", "findKey", "pick", "omit", "tap"], function (name) {
        var old = BI[name];
        BI[name] = function (obj, fn) {
            return typeof fn === "function" ? old(obj, function (key, value) {
                if (!(key in Fix.$$skipArray)) {
                    return fn.apply(this, arguments);
                }
            }) : old.apply(this, arguments);
        };
    });
}());<commit_msg>update<commit_after>;(function () {
    function initWatch (vm, watch) {
        vm._watchers || (vm._watchers = []);
        for (var key in watch) {
            var handler = watch[key];
            if (BI.isArray(handler)) {
                for (var i = 0; i < handler.length; i++) {
                    vm._watchers.push(createWatcher(vm, key, handler[i]));
                }
            } else {
                vm._watchers.push(createWatcher(vm, key, handler));
            }
        }
    }

    function createWatcher (vm, keyOrFn, handler) {
        return Fix.watch(vm.model, keyOrFn, _.bind(handler, vm), {
            store: vm.store
        });
    }

    var target = null;
    const targetStack = [];

    function pushTarget (_target) {
        if (target) targetStack.push(target);
        Fix.Model.target = target = _target;
    }

    function popTarget () {
        Fix.Model.target = target = targetStack.pop();
    }

    var oldWatch = Fix.watch;
    Fix.watch = function (model, expOrFn, cb, options) {
        if (BI.isPlainObject(cb)) {
            options = cb;
            cb = cb.handler;
        }
        if (typeof cb === "string") {
            cb = model[cb];
        }
        return oldWatch.call(this, model, expOrFn, function () {
            pushTarget(options.store);
            var res = cb.apply(this, arguments);
            popTarget();
            return res;
        }, options);
    };

    function findStore (widget) {
        var p = widget;
        while (p) {
            if (p.store || p.__cacheStore) {
                break;
            }
            p = p._parent || (p.options && p.options.element);
        }
        if (p) {
            widget.__cacheStore = p.store;
            return p.__cacheStore || p.store;
        }
    }

    var _init = BI.Widget.prototype._init;
    BI.Widget.prototype._init = function () {
        var needPop = false;
        if (window.Fix && this._store) {
            var store = findStore(this.options.element);
            if (store) {
                pushTarget(store);
                needPop = true;
            }
            this.store = this._store();
            needPop && popTarget();
            needPop = false;
            pushTarget(this.store);
            if (this.store instanceof Fix.Model) {
                this.model = this.store.model;
            } else {
                this.model = this.store;
            }
            initWatch(this, this.watch);
            needPop = true;
        }
        _init.apply(this, arguments);
        needPop && popTarget();
    };

    var unMount = BI.Widget.prototype.__d;
    BI.Widget.prototype.__d = function () {
        unMount.apply(this, arguments);
        this.store && BI.isFunction(this.store.destroy) && this.store.destroy();
        BI.each(this._watchers, function (i, unwatches) {
            unwatches = BI.isArray(unwatches) ? unwatches : [unwatches];
            BI.each(unwatches, function (j, unwatch) {
                unwatch();
            });
        });
        this._watchers && (this._watchers = []);
        this.store && (this.store._parent = null, this.store = null);
    };

    _.each(["_mount", "populate"], function (name) {
        var old = BI.Widget.prototype[name];
        old && (BI.Widget.prototype[name] = function () {
            this.store && pushTarget(this.store);
            var res = old.apply(this, arguments);
            this.store && popTarget();
            return res;
        });
    });

    _.each(["each", "map", "reduce", "reduceRight", "find", "filter", "reject", "every", "all", "some", "any", "max", "min",
        "sortBy", "groupBy", "indexBy", "countBy", "partition",
        "keys", "allKeys", "values", "pairs", "invert",
        "mapObject", "findKey", "pick", "omit", "tap"], function (name) {
        var old = BI[name];
        BI[name] = function (obj, fn) {
            return typeof fn === "function" ? old(obj, function (key, value) {
                if (!(key in Fix.$$skipArray)) {
                    return fn.apply(this, arguments);
                }
            }) : old.apply(this, arguments);
        };
    });
}());<|endoftext|>