diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb4697d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +_site +*~ +*# diff --git a/_assets/images/body/arrow-down.png b/_assets/images/body/arrow-down.png new file mode 100644 index 0000000..37ad8d4 Binary files /dev/null and b/_assets/images/body/arrow-down.png differ diff --git a/_assets/images/body/arrow-right.png b/_assets/images/body/arrow-right.png new file mode 100644 index 0000000..bccb689 Binary files /dev/null and b/_assets/images/body/arrow-right.png differ diff --git a/_assets/images/body/black_down_arrow.png b/_assets/images/body/black_down_arrow.png new file mode 100644 index 0000000..578714c Binary files /dev/null and b/_assets/images/body/black_down_arrow.png differ diff --git a/_assets/images/body/buttons/download.png b/_assets/images/body/buttons/download.png new file mode 100644 index 0000000..5c01942 Binary files /dev/null and b/_assets/images/body/buttons/download.png differ diff --git a/_assets/images/body/buttons/download_redphone.png b/_assets/images/body/buttons/download_redphone.png new file mode 100644 index 0000000..f817ee9 Binary files /dev/null and b/_assets/images/body/buttons/download_redphone.png differ diff --git a/_assets/images/body/buttons/download_textSecure.png b/_assets/images/body/buttons/download_textSecure.png new file mode 100644 index 0000000..83729bc Binary files /dev/null and b/_assets/images/body/buttons/download_textSecure.png differ diff --git a/_assets/images/body/buttons/get_info.png b/_assets/images/body/buttons/get_info.png new file mode 100644 index 0000000..3b641ce Binary files /dev/null and b/_assets/images/body/buttons/get_info.png differ diff --git a/_assets/images/body/buttons/see_more_apps.png b/_assets/images/body/buttons/see_more_apps.png new file mode 100644 index 0000000..738c6f3 Binary files /dev/null and b/_assets/images/body/buttons/see_more_apps.png differ diff --git a/_assets/images/body/checkmark.png b/_assets/images/body/checkmark.png new file mode 100644 index 0000000..c8ad5b7 Binary files /dev/null and b/_assets/images/body/checkmark.png differ diff --git a/_assets/images/body/full_device.png b/_assets/images/body/full_device.png new file mode 100644 index 0000000..cef3694 Binary files /dev/null and b/_assets/images/body/full_device.png differ diff --git a/_assets/images/body/full_redphone_device.png b/_assets/images/body/full_redphone_device.png new file mode 100644 index 0000000..e549cad Binary files /dev/null and b/_assets/images/body/full_redphone_device.png differ diff --git a/_assets/images/body/galaxy_nexus.png b/_assets/images/body/galaxy_nexus.png new file mode 100644 index 0000000..c38538f Binary files /dev/null and b/_assets/images/body/galaxy_nexus.png differ diff --git a/_assets/images/body/half_phone_dialing.png b/_assets/images/body/half_phone_dialing.png new file mode 100644 index 0000000..18ec077 Binary files /dev/null and b/_assets/images/body/half_phone_dialing.png differ diff --git a/_assets/images/body/half_phone_verify.png b/_assets/images/body/half_phone_verify.png new file mode 100644 index 0000000..a99ede7 Binary files /dev/null and b/_assets/images/body/half_phone_verify.png differ diff --git a/_assets/images/body/icons.png b/_assets/images/body/icons.png new file mode 100644 index 0000000..b15d488 Binary files /dev/null and b/_assets/images/body/icons.png differ diff --git a/_assets/images/body/rss.png b/_assets/images/body/rss.png new file mode 100644 index 0000000..5f414be Binary files /dev/null and b/_assets/images/body/rss.png differ diff --git a/_assets/images/body/texture.png b/_assets/images/body/texture.png new file mode 100644 index 0000000..c004a69 Binary files /dev/null and b/_assets/images/body/texture.png differ diff --git a/_assets/images/body/texture_light.png b/_assets/images/body/texture_light.png new file mode 100644 index 0000000..9c2296b Binary files /dev/null and b/_assets/images/body/texture_light.png differ diff --git a/_assets/images/body/two_phones.png b/_assets/images/body/two_phones.png new file mode 100644 index 0000000..687fd9d Binary files /dev/null and b/_assets/images/body/two_phones.png differ diff --git a/_assets/images/body/white_down_arrow.png b/_assets/images/body/white_down_arrow.png new file mode 100644 index 0000000..ee07703 Binary files /dev/null and b/_assets/images/body/white_down_arrow.png differ diff --git a/_assets/images/header/favicon.ico b/_assets/images/header/favicon.ico new file mode 100644 index 0000000..458a332 Binary files /dev/null and b/_assets/images/header/favicon.ico differ diff --git a/_assets/images/header/mobile.png b/_assets/images/header/mobile.png new file mode 100644 index 0000000..67948ac Binary files /dev/null and b/_assets/images/header/mobile.png differ diff --git a/_assets/images/header/raven.png b/_assets/images/header/raven.png new file mode 100644 index 0000000..4be41c4 Binary files /dev/null and b/_assets/images/header/raven.png differ diff --git a/_assets/images/header/social_icons.png b/_assets/images/header/social_icons.png new file mode 100644 index 0000000..a846f36 Binary files /dev/null and b/_assets/images/header/social_icons.png differ diff --git a/_assets/images/header/spacer.png b/_assets/images/header/spacer.png new file mode 100644 index 0000000..b541977 Binary files /dev/null and b/_assets/images/header/spacer.png differ diff --git a/_assets/images/header/telephone.png b/_assets/images/header/telephone.png new file mode 100644 index 0000000..3147b39 Binary files /dev/null and b/_assets/images/header/telephone.png differ diff --git a/_assets/images/header/telephone_solid.png b/_assets/images/header/telephone_solid.png new file mode 100644 index 0000000..962fb62 Binary files /dev/null and b/_assets/images/header/telephone_solid.png differ diff --git a/_assets/images/header/whispersystems.png b/_assets/images/header/whispersystems.png new file mode 100644 index 0000000..e8b9330 Binary files /dev/null and b/_assets/images/header/whispersystems.png differ diff --git a/_assets/images/screens/green1.jpg b/_assets/images/screens/green1.jpg new file mode 100644 index 0000000..f9f32ea Binary files /dev/null and b/_assets/images/screens/green1.jpg differ diff --git a/_assets/images/screens/green2.jpg b/_assets/images/screens/green2.jpg new file mode 100644 index 0000000..f0d52f4 Binary files /dev/null and b/_assets/images/screens/green2.jpg differ diff --git a/_assets/images/screens/green3.jpg b/_assets/images/screens/green3.jpg new file mode 100644 index 0000000..1a3c581 Binary files /dev/null and b/_assets/images/screens/green3.jpg differ diff --git a/_assets/images/screens/red1.jpg b/_assets/images/screens/red1.jpg new file mode 100644 index 0000000..05377dc Binary files /dev/null and b/_assets/images/screens/red1.jpg differ diff --git a/_assets/images/screens/red2.jpg b/_assets/images/screens/red2.jpg new file mode 100644 index 0000000..328eaee Binary files /dev/null and b/_assets/images/screens/red2.jpg differ diff --git a/_assets/images/screens/redphone_connected.png b/_assets/images/screens/redphone_connected.png new file mode 100644 index 0000000..1238b21 Binary files /dev/null and b/_assets/images/screens/redphone_connected.png differ diff --git a/_assets/images/screens/redphone_dialer.png b/_assets/images/screens/redphone_dialer.png new file mode 100644 index 0000000..bd935af Binary files /dev/null and b/_assets/images/screens/redphone_dialer.png differ diff --git a/_assets/images/screens/redphone_incoming.png b/_assets/images/screens/redphone_incoming.png new file mode 100644 index 0000000..7caa5fa Binary files /dev/null and b/_assets/images/screens/redphone_incoming.png differ diff --git a/_assets/images/screens/redphone_upgrade.png b/_assets/images/screens/redphone_upgrade.png new file mode 100644 index 0000000..db87f92 Binary files /dev/null and b/_assets/images/screens/redphone_upgrade.png differ diff --git a/_assets/images/screens/textsecure_conversationlist.png b/_assets/images/screens/textsecure_conversationlist.png new file mode 100644 index 0000000..3579519 Binary files /dev/null and b/_assets/images/screens/textsecure_conversationlist.png differ diff --git a/_assets/images/screens/textsecure_passphrase.png b/_assets/images/screens/textsecure_passphrase.png new file mode 100644 index 0000000..7439a9a Binary files /dev/null and b/_assets/images/screens/textsecure_passphrase.png differ diff --git a/_assets/images/screens/textsecure_upgrade.png b/_assets/images/screens/textsecure_upgrade.png new file mode 100644 index 0000000..1eb497d Binary files /dev/null and b/_assets/images/screens/textsecure_upgrade.png differ diff --git a/_assets/javascripts/main.js b/_assets/javascripts/main.js new file mode 100644 index 0000000..546d6eb --- /dev/null +++ b/_assets/javascripts/main.js @@ -0,0 +1,75 @@ + +jQuery(function($) { + $('.scroll').click(function() { + var anchor_name = $(this).attr('href').split('#')[1]; + var anchor = $('#' + anchor_name); + $('html, body').animate({ + scrollTop: anchor.offset().top + }, 600); + return false; + }); + + var redphone_carousel_paused = false; + var textsecure_carousel_paused = false; + + $('#redphone_carousel').carousel(); + $('#textsecure_carousel').carousel(); + + $("#encrypted_voice .features a").click(function(e){ + e.preventDefault(); + var index = parseInt($(this).attr('data-to')); + redphone_carousel_paused = true; + $('#redphone_carousel').carousel(index); + var nav = $('#encrypted_voice .features'); + var item = nav.find('a').get(index); + nav.find('a.active').removeClass('active'); + $(item).addClass('active'); + }); + + $("#encrypted_texts .features a").click(function(e){ + e.preventDefault(); + var index = parseInt($(this).attr('data-to')); + textsecure_carousel_paused = true; + $('#textsecure_carousel').carousel(index); + var nav = $('#encrypted_texts .features'); + var item = nav.find('a').get(index); + nav.find('a.active').removeClass('active'); + $(item).addClass('active'); + }); + + + $("#redphone_carousel").bind('slide', function(e) { + var elements = 4; + var nav = $('#encrypted_voice .features'); + var index = $('#redphone_carousel').find('.item.active').index(); + index = (index == elements - 1) ? 0 : index + 1; + var item = nav.find('a').get(index); + nav.find('a.active').removeClass('active'); + $(item).addClass('active'); + }); + + $("#textsecure_carousel").bind('slide', function(e) { + var elements = 3; + var nav = $('#encrypted_texts .features'); + var index = $('#textsecure_carousel').find('.item.active').index(); + index = (index == elements - 1) ? 0 : index + 1; + var item = nav.find('a').get(index); + nav.find('a.active').removeClass('active'); + $(item).addClass('active'); + }); + + $("#redphone_carousel").bind('slid', function(e) { + if (redphone_carousel_paused) { + $('#redphone_carousel').carousel("pause"); + $('#redphone_carousel').carousel({interval: false}); + } + }); + + $("#textsecure_carousel").bind('slid', function(e) { + if (textsecure_carousel_paused) { + $('#textsecure_carousel').carousel("pause"); + $('#textsecure_carousel').carousel({interval: false}); + } + }); +}); + diff --git a/_assets/javascripts/vendor/bootstrap-carousel.js b/_assets/javascripts/vendor/bootstrap-carousel.js new file mode 100644 index 0000000..238ff42 --- /dev/null +++ b/_assets/javascripts/vendor/bootstrap-carousel.js @@ -0,0 +1,185 @@ +/* ========================================================== + * bootstrap-carousel.js v2.2.2 + * http://twitter.github.com/bootstrap/javascript.html#carousel + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CAROUSEL CLASS DEFINITION + * ========================= */ + + var Carousel = function (element, options) { + this.$element = $(element) + this.options = options + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.prototype = { + + cycle: function (e) { + if (!e) this.paused = false + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + return this + } + + , to: function (pos) { + var $active = this.$element.find('.item.active') + , children = $active.parent().children() + , activePos = children.index($active) + , that = this + + if (pos > (children.length - 1) || pos < 0) return + + if (this.sliding) { + return this.$element.one('slid', function () { + that.to(pos) + }) + } + + if (activePos == pos) { + return this.pause().cycle() + } + + return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos])) + } + + , pause: function (e) { + if (!e) this.paused = true + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle() + } + clearInterval(this.interval) + this.interval = null + return this + } + + , next: function () { + if (this.sliding) return + return this.slide('next') + } + + , prev: function () { + if (this.sliding) return + return this.slide('prev') + } + + , slide: function (type, next) { + var $active = this.$element.find('.item.active') + , $next = next || $active[type]() + , isCycling = this.interval + , direction = type == 'next' ? 'left' : 'right' + , fallback = type == 'next' ? 'first' : 'last' + , that = this + , e + + this.sliding = true + + isCycling && this.pause() + + $next = $next.length ? $next : this.$element.find('.item')[fallback]() + + e = $.Event('slide', { + relatedTarget: $next[0] + }) + + if ($next.hasClass('active')) return + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + this.$element.one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + } + + + /* CAROUSEL PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.carousel + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('carousel') + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) + , action = typeof option == 'string' ? option : options.slide + if (!data) $this.data('carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.cycle() + }) + } + + $.fn.carousel.defaults = { + interval: 5000 + , pause: 'hover' + } + + $.fn.carousel.Constructor = Carousel + + + /* CAROUSEL NO CONFLICT + * ==================== */ + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + /* CAROUSEL DATA-API + * ================= */ + + $(document).on('click.carousel.data-api', '[data-slide]', function (e) { + var $this = $(this), href + , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + , options = $.extend({}, $target.data(), $this.data()) + $target.carousel(options) + e.preventDefault() + }) + +}(window.jQuery); \ No newline at end of file diff --git a/_assets/javascripts/vendor/bootstrap-transition.js b/_assets/javascripts/vendor/bootstrap-transition.js new file mode 100644 index 0000000..b0f12c2 --- /dev/null +++ b/_assets/javascripts/vendor/bootstrap-transition.js @@ -0,0 +1,60 @@ +/* =================================================== + * bootstrap-transition.js v2.2.2 + * http://twitter.github.com/bootstrap/javascript.html#transitions + * =================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $(function () { + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.jQuery); \ No newline at end of file diff --git a/_assets/javascripts/vendor/jquery-1.8.3.min.js b/_assets/javascripts/vendor/jquery-1.8.3.min.js new file mode 100644 index 0000000..83589da --- /dev/null +++ b/_assets/javascripts/vendor/jquery-1.8.3.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/_assets/javascripts/vendor/modernizr-2.6.2-respond-1.1.0.min.js b/_assets/javascripts/vendor/modernizr-2.6.2-respond-1.1.0.min.js new file mode 100644 index 0000000..302f461 --- /dev/null +++ b/_assets/javascripts/vendor/modernizr-2.6.2-respond-1.1.0.min.js @@ -0,0 +1,11 @@ +/* Modernizr 2.6.2 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load + */ +;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f #mq-test-1 { width: 42px; }';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document); + +/*! Respond.js v1.1.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ +(function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this); \ No newline at end of file diff --git a/_assets/stylesheets/bootstrap-carousel.css b/_assets/stylesheets/bootstrap-carousel.css new file mode 100644 index 0000000..f24214c --- /dev/null +++ b/_assets/stylesheets/bootstrap-carousel.css @@ -0,0 +1,114 @@ +/* extracted from bootstrap.css */ + +.carousel { + position: relative; + margin-bottom: 18px; + line-height: 1; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -ms-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel .item > img { + display: block; + line-height: 1; +} + +.carousel .active, +.carousel .next, +.carousel .prev { + display: block; +} + +.carousel .active { + left: 0; +} + +.carousel .next, +.carousel .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel .next { + left: 100%; +} + +.carousel .prev { + left: -100%; +} + +.carousel .next.left, +.carousel .prev.right { + left: 0; +} + +.carousel .active.left { + left: -100%; +} + +.carousel .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.right { + right: 15px; + left: auto; +} + +.carousel-control:hover { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-caption { + position: absolute; + right: 0; + bottom: 0; + left: 0; + padding: 10px 15px 5px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} + +.carousel-caption h4, +.carousel-caption p { + color: #ffffff; +} diff --git a/_assets/stylesheets/main.css.erb b/_assets/stylesheets/main.css.erb new file mode 100644 index 0000000..67e9482 --- /dev/null +++ b/_assets/stylesheets/main.css.erb @@ -0,0 +1,682 @@ +/*********** + * Layout + ***********/ + +body { + font-family: 'OpenSansRegular', Helvetica, Arial, sans-serif; +} + +#wrap { } + +#container { + background-color: #fff; + margin: 0 auto; + min-width: 1140px; + /* max-width: 1500px; */ +} + +.container { + /* min-width: 1140px; + max-width: 1500px; */ + width: 1140px; + margin: 0 auto !important; + padding: 0 !important; +} + + +/******************** + * General Styles + ********************/ + +.clearfix { clear: both; } +.light { font-family: 'OpenSansLight', Helvetica, Arial, sans-serif; } +.red { color: #be4a4a; } +.green { color: #64902a; } +.clearfix { clear: both; } + +.buttons { margin-top: 20px; } + +.button { + display: inline-block; + margin: 20px; + margin-top: 15px; + text-decoration: none; + line-height: 62px; + width: 275px; + height: 66px; + text-align: center; +} +.button-download { + color: white; + background-color: #212121; + background-image: url(<%= asset_path "body/buttons/download.png" %>); + font-family: 'OpenSansLight', Helvetica, Arial, sans-serif; +} +.button-download .arrow { + padding-left: 5px; +} +.button-info { + font-family: 'OpenSansSemibold', Helvetica, Arial, sans-serif; + background-image: url(<%= asset_path "body/buttons/get_info.png" %>); + color: #333; +} +.button-info .arrow { + padding-left: 5px; +} + +.button:hover { + opacity: 0.85; +} + + +/********** + * Navbar + **********/ + +.bar-wrap { + width: 100%; + background-color: #171717; +} + +.bar { + height: 79px; + position: relative; + width: 1140px; + margin: 0 auto; +} +.bar ul { + margin: 0; + list-style: none; + position: absolute; + top: 5px; + right: 20px; +} +.bar li { + float: left; +} +.bar li a { + text-decoration: none; + line-height: 50px; + display: block; + float: none; + padding: 10px 15px; + color: #cecece; + text-transform: uppercase; + font-weight: bold; + font-size: 12px; +} +.bar li a:hover { text-decoration: underline; } +.bar li a.facebook, +.bar li a.twitter { + display: block; + width: 42px; + height: 34px; + margin-top: 14px; + margin-left: 8px; + padding: 0; + text-indent: -9000px; + background-image: url(<%= asset_path "header/social_icons.png" %>); + +} +.bar li a.twitter { + background-position: 42px 0; +} +.bar .notice { + font-size: 14px; + margin-left: 58px; + padding: 15px 0 0 0; + float: left; + color: #cecece; +} + +/********** + * Header + **********/ + +.main-head { + background-color: #171717; + min-width: 1140px; +} +.header-graphics { + overflow: visible; + width: 420px; + height: 19px; + z-index: 10; + position: relative; + margin-left: 40px; + vertical-align: top; +} +.header-graphics a { text-decoration: none; } +.header-graphics img { + vertical-align: top; +} + +#telephone { + background-color: #696969; + text-align: right; + background-image: url(<%= asset_path "header/telephone.png" %>); + background-repeat: no-repeat; + position: relative; + width: 100%; + background-size: auto 100%; /* cover */ + background-position: center; + height: 480px; +} +#telephone .text { + margin-top: 0; /* if this is not here, messes up bar size above. */ + padding-top: 160px; + text-align: right; + width: 1140px; + margin: 0 auto; +} +#telephone .tagline1 { + padding: 0 20px 0 0; + margin: 0; + margin-top: 30px; + color: white; + font-size: 48px; + font-family: 'BitterRegular', serif; +} +#telephone .tagline2 { + padding: 0 20px 0 0; + margin: 0; + margin-top: 10px; + color: #eee; + font-size: 22px; + font-family: 'OpenSansLight', Helvetica, Arial, sans-serif; +} +#telephone .tagline2 strong { + font-weight: normal; + font-family: 'OpenSansSemibold', Helvetica, Arial, sans-serif; +} + +.solutions { + color: white; + height: 100px; + padding-left: 100px; + position: relative; +} +.solutions p { + padding-left: 360px; + float: left; + font-size: 28px; + color: #ddd; + font-family: 'BitterRegular', serif; +/* font-family: 'Merriweather', serif; */ +} +.solutions .mobileicons { + position: absolute; +/* top: 50px;*/ + top: 15px; + right: 260px; +} + +.solutions .spacer { + position: absolute; + top: 15px; + right: 565px; +} + +/********** + * Body + **********/ + +#blog { + clear: both; + background-image: url(<%= asset_path "body/black_down_arrow.png" %>); + background-repeat: no-repeat; + background-position: 150px 0; + width: 1000px; + margin-left: auto; + margin-right: auto; + margin-bottom: 100px; + min-height: 431px; +} + +#blog #title { + margin-left: 140px; +} + +#blog #title h2 { + margin: 0px; + padding-top: 20px; + color: #aaa; + font-size: 46px; + font-weight: normal; + font-family: 'OpenSansLight', Helvetica, Arial, sans-serif; + line-height: normal; +} + +#blog article.snippet { + padding-top: 20px; +} + +#blog h2 { + color: #555; + font-size: 30px; + font-weight: normal; + font-family: 'BitterRegular', serif; + margin: 0; + padding: 0; + padding-top: 15px; + padding-bottom: 10px; + line-height: 105%; +/* line-height: 28px;*/ +} + +#blog article.snippet h2 { + padding:0; +} + +#blog h2 a { + text-decoration: none; +/* color: #333;*/ + color: inherit; +} + +#blog h2 a:hover { + color: #666; +} + +#blog h3.date { + font-family: 'OpenSansLight', Helvetica, Arial, sans-serif; + font-size: 12px; + color: #aaa; + margin: 0px; + padding: 0px; +} + +#blog article { + margin-left: 140px; + font: 100%/1.5em 'Nobile'; + font-weight: normal; + padding-right: 100px; +/* margin-left: 200px;*/ +} + +#blog p a { + text-decoration: none; + color: #888; +} + +#blog p a:hover { + color: #333; +} + + +#blog ul a { + text-decoration: none; + color: #888; +} + +#blog ul a:hover { + color: #333; +} + +#blog article img.nice { + max-width: 100%; + padding: 6px; + box-shadow: 0px 0px 5px #888; + display: block; + margin-left: auto; + margin-right: auto; + margin-bottom: 15px; +} + +#blog article img.nice-left { + max-width: 100%; + padding: 6px; + box-shadow: 0px 0px 5px #888; + display: block; + margin-right: 20px; + margin-bottom: 40px; + float: left; + clear: both; +} + + +#blog blockquote { + margin: 1em 40px; + position: relative; + text-align: justify; +} + +#blog blockquote:before { + display: block; + content: "\201C"; + font-size: 80px; + position: absolute; + left: -40px; + top: 20px; + color: #7a7a7a; +} + +ul.social-buttons{ + float: left; + list-style: none; + margin: 15px 0 30px 0; + padding: 0; +} + +ul.social-buttons li{ + display: block; + float: left; + margin-right: 10px; +} + + +#main { + clear: both; + background-image: url(<%= asset_path "body/black_down_arrow.png" %>); + background-repeat: no-repeat; + background-position: center 0; +} + +#main article { + clear: both; + padding: 60px 0 40px 0; + min-width: 1140px; +} +#main article h2 { + color: #333; + font-size: 36px; + text-align: center; + font-weight: normal; + font-family: 'BitterRegular', serif; +} +#main article h3 { + color: #555; + text-align: center; + font-weight: normal; + font-family: 'OpenSansLight', Helvetica, Arial, sans-serif; + font-size: 22px; +/* padding: 0px 110px 30px;*/ + padding-bottom: 30px; +} +#main article h3 strong { + font-weight: normal; + font-family: 'OpenSansSemibold', Helvetica, Arial, sans-serif; +} + +.checkpoints { + width: 60%; + float: left; + padding-left: 30px; +} +.checkpoint { + color: #555; + background-image: url(<%= asset_path "body/checkmark.png" %>); + background-repeat: no-repeat; + padding-left: 100px; + height: 70px; + margin-bottom: 60px; + margin-top: 20px; +} +.checkpoint h4 { + font-size: 22px; + font-weight: normal; + margin: 0; +} +.checkpoint h4 strong { + font-weight: normal; + font-family: 'OpenSansSemibold', Helvetica, Arial, sans-serif; +} +.checkpoint p { + margin: 5px 0; + font-size: 16px; +} + +#privacy { height: 500px; } +#privacy .illustration { + float: right; + margin-right: 10px; +} + +.striped { + background-image: url(<%= asset_path "body/texture.png" %>); + background-color: #eee; + border-top: 1px dashed #ddd; + border-bottom: 1px dashed #ddd; +} +#encrypted_texts .striped { + background-image: url(<%= asset_path "body/texture_light.png" %>); + background-color: #fafafa; +} + +ul.features { + list-style: none; + color: #555; + padding-top: 10px; + width: 300px; +} + +ul.features li { + display: block; + padding: 12px 25px; + margin-right: 10px; + width: 380px; + float: left; + position: relative; +} + +ul.features li a { + text-decoration: none; + color: inherit; + opacity: 0.7; +} + +ul.features li a.active { + opacity: 1; +} + +#encrypted_voice { + background-color: #faf9f9; + position: relative; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + height: 850px; +} + +#encrypted_voice h3 { + padding-left: 220px; + padding-right: 220px; +} + +#encrypted_voice .carousel-container { + width: 585px; + position: absolute; + right: 50%; + bottom: 0; + height: 50px; + /*background-color: red; */ +} +#encrypted_voice .carousel-frame { + position: absolute; + bottom: -75px; +} + + +#encrypted_voice ul.features { margin-left: 550px; } +#encrypted_voice .buttons { margin-left: 550px; } + +#encrypted_texts { + height: 850px; + position: relative; +} + +#encrypted_texts h3 { + padding-left: 150px; + padding-right: 150px; +} + +#encrypted_texts ul.features { + margin-left: 190px; + margin-right: 100px; +} + +#encrypted_texts .carousel-container { + position: absolute; + width: 550px; + bottom: 0; + left: 50%; +/* height: 50px;*/ + /* background-color: red; */ +} + +#encrypted_texts .carousel-frame { + position: absolute; + left: 240px; + bottom: -50px; +} + +#encrypted_texts .buttons { + margin-left: 190px; + width: 500px; +} + +#bottom { + padding-top: 50px; + height: 75px; + background-color: #222; + text-align: center; + color: #fff; + font-size: 25px; + background-image: url(<%= asset_path "body/white_down_arrow.png" %>); + background-repeat: no-repeat; + background-position: center -1px; +} + +/**** code blocks ****/ + +code, tt { + margin: 0 2px; + padding: 0 5px; + white-space: nowrap; + border: 1px solid #eaeaea; + background-color: #f8f8f8; + border-radius: 3px; } + +pre code { + margin: 0; + padding: 0; + white-space: pre; + border: none; + background: transparent; } + +.highlight pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; } + +pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; } + pre code, pre tt { + background-color: transparent; + border: none; } + + +/*********** + * Carousel + ***********/ + + +.carousel-frame { + background-repeat: no-repeat; + /* default to a RedPhone phone image */ + background-image: url(<%= asset_path "body/full_device.png" %>); + width: 400px; + padding-left: 31px; + padding-top: 70px; + margin-left: 150px; +} +.carousel { margin-bottom: 0; overflow: hidden; } +.carousel, .carousel img { margin-left: 20px; margin-top: 40px; } +.carousel-inner { width: 290px; height: 699px; } +.carousel .item { overflow: hidden; } +a.carousel-control { text-decoration: none; } + +#textsecure_carousel_frame { + /* override the redphone image with the textsecure phone image */ + background-image: url(<%= asset_path "body/full_device.png" %>); + /* textsecure image has slightly different dimensions */ + padding-left: 29px; + padding-top: 74px; + margin-left: -150px; +} +#textsecure_carousel_frame .carousel, +#textsecure_carousel_frame .carousel img { /*width: 274px;*/ } +#textsecure_carousel_frame .carousel .carousel-inner { /*height: 305px;*/ height: 699px; } + +/********* + * Icons + *********/ + +i.icon { + background-image: url(<%= asset_path "body/icons.png" %>); + background-repeat: no-repeat; + display: inline-block; + position: absolute; + top: 12px; + left: -20px; + width: 30px; + height: 30px; +} + +/* red icons -- 30px wide */ +i.icon.dial { + background-position: -170px 0; +} +i.icon.cell-arrow { + background-position: -140px 0; +} +i.icon.ring { + background-position: -110px 0; +} +i.icon.cycle { + background-position: -80px 0; +} + +/* green icons -- 20px wide */ +i.heart, i.speech, i.alert, i.cell { + width: 21px; + left: -15px; +} + +i.icon.heart { + width: 20px; +} + +i.icon.speech { + background-position: -20px; +} + +i.icon.alert { + background-position: -41px; +} + +i.icon.cell { + background-position: -62px; +} + +.rss { + float: right; + margin-right: 120px; + margin-top: 40px; + opacity: 0.5; +} + +.documentation { + margin: auto; + padding-bottom: 30px; + width: 720px; +} diff --git a/_assets/stylesheets/normalize.css b/_assets/stylesheets/normalize.css new file mode 100644 index 0000000..57b5d26 --- /dev/null +++ b/_assets/stylesheets/normalize.css @@ -0,0 +1,375 @@ +/*! normalize.css v2.0.1 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/* + * Corrects `block` display not defined in IE 8/9. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary { + display: block; +} + +/* + * Corrects `inline-block` display not defined in IE 8/9. + */ + +audio, +canvas, +video { + display: inline-block; +} + +/* + * Prevents modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/* + * Addresses styling for `hidden` attribute not present in IE 8/9. + */ + +[hidden] { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/* + * 1. Sets default font family to sans-serif. + * 2. Prevents iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + -ms-text-size-adjust: 100%; /* 2 */ +} + +/* + * Removes default margin. + */ + +body { + margin: 0; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/* + * Addresses `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/* + * Improves readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/* + * Addresses `h1` font sizes within `section` and `article` in Firefox 4+, + * Safari 5, and Chrome. + */ + +h1 { + font-size: 2em; +} + +/* + * Addresses styling not present in IE 8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/* + * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/* + * Addresses styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/* + * Addresses styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + + +/* + * Corrects font family set oddly in Safari 5 and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +/* + * Improves readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +/* + * Sets consistent quote types. + */ + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +/* + * Addresses inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/* + * Prevents `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/* + * Removes border when inside `a` element in IE 8/9. + */ + +img { + border: 0; +} + +/* + * Corrects overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/* + * Addresses margin not present in IE 8/9 and Safari 5. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/* + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/* + * 1. Corrects color not being inherited in IE 8/9. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/* + * 1. Corrects font family not being inherited in all browsers. + * 2. Corrects font size not being inherited in all browsers. + * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome + */ + +button, +input, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 2 */ + margin: 0; /* 3 */ +} + +/* + * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/* + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Corrects inability to style clickable `input` types in iOS. + * 3. Improves usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/* + * Re-set default cursor for disabled elements. + */ + +button[disabled], +input[disabled] { + cursor: default; +} + +/* + * 1. Addresses box sizing set to `content-box` in IE 8/9. + * 2. Removes excess padding in IE 8/9. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/* + * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/* + * Removes inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* + * Removes inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + * 1. Removes default vertical scrollbar in IE 8/9. + * 2. Improves readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/* ========================================================================== + Tables + ========================================================================== */ + +/* + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..d851a2f --- /dev/null +++ b/_config.yml @@ -0,0 +1,4 @@ +safe: false +auto: true +pygments: true +permalink: /blog/:title diff --git a/_includes/footer.html b/_includes/footer.html new file mode 100644 index 0000000..0083eb9 --- /dev/null +++ b/_includes/footer.html @@ -0,0 +1,44 @@ +
+ Stay in touch, + on Twitter. + +
+ +
+ +
+
+ + + + + + + + + + + + + diff --git a/_includes/nav.html b/_includes/nav.html new file mode 100644 index 0000000..8c5f256 --- /dev/null +++ b/_includes/nav.html @@ -0,0 +1,45 @@ + + + + + + Open WhisperSystems >> {{ page.title }} + + + + + + + + + + + + + + + + +
+
+
+ diff --git a/_layouts/blog.html b/_layouts/blog.html new file mode 100644 index 0000000..3f31227 --- /dev/null +++ b/_layouts/blog.html @@ -0,0 +1,20 @@ +--- +layout: root +--- + +
+ +
+ +
+ {% assign title_parts = page.title | split: ' >> ' %} + {% if title_parts[1] and title_parts.first == "Blog" %} +

Blog >> {{ title_parts[1] }}

+ {% else %} +

{{ page.title }}

+ {% endif %} +
+ + {{ content }} + +
diff --git a/_layouts/doc.html b/_layouts/doc.html new file mode 100644 index 0000000..ceae49d --- /dev/null +++ b/_layouts/doc.html @@ -0,0 +1,9 @@ +--- +layout: root +--- +
+

{{ page.title }}

+
+ {{ content }} +
+
diff --git a/_layouts/post.html b/_layouts/post.html new file mode 100644 index 0000000..eadbb7f --- /dev/null +++ b/_layouts/post.html @@ -0,0 +1,43 @@ +--- +layout: blog +--- + +
+ +{% assign parts = content | split: 'XXXXX' %} +{{ parts.first }} +{% if parts[1] %} +{{ parts[1] }} +{% endif %} + + + +
+ + + + + + + +
diff --git a/_layouts/root.html b/_layouts/root.html new file mode 100644 index 0000000..12826c4 --- /dev/null +++ b/_layouts/root.html @@ -0,0 +1,142 @@ + + + + + + + {% assign title_parts = page.title | split: " " %} + {% if title_parts[0] == "Blog" and title_parts[1] == ">>" %} + + + + + + {% assign title_parts = page.title | split: " >> " %} + + + {% assign content_parts = page.content | split: 'XXXXX' %} + + + {% if page.image %} + + {% endif %} + {% endif %} + + Open WhisperSystems >> {{ page.title }} + + + + + + + {% stylesheet normalize %} + {% stylesheet bootstrap-carousel %} + {% stylesheet main %} + + + + + {% javascript vendor/modernizr-2.6.2-respond-1.1.0.min %} + + + + + + +
+
+
+ + + {% if page.header == true %} +
+
+

Security, simplified.

+

Open Source security for mobile devices.

+
+
+ +
+

Get started.

+ + Mobile Icons +
+ {% endif %} +
+ + {{ content }} + +
+ Stay in touch, + on Twitter. + +
+ +
+ +
+
+
+ + + + + + + {% javascript vendor/bootstrap-transition %} + {% javascript vendor/bootstrap-carousel %} + {% javascript main %} + + + + + + + + diff --git a/_plugins/assets.rb b/_plugins/assets.rb new file mode 100644 index 0000000..b9c6c96 --- /dev/null +++ b/_plugins/assets.rb @@ -0,0 +1 @@ +require "jekyll-assets" diff --git a/_posts/2013-01-21-welcome.md b/_posts/2013-01-21-welcome.md new file mode 100644 index 0000000..1d144f8 --- /dev/null +++ b/_posts/2013-01-21-welcome.md @@ -0,0 +1,23 @@ +--- +title: "Blog >> A New Home" +layout: post +--- + +Whisper Systems was a company focused on the development of mobile security software, which was acquired by +Twitter in late 2011. Twitter very generously made some of the Whisper Systems software available under an +Open Source license (GPLv3), which has since been under open development by the community. The software has +seen a number of new releases based on that open development, and we've been calling the project for this +continued work "Open Whisper Systems." Welcome to the project's new home. + +XXXXX + +This is where we will be promoting, distributing, and coordinating the continued development of mobile security +and privacy software. In an environment of increasingly pervasive surveillance, we want to make it as easy as +possible for anyone to be able to organize and communicate securely. We hope you'll join us. + +Easy ways to get involved are [filing bugs](https://github.com/whispersystems/) (or fixing them!), contributing to +language translations ([here](https://www.transifex.com/projects/p/redphone/) and +[here](https://www.transifex.com/projects/p/textsecure-official)), creating +user [documentation](https://github.com/WhisperSystems/RedPhone/wiki), or +[joining the mailing list](https://lists.riseup.net/www/info/whispersystems). We appreciate all the help we've gotten +thus far, and hope the momentum continues. diff --git a/_posts/2013-01-23-spring-break-of-code.md b/_posts/2013-01-23-spring-break-of-code.md new file mode 100644 index 0000000..8589bdf --- /dev/null +++ b/_posts/2013-01-23-spring-break-of-code.md @@ -0,0 +1,83 @@ +--- +title: "Blog >> Spring Break Of Code" +layout: post +--- + +This Spring will be the first Open Whisper Systems *Spring Break Of Code*, a week-long expenses-paid retreat to +Maui for folks who like software development, security, and the beach. We've rented a large beachfront house on +the west coast of Maui for everyone to stay in, and will pay for your airfare. While there, you can split your +time between island living and working on an Open Whisper Systems related project that you propose. + + + +XXXXX + +## The Details + +*Spring Break Of Code* will be **March 23rd to March 31st, 2013**. We've rented a large beachfront house in Puamana, on +the west coast of Maui, HI (within walking distance to a few surf spots). We will be taking up to eight people, and will +cover your costs for: + +- Lodging in a large beachfront house. +- Your airfare from the US. +- A surfboard for the week. + +*Spring Break Of Code* is an opportunity for hackers interested in security and privacy to spend some time contributing +to Open Whisper Systems related projects in a retreat-like setting with other co-conspirators. Think of it as an extended +hackathon, but with your travel expenses paid, and with breaks for surfing, hiking, swimming, and just generally being in Maui. + +## Interested? + +To apply to *Spring Break Of Code*, send an email to **springbreakofcode@whispersystems.org** with the following information: + +- **Tell us about yourself.** Who are you, where do you live, what have you been working on, and what interests you about + Open Whisper Systems? Don't worry if you are a student or don't have tons of "industry" experience, personal projects + are great. +- **Examples of your work.** Are there other public contributions you've made that you're proud of? +- **What you want to work on for Spring Break Of Code.** This should be something you're excited about that can either + be finished in a week, or that a useful and discrete part of can be finished in a week. Some example ideas could be: + + 1. Any of the open issues on our GitHub trackers ([here](https://github.com/WhisperSystems/TextSecure/issues) or + [here](https://github.com/WhisperSystems/RedPhone/issues/)). + 1. Writing mountains of sorely lacking unit and integration tests. + 1. Doing some much needed design work on any of our apps, icons, etc. + 1. Migrating TextSecure to a page-level DB solution. + 1. Putting together a good solution for user-oriented documentation. + 1. Working on anything for our website. + 1. Adding "push to talk" functionality to RedPhone. + 1. Developing RedPhone distributed call quality measurement and analytics. + 1. Adding a data based (non-SMS) channel to TextSecure. + 1. Writing an application-level multi-master database replication solution for RedPhone master switches. + 1. A plan for iOS TextSecure integration. + 1. A plan for TextSecure identity key management. + + Or anything else you're excited about: fixing broken windows that have annoyed you, writing features you think would + be useful, or even developing a new small app that you think would help. Think of the skills you're good at or interested in, + and how you might be able to apply those to helping our project better achieve the goal of dead-simple mobile security and + privacy for everyone. + + Please include some information about why you're confident you'll be able to complete your project over *Spring Break Of Code*. + +## You should also know... + +We understand that it requires commitment in order to travel great distance and spend a week with people you +might not already know. We'll work hard to ensure that the infrastructure is set up well in order to make +this week great, but we also want to set the framework for the expectations we believe we should have for +each other: + +- **Respect:** We ask for everyone to respect each other, the space, and the local area. We want this event to +be inclusive for everyone involved, and will not tolerate harassment or rude behavior. + +- **Consent:** Any interaction with anyone at *Spring Break Of Code* should be consensual. + +- **Privacy:** The house we've rented is spacious, but not large enough for everyone to have their own private +room. We will organize shared rooms based on gender, and will do our best to ensure that everyone has the space +they need. + +## Timeline + +We want to have selected all the proposals we have space for by February 23rd. If you're interested, please submit a +proposal between now and then. We'll be accepting proposals as we go, however, so we might run out of space before then; +the earlier you get something in the better. + +We're excited, and hope you will be too! \ No newline at end of file diff --git a/_posts/2013-01-31-low-latency-switching.md b/_posts/2013-01-31-low-latency-switching.md new file mode 100644 index 0000000..ef16b36 --- /dev/null +++ b/_posts/2013-01-31-low-latency-switching.md @@ -0,0 +1,142 @@ +--- +title: "Blog >> Creating a low-latency calling network" +layout: post +--- + +RedPhone is our mobile app for end-to-end encrypted voice calls. When we talk about RedPhone, we tend to +emphasize the cryptography, and how using it can help keep your communications safe. What we don't talk about +as much is the VoIP application underneath all of that, which it turns out was actually the hard part. + +When we were developing RedPhone, we discovered that the cryptographic aspects of it were relatively straightforward. +What we didn't anticipate was how difficult the mechanics of delivering high quality, low latency, and highly available +voice communication would be. + +This describes the basic strategy we developed for the network side of low-latency and highly-available calls. + +XXXXX + +## Our Own Infrastructure + +Other than low-latency and high-availability, our other objectives with RedPhone were to make it simple and mobile-oriented. +For us this primarily meant avoiding a complex registration process, and not doing things like holding persistent signaling +sockets open to a server at all times (as a standard desktop-oriented VoIP client would do). + +Based on these and other design objectives, it was clear that we'd have to write our own switch, rather than using something like +Asterix or FreeSWITCH. We didn't like their complexity, and we knew that we didn't need 9/10ths of the stuff in SIP. Instead we +decided to [write our own](https://github.com/WhisperSystems/RedPhone/wiki/Signaling-Protocol) minimal signaling protocol +and use [push notifications](https://github.com/WhisperSystems/RedPhone/wiki/Signaling-Protocol#wiki-compressed) +(at first SMS, then eventually GCM when it was introduced) in order to initiate calls. + +## Low Latency and High Availability + +With that, we had a pretty nice setup for a single server in a single region. A client initiating a call could contact +the server, the server would send a push notification to the client receiving the call, and that client would connect back +to the server in order to complete the call. + +However, the NATs generally employed by mobile data networks are pathological, such that it's virtually impossible for two +clients on a mobile data network to establish a direct connection with each-other. To deal with that, our switch acted as a +basic [TURN](https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT) server, shoveling packets back and forth between +connecting clients. + +This was fine if the callers were in the same region as the server, but callers in other regions would have experienced high +latency. If the switch was on the east coast of the US and both callers were in Germany, their traffic would have to travel +all the way across the Atlantic and back, adding a frustrating couple of hundred milliseconds latency to their conversation. + +What's more, if we only had a single switch, RedPhone service would have become entirely unavailable if that switch had gone +down for any reason (as servers are wont to do). + +The solution was pretty obviously more servers, in different places. If every region had a server close to it, local callers +could route their traffic through that switch to get low latency. + +But even if we put a bunch of servers in different regions all around the planet, how would a client initiating a call know the +closest switch to talk to? + +### GSLB + +One option would have been for us to operate all of our switches on a single [anycast](https://en.wikipedia.org/wiki/Anycast) +IP address. Using the magic of anycast networking, clients connecting to that IP address would have been routed to the closest +instance of a RedPhone switch. But that's difficult to setup, and doesn't work well for TCP-based connections, which is how +our signaling protocol operates. + +Instead we ended up using a DNS provider that allows us respond to DNS requests differently based on which region the DNS lookup +went to. Providers like these basically have a set of globally distributed DNS servers on their own anycast IP address, each of +which can be configured to return a different response to a DNS lookup. + +This meant that we could put each switch on a different IP address, but have a single DNS name that connecting clients would +lookup when they wanted to connect to a switch. A client would automatically get the IP addresses of the switches in its region +when it did a DNS lookup on that name. These should represent the lowest latency routes. + +At first we used Dynect for this, who charged something like $500/month. When the "latency based routing" feature became +available for Amazon's Route 53, we switched to them. The service is basically the same, but they charge something like $5/month. + +### Multi-Connect + +At this point we were closer to what we wanted. We could spread switches all over the world, and an initiating client would +automatically connect to one of the switches in its region. The problem came with how "region" was defined. Since we were using +DNS-based GSLB, the regions were defined by the locations that our DNS provider had servers. For most providers, including +Amazon Route 53, that ends up being pretty coarse. Users of AWS services should be familiar with this map: + + + +These are Amazon's AWS data centers, and by extension the regions that can be defined using Route 53's Latency Based Routing. + +Unfortunately there's a lot of open space in this map. The United States is covered pretty well, but all of Europe is one coarse +blob. Africa and central Asia aren't defined at all, and all of South America is one coarse blob as well. If we were to limit +our geographical diversity to these data centers alone, many regions of the world would still see high latency calls. + +For example, someone doing a DNS lookup for a Route 53 LBR name in South Africa will get the result defined for Amazon's Ireland +region. Looking at [a cable map](http://cablemap.info/), it's easy to see why that would be true (that's where the fiber goes). +But the round trip time between South Africa and the UK is just over 200ms, which would make for a pretty terrible call if two +people in South Africa wanted to speak with each-other and had to route all their traffic through the UK. + +So DNS GSLB was a good start, but we needed something to increase the granularity of where a client connects. The answer for us +came from a suggestion a [friend](http://sigbus.net) made for [a different project](http://convergence.io). For every coarse DNS +GSLB region, we constructed a DNS response that included all IP addresses which existed within that region. So Route 53 LBR +responses for AWS's Ireland region would include IP addresses for switches in Europe, but also switches in Africa, since all of +Europe and Africa is treated as one coarse region by Route 53. + +So now when a connecting client did a DNS lookup, it would get back IP addresses for all the switches that could potentially be +the lowest latency route. For an initiating client in the US, where Amazon LBR regions are a little more fine grained, all of +those IP addresses would likely be good candidates. For an initiating client in South Africa, however (where the Amazon LBR +region is extremely coarse), those IP addresses would range from good candidates in South Africa, to poor candidates in Egypt and +Europe. + +To narrow it down, the initiating client then *simultaneously* +[initiates a TCP connection to all of the IP addresses](https://github.com/WhisperSystems/RedPhone/blob/master/src/org/thoughtcrime/redphone/network/LowLatencySocketConnector.java#L44) in the DNS response. The client then waits for one of the TCP connections to +complete, and immediately closes all of the outstanding connections before they also complete. The first connection to complete is +almost always the closest switch under the least load. Clients in South Africa multi-connecting to IP addresses in ZA and the UK +will connect to the switches in ZA, while clients in the UK connecting to the same list of IP addresses will end up connecting to +switches in the UK. + + + +Knowing which DNS GSLB region to include a switch's IP address in easy: just bring up the switch, do the DNS resolution from that +switch, and see which region's response gets returned. Add that switch's IP address to that region's response, and it's online. + +### As A High Availability Strategy + +A typical HA server architecture would include a number of load balancers in round-robin DNS, with each load balancer fronting +requests for some number of servers behind it, along with monitoring to detect when a load balancer fails and should be removed +from DNS. + +The nice side effect of the multi-connect approach is that it also provides high availability without the need for dedicated load +balancers. It effectively turns the client itself into the load balancer. If a switch goes down, the next-closest switch will +transparently get a client's connection instead. + +Doing rolling upgrades of the switch software is simple: tell the switch to "drain" (reject new connections, wait for existing +connections to complete), then shut it down, push the update, and bring it back up. This can all be automated, and is fully +transparent to connecting clients. Any incoming connections will simply end up multi-connecting somewhere else. + +# The Result + +All together, we have a fairly simple infrastructure for facilitating low-latency and highly-available calls. We deploy switches +globally, divide them up into DNS GSLB regions, and then have clients include multi-connect logic to those switches. When a +client wants to make a call, it's four simple steps to getting it initiated through a low-latency route: + +1. Initiate a DNS resolution for the name that all switches are referenced by. +1. *Simultaneously* connect to all of the IP addresses returned in the region-specific DNS response. +1. Wait for a TCP connection to complete, and then immediately close the others before they complete. +1. Send the initiate request via that connection, and wait for the client to respond. + +This is only the network half of the picture. We'll write more about what it takes on the client side in order to produce +low latency calls with good quality audio, as well as some other niceties that we developed along the way. \ No newline at end of file diff --git a/_posts/2013-02-18-client-side-audio-quality.md b/_posts/2013-02-18-client-side-audio-quality.md new file mode 100644 index 0000000..419306f --- /dev/null +++ b/_posts/2013-02-18-client-side-audio-quality.md @@ -0,0 +1,153 @@ +--- +title: "Blog >> Client side call quality" +layout: post +--- + +In our [previous post](/blog/low-latency-switching), we discussed the global infrastructure that allows RedPhone clients +to find low latency servers when establishing a call. This post discusses the techniques we use to retain call quality +when network conditions are less than ideal. + +XXXXX + +## Client side call quality + +Building any VoIP client is difficult, and building a VoIP client for a mobile device introduces additional specialized +difficulties. All VoIP solutions contend with packet switched networks that were not designed to transmit real-time media +streams. Packet latency and packet loss are the principal manifestations of this reality, and the +[jitter buffer](http://en.wikipedia.org/wiki/Jitter#Jitter_buffers) is their canonical solution. + +A jitter buffer stores a small amount of incoming audio data in a delay buffer, draining the buffer when audio packets are +late, then refilling it when those packets eventually arrive. Given bounded packet latency and a sufficiently large buffer, +the audio player will never need to pause the audio signal while it waits for a new packet of audio data to arrive. For +example, if packets can arrive up to but no more than 50msec late, then a jitter buffer storing 50msec of audio will ensure +that audio data is always available when it is needed. + +In the real world there are no upper-bounds on packet latency. Because RedPhone uses UDP packets to transmit its audio stream, +some packets may never arrive, or may arrive out of order. Choosing a size of the jitter buffer that keeps the worst-case +number of audio packets that fail to arrive before they're needed below an acceptable threshold would require making a worst-case +estimate in the variability in packet arrival times. The tradeoff in using a large jitter buffer is that the audio latency is +significantly increased, which is also undesirable. To provide the best call quality attainable given current network conditions, +an adaptive jitter buffer is used to dynamically adjust the amount of buffered audio data. + +## Adaptive jitter buffers + +In choosing the optimal size of the adaptive jitter buffer, we need a consistent framework for comparing the "badness" +(we'll refer to this as the cost) of audio latency with the cost of not having audio when we need it. A simple way to +express this would be: + +w_1 E[latency] = w_2 E[late] + +The above formula equates a specific expected latency with a specific expected rate of late audio packets. By adjusting +weighting coefficients we can, for example, assert that an extra hundred milliseconds of latency is equivalent--in terms +of perceptual quality degradation--to three late audio segments per minute. + +The model provided above gives a description of the relative quality of different latencies and missing audio packet rates. +To determine the best jitter buffer size to use, we need to know what the expected latency and the missing audio rate are +for a given buffer size. Making that computation requires a statistical model of individual packet latencies. For one +possible choice for a latency model, where packet latency has a log-normal distribution with known parameters, the optimal +jitter buffer size can be computed by: + +\underset{x}{\texttt{argmin}} \left[ w_1 x + w_2 - w_2\Phi\left(\frac{\ln x - \mu}{\sigma}\right)\right + +In this, phi is the cumulative distribution function of the normal distribution, mu and sigma define the packet latency model, +and x is the additional delay introduced by the jitter buffer. + +In practice, we found that a linear relationship between latency, missing audio, and call quality poorly captures reported +perception of quality. From our testing, we expect the perceptual cost of latency and missing audio to follow a roughly +sigmoidal profile. This means that for low latencies and low rates of missing audio, the effect on call quality is barely +noticeable. Then, as the latency and missing audio increase, the perceived call quality begins to rapidly decrease, finally +levelling out into another quality plateau (of generally unusable audio quality). + +One additional reason that the cost of late audio packets is nonlinear is that maximum audio gap length, rather than the absolute +number of missing audio packets, is strongly correlated with perceived audio quality. This is because occasionally missing packets +can be masked by the audio codec, while longer gaps cause perceptible audio degradation. This means that the cost of two late +audio packets in a row is much higher than the cost of two late packets separated by several on-time packets, even when the +absolute rate of late packets is identical. + +## Latency Model + +While the log-normal model of packet latency is easy to analyze, it turns out to be a poor model of real-world conditions +encountered by mobile devices. To understand RedPhone's call quality, we tracked packet latency statistics during calls +on a variety of US carriers. The data we collected was remarkable. + +We'd expected to see packet latencies distributed to be weakly correlated with the latencies of adjacent packets and to have +an unimodal distribution. What our data showed was the combination of a packet latency distribution close to what we'd expected +to find with a second process we hadn't been looking for. This second process was asymmetric, affecting transmit latencies much +more often than received latencies, and it operated over much longer timescales than we'd expected. + +In the data, we saw a device's data uplink would stop transmitting for a short period of time, sometimes only a dozen +milliseconds, sometimes a second or more. When the device began transmitting packets again, the backlog of unset packets would +transmit in a rapid burst rather than being dropped entirely. We're not certain what the root cause of this phenomenon is, but +temporary interference with the low-power uplink signal (rather than the high-power downlink signal) and power-saving behavior in +the radio hardware have been suggested as possible explanations. + +These long gaps in incoming audio required a different approach to adaptively sizing our jitter buffer. If we'd attempted to fit +a normal or log-normal model of packet latencies to the observed latencies, the optimal buffer length derived from those parameters +would have been much longer than needed--since the periods of consecutive, highly delayed packets skew the distribution towards a +higher expected latency. Instead, we focused on tracking a model of the lengths of these network dropouts rather than individual +packet latencies. + +## RedPhone's Adaptive Jitter Buffer Design + +We began by defining the maximum jitter buffer size we'd consider using in practice -- regardless of network conditions -- as +about half a second. Then, we divided this timespan into bins with lengths equal to a single UDP packet (40 milliseconds). When +a network dropout is detected by the +[DropoutTracker](https://github.com/WhisperSystems/RedPhone/blob/master/src/org/thoughtcrime/redphone/audio/DropoutTracker.java), +it increments the count in the bucket corresponding to the length of the dropout. Bucket counts are rolling counts, so older +events are dropped after a sufficient amount of time has elapsed. Dropouts longer than the maximum buffer length are counted in +the last bucket. We define the maximum number of acceptable network dropout events and examine the bin counts to find the jitter +buffer size that would have resulted in fewer than that many dropouts given recent network performance. + +The desired jitter buffer size is then smoothly adjusted to track this ideal size. When the optimal size of the jitter buffer +changes, the total time delay between one phone's microphone and the other's speaker changes as well. Since both these data +sources and sinks are synced to real-time clocks, adjusting the amount of data between them isn't trivial. + +Every audio packet has a sequence number that increments predictably. RedPhone computes a long-term estimate of which sequence +numbers should arrive at what times. This estimate allows it to adapt to clock-rate skew between devices. When the number of +audio packets stored in RedPhone's jitter buffer is significantly different from the number expected at a given time, or when the +buffer is nearly empty, the audio playback rate is adjusted. If there's not enough audio we stretch the audio signal out in time +to allow the buffer to fill. If there are too many packets in the buffer we play the audio data faster. The +[PacketLossConcealer](https://github.com/WhisperSystems/RedPhone/blob/master/src/org/thoughtcrime/redphone/audio/PacketLossConcealer.java) uses a native library to adjust the audio playback rate without altering pitch, allowing RedPhone to adjust the total time +delay between microphone and speaker on the fly. + +## Android's AudioMixer API + +Low-latency playback of dynamically generated audio is challenging on Android. Games, which require low latency playback, use +pre-loaded audio clips which can be triggered when needed. However, the interface to the system's audio mixer was designed for +media playback applications that stream media for playback but are relatively insensitive to latency. This interface buffers +audio written to it, in an attempt to relieve the application from the burdens of implementing a low-latency callback based +solution. The size and current state of this buffer is not directly accessible--although the current playhead position can be +accessed, this value is updated intermittently via a binder interface. RedPhone implements a [LatencyMinimizingAudioPlayer](https://github.com/WhisperSystems/RedPhone/blob/master/src/org/thoughtcrime/redphone/audio/LatencyMinimizingAudioPlayer.java) that attempts to find the minimum reported buffer level that can be maintained in the mixer without +causing underflows. + +The implementation counts audio underflow events using a leaky integrator. When these events occur frequently, the desired buffer +level increases. If very few have occurred recently, the buffer level is allowed to decrease slowly. Since different vendor +implementations of the system mixer can have very different buffer levels required to avoid underflow, this system is necessary to +ensure we get the lowest audio latency possible on a given device. Additionally, on some devices, the mixer will stop playback +when an underflow occurs for an extended period of time, and it will not resume until the buffer is filled past a certain +threshold. This behavior is desirable for a media player streaming audio over an unreliable network, but in our system it can +cause playback to stop indefinitely, since the system will not fill the mixer's audio buffer beyond the desired level. +To resolve this, [RobustAudioTrack](https://github.com/WhisperSystems/RedPhone/blob/master/src/org/thoughtcrime/redphone/audio/RobustAudioTrack.java) detects this lockup condition and inserts more audio than the desired level to restart playback. + +## Future Work + +RedPhone's use of audio playback rate adjustment doesn't currently take the content of the audio signal into account. When a +dropout occurs, followed by the burst of missing audio packets, if it is shorter than a few seconds, the entire segment is played +back at accelerated speed. Other VoIP solutions detect periods of silence and compress these when possible, leaving speaking +segments unaltered. This can allow time-shifting with less perceptible degradation in audio quality. Implementing this would +make a great project for [Spring Break of Code](http://www.whispersystems.org/blog/spring-break-of-code). + +Additionally, the desired jitter buffer size is unrelated to the total network latency between clients. Ideally, when the +network latency is already high, we should accept a higher level of missing audio packets rather than increase the latency +further. RedPhone could detect the roundtrip network latency in a call and, in response, adjust the tradeoff between jitter +buffer size and missing audio packets. + +## Review + +In this post we described two systems developed for RedPhone that help provide call audio quality. The first is an adaptive +jitter buffer implementation that's designed to address the particular packet latency characteristics we observe on mobile data +networks. That implementation combines an algorithm that selects the optimal buffer size with an ability to mask small amounts +of missing audio by synthesizing material to fill gaps and adjusting audio playback rate. The second system provides a +low-latency interface to Android's hardware audio mixer usable by applications that need to minimize the delay between audio +synthesis and playback. Together, these systems provide the foundation for building a VoIP application that provides the +minimum audio latency deliverable over a given network, without significant loss of audio quality. \ No newline at end of file diff --git a/_posts/2013-03-01-spring-break-of-code-lineup.md b/_posts/2013-03-01-spring-break-of-code-lineup.md new file mode 100644 index 0000000..2db4bf5 --- /dev/null +++ b/_posts/2013-03-01-spring-break-of-code-lineup.md @@ -0,0 +1,73 @@ +--- +title: "Blog >> SBoC Lineup" +layout: post +--- + +We were excited about our [Spring Break Of Code announcement](/blog/spring-break-of-code/), but the response +was better than we anticipated: over 100 extremely impressive proposals from folks around the world who are +passionate about pushing the envelope of security and privacy software. After reading all the proposals, we +really wish we'd rented a bigger house. + +We think the final lineup of accepted proposals is great: + +XXXXX + +Christine Corbett +**Christine Corbett** ([@corbett](https://twitter.com/corbett)) I'm an MIT educated software engineer with several prominent +iOS/Android apps (CircleOf6, Encyclopedia) in both the non-profit and for-profit sectors. I'll be working on an iOS TextSecure +integration plan (with prototype) and lending my hand to RedPhone wherever possible. + +I'm a huge productivity and project management geek which will also come in handy as we manage the balance between surfing +the internet/waves and getting things done. + +

+ +Rhodey +**Rhodey** Engineer in my early 20's, interested in most everything with a strong biased for space, hacking, music, and sailing. +Plans to spend SBoC developing software which allows cellphones to determine their environment as friendly or hostile +and react accordingly. I also hope to spend some time looking into adding a data based (non-SMS) channel to TextSecure. + +

+ +Lilia +**Lilia** I'm a software developer, occasional hardware hacker, and yoyoer from San Francisco. I'll be helping people +understand the whys, and hows of secure communications by building out app documentation and on-boarding information. + +

+ +Tyler +**Tyler Reinhard** ([@abolishme](https://twitter.com/abolishme)) It’s hard to know how to describe Tyler’s work, but +we know he’s done the following: lectured on design and social critique throughout Scandinavia; co-owned and operated +a hand-composition letterpress studio; typeset a newspaper written in the Lakota language; survived a quarter-year of +work as *Chef Garde Manger* behind the pass of a [AAA 3-Diamond fine-dining restaurant](http://signatureswinona.com/) +with no prior professional kitchen experience; appeared as a “critical theorist" in a cultural documentary called +[Twilight of the Mississippi](http://www.youtube.com/watch?v=sH_DskTuDlA); collaborated on an international hoax that +nearly gave [Glenn Beck a heart attack on-air](http://www.glennbeck.com/2011/04/18/something-missing-from-the-office-friday-was-national-steal-from-work-day/); lost a tooth in a work-related crowbar accident; and published a 7,000-word essay for a +comprehensive note-taking methodology called [Semantic Notes](http://semanot.es/). + +

+ +Calder +**Calder Coalson** I'm a Chicago native and junior CS major at Carleton College in Minnesota. I enjoy programming things, +exercising free speech, pranking people, centrifuges, airplanes, sailing, xkcd, board games, space, cats, space cats, wait, +what's a space cat? I'm dying to work on designing a more intuitive and (yes) *fun* identity system. + +

+ +Isis Lovecruft +**Isis Lovecruft** ([@isislovecruft](https://twitter.com/isislovecruft)) I’m in my early twenties. I do lots of things +and wander to lots of places. I double majored in Theoretical Physics, and English Literature, with a specialisation +in Feminist Critical Theory. I’m highly interested in cryptography and network security, and I occasionally provide +workshops and lectures on digital security topics for free to activist groups. It's hard to know how to classify my +software development work, but the one unifying theme across all of my efforts is my overwhelming love for the Java +programming language. At Spring Break Of Code I'll be working on improving group messaging support in TextSecure. + +

+ +Andy Isaacson +**Andy Isaacson** ([@eqe](https://twitter.com/eqe)) is a kernel hacker and distributed systems implementor interested in +security and individual freedom. He co-founded Noisebridge hackerspace in SF and helps run Noisetor, the Tor Exit Node +operated by Noisebridge. At SBoC he'll be implementing multimaster database reliability for the RedPhone server backend +and fixing some nagging documentation bugs. + +

\ No newline at end of file diff --git a/_posts/2013-03-06-merch.md b/_posts/2013-03-06-merch.md new file mode 100644 index 0000000..c7e3f6e --- /dev/null +++ b/_posts/2013-03-06-merch.md @@ -0,0 +1,25 @@ +--- +title: "Blog >> Merchandise" +layout: post +--- + +It's a busy time here at the Open Whisper Systems factory, and we need all the floor space we can get. We still have some +first-edition T-Shirts that are taking up some space, so we're offering them to you for the cost of shipping and handling. + +There are two designs available in a number of sizes: + +XXXXX + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_posts/2013-03-25-dirigibles-chinese-junk-rigs-and-surfboards.md b/_posts/2013-03-25-dirigibles-chinese-junk-rigs-and-surfboards.md new file mode 100644 index 0000000..054d85b --- /dev/null +++ b/_posts/2013-03-25-dirigibles-chinese-junk-rigs-and-surfboards.md @@ -0,0 +1,92 @@ +--- +title: "Blog >> Dirigibles, Chinese Junk Rigs, and Surfboards" +layout: post +--- + +*A guest post by [Isis Lovecruft](https://blog.patternsinthevoid.net/). Spring Break Of Code, Day One.* + +One of the first times I met up with [Moxie](https://twitter.com/moxie) while travelling, we met at a dive bar in +San Francisco's Mission District, packed with hipsters. I had nineteen years, a modified state ID card, and just +hitchhiked into town. We sat at the bar, and both ordered well gin and tonics. + +I had a proposal, the sort of get-rich-quick scheme it seems that only 18th century pirates and lazy hacker-squatters are +capable of contriving: We fly to China. Then, we spend a few grand purchasing a Chinese junk rig, and equip it with a system +of pulleys so that we can man the sails from the cockpit, solo if necessary. Next, we fill the cabin with about as much potable +water as we can carry and enough dried food to stave off starvation, and set a course across the northern arc of the +Pacific -- avoiding the treachery of the South Seas -- for San Francisco. The choice of vessel was key, the battoned sails +and flattened hull of a Chinese junk rig make it arguably one of the safest ships to make a transoceanic voyage alone, not +to mention the finicial incentives: being rare in the Americas, a well-kept junk rig would go for anywhere from $50,000 +to $250,000 USD -- not to mention grant you free slip fees at just about any marina from Anchorage to Punta Arenas. How could +anyone turn down such a preposterous plot which included adventure on the high seas, a high mortality risk, riches and notoriety? + +XXXXX + +As I recall, Moxie shook and hung his head, and smiling countered my proposition. + +"Ever heard of Santos Dumont?" he asked. +"Nope." +"So. Santos Dumont was a Brazilian hero, originally a Frenchman. This was around the late 1800s. He was the type of dude who +would trek across the Amazon alone, leave for the North Pole with a party of eight and return with a party of three -- your +standard gentleman-adventurer, a total madman. Sometime around the turn of the century, he returns to Paris to participate +in a race to sail dirigible from a certain point around the Eifel Tower and back. He wins, but being rich already, gives half +the money to charity. The other half of the prize he puts in the care of a trust fund with the instructions that it should be +awarded to anyone who can beat his time -- thirty minutes or so, from what I remember." +"No one's won it yet?" +"I'm not entirely sure, but the story appears to end there -- at least, there is no record of anyone claiming the money in the +trust -- and it's been sitting there, collecting interest, for over a century now." Moxie swept the dreads out of his face, +took a sip of the gin, and continued: "It should be simple to beat the time given the advantages of modern materials..." + +He and I have had a friendly series of bets throughout our friendship. Moxie usually wins...and I usually forget to name +my stakes. I should have bet on this: If ever anyone were to be the cause for my going to the North Pole, it would be Moxie. + +I awoke this morning in my underwear on top of a snarled mess of sheets, with my head rather uncomfortably hanging off +the edge of the bed, two laptops and three android android phones¹ piled on top of and around me. The rhythmic pink-noise +crash of surf was drafting in on sticky air through an open window above my face. I opened my eyes. Knots of lime-coloured vines + hung from a tamarind tree with dark beanpods of fruit half a meter long. + + + +*Qu'est-que fuck? How did I get to Yavin IV?* I blinked, expecting the familiar snowy silence of Prenzlauerburg to +replace the acerbic green foliage, the clockwork clacking of the U-Bahn across the raised tracks to replace the steady +sound of waves... + + + +*Nope. Still on Yavin IV.* + +Then I remembered the dark curls hanging over noetic eyes and «à plus» on a trainstation platform in the French Alps, +the two-hour search and interrogation by US customs agents in the basement of the Montréal airport, talking all night with +expat Iranian dissident-hackers and deciphering the pyobfsproxy stacktraces and kanji showing up in my terminal at the Tor +developer meeting at Harvard, and then the series of flights which brought me to the longitudinal apogee of my starting point +five days ago. The shortest path of return is straight down; the fastest takes me +[directly over the North Pole](http://www.distance.to/Honolulu_Berlin). Damnit, should've made that bet... + +One of the bets I lost years ago -- I think this one was the cost of my hubristic belief that I could pick a lock faster than +Moxie -- had the stakes "loser has to go surfing naked". I still haven't paid that debt, but, having been on a surf team as a +kid, I bet that, wetsuit or otherwise, I could surf better than he could. I think I forgot to name my stakes again, but it +doesn't matter because I had to let Moxie off the hook this time, due to the painful complications of his recent knee surgery. +Though, while waiting for the others to arrive, Christine, Moxie, and I did get a chance to to test out the small surf in +our front yard. + + + +I haven't had to write any Java yet, and, tragically, my watercolour portait +of [James Arthur Gosling](http://www.novosti.rs/upload/images/2011/03/3003j/james-gosling-java.jpg) was confiscated at U.S. +Customs in Montrèal, but I did write about twelve pages of equations in an attempt to sort out an elliptic curve MQV variation, +changed to add embedded, deniable, and authenticated, key exchanges for both a long-term identity key and ephemeral session key +as per Ian Goldberg et.al.'s denAKE() algorithm in the +[Multi-Party Off-The-Record paper](http://www.cypherpunks.ca/~iang/pubs/mpotr.pdf). That'll get added +to [my fork of a collaborative MPOTR spec](https://github.com/isislovecruft/mpOTR) git repo shortly, and review by +cryptologists is greatly appreciated. I also rooted my newly-acquired (for [OONI](https://ooni.torproject.org/) mobile +development testing and reading [arxiv](http://arxiv.org/) papers) android jellybean tablet, and finally ate the taco and +tapatio-coated mango I'd been craving in Berlin. + + + +[isis](https://blog.patternsinthevoid.net) [agora](https://github.com/isislovecruft) [lovecruft](https://twitter.com/isislovecruft) + +Lahaina, Maui, Hawaii, United States + +24 March 2013 + +¹ Well, actually, one of them was a mozilla boot-to-gecko developer phone. \ No newline at end of file diff --git a/_posts/2013-03-26-highly-unconventional-suggested-first-aid.md b/_posts/2013-03-26-highly-unconventional-suggested-first-aid.md new file mode 100644 index 0000000..d96daa4 --- /dev/null +++ b/_posts/2013-03-26-highly-unconventional-suggested-first-aid.md @@ -0,0 +1,53 @@ +--- +title: "Blog >> Highly Unconventional Suggested First Aid" +layout: post +--- + +*A guest post by [rhodey](http://anhonesteffort.org). Spring Break Of Code, Day Two* + +"I am torn on how best to introduce myself out of context like this, the idea of rattling off facts from my resume is my +first instinct, but that seems terribly conventional. With the goal of introducing myself and the entirety of my character +my second (highly unconventional) instinct is to link you to my online dating profile with the prayer that such an action +would be taken in the desired context. Through my indecision I hope to explain who I am and why I would like to travel +across the country to be involved with the Institute for Disruptive Studies. So here goes..." + +XXXXX + +Looking back, the message reads a bit formal and robotic, but it caught the attention of the Institute for Disruptive Studies +nonetheless; specifically [moxie's](https://twitter.com/moxie). I went on to disclose my OkCupid profile, here however I will +not be so bold. + +A couple months past with sparse contact throughout, until the announcing of Whisper System's Spring Break of Code. I'd had +more than enough of the Vermont Winter, incompetent college administrators, and silent, eventless nights, so in undeniable +desperation I sent in my application. Applicants were asked to submit a proposal describing the work they'd be doing while +in Maui, my idea was something along the lines of [GeoFencing](http://en.wikipedia.org/wiki/Geo-fence). + +I arrived at our beach house in Maui around 4:00PM and was almost immediately forced into work on my GeoFencing application. + + +*Amateur surfing at low tide.* + +With my right foot and left hand out of commission there wasn't much (anything) to do other than familiarize myself with the +Android development environment and mend my wounds. With future scale in mind, I quickly discovered a brand new class of +databases, Spatial Databases. Databases optimized to store and query data related to objects in space, including points, +lines and polygons (wikipedia). Given Android's default database implementation of SQLite and SpatiaLite's turn-key Android +support, implementing [SpatiaLite](https://www.gaia-gis.it/fossil/libspatialite/index) was an easy choice. + +Eventually I'd like to switch to Open Street Maps, but for now at least, in my lacking Android experience I'm developing on +the [Google Maps Android V2 API](https://developers.google.com/maps/documentation/android/). The basic idea of my SBoC proposal +was to define environments as "trusted" or "hostile" and have client phones react accordingly. For example, a phone inside a +police station may wipe its call and message history, and then using its microphone being espionage. + + +*Relaxing inside the (presumably) trusted hammock polygon.* + +It took me awhile to discover [Action Bar Sherlock](http://actionbarsherlock.com/), and awhile more to switch out my hacked +together fragment layout. In the end though, there really isn't any better path to take. Now, with my 90% complete UI, what's +left is to implement a couple POC actions and trigger them on the enter or exit of polygons. Oh, and wait for this super glue +on my foot to scab off and hopefully give way to sealed skin. + +[rhodey](http://anhonesteffort.org) + +Lahaina, Maui, Hawaii, United States + +25 March 2013 \ No newline at end of file diff --git a/_posts/2013-03-27-streamlining-textsecure-settings.md b/_posts/2013-03-27-streamlining-textsecure-settings.md new file mode 100644 index 0000000..bb33af4 --- /dev/null +++ b/_posts/2013-03-27-streamlining-textsecure-settings.md @@ -0,0 +1,119 @@ +--- +title: Blog >> Streamlining TextSecure Settings +layout: post +--- + +*A guest post by [lilia](https://twitter.com/liliakai). Spring Break Of Code, Day Three* + +I am no stranger to Hawaii. Although I've never lived here myself, I've visited +the islands perhaps a dozen times. My grandmother and my father were born and +raised here. My mother attended college here. I have aunts, uncles, and cousins +who've lived on various islands, moved away, came back, moved away and back +again. I even have Native Hawaiian blood in my veins. + +But this trip is different. This time it's not about family or heritage. This +time, I have a mission: to make secure text messaging and calling easier, more +accessible, and more prevalent. + +XXXXX + +The first time I used TextSecure was a bit of a blur. "Hey do you have +TextSecure?", my roommate, Mark, asked one First Friday in Oakland. "Huh? What? +Uh...no?" "Oh, well you should download it so we can exchange keys." Despite +some initial awkwardness concerning session initialization, we were soon +transmitting such covert secrets as "Neat, it's working" and "yay! :)". + +At this point my knowledge of cryptography was (is) somewhat rudimentary. I +knew basically what encryption was and how to use RSA key pairs for ssh, but I +thought of encrypted SMS as more of a nerdy novelty than anything else. I +figured it might be a practical precaution for activists, whistle-blowers, and +rebel freedom fighters operating under and against oppressive goverments, or +perhaps goverment agents operating in hostile foreign countries, but for 99% of +people I knew and 99% of their SMS conversations, surely this app would be, as +they say, like wearing a tin foil hat. + +Now I see things differently. The truth is, even here in the so-called land of +the free, we are constantly under surveillance, both passive and active, by our +[goverment](http://www.aclu.org/spy-files), our +[corporations](https://www.eff.org/nsa/hepting), our +[law enforcement](http://www.npr.org/2013/02/22/172696814/as-police-drones-take-off-washington-state-pushes-back), +and [ourselves](http://www.huffingtonpost.com/steven-kurlander/domestic-surveillance-spy_b_2866085.html). + +Once you accept these facts, it's easy to see that you should use encryption to +protect your important data and communications. But surely encrypting something +like "yay :)" is overkill, right? The catch here is that encryption is most +effective when everyone uses it all the time. Otherwise the encrypted stuff +sticks out like a sore thumb, announcing to all the world that this data is +special and secret. So even if you have nothing to hide, using encryption as +part of your regular routine will help protect you when you really need it, not +to mention helping to protect others who really need it. + +The problem is, the barrier to entry has traditionally been fairly high. Access +to modern encryption used to be restricted to government agencies. This is now +changing as more and more people pick up on PGP for email, HTTPS for the web, +and now TextSecure and RedPhone for mobile, but we still have some work to do +to make encrypted texting and calling as simple and painless as possible. + +So back to TextSecure. Hopefully by now you've installed it. If not, go ahead. +I'll wait. Back? Good. Now open the settings menu. You're probably thinking +something like "Oh. My. Glob. Becky. Look at that settings menu. It is so big." +You're right, but don't worry because we have a plan to change that. Some +settings will be removed, others will be reorganized. Whether you're a seasoned +secure texter or freshly installed, keep an eye out for these changes in +upcoming releases. + +### On the chopping block + +* MMS delivery reports +Though this option may return in the future, it's not implemented yet, so it +shouldn't be sitting there teasing you in its disabled state. + +* Import/Export my identity key +Due to changes in Android's support of custom contact metadata, these functions +have been rendered mostly useless. We're working on an alternative cloud-based +identity import/export feature, but in the meantime we'll be removing these +options so you can focus on the settings and features that matter. + +* Include whitespace tag +Inherited from the OTR protocol, whitespace tagging is how TextSecure signals +the recipients of your messages that you are a TextSecure user who is willing +and able to have a secure conversation. The motivation for making this signal +optional was the thought that some TextSecure users might not wish to self +identify as such. However, those users are likely in the minority, and once +everyone is using secure SMS, there won't be any reason to hide that fact. + +* Sign key exchange +The use case for this setting had to do with someone using a single identity +key on multiple devices. Again, this is a rare edge case. If you happen to fall +into this category, and don't want to associate your secure sessions on a +particular device with your primary identity key, it is recommended that you +use a different identity key on such devices. As a result of removing this +option, we also remove the need to ever verify a session key rather than an +identity key, and thus greatly simplify the process for protecting against +man-in-the-middle attacks. + +### Relocating + +A few of these "settings" are more like features or functions. Others are only +needed in rare instances or by advanced users. We'll be doing some reorganizing +to reflect that fact. So if you see these things disappear, don't worry. +They've just moved to a new home. + +* Change my password +* Complete key exchanges +* View my identity key +* Manage identity keys +* Enable Fallback MMSC +* MMSC URL +* MMS Proxy Host +* MMS Proxy Port + +With these changes, we can essentially cut the settings menu in half, making +your TextSecure configuration experience cleaner, simpler, and more +streamlined. + +[lilia](https://twitter.com/liliakai) + +Lahaina, Maui, Hawaii, United States + +26 March 2013 \ No newline at end of file diff --git a/_posts/2013-03-28-sure.md b/_posts/2013-03-28-sure.md new file mode 100644 index 0000000..023fe14 --- /dev/null +++ b/_posts/2013-03-28-sure.md @@ -0,0 +1,92 @@ +--- +title: Blog >> Sure! +layout: post +--- + +*A guest post by [Christine](https://twitter.com/corbett). Spring Break Of Code, Day Four* + +The main sound on top of the ocean is the click clack of laptop keys, +and the jangle of test calls and SMSes. A neighbor stopped by to +comment that we must be the next Facebook, the next Google; working +instead of surfing made sense in his mind only in the land of money at +the end of the tunnel. He loaned us his stand up paddle boards, surely +expecting a return on investment 10 fold down the line when we exited +into the sunset. A journalist visiting Open Whisper Systems' Spring +Break of Code commented that she expected more philosophy, politics, +and conversation. After all this group is composed of people who are +not only technologists, but also open source evangelists, activists, +and humanists. [Lilia](/blog/streamlining-textsecure-settings/) went over +some of the *why*, but practically anyone +could see we were concentrating on the *how*, and in the frenzied silence +it was clear that a common philosophy was assumed and what bound us +here was the challenges in the technology to power that philosophy. + +XXXXX + +[Rhodey](/blog/highly-unconventional-suggested-first-aid/) and +[Isis](/blog/dirigibles-chinese-junk-rigs-and-surfboards/) +shared their meeting [Moxie](http://www.thoughtcrime.org) stories. I'll go a bit +further and trace back time, as we go farther back. I first met Moxie +in a crowded hotel room in New York City around 2004, a place to crash +between sessions at a hacker conference, huddled in a circle +discussing things entirely new to me. Some time later I saw him on the +West coast, he was living in a hand built houseboat, from recycled +material, off the coast of the San Francisco Bay. In Boston, he +stopped by my makerspace warehouse of a home for a few evenings when +he was in the area to screen his [documentary](http://vimeo.com/15351476) about his sailing from +the coast of Florida to the Caribbean. He pulled up in a vegetable oil +powered VW truckbed, and driving around we couldn't help but smell +french fries in the fumes. + +Back in San Francisco, I had begun my hobbyist career in mobile +application development, and taken the summer off from my PhD to +concentrate on a successful [offline Wikipedia client](http://steamheavyindustries.com), and a +thusfar-failed [micro video messaging service](http://www.kliq.tv/), both for iOS. +Frequenting the maker space Noisebridge, Moxie was already hard at +work on Whisper Systems' apps, both for Android. One day he announced +he would be heading to Arizona to pick up a hotair balloon he had +purchased on the cheap with the goal of air delivering it back to his +San Francisco home. Convinced he might be in over his head, I tried to +dissuade him. Never fear, he would receive a free lesson from the +owner, and air currents and water currents weren't all that different. +A captain of the seas could also captain the skies. I wasn't +convinced, but Moxie made the journey. + +Given this history, when Moxie wrote me "Want to come to Hawaii for a +week, to hack?", I didn't have to ask what for, when or why to +immediately reply "sure". Back in my home of Zurich, Switzerland, I +had transitioned to apps for social good–[Circle of 6](http://circleof6app.com), an anti sexual +assault app being the flagship, and had formed a non-profit Tech for +Good, to spearhead them. I knew anything Moxie was up to would fit in, +technically and philosophically with my personal missions. On arrival +to Hawaii, it likewise came as no surprise to me that Moxie +Marlinspike had curated a technically stellar and necessarily diverse +group. The network went down due to a wayward bit coin trading AI. We +learned about notation for juggling patterns, the preferred sport of +anarchists (soccer anyone?), and conversed about whether ideology +should serve people, people ideology, and what ideology choosing +between the two options would entail. We surfed, dined, and even +discussed politics to the delight of the journalist. + +This week I've been working on the iOS version of TextSecure. I've had +a delightful time, and plenty of lessons I've learned from my other +projects have been more than useful. It's extremely helpful to have +Moxie working on the data channel backend and Tyler working on design +by my side. We already have a [Github project](https://github.com/WhisperSystems/TextSecure-iOS) +for the repository, and a +bare bones prototype with user authentication and sending a simple +message working. I have been working on the backend cryptography, +integrating OpenSSL, and preparing for the end to end prototype by the +end of the week. Here are a few teasers: + + + + + + + +[Christine](https://twitter.com/corbett) + +Lahaina, Maui, Hawaii, United States + +27 March 2013 diff --git a/_posts/2013-03-29-all-the-things-that-pull-and-push.md b/_posts/2013-03-29-all-the-things-that-pull-and-push.md new file mode 100644 index 0000000..bdb7dfb --- /dev/null +++ b/_posts/2013-03-29-all-the-things-that-pull-and-push.md @@ -0,0 +1,99 @@ +--- +title: Blog >> All The Things That Pull And Push +layout: post +--- + +*A guest post by [Tyler](https://twitter.com/abolishme). Spring Break Of Code, Day Five* + + + + +I know very well that each and every crisis of modernity is concentrating, concatenating, and seating more deeply into +everyday life. I know the struggles of the world's unseen and unheard are being subsumed -- appropriated -- under and +into the framework of a liberal democracy, leaving those at the periphery still under the yoke of capital. The Right further +entrenches itself into political discourse, both in the [United States](http://www.alecexposed.org/), and (more extremely) +abroad ([Finland](http://yle.fi/uutiset/book_racism_becoming_more_acceptable_in_finland/6360055), +[Greece](http://www.economist.com/blogs/charlemagne/2013/03/greek-politics), ... et al.). The Left is no less problematic: +reiterating the petty values of social democracy, negotiating the terms of our entrapment within capitalism. Every season, +new horrors fall from the clouds and rise from the seas as industrial civilization demonstrates that terraforming can also +work in reverse. The world's genetic library -- the most prime commons, if ever one existed -- is rapidly contracting via +extinction, privatization, and engineering. The colossal failure of ideology in the twentieth century has left the radicals +of today no other choice but to see themselves as "post-ideological". This is a deeply concerning conundrum, as ideology +survives in post-ideology, different only to the extent that it is less apparent. Yes, it seems like we are living in end +times -- an entire era of Apocalypse -- made only more insidious by our optimism in its shadow. + +XXXXX + +Although I know *epistemologically* that these are end times, *tacitly* it's harder to grasp. I'm in Hawaii. The sun shines +as the Pacific rolls in, each respectively constant and warm. The breeze is gentle, clicking through the palm fronds. The +roosters gloat in the blue light of the early morning hours. Entire pods of whales breach in our backyard, cavalier and +ambivalent. I'm working with some of the most intelligent people I've ever met. How could any of this ever go away? It's +all very unspeakable and horrifying. + +In times like these, it's hard to be serious. The schizophrenic dance between the panic-inducing terror of the consequences +of modern life, and the horrific pleasantness of modern life itself can really erode one's psyche. As difficult as seriousness +is, it can be even harder to be *absurd*. Here we are, trying to make "a new normal"; trying to make phone calls and SMS's +more secure, not as some self-interested career decision, but as an open-source project: a sort of volunteerism to force +others to adopt these standards for their communication apps. Our group is part entrepreneur and part anarchist, our labor +is part social work, part social war ... when I think about it, it's completely absurd. + +But what is a great work of satire without elements of both grave seriousness and wanton absurdity? + +Our focal depth is acute. We're craftspeople -- we want to build something with utility and panache. The wide-angle of our +work, as with most open-source projects, cannot be engineered from the terrace of a beach house. So it is with some synthesis +of seriousness *and* absurdity that a great work of satire is made. + +Personally, I've tried to live according to that principle -- right now, I'm a high-school dropout sitting amongst current +and former employees of Twitter, an MIT-educated theoretical physicist, globe-trotting journalists, renown mathematicians, +and emerging prodigy developers. I'm always deprecating my own qualifications (damn you, scandi-minnesotan morality), but the +truth is I've barely survived a very real sequence of mishaps in the world of anarchist-influenced creative- and +[knowledge-based work](http://en.wikipedia.org/wiki/Knowledge_worker) that have spanned a decade of more than a dozen +David v. Goliath scale forays into the production and maintenance of media, technology, design, and lifestyle products +and projects. + +As my skepticism of activism -- the notion that our actions can produce consequent shifts in some total structure of daily +life -- grows wildly out of control, I'm struck by how much consolation I derive from the micro-activisms of productivity +tricks. Using the Getting Things Done methodology to approach not-doing-anything is the perfect irony to complete my satire, +so here goes: + +> For Jacques Lacan, an idiot is someone who believes in their immediate identity with their self; "like a king who believes he is a king." + +## Two tips for the idiots. + +### Installing Ruby on OS X 10.8, Mountain Lion + +The second after I arrived, I opened up this shiny new MacBook Air, and realized that I had forgotten to install a current +version of Ruby. Amidst the nerds, many of whom have spent the vacation essentially working on black screens of streaming +zeros and ones, I immediately felt what I believe is referred to as +[Symbolic Castration Anxiety](http://en.wikipedia.org/wiki/Castration_complex). Without Ruby, I was unable to test my +[responsive web design](http://mediaqueri.es/) rewrites of the whispersystems.org CSS and HTML files buried in the +[JEKYLL](http://jekyllrb.com/) generator. I was left with no choice but to "figure it out, *idiot*." Turns out, it's a +little more complicated on OS X 10.8 than on previous versions of Apple's operating system: + +1. [Install Homebrew](http://mxcl.github.com/homebrew/) in Terminal: `ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"`. +2. Unlike in previous versions of OS X, Ruby Version Manager (RVM) requires xCode's command line tools, so you'll need to install xCode. +3. In xCode, navigate to `preferences > downloads > components`, install "Command Line Tools". +4. [Install RVM](https://rvm.io/rvm/install/) in Terminal: `user$ \curl -L https://get.rvm.io | bash -s stable`. Check install link for clarifying instructions. +5. Install Ruby via RVM in Terminal: `rvm install 2.0.0`. + +### Wireless Mirroring w/ Photoshop's Remote Connections & xScope + +I've been using Iconfactory's suite of design tools, [xScope](http://xscopeapp.com/), for years now. If you do design work +in OS X, give it a try. When I first got it, it totally changed how I designed, and what I was capable of doing -- setting +screen-wide guides *a la* photoshop, copying the color of a single pixel via loupe, a device-specific overlay window framing +your design, an x-y pixel ruler for measuring the distance between objects of a different color, etc. In a recent update, +they added support for many different forms of mirroring on-screen work to a iOS device. This feature has proved indispensable +in that it enables real-time retina testing on my phone, so I can get immediate feedback regarding changes to the pixel-perfect +photoshop mockup of TextSecure's interface. Here's how to do it: + +1. Spring for xScope, you'll thank me later. +2. Launch the app, and navigate to `Preferences > Mirror > "Allow iOS Devices on Local Network to Connect with deny/allow prompt"`. +3. Launch Photoshop. Navigate to `Edit > Remote Connections ...`, choose a password and enable a remote connection. +5. Enter this password in the mirror tab of xScope's preferences. +6. Install the free [xScope mirror app](https://itunes.apple.com/app/xscope-mirror/id488819289) on your iOS device, and launch it. +7. On the iOS device with the xScope mirror, just select your computer and allow the connection when prompted in OS X. From there you can choose to view the screen (to compare windows), the clipboard, the area around your cursor, or the photoshop document itself. This is especially convenient because it is otherwise impossible to preview a pixel-for-pixel mockup at 100% on most non-retina laptops, because the retina display on the iPhone has more vertical pixels than most displays. + + + +*Tyler Reinhard* also writes [http://abolish.me](http://abolish.me), a clearing house for thoughts on the design of systems and things, and +tweets [@abolishme](https://twitter.com/abolishme). \ No newline at end of file diff --git a/_posts/2013-03-30-call-quality-metrics.md b/_posts/2013-03-30-call-quality-metrics.md new file mode 100644 index 0000000..e099038 --- /dev/null +++ b/_posts/2013-03-30-call-quality-metrics.md @@ -0,0 +1,53 @@ +--- +title: Blog >> Call Quality Metrics +layout: post +--- + +*Post by [Stuart Anderson](https://twitter.com/emblem__). Spring Break Of Code, Day Six* + +Because secure systems aren't valuable if they're not used, WhisperSystems has always focused on delivering strong +cryptography alongside a great user experience. That's the reason [call quality](http://www.whispersystems.org/blog/client-side-audio-quality) has always been a priority in RedPhone's development. + +We know that, for many users, RedPhone has consistently delivered a call quality experience comparable to commercial +mobile VoIP solutions. But we also hear from users who report problems like dropped calls, distracting levels of echo +and latency, or inaudibly low in-call volume. While we investigate these reports and attempt to resolve them, we don't +have a clear view of what situations cause RedPhone's call quality to degrade, or how to prioritize our development efforts. + +XXXXX + +This week we built a call quality metrics reporting infrastructure for RedPhone. For the RedPhone Android client this is +an opt-in feature that allows callers to elect to have anonymized data about RedPhone's performance during each call delivered +to WhisperSystems for analysis. A second opt-in feature presents a quality feedback dialog after each call. This dialog +gathers feedback about overall call quality and specific problems that may have occurred during the call. + +When you upgrade to a version of RedPhone that supports quality metrics you'll be asked at the end of your next call +whether RedPhone should send anonymized data about each call or ask you to provide call quality ratings after each +of your calls. If you ever change your mind, these settings are always available in the main RedPhone preferences activity. + +Once enabled, the call metrics system collects the information we need to understand call performance. The collected +data includes: + + * Device description (model, manufacturer, carrier, network type, Android version, persistent random UUID) + * Microphone and codec performance + * Packet arrival interval histogram + * Out of order arrival counts + * Audio gap fill counts + * CPU load, memory usage + +The call quality user feedback dialog displays an overall quality rating and a small number of specific quality issues +that will change periodically. + + + +We wanted to ensure that the anonymized call quality data you send us is never visible to a third party. We encrypt the +JSON-encoded data as it streams to the local disk during the call. That encrypted data is uploaded to a +[RedPhone Data Collection Server](https://github.com/whispersystems/RedPhone-DCS) running on Heroku, and using AmazonS3 +for persistence. Because only WhisperSystems has the private key used to encrypt the stream, only we can decrypt the +metrics data after collecting it from S3. + +We look forward to sharing the results of our analysis of the data produced from your feedback, and delivering further +improvements in RedPhone's call quality in the coming weeks. + +[Stuart O. Anderson](https://twitter.com/emblem__) + +Lahaina, Maui, Hawaii, United States diff --git a/_posts/2013-03-31-sboc-goodbye.md b/_posts/2013-03-31-sboc-goodbye.md new file mode 100644 index 0000000..fdaa06d --- /dev/null +++ b/_posts/2013-03-31-sboc-goodbye.md @@ -0,0 +1,15 @@ +--- +title: Blog >> SBoC Farewell +layout: post +image: /blog/images/sboc-goodbye.jpg +--- + +The last code committed, the final waves surfed in to the shore, the closing sunset of Spring Break Of Code. + + + +XXXXX + + + +[*Looking good!*](https://news.ycombinator.com/item?id=5460204) \ No newline at end of file diff --git a/_posts/2013-06-10-how-to-help.md b/_posts/2013-06-10-how-to-help.md new file mode 100644 index 0000000..65d0e27 --- /dev/null +++ b/_posts/2013-06-10-how-to-help.md @@ -0,0 +1,35 @@ +--- +title: Blog >> Interested in privacy enhancing technology? How to get involved at Open Whisper Systems. +layout: post +--- + +Open Whisper Systems is a project focused on developing Open Source security and privacy apps for the +mobile environment. With all of the recent discussion about [PRISM](https://en.wikipedia.org/wiki/PRISM_(surveillance_program%29), +[Boundless Informant](https://en.wikipedia.org/wiki/Boundless_Informant), and +[FISA orders](http://www.guardian.co.uk/world/interactive/2013/jun/06/verizon-telephone-data-court-order), +there has been a surge of new users and inquiries about how to get involved. + +XXXXX + +If you're interested in the project, here are some ways to help out Open Whisper Systems: + +* **Use the software and provide feedback.** One of the best ways to help is by providing valuable user feedback. + Install [TextSecure](https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms) or + [RedPhone](https://play.google.com/store/apps/details?id=org.thoughtcrime.redphone) and file bugs you encounter + or features you feel are missing [on the issue tracker](https://github.com/whispersystems/textsecure/issues). +* **Help spread the word!** Tell a friend. +* **Translate to non-English languages.** Localizing the software for different regions helps ensure we can distribute + it as widely as possible. You can help with translation by joining the Transifex translation + teams for [TextSecure](https://transifex.com/projects/p/textsecure-official) and + [RedPhone](https://transifex.com/projects/p/redphone). +* **Contribute code.** If you're a software developer, pull requests are invaluable. A + good place to start is with any of the many [outstanding issues](https://github.com/whispersystems) on GitHub. + If there are features or other areas of interest that you're drawn to -- get in touch, or just get started. +* **Design.** If you're a designer, we are in dangerous need of assistance. If you get in touch we can send you + a current list of areas we need help with (as if it isn't already obvious). +* **Funding.** Lastly, if you don't have any time to spare, but still want to contribute, we accept Bitcoin: + + Donate Bitcoins + + + diff --git a/_posts/2013-07-25-iphone-rsn.md b/_posts/2013-07-25-iphone-rsn.md new file mode 100644 index 0000000..510ba8a --- /dev/null +++ b/_posts/2013-07-25-iphone-rsn.md @@ -0,0 +1,22 @@ +--- +layout: post +title: "Blog >> Open Whisper Systems is coming to iPhone!" +--- + + + +XXXXX + + + +The rumors are true. We want Open Source secure communication to be ubiquitous, so we're working towards making our apps +available in as many popular environments as we can, starting with the addition of iOS. + +Development for RedPhone on iOS has been underway since the beginning of the year, and development for TextSecure on iOS +got off to an amazing start at this year's [Spring Break Of Code](https://whispersystems.org/blog/sure). + +We're on track to start releasing iPhone apps by the end of the summer. You can sign up above to be notified when these apps +become available (we'll only ever use your email to let you know about new Open Whisper Systems iPhone apps). + +And of course, Android users can already download our apps [from the Play Store](https://play.google.com/store/apps/developer?id=Open+Whisper+Systems). + diff --git a/_posts/2013-07-27-simplifying-otr-deniability.md b/_posts/2013-07-27-simplifying-otr-deniability.md new file mode 100644 index 0000000..7ca41da --- /dev/null +++ b/_posts/2013-07-27-simplifying-otr-deniability.md @@ -0,0 +1,135 @@ +--- +title: Blog >> Simplifying OTR deniability. +layout: post +--- + +At Open Whisper Systems we help develop [TextSecure](https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms), an +encrypted chat application for Android. TextSecure was designed as a general purpose SMS/MMS client which would also +automatically encrypt conversations when communicating with other TextSecure users. For those encrypted sessions, TextSecure +uses a compact derivative of the well known [OTR protocol](http://www.cypherpunks.ca/otr/). + +We're currently in the process of transitioning TextSecure to use a device's data channel as a transport for communication +with other TextSecure users whenever possible. This enables communication with the upcoming [TextSecure for iOS](/blog/iphone-rsn), +helps users avoid SMS fees, and obscures conversation metadata from telcos. + +The transition to a new transport is also a good opportunity for us to evaluate and introduce additional cryptographic +protocol changes. Below is one cryptographic protocol change we're thinking of making that we'd welcome feedback on. + +XXXXX + +## OTR Today + +One of OTR's primary features is a property called *deniability*. If someone receives an OTR message from you, they can be +absolutely sure you sent it (rather than having been forged by some third party), but can't prove to anyone else that +it was a message you wrote. This is a nice change compared to PGP signatures, for instance, where anyone who receives a +PGP signed message can prove exactly who wrote it to anyone else. + +Let's see how this works. A simplified version of the initial OTR key exchange looks like this: + + + +Each participant has a long-term identity key (A and B) that they use to sign an ephemeral key (a and b), which they exchange +and use to [calculate a shared secret](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange). In reality, this +initial exchange is more complex, since it actually happens inside *another* ephemeral key exchange (for privacy reasons), +but this is the basic thrust of it. + +The shared secret from this key exchange is used to derive a sending and receiving cipher key for each party, as well as a +set of MAC keys for each party. Every transmitted message includes a +[MAC](https://en.wikipedia.org/wiki/Message_authentication_code), which the message's recipient can verify. Since the key +used to construct and verify the MAC was derived from the shared secret, and since the shared secret was derived from +a key exchange that was in turn signed by the sender's long-term identity key, the recipient can be sure that the message +was really constructed by their peer in the conversation. + +The message is "deniable," however, because the MAC keys are derived from a *shared* secret. Unlike PGP signatures, where +the sender is the only person capable of producing the signature, the recipient of an OTR message is *also* capable of producing +a sender's MAC. This doesn't compromise the integrity of the conversation for its participants, but does prevent a message's +recipient from revealing the MAC'd message to a third party as proof that it was produced by the sender, since it could have +just as easily been constructed by the recipient themselves. Exactly what we want. + +OTR's deniability efforts don't stop there, however. As a conversation progresses, OTR's key material will continually roll +forward (for ongoing [forward secrecy](https://en.wikipedia.org/wiki/Perfect_forward_secrecy)), and every time a conversation's +MAC keys roll forward, OTR publishes the old ones onto the wire in the clear. The idea being that, given old MAC keys, any +passive observer could technically modify old ciphertext and produce forged but valid MACs for it, which increases a message's +plausible deniability without compromising a conversation's integrity (since those old MAC keys can't be used for new messages). + +## Limitations + +As implementors of a protocol that's derivative of OTR, there are a few things that we haven't been satisfied with. + +### Complexity + +OTR uses a Diffie-Hellman key exchange of ephemeral keys, signed by long-term identity keys. While Diffie-Hellman is remarkably +simple, [DSA](https://en.wikipedia.org/wiki/Digital_Signature_Algorithm) (used to calculate those identity key signatures) is not +nearly as simple, and is often +[easy to fuck up](http://www.exophase.com/20540/hackers-describe-ps3-security-as-epic-fail-gain-unrestricted-access/). It'd be nice +to avoid subjecting ourselves to that increased complexity if we can. + +Additionally, publishing old MAC keys in the clear is a somewhat strange contortion for a protocol to make, and has a dangerous +feeling associated with it. Ephemeral or not, it seems like it'd be ideal if all our secrets could remain secret. We'd +be happy if it were possible for us to eliminate that added protocol complexity as well. + +### Limited Forgability + +Presumably, OTR goes through the contortions of publishing old MAC keys to increase an old message's forgability, +which should strengthen that message's deniability (if *anyone* could have forged it, it's easier to deny). However, it's +not entirely clear how this works in practice. + +It's true that by publishing old MAC keys, anyone is capable of modifying the *ciphertext* of a previously observed +message. However, even if that person can guess the plaintext and is capable of making predictable modifications to the +ciphertext via a malleable encryption scheme, they still can't demonstrate valid plaintext to anyone else without the cipher +keys (and if they had those, they would be able to calculate the MAC keys anyway). + +What's more, since the initial OTR key exchange is signed and transmitted through an unobservable channel (an "outer" ephemeral +key exchange), it's not actually possible for *anyone* to produce what appears to be a conversation with you. Only people you've +*actually* had a conversation with are in posession of a signed ephemeral key from you, and are thus the only ones capable of +producing plaintext messages attributed to you. Publishing old plaintext MAC keys in the clear does not substantially increase +this set of people's ability to forge messages from you, since they are already in possession of the MAC keys. + +So even after going through the contortions of publishing plaintext MAC keys, the set of people capable of producing forged +messages from a sender is still just the set of people who've actually received messages from that sender. + +## Potential Simplifications and Improvements + +The inimitable [Trevor Perrin](http://trevp.net/) turned us on to a trick that we can use to greatly simplify and improve +OTR's deniability property. All it takes is modifying the initial key exchange from this: + + + +To this: + + + +This replaces two DSA signatures and one Diffie-Hellman exchange with three Diffie-Hellman exchanges. Each participant still +has a long-term identity key (A and B) and an ephemeral key (a and b). However, instead of signing the ephemeral keys, +participants simply exchange both unsigned keys (gA,ga) and (gB,gb) to calculate +three shared secrets: gaB, gAb, and gab. + +By then using all three shared secrets as one combined seed to the initial +[KDF](https://en.wikipedia.org/wiki/Key_derivation_function), we accomplish the following: + +1. **Reduced Algorithmic Complexity**. We've eliminated DSA and have a nice authenticated key exchange that relies solely + on the simplicity of Diffie-Hellman. +1. **Increased Forgability**. Since there are no signatures involved, anyone could take A's public key, make up an ephemeral + keypair for A ("a" in the diagram above), combine that with their own identity key and ephemeral key ("C" and "c"), and + produce an entire forged transcript -- *even if they've never had a conversation with "A" before*. Now anyone is capable + of easily producing a forged message from anyone else, whether they've actually had a conversation with them before or not. +1. **Reduced Protocol Complexity**. Since *anyone* is capable of using *only* someone's public identity key to produce an + entire forged conversation, there is no need to publish old MAC keys in the clear any longer. Our secrets can remain secret, + and we can eliminate that somewhat odd bit of protocol complexity. +1. **Maintained Forward Secrecy**. Since an ephemeral handshake is part of the KDF seed, the compromise of an identity key + will still never result in the compromise of previously transmitted ciphertext -- or even passive observation of future + ciphertext. +1. **Smaller Payloads**. Instead of transmitting an identity key, an ephemeral key, and a signature during the handshake, + one only needs to transmit an identity key and an ephemeral key, reducing the payload by the size of the signature (a + significant amount for transports like SMS). Additionally, subsequent message payload sizes are also reduced, since broadcasting + plaintext MAC keys is no longer necessary. + +We found Trevor's suggestion to have surprising results. With one small change to the initial key exchange, we can reduce +its complexity (no more DSA), eliminate publishing old MAC keys in the clear, increase deniability by increasing forgability, +and reduce payload size -- all without increasing the number of round trips required or introducing any other additional +complexity. + +We're currently looking at integrating this change into the next version of the TextSecure protocol, along with a number of +other improvements for asynchronous communication that we'll write more about later. + +[Moxie Marlinspike](https://twitter.com/moxie), 27 July 2013 diff --git a/_posts/2013-08-22-asynchronous-security.md b/_posts/2013-08-22-asynchronous-security.md new file mode 100644 index 0000000..fef49e5 --- /dev/null +++ b/_posts/2013-08-22-asynchronous-security.md @@ -0,0 +1,113 @@ +--- +layout: post +title: "Blog >> Forward Secrecy for Asynchronous Messages" +--- + +Traditionally, asynchronous messaging systems such as email have relied on protocols like PGP or S/MIME for +cryptographic security. These protocols work the way most people are familiar with: one who wishes to receive +encrypted email advertises a public key, and those wishing to send encrypted email to that person encrypt their +outgoing message with that public key. + +XXXXX + + + +While this works, it means that every time anyone sends a message to a given recipient, that message is encrypted +with the recipient's *same* public key. Over and over again. + +If an attacker were to record all of a target's ciphertext traffic over some extended period of time, and then compromise +that one key at any point in the future (perhaps by seizing the device it's on), they would have the ability to decrypt +all of the previously recorded ciphertext traffic belonging to the target. + +## Forward Secrecy + +Modern cryptographic protocols like [OTR](https://en.wikipedia.org/wiki/Off-the-Record_Messaging) remedy this +situation through the use of [ephemeral key exchanges](https://en.wikipedia.org/wiki/Diffie_hellman). Rather than +always encrypting to the same static public key, peers in a conversation instead negotiate secrets through an +ephemeral key exchange. OTR takes this a step further by piggy-backing a new Diffie-Hellman exchange on each exchange +of messages in a conversation, which continually ratchets the key material forward. + +Since these key exchange parts are ephemeral, recording ciphertext traffic doesn't help a would-be adversary, since +there is no durable key for them to compromise in the future. Even if one's device is compromised, there is no key +material on the device to help an adversary decrypt previously exchanged ciphertext. This property is often referred +to as [Perfect Forward Secrecy](https://en.wikipedia.org/wiki/Perfect_forward_secrecy). + +## Asynchronous Life + +OTR was designed for synchronous transports. It works well for desktop IM clients, but is not well tailored for the +mobile environment, where a number of factors such as the OS process model, battery constraints, and network conditions +have conspired to make mobile messaging systems asynchronous. + +If an application running on iOS wishes to receive messages while it's in the background, for instance, the only reliable +mechanism is to use Apple Push Notifications. Once a push notification is delivered, the user will be presented with a +familiar prompt: + + + +But on iOS, the actual app still hasn't received anything at this point. Only once a user *physically taps* the prompt +or otherwise opens the app does the app itself finally receive the message. + +These types of asynchronous transports pose a fundamental problem for forward secrecy protocols: in order to send a message, +the app first needs to complete a key exchange. However, to complete a key exchange requires a full round trip of sending a key +exchange message and waiting for a key exchange message response -- in a world where there is no guarantee of a rapid response. + +On platforms like iOS, this would make for a particularly bad user experience: + +1. Someone has a message to send, but first has to send a key exchange message and wait for + a key exchange message response. +1. Meanwhile, the recipient of the would-be message gets a visual notification of having received + a key exchange message, and has to physically interact with the app before the app has the opportunity + to process the key exchange message and respond with one. If the user is away from their device + or doesn't immediately click through to the app, the sender is left waiting. +1. The receiving user still hasn't received a message, though, and has to continue waiting for the *actual* + message to be delivered. +1. If the sending user has navigated away from the app, they will then get their own notification that + they've received a key exchange response from the message recipient, and will have to navigate *back* + to the app in order for the app to be able to process the key exchange response and *finally* send the encrypted message. +1. At this point, the message's recipient finally receives it. + +From a user experience perspective, this is not a tenable model. + +## Coping With Asynchronous Life + +Most secure messaging apps on platforms like iOS do one of two things when presented with this problem: either function +synchronously, or revert to the PGP world of static public keys. + +For instance, iOS apps like Silent Circle and ChatSecure provide forward secrecy, but are synchronous messaging systems that +only function when the app is in the foreground. If someone sends you a message after the app has been out of the foreground +for two minutes, you just don't get the message. This results in an awkward scenario where two users of these apps that wish +to communicate with each other need to somehow prearrange to both open the app simultaneously and keep it open for the duration +of their conversation. + +On the other hand, iOS apps like Threema and the proposed Heml support asynchronous messaging, but do not provide forward +secrecy. Users have static public keys that are maintained by a server, which anyone else can query and encrypt to without +having to engage in a key exchange round trip to the user. This allows for the frictionless asynchronous experience that +mobile users have come to expect, but unfortunately relies on an undesirable cryptographic protocol model (the PGP model) +that is increasingly being seen as an architectural dead end. + +## The TextSecure Protocol + +[TextSecure's](https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms) upcoming [iOS client](/blog/iphone-rsn) +(and Android data channel client) uses a simple trick to provide asynchronous messaging while simultaneously providing forward +secrecy. + +At registration time, the TextSecure client preemptively generates 100 signed key exchange messages and sends them to +the server. We call these "prekeys." A client that wishes to send a secure message to a user for the first time can now: + +1. Connect to the server and request the destination's next "prekey." +1. Generate its own key exchange message half. +1. Calculate a shared secret with the prekey it received and its own key exchange half. +1. Use the shared secret to encrypt the message. +1. Package up the prekey id, the locally generated key exchange message, and the ciphertext. +1. Send it all in one bundle to the destination client. + +The user experience for the sender is ideal: they type a message, hit send, and an encrypted message is immediately sent. + +The destination client receives all of this as a *single* push notification. When the user taps it, the client has everything +it needs to calculate the key exchange on its end, immediately decrypt the ciphertext, and display the message. + +With the initial key exchange out of the way, both parties can then continue communicating with an OTR-style protocol +as usual. Since the server never hands out the same prekey twice (and the client would never accept the same prekey twice), we +are able to provide forward secrecy in a fully asynchronous environment. + +[Moxie Marlinspike](https://twitter.com/moxie), 22 August 2013 diff --git a/_posts/2013-09-27-hackathon-zurich.md b/_posts/2013-09-27-hackathon-zurich.md new file mode 100644 index 0000000..c8a804c --- /dev/null +++ b/_posts/2013-09-27-hackathon-zurich.md @@ -0,0 +1,26 @@ +--- +title: "Blog >> Open Whisper Systems Alpine Hackathon" +layout: post +--- + +From October 11th to October 13th, we'll be hosting an informal Open Whisper Systems *Alpine Hackathon* for those in or +around Zurich, Switzerland who would like to contribute to Open Whisper Systems related projects in a collaborative +setting with other co-conspirators. + +XXXXX + +## The Details + +Evening Friday October 11 to afternoon Sunday October 13th. Food provided, event is free +(courtesy of [Colab Zurich](http://colab-zurich.ch/)). + +If you're thinking of attending, please send an email to alpinehackathon@whispersystems.org with the following +information (brief is fine): + +1. Tell us a bit about yourself, what you spend your time on, and any public contributions you're proud of. +1. What you want to work on (any of the open issues on our [GitHub trackers](https://github.com/WhisperSystems) could + be a good start). + +We'll see you there! + +-- [Christine Corbett](https://twitter.com/corbett), 27 September 2013 diff --git a/_posts/2013-10-22-alpine-hackathon-reportback.md b/_posts/2013-10-22-alpine-hackathon-reportback.md new file mode 100644 index 0000000..3a40026 --- /dev/null +++ b/_posts/2013-10-22-alpine-hackathon-reportback.md @@ -0,0 +1,55 @@ +--- +title: "Blog >> Alpine Hackathon Reportback" +layout: post +--- + +*A guest post by [meskio](http://meskio.net/).* + +My cell phone used to be a black and white nokia until a couple of weeks ago, when I decided to enter in the smartphone world. +Now that there are more mobile devices connected to internet than computers, I think it's time for me as well to discover +the possibilities of this technology. During this few weeks I've been playing with my new toy, checking how to secure it, +what freesoftware is around to use cryptography on it. + +XXXXX + +Someone on the irc told me there will be a hackathon of whispersystems not that far away from my place. I couldn't miss this +opportunity to get my hands on android development and try to do something useful. So there I was in Zurich, after three +hours of travel, sleeping on a couch that a friend of a friend has lent me, anxious to hack with the whispersystems hackers. + + + +Colab is a great place for hackathons with great sound system (when you manage to make it work), tables with electrical +plugs everywhere and comfortable sofas to change your place when you are tired of the table. But the most important of +everything, they have a fridge full of drinks with club mate. + +We've been 6 people on the hackathon: Christine and Frederic hacking on the iOS version of TextSecure, Desiree, Kashif and +me learning while coding for the android version of TextSecure and Moxie trying to have something done on the server side +while we all ask him questions. + + + +Kashif and Desiree couldn't stay for the whole weekend, but they were full of energy and pretty productive. Kashif wrote +some lines about the weekend: + +> It was my first hackathon, and it was great to experience a different culture +> of coding/hacking as compared to my daytime job. Also, the pros who were there +> were very kind and helpful. Overall it was a great experience and I'm pretty +> sure I'll be going back to future hackathons. + +Christine took care of the organization of the event, welcoming us, providing food and bringing us to good places for beers. +When Frederic was not concentrated behind his screen was taking pictures of the event. And in the breaks Moxie amaze us with +his stories. + + + + + +Time past fast when you are focus on something, I have the feeling that the weekend was really short and that I didn't have +time to accomplish much. But I have few commits merged on the main repository and I learned a lot. I'm glad I went to of the +hackathon. + +-- [meskio](http://meskio.net/) + +Zurich, Switzerland + +22 October 2013 diff --git a/_posts/2013-10-23-winter-break-of-code.md b/_posts/2013-10-23-winter-break-of-code.md new file mode 100644 index 0000000..be360a6 --- /dev/null +++ b/_posts/2013-10-23-winter-break-of-code.md @@ -0,0 +1,105 @@ +--- +title: "Blog >> Winter Break Of Code" +layout: post +--- + +At Open Whisper Systems, we're focused on creating easy to use privacy enhancing technology. Our projects are free, Open Source, +and tend to be oriented around the mobile environment. We've been working on apps like [TextSecure](https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms) and [RedPhone](https://play.google.com/store/apps/details?id=org.thoughtcrime.redphone) +(which provide secure text messages and secure phone calls) for years now, because we believe that it's possible to develop +well-designed secure communication tools that are both privacy preserving *and* a joy to use. + +This winter, we'd like to invite you to join us for "Winter Break Of Code," a week-long free trip to Kauai for anyone +who'd like to spend a week working on this type of easy to use privacy enhancing technology in a collaborative +environment. We've rented a large beachfront house on the north coast of Kauai for everyone to stay +in, and we'll pay for your airfare. While there, you can split your time between island living and working on an Open Whisper +Systems related privacy project that you propose. + +XXXXX + +## The Precedent + + + +Earlier this year, we hosted the Open Whisper Systems [Spring Break Of Code](https://whispersystems.org/blog/spring-break-of-code-lineup/) in Maui. It vastly exceeded the expectations of the organizers, and was an amazing week that connected a group with +a great skill and interest mix, launched exciting new projects, and moved old ones lightyears forward. We encourage you to +read more about it ([here](https://whispersystems.org/blog/dirigibles-chinese-junk-rigs-and-surfboards), +[here](https://whispersystems.org/blog/highly-unconventional-suggested-first-aid), +[here](https://whispersystems.org/blog/streamlining-textsecure-settings), +[here](https://whispersystems.org/blog/sure), +[here](https://whispersystems.org/blog/all-the-things-that-pull-and-push), +[here](https://whispersystems.org/blog/call-quality-metrics), and +[here](https://whispersystems.org/blog/sboc-goodbye)). We're hoping to repeat the experience. + +## The Details + +*Winter Break Of Code* will be **January 5th to January 12st, 2014**. We've rented a large beachfront house in Hanalei, on +the north coast of Kauai, HI (within walking distance to a world class surf spot). We will be taking up to eight people, and will +cover your costs for: + +- Lodging in a large beachfront house. +- Your roundtrip airfare. +- A surfboard for the week. + +*Winter Break Of Code* is an opportunity for designers, developers, writers, strategists, and creative thinkers interested in privacy +and security to spend some time contributing to privacy related projects in a retreat-like setting with other co-conspirators. +Think of it as an extended hackathon, but with your travel expenses paid, and with breaks for surfing, hiking, swimming, and +just generally being in Kauai. + +## Interested? + +To apply to *Winter Break Of Code*, send an email to **winterbreakofcode@whispersystems.org** with the following information: + +- **Tell us about yourself.** Who are you, where do you live, what have you been working on, and what interests you about + Open Whisper Systems? Don't worry if you are a student or don't have tons of "industry" experience, personal projects + are great. +- **Examples of your work.** Are there other public contributions you've made that you're proud of? +- **What you want to work on for Winter Break Of Code.** This should be something you're excited about that can either + be finished in a week, or that a useful and discrete part of can be finished in a week. + + Some example ideas could be: + + 1. Working on a desktop/browser extension version of RedPhone or TextSecure. + 1. Helping with the iOS development effort. + 1. Any of the open issues on our GitHub trackers ([here](https://github.com/WhisperSystems/TextSecure/issues) or + [here](https://github.com/WhisperSystems/RedPhone/issues/)). + 1. Doing some much needed design work on any Open Whisper Systems apps, icons, branding, etc. + 1. A system for distributing our Android apps [outside the Play Store](https://github.com/WhisperSystems/TextSecure/issues/127#issuecomment-21763521). + 1. Helping ship projects that are still incubating, such as [Zones](https://github.com/whispersystems/zones), or + projects that are on the horizon, such as Secure Sync. + 1. Putting together a good solution for Open Whisper Systems user-oriented documentation. + 1. Working on anything for the website. + 1. Adding "push to talk" functionality to RedPhone. + 1. Improving RedPhone call quality. + 1. Making UX iterations to the way the apps function (on Android or iOS). + 1. Adding multi-device support to TextSecure and RedPhone. + + Or anything else you're excited about: fixing broken windows that have annoyed you, writing features you think would + be useful, or even developing a new small app (or existing project of your own) that you think would help. Just think + of the skills you're good at or are interested in developing and how you might be able to apply those to helping better + achieve the goal of dead-simple mobile security and privacy for everyone. + + Please include some information about why you're confident you'll be able to complete your project over *Winter Break Of Code*. + +## You should also know... + +We understand that it requires commitment in order to travel great distance and spend a week with people you +might not already know. We'll work hard to ensure that the infrastructure is set up well in order to make +this week great, but we also want to set the framework for the expectations we believe we should have for +each other: + +- **Respect:** We ask for everyone to respect each other, the space, and the local area. We want this event to +be inclusive for everyone involved, and will not tolerate harassment or rude behavior. + +- **Consent:** Any interaction with anyone at *Winter Break Of Code* should be consensual. + +- **Privacy:** The house we've rented is spacious, but not large enough for everyone to have their own private +room. We will organize shared rooms based on gender, and will do our best to ensure that everyone has the space +they need. + +## Timeline + +We want to have selected all the proposals we have space for by December 1st. If you're interested, please submit a +proposal between now and then. We'll be accepting proposals as we go, however, so we might run out of space before then; +the earlier you get something in the better. + +We're excited, and hope you will be too! diff --git a/_posts/2013-11-26-advanced-ratcheting.md b/_posts/2013-11-26-advanced-ratcheting.md new file mode 100644 index 0000000..682fc7f --- /dev/null +++ b/_posts/2013-11-26-advanced-ratcheting.md @@ -0,0 +1,224 @@ +--- +title: "Blog >> Advanced cryptographic ratcheting" +layout: post +--- + +At Open WhisperSystems, we've been working on improving our encrypted asynchronous chat protocol for TextSecure. +The TextSecure protocol was originally a derivative of [OTR](https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html), +with minor changes to accommodate it for transports with constraints like SMS or Push. Some of the recent +changes we've made include +[simplifying and improving OTR's deniability](https://whispersystems.org/blog/simplifying-otr-deniability), as well as +creating a [key exchange mechanism for asynchronous transports](/blog/asynchronous-security). +Our most recent change incorporates what we believe to be substantial improvements to OTR's forward secrecy "ratchet." + +XXXXX + +## The OTR Ratchet + +As we've [discussed previously](/blog/asynchronous-security), "[forward secrecy](https://en.wikipedia.org/wiki/Forward_secrecy)" +is one of the critical security properties OTR is designed to provide. In contrast to the PGP protocol model, where messages +to a recipient are encrypted with the same public key over and over again, OTR uses +[ephemeral key exchanges](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange) for each session. This is a critical +feature of any modern secure protocol, because otherwise a network adversary who records (potentially years of) ciphertext traffic +can later decrypt *all of it* if they manage to +[later compromise the one key that was used](http://www.thoughtcrime.org/blog/lavabit-critique/). +By contract, with ephemeral key exchanges, there is no key to compromise in the future (since the keys are only ephemerally +in memory for a short time), so any recorded ciphertext should remain private. + +Simply doing an ephemeral key exchange at the beginning of a session is enough to provide this property, but OTR takes things +a step further by continuously ratcheting the key material forward during the course of a session. The OTR ratchet is what +we call a "three step ratchet." + +1. Alice sends an encrypted message to Bob. Along with the actual message content, Alice "advertises" a new + Diffie-Hellman key that she will use in the future. +1. Bob sends an encrypted message to Alice. Along with the actual message content, Bob "acknowledges" the + key that Alice advertised, and also advertises his own next key. +1. Alice will use the advertised and acknowledged key the next time she sends a message. + + + +Note that, until Bob has acknowledged Alice's next key, she can't use it. If Alice needs to send multiple messages +to Bob before he replies, Alice will need to keep using her current key and advertising the same next key. + +## TextSecure and Forward Secrecy + +Given that OTR was originally positioned for instant messaging apps, it's not clear why individual message +level forward secrecy is necessary. Instant messaging sessions tend to be ephemeral, and the messages themselves tend +to be in memory for the duration of the session, so it's not entirely obvious what immediate value a ratcheting forward secrecy +protocol provides in that context. Simply doing an ephemeral Diffie-Hellman key exchange at the beginning of every session +would probably be enough. + +As an asynchronous messaging app, however, TextSecure benefits greatly from such a ratcheting forward secrecy mechanism. +Asynchronous chat sessions tend to be extremely long lived (perhaps even years long), in contrast to IM sessions which +are constantly being setup and torn down. In the context of long-lived sessions, however, the OTR ratcheting protocol leaves +something to be desired. Given the nature of a "three step" ratchet, if a sender transmits something to a receiver, and the +receiver doesn't respond for a few days, the sender has to keep the key material used to encrypt that message around for *days*. + +There are other simple problems as well. OTR was designed for transports which guarantee in-order delivery, which most +asychronous messaging transports don't provide. There is a counter which prevents replay attacks, but it's complex to +adapt to an unreliable transport, and there is also a possibility that old messages can arrive after key material has +been rolled forward. + +## The SCIMP Ratchet + +Silent Circle uses a *synchronous* protocol of their own devising (called SCIMP) that employs a different style of ratchet. + +Each message key is derived as an iterative hash of the last message key used. + +1. As soon as Alice sends a message to Bob, she hashes her encryption key to get her next encryption key. +1. Alice immediately destroys her encryption key and replaces it with her next encryption key. + + + +It's clear that an asynchronous messaging app like TextSecure could benefit from an immediate ratchet. Even with long running +sessions, there would never be *any* outstanding key material available for compromise. However, a protocol like SCIMP has some +drawbacks as well: + +1. The first question is what a client should do when a message is lost. If a client is expecting a message with + sequence number `5` but instead receives a message with sequence number `6` (common for asynchronous transports), + what should the client do? It's possible to derive the key material for sequence number `5` and then immediately + derive the key material for sequence number `6` to decrypt the message, but the client would need to hang on to + the key material for sequence number `5` until the message arrives. + + That key material is sensitive, however, because it can be used to calculate the key material for *every subsequent + sequence number*. So a client can't hang on to it forever, and using time-based or window-based approaches for + how long a client should retain it are always going to be hard to tune and inevitably tuned incorrectly for some + percentage of cases. +2. The OTR style ratchet has the nice property of being "self healing." If, for whatever reason, any individual ephemeral + key is compromised or otherwise found to be weak at any time, the ratchet will heal itself. We call this "future secrecy." + In the SCIMP hash iteration case, however, any individual ephemeral key compromise or problem will extend through the + entire session. + +## The Window Of Compromise + +A ratcheting protocol is largely about reducing the impacts of a key compromise. A hash ratchet protocol like SCIMP +has *excellent* forward secrecy properties but poor future secrecy properties, while a DH ratchet protocol like OTR +has less than perfect forward secrecy properties but nice future secrecy properties: + + + +## The TextSecure Ratchet + +We wanted a ratchet that combines the best of both worlds: the optimal *forward* secrecy that a hash iteration ratchet like +SCIMP provides, as well as the the nice *future* secrecy properties that a DH ratchet like OTR provides, with as little +of the negatives of both as possible. The inimitable [Trevor Perrin](https://github.com/trevp__) did most of the heavy +lifting for the primary innovations in combining the two. + +First, remember that the OTR message format looks roughly like this: + + struct { + opaque sender_key_id[4]; + opaque receiver_key_id[4]; + opaque next_key_id[4]; + opaque next_key[32]; + opaque ciphertext[...]; + opaque mac[10]; + } OTR_Message; + +All these key IDs are necessary because OTR is based on a mechanism of "advertising" keys and receiving confirmations +for those keys in subsequent messages. By advertising a key under a MAC from the previous key, the integrity of +advertised keys can be traced all the way back to the original shared key, ensuring that no MITM attack is possible +on any of the subsequently advertised keys. However, that is the source of our "three step" DH ratchet problem, and also +makes for a fair amount of book keeping. + +We wanted to incorporate a DH ratchet into our ratcheting protocol because of the "future" secrecy it provides. However, +it would be nice if we could eliminate the "advertise" step in the OTR ratchet and bring it down to a "two step" ratchet. +In order to achieve a "two step" ratchet, we derive a `RootKey` in our initial handshake KDF, and both mix it into and +re-derive it from every subsequent DH KDF. This makes it possible to chain the key material together so that Alice can +create and use a new DH ephemeral key *immediately* without first advertising it and waiting for acknowledgment. Because +the `RootKey` is mixed into the KDF, trust in new ephemerals can still be chained back to the initial handshake. + +This transforms the "three step" DH ratchet into a "two step" DH ratchet: + +1. Alice generates a new ECDH ephemeral key `A1` and uses it immediately to send a message. +2. Alice receives a message with Bob's new ECDH ephemeral `B1` and can then + destroy `A1` and generate `A2` when sending her next message. + + + + +This is a best possible case DH ratchet, and it also greatly simplifies the message format, which is now simply: + + struct { + opaque sender_ephemeral[32]; + opaque body[...] + opaque mac[10] + } + +It also eliminates all the key ID book keeping. + +To get the immediate forward secrecy of a SCIMP-like protocol, we can now mix in that style of hash iteration +ratchet for the space between DH round trip clicks. Essentially, for each message sent within the context of +a single DH ratchet click, there is a sub-ratchet in the hash iteration ratchet style. + +From Alice's perspective, the final picture looks like this: + + Alice + + Sending | Receiving + + MK CK RK CK MK + -- -- -- -- -- + ECDH(A0,B0) + | + | + ECDH(A1,B0) + + /| + / | + / + ECDH(A1,B1) + CK-A1-B0 |\ + | | \ + MK-0 ----+ | \ + | | CK-A1-B1 + MK-1 ----+ | | + | | +---- MK-0 + MK-2 ----+ | | + | +---- MK-1 + ECDH(A2,B1) + + /| + / | + / | + CK-A2-B1 | + | + ECDH(A2,B2) + MK-0 ----+ \ + \ + \ + CK-A2-B2 + | + +---- MK-0 + | + +---- MK-1 + +1. Each DH ratchet is combined with the existing root key (`RK`) to derive a new `RK` as well + as a "chain key" for that DH pair. +1. Each "chain key" is hash iterated for each message sent/received under that chain. +1. Rather than hash iterating the cipher keys used to encrypt a message directly (SCIMP style), there + is a layer of indirection where message keys are derived from the chain keys. This solves + SCIMP's "delayed message problem," because in the case of a delayed message its keys can be + immediately derived and cached without holding back the chain key from ratcheting forward. + Those cached message keys can not be used to derive any subsequent message keys, maintaining + forward secrecy. + +The final message format is simply: + + struct { + opaque sender_ephemeral_key[32]; + opaque counter[3]; + opaque mac[10]; + } + +The result is a ratcheting protocol that combines the best of a DH ratchet's "future secrecy" +properties with the optimal "forward secrecy" properties from a hash ratchet. It also simplifies +the wire format and eliminates all the key ID book keeping. Nice properties like cryptographically-enforced +message ordering and replay protection all come for free, without any complex record keeping required. +The code is simpler, and the protocol security is more robust. + +We think this represents an improved cryptographic protocol for asynchronous messaging systems +like TextSecure. Another asynchronous messaging system, Pond, has +[also incorporated it](https://github.com/agl/pond/commit/338395668fbb8a7819c0fccf54dccaa4d7f0ae9e). + +This is obviously a simplified protocol description, but the [full specification +can be found here](https://github.com/trevp/axolotl/wiki) if you'd like to look at it critically or +in more detail. + +-- [Moxie Marlinspike](https://twitter.com/moxie), 26 November 2013 diff --git a/_posts/2013-12-09-cyanogen-integration.md b/_posts/2013-12-09-cyanogen-integration.md new file mode 100644 index 0000000..9a46afa --- /dev/null +++ b/_posts/2013-12-09-cyanogen-integration.md @@ -0,0 +1,83 @@ +--- +title: "Blog >> TextSecure, Now With 10 Million More Users" +layout: post +--- + +At Open WhisperSystems, we're working to both advance the state of the art for secure communication +and also reduce the friction required for ordinary people to make use of it. We want everyone to have +access to advanced secure communication methods that are as easy and reliable to use as making a normal phone call or sending +a normal text message. + +With these goals in mind, we've been working with [CyanogenMod](http://www.cyanogenmod.org/) over the past few months. +CyanogenMod is an open source aftermarket Android firmware distribution with [ten million users](http://stats.cyanogenmod.com/) +and ~20k installs a day. Their rapid growth is beginning to rival Microsoft for the third largest smartphone OS distribution. + +As of today, the TextSecure protocol will begin shipping as part of the CyanogenMod OS-level SMS provider, in an effort to provide +completely transparent end-to-end text message encryption between all of their users. + +XXXXX + +## Integration + +We've modified the Cyanogen SMS/MMS provider to speak the +[TextSecure](https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms) protocol. +If an outgoing SMS message is addressed to another CyanogenMod or TextSecure user, it will be transparently encrypted and sent +over the data channel as a push message to the receiving device. That device will then decrypt the message and deliver +it to the system as a normal incoming SMS. + +The result is a system where a CyanogenMod user can choose to use any SMS app they'd like, and their communication +with other CyanogenMod or TextSecure users will be transparently encrypted end-to-end over the data channel without +requiring them to modify their work flow at all. + +Here's how an encrypted conversation looks: + + + +There's no visible difference. Nothing at all changes for the user, and the entire process is completely transparent. +The user doesn't have to initiate a key exchange and wait for a round trip to complete, or know that the recipient is +"online." They simply send a message, and it's sent immediately. Everything works just like the normal asynchronous +SMS experience, even if the recipient doesn't have their device on. + +The demo above uses the stock Messaging app, but users could choose to install any other SMS app instead, with the same effect. +We will also be adding some minimal visual feedback to the stock CyanogenMod Messaging app to indicate when the user has an +expectation of privacy and when they don't, but the base experience won't change at all. + +Technical users have the option to verify identity keys, and all users are notified if an identity key changes. + +## Technical Details + +This project incorporates all of the TextSecure protocol features. The encryption layer is the +[TextSecure V2](https://github.com/WhisperSystems/TextSecure/wiki/ProtocolV2) protocol, which employs the +[Axolotl forward secrecy ratchet](https://www.whispersystems.org/blog/advanced-ratcheting/) for forward secrecy and the +[3DHE agreement](https://whispersystems.org/blog/simplifying-otr-deniability) for deniable messages. + +The TextSecure V2 cryptographic primitives are Curve25519, AES-256, and HmacSHA256. + +The transport protocol is the [TextSecure Push API](https://github.com/WhisperSystems/TextSecure-Server/wiki/API-Protocol), +which makes use of a [prekey system](https://whispersystems.org/blog/asynchronous-security) to obtain forward secrecy +in an asynchronous messaging environment. + +The client logic is contained in a CyanogenMod system app called +[WhisperPush](https://github.com/CyanogenMod/android_external_whispersystems_WhisperPush), which the system hands outgoing SMS +messages to for optional delivery. The Cyanogen team runs their own TextSecure server for WhisperPush clients, +which federates with the Open WhisperSystems [TextSecure server](https://github.com/WhisperSystems/TextSecure-Server), so +that both clients can exchange messages with each-other seamlessly. All of the code involved throughout the entire stack is +fully Open Source. + +## The Future + +This effort marks the beginning of our transition to the data channel as a TextSecure transport, which should hopefully open up +a host of ongoing opportunities. With the [TextSecure iOS client](https://github.com/whispersystems/TextSecure-iOS) nearing +completion and a TextSecure browser extension about to get underway, soon we will have a truly cross platform +seamless asynchronous messaging system built on open protocols and open source software, with an already massive user base. + +Cyanogen deserves enormous praise for their substantial commitment of time and resources to this development effort. Their +genuine resolve to protect their users from large-scale dragnet surveillance is truly remarkable in a world where most companies +are instead angling to collect as much information about their users as possible. They've set the bar high for themselves, +but I think we can expect more great things from them in the future. + +Want to help support Open WhisperSystems? The Freedom Of The Press Foundation is +[accepting tax-deductable donations](https://pressfreedomfoundation.org/bundle/encryption-tools-journalists) for us and other +important projects in this space. + +-- [Moxie Marlinspike](https://twitter.com/moxie), 09 December 2013 diff --git a/_posts/2013-12-11-winter-break-of-code-lineup.md b/_posts/2013-12-11-winter-break-of-code-lineup.md new file mode 100644 index 0000000..a8ad94a --- /dev/null +++ b/_posts/2013-12-11-winter-break-of-code-lineup.md @@ -0,0 +1,107 @@ +--- +title: "Blog >> WBoC Lineup" +layout: post +--- + +After our wonderful experience with [Spring Break Of Code](https://whispersystems.org/blog/sure), we were excited to try this +again. Even with high expectations based on our experience in the Spring, the response was still better than what +we could have hoped for. The hundreds of high quality proposals we received were really inspiring, and +we hope that one day we can get a space large enough for all of the amazing people who are passionate +about the development of privacy enhancing technology. + +We think the final lineup of those attending in January is going to be great: + +XXXXX + +Rhodey +**Rhodey** ([@notrhodey](https://twitter.com/notrhodey)) space, privacy, robits and the cheaper things in life. I plan +to spend WBoC working on Secure Sync, a contact and calendar synchronization service for Android featuring end-to-end +encryption. I also hope to prepare "Zones" for release on Google Play by closing what it left of the GitHub issues and +polishing other bits. + +

+ +Christine +**Christine Corbett** ([@corbett](https://twitter.com/corbett)) Christine Corbett Moran is a PhD candidate in Computational +Astrophysics alongside actively contributing to mobile products for social good. In her spare time, she enjoys skating for +the Zurich City Roller Girlz roller derby team, adventure sports, and world travel. At WBoC she'll be continuing development +of TextSecure iOS and her surfing technique. + +

+ +Meskio +**Meskio** ([meskio](http://meskio.net)) I'm a computer geek interested on the possibilities that new technologies bring +to empower people. I love to learn programming languages and develop free software. I've being working for the past two +years at CERN (Geneva, switzerland) as a C++ developer in the control system of the accelerators. I'm a maniac of mountains +and traveling, going to remote places searching for new routes to climb. At the WBoC I'll be working on adding OpenStreetMap +support to Zones and squashing bugs on TextSecure. + +

+ +Ellie Frost +**Ellie Frost** ([@stillinbeta](https://twitter.com/stillinbeta)) I'm a software engineer, +presently working towards a degree in computer science at the University of Toronto. I like open source, distributed systems, +and vegan food. I dislike single points of failure, untested code, and patriarchy. + +I will be working on a system for distributing APKs, collecting statistics, and handling crash reports outside of the +Google Play framework. This will make it easier to run Open WhisperSystems' software on Android devices without Google's +proprietary software. + +

+ +Matt Corallo +**Matt Corallo** Matt is a senior Computer Science student at UNC. He has been developer on the Bitcoin Core client +(the most popular Bitcoin client) for over two years and the bitcoinj library (the most popular library which +powers the top mobile client and several desktop clients) for over a year. His research interests include software +mechanisms for protecting systems against physical attacks and practical secure systems. During the WBoC, Matt will be +working to implement browser extensions for TextSecure and RedPhone to allow users access to their text messages and +phone calls outside of their smartphone. + +

+ +Meghana +**Meghana Khandekar** ([@mkhandekar](https://twitter.com/mkhandekar)) Meghana is a MFA Interaction Design student at School of +Visual Arts in New York. She explores the way people interact with others, technology & products, and ultimately improves those +experiences. She has worked with startups, Berkman Center, World Bank, and UNICEF to design software & systems solutions to +improve access to & delivery of services and information. Through this work experience she has come to design for discourse +around human rights, freedom of expression and digital security. + +Meghana's primary goal for the week will be understanding Open WhisperSystems' mission, audience & brand attributes, the +market(s) it belongs, its competitors and collaborators and the desired perception & image within those groups. All this +will inform Open WhisperSystems' new branding, website design, and communication strategy. If time permits, that work could +influence aspects of TextSecure and RedPhone design and user experience as well. + +

+ +Jake +**Jake McGinty** I like the distorted, the unexpected, and solid colors. To pass the time I am enjoying my sensory inputs, +providing sensory output, and generally trying to find good problems around free information. I am in awe at the doors +technology has opened as well as its amazing potential for unintended consequences. I'm always searching for the secrets +of the human factor and the subtle effects technology has on our behavior. I'll be working on improving the look and feel +of TextSecure, stomping out bugs, as well as filling some outstanding feature requests to pump up TextSecure's client-side +security. Beyond that, hopping around, learning, contributing, falling into water a lot, and generally mushing minds together. + +

+ +Lilia +**Lilia Kai** ([@liliakai](https://twitter.com/liliakai)) As a web developer for the EFF, and given my laser-enhanced 20/15 +visual acuity, I'm pretty much a superhero. Other hats I've worn include arduino hacker, duck farmer, and pro yoyoer. +This winter break I'll be using my superpowers to ensure that no matter what device, browser, search engine, or screen +size you prefer, the Open WhisperSystems website is always looking good! + +

+ +Tyler +**Tyler Reinhard** ([@abolishme](https://twitter.com/abolishme)) Tyler is a [workflow publisher](http://abolish.me), +designer, front-end web developer, and [social theorist](https://twitter.com/mask_mag) living in Brooklyn, NY. He's been +involved with Whisper Systems since the original beta, and is currently working on the iOS interface for a new implementation +of Open WhisperSystems secure communication software. Tyler is also the co-founder of [Mask Magazine](http://maskmagazine.com), +a style magazine for antagonist youth. + +

+ +Moxie +**Moxie Marlinspike** ([@moxie](https://twitter.com/moxie)) Interested in the tension towards the unmediated, +combined with a strange passion for secure protocols. Ultimately, we also needed someone there to wash the dishes. + +

diff --git a/_posts/2013-12-16-bithub.md b/_posts/2013-12-16-bithub.md new file mode 100644 index 0000000..86a4656 --- /dev/null +++ b/_posts/2013-12-16-bithub.md @@ -0,0 +1,88 @@ +--- +title: "Blog >> BitHub = Bitcoin + GitHub. An experiment in funding privacy OSS." +layout: post +--- + +At Open WhisperSystems, we often get emails from people who'd like to donate money to the project. For an OSS project, +particularly one that aspires to a collective sense of ownership, handling donations is not always entirely straightforward. + +The fundamental contradiction is that while donations are meant for a *project*, they're traditionally sent to a *person*. +Even if a project sets up a bank account, there are still only a few people who have access to the money itself, and +distributing it appropriately can be hard to figure out. + +Its never been clear to us how we should handle small donations, so often times when people ask about donating, we just tell +them that the best way to help is to use the software, spread the word, and file well documented bugs when they find them. Which +is true! But it'd also be great if we had a nice system for handling donations that matched our objectives for collective ownership. + +XXXXX + +## A Bitcoin Experiment + +We've written and deployed a [simple service](https://github.com/WhisperSystems/BitHub) called "BitHub" that does two things: + +1. Accepts Bitcoin donations and allocates them into a single pool of funds. +1. Distributes the Bitcoin donations from that pool to *anyone* who commits to our repositories. + +We're starting with an initial "worse is better" distribution strategy: the owner of every merged pull request is +paid 2% of our total balance at the time of the merge. Depending on how that works, we might adjust the payout strategy +in the future, or even add features like the ability to donate for bounties on specific GitHub [issues](https://github.com/WhisperSystems/TextSecure/issues). + +In order to effectively communicate the current payout for a project to developers, a BitHub instance will render the current +payout amount (in USD) as an image that can be embedded in a GitHub project's README.md (or anywhere). + +For example, this is the current Open WhisperSystems payout per commit, rendered dynamically as an image by the Open +WhisperSystems BitHub instance: + + + +A project's BitHub instance will also return JSON (or rendered HTML) of the most recent payouts. For example, these are the +five most recent Open WhisperSystems payouts returned from the API: + + + +This way anyone can donate to the project, and the donations are distributed to anyone who'd like to be involved in the project. + +## We've got Bitcoin! We need Bitcoin! + +If you'd like to help the development of Free and Open Source privacy software that is attempting to +[advance the state of the art](/blog/advanced-ratcheting) for secure communication and also +[reduce the friction required](/blog/cyanogen-integration) for ordinary people to make use of it, you can +submit Bitcoin donations here: + +Donate Bitcoins + + + +Anyone will be able to use your donation to contribute time to Open WhisperSystems projects, and you can watch the commits +that your donation is paid out on. + +If you'd like to commit code to Free and Open Source privacy software, commits to these repositories are currently paying +loading... from our BitHub instance: + + + +* [Android RedPhone](https://github.com/whispersystems/redphone) +* [Android TextSecure](https://github.com/whispersystems/textsecure) +* [TextSecure Server](https://github.com/whispersystems/TextSecure-Server) +* [iOS TextSecure](https://github.com/whispersystems/TextSecure-iOS) +* [BitHub](https://github.com/whispersystems/bithub) + +## Try It Yourself + +The BitHub project is itself open source and available for [anyone to deploy themselves](https://github.com/WhisperSystems/BitHub). + +It should be extremely easy to configure and deploy, and it even pays out for commits to itself! + +This was inspired by the [tip4commit](http://tip4commit.com) prototype, which we saw last week. We thought the idea was great, +and wanted anyone to be able to host a system like that themselves. diff --git a/blog/images/alpine_action.jpg b/blog/images/alpine_action.jpg new file mode 100644 index 0000000..2833273 Binary files /dev/null and b/blog/images/alpine_action.jpg differ diff --git a/blog/images/alpine_anon.jpg b/blog/images/alpine_anon.jpg new file mode 100644 index 0000000..90528a5 Binary files /dev/null and b/blog/images/alpine_anon.jpg differ diff --git a/blog/images/alpine_rocket.jpg b/blog/images/alpine_rocket.jpg new file mode 100644 index 0000000..64bc857 Binary files /dev/null and b/blog/images/alpine_rocket.jpg differ diff --git a/blog/images/alpine_sign.jpg b/blog/images/alpine_sign.jpg new file mode 100644 index 0000000..3114a54 Binary files /dev/null and b/blog/images/alpine_sign.jpg differ diff --git a/blog/images/andy-sboc.jpg b/blog/images/andy-sboc.jpg new file mode 100644 index 0000000..87a49f8 Binary files /dev/null and b/blog/images/andy-sboc.jpg differ diff --git a/blog/images/awsmap.png b/blog/images/awsmap.png new file mode 100644 index 0000000..c66b598 Binary files /dev/null and b/blog/images/awsmap.png differ diff --git a/blog/images/btc.png b/blog/images/btc.png new file mode 100644 index 0000000..b308767 Binary files /dev/null and b/blog/images/btc.png differ diff --git a/blog/images/calder-sboc.png b/blog/images/calder-sboc.png new file mode 100644 index 0000000..28c8a39 Binary files /dev/null and b/blog/images/calder-sboc.png differ diff --git a/blog/images/call-quality-metrics.png b/blog/images/call-quality-metrics.png new file mode 100644 index 0000000..a3b9dac Binary files /dev/null and b/blog/images/call-quality-metrics.png differ diff --git a/blog/images/christine-sboc.jpg b/blog/images/christine-sboc.jpg new file mode 100644 index 0000000..d103c59 Binary files /dev/null and b/blog/images/christine-sboc.jpg differ diff --git a/blog/images/christine-wboc.jpg b/blog/images/christine-wboc.jpg new file mode 100644 index 0000000..25230ed Binary files /dev/null and b/blog/images/christine-wboc.jpg differ diff --git a/blog/images/client-audio-quality-equation1.png b/blog/images/client-audio-quality-equation1.png new file mode 100644 index 0000000..590fccb Binary files /dev/null and b/blog/images/client-audio-quality-equation1.png differ diff --git a/blog/images/client-audio-quality-equation2.png b/blog/images/client-audio-quality-equation2.png new file mode 100644 index 0000000..f6ce684 Binary files /dev/null and b/blog/images/client-audio-quality-equation2.png differ diff --git a/blog/images/compromise_window.png b/blog/images/compromise_window.png new file mode 100644 index 0000000..1c2d3f8 Binary files /dev/null and b/blog/images/compromise_window.png differ diff --git a/blog/images/cyanogenmod-screenshot.png b/blog/images/cyanogenmod-screenshot.png new file mode 100644 index 0000000..1bf1141 Binary files /dev/null and b/blog/images/cyanogenmod-screenshot.png differ diff --git a/blog/images/eberswalderstrasse-prenzlauerberg-hinterof.jpg b/blog/images/eberswalderstrasse-prenzlauerberg-hinterof.jpg new file mode 100644 index 0000000..fe2ae80 Binary files /dev/null and b/blog/images/eberswalderstrasse-prenzlauerberg-hinterof.jpg differ diff --git a/blog/images/ellie-wboc.jpg b/blog/images/ellie-wboc.jpg new file mode 100644 index 0000000..8177dea Binary files /dev/null and b/blog/images/ellie-wboc.jpg differ diff --git a/blog/images/encrypt-pgp.png b/blog/images/encrypt-pgp.png new file mode 100644 index 0000000..986417f Binary files /dev/null and b/blog/images/encrypt-pgp.png differ diff --git a/blog/images/feet.png b/blog/images/feet.png new file mode 100644 index 0000000..76c4151 Binary files /dev/null and b/blog/images/feet.png differ diff --git a/blog/images/hammockfence.jpg b/blog/images/hammockfence.jpg new file mode 100644 index 0000000..855aedf Binary files /dev/null and b/blog/images/hammockfence.jpg differ diff --git a/blog/images/instantinjury.jpg b/blog/images/instantinjury.jpg new file mode 100644 index 0000000..0670eb4 Binary files /dev/null and b/blog/images/instantinjury.jpg differ diff --git a/blog/images/isis-sboc.jpg b/blog/images/isis-sboc.jpg new file mode 100644 index 0000000..ff15894 Binary files /dev/null and b/blog/images/isis-sboc.jpg differ diff --git a/blog/images/jake-wboc.jpg b/blog/images/jake-wboc.jpg new file mode 100644 index 0000000..0242fb7 Binary files /dev/null and b/blog/images/jake-wboc.jpg differ diff --git a/blog/images/lilia-sboc.jpg b/blog/images/lilia-sboc.jpg new file mode 100644 index 0000000..c268805 Binary files /dev/null and b/blog/images/lilia-sboc.jpg differ diff --git a/blog/images/lilia-wboc.jpg b/blog/images/lilia-wboc.jpg new file mode 100644 index 0000000..a1cdc8b Binary files /dev/null and b/blog/images/lilia-wboc.jpg differ diff --git a/blog/images/loadscreen.png b/blog/images/loadscreen.png new file mode 100644 index 0000000..8cc288f Binary files /dev/null and b/blog/images/loadscreen.png differ diff --git a/blog/images/matt-wboc.jpg b/blog/images/matt-wboc.jpg new file mode 100644 index 0000000..f6811bb Binary files /dev/null and b/blog/images/matt-wboc.jpg differ diff --git a/blog/images/maui.png b/blog/images/maui.png new file mode 100644 index 0000000..47e60f2 Binary files /dev/null and b/blog/images/maui.png differ diff --git a/blog/images/meghana-wboc.jpg b/blog/images/meghana-wboc.jpg new file mode 100644 index 0000000..d379d39 Binary files /dev/null and b/blog/images/meghana-wboc.jpg differ diff --git a/blog/images/meskio-wboc.jpg b/blog/images/meskio-wboc.jpg new file mode 100644 index 0000000..ec9a9aa Binary files /dev/null and b/blog/images/meskio-wboc.jpg differ diff --git a/blog/images/moxie-wboc.jpg b/blog/images/moxie-wboc.jpg new file mode 100644 index 0000000..8e8b04e Binary files /dev/null and b/blog/images/moxie-wboc.jpg differ diff --git a/blog/images/multiconnect.png b/blog/images/multiconnect.png new file mode 100644 index 0000000..91f75f7 Binary files /dev/null and b/blog/images/multiconnect.png differ diff --git a/blog/images/newmessage-scaled.jpg b/blog/images/newmessage-scaled.jpg new file mode 100644 index 0000000..eaf4cff Binary files /dev/null and b/blog/images/newmessage-scaled.jpg differ diff --git a/blog/images/newmessage.jpg b/blog/images/newmessage.jpg new file mode 100644 index 0000000..9b9f1f4 Binary files /dev/null and b/blog/images/newmessage.jpg differ diff --git a/blog/images/otr-current.png b/blog/images/otr-current.png new file mode 100644 index 0000000..415dc4c Binary files /dev/null and b/blog/images/otr-current.png differ diff --git a/blog/images/otr-simplified.png b/blog/images/otr-simplified.png new file mode 100644 index 0000000..2752b56 Binary files /dev/null and b/blog/images/otr-simplified.png differ diff --git a/blog/images/paddlehard.jpg b/blog/images/paddlehard.jpg new file mode 100644 index 0000000..529b9fa Binary files /dev/null and b/blog/images/paddlehard.jpg differ diff --git a/blog/images/redphone-ios-soon.png b/blog/images/redphone-ios-soon.png new file mode 100644 index 0000000..5249705 Binary files /dev/null and b/blog/images/redphone-ios-soon.png differ diff --git a/blog/images/rhodey-sboc.jpg b/blog/images/rhodey-sboc.jpg new file mode 100644 index 0000000..10ba5dd Binary files /dev/null and b/blog/images/rhodey-sboc.jpg differ diff --git a/blog/images/rhodey-wboc.png b/blog/images/rhodey-wboc.png new file mode 100644 index 0000000..fb388c9 Binary files /dev/null and b/blog/images/rhodey-wboc.png differ diff --git a/blog/images/sboc-goodbye.jpg b/blog/images/sboc-goodbye.jpg new file mode 100644 index 0000000..9e8f5dc Binary files /dev/null and b/blog/images/sboc-goodbye.jpg differ diff --git a/blog/images/scimp_ratchet.png b/blog/images/scimp_ratchet.png new file mode 100644 index 0000000..b27c8dc Binary files /dev/null and b/blog/images/scimp_ratchet.png differ diff --git a/blog/images/surfsup.jpg b/blog/images/surfsup.jpg new file mode 100644 index 0000000..a64a567 Binary files /dev/null and b/blog/images/surfsup.jpg differ diff --git a/blog/images/tamarind.jpg b/blog/images/tamarind.jpg new file mode 100644 index 0000000..70854c4 Binary files /dev/null and b/blog/images/tamarind.jpg differ diff --git a/blog/images/threestepratchet.png b/blog/images/threestepratchet.png new file mode 100644 index 0000000..531b471 Binary files /dev/null and b/blog/images/threestepratchet.png differ diff --git a/blog/images/twostep_ratchet.png b/blog/images/twostep_ratchet.png new file mode 100644 index 0000000..475e49d Binary files /dev/null and b/blog/images/twostep_ratchet.png differ diff --git a/blog/images/tyler-goodbye.jpg b/blog/images/tyler-goodbye.jpg new file mode 100644 index 0000000..7fe5912 Binary files /dev/null and b/blog/images/tyler-goodbye.jpg differ diff --git a/blog/images/tyler-sboc.jpg b/blog/images/tyler-sboc.jpg new file mode 100644 index 0000000..9edfa97 Binary files /dev/null and b/blog/images/tyler-sboc.jpg differ diff --git a/blog/images/verificationview.png b/blog/images/verificationview.png new file mode 100644 index 0000000..093a7fd Binary files /dev/null and b/blog/images/verificationview.png differ diff --git a/blog/images/waves.png b/blog/images/waves.png new file mode 100644 index 0000000..ec82aa6 Binary files /dev/null and b/blog/images/waves.png differ diff --git a/blog/index.html b/blog/index.html new file mode 100644 index 0000000..9d4077d --- /dev/null +++ b/blog/index.html @@ -0,0 +1,20 @@ +--- +layout: blog +title: Blog +--- + +{% for post in site.posts %} +

+ {% assign title_parts = post.title | split: ' >> ' %} +

{{ title_parts[1] }}

+

{{ post.date | date_to_string }}

+

+ {% assign parts = post.content | split: 'XXXXX' %} + {{ parts.first }} + {% if parts[1] %} + Read more... + {% endif %} +

+
+{% endfor %} + diff --git a/blog/rss.xml b/blog/rss.xml new file mode 100644 index 0000000..09107b8 --- /dev/null +++ b/blog/rss.xml @@ -0,0 +1,34 @@ +--- +layout: nil +--- + + + + Open Whisper Systems Blog + http://www.whispersystems.org/blog/ + + Open Whisper Systems Blog + en-us + {{ site.time | date: "%a, %d %b %Y %H:%M:%S %z" }} + {{ site.time | date: "%a, %d %b %Y %H:%M:%S %z" }} + + {% for post in site.posts %} + + {% assign title_parts = post.title | split: ' >> ' %} + {{ title_parts[1] }} + http://www.whispersystems.org{{ post.url }} + {{ post.date | date: "%a, %d %b %Y %H:%M:%S %z" }} + moxie@whispersystems.org (Moxie Marlinspike) + http://www.whispersystems.org{{ post.id }} + + {% assign parts = post.content | split: 'XXXXX' %} + {{ parts.first | xml_escape }} + {% if parts[1] %} + Read more... + {% endif %} + + + {% endfor %} + + + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..0c314db --- /dev/null +++ b/docs/index.html @@ -0,0 +1,13 @@ +--- +layout: root +title: Documentation +--- + +
+

Documentation

+ {% for page in site.pages %} + {% if page.doc %} + {{ page.title }} + {% endif %} + {% endfor %} +
diff --git a/docs/textsecure-settings.md b/docs/textsecure-settings.md new file mode 100644 index 0000000..c0e94a9 --- /dev/null +++ b/docs/textsecure-settings.md @@ -0,0 +1,100 @@ +--- +layout: doc +title: TextSecure Settings +doc: true +--- +## Use Settings + +**Use for all SMS** +Use TextSecure for viewing and storing all incoming text messages + +**Use for all MMS** +Use TextSecure for viewing and storing all incoming text messages + +## Delivery Reports + +**SMS delivery reports** +Request a delivery report for each SMS message you send + +**MMS delivery reports** +Request a delivery report for each MMS message you send +This feature is not yet implemented. + +## Storage + +**Delete old messages** +Automatically delete older messages once a conversation thread exceeds the +length specified by **Conversation length limit**. + +**Conversation length limit** + +**Trim all threads now** +Scan through all conversation threads and enforce conversation length limits. + +## Input Settings + +**Enter Sends** +Pressing the enter key will send text messages. + +## Encryption Settings + +**Change Passphrase** +Change my passphrase + +**Complete Key Exchanges** +Automatically complete key exchanges for new sessions or for existing sessions +with the same identity key + +**Include whitespace tag** +Include a whitespace tag at the end of every non-encrypted message + +**Sign Key Exchange** +Sign key exchange messages with identity key. + +**Timeout passphrase** +Forget passphrase from memory after some interval + +**Timeout interval** +The amount of time to wait before forgetting passphrase from memory + +## Identity Key Settings + +**View my identity key** +View my identity key + +**Export my identity key** +Export my identity key + +**Import Contact's Key** +Import an identity key from a contact + +**Manage Identity Keys** +Manage configured identity keys + +## Notification Settings + +**Notifications** +Display message notifications in status bar + +**LED Color** +Change notification LED color + +**LED Blink Pattern** +Change notification LED blink pattern + +**Select Ringtone** + +**Vibrate** +Also vibrate when notified + +## Advanced: MMS Access Point Names + +**Enable Fallback MMSC** +Use MMSC information configured here when system APN Information is +unavailable + +**MMSC URL (Required)** + +**MMS Proxy Host (Optional)** + +**MMS proxy Port (Optional)** diff --git a/fonts/bitter/Bitter OFL SIL Font License 1.1.txt b/fonts/bitter/Bitter OFL SIL Font License 1.1.txt new file mode 100644 index 0000000..3bb8ebd --- /dev/null +++ b/fonts/bitter/Bitter OFL SIL Font License 1.1.txt @@ -0,0 +1,94 @@ +Copyright (c) 2011, Sol Matas (www.huertatipografica.com.ar), +with Reserved Font Name "Bitter" + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/bitter/Bitter-Bold-webfont.eot b/fonts/bitter/Bitter-Bold-webfont.eot new file mode 100644 index 0000000..0deb2ff Binary files /dev/null and b/fonts/bitter/Bitter-Bold-webfont.eot differ diff --git a/fonts/bitter/Bitter-Bold-webfont.svg b/fonts/bitter/Bitter-Bold-webfont.svg new file mode 100644 index 0000000..75e6b5e --- /dev/null +++ b/fonts/bitter/Bitter-Bold-webfont.svg @@ -0,0 +1,147 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2011 Sol Matas wwwhuertatipograficacomar with Reserved Font Name Bitter +Designer : Sol Matas +Foundry : Sol Matas +Foundry URL : wwwhuertatipograficacomar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/bitter/Bitter-Bold-webfont.ttf b/fonts/bitter/Bitter-Bold-webfont.ttf new file mode 100644 index 0000000..d50aa4c Binary files /dev/null and b/fonts/bitter/Bitter-Bold-webfont.ttf differ diff --git a/fonts/bitter/Bitter-Bold-webfont.woff b/fonts/bitter/Bitter-Bold-webfont.woff new file mode 100644 index 0000000..aedfbe5 Binary files /dev/null and b/fonts/bitter/Bitter-Bold-webfont.woff differ diff --git a/fonts/bitter/Bitter-Italic-webfont.eot b/fonts/bitter/Bitter-Italic-webfont.eot new file mode 100644 index 0000000..76ecf10 Binary files /dev/null and b/fonts/bitter/Bitter-Italic-webfont.eot differ diff --git a/fonts/bitter/Bitter-Italic-webfont.svg b/fonts/bitter/Bitter-Italic-webfont.svg new file mode 100644 index 0000000..761595d --- /dev/null +++ b/fonts/bitter/Bitter-Italic-webfont.svg @@ -0,0 +1,147 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2011 Sol Matas wwwhuertatipograficacomar with Reserved Font Name Bitter +Designer : Sol Matas +Foundry : Sol Matas +Foundry URL : wwwhuertatipograficacomar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/bitter/Bitter-Italic-webfont.ttf b/fonts/bitter/Bitter-Italic-webfont.ttf new file mode 100644 index 0000000..2d14af9 Binary files /dev/null and b/fonts/bitter/Bitter-Italic-webfont.ttf differ diff --git a/fonts/bitter/Bitter-Italic-webfont.woff b/fonts/bitter/Bitter-Italic-webfont.woff new file mode 100644 index 0000000..bca54ee Binary files /dev/null and b/fonts/bitter/Bitter-Italic-webfont.woff differ diff --git a/fonts/bitter/Bitter-Regular-webfont.eot b/fonts/bitter/Bitter-Regular-webfont.eot new file mode 100644 index 0000000..e1c33ef Binary files /dev/null and b/fonts/bitter/Bitter-Regular-webfont.eot differ diff --git a/fonts/bitter/Bitter-Regular-webfont.svg b/fonts/bitter/Bitter-Regular-webfont.svg new file mode 100644 index 0000000..02e547c --- /dev/null +++ b/fonts/bitter/Bitter-Regular-webfont.svg @@ -0,0 +1,147 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2011 Sol Matas wwwhuertatipograficacomar with Reserved Font Name Bitter +Designer : Sol Matas +Foundry : Sol Matas +Foundry URL : wwwhuertatipograficacomar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/bitter/Bitter-Regular-webfont.ttf b/fonts/bitter/Bitter-Regular-webfont.ttf new file mode 100644 index 0000000..96f55f3 Binary files /dev/null and b/fonts/bitter/Bitter-Regular-webfont.ttf differ diff --git a/fonts/bitter/Bitter-Regular-webfont.woff b/fonts/bitter/Bitter-Regular-webfont.woff new file mode 100644 index 0000000..3bae981 Binary files /dev/null and b/fonts/bitter/Bitter-Regular-webfont.woff differ diff --git a/fonts/bitter/demo.html b/fonts/bitter/demo.html new file mode 100644 index 0000000..7b30f76 --- /dev/null +++ b/fonts/bitter/demo.html @@ -0,0 +1,43 @@ + + + + + + + Font Face Demo + + + + + +
+

Font-face Demo for the Bitter Font

+ + + +

Bitter Regular - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Bitter Italic - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Bitter Bold - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ +
+ + diff --git a/fonts/bitter/stylesheet.css b/fonts/bitter/stylesheet.css new file mode 100644 index 0000000..7f933bb --- /dev/null +++ b/fonts/bitter/stylesheet.css @@ -0,0 +1,40 @@ +/* Generated by Font Squirrel (http://www.fontsquirrel.com) on December 31, 2012 03:41:16 PM America/New_York */ + + + +@font-face { + font-family: 'BitterRegular'; + src: url('Bitter-Regular-webfont.eot'); + src: url('Bitter-Regular-webfont.eot?#iefix') format('embedded-opentype'), + url('Bitter-Regular-webfont.woff') format('woff'), + url('Bitter-Regular-webfont.ttf') format('truetype'), + url('Bitter-Regular-webfont.svg#BitterRegular') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'BitterItalic'; + src: url('Bitter-Italic-webfont.eot'); + src: url('Bitter-Italic-webfont.eot?#iefix') format('embedded-opentype'), + url('Bitter-Italic-webfont.woff') format('woff'), + url('Bitter-Italic-webfont.ttf') format('truetype'), + url('Bitter-Italic-webfont.svg#BitterItalic') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'BitterBold'; + src: url('Bitter-Bold-webfont.eot'); + src: url('Bitter-Bold-webfont.eot?#iefix') format('embedded-opentype'), + url('Bitter-Bold-webfont.woff') format('woff'), + url('Bitter-Bold-webfont.ttf') format('truetype'), + url('Bitter-Bold-webfont.svg#BitterBold') format('svg'); + font-weight: normal; + font-style: normal; + +} + diff --git a/fonts/opensans/Apache License Version 2.txt b/fonts/opensans/Apache License Version 2.txt new file mode 100644 index 0000000..4df74b8 --- /dev/null +++ b/fonts/opensans/Apache License Version 2.txt @@ -0,0 +1,53 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. \ No newline at end of file diff --git a/fonts/opensans/OpenSans-Bold-webfont.eot b/fonts/opensans/OpenSans-Bold-webfont.eot new file mode 100644 index 0000000..57cbf58 Binary files /dev/null and b/fonts/opensans/OpenSans-Bold-webfont.eot differ diff --git a/fonts/opensans/OpenSans-Bold-webfont.svg b/fonts/opensans/OpenSans-Bold-webfont.svg new file mode 100644 index 0000000..4670a5a --- /dev/null +++ b/fonts/opensans/OpenSans-Bold-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-Bold-webfont.ttf b/fonts/opensans/OpenSans-Bold-webfont.ttf new file mode 100644 index 0000000..665f6cf Binary files /dev/null and b/fonts/opensans/OpenSans-Bold-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-Bold-webfont.woff b/fonts/opensans/OpenSans-Bold-webfont.woff new file mode 100644 index 0000000..2ad42ff Binary files /dev/null and b/fonts/opensans/OpenSans-Bold-webfont.woff differ diff --git a/fonts/opensans/OpenSans-BoldItalic-webfont.eot b/fonts/opensans/OpenSans-BoldItalic-webfont.eot new file mode 100644 index 0000000..3694b36 Binary files /dev/null and b/fonts/opensans/OpenSans-BoldItalic-webfont.eot differ diff --git a/fonts/opensans/OpenSans-BoldItalic-webfont.svg b/fonts/opensans/OpenSans-BoldItalic-webfont.svg new file mode 100644 index 0000000..49edc3b --- /dev/null +++ b/fonts/opensans/OpenSans-BoldItalic-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-BoldItalic-webfont.ttf b/fonts/opensans/OpenSans-BoldItalic-webfont.ttf new file mode 100644 index 0000000..5b65de3 Binary files /dev/null and b/fonts/opensans/OpenSans-BoldItalic-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-BoldItalic-webfont.woff b/fonts/opensans/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 0000000..016ca0a Binary files /dev/null and b/fonts/opensans/OpenSans-BoldItalic-webfont.woff differ diff --git a/fonts/opensans/OpenSans-ExtraBold-webfont.eot b/fonts/opensans/OpenSans-ExtraBold-webfont.eot new file mode 100644 index 0000000..78b28d8 Binary files /dev/null and b/fonts/opensans/OpenSans-ExtraBold-webfont.eot differ diff --git a/fonts/opensans/OpenSans-ExtraBold-webfont.svg b/fonts/opensans/OpenSans-ExtraBold-webfont.svg new file mode 100644 index 0000000..b3c0d0a --- /dev/null +++ b/fonts/opensans/OpenSans-ExtraBold-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 2011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-ExtraBold-webfont.ttf b/fonts/opensans/OpenSans-ExtraBold-webfont.ttf new file mode 100644 index 0000000..fab2415 Binary files /dev/null and b/fonts/opensans/OpenSans-ExtraBold-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-ExtraBold-webfont.woff b/fonts/opensans/OpenSans-ExtraBold-webfont.woff new file mode 100644 index 0000000..f9ce8ff Binary files /dev/null and b/fonts/opensans/OpenSans-ExtraBold-webfont.woff differ diff --git a/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.eot b/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.eot new file mode 100644 index 0000000..d800df5 Binary files /dev/null and b/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.eot differ diff --git a/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.svg b/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.svg new file mode 100644 index 0000000..551161e --- /dev/null +++ b/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.ttf b/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.ttf new file mode 100644 index 0000000..4b2d1ae Binary files /dev/null and b/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.woff b/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.woff new file mode 100644 index 0000000..eb171a2 Binary files /dev/null and b/fonts/opensans/OpenSans-ExtraBoldItalic-webfont.woff differ diff --git a/fonts/opensans/OpenSans-Italic-webfont.eot b/fonts/opensans/OpenSans-Italic-webfont.eot new file mode 100644 index 0000000..0708ffe Binary files /dev/null and b/fonts/opensans/OpenSans-Italic-webfont.eot differ diff --git a/fonts/opensans/OpenSans-Italic-webfont.svg b/fonts/opensans/OpenSans-Italic-webfont.svg new file mode 100644 index 0000000..d42ede8 --- /dev/null +++ b/fonts/opensans/OpenSans-Italic-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-Italic-webfont.ttf b/fonts/opensans/OpenSans-Italic-webfont.ttf new file mode 100644 index 0000000..7b58f0c Binary files /dev/null and b/fonts/opensans/OpenSans-Italic-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-Italic-webfont.woff b/fonts/opensans/OpenSans-Italic-webfont.woff new file mode 100644 index 0000000..862efc5 Binary files /dev/null and b/fonts/opensans/OpenSans-Italic-webfont.woff differ diff --git a/fonts/opensans/OpenSans-Light-webfont.eot b/fonts/opensans/OpenSans-Light-webfont.eot new file mode 100644 index 0000000..5428f04 Binary files /dev/null and b/fonts/opensans/OpenSans-Light-webfont.eot differ diff --git a/fonts/opensans/OpenSans-Light-webfont.svg b/fonts/opensans/OpenSans-Light-webfont.svg new file mode 100644 index 0000000..bb684c7 --- /dev/null +++ b/fonts/opensans/OpenSans-Light-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-Light-webfont.ttf b/fonts/opensans/OpenSans-Light-webfont.ttf new file mode 100644 index 0000000..6bd0fa0 Binary files /dev/null and b/fonts/opensans/OpenSans-Light-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-Light-webfont.woff b/fonts/opensans/OpenSans-Light-webfont.woff new file mode 100644 index 0000000..7899301 Binary files /dev/null and b/fonts/opensans/OpenSans-Light-webfont.woff differ diff --git a/fonts/opensans/OpenSans-LightItalic-webfont.eot b/fonts/opensans/OpenSans-LightItalic-webfont.eot new file mode 100644 index 0000000..efad7fa Binary files /dev/null and b/fonts/opensans/OpenSans-LightItalic-webfont.eot differ diff --git a/fonts/opensans/OpenSans-LightItalic-webfont.svg b/fonts/opensans/OpenSans-LightItalic-webfont.svg new file mode 100644 index 0000000..c1930ef --- /dev/null +++ b/fonts/opensans/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-LightItalic-webfont.ttf b/fonts/opensans/OpenSans-LightItalic-webfont.ttf new file mode 100644 index 0000000..5089fc3 Binary files /dev/null and b/fonts/opensans/OpenSans-LightItalic-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-LightItalic-webfont.woff b/fonts/opensans/OpenSans-LightItalic-webfont.woff new file mode 100644 index 0000000..0e16002 Binary files /dev/null and b/fonts/opensans/OpenSans-LightItalic-webfont.woff differ diff --git a/fonts/opensans/OpenSans-Regular-webfont.eot b/fonts/opensans/OpenSans-Regular-webfont.eot new file mode 100644 index 0000000..6efbe0a Binary files /dev/null and b/fonts/opensans/OpenSans-Regular-webfont.eot differ diff --git a/fonts/opensans/OpenSans-Regular-webfont.svg b/fonts/opensans/OpenSans-Regular-webfont.svg new file mode 100644 index 0000000..731bec0 --- /dev/null +++ b/fonts/opensans/OpenSans-Regular-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-Regular-webfont.ttf b/fonts/opensans/OpenSans-Regular-webfont.ttf new file mode 100644 index 0000000..acd25ff Binary files /dev/null and b/fonts/opensans/OpenSans-Regular-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-Regular-webfont.woff b/fonts/opensans/OpenSans-Regular-webfont.woff new file mode 100644 index 0000000..f4329d9 Binary files /dev/null and b/fonts/opensans/OpenSans-Regular-webfont.woff differ diff --git a/fonts/opensans/OpenSans-Semibold-webfont.eot b/fonts/opensans/OpenSans-Semibold-webfont.eot new file mode 100644 index 0000000..11cb246 Binary files /dev/null and b/fonts/opensans/OpenSans-Semibold-webfont.eot differ diff --git a/fonts/opensans/OpenSans-Semibold-webfont.svg b/fonts/opensans/OpenSans-Semibold-webfont.svg new file mode 100644 index 0000000..2d958e2 --- /dev/null +++ b/fonts/opensans/OpenSans-Semibold-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 2011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-Semibold-webfont.ttf b/fonts/opensans/OpenSans-Semibold-webfont.ttf new file mode 100644 index 0000000..26c7d6e Binary files /dev/null and b/fonts/opensans/OpenSans-Semibold-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-Semibold-webfont.woff b/fonts/opensans/OpenSans-Semibold-webfont.woff new file mode 100644 index 0000000..8e89c1f Binary files /dev/null and b/fonts/opensans/OpenSans-Semibold-webfont.woff differ diff --git a/fonts/opensans/OpenSans-SemiboldItalic-webfont.eot b/fonts/opensans/OpenSans-SemiboldItalic-webfont.eot new file mode 100644 index 0000000..79dcf80 Binary files /dev/null and b/fonts/opensans/OpenSans-SemiboldItalic-webfont.eot differ diff --git a/fonts/opensans/OpenSans-SemiboldItalic-webfont.svg b/fonts/opensans/OpenSans-SemiboldItalic-webfont.svg new file mode 100644 index 0000000..57356bf --- /dev/null +++ b/fonts/opensans/OpenSans-SemiboldItalic-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/opensans/OpenSans-SemiboldItalic-webfont.ttf b/fonts/opensans/OpenSans-SemiboldItalic-webfont.ttf new file mode 100644 index 0000000..fd8459e Binary files /dev/null and b/fonts/opensans/OpenSans-SemiboldItalic-webfont.ttf differ diff --git a/fonts/opensans/OpenSans-SemiboldItalic-webfont.woff b/fonts/opensans/OpenSans-SemiboldItalic-webfont.woff new file mode 100644 index 0000000..aa16663 Binary files /dev/null and b/fonts/opensans/OpenSans-SemiboldItalic-webfont.woff differ diff --git a/fonts/opensans/demo.html b/fonts/opensans/demo.html new file mode 100644 index 0000000..e96b3b1 --- /dev/null +++ b/fonts/opensans/demo.html @@ -0,0 +1,78 @@ + + + + + + + Font Face Demo + + + + + +
+

Font-face Demo for the Open Sans Font

+ + + +

Open Sans Light - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Open Sans Light Italic - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Open Sans Regular - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Open Sans Italic - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Open Sans Semibold - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Open Sans Semibold Italic - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Open Sans Bold - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Open Sans Bold Italic - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Open Sans Extrabold - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + + +

Open Sans Extrabold Italic - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ +
+ + diff --git a/fonts/opensans/open-sans-fontfacekit.zip b/fonts/opensans/open-sans-fontfacekit.zip new file mode 100644 index 0000000..3ddab94 Binary files /dev/null and b/fonts/opensans/open-sans-fontfacekit.zip differ diff --git a/fonts/opensans/stylesheet.css b/fonts/opensans/stylesheet.css new file mode 100644 index 0000000..fad62b4 --- /dev/null +++ b/fonts/opensans/stylesheet.css @@ -0,0 +1,124 @@ +/* Generated by Font Squirrel (http://www.fontsquirrel.com) on October 19, 2011 05:36:08 AM America/New_York */ + + + +@font-face { + font-family: 'OpenSansLight'; + src: url('OpenSans-Light-webfont.eot'); + src: url('OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-Light-webfont.woff') format('woff'), + url('OpenSans-Light-webfont.ttf') format('truetype'), + url('OpenSans-Light-webfont.svg#OpenSansLight') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'OpenSansLightItalic'; + src: url('OpenSans-LightItalic-webfont.eot'); + src: url('OpenSans-LightItalic-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-LightItalic-webfont.woff') format('woff'), + url('OpenSans-LightItalic-webfont.ttf') format('truetype'), + url('OpenSans-LightItalic-webfont.svg#OpenSansLightItalic') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'OpenSansRegular'; + src: url('OpenSans-Regular-webfont.eot'); + src: url('OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-Regular-webfont.woff') format('woff'), + url('OpenSans-Regular-webfont.ttf') format('truetype'), + url('OpenSans-Regular-webfont.svg#OpenSansRegular') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'OpenSansItalic'; + src: url('OpenSans-Italic-webfont.eot'); + src: url('OpenSans-Italic-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-Italic-webfont.woff') format('woff'), + url('OpenSans-Italic-webfont.ttf') format('truetype'), + url('OpenSans-Italic-webfont.svg#OpenSansItalic') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'OpenSansSemibold'; + src: url('OpenSans-Semibold-webfont.eot'); + src: url('OpenSans-Semibold-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-Semibold-webfont.woff') format('woff'), + url('OpenSans-Semibold-webfont.ttf') format('truetype'), + url('OpenSans-Semibold-webfont.svg#OpenSansSemibold') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'OpenSansSemiboldItalic'; + src: url('OpenSans-SemiboldItalic-webfont.eot'); + src: url('OpenSans-SemiboldItalic-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-SemiboldItalic-webfont.woff') format('woff'), + url('OpenSans-SemiboldItalic-webfont.ttf') format('truetype'), + url('OpenSans-SemiboldItalic-webfont.svg#OpenSansSemiboldItalic') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'OpenSansBold'; + src: url('OpenSans-Bold-webfont.eot'); + src: url('OpenSans-Bold-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-Bold-webfont.woff') format('woff'), + url('OpenSans-Bold-webfont.ttf') format('truetype'), + url('OpenSans-Bold-webfont.svg#OpenSansBold') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'OpenSansBoldItalic'; + src: url('OpenSans-BoldItalic-webfont.eot'); + src: url('OpenSans-BoldItalic-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-BoldItalic-webfont.woff') format('woff'), + url('OpenSans-BoldItalic-webfont.ttf') format('truetype'), + url('OpenSans-BoldItalic-webfont.svg#OpenSansBoldItalic') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'OpenSansExtrabold'; + src: url('OpenSans-ExtraBold-webfont.eot'); + src: url('OpenSans-ExtraBold-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-ExtraBold-webfont.woff') format('woff'), + url('OpenSans-ExtraBold-webfont.ttf') format('truetype'), + url('OpenSans-ExtraBold-webfont.svg#OpenSansExtrabold') format('svg'); + font-weight: normal; + font-style: normal; + +} + +@font-face { + font-family: 'OpenSansExtraboldItalic'; + src: url('OpenSans-ExtraBoldItalic-webfont.eot'); + src: url('OpenSans-ExtraBoldItalic-webfont.eot?#iefix') format('embedded-opentype'), + url('OpenSans-ExtraBoldItalic-webfont.woff') format('woff'), + url('OpenSans-ExtraBoldItalic-webfont.ttf') format('truetype'), + url('OpenSans-ExtraBoldItalic-webfont.svg#OpenSansExtraboldItalic') format('svg'); + font-weight: normal; + font-style: normal; + +} + diff --git a/index.html b/index.html new file mode 100644 index 0000000..f7815a0 --- /dev/null +++ b/index.html @@ -0,0 +1,182 @@ +--- +layout: root +title: Open WhisperSystems +header: true +--- + +
+
+
+
+

Need some privacy?

+

+ Secure your communication with our mobile applications. + It's that simple. +

+
+ +
+
+

Encrypted Communication And Storage

+

+ Our projects are focused on creating simple and + easy to use tools for secure mobile communication and secure mobile + storage. +

+
+ +
+

Open Source Software

+

+ The source for all our projects is open, so that + anyone can easily verify they work as advertised. They are licensed + GPLv3 and will always be free. +

+
+ +
+ + Cellphones +
+
+ +
+
+
+

Encrypted calls for Android

+

+ RedPhone provides end-to-end encryption + for your calls, securing your conversations so that nobody can listen + in. +

+
+
+ +
+ +
 
+
+ + + + + +
+ +
+
+
+

Secure texts for Android

+

+ TextSecure encrypts your text messages + over the air and on your phone. It's almost identical to the normal + text messaging application, and is just as easy to use. +

+
+
+ +
+ +
 
+
+ + + + +
+