rails-assets-diaspora-jsxc-0.1.4.alpha.1/0000755000076400007640000000000012572247340017160 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/0000755000076400007640000000000012572247340017740 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/0000755000076400007640000000000012572247340021242 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/stylesheets/0000755000076400007640000000000012572247340023616 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/stylesheets/diaspora_jsxc/0000755000076400007640000000000012572247340026447 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/stylesheets/diaspora_jsxc/jquery.colorbox.scss0000644000076400007640000000616312572247340032517 0ustar pravipravi/* Remove close button from firstrunwizard */ #closeWizard { display: none !important; } /* Colorbox Core Style: The following CSS is consistent between example themes and should not be altered. */ #colorbox,#cboxOverlay,#cboxWrapper { position: absolute; top: 0; left: 0; z-index: 9999; overflow: hidden; } #cboxWrapper { max-width: none; } #cboxOverlay { position: fixed; width: 100%; height: 100%; } #cboxMiddleLeft,#cboxBottomLeft { clear: left; } #cboxContent { position: relative; } #cboxLoadedContent { overflow: auto; -webkit-overflow-scrolling: touch; } #cboxTitle { margin: 0; } #cboxLoadingOverlay,#cboxLoadingGraphic { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } #cboxPrevious,#cboxNext,#cboxClose,#cboxSlideshow { cursor: pointer; } .cboxPhoto { float: left; margin: auto; border: 0; display: block; max-width: none; -ms-interpolation-mode: bicubic; } .cboxIframe { width: 100%; height: 100%; display: block; border: 0; } #colorbox,#cboxContent,#cboxLoadedContent { box-sizing: content-box; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; } /* User Style: Change the following styles to modify the appearance of Colorbox. They are ordered & tabbed in a way that represents the nesting of the generated HTML. */ #cboxOverlay { background: #000; } #colorbox { } #cboxContent { margin-top: 20px; } .cboxIframe { background: #fff; } #cboxError { padding: 50px; border: 0px solid #ccc; } #cboxLoadedContent { border: 0px solid #555; background: #fff; border-radius: 5px; } #cboxTitle { position: absolute; top: -20px; left: 0; color: #ccc; } #cboxCurrent { position: absolute; top: -20px; right: 0px; color: #ccc; } #cboxSlideshow { position: absolute; top: -20px; right: 90px; color: #fff; } #cboxPrevious:hover { background-position: bottom left; } #cboxNext:hover { background-position: bottom right; } #cboxLoadingOverlay { background: #fff; } #cboxClose { position: absolute; top: 5px; right: 5px; display: block; opacity: 0.5; width: 19px !important; height: 19px; border: 0px; text-indent: -9999px; background-color: #fff; } #cboxClose:before { content: '×'; position: absolute; top: 0px; left: 0px; display: block; width: 19px; height: 19px; opacity: 0.5; text-indent: 0; text-align: center; line-height: 19px; font-size: 19px; } #cboxClose:before:hover { opacity: 1; } #cboxClose:hover { background-position: right center !important; opacity: 1.0; } /* The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill when an alpha filter (opacity change) is set on the element or ancestor element. This style is not applied to or needed in IE9. See: http://jacklmoore.com/notes/ie-transparency-problems/ */ .cboxIE #cboxTopLeft,.cboxIE #cboxTopCenter,.cboxIE #cboxTopRight,.cboxIE #cboxBottomLeft,.cboxIE #cboxBottomCenter,.cboxIE #cboxBottomRight,.cboxIE #cboxMiddleLeft,.cboxIE #cboxMiddleRight { filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF, endColorstr=#00FFFFFF); }rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/stylesheets/diaspora_jsxc/jquery-ui.min.scss0000644000076400007640000006206512572247340032071 0ustar pravipravi/*! jQuery UI - v1.10.4 - 2014-01-17 * http://jqueryui.com * Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;min-height:0}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:700;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:0;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:0}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;min-height:0;font-weight:400}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:400;margin:-1px}.ui-menu .ui-state-disabled{font-weight:400;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url(images/animated-overlay.gif);height:100%;filter:alpha(opacity=25);opacity:.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted #000}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:0;background:0;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:0;border-bottom:0;border-right:0}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:0}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:700}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:400;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:400;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:400;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:700}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:400}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/stylesheets/diaspora_jsxc/magnific-popup.scss0000644000076400007640000001715512572247340032273 0ustar pravipravi/* Magnific Popup CSS */ .mfp-bg { top: 0; left: 0; width: 100%; height: 100%; z-index: 1042; overflow: hidden; position: fixed; background: #0b0b0b; opacity: 0.8; filter: alpha(opacity=80); } .mfp-wrap { top: 0; left: 0; width: 100%; height: 100%; z-index: 1043; position: fixed; outline: none !important; -webkit-backface-visibility: hidden; } .mfp-container { text-align: center; position: absolute; width: 100%; height: 100%; left: 0; top: 0; padding: 0 8px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .mfp-container:before { content: ''; display: inline-block; height: 100%; vertical-align: middle; } .mfp-align-top .mfp-container:before { display: none; } .mfp-content { position: relative; display: inline-block; vertical-align: middle; margin: 0 auto; text-align: left; z-index: 1045; } .mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content { width: 100%; cursor: auto; } .mfp-ajax-cur { cursor: progress; } .mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close { cursor: -moz-zoom-out; cursor: -webkit-zoom-out; cursor: zoom-out; } .mfp-zoom { cursor: pointer; cursor: -webkit-zoom-in; cursor: -moz-zoom-in; cursor: zoom-in; } .mfp-auto-cursor .mfp-content { cursor: auto; } .mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter { -webkit-user-select: none; -moz-user-select: none; user-select: none; } .mfp-loading.mfp-figure { display: none; } .mfp-hide { display: none !important; } .mfp-preloader { color: #CCC; position: absolute; top: 50%; width: auto; text-align: center; margin-top: -0.8em; left: 8px; right: 8px; z-index: 1044; } .mfp-preloader a { color: #CCC; } .mfp-preloader a:hover { color: #FFF; } .mfp-s-ready .mfp-preloader { display: none; } .mfp-s-error .mfp-content { display: none; } button.mfp-close, button.mfp-arrow { overflow: visible; cursor: pointer; background: transparent; border: 0; -webkit-appearance: none; display: block; outline: none; padding: 0; z-index: 1046; -webkit-box-shadow: none; box-shadow: none; } button::-moz-focus-inner { padding: 0; border: 0; } .mfp-close { width: 44px; height: 44px; line-height: 44px; position: absolute; right: 0; top: 0; text-decoration: none; text-align: center; opacity: 0.65; filter: alpha(opacity=65); padding: 0 0 18px 10px; color: #FFF; font-style: normal; font-size: 28px; font-family: Arial, Baskerville, monospace; } .mfp-close:hover, .mfp-close:focus { opacity: 1; filter: alpha(opacity=100); } .mfp-close:active { top: 1px; } .mfp-close-btn-in .mfp-close { color: #333; } .mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close { color: #FFF; right: -6px; text-align: right; padding-right: 6px; width: 100%; } .mfp-counter { position: absolute; top: 0; right: 0; color: #CCC; font-size: 12px; line-height: 18px; white-space: nowrap; } .mfp-arrow { position: absolute; opacity: 0.65; filter: alpha(opacity=65); margin: 0; top: 50%; margin-top: -55px; padding: 0; width: 90px; height: 110px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .mfp-arrow:active { margin-top: -54px; } .mfp-arrow:hover, .mfp-arrow:focus { opacity: 1; filter: alpha(opacity=100); } .mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a { content: ''; display: block; width: 0; height: 0; position: absolute; left: 0; top: 0; margin-top: 35px; margin-left: 35px; border: medium inset transparent; } .mfp-arrow:after, .mfp-arrow .mfp-a { border-top-width: 13px; border-bottom-width: 13px; top: 8px; } .mfp-arrow:before, .mfp-arrow .mfp-b { border-top-width: 21px; border-bottom-width: 21px; opacity: 0.7; } .mfp-arrow-left { left: 0; } .mfp-arrow-left:after, .mfp-arrow-left .mfp-a { border-right: 17px solid #FFF; margin-left: 31px; } .mfp-arrow-left:before, .mfp-arrow-left .mfp-b { margin-left: 25px; border-right: 27px solid #3F3F3F; } .mfp-arrow-right { right: 0; } .mfp-arrow-right:after, .mfp-arrow-right .mfp-a { border-left: 17px solid #FFF; margin-left: 39px; } .mfp-arrow-right:before, .mfp-arrow-right .mfp-b { border-left: 27px solid #3F3F3F; } .mfp-iframe-holder { padding-top: 40px; padding-bottom: 40px; } .mfp-iframe-holder .mfp-content { line-height: 0; width: 100%; max-width: 900px; } .mfp-iframe-holder .mfp-close { top: -40px; } .mfp-iframe-scaler { width: 100%; height: 0; overflow: hidden; padding-top: 56.25%; } .mfp-iframe-scaler iframe { position: absolute; display: block; top: 0; left: 0; width: 100%; height: 100%; box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); background: #000; } /* Main image in popup */ img.mfp-img { width: auto; max-width: 100%; height: auto; display: block; line-height: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding: 40px 0 40px; margin: 0 auto; } /* The shadow behind the image */ .mfp-figure { line-height: 0; } .mfp-figure:after { content: ''; position: absolute; left: 0; top: 40px; bottom: 40px; display: block; right: 0; width: auto; height: auto; z-index: -1; box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); background: #444; } .mfp-figure small { color: #BDBDBD; display: block; font-size: 12px; line-height: 14px; } .mfp-figure figure { margin: 0; } .mfp-bottom-bar { margin-top: -36px; position: absolute; top: 100%; left: 0; width: 100%; cursor: auto; } .mfp-title { text-align: left; line-height: 18px; color: #F3F3F3; word-wrap: break-word; padding-right: 36px; } .mfp-image-holder .mfp-content { max-width: 100%; } .mfp-gallery .mfp-image-holder .mfp-figure { cursor: pointer; } @media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { /** * Remove all paddings around the image on small screen */ .mfp-img-mobile .mfp-image-holder { padding-left: 0; padding-right: 0; } .mfp-img-mobile img.mfp-img { padding: 0; } .mfp-img-mobile .mfp-figure:after { top: 0; bottom: 0; } .mfp-img-mobile .mfp-figure small { display: inline; margin-left: 5px; } .mfp-img-mobile .mfp-bottom-bar { background: rgba(0, 0, 0, 0.6); bottom: 0; margin: 0; top: auto; padding: 3px 5px; position: fixed; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .mfp-img-mobile .mfp-bottom-bar:empty { padding: 0; } .mfp-img-mobile .mfp-counter { right: 5px; top: 3px; } .mfp-img-mobile .mfp-close { top: 0; right: 0; width: 35px; height: 35px; line-height: 35px; background: rgba(0, 0, 0, 0.6); position: fixed; text-align: center; padding: 0; } } @media all and (max-width: 900px) { .mfp-arrow { -webkit-transform: scale(0.75); transform: scale(0.75); } .mfp-arrow-left { -webkit-transform-origin: 0; transform-origin: 0; } .mfp-arrow-right { -webkit-transform-origin: 100%; transform-origin: 100%; } .mfp-container { padding-left: 6px; padding-right: 6px; } } .mfp-ie7 .mfp-img { padding: 0; } .mfp-ie7 .mfp-bottom-bar { width: 600px; left: 50%; margin-left: -300px; margin-top: 5px; padding-bottom: 5px; } .mfp-ie7 .mfp-container { padding: 0; } .mfp-ie7 .mfp-content { padding-top: 44px; } .mfp-ie7 .mfp-close { top: 0; right: 0; padding-top: 0; } rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/stylesheets/diaspora_jsxc/jsxc.scss0000644000076400007640000101163712572247340030324 0ustar pravipravi/* basic scrollbar styling */ /* vertical scrollbar */ .mCSB_container { width: auto; margin-right: 30px; overflow: hidden; } .mCSB_container.mCS_no_scrollbar { margin-right: 0; } .mCS_disabled .mCSB_container.mCS_no_scrollbar, .mCS_destroyed .mCSB_container.mCS_no_scrollbar { margin-right: 30px; } .mCustomScrollBox .mCSB_scrollTools { width: 16px; height: 100%; top: 0; right: 0; } .mCSB_scrollTools .mCSB_draggerContainer { height: 100%; box-sizing: border-box; } .mCSB_scrollTools .mCSB_buttonUp + .mCSB_draggerContainer { padding-bottom: 40px; } .mCSB_scrollTools .mCSB_draggerRail { width: 2px; height: 100%; margin: 0 auto; border-radius: 10px; } .mCSB_scrollTools .mCSB_dragger { cursor: pointer; width: 100%; height: 30px; } .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { width: 4px; height: 100%; margin: 0 auto; border-radius: 10px; text-align: center; } .mCSB_scrollTools .mCSB_buttonUp, .mCSB_scrollTools .mCSB_buttonDown { height: 20px; overflow: hidden; margin: 0 auto; cursor: pointer; } .mCSB_scrollTools .mCSB_buttonDown { bottom: 0; margin-top: -40px; } /* horizontal scrollbar */ .mCSB_horizontal .mCSB_container { height: auto; margin-right: 0; margin-bottom: 30px; overflow: hidden; } .mCSB_horizontal .mCSB_container.mCS_no_scrollbar { margin-bottom: 0; } .mCS_disabled .mCSB_horizontal .mCSB_container.mCS_no_scrollbar, .mCS_destroyed .mCSB_horizontal .mCSB_container.mCS_no_scrollbar { margin-right: 0; margin-bottom: 30px; } .mCSB_horizontal.mCustomScrollBox .mCSB_scrollTools { width: 100%; height: 16px; top: auto; right: auto; bottom: 0; left: 0; overflow: hidden; } .mCSB_horizontal .mCSB_scrollTools .mCSB_draggerContainer { height: 100%; width: auto; box-sizing: border-box; overflow: hidden; } .mCSB_horizontal .mCSB_scrollTools .mCSB_buttonLeft + .mCSB_draggerContainer { padding-bottom: 0; padding-right: 20px; } .mCSB_horizontal .mCSB_scrollTools .mCSB_draggerRail { width: 100%; height: 2px; margin: 7px 0; border-radius: 10px; } .mCSB_horizontal .mCSB_scrollTools .mCSB_dragger { width: 30px; height: 100%; } .mCSB_horizontal .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { width: 100%; height: 4px; margin: 6px auto; border-radius: 10px; } .mCSB_horizontal .mCSB_scrollTools .mCSB_buttonLeft, .mCSB_horizontal .mCSB_scrollTools .mCSB_buttonRight { width: 20px; height: 100%; overflow: hidden; margin: 0 auto; cursor: pointer; float: left; } .mCSB_horizontal .mCSB_scrollTools .mCSB_buttonRight { right: 0; bottom: auto; margin-left: -40px; margin-top: -16px; float: right; } /* default scrollbar colors and backgrounds */ .mCustomScrollBox .mCSB_scrollTools { opacity: 0.75; } .mCustomScrollBox:hover .mCSB_scrollTools { opacity: 1; } .mCSB_scrollTools .mCSB_draggerRail { background: #000; /* rgba fallback */ background: rgba(0, 0, 0, 0.4); filter: "alpha(opacity=40)"; -ms-filter: "alpha(opacity=40)"; /* old ie */ } .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { background: #fff; /* rgba fallback */ background: rgba(255, 255, 255, 0.75); filter: "alpha(opacity=75)"; -ms-filter: "alpha(opacity=75)"; /* old ie */ } .mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { background: rgba(255, 255, 255, 0.85); filter: "alpha(opacity=85)"; -ms-filter: "alpha(opacity=85)"; /* old ie */ } .mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, .mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { background: rgba(255, 255, 255, 0.9); filter: "alpha(opacity=90)"; -ms-filter: "alpha(opacity=90)"; /* old ie */ } .mCSB_scrollTools .mCSB_buttonUp, .mCSB_scrollTools .mCSB_buttonDown, .mCSB_scrollTools .mCSB_buttonLeft, .mCSB_scrollTools .mCSB_buttonRight { background-image: url(mCSB_buttons.png); background-repeat: no-repeat; opacity: 0.4; filter: "alpha(opacity=40)"; -ms-filter: "alpha(opacity=40)"; /* old ie */ } .mCSB_scrollTools .mCSB_buttonUp { background-position: 0 0; /* sprites locations are 0 0/-16px 0/-32px 0/-48px 0 (light) and -80px 0/-96px 0/-112px 0/-128px 0 (dark) */ } .mCSB_scrollTools .mCSB_buttonDown { background-position: 0 -20px; /* sprites locations are 0 -20px/-16px -20px/-32px -20px/-48px -20px (light) and -80px -20px/-96px -20px/-112px -20px/-128px -20px (dark) */ } .mCSB_scrollTools .mCSB_buttonLeft { background-position: 0 -40px; /* sprites locations are 0 -40px/-20px -40px/-40px -40px/-60px -40px (light) and -80px -40px/-100px -40px/-120px -40px/-140px -40px (dark) */ } .mCSB_scrollTools .mCSB_buttonRight { background-position: 0 -56px; /* sprites locations are 0 -56px/-20px -56px/-40px -56px/-60px -56px (light) and -80px -56px/-100px -56px/-120px -56px/-140px -56px (dark) */ } .mCSB_scrollTools .mCSB_buttonUp:hover, .mCSB_scrollTools .mCSB_buttonDown:hover, .mCSB_scrollTools .mCSB_buttonLeft:hover, .mCSB_scrollTools .mCSB_buttonRight:hover { opacity: 0.75; filter: "alpha(opacity=75)"; -ms-filter: "alpha(opacity=75)"; /* old ie */ } .mCSB_scrollTools .mCSB_buttonUp:active, .mCSB_scrollTools .mCSB_buttonDown:active, .mCSB_scrollTools .mCSB_buttonLeft:active, .mCSB_scrollTools .mCSB_buttonRight:active { opacity: 0.9; filter: "alpha(opacity=90)"; -ms-filter: "alpha(opacity=90)"; /* old ie */ } /* Magnific Popup CSS */ .mfp-bg { top: 0; left: 0; width: 100%; height: 100%; z-index: 1042; overflow: hidden; position: fixed; background: #0b0b0b; opacity: 0.8; filter: alpha(opacity=80); } .mfp-wrap { top: 0; left: 0; width: 100%; height: 100%; z-index: 1043; position: fixed; outline: none !important; -webkit-backface-visibility: hidden; } .mfp-container { text-align: center; position: absolute; width: 100%; height: 100%; left: 0; top: 0; padding: 0 8px; box-sizing: border-box; } .mfp-container:before { content: ''; display: inline-block; height: 100%; vertical-align: middle; } .mfp-align-top .mfp-container:before { display: none; } .mfp-content { position: relative; display: inline-block; vertical-align: middle; margin: 0 auto; text-align: left; z-index: 1045; } .mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content { width: 100%; cursor: auto; } .mfp-ajax-cur { cursor: progress; } .mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close { cursor: -webkit-zoom-out; cursor: zoom-out; } .mfp-zoom { cursor: pointer; cursor: -webkit-zoom-in; cursor: zoom-in; } .mfp-auto-cursor .mfp-content { cursor: auto; } .mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .mfp-loading.mfp-figure { display: none; } .mfp-hide { display: none !important; } .mfp-preloader { color: #CCC; position: absolute; top: 50%; width: auto; text-align: center; margin-top: -0.8em; left: 8px; right: 8px; z-index: 1044; } .mfp-preloader a { color: #CCC; } .mfp-preloader a:hover { color: #FFF; } .mfp-s-ready .mfp-preloader { display: none; } .mfp-s-error .mfp-content { display: none; } button.mfp-close, button.mfp-arrow { overflow: visible; cursor: pointer; background: transparent; border: 0; -webkit-appearance: none; display: block; outline: none; padding: 0; z-index: 1046; box-shadow: none; } button::-moz-focus-inner { padding: 0; border: 0; } .mfp-close { width: 44px; height: 44px; line-height: 44px; position: absolute; right: 0; top: 0; text-decoration: none; text-align: center; opacity: 0.65; filter: alpha(opacity=65); padding: 0 0 18px 10px; color: #FFF; font-style: normal; font-size: 28px; font-family: Arial, Baskerville, monospace; } .mfp-close:hover, .mfp-close:focus { opacity: 1; filter: alpha(opacity=100); } .mfp-close:active { top: 1px; } .mfp-close-btn-in .mfp-close { color: #333; } .mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close { color: #FFF; right: -6px; text-align: right; padding-right: 6px; width: 100%; } .mfp-counter { position: absolute; top: 0; right: 0; color: #CCC; font-size: 12px; line-height: 18px; white-space: nowrap; } .mfp-arrow { position: absolute; opacity: 0.65; filter: alpha(opacity=65); margin: 0; top: 50%; margin-top: -55px; padding: 0; width: 90px; height: 110px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .mfp-arrow:active { margin-top: -54px; } .mfp-arrow:hover, .mfp-arrow:focus { opacity: 1; filter: alpha(opacity=100); } .mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a { content: ''; display: block; width: 0; height: 0; position: absolute; left: 0; top: 0; margin-top: 35px; margin-left: 35px; border: medium inset transparent; } .mfp-arrow:after, .mfp-arrow .mfp-a { border-top-width: 13px; border-bottom-width: 13px; top: 8px; } .mfp-arrow:before, .mfp-arrow .mfp-b { border-top-width: 21px; border-bottom-width: 21px; opacity: 0.7; } .mfp-arrow-left { left: 0; } .mfp-arrow-left:after, .mfp-arrow-left .mfp-a { border-right: 17px solid #FFF; margin-left: 31px; } .mfp-arrow-left:before, .mfp-arrow-left .mfp-b { margin-left: 25px; border-right: 27px solid #3F3F3F; } .mfp-arrow-right { right: 0; } .mfp-arrow-right:after, .mfp-arrow-right .mfp-a { border-left: 17px solid #FFF; margin-left: 39px; } .mfp-arrow-right:before, .mfp-arrow-right .mfp-b { border-left: 27px solid #3F3F3F; } .mfp-iframe-holder { padding-top: 40px; padding-bottom: 40px; } .mfp-iframe-holder .mfp-content { line-height: 0; width: 100%; max-width: 900px; } .mfp-iframe-holder .mfp-close { top: -40px; } .mfp-iframe-scaler { width: 100%; height: 0; overflow: hidden; padding-top: 56.25%; } .mfp-iframe-scaler iframe { position: absolute; display: block; top: 0; left: 0; width: 100%; height: 100%; box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); background: #000; } /* Main image in popup */ img.mfp-img { width: auto; max-width: 100%; height: auto; display: block; line-height: 0; box-sizing: border-box; padding: 40px 0 40px; margin: 0 auto; } /* The shadow behind the image */ .mfp-figure { line-height: 0; } .mfp-figure:after { content: ''; position: absolute; left: 0; top: 40px; bottom: 40px; display: block; right: 0; width: auto; height: auto; z-index: -1; box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); background: #444; } .mfp-figure small { color: #BDBDBD; display: block; font-size: 12px; line-height: 14px; } .mfp-figure figure { margin: 0; } .mfp-bottom-bar { margin-top: -36px; position: absolute; top: 100%; left: 0; width: 100%; cursor: auto; } .mfp-title { text-align: left; line-height: 18px; color: #F3F3F3; word-wrap: break-word; padding-right: 36px; } .mfp-image-holder .mfp-content { max-width: 100%; } .mfp-gallery .mfp-image-holder .mfp-figure { cursor: pointer; } @media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { /** * Remove all paddings around the image on small screen */ .mfp-img-mobile .mfp-image-holder { padding-left: 0; padding-right: 0; } .mfp-img-mobile img.mfp-img { padding: 0; } .mfp-img-mobile .mfp-figure:after { top: 0; bottom: 0; } .mfp-img-mobile .mfp-figure small { display: inline; margin-left: 5px; } .mfp-img-mobile .mfp-bottom-bar { background: rgba(0, 0, 0, 0.6); bottom: 0; margin: 0; top: auto; padding: 3px 5px; position: fixed; box-sizing: border-box; } .mfp-img-mobile .mfp-bottom-bar:empty { padding: 0; } .mfp-img-mobile .mfp-counter { right: 5px; top: 3px; } .mfp-img-mobile .mfp-close { top: 0; right: 0; width: 35px; height: 35px; line-height: 35px; background: rgba(0, 0, 0, 0.6); position: fixed; text-align: center; padding: 0; } } @media all and (max-width: 900px) { .mfp-arrow { -webkit-transform: scale(0.75); -ms-transform: scale(0.75); transform: scale(0.75); } .mfp-arrow-left { -webkit-transform-origin: 0; -ms-transform-origin: 0; transform-origin: 0; } .mfp-arrow-right { -webkit-transform-origin: 100%; -ms-transform-origin: 100%; transform-origin: 100%; } .mfp-container { padding-left: 6px; padding-right: 6px; } } .mfp-ie7 .mfp-img { padding: 0; } .mfp-ie7 .mfp-bottom-bar { width: 600px; left: 50%; margin-left: -300px; margin-top: 5px; padding-bottom: 5px; } .mfp-ie7 .mfp-container { padding: 0; } .mfp-ie7 .mfp-content { padding-top: 44px; } .mfp-ie7 .mfp-close { top: 0; right: 0; padding-top: 0; } /* BEGIN: bootstrap */ @-webkit-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } #jsxc_dialog { @-webkit-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } } #jsxc_dialog .clearfix:before, #jsxc_dialog .clearfix:after { content: " "; display: table; } #jsxc_dialog .clearfix:after { clear: both; } #jsxc_dialog .center-block { display: block; margin-left: auto; margin-right: auto; } #jsxc_dialog .pull-right { float: right !important; } #jsxc_dialog .pull-left { float: left !important; } #jsxc_dialog .hide { display: none !important; } #jsxc_dialog .show { display: block !important; } #jsxc_dialog .invisible { visibility: hidden; } #jsxc_dialog .text-hide { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0; } #jsxc_dialog .hidden { display: none !important; } #jsxc_dialog .affix { position: fixed; } #jsxc_dialog code, #jsxc_dialog kbd, #jsxc_dialog pre, #jsxc_dialog samp { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } #jsxc_dialog code { padding: 2px 4px; font-size: 90%; color: #c7254e; background-color: #f9f2f4; border-radius: 4px; } #jsxc_dialog kbd { padding: 2px 4px; font-size: 90%; color: #fff; background-color: #333; border-radius: 3px; box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); } #jsxc_dialog kbd kbd { padding: 0; font-size: 100%; font-weight: bold; box-shadow: none; } #jsxc_dialog pre { display: block; padding: 9.5px; margin: 0 0 10px; font-size: 13px; line-height: 1.428571429; word-break: break-all; word-wrap: break-word; color: #333333; background-color: #f5f5f5; border: 1px solid #ccc; border-radius: 4px; } #jsxc_dialog pre code { padding: 0; font-size: inherit; color: inherit; white-space: pre-wrap; background-color: transparent; border-radius: 0; } #jsxc_dialog .pre-scrollable { max-height: 340px; overflow-y: scroll; } #jsxc_dialog .container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px; } #jsxc_dialog .container:before, #jsxc_dialog .container:after { content: " "; display: table; } #jsxc_dialog .container:after { clear: both; } @media (min-width: 768px) { #jsxc_dialog .container { width: 750px; } } @media (min-width: 992px) { #jsxc_dialog .container { width: 970px; } } @media (min-width: 1200px) { #jsxc_dialog .container { width: 1170px; } } #jsxc_dialog .container-fluid { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px; } #jsxc_dialog .container-fluid:before, #jsxc_dialog .container-fluid:after { content: " "; display: table; } #jsxc_dialog .container-fluid:after { clear: both; } #jsxc_dialog .row { margin-left: -15px; margin-right: -15px; } #jsxc_dialog .row:before, #jsxc_dialog .row:after { content: " "; display: table; } #jsxc_dialog .row:after { clear: both; } #jsxc_dialog .col-xs-1, #jsxc_dialog .col-sm-1, #jsxc_dialog .col-md-1, #jsxc_dialog .col-lg-1, #jsxc_dialog .col-xs-2, #jsxc_dialog .col-sm-2, #jsxc_dialog .col-md-2, #jsxc_dialog .col-lg-2, #jsxc_dialog .col-xs-3, #jsxc_dialog .col-sm-3, #jsxc_dialog .col-md-3, #jsxc_dialog .col-lg-3, #jsxc_dialog .col-xs-4, #jsxc_dialog .col-sm-4, #jsxc_dialog .col-md-4, #jsxc_dialog .col-lg-4, #jsxc_dialog .col-xs-5, #jsxc_dialog .col-sm-5, #jsxc_dialog .col-md-5, #jsxc_dialog .col-lg-5, #jsxc_dialog .col-xs-6, #jsxc_dialog .col-sm-6, #jsxc_dialog .col-md-6, #jsxc_dialog .col-lg-6, #jsxc_dialog .col-xs-7, #jsxc_dialog .col-sm-7, #jsxc_dialog .col-md-7, #jsxc_dialog .col-lg-7, #jsxc_dialog .col-xs-8, #jsxc_dialog .col-sm-8, #jsxc_dialog .col-md-8, #jsxc_dialog .col-lg-8, #jsxc_dialog .col-xs-9, #jsxc_dialog .col-sm-9, #jsxc_dialog .col-md-9, #jsxc_dialog .col-lg-9, #jsxc_dialog .col-xs-10, #jsxc_dialog .col-sm-10, #jsxc_dialog .col-md-10, #jsxc_dialog .col-lg-10, #jsxc_dialog .col-xs-11, #jsxc_dialog .col-sm-11, #jsxc_dialog .col-md-11, #jsxc_dialog .col-lg-11, #jsxc_dialog .col-xs-12, #jsxc_dialog .col-sm-12, #jsxc_dialog .col-md-12, #jsxc_dialog .col-lg-12 { position: relative; min-height: 1px; padding-left: 15px; padding-right: 15px; } #jsxc_dialog .col-xs-1, #jsxc_dialog .col-xs-2, #jsxc_dialog .col-xs-3, #jsxc_dialog .col-xs-4, #jsxc_dialog .col-xs-5, #jsxc_dialog .col-xs-6, #jsxc_dialog .col-xs-7, #jsxc_dialog .col-xs-8, #jsxc_dialog .col-xs-9, #jsxc_dialog .col-xs-10, #jsxc_dialog .col-xs-11, #jsxc_dialog .col-xs-12 { float: left; } #jsxc_dialog .col-xs-1 { width: 8.3333333333%; } #jsxc_dialog .col-xs-2 { width: 16.6666666667%; } #jsxc_dialog .col-xs-3 { width: 25%; } #jsxc_dialog .col-xs-4 { width: 33.3333333333%; } #jsxc_dialog .col-xs-5 { width: 41.6666666667%; } #jsxc_dialog .col-xs-6 { width: 50%; } #jsxc_dialog .col-xs-7 { width: 58.3333333333%; } #jsxc_dialog .col-xs-8 { width: 66.6666666667%; } #jsxc_dialog .col-xs-9 { width: 75%; } #jsxc_dialog .col-xs-10 { width: 83.3333333333%; } #jsxc_dialog .col-xs-11 { width: 91.6666666667%; } #jsxc_dialog .col-xs-12 { width: 100%; } #jsxc_dialog .col-xs-pull-0 { right: auto; } #jsxc_dialog .col-xs-pull-1 { right: 8.3333333333%; } #jsxc_dialog .col-xs-pull-2 { right: 16.6666666667%; } #jsxc_dialog .col-xs-pull-3 { right: 25%; } #jsxc_dialog .col-xs-pull-4 { right: 33.3333333333%; } #jsxc_dialog .col-xs-pull-5 { right: 41.6666666667%; } #jsxc_dialog .col-xs-pull-6 { right: 50%; } #jsxc_dialog .col-xs-pull-7 { right: 58.3333333333%; } #jsxc_dialog .col-xs-pull-8 { right: 66.6666666667%; } #jsxc_dialog .col-xs-pull-9 { right: 75%; } #jsxc_dialog .col-xs-pull-10 { right: 83.3333333333%; } #jsxc_dialog .col-xs-pull-11 { right: 91.6666666667%; } #jsxc_dialog .col-xs-pull-12 { right: 100%; } #jsxc_dialog .col-xs-push-0 { left: auto; } #jsxc_dialog .col-xs-push-1 { left: 8.3333333333%; } #jsxc_dialog .col-xs-push-2 { left: 16.6666666667%; } #jsxc_dialog .col-xs-push-3 { left: 25%; } #jsxc_dialog .col-xs-push-4 { left: 33.3333333333%; } #jsxc_dialog .col-xs-push-5 { left: 41.6666666667%; } #jsxc_dialog .col-xs-push-6 { left: 50%; } #jsxc_dialog .col-xs-push-7 { left: 58.3333333333%; } #jsxc_dialog .col-xs-push-8 { left: 66.6666666667%; } #jsxc_dialog .col-xs-push-9 { left: 75%; } #jsxc_dialog .col-xs-push-10 { left: 83.3333333333%; } #jsxc_dialog .col-xs-push-11 { left: 91.6666666667%; } #jsxc_dialog .col-xs-push-12 { left: 100%; } #jsxc_dialog .col-xs-offset-0 { margin-left: 0%; } #jsxc_dialog .col-xs-offset-1 { margin-left: 8.3333333333%; } #jsxc_dialog .col-xs-offset-2 { margin-left: 16.6666666667%; } #jsxc_dialog .col-xs-offset-3 { margin-left: 25%; } #jsxc_dialog .col-xs-offset-4 { margin-left: 33.3333333333%; } #jsxc_dialog .col-xs-offset-5 { margin-left: 41.6666666667%; } #jsxc_dialog .col-xs-offset-6 { margin-left: 50%; } #jsxc_dialog .col-xs-offset-7 { margin-left: 58.3333333333%; } #jsxc_dialog .col-xs-offset-8 { margin-left: 66.6666666667%; } #jsxc_dialog .col-xs-offset-9 { margin-left: 75%; } #jsxc_dialog .col-xs-offset-10 { margin-left: 83.3333333333%; } #jsxc_dialog .col-xs-offset-11 { margin-left: 91.6666666667%; } #jsxc_dialog .col-xs-offset-12 { margin-left: 100%; } @media (min-width: 768px) { #jsxc_dialog .col-sm-1, #jsxc_dialog .col-sm-2, #jsxc_dialog .col-sm-3, #jsxc_dialog .col-sm-4, #jsxc_dialog .col-sm-5, #jsxc_dialog .col-sm-6, #jsxc_dialog .col-sm-7, #jsxc_dialog .col-sm-8, #jsxc_dialog .col-sm-9, #jsxc_dialog .col-sm-10, #jsxc_dialog .col-sm-11, #jsxc_dialog .col-sm-12 { float: left; } #jsxc_dialog .col-sm-1 { width: 8.3333333333%; } #jsxc_dialog .col-sm-2 { width: 16.6666666667%; } #jsxc_dialog .col-sm-3 { width: 25%; } #jsxc_dialog .col-sm-4 { width: 33.3333333333%; } #jsxc_dialog .col-sm-5 { width: 41.6666666667%; } #jsxc_dialog .col-sm-6 { width: 50%; } #jsxc_dialog .col-sm-7 { width: 58.3333333333%; } #jsxc_dialog .col-sm-8 { width: 66.6666666667%; } #jsxc_dialog .col-sm-9 { width: 75%; } #jsxc_dialog .col-sm-10 { width: 83.3333333333%; } #jsxc_dialog .col-sm-11 { width: 91.6666666667%; } #jsxc_dialog .col-sm-12 { width: 100%; } #jsxc_dialog .col-sm-pull-0 { right: auto; } #jsxc_dialog .col-sm-pull-1 { right: 8.3333333333%; } #jsxc_dialog .col-sm-pull-2 { right: 16.6666666667%; } #jsxc_dialog .col-sm-pull-3 { right: 25%; } #jsxc_dialog .col-sm-pull-4 { right: 33.3333333333%; } #jsxc_dialog .col-sm-pull-5 { right: 41.6666666667%; } #jsxc_dialog .col-sm-pull-6 { right: 50%; } #jsxc_dialog .col-sm-pull-7 { right: 58.3333333333%; } #jsxc_dialog .col-sm-pull-8 { right: 66.6666666667%; } #jsxc_dialog .col-sm-pull-9 { right: 75%; } #jsxc_dialog .col-sm-pull-10 { right: 83.3333333333%; } #jsxc_dialog .col-sm-pull-11 { right: 91.6666666667%; } #jsxc_dialog .col-sm-pull-12 { right: 100%; } #jsxc_dialog .col-sm-push-0 { left: auto; } #jsxc_dialog .col-sm-push-1 { left: 8.3333333333%; } #jsxc_dialog .col-sm-push-2 { left: 16.6666666667%; } #jsxc_dialog .col-sm-push-3 { left: 25%; } #jsxc_dialog .col-sm-push-4 { left: 33.3333333333%; } #jsxc_dialog .col-sm-push-5 { left: 41.6666666667%; } #jsxc_dialog .col-sm-push-6 { left: 50%; } #jsxc_dialog .col-sm-push-7 { left: 58.3333333333%; } #jsxc_dialog .col-sm-push-8 { left: 66.6666666667%; } #jsxc_dialog .col-sm-push-9 { left: 75%; } #jsxc_dialog .col-sm-push-10 { left: 83.3333333333%; } #jsxc_dialog .col-sm-push-11 { left: 91.6666666667%; } #jsxc_dialog .col-sm-push-12 { left: 100%; } #jsxc_dialog .col-sm-offset-0 { margin-left: 0%; } #jsxc_dialog .col-sm-offset-1 { margin-left: 8.3333333333%; } #jsxc_dialog .col-sm-offset-2 { margin-left: 16.6666666667%; } #jsxc_dialog .col-sm-offset-3 { margin-left: 25%; } #jsxc_dialog .col-sm-offset-4 { margin-left: 33.3333333333%; } #jsxc_dialog .col-sm-offset-5 { margin-left: 41.6666666667%; } #jsxc_dialog .col-sm-offset-6 { margin-left: 50%; } #jsxc_dialog .col-sm-offset-7 { margin-left: 58.3333333333%; } #jsxc_dialog .col-sm-offset-8 { margin-left: 66.6666666667%; } #jsxc_dialog .col-sm-offset-9 { margin-left: 75%; } #jsxc_dialog .col-sm-offset-10 { margin-left: 83.3333333333%; } #jsxc_dialog .col-sm-offset-11 { margin-left: 91.6666666667%; } #jsxc_dialog .col-sm-offset-12 { margin-left: 100%; } } @media (min-width: 992px) { #jsxc_dialog .col-md-1, #jsxc_dialog .col-md-2, #jsxc_dialog .col-md-3, #jsxc_dialog .col-md-4, #jsxc_dialog .col-md-5, #jsxc_dialog .col-md-6, #jsxc_dialog .col-md-7, #jsxc_dialog .col-md-8, #jsxc_dialog .col-md-9, #jsxc_dialog .col-md-10, #jsxc_dialog .col-md-11, #jsxc_dialog .col-md-12 { float: left; } #jsxc_dialog .col-md-1 { width: 8.3333333333%; } #jsxc_dialog .col-md-2 { width: 16.6666666667%; } #jsxc_dialog .col-md-3 { width: 25%; } #jsxc_dialog .col-md-4 { width: 33.3333333333%; } #jsxc_dialog .col-md-5 { width: 41.6666666667%; } #jsxc_dialog .col-md-6 { width: 50%; } #jsxc_dialog .col-md-7 { width: 58.3333333333%; } #jsxc_dialog .col-md-8 { width: 66.6666666667%; } #jsxc_dialog .col-md-9 { width: 75%; } #jsxc_dialog .col-md-10 { width: 83.3333333333%; } #jsxc_dialog .col-md-11 { width: 91.6666666667%; } #jsxc_dialog .col-md-12 { width: 100%; } #jsxc_dialog .col-md-pull-0 { right: auto; } #jsxc_dialog .col-md-pull-1 { right: 8.3333333333%; } #jsxc_dialog .col-md-pull-2 { right: 16.6666666667%; } #jsxc_dialog .col-md-pull-3 { right: 25%; } #jsxc_dialog .col-md-pull-4 { right: 33.3333333333%; } #jsxc_dialog .col-md-pull-5 { right: 41.6666666667%; } #jsxc_dialog .col-md-pull-6 { right: 50%; } #jsxc_dialog .col-md-pull-7 { right: 58.3333333333%; } #jsxc_dialog .col-md-pull-8 { right: 66.6666666667%; } #jsxc_dialog .col-md-pull-9 { right: 75%; } #jsxc_dialog .col-md-pull-10 { right: 83.3333333333%; } #jsxc_dialog .col-md-pull-11 { right: 91.6666666667%; } #jsxc_dialog .col-md-pull-12 { right: 100%; } #jsxc_dialog .col-md-push-0 { left: auto; } #jsxc_dialog .col-md-push-1 { left: 8.3333333333%; } #jsxc_dialog .col-md-push-2 { left: 16.6666666667%; } #jsxc_dialog .col-md-push-3 { left: 25%; } #jsxc_dialog .col-md-push-4 { left: 33.3333333333%; } #jsxc_dialog .col-md-push-5 { left: 41.6666666667%; } #jsxc_dialog .col-md-push-6 { left: 50%; } #jsxc_dialog .col-md-push-7 { left: 58.3333333333%; } #jsxc_dialog .col-md-push-8 { left: 66.6666666667%; } #jsxc_dialog .col-md-push-9 { left: 75%; } #jsxc_dialog .col-md-push-10 { left: 83.3333333333%; } #jsxc_dialog .col-md-push-11 { left: 91.6666666667%; } #jsxc_dialog .col-md-push-12 { left: 100%; } #jsxc_dialog .col-md-offset-0 { margin-left: 0%; } #jsxc_dialog .col-md-offset-1 { margin-left: 8.3333333333%; } #jsxc_dialog .col-md-offset-2 { margin-left: 16.6666666667%; } #jsxc_dialog .col-md-offset-3 { margin-left: 25%; } #jsxc_dialog .col-md-offset-4 { margin-left: 33.3333333333%; } #jsxc_dialog .col-md-offset-5 { margin-left: 41.6666666667%; } #jsxc_dialog .col-md-offset-6 { margin-left: 50%; } #jsxc_dialog .col-md-offset-7 { margin-left: 58.3333333333%; } #jsxc_dialog .col-md-offset-8 { margin-left: 66.6666666667%; } #jsxc_dialog .col-md-offset-9 { margin-left: 75%; } #jsxc_dialog .col-md-offset-10 { margin-left: 83.3333333333%; } #jsxc_dialog .col-md-offset-11 { margin-left: 91.6666666667%; } #jsxc_dialog .col-md-offset-12 { margin-left: 100%; } } @media (min-width: 1200px) { #jsxc_dialog .col-lg-1, #jsxc_dialog .col-lg-2, #jsxc_dialog .col-lg-3, #jsxc_dialog .col-lg-4, #jsxc_dialog .col-lg-5, #jsxc_dialog .col-lg-6, #jsxc_dialog .col-lg-7, #jsxc_dialog .col-lg-8, #jsxc_dialog .col-lg-9, #jsxc_dialog .col-lg-10, #jsxc_dialog .col-lg-11, #jsxc_dialog .col-lg-12 { float: left; } #jsxc_dialog .col-lg-1 { width: 8.3333333333%; } #jsxc_dialog .col-lg-2 { width: 16.6666666667%; } #jsxc_dialog .col-lg-3 { width: 25%; } #jsxc_dialog .col-lg-4 { width: 33.3333333333%; } #jsxc_dialog .col-lg-5 { width: 41.6666666667%; } #jsxc_dialog .col-lg-6 { width: 50%; } #jsxc_dialog .col-lg-7 { width: 58.3333333333%; } #jsxc_dialog .col-lg-8 { width: 66.6666666667%; } #jsxc_dialog .col-lg-9 { width: 75%; } #jsxc_dialog .col-lg-10 { width: 83.3333333333%; } #jsxc_dialog .col-lg-11 { width: 91.6666666667%; } #jsxc_dialog .col-lg-12 { width: 100%; } #jsxc_dialog .col-lg-pull-0 { right: auto; } #jsxc_dialog .col-lg-pull-1 { right: 8.3333333333%; } #jsxc_dialog .col-lg-pull-2 { right: 16.6666666667%; } #jsxc_dialog .col-lg-pull-3 { right: 25%; } #jsxc_dialog .col-lg-pull-4 { right: 33.3333333333%; } #jsxc_dialog .col-lg-pull-5 { right: 41.6666666667%; } #jsxc_dialog .col-lg-pull-6 { right: 50%; } #jsxc_dialog .col-lg-pull-7 { right: 58.3333333333%; } #jsxc_dialog .col-lg-pull-8 { right: 66.6666666667%; } #jsxc_dialog .col-lg-pull-9 { right: 75%; } #jsxc_dialog .col-lg-pull-10 { right: 83.3333333333%; } #jsxc_dialog .col-lg-pull-11 { right: 91.6666666667%; } #jsxc_dialog .col-lg-pull-12 { right: 100%; } #jsxc_dialog .col-lg-push-0 { left: auto; } #jsxc_dialog .col-lg-push-1 { left: 8.3333333333%; } #jsxc_dialog .col-lg-push-2 { left: 16.6666666667%; } #jsxc_dialog .col-lg-push-3 { left: 25%; } #jsxc_dialog .col-lg-push-4 { left: 33.3333333333%; } #jsxc_dialog .col-lg-push-5 { left: 41.6666666667%; } #jsxc_dialog .col-lg-push-6 { left: 50%; } #jsxc_dialog .col-lg-push-7 { left: 58.3333333333%; } #jsxc_dialog .col-lg-push-8 { left: 66.6666666667%; } #jsxc_dialog .col-lg-push-9 { left: 75%; } #jsxc_dialog .col-lg-push-10 { left: 83.3333333333%; } #jsxc_dialog .col-lg-push-11 { left: 91.6666666667%; } #jsxc_dialog .col-lg-push-12 { left: 100%; } #jsxc_dialog .col-lg-offset-0 { margin-left: 0%; } #jsxc_dialog .col-lg-offset-1 { margin-left: 8.3333333333%; } #jsxc_dialog .col-lg-offset-2 { margin-left: 16.6666666667%; } #jsxc_dialog .col-lg-offset-3 { margin-left: 25%; } #jsxc_dialog .col-lg-offset-4 { margin-left: 33.3333333333%; } #jsxc_dialog .col-lg-offset-5 { margin-left: 41.6666666667%; } #jsxc_dialog .col-lg-offset-6 { margin-left: 50%; } #jsxc_dialog .col-lg-offset-7 { margin-left: 58.3333333333%; } #jsxc_dialog .col-lg-offset-8 { margin-left: 66.6666666667%; } #jsxc_dialog .col-lg-offset-9 { margin-left: 75%; } #jsxc_dialog .col-lg-offset-10 { margin-left: 83.3333333333%; } #jsxc_dialog .col-lg-offset-11 { margin-left: 91.6666666667%; } #jsxc_dialog .col-lg-offset-12 { margin-left: 100%; } } #jsxc_dialog .alert { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; } #jsxc_dialog .alert h4 { margin-top: 0; color: inherit; } #jsxc_dialog .alert .alert-link { font-weight: bold; } #jsxc_dialog .alert > p, #jsxc_dialog .alert > ul { margin-bottom: 0; } #jsxc_dialog .alert > p + p { margin-top: 5px; } #jsxc_dialog .alert-dismissable, #jsxc_dialog .alert-dismissible { padding-right: 35px; } #jsxc_dialog .alert-dismissable .close, #jsxc_dialog .alert-dismissible .close { position: relative; top: -2px; right: -21px; color: inherit; } #jsxc_dialog .alert-success { background-color: #dff0d8; border-color: #d6e9c6; color: #3c763d; } #jsxc_dialog .alert-success hr { border-top-color: #c9e2b3; } #jsxc_dialog .alert-success .alert-link { color: #2b542c; } #jsxc_dialog .alert-info { background-color: #d9edf7; border-color: #bce8f1; color: #31708f; } #jsxc_dialog .alert-info hr { border-top-color: #a6e1ec; } #jsxc_dialog .alert-info .alert-link { color: #245269; } #jsxc_dialog .alert-warning { background-color: #fcf8e3; border-color: #faebcc; color: #8a6d3b; } #jsxc_dialog .alert-warning hr { border-top-color: #f7e1b5; } #jsxc_dialog .alert-warning .alert-link { color: #66512c; } #jsxc_dialog .alert-danger { background-color: #f2dede; border-color: #ebccd1; color: #a94442; } #jsxc_dialog .alert-danger hr { border-top-color: #e4b9c0; } #jsxc_dialog .alert-danger .alert-link { color: #843534; } #jsxc_dialog .btn { display: inline-block; margin-bottom: 0; font-weight: normal; text-align: center; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; background-image: none; border: 1px solid transparent; white-space: nowrap; padding: 6px 12px; font-size: 14px; line-height: 1.428571429; border-radius: 4px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #jsxc_dialog .btn:focus, #jsxc_dialog .btn.focus, #jsxc_dialog .btn:active:focus, #jsxc_dialog .btn:active.focus, #jsxc_dialog .btn.active:focus, #jsxc_dialog .btn.active.focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } #jsxc_dialog .btn:hover, #jsxc_dialog .btn:focus, #jsxc_dialog .btn.focus { color: #333; text-decoration: none; } #jsxc_dialog .btn:active, #jsxc_dialog .btn.active { outline: 0; background-image: none; box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } #jsxc_dialog .btn.disabled, #jsxc_dialog .btn[disabled], fieldset[disabled] #jsxc_dialog .btn { cursor: not-allowed; pointer-events: none; opacity: 0.65; filter: alpha(opacity=65); box-shadow: none; } #jsxc_dialog .btn-default { color: #333; background-color: #fff; border-color: #ccc; } #jsxc_dialog .btn-default:hover, #jsxc_dialog .btn-default:focus, #jsxc_dialog .btn-default.focus, #jsxc_dialog .btn-default:active, #jsxc_dialog .btn-default.active, .open > #jsxc_dialog .btn-default.dropdown-toggle { color: #333; background-color: #e6e6e6; border-color: #adadad; } #jsxc_dialog .btn-default:active, #jsxc_dialog .btn-default.active, .open > #jsxc_dialog .btn-default.dropdown-toggle { background-image: none; } #jsxc_dialog .btn-default.disabled, #jsxc_dialog .btn-default.disabled:hover, #jsxc_dialog .btn-default.disabled:focus, #jsxc_dialog .btn-default.disabled.focus, #jsxc_dialog .btn-default.disabled:active, #jsxc_dialog .btn-default.disabled.active, #jsxc_dialog .btn-default[disabled], #jsxc_dialog .btn-default[disabled]:hover, #jsxc_dialog .btn-default[disabled]:focus, #jsxc_dialog .btn-default[disabled].focus, #jsxc_dialog .btn-default[disabled]:active, #jsxc_dialog .btn-default[disabled].active, fieldset[disabled] #jsxc_dialog .btn-default, fieldset[disabled] #jsxc_dialog .btn-default:hover, fieldset[disabled] #jsxc_dialog .btn-default:focus, fieldset[disabled] #jsxc_dialog .btn-default.focus, fieldset[disabled] #jsxc_dialog .btn-default:active, fieldset[disabled] #jsxc_dialog .btn-default.active { background-color: #fff; border-color: #ccc; } #jsxc_dialog .btn-default .badge { color: #fff; background-color: #333; } #jsxc_dialog .btn-primary { color: #fff; background-color: #337ab7; border-color: #2e6da4; } #jsxc_dialog .btn-primary:hover, #jsxc_dialog .btn-primary:focus, #jsxc_dialog .btn-primary.focus, #jsxc_dialog .btn-primary:active, #jsxc_dialog .btn-primary.active, .open > #jsxc_dialog .btn-primary.dropdown-toggle { color: #fff; background-color: #286090; border-color: #204d74; } #jsxc_dialog .btn-primary:active, #jsxc_dialog .btn-primary.active, .open > #jsxc_dialog .btn-primary.dropdown-toggle { background-image: none; } #jsxc_dialog .btn-primary.disabled, #jsxc_dialog .btn-primary.disabled:hover, #jsxc_dialog .btn-primary.disabled:focus, #jsxc_dialog .btn-primary.disabled.focus, #jsxc_dialog .btn-primary.disabled:active, #jsxc_dialog .btn-primary.disabled.active, #jsxc_dialog .btn-primary[disabled], #jsxc_dialog .btn-primary[disabled]:hover, #jsxc_dialog .btn-primary[disabled]:focus, #jsxc_dialog .btn-primary[disabled].focus, #jsxc_dialog .btn-primary[disabled]:active, #jsxc_dialog .btn-primary[disabled].active, fieldset[disabled] #jsxc_dialog .btn-primary, fieldset[disabled] #jsxc_dialog .btn-primary:hover, fieldset[disabled] #jsxc_dialog .btn-primary:focus, fieldset[disabled] #jsxc_dialog .btn-primary.focus, fieldset[disabled] #jsxc_dialog .btn-primary:active, fieldset[disabled] #jsxc_dialog .btn-primary.active { background-color: #337ab7; border-color: #2e6da4; } #jsxc_dialog .btn-primary .badge { color: #337ab7; background-color: #fff; } #jsxc_dialog .btn-success { color: #fff; background-color: #5cb85c; border-color: #4cae4c; } #jsxc_dialog .btn-success:hover, #jsxc_dialog .btn-success:focus, #jsxc_dialog .btn-success.focus, #jsxc_dialog .btn-success:active, #jsxc_dialog .btn-success.active, .open > #jsxc_dialog .btn-success.dropdown-toggle { color: #fff; background-color: #449d44; border-color: #398439; } #jsxc_dialog .btn-success:active, #jsxc_dialog .btn-success.active, .open > #jsxc_dialog .btn-success.dropdown-toggle { background-image: none; } #jsxc_dialog .btn-success.disabled, #jsxc_dialog .btn-success.disabled:hover, #jsxc_dialog .btn-success.disabled:focus, #jsxc_dialog .btn-success.disabled.focus, #jsxc_dialog .btn-success.disabled:active, #jsxc_dialog .btn-success.disabled.active, #jsxc_dialog .btn-success[disabled], #jsxc_dialog .btn-success[disabled]:hover, #jsxc_dialog .btn-success[disabled]:focus, #jsxc_dialog .btn-success[disabled].focus, #jsxc_dialog .btn-success[disabled]:active, #jsxc_dialog .btn-success[disabled].active, fieldset[disabled] #jsxc_dialog .btn-success, fieldset[disabled] #jsxc_dialog .btn-success:hover, fieldset[disabled] #jsxc_dialog .btn-success:focus, fieldset[disabled] #jsxc_dialog .btn-success.focus, fieldset[disabled] #jsxc_dialog .btn-success:active, fieldset[disabled] #jsxc_dialog .btn-success.active { background-color: #5cb85c; border-color: #4cae4c; } #jsxc_dialog .btn-success .badge { color: #5cb85c; background-color: #fff; } #jsxc_dialog .btn-info { color: #fff; background-color: #5bc0de; border-color: #46b8da; } #jsxc_dialog .btn-info:hover, #jsxc_dialog .btn-info:focus, #jsxc_dialog .btn-info.focus, #jsxc_dialog .btn-info:active, #jsxc_dialog .btn-info.active, .open > #jsxc_dialog .btn-info.dropdown-toggle { color: #fff; background-color: #31b0d5; border-color: #269abc; } #jsxc_dialog .btn-info:active, #jsxc_dialog .btn-info.active, .open > #jsxc_dialog .btn-info.dropdown-toggle { background-image: none; } #jsxc_dialog .btn-info.disabled, #jsxc_dialog .btn-info.disabled:hover, #jsxc_dialog .btn-info.disabled:focus, #jsxc_dialog .btn-info.disabled.focus, #jsxc_dialog .btn-info.disabled:active, #jsxc_dialog .btn-info.disabled.active, #jsxc_dialog .btn-info[disabled], #jsxc_dialog .btn-info[disabled]:hover, #jsxc_dialog .btn-info[disabled]:focus, #jsxc_dialog .btn-info[disabled].focus, #jsxc_dialog .btn-info[disabled]:active, #jsxc_dialog .btn-info[disabled].active, fieldset[disabled] #jsxc_dialog .btn-info, fieldset[disabled] #jsxc_dialog .btn-info:hover, fieldset[disabled] #jsxc_dialog .btn-info:focus, fieldset[disabled] #jsxc_dialog .btn-info.focus, fieldset[disabled] #jsxc_dialog .btn-info:active, fieldset[disabled] #jsxc_dialog .btn-info.active { background-color: #5bc0de; border-color: #46b8da; } #jsxc_dialog .btn-info .badge { color: #5bc0de; background-color: #fff; } #jsxc_dialog .btn-warning { color: #fff; background-color: #f0ad4e; border-color: #eea236; } #jsxc_dialog .btn-warning:hover, #jsxc_dialog .btn-warning:focus, #jsxc_dialog .btn-warning.focus, #jsxc_dialog .btn-warning:active, #jsxc_dialog .btn-warning.active, .open > #jsxc_dialog .btn-warning.dropdown-toggle { color: #fff; background-color: #ec971f; border-color: #d58512; } #jsxc_dialog .btn-warning:active, #jsxc_dialog .btn-warning.active, .open > #jsxc_dialog .btn-warning.dropdown-toggle { background-image: none; } #jsxc_dialog .btn-warning.disabled, #jsxc_dialog .btn-warning.disabled:hover, #jsxc_dialog .btn-warning.disabled:focus, #jsxc_dialog .btn-warning.disabled.focus, #jsxc_dialog .btn-warning.disabled:active, #jsxc_dialog .btn-warning.disabled.active, #jsxc_dialog .btn-warning[disabled], #jsxc_dialog .btn-warning[disabled]:hover, #jsxc_dialog .btn-warning[disabled]:focus, #jsxc_dialog .btn-warning[disabled].focus, #jsxc_dialog .btn-warning[disabled]:active, #jsxc_dialog .btn-warning[disabled].active, fieldset[disabled] #jsxc_dialog .btn-warning, fieldset[disabled] #jsxc_dialog .btn-warning:hover, fieldset[disabled] #jsxc_dialog .btn-warning:focus, fieldset[disabled] #jsxc_dialog .btn-warning.focus, fieldset[disabled] #jsxc_dialog .btn-warning:active, fieldset[disabled] #jsxc_dialog .btn-warning.active { background-color: #f0ad4e; border-color: #eea236; } #jsxc_dialog .btn-warning .badge { color: #f0ad4e; background-color: #fff; } #jsxc_dialog .btn-danger { color: #fff; background-color: #d9534f; border-color: #d43f3a; } #jsxc_dialog .btn-danger:hover, #jsxc_dialog .btn-danger:focus, #jsxc_dialog .btn-danger.focus, #jsxc_dialog .btn-danger:active, #jsxc_dialog .btn-danger.active, .open > #jsxc_dialog .btn-danger.dropdown-toggle { color: #fff; background-color: #c9302c; border-color: #ac2925; } #jsxc_dialog .btn-danger:active, #jsxc_dialog .btn-danger.active, .open > #jsxc_dialog .btn-danger.dropdown-toggle { background-image: none; } #jsxc_dialog .btn-danger.disabled, #jsxc_dialog .btn-danger.disabled:hover, #jsxc_dialog .btn-danger.disabled:focus, #jsxc_dialog .btn-danger.disabled.focus, #jsxc_dialog .btn-danger.disabled:active, #jsxc_dialog .btn-danger.disabled.active, #jsxc_dialog .btn-danger[disabled], #jsxc_dialog .btn-danger[disabled]:hover, #jsxc_dialog .btn-danger[disabled]:focus, #jsxc_dialog .btn-danger[disabled].focus, #jsxc_dialog .btn-danger[disabled]:active, #jsxc_dialog .btn-danger[disabled].active, fieldset[disabled] #jsxc_dialog .btn-danger, fieldset[disabled] #jsxc_dialog .btn-danger:hover, fieldset[disabled] #jsxc_dialog .btn-danger:focus, fieldset[disabled] #jsxc_dialog .btn-danger.focus, fieldset[disabled] #jsxc_dialog .btn-danger:active, fieldset[disabled] #jsxc_dialog .btn-danger.active { background-color: #d9534f; border-color: #d43f3a; } #jsxc_dialog .btn-danger .badge { color: #d9534f; background-color: #fff; } #jsxc_dialog .btn-link { color: #337ab7; font-weight: normal; border-radius: 0; } #jsxc_dialog .btn-link, #jsxc_dialog .btn-link:active, #jsxc_dialog .btn-link.active, #jsxc_dialog .btn-link[disabled], fieldset[disabled] #jsxc_dialog .btn-link { background-color: transparent; box-shadow: none; } #jsxc_dialog .btn-link, #jsxc_dialog .btn-link:hover, #jsxc_dialog .btn-link:focus, #jsxc_dialog .btn-link:active { border-color: transparent; } #jsxc_dialog .btn-link:hover, #jsxc_dialog .btn-link:focus { color: #23527c; text-decoration: underline; background-color: transparent; } #jsxc_dialog .btn-link[disabled]:hover, #jsxc_dialog .btn-link[disabled]:focus, fieldset[disabled] #jsxc_dialog .btn-link:hover, fieldset[disabled] #jsxc_dialog .btn-link:focus { color: #777777; text-decoration: none; } #jsxc_dialog .btn-lg, #jsxc_dialog .btn-group-lg > .btn { padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } #jsxc_dialog .btn-sm, #jsxc_dialog .btn-group-sm > .btn { padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } #jsxc_dialog .btn-xs, #jsxc_dialog .btn-group-xs > .btn { padding: 1px 5px; font-size: 12px; line-height: 1.5; border-radius: 3px; } #jsxc_dialog .btn-block { display: block; width: 100%; } #jsxc_dialog .btn-block + .btn-block { margin-top: 5px; } #jsxc_dialog input[type="submit"].btn-block, #jsxc_dialog input[type="reset"].btn-block, #jsxc_dialog input[type="button"].btn-block { width: 100%; } #jsxc_dialog .btn-group, #jsxc_dialog .btn-group-vertical { position: relative; display: inline-block; vertical-align: middle; } #jsxc_dialog .btn-group > .btn, #jsxc_dialog .btn-group-vertical > .btn { position: relative; float: left; } #jsxc_dialog .btn-group > .btn:hover, #jsxc_dialog .btn-group > .btn:focus, #jsxc_dialog .btn-group > .btn:active, #jsxc_dialog .btn-group > .btn.active, #jsxc_dialog .btn-group-vertical > .btn:hover, #jsxc_dialog .btn-group-vertical > .btn:focus, #jsxc_dialog .btn-group-vertical > .btn:active, #jsxc_dialog .btn-group-vertical > .btn.active { z-index: 2; } #jsxc_dialog .btn-group .btn + .btn, #jsxc_dialog .btn-group .btn + .btn-group, #jsxc_dialog .btn-group .btn-group + .btn, #jsxc_dialog .btn-group .btn-group + .btn-group { margin-left: -1px; } #jsxc_dialog .btn-toolbar { margin-left: -5px; } #jsxc_dialog .btn-toolbar:before, #jsxc_dialog .btn-toolbar:after { content: " "; display: table; } #jsxc_dialog .btn-toolbar:after { clear: both; } #jsxc_dialog .btn-toolbar .btn-group, #jsxc_dialog .btn-toolbar .input-group { float: left; } #jsxc_dialog .btn-toolbar > .btn, #jsxc_dialog .btn-toolbar > .btn-group, #jsxc_dialog .btn-toolbar > .input-group { margin-left: 5px; } #jsxc_dialog .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { border-radius: 0; } #jsxc_dialog .btn-group > .btn:first-child { margin-left: 0; } #jsxc_dialog .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { border-bottom-right-radius: 0; border-top-right-radius: 0; } #jsxc_dialog .btn-group > .btn:last-child:not(:first-child), #jsxc_dialog .btn-group > .dropdown-toggle:not(:first-child) { border-bottom-left-radius: 0; border-top-left-radius: 0; } #jsxc_dialog .btn-group > .btn-group { float: left; } #jsxc_dialog .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } #jsxc_dialog .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, #jsxc_dialog .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-top-right-radius: 0; } #jsxc_dialog .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { border-bottom-left-radius: 0; border-top-left-radius: 0; } #jsxc_dialog .btn-group .dropdown-toggle:active, #jsxc_dialog .btn-group.open .dropdown-toggle { outline: 0; } #jsxc_dialog .btn-group > .btn + .dropdown-toggle { padding-left: 8px; padding-right: 8px; } #jsxc_dialog .btn-group > .btn-lg + .dropdown-toggle, #jsxc_dialog .btn-group-lg.btn-group > .btn + .dropdown-toggle { padding-left: 12px; padding-right: 12px; } #jsxc_dialog .btn-group.open .dropdown-toggle { box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } #jsxc_dialog .btn-group.open .dropdown-toggle.btn-link { box-shadow: none; } #jsxc_dialog .btn .caret { margin-left: 0; } #jsxc_dialog .btn-lg .caret, #jsxc_dialog .btn-group-lg > .btn .caret { border-width: 5px 5px 0; border-bottom-width: 0; } #jsxc_dialog .dropup .btn-lg .caret, #jsxc_dialog .dropup .btn-group-lg > .btn .caret { border-width: 0 5px 5px; } #jsxc_dialog .btn-group-vertical > .btn, #jsxc_dialog .btn-group-vertical > .btn-group, #jsxc_dialog .btn-group-vertical > .btn-group > .btn { display: block; float: none; width: 100%; max-width: 100%; } #jsxc_dialog .btn-group-vertical > .btn-group:before, #jsxc_dialog .btn-group-vertical > .btn-group:after { content: " "; display: table; } #jsxc_dialog .btn-group-vertical > .btn-group:after { clear: both; } #jsxc_dialog .btn-group-vertical > .btn-group > .btn { float: none; } #jsxc_dialog .btn-group-vertical > .btn + .btn, #jsxc_dialog .btn-group-vertical > .btn + .btn-group, #jsxc_dialog .btn-group-vertical > .btn-group + .btn, #jsxc_dialog .btn-group-vertical > .btn-group + .btn-group { margin-top: -1px; margin-left: 0; } #jsxc_dialog .btn-group-vertical > .btn:not(:first-child):not(:last-child) { border-radius: 0; } #jsxc_dialog .btn-group-vertical > .btn:first-child:not(:last-child) { border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } #jsxc_dialog .btn-group-vertical > .btn:last-child:not(:first-child) { border-bottom-left-radius: 4px; border-top-right-radius: 0; border-top-left-radius: 0; } #jsxc_dialog .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } #jsxc_dialog .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, #jsxc_dialog .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-bottom-left-radius: 0; } #jsxc_dialog .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-right-radius: 0; border-top-left-radius: 0; } #jsxc_dialog .btn-group-justified { display: table; width: 100%; table-layout: fixed; border-collapse: separate; } #jsxc_dialog .btn-group-justified > .btn, #jsxc_dialog .btn-group-justified > .btn-group { float: none; display: table-cell; width: 1%; } #jsxc_dialog .btn-group-justified > .btn-group .btn { width: 100%; } #jsxc_dialog .btn-group-justified > .btn-group .dropdown-menu { left: auto; } #jsxc_dialog [data-toggle="buttons"] > .btn input[type="radio"], #jsxc_dialog [data-toggle="buttons"] > .btn input[type="checkbox"], #jsxc_dialog [data-toggle="buttons"] > .btn-group > .btn input[type="radio"], #jsxc_dialog [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { position: absolute; clip: rect(0, 0, 0, 0); pointer-events: none; } #jsxc_dialog fieldset { padding: 0; margin: 0; border: 0; min-width: 0; } #jsxc_dialog legend { display: block; width: 100%; padding: 0; margin-bottom: 20px; font-size: 21px; line-height: inherit; color: #333333; border: 0; border-bottom: 1px solid #e5e5e5; } #jsxc_dialog label { display: inline-block; max-width: 100%; margin-bottom: 5px; font-weight: bold; } #jsxc_dialog input[type="search"] { box-sizing: border-box; } #jsxc_dialog input[type="radio"], #jsxc_dialog input[type="checkbox"] { margin: 4px 0 0; margin-top: 1px \9; line-height: normal; } #jsxc_dialog input[type="file"] { display: block; } #jsxc_dialog input[type="range"] { display: block; width: 100%; } #jsxc_dialog select[multiple], #jsxc_dialog select[size] { height: auto; } #jsxc_dialog input[type="file"]:focus, #jsxc_dialog input[type="radio"]:focus, #jsxc_dialog input[type="checkbox"]:focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } #jsxc_dialog output { display: block; padding-top: 7px; font-size: 14px; line-height: 1.428571429; color: #555555; } #jsxc_dialog .form-control { display: block; width: 100%; height: 34px; padding: 6px 12px; font-size: 14px; line-height: 1.428571429; color: #555555; background-color: #fff; background-image: none; border: 1px solid #ccc; border-radius: 4px; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; } #jsxc_dialog .form-control:focus { border-color: #66afe9; outline: 0; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); } #jsxc_dialog .form-control::-moz-placeholder { color: #999; opacity: 1; } #jsxc_dialog .form-control:-ms-input-placeholder { color: #999; } #jsxc_dialog .form-control::-webkit-input-placeholder { color: #999; } #jsxc_dialog .form-control[disabled], #jsxc_dialog .form-control[readonly], fieldset[disabled] #jsxc_dialog .form-control { background-color: #eeeeee; opacity: 1; } #jsxc_dialog .form-control[disabled], fieldset[disabled] #jsxc_dialog .form-control { cursor: not-allowed; } #jsxc_dialog textarea.form-control { height: auto; } #jsxc_dialog input[type="search"] { -webkit-appearance: none; } @media screen and (-webkit-min-device-pixel-ratio: 0) { #jsxc_dialog input[type="date"], #jsxc_dialog input[type="time"], #jsxc_dialog input[type="datetime-local"], #jsxc_dialog input[type="month"] { line-height: 34px; } #jsxc_dialog input[type="date"].input-sm, .input-group-sm #jsxc_dialog input[type="date"], #jsxc_dialog input[type="time"].input-sm, .input-group-sm #jsxc_dialog input[type="time"], #jsxc_dialog input[type="datetime-local"].input-sm, .input-group-sm #jsxc_dialog input[type="datetime-local"], #jsxc_dialog input[type="month"].input-sm, .input-group-sm #jsxc_dialog input[type="month"] { line-height: 30px; } #jsxc_dialog input[type="date"].input-lg, .input-group-lg #jsxc_dialog input[type="date"], #jsxc_dialog input[type="time"].input-lg, .input-group-lg #jsxc_dialog input[type="time"], #jsxc_dialog input[type="datetime-local"].input-lg, .input-group-lg #jsxc_dialog input[type="datetime-local"], #jsxc_dialog input[type="month"].input-lg, .input-group-lg #jsxc_dialog input[type="month"] { line-height: 46px; } } #jsxc_dialog .form-group { margin-bottom: 15px; } #jsxc_dialog .radio, #jsxc_dialog .checkbox { position: relative; display: block; margin-top: 10px; margin-bottom: 10px; } #jsxc_dialog .radio label, #jsxc_dialog .checkbox label { min-height: 20px; padding-left: 20px; margin-bottom: 0; font-weight: normal; cursor: pointer; } #jsxc_dialog .radio input[type="radio"], #jsxc_dialog .radio-inline input[type="radio"], #jsxc_dialog .checkbox input[type="checkbox"], #jsxc_dialog .checkbox-inline input[type="checkbox"] { position: absolute; margin-left: -20px; margin-top: 4px \9; } #jsxc_dialog .radio + .radio, #jsxc_dialog .checkbox + .checkbox { margin-top: -5px; } #jsxc_dialog .radio-inline, #jsxc_dialog .checkbox-inline { position: relative; display: inline-block; padding-left: 20px; margin-bottom: 0; vertical-align: middle; font-weight: normal; cursor: pointer; } #jsxc_dialog .radio-inline + .radio-inline, #jsxc_dialog .checkbox-inline + .checkbox-inline { margin-top: 0; margin-left: 10px; } #jsxc_dialog input[type="radio"][disabled], #jsxc_dialog input[type="radio"].disabled, fieldset[disabled] #jsxc_dialog input[type="radio"], #jsxc_dialog input[type="checkbox"][disabled], #jsxc_dialog input[type="checkbox"].disabled, fieldset[disabled] #jsxc_dialog input[type="checkbox"] { cursor: not-allowed; } #jsxc_dialog .radio-inline.disabled, fieldset[disabled] #jsxc_dialog .radio-inline, #jsxc_dialog .checkbox-inline.disabled, fieldset[disabled] #jsxc_dialog .checkbox-inline { cursor: not-allowed; } #jsxc_dialog .radio.disabled label, fieldset[disabled] #jsxc_dialog .radio label, #jsxc_dialog .checkbox.disabled label, fieldset[disabled] #jsxc_dialog .checkbox label { cursor: not-allowed; } #jsxc_dialog .form-control-static { padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; min-height: 34px; } #jsxc_dialog .form-control-static.input-lg, #jsxc_dialog .form-control-static.input-sm { padding-left: 0; padding-right: 0; } #jsxc_dialog .input-sm { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } #jsxc_dialog select.input-sm { height: 30px; line-height: 30px; } #jsxc_dialog textarea.input-sm, #jsxc_dialog select[multiple].input-sm { height: auto; } #jsxc_dialog .form-group-sm .form-control { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } #jsxc_dialog .form-group-sm select.form-control { height: 30px; line-height: 30px; } #jsxc_dialog .form-group-sm textarea.form-control, #jsxc_dialog .form-group-sm select[multiple].form-control { height: auto; } #jsxc_dialog .form-group-sm .form-control-static { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; min-height: 32px; } #jsxc_dialog .input-lg { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } #jsxc_dialog select.input-lg { height: 46px; line-height: 46px; } #jsxc_dialog textarea.input-lg, #jsxc_dialog select[multiple].input-lg { height: auto; } #jsxc_dialog .form-group-lg .form-control { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } #jsxc_dialog .form-group-lg select.form-control { height: 46px; line-height: 46px; } #jsxc_dialog .form-group-lg textarea.form-control, #jsxc_dialog .form-group-lg select[multiple].form-control { height: auto; } #jsxc_dialog .form-group-lg .form-control-static { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; min-height: 38px; } #jsxc_dialog .has-feedback { position: relative; } #jsxc_dialog .has-feedback .form-control { padding-right: 42.5px; } #jsxc_dialog .form-control-feedback { position: absolute; top: 0; right: 0; z-index: 2; display: block; width: 34px; height: 34px; line-height: 34px; text-align: center; pointer-events: none; } #jsxc_dialog .input-lg + .form-control-feedback { width: 46px; height: 46px; line-height: 46px; } #jsxc_dialog .input-sm + .form-control-feedback { width: 30px; height: 30px; line-height: 30px; } #jsxc_dialog .has-success .help-block, #jsxc_dialog .has-success .control-label, #jsxc_dialog .has-success .radio, #jsxc_dialog .has-success .checkbox, #jsxc_dialog .has-success .radio-inline, #jsxc_dialog .has-success .checkbox-inline, #jsxc_dialog .has-success.radio label, #jsxc_dialog .has-success.checkbox label, #jsxc_dialog .has-success.radio-inline label, #jsxc_dialog .has-success.checkbox-inline label { color: #3c763d; } #jsxc_dialog .has-success .form-control { border-color: #3c763d; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } #jsxc_dialog .has-success .form-control:focus { border-color: #2b542c; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; } #jsxc_dialog .has-success .input-group-addon { color: #3c763d; border-color: #3c763d; background-color: #dff0d8; } #jsxc_dialog .has-success .form-control-feedback { color: #3c763d; } #jsxc_dialog .has-warning .help-block, #jsxc_dialog .has-warning .control-label, #jsxc_dialog .has-warning .radio, #jsxc_dialog .has-warning .checkbox, #jsxc_dialog .has-warning .radio-inline, #jsxc_dialog .has-warning .checkbox-inline, #jsxc_dialog .has-warning.radio label, #jsxc_dialog .has-warning.checkbox label, #jsxc_dialog .has-warning.radio-inline label, #jsxc_dialog .has-warning.checkbox-inline label { color: #8a6d3b; } #jsxc_dialog .has-warning .form-control { border-color: #8a6d3b; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } #jsxc_dialog .has-warning .form-control:focus { border-color: #66512c; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; } #jsxc_dialog .has-warning .input-group-addon { color: #8a6d3b; border-color: #8a6d3b; background-color: #fcf8e3; } #jsxc_dialog .has-warning .form-control-feedback { color: #8a6d3b; } #jsxc_dialog .has-error .help-block, #jsxc_dialog .has-error .control-label, #jsxc_dialog .has-error .radio, #jsxc_dialog .has-error .checkbox, #jsxc_dialog .has-error .radio-inline, #jsxc_dialog .has-error .checkbox-inline, #jsxc_dialog .has-error.radio label, #jsxc_dialog .has-error.checkbox label, #jsxc_dialog .has-error.radio-inline label, #jsxc_dialog .has-error.checkbox-inline label { color: #a94442; } #jsxc_dialog .has-error .form-control { border-color: #a94442; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } #jsxc_dialog .has-error .form-control:focus { border-color: #843534; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; } #jsxc_dialog .has-error .input-group-addon { color: #a94442; border-color: #a94442; background-color: #f2dede; } #jsxc_dialog .has-error .form-control-feedback { color: #a94442; } #jsxc_dialog .has-feedback label ~ .form-control-feedback { top: 25px; } #jsxc_dialog .has-feedback label.sr-only ~ .form-control-feedback { top: 0; } #jsxc_dialog .help-block { display: block; margin-top: 5px; margin-bottom: 10px; color: #737373; } @media (min-width: 768px) { #jsxc_dialog .form-inline .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } #jsxc_dialog .form-inline .form-control { display: inline-block; width: auto; vertical-align: middle; } #jsxc_dialog .form-inline .form-control-static { display: inline-block; } #jsxc_dialog .form-inline .input-group { display: inline-table; vertical-align: middle; } #jsxc_dialog .form-inline .input-group .input-group-addon, #jsxc_dialog .form-inline .input-group .input-group-btn, #jsxc_dialog .form-inline .input-group .form-control { width: auto; } #jsxc_dialog .form-inline .input-group > .form-control { width: 100%; } #jsxc_dialog .form-inline .control-label { margin-bottom: 0; vertical-align: middle; } #jsxc_dialog .form-inline .radio, #jsxc_dialog .form-inline .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } #jsxc_dialog .form-inline .radio label, #jsxc_dialog .form-inline .checkbox label { padding-left: 0; } #jsxc_dialog .form-inline .radio input[type="radio"], #jsxc_dialog .form-inline .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } #jsxc_dialog .form-inline .has-feedback .form-control-feedback { top: 0; } } #jsxc_dialog .form-horizontal .radio, #jsxc_dialog .form-horizontal .checkbox, #jsxc_dialog .form-horizontal .radio-inline, #jsxc_dialog .form-horizontal .checkbox-inline { margin-top: 0; margin-bottom: 0; padding-top: 7px; } #jsxc_dialog .form-horizontal .radio, #jsxc_dialog .form-horizontal .checkbox { min-height: 27px; } #jsxc_dialog .form-horizontal .form-group { margin-left: -15px; margin-right: -15px; } #jsxc_dialog .form-horizontal .form-group:before, #jsxc_dialog .form-horizontal .form-group:after { content: " "; display: table; } #jsxc_dialog .form-horizontal .form-group:after { clear: both; } @media (min-width: 768px) { #jsxc_dialog .form-horizontal .control-label { text-align: right; margin-bottom: 0; padding-top: 7px; } } #jsxc_dialog .form-horizontal .has-feedback .form-control-feedback { right: 15px; } @media (min-width: 768px) { #jsxc_dialog .form-horizontal .form-group-lg .control-label { padding-top: 14.333333px; } } @media (min-width: 768px) { #jsxc_dialog .form-horizontal .form-group-sm .control-label { padding-top: 6px; } } #jsxc_dialog .progress { overflow: hidden; height: 20px; margin-bottom: 20px; background-color: #f5f5f5; border-radius: 4px; box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); } #jsxc_dialog .progress-bar { float: left; width: 0%; height: 100%; font-size: 12px; line-height: 20px; color: #fff; text-align: center; background-color: #337ab7; box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); -webkit-transition: width 0.6s ease; transition: width 0.6s ease; } #jsxc_dialog .progress-striped .progress-bar, #jsxc_dialog .progress-bar-striped { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-size: 40px 40px; } #jsxc_dialog .progress.active .progress-bar, #jsxc_dialog .progress-bar.active { -webkit-animation: progress-bar-stripes 2s linear infinite; animation: progress-bar-stripes 2s linear infinite; } #jsxc_dialog .progress-bar-success { background-color: #5cb85c; } .progress-striped #jsxc_dialog .progress-bar-success { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } #jsxc_dialog .progress-bar-info { background-color: #5bc0de; } .progress-striped #jsxc_dialog .progress-bar-info { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } #jsxc_dialog .progress-bar-warning { background-color: #f0ad4e; } .progress-striped #jsxc_dialog .progress-bar-warning { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } #jsxc_dialog .progress-bar-danger { background-color: #d9534f; } .progress-striped #jsxc_dialog .progress-bar-danger { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } #jsxc_dialog .progress { margin-bottom: 0px; } .mfp-bg { z-index: 9000; } .mfp-wrap { z-index: 9010; } .mfp-content { text-align: center; } #jsxc_dialog .mfp-close { font-size: 23px; } /* END: bootstrap */ #jsxc_buddylist li:hover .jsxc_avatar, .jsxc_avatar { width: 25px; height: 25px; line-height: 25px; margin-top: 2px; margin-right: 4px; background-color: #999999; border-radius: 2px; float: left; text-align: center; font-weight: bold; font-size: 30px; color: #b3b3b3; overflow: hidden; position: relative; font-family: Arial, sans-serif; background-size: cover; background-position: center center; } div.jsxc_transfer, div.jsxc_transfer.jsxc_disabled:hover { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICBpZD0ic3ZnMzA0MSIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4K2RldmVsIHIiCiAgIHdpZHRoPSIxNSIKICAgaGVpZ2h0PSIxNSIKICAgc29kaXBvZGk6ZG9jbmFtZT0icGFkbG9ja19vcGVuLXdoaXRlLnN2ZyI+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhMzA0NyI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczMwNDUiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODU1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaWQ9Im5hbWVkdmlldzMwNDMiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIGlua3NjYXBlOnpvb209IjQ0LjUwMDU4NyIKICAgICBpbmtzY2FwZTpjeD0iNi4yOTI4NzEiCiAgICAgaW5rc2NhcGU6Y3k9IjEwLjk4Njk3OSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iNjUiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjI0IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMzA0MSIKICAgICBib3JkZXJsYXllcj0idHJ1ZSIgLz4KICA8cmVjdAogICAgIHN0eWxlPSJmaWxsOiM4MDgwODA7c3Ryb2tlOiM4MDgwODA7c3Ryb2tlLXdpZHRoOjAuOTI1MjI3OTQiCiAgICAgaWQ9InJlY3QzMDUxIgogICAgIHdpZHRoPSIxMC4yMzIzOTQiCiAgICAgaGVpZ2h0PSI2LjQ2ODc1NDgiCiAgICAgeD0iMi41NTM0Mjc1IgogICAgIHk9IjguMDc0MjU1IiAvPgogIDxwYXRoCiAgICAgc3R5bGU9ImNvbG9yOiMwMDAwMDA7Zm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zdHJldGNoOm5vcm1hbDtmb250LXNpemU6bWVkaXVtO2xpbmUtaGVpZ2h0Om5vcm1hbDtmb250LWZhbWlseTpzYW5zLXNlcmlmO3RleHQtaW5kZW50OjA7dGV4dC1hbGlnbjpzdGFydDt0ZXh0LWRlY29yYXRpb246bm9uZTt0ZXh0LWRlY29yYXRpb24tbGluZTpub25lO3RleHQtZGVjb3JhdGlvbi1jb2xvcjpjdXJyZW50Q29sb3I7bGV0dGVyLXNwYWNpbmc6bm9ybWFsO3dvcmQtc3BhY2luZzpub3JtYWw7dGV4dC10cmFuc2Zvcm06bm9uZTtkaXJlY3Rpb246bHRyO2Jsb2NrLXByb2dyZXNzaW9uOnRiO3dyaXRpbmctbW9kZTpsci10YjtiYXNlbGluZS1zaGlmdDpiYXNlbGluZTt0ZXh0LWFuY2hvcjpzdGFydDtjbGlwLXJ1bGU6bm9uemVybztkaXNwbGF5OmlubGluZTtvdmVyZmxvdzp2aXNpYmxlO3Zpc2liaWxpdHk6dmlzaWJsZTtvcGFjaXR5OjE7aXNvbGF0aW9uOmF1dG87Y29sb3ItaW50ZXJwb2xhdGlvbjpzUkdCO2NvbG9yLWludGVycG9sYXRpb24tZmlsdGVyczpsaW5lYXJSR0I7ZmlsbDojODA4MDgwO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjkwMzg0Njg2O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1kYXNob2Zmc2V0OjA7c3Ryb2tlLW9wYWNpdHk6MTtjb2xvci1yZW5kZXJpbmc6YXV0bztpbWFnZS1yZW5kZXJpbmc6YXV0bztzaGFwZS1yZW5kZXJpbmc6YXV0bzt0ZXh0LXJlbmRlcmluZzphdXRvO2VuYWJsZS1iYWNrZ3JvdW5kOmFjY3VtdWxhdGUiCiAgICAgZD0iTSA3LjUwNzgxMjUsMC4wMDU1NjE0NCBDIDUuMDI2MDA1NCwwLjAwNTU2MTQ0IDMuNDkxNjAzLDAuNzk4MzQ0NjQgMi43NSwxLjk0Njk2NzYgMi4wMDgzOTcsMy4wOTU1OTA3IDIuMDg3ODkwNiw0LjM0OTY5NTQgMi4wODc4OTA2LDUuMDI1MDkyNiBsIDEuOTA0Mjk2OSwwIGMgMCwtMC43MzI5MzQ0IDAuMDEzNjk5LC0xLjUxMjU1MDMgMC4zNTc0MjE5LC0yLjA0NDkyMTggMC4zNDM3MjMxLC0wLjUzMjM3MTUgMS4wNDMzMzQzLC0xLjA3MDMxMjUgMy4xNTgyMDMxLC0xLjA3MDMxMjUgMi4wMjY0MjE5LDAgMi45NjY5NjM1LDAuNjI2NTU0NSAzLjQzMjY5MTUsMS4zODI3NDg0IDAuNDY1NzI4LDAuNzU2MTkzOSAwLjQwMDMzMywxLjcxNDI3ODkgMC40MDAzMzMsMS43MTQyNzg5IDAuMDQ1MTcsMS43NzMyMjYzIC0wLjA2NTk5LDQuMzAzMTczOCAwLjAwNDksNS41MzU3ODQ0IGwgMC4wNTI3NCwwLjg5ODQzOCAwLjg5ODQzNywwIDAuOTQ1NDQ1LC0wLjAwMzEgMC4wMSwtNi40MzYxMzczIGMgMCwwIDAuMDYyMDEsLTEuNjYyMTMyOCAtMC42ODUzMjEsLTIuODc1NDgyNyBDIDExLjgxOTc2OCwwLjkxMzAwMzY0IDEwLjA3ODA2NCwwLjAwNTU2MTQ0IDcuNTA3ODEyNSwwLjAwNTU2MTQ0IFoiCiAgICAgaWQ9InBhdGgzODQ4IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc29kaXBvZGk6bm9kZXR5cGVzPSJzc2Njc3NzY2NjY2NjY3MiIC8+Cjwvc3ZnPgo="); background-repeat: no-repeat; background-position: center center; background-size: 12px 12px; } #jsxc_buddylist li:hover .jsxc_avatar, .jsxc_avatar { width: 25px; height: 25px; line-height: 25px; margin-top: 2px; margin-right: 4px; background-color: #999999; border-radius: 2px; float: left; text-align: center; font-weight: bold; font-size: 30px; color: #b3b3b3; overflow: hidden; position: relative; font-family: Arial, sans-serif; background-size: cover; background-position: center center; } div.jsxc_transfer, div.jsxc_transfer.jsxc_disabled:hover { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICBpZD0ic3ZnMzA0MSIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4K2RldmVsIHIiCiAgIHdpZHRoPSIxNSIKICAgaGVpZ2h0PSIxNSIKICAgc29kaXBvZGk6ZG9jbmFtZT0icGFkbG9ja19vcGVuLXdoaXRlLnN2ZyI+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhMzA0NyI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczMwNDUiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODU1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaWQ9Im5hbWVkdmlldzMwNDMiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIGlua3NjYXBlOnpvb209IjQ0LjUwMDU4NyIKICAgICBpbmtzY2FwZTpjeD0iNi4yOTI4NzEiCiAgICAgaW5rc2NhcGU6Y3k9IjEwLjk4Njk3OSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iNjUiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjI0IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMzA0MSIKICAgICBib3JkZXJsYXllcj0idHJ1ZSIgLz4KICA8cmVjdAogICAgIHN0eWxlPSJmaWxsOiM4MDgwODA7c3Ryb2tlOiM4MDgwODA7c3Ryb2tlLXdpZHRoOjAuOTI1MjI3OTQiCiAgICAgaWQ9InJlY3QzMDUxIgogICAgIHdpZHRoPSIxMC4yMzIzOTQiCiAgICAgaGVpZ2h0PSI2LjQ2ODc1NDgiCiAgICAgeD0iMi41NTM0Mjc1IgogICAgIHk9IjguMDc0MjU1IiAvPgogIDxwYXRoCiAgICAgc3R5bGU9ImNvbG9yOiMwMDAwMDA7Zm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zdHJldGNoOm5vcm1hbDtmb250LXNpemU6bWVkaXVtO2xpbmUtaGVpZ2h0Om5vcm1hbDtmb250LWZhbWlseTpzYW5zLXNlcmlmO3RleHQtaW5kZW50OjA7dGV4dC1hbGlnbjpzdGFydDt0ZXh0LWRlY29yYXRpb246bm9uZTt0ZXh0LWRlY29yYXRpb24tbGluZTpub25lO3RleHQtZGVjb3JhdGlvbi1jb2xvcjpjdXJyZW50Q29sb3I7bGV0dGVyLXNwYWNpbmc6bm9ybWFsO3dvcmQtc3BhY2luZzpub3JtYWw7dGV4dC10cmFuc2Zvcm06bm9uZTtkaXJlY3Rpb246bHRyO2Jsb2NrLXByb2dyZXNzaW9uOnRiO3dyaXRpbmctbW9kZTpsci10YjtiYXNlbGluZS1zaGlmdDpiYXNlbGluZTt0ZXh0LWFuY2hvcjpzdGFydDtjbGlwLXJ1bGU6bm9uemVybztkaXNwbGF5OmlubGluZTtvdmVyZmxvdzp2aXNpYmxlO3Zpc2liaWxpdHk6dmlzaWJsZTtvcGFjaXR5OjE7aXNvbGF0aW9uOmF1dG87Y29sb3ItaW50ZXJwb2xhdGlvbjpzUkdCO2NvbG9yLWludGVycG9sYXRpb24tZmlsdGVyczpsaW5lYXJSR0I7ZmlsbDojODA4MDgwO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjkwMzg0Njg2O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1kYXNob2Zmc2V0OjA7c3Ryb2tlLW9wYWNpdHk6MTtjb2xvci1yZW5kZXJpbmc6YXV0bztpbWFnZS1yZW5kZXJpbmc6YXV0bztzaGFwZS1yZW5kZXJpbmc6YXV0bzt0ZXh0LXJlbmRlcmluZzphdXRvO2VuYWJsZS1iYWNrZ3JvdW5kOmFjY3VtdWxhdGUiCiAgICAgZD0iTSA3LjUwNzgxMjUsMC4wMDU1NjE0NCBDIDUuMDI2MDA1NCwwLjAwNTU2MTQ0IDMuNDkxNjAzLDAuNzk4MzQ0NjQgMi43NSwxLjk0Njk2NzYgMi4wMDgzOTcsMy4wOTU1OTA3IDIuMDg3ODkwNiw0LjM0OTY5NTQgMi4wODc4OTA2LDUuMDI1MDkyNiBsIDEuOTA0Mjk2OSwwIGMgMCwtMC43MzI5MzQ0IDAuMDEzNjk5LC0xLjUxMjU1MDMgMC4zNTc0MjE5LC0yLjA0NDkyMTggMC4zNDM3MjMxLC0wLjUzMjM3MTUgMS4wNDMzMzQzLC0xLjA3MDMxMjUgMy4xNTgyMDMxLC0xLjA3MDMxMjUgMi4wMjY0MjE5LDAgMi45NjY5NjM1LDAuNjI2NTU0NSAzLjQzMjY5MTUsMS4zODI3NDg0IDAuNDY1NzI4LDAuNzU2MTkzOSAwLjQwMDMzMywxLjcxNDI3ODkgMC40MDAzMzMsMS43MTQyNzg5IDAuMDQ1MTcsMS43NzMyMjYzIC0wLjA2NTk5LDQuMzAzMTczOCAwLjAwNDksNS41MzU3ODQ0IGwgMC4wNTI3NCwwLjg5ODQzOCAwLjg5ODQzNywwIDAuOTQ1NDQ1LC0wLjAwMzEgMC4wMSwtNi40MzYxMzczIGMgMCwwIDAuMDYyMDEsLTEuNjYyMTMyOCAtMC42ODUzMjEsLTIuODc1NDgyNyBDIDExLjgxOTc2OCwwLjkxMzAwMzY0IDEwLjA3ODA2NCwwLjAwNTU2MTQ0IDcuNTA3ODEyNSwwLjAwNTU2MTQ0IFoiCiAgICAgaWQ9InBhdGgzODQ4IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc29kaXBvZGk6bm9kZXR5cGVzPSJzc2Njc3NzY2NjY2NjY3MiIC8+Cjwvc3ZnPgo="); background-repeat: no-repeat; background-position: center center; background-size: 12px 12px; } #jsxc_buddylist { list-style: none; padding: 0; margin: 0; width: 204px; } #jsxc_buddylist li { padding: 0; margin: 0 4px; height: 30px; border-bottom: 1px solid gray; cursor: pointer; width: 200px; position: relative; color: gray; font-family: Arial, sans-serif; line-height: 30px; padding-left: 3px; z-index: 85; overflow: hidden; } #jsxc_buddylist li.jsxc_expand { height: 54px; } #jsxc_buddylist li.jsxc_expand .jsxc_avatar { width: 48px; height: 48px; } #jsxc_buddylist li.jsxc_expand .jsxc_avatar img { width: 48px; height: 48px; } #jsxc_buddylist li.jsxc_bookmarked .jsxc_avatar:after { content: " "; width: 20%; height: 30%; position: absolute; top: 0; right: 2px; background-size: contain; background-repeat: no-repeat; background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTIuOTIzNjk1IgogICBoZWlnaHQ9IjE5LjU1MTIyOSIKICAgdmlld0JveD0iMCAwIDMuNDE5Mzk0MSA1LjE3MjkyOTYiCiAgIGlkPSJzdmcyIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlua3NjYXBlOnZlcnNpb249IjAuOTErZGV2ZWwgciIKICAgc29kaXBvZGk6ZG9jbmFtZT0iYm9va21hcmtfcmVkLnN2ZyI+CiAgPGRlZnMKICAgICBpZD0iZGVmczQiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIGlkPSJiYXNlIgogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAuMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnpvb209IjIyLjQiCiAgICAgaW5rc2NhcGU6Y3g9Ii0xLjYyMTA2NyIKICAgICBpbmtzY2FwZTpjeT0iMTEuOTk5NDkyIgogICAgIGlua3NjYXBlOmRvY3VtZW50LXVuaXRzPSJtbSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIHVuaXRzPSJweCIKICAgICBmaXQtbWFyZ2luLXRvcD0iMCIKICAgICBmaXQtbWFyZ2luLWxlZnQ9IjAiCiAgICAgZml0LW1hcmdpbi1yaWdodD0iMCIKICAgICBmaXQtbWFyZ2luLWJvdHRvbT0iMCIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE4NTUiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTA1NiIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iNjUiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjI0IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNyI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICBpbmtzY2FwZTpsYWJlbD0iTGF5ZXIgMSIKICAgICBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIgogICAgIGlkPSJsYXllcjEiCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTAuODg3ODI4NjQsLTI5MS44NDQ5NykiPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOm5vbmU7ZmlsbC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlOiM4MDAwMDA7c3Ryb2tlLXdpZHRoOjAuMjY0NTgzMzI7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46bWl0ZXI7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGQ9Im0gMS4wMjAxMjAzLDI5MS44NDQ5NyAwLDQuODUzNTUgMS41Nzc0MDU1LC0xLjU3NzQgMS41Nzc0MDUzLDEuNTc3NCAwLC00LjgzODM5IgogICAgICAgaWQ9InBhdGg0MTQxIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2NjY2MiIC8+CiAgICA8cGF0aAogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIGlkPSJwYXRoNDE2MiIKICAgICAgIGQ9Im0gMS4wMjAxMjAzLDI5MS44NDQ5NyAwLDQuODUzNTUgMS41Nzc0MDU1LC0xLjU3NzQgMS41Nzc0MDUzLDEuNTc3NCAwLC00LjgzODM5IgogICAgICAgc3R5bGU9ImZpbGw6I2ZmMDAwMDtmaWxsLXJ1bGU6ZXZlbm9kZDtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MC4yNjQ1ODMzMjtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgc29kaXBvZGk6bm9kZXR5cGVzPSJjY2NjYyIgLz4KICA8L2c+Cjwvc3ZnPgo="); } #jsxc_buddylist li.jsxc_bookmarked .jsxc_bookmarkOptions { text-indent: 9999px; background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMjcyLjcwNTkzIgogICBoZWlnaHQ9IjI3NS4xOTQ0OSIKICAgaWQ9InN2ZzIiCiAgIHZlcnNpb249IjEuMSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC40OC4zLjEgcjk4ODYiCiAgIHNvZGlwb2RpOmRvY25hbWU9ImdlYXIuc3ZnIj4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iMC43IgogICAgIGlua3NjYXBlOmN4PSIxNTkuMTExMTgiCiAgICAgaW5rc2NhcGU6Y3k9Ijc1LjQ3NTkzNiIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0icHgiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjExMTEiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iODQwIgogICAgIGlua3NjYXBlOndpbmRvdy14PSIxOTEiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjI4IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjAiCiAgICAgZml0LW1hcmdpbi10b3A9IjAiCiAgICAgZml0LW1hcmdpbi1sZWZ0PSIwIgogICAgIGZpdC1tYXJnaW4tcmlnaHQ9IjAiCiAgICAgZml0LW1hcmdpbi1ib3R0b209IjAiIC8+CiAgPGRlZnMKICAgICBpZD0iZGVmczQiPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDQ2MTciPgogICAgICA8cGF0aAogICAgICAgICBzb2RpcG9kaTp0eXBlPSJhcmMiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNiM2IzYjM7c3Ryb2tlOm5vbmUiCiAgICAgICAgIGlkPSJwYXRoNDYxOSIKICAgICAgICAgc29kaXBvZGk6Y3g9IjE0MS40Mjg1NyIKICAgICAgICAgc29kaXBvZGk6Y3k9IjE0MC45MDg3NyIKICAgICAgICAgc29kaXBvZGk6cng9IjEyNC4yODU3MSIKICAgICAgICAgc29kaXBvZGk6cnk9IjEyNC4yODU3MSIKICAgICAgICAgZD0ibSAyNjUuNzE0MjksMTQwLjkwODc3IGEgMTI0LjI4NTcxLDEyNC4yODU3MSAwIDEgMSAtMjQ4LjU3MTQzLDAgMTI0LjI4NTcxLDEyNC4yODU3MSAwIDEgMSAyNDguNTcxNDMsMCB6IgogICAgICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzAuNDg2NTYsMjc1LjE0ODg4KSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgPC9kZWZzPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTciPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNzUuNTYyMTYsLTI3OC40NjA0KSI+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2IzYjNiMztzdHJva2U6bm9uZSIKICAgICAgIGQ9Im0gMzIyLjkwMDc3LDU1Mi4zNzYwOSBjIC0wLjgwMjUsLTEuMDMyNjUgLTQuMTI5OCwtNi43NzgxMiAtNy4zOTQsLTEyLjc2NzcxIC01LjY2MDYyLC0xMC4zODY4NiAtNS45MzQ5LC0xMS40NTk3MSAtNS45MzQ5LC0yMy4yMTQyOSAwLC02Ljc3ODI3IC0wLjE2MDcxLC0xMi4zMzQ3MSAtMC4zNTcxNCwtMTIuMzQ3NjQgLTAuMTk2NDMsLTAuMDEyOSAtNy4xMDcxNCwtMS4yNTM1MSAtMTUuMzU3MTQsLTIuNzU2ODYgLTguMjUsLTEuNTAzMzIgLTE1LjQyMDU0LC0yLjI5NjMyIC0xNS45MzQ1MywtMS43NjIyIC0wLjUxMzk5LDAuNTM0MTMgLTIuNjUwNjgsNS44NTIgLTQuNzQ4MiwxMS44MTc1IC0zLjI5Njc5LDkuMzc2MyAtNC45MTI3MSwxMS44MTMzOSAtMTEuOTIyNjEsMTcuOTgxMzUgLTEzLjE2Nzc2LDExLjU4NjE3IC0xMi43ODAyNCwxMS40NzQxOCAtMjEuODk4NjUsNi4zMjgwNyBsIC03LjkxODY3LC00LjQ2OTAyIDIuNTk0NzMsLTEzLjcwNDkyIGMgMi40OTM3NCwtMTMuMTcxNDggMi45MDIzMywtMTQuMDU1MjkgMTAuNDk3MDUsLTIyLjcwNTc5IDQuMzQ2MjcsLTQuOTUwNDcgNy45MDIzMSwtOS41NjY3NiA3LjkwMjMxLC0xMC4yNTg0IDAsLTEuNDc1NTkgLTE4LjMxMzM3LC0yMy44MDc5MyAtMjAuMDYxNjUsLTI0LjQ2NDMgLTAuNjU0MzMsLTAuMjQ1NjYgLTYuMzE3OTUsMi41MTEzMyAtMTIuNTg1ODMsNi4xMjY2NCBsIC0xMS4zOTYxNCw2LjU3MzI5IC0xMy4xMzEzMiwtMC40MTIzNCAtMTMuMTMxMzEsLTAuNDEyMzYgLTMuMjgwMywtOC43MzUzOSAtMy4yODAzMSwtOC43MzU0IDEwLjAwNjk2LC04LjE3NTE3IGMgMTAuODQxMzEsLTguODU2NzggMTIuNzE2MzUsLTkuNzAxNDggMjcuMjE3MDQsLTEyLjI2MTEzIGwgOS42NDI4NiwtMS43MDIxNCAwLC0xNi4xNjU1MyAwLC0xNi4xNjU1MyAtNy41LC0xLjQ3NzI2IGMgLTQuMTI1LC0wLjgxMjQ5IC05Ljg0MjUsLTEuODgxMSAtMTIuNzA1NTYsLTIuMzc0NjkgLTMuNDY0NjQsLTAuNTk3MyAtOC43NjIwMywtMy44NTQyOSAtMTUuODM5ODcsLTkuNzM4ODIgbCAtMTAuNjM0MzIsLTguODQxNCAzLjE3ODg1LC04LjUyODA2IDMuMTc4ODYsLTguNTI4MDUgMTMuNjA2MzgsLTAuNDA3MzYgMTMuNjA2MzcsLTAuNDA3MzUgMTAuOTU4NCw2LjQ3ODc4IGMgNi4wMjcxMiwzLjU2MzMzIDExLjM4NzQyLDYuNDQ4MDUgMTEuOTExNzgsNi40MTA0OCAxLjA3MjUzLC0wLjA3NjggMTkuMjU3NTEsLTIyLjE3MDk2IDIwLjAwNzIxLC0yNC4zMDgwNiAwLjI2NTMxLC0wLjc1NjMxIC0yLjY3ODE5LC01LjA2MzE2IC02LjU0MTEyLC05LjU3MDggLTkuMjM0MDUsLTEwLjc3NTE4IC04Ljk0Nzg5LC0xMC4xNzIwOSAtMTEuNzUxODQsLTI0Ljc2NzI0IGwgLTIuNDMyMzcsLTEyLjY2MTAyIDguMjMwNjYsLTQuOTAyOTcgOC4yMzA2NSwtNC45MDI5OCAxMC41OTI3Miw5LjA3NDQyIGMgOS45Njg4LDguNTM5OTMgMTAuODQ0NTgsOS43NzM3NSAxNC44NjksMjAuOTQ3ODMgMi43ODk4Niw3Ljc0NjI0IDQuOTc5MDcsMTEuNzg3MDYgNi4yOTgxLDExLjYyNSAxLjExMiwtMC4xMzY2MyA4LjI4OTY3LC0xLjMzNzU0IDE1Ljk1MDM4LC0yLjY2ODY5IGwgMTMuOTI4NTcsLTIuNDIwMjggMCwtMTIuMTg2NDEgYyAwLC0xMS43ODUyMSAwLjIxODU2LC0xMi41OTA5MyA2LjYzODg3LC0yNC40NzQxNiAzLjY1MTM5LC02Ljc1ODI3IDYuODM2NzgsLTEyLjUyNjcyIDcuMDc4NjUsLTEyLjgxODc4IDAuMjQxODcsLTAuMjkyMDYgNC42MTA2MywwLjI1NTk2IDkuNzA4MzQsMS4yMTc4MyAxMC4zNDQ0MSwxLjk1MTg2IDkuMjkyMTcsMC4zNDQ2IDEyLjM5NjI2LDE4LjkzNDUgMS41Mzc1MSw5LjIwNzkgMS40MTQzOCwxMC4xNTIzOCAtMi44NjU1LDIxLjk4MDM5IC0yLjQ1OTYyLDYuNzk3NDkgLTQuMjkxNzcsMTIuNDg4ODUgLTQuMDcxNDcsMTIuNjQ3NDYgNC43MTE3NywzLjM5MjI2IDI3LjEwMywxNS4xNzk1MyAyOC4xNTIwMiwxNC44MTk4OCAwLjc5ODI5LC0wLjI3MzY5IDQuODQ5NDMsLTQuNTgwMjMgOS4wMDI1NSwtOS41NzAwOCA2Ljk3NjEsLTguMzgxNjEgOC41MjI2MywtOS40MzggMjAuMzA5MzMsLTEzLjg3MjcyIGwgMTIuNzU4MjEsLTQuODAwMjUgNS4wODkyMyw1Ljg3ODY1IGMgMi43OTkwNywzLjIzMzI2IDUuNTM5MDQsNi42Mjg5OSA2LjA4ODgxLDcuNTQ2MDcgMC41NDk3NywwLjkxNzA5IC0yLjA0NDU1LDYuNzY0NDIgLTUuNzY1MTgsMTIuOTk0MDcgLTYuMTk0MTksMTAuMzcxMjYgLTcuNjkxNTYsMTEuODY4ODkgLTE3Ljc1MjE5LDE3Ljc1NTIyIC02LjA0MzA3LDMuNTM1NzEgLTExLjAwMjMsNy4wMDcyNCAtMTEuMDIwNTEsNy43MTQ1MSAtMC4wMTgzLDAuNzA3MjYgMi4zMTU2Myw3LjYxNzk4IDUuMTg2MzMsMTUuMzU3MTQgMy42MTg5NSw5Ljc1NjM4IDUuOTE4NzcsMTQuMDcwNjkgNy41LDE0LjA2OTUyIDEuMjU0MywtOS4zZS00IDYuOTcwNywtMC44OTYxNCAxMi43MDMxMSwtMS45ODkzNiAxMC40MjAwNiwtMS45ODcyIDEwLjQyNTc3LC0xLjk4NjU0IDIzLjU3MTQzLDIuNzAxNzYgbCAxMy4xNDg4Niw0LjY4OTQ0IDAuNDE5NTQsOS4zMTY3OSAwLjQxOTU0LDkuMzE2OCAtOC4xNTg4NywzLjA1MjYxIGMgLTE1Ljg5MjA3LDUuOTQ1OTkgLTE4Ljg3NDM3LDYuMzI2ODkgLTMyLjA1NjgxLDQuMDk0MiBsIC0xMi4yMzM3NiwtMi4wNzIgLTUuMjY2MjQsMTQuNTYxMjkgYyAtMi44OTY0NSw4LjAwODcxIC01LjI1NTk1LDE1LjEyIC01LjI0MzMzLDE1LjgwMjg3IDAuMDEyOCwwLjY4Mjg1IDQuOTk0NzUsMy45OTYxOCAxMS4wNzE0Myw3LjM2MjkzIDEwLjUwMDExLDUuODE3NTQgMTEuMzc5MjQsNi43MDE0NCAxNy43MTE5NywxNy44MDgyOCBsIDYuNjYzNDcsMTEuNjg2OTMgLTIuNzE4MSwzLjYyMDI5IGMgLTEuNDk0OTYsMS45OTExNSAtNC4xNzIwOSw1LjMzNTExIC01Ljk0OTE5LDcuNDMxMDIgbCAtMy4yMzEwOCwzLjgxMDc1IC0xMi44NTE2NSwtNC44NTc4MiBjIC0xMC41Nzc2MSwtMy45OTgyNSAtMTMuNzM3MzUsLTUuOTMyMzcgLTE3Ljg1NzE0LC0xMC45MzA1OCAtMi43NTMwMywtMy4zNDAwMyAtNi42MTI2NCwtNy44MjE1NyAtOC41NzY5MywtOS45NTkgbCAtMy41NzE0MywtMy44ODYyMyAtMTMuNTcxNDIsNy45MjU4MyBjIC03LjQ2NDI5LDQuMzU5MiAtMTMuNzQ5MTksOC4wOTY4NCAtMTMuOTY2NDYsOC4zMDU4NSAtMC4yMTcyNywwLjIwOTAzIDEuNjAzNzYsNS43NzM3IDQuMDQ2NzMsMTIuMzY1OTYgNC4zMjQ5LDExLjY3MDYyIDQuMzk4MDgsMTIuMjY3NzkgMi43ODIyMSwyMi43MDAyMiAtMi42NjgwMywxNy4yMjUzMiAtMi40MDI4OCwxNi43MDQ4NSAtOS4wNDc1MSwxNy43NjEwMiAtMy4yNzY4LDAuNTIwODYgLTcuMjkxMjUsMS4yNzkwMyAtOC45MjA5NywxLjY4NDgzIC0xLjYyOTczLDAuNDA1OCAtMy42MTk3NSwtMC4xMDcxNCAtNC40MjIyNSwtMS4xMzk3MyBsIDAsMCB6IG0gNS43NTYyMiwtOTEuMjEwOTEgYyA0MC42MzU2LC0xNS4yMDM3MSA0MC43MjA0NywtNzQuNjMyMzUgMC4xMjgyOCwtODkuODY2NDcgLTExLjYzNTEsLTQuMzY2NjIgLTI4LjE5ODAzLC0zLjc3Njc3IC0zOC4zNzYwMywxLjM2NjY5IC0zNy4yNzI2LDE4LjgzNTcyIC0zNS41MDEzMyw3Mi4wOTI0NCAyLjkyMzE1LDg3Ljg5MDQyIDEwLjg1MTY3LDQuNDYxNiAyNC40MDM2OCw0LjY5NTM3IDM1LjMyNDU0LDAuNjA5MzYgbCA2ZS01LDAgeiIKICAgICAgIGlkPSJwYXRoNDU4NCIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGg0NjE3KSIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTpub25lIgogICAgICAgZD0ibSAxMzcuNDA5MTUsMjU0LjgzMjUgYyAtMS4yNjM4OCwtMy4xNTg3NiAtMi4zMDY3NSwtOS43NDgwNSAtMi4zMTc0OCwtMTQuNjQyODYgLTAuMDMsLTEzLjY4MjQ5IC0wLjY2NzkzLC0xNC45MzI1MyAtOC40NzUwNywtMTYuNjA2ODYgLTMuNzI4MjIsLTAuNzk5NTcgLTEwLjg5NTY5LC0xLjg3MDk0IC0xNS45Mjc3MSwtMi4zODA4NiBsIC05LjE0OTE0LC0wLjkyNzExIC00LjAyNzc2NywxMC42MjkxNiBjIC0zLjkwNDkwOSwxMC4zMDQ5NCAtOS40MjE3NDIsMTguMjQzMTUgLTEyLjY3ODQ3MywxOC4yNDMxNSAtMS43MzY2MDYsMCAtMTcuMzg0NDQ3LC04LjY5ODg0IC0yMS42ODA3OSwtMTIuMDUyNjQgLTQuMjAxMzEsLTMuMjc5NjEgLTEuOTMxNjY3LC0xMC4xOTMyMyA2Ljk4MDU1OSwtMjEuMjYzNjMgbCA3Ljg0NTA4NCwtOS43NDQ4NCAtNi4zODU4MjQsLTguMTEyMyBjIC0zLjUxMjIwMywtNC40NjE3NyAtOC4yNDU5MjMsLTEwLjMwODU2IC0xMC41MTkzNzYsLTEyLjk5Mjg3IGwgLTQuMTMzNTUyLC00Ljg4MDU3IC0xMi4zMjkyMTQsNi42NjYyOCBjIC02Ljc4MTA2OCwzLjY2NjQ2IC0xMy42NTY2MDEsNi42NjYyOSAtMTUuMjc4OTY0LDYuNjY2MjkgLTMuMjcxNzMxLDAgLTguMzM4MDgyLC05LjU1MTEyIC0xMS42MTI0MjUsLTIxLjg5MTgyIC0xLjc2NzQ3LC02LjY2MTQyIC0xLjcxMDI5NywtNi45ODExMiAxLjcxMDM1OSwtOS41NjM1NSAxLjk0NjQyNiwtMS40Njk0NiA5LjE2Mzk1NiwtMy44MDk0NiAxNi4wMzg5NTYsLTUuMTk5OTkgbCAxMi41LC0yLjUyODIzIDAsLTE2LjcwNzA0IDAsLTE2LjcwNzA0IC0xMC4zNTcxNDMsLTEuNzg4MTQgYyAtNS42OTY0MjksLTAuOTgzNDggLTEyLjg0MzU4MSwtMy4wMjIxMyAtMTUuODgyNTYxLC00LjUzMDM0IC01LjAyMjUxMywtMi40OTI2IC01LjQ1ODQxNSwtMy4xNTUwNyAtNC43ODkyNTksLTcuMjc4NiAwLjQwNDg4NywtMi40OTUwMyAyLjU0Nzk1OCwtOS4xOTMzMjkgNC43NjIzOCwtMTQuODg1MTE3IDMuNTkyNTU3LC05LjIzNDA0NiA0LjQzNDQ4OCwtMTAuMzQ4NzA2IDcuODE2NjM5LC0xMC4zNDg3MDYgMi4wODQ3MjgsMCA5LjEwMDM0NSwzLjAwODQxIDE1LjU5MDI2LDYuNjg1MzU3IGwgMTEuNzk5ODQ1LDYuNjg1MzU2IDQuMTY2NjM5LC00Ljg5OTY0MiBjIDkuMDg4MTM0LC0xMC42ODY5MzUgMTUuNDY0NjI4LC0xOS41NDU0NzEgMTUuNDY0NjI4LC0yMS40ODQyMTQgMCwtMS4xMjE1NzcgLTIuNjI0MDQsLTUuMjE0NjgzIC01LjgzMTIwMSwtOS4wOTU3OSAtNi43OTQ3LC04LjIyMjUyNyAtOS44ODMwODQsLTEzLjc1OTQ1OSAtOS44ODMwODQsLTE3LjcxODYzOSAwLC0zLjIxMDEzMiAxOC45NzQ3NzUsLTE1Ljg4NjcxNCAyMy43Nzk4MiwtMTUuODg2NzE0IDMuNjI1NTQ4LDAgNy44OTU0NDUsNS44MjczOTMgMTIuNjgyNjUzLDE3LjMwODc5OSAyLjA5MTM4NCw1LjAxNTg3NSA0LjM0OTY5MSw5LjY5NDQzIDUuMDE4NDYxLDEwLjM5Njc4OCAwLjcxMTQyLDAuNzQ3MTQ1IDcuNzY5NTEsMC4yMjI2MjUgMTcuMDEwMzcsLTEuMjY0MTI0IGwgMTUuNzk0NDEsLTIuNTQxMTM5IDAsLTExLjkyMTI1MiBjIDAsLTcuNjIxNjkzIDAuODI4NzksLTEzLjk5MjYxNCAyLjI5Nzk3LC0xNy42NjQ0NDggMi4xNTQ1MiwtNS4zODQ2NjQgMi42NjAwMSwtNS43NDMxOTUgOC4wOTcyNywtNS43NDMxOTUgMy4xODk2MSwwIDkuODY5ODEsMC43MDg4NDkgMTQuODQ0ODksMS41NzUyMjEgbCA5LjA0NTU4LDEuNTc1MjIyIDAsNi45MjI0NjEgYyAwLDMuODA3MzU0IC0xLjY1NDExLDEyLjE1ODY3MSAtMy42NzU4MSwxOC41NTg0ODQgLTIuMDIxNyw2LjM5OTgxMyAtMy40NjgxMywxMS44MjkxOTkgLTMuMjE0MjksMTIuMDY1MzAyIDAuMjUzODUsMC4yMzYxMDMgNi44MjUxMiwzLjgyMDA5NSAxNC42MDI4Myw3Ljk2NDQzIGwgMTQuMTQxMjksNy41MzUxNTEgOC43MTU4NiwtOS40MzUxMDggYyA4LjIzNjMyLC04LjkxNjAyNSAxNS4zNjIyLC0xMy45MDQwMiAxOS44NjMzMiwtMTMuOTA0MDIgMS43ODUyMiwwIDE4LjEzODIzLDE4LjAyMDMzMiAxOC4xMzgyMywxOS45ODc1NjggMCwyLjY1NDEwNiAtMTAuNTE1NjMsMTIuNzA1OTMyIC0xOC45NDM3NCwxOC4xMDgyMjMgLTkuMTAyNDYsNS44MzQ1MjkgLTkuODIxMjcsNi42NTI2ODMgLTguOTM3NzYsMTAuMTcyOSAxLjU3MjQyLDYuMjY0OTc2IDkuNDA2MSwyNS45MDc3NTYgMTAuNjM1MTUsMjYuNjY3MzQ2IDAuNjI1NzgsMC4zODY3NSA2LjU1NDk3LC0wLjAyMTYgMTMuMTc1OTcsLTAuOTA3NTEgOS45OTY4MSwtMS4zMzc1NiAxMy4xMTg5MywtMS4yNTA0NCAxOC40MTE0MywwLjUxMzczIGwgNi4zNzMyNCwyLjEyNDQxIDAsMTMuMzg5NTYgMCwxMy4zODk1NiAtNi40Mjg1NywxLjg5NDI2IGMgLTUuMTc4NTcsMS41MjU5MyAtOC44NzMyOSwxLjU2NjIgLTE5LjAwMTQ1LDAuMjA3MTIgLTcuNDE4MSwtMC45OTU0MiAtMTMuMDU1ODIsLTEuMTYwNTkgLTEzLjc1MDg0LC0wLjQwMjg2IC0xLjk1Njk4LDIuMTMzNiAtMTAuMzc2NiwyOC45NzQ1NiAtOS41MjI0MSwzMC4zNTY2NSAwLjQzNzAxLDAuNzA3MTEgNS4xOTY3MSwzLjkwMDkxIDEwLjU3NzEsNy4wOTczNCA2LjI1MzgsMy43MTUzMiAxMS4xNzk2LDcuOTIyODMgMTMuNjU1NTgsMTEuNjY0MjkgbCAzLjg3MzA3LDUuODUyNiAtMi44NjI4OCwzLjYzOTU2IGMgLTQuMzg4NjQsNS41NzkyNyAtMTIuNDI0NjYsMTQuMzEyMTUgLTE0LjE1Mjk3LDE1LjM4MDMxIC0zLjI5OTgzLDIuMDM5NCAtMTIuNjkzMDUsLTMuODEzNDMgLTIxLjY3MjM1LC0xMy41MDM4NiBsIC05LjI4NTcxLC0xMC4wMjExMSAtMTMuNTcxNDMsOC4xMzExMyBjIC03LjQ2NDI4LDQuNDcyMTEgLTEzLjc5ODUxLDguMzExOTMgLTE0LjA3NjA2LDguNTMyOTEgLTAuMjc3NTUsMC4yMjEgMS4yMDYwMiw1LjUzODQ0IDMuMjk2ODIsMTEuODE2NTQgMi41NTUzNCw3LjY3MyAzLjY1NzMzLDEzLjY3MzM1IDMuMzYxNzgsMTguMzA0OSBsIC0wLjQzOTY4LDYuODkwMTUgLTcuODU3MTQsMS42NDc5NSBjIC00LjMyMTQzLDAuOTA2MzkgLTEwLjg0MDkyLDEuNzA5OTYgLTE0LjQ4Nzc1LDEuNzg1NzIgLTYuNDUwNTIsMC4xMzQgLTYuNjkzMDEsLTAuMDE4MyAtOC45Mjg1NywtNS42MDU0NCB6IG0gMTkuNjEwMzYsLTczLjM2NTIgYyAzNC4wNTQ0NiwtMTYuNjYxMjkgMzUuOTIwNjYsLTY3LjEzMDI4IDMuMTczODQsLTg1LjgzMjQ2NSAtMTIuNTgwNzMsLTcuMTg1MDM4IC0zMS4yNDg4MywtOC4xMTY4ODcgLTQ0LjYxODg0LC0yLjIyNzIyMiAtOC4yMzI1NiwzLjYyNjU1IC0xOC41NDgwMTYsMTMuNTA0MDE3IC0yMy4wOTExOCwyMi4xMTA3MjcgLTMuNDE2Nzc2LDYuNDcyODUgLTMuODAwNzIxLDguNzE1NSAtMy44MDA3MjEsMjIuMjAwMjEgMCwxMi45MDM0NCAwLjQ1NzkxMiwxNS44NTc2MSAzLjI3NjE2LDIxLjEzNTggNi45ODQ1NTIsMTMuMDgxMTIgMTguODI0MDgxLDIyLjQ1Nzk1IDMyLjc4OTQ0MSwyNS45NjkwNSA5LjMxMzM3LDIuMzQxNTEgMjMuNjc5NDcsMC44NDc0OCAzMi4yNzEzLC0zLjM1NjEgeiIKICAgICAgIGlkPSJwYXRoMjk4NSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzUuNTYyMTYsMjc4LjQ2MDQpIiAvPgogIDwvZz4KPC9zdmc+Cg=="); background-size: 15px 15px; } #jsxc_buddylist .jsxc_name { padding-right: 30px; } #jsxc_buddylist .jsxc_unreadMsg .jsxc_name { padding-right: 0px; } #jsxc_buddylist .jsxc_oneway { opacity: 0.7; } #jsxc_buddylist .jsxc_right { float: right; margin-right: 6px; } #jsxc_buddylist .jsxc_right div { font-weight: bold; text-align: center; font-size: 13px; line-height: 20px; color: #fff; } #jsxc_buddylist .jsxc_right div:hover { opacity: 1; } #jsxc_buddylist .jsxc_unread { margin-right: 30px; margin-top: 6px; } #jsxc_buddylist .jsxc_control { position: absolute; width: 30px; height: 30px; top: 0; right: 0; cursor: pointer; margin-right: 14px; } #jsxc_buddylist .jsxc_control:after { content: '▾'; position: absolute; left: 50%; top: 15px; width: 16px; height: 16px; line-height: 16px; text-align: center; margin-left: -8px; margin-top: -8px; border-radius: 8px; color: #b3b3b3; background-color: rgba(102, 102, 102, 0.5); opacity: 0.6; -webkit-transition: -webkit-transform 0.5s; transition: transform 0.5s; } #jsxc_buddylist .jsxc_control:hover:after { color: #fff; opacity: 1; } #jsxc_buddylist .jsxc_options { height: 20px; float: left; border-radius: 2px; background-color: rgba(102, 102, 102, 0.5); } #jsxc_buddylist .jsxc_options > div { height: 20px; width: 20px; float: left; margin-right: 0 1px; background-repeat: no-repeat; background-position: center center; opacity: 0.6; cursor: pointer; } #jsxc_buddylist .jsxc_options > div:hover { opacity: 1; } #jsxc_buddylist .jsxc_chaticon { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMjUiCiAgIGhlaWdodD0iMjUiCiAgIGlkPSJzdmcyIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlua3NjYXBlOnZlcnNpb249IjAuNDgrZGV2ZWwgciIKICAgdmlld0JveD0iMCAwIDI1IDI1LjAwMDAwMSIKICAgc29kaXBvZGk6ZG9jbmFtZT0ic3BlZWNoX2JhbGxvb25fd2hpdGUuc3ZnIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzNCIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iMjIuNCIKICAgICBpbmtzY2FwZTpjeD0iMjUuMTg2NjI4IgogICAgIGlua3NjYXBlOmN5PSIxNC40Nzk5OTkiCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9InB4IgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgZml0LW1hcmdpbi10b3A9IjAiCiAgICAgZml0LW1hcmdpbi1sZWZ0PSIwIgogICAgIGZpdC1tYXJnaW4tcmlnaHQ9IjAiCiAgICAgZml0LW1hcmdpbi1ib3R0b209IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODU1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjY1IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTciPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMjguMjQyMTksLTMyMC42Njc5OCkiPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiMwMDAwMDA7c3Ryb2tlLXdpZHRoOjA7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGQ9Im0gMjQwLjc3NjI3LDMyNC4wMjU3OCBhIDEyLjQ4OTMwOSw3LjkyNTQ0MjYgMCAwIDAgLTEyLjQ4OTQ0LDcuOTI1MzggMTIuNDg5MzA5LDcuOTI1NDQyNiAwIDAgMCA1LjI2MTQ2LDYuNDU2MzcgYyAtMC4xNzg2MiwxLjkxMTk2IC0xLjA2MTE5LDMuOTUzNjMgLTMuMTQ2MDQsNC42NDQzNyAyLjU0MTIxLC0wLjExNDQ0IDUuNjAwMjYsLTEuOTMwNTcgNy40NzIwOSwtMy40MDEzNyBhIDEyLjQ4OTMwOSw3LjkyNTQ0MjYgMCAwIDAgMi45MDE5MywwLjIyNjE2IDEyLjQ4OTMwOSw3LjkyNTQ0MjYgMCAwIDAgMTIuNDg5MjgsLTcuOTI1NTMgMTIuNDg5MzA5LDcuOTI1NDQyNiAwIDAgMCAtMTIuNDg5MjgsLTcuOTI1MzggeiIKICAgICAgIGlkPSJwYXRoNDEwMSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPC9nPgo8L3N2Zz4K"); background-size: 15px 15px; } #jsxc_buddylist .jsxc_videoicon { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iNTM1LjAwNDU4IgogICBoZWlnaHQ9IjUxMC40MzY4IgogICBpZD0ic3ZnMzg5NiIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4K2RldmVsIHIiCiAgIHNvZGlwb2RpOmRvY25hbWU9ImNhbWVyYV9pY29uX3doaXRlLnN2ZyI+CiAgPGRlZnMKICAgICBpZD0iZGVmczM4OTgiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIGlkPSJiYXNlIgogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAuMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnpvb209IjAuOTg5OTQ5NDkiCiAgICAgaW5rc2NhcGU6Y3g9IjM1My45MTkzNCIKICAgICBpbmtzY2FwZTpjeT0iMjMzLjg0NTYiCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9InB4IgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgZml0LW1hcmdpbi10b3A9IjAiCiAgICAgZml0LW1hcmdpbi1sZWZ0PSIwIgogICAgIGZpdC1tYXJnaW4tcmlnaHQ9IjAiCiAgICAgZml0LW1hcmdpbi1ib3R0b209IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODU1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjY1IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTM5MDEiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjcxNDI3NzEsLTcyLjM2MjE3NykiPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNjE3MjY5NDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgaWQ9InJlY3QzOTA0IgogICAgICAgd2lkdGg9IjM3OC4zNzI2OCIKICAgICAgIGhlaWdodD0iMzAyLjY1NTgyIgogICAgICAgeD0iMTAuOTExOTIyIgogICAgICAgeT0iMTgyLjQwNjM0IiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOm5vbmUiCiAgICAgICBkPSJtIDM2MS42NTE0OCwzMTMuNTE3NjggMTc3LjE2MDc0LC0xMzEuNzg1MTYgMCwzMDIuMjI5OTkgLTE3OS44Mzg4NCwtMTMzLjc3NzM0IHoiCiAgICAgICBpZD0icGF0aDM5MDYiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogIDwvZz4KPC9zdmc+Cg=="); background-size: 13px 13px; } #jsxc_buddylist .jsxc_vcardicon { font-size: 15px; line-height: 20px; text-align: center; color: #fff; font-weight: bold; font-family: serif; } #jsxc_buddylist li.jsxc_expand .jsxc_control:after { -webkit-transform: rotate(180deg); -ms-transform: rotate(180deg); transform: rotate(180deg); } #jsxc_buddylist.jsxc_hideOffline .jsxc_offline { display: none; } .jsxc_online { border-left: 4px solid #00bfff !important; } .jsxc_chat { border-left: 4px solid #00bfff !important; } .jsxc_away { border-left: 4px solid #ffa500 !important; } .jsxc_xa { border-left: 4px solid #ffa500 !important; } .jsxc_dnd { border-left: 4px solid #f00 !important; } .jsxc_offline { border-left: 4px solid #666666 !important; } .jsxc_hidden { display: none; } .jsxc_invalid { border: 2px solid #f00 !important; } .jsxc_emoticon { display: inline-block; width: 19px; height: 19px; background-size: 19px 19px !important; border: 0; } .jsxc_angel { background: url("data:image/png;base64,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"); } .jsxc_angry { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAB10RVh0Q29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAAAGHRFWHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuMjBZn3ZRAAAGvElEQVRIS+1Wf0zUZRh/OTkgIQkDio1IYSVCJIRUorfLH0mOFBlUa9k0oEaRTSukHyysGYpHTKZrMwppzdVcv3ZmFFKkkHp1kAdCJ5d5XoLn185vXbduR9Cn53nvTm1JaPVn7/bZ8/2+7/M+n+d53uf9IcT/bfwMTKOhtRqNeD9lmujPvUW4dLOFKzVZ9HMfjxFY5z9rmdpQYSzICxlr2TYTdksJ1BO18J5pgu/Ma/AOb4LLWooPmtJwb37IWHi4MBJz5r9h19Lk2iXzxYhp7zyop1rg/fkQfO6DGP3FD9/PX8p/H3+T9Jx+E+a9OixZIEZ4LoFtXFa7gtLXurFKA+fRcrjP7IbHtQfes0b41N0Y/Wm3lPzvOUP4cY9fMkhPsT2KhmoNKFOtxHrFpTJrmXTrywKOI0UUaTNFsoNS2wzfjzvgUwgkPacI1K8ONxNapHQ7d8Ad6HcPFmNXowiSX1LktVVrBcwdU6HYN0H9wQDfaQNGT2+W8J0ywDNsgPtkPVSHAa4TBji/N0A5US+/ud99cjPp1MHTG4OmFwUCaf/bwDP188TIvo8EejpnYWiwCurxKvhOVmF0eJ2U7uPr4CIox6oknN89A8egH6wf7GcdtXcWvD0CxYvlmo9fcFy9re8Q6WcC1oPpUKwlRFQKu3kFvN+XwHO8DOqxMjipiodoTMqBEjhI2vtJDpQSHpJyyFqGIXM61K8FBj4WCA+T1X7RNq0gT4xZOwTs+wVc5qnw2JbBayvAvYvTMdSTD/fRAqjfFsA5UEiEyzF0ZDmcffRN0mEpgPXQMlQ9kU61UUDbbhlsB2Pg6BJwmgRtNTE23j5f22SggiJF9nK0l3A0A16rDvq0LOhvjYe183a4+nUYssyF4xsdnJZ5cPXqoPTNQ0/7bcjJnAJ9brTst399E/o+p2i/ELDtE2h5Ra41HzJ/biF0+vS1CQwdEPCY/cQ+SyjcvdOhnaThSYiKDEHN2mvh6E6VUA6nQemegZeeuAGJsdFSZ5EuEurh6bB3hkpiXraeTwVMnwgETrg/E/MxyNG6KC2+w364u/lfg4Q46a2Efo4Wtq442A/FQvkqTi7J7cnJ0ISEyPFVhZPg7tHIzDGxea/AASLuahVIuk70/yViXY5wMWkwWpbKQX8GFs2PhLgqSWLVijD0tGkofRoa10A1a5CdRdEGxhvo0GE7xzrPEzNpxx6B7Ezh+gux/lbh8lCUXP4cLU+2EymvT90LEQhLr0NoaiW2N4bICDiaYOHUrItGREYjImY+Iis4GC2nmSP+W2K+ZS5MMUfKXjMxk9xdPBtl5dMlqdxugerninVQAS0t1qNuPa0/pZjHLO3n08znwj5a44ummhfeTUY4Yk5xkJRl0BAbk4TkFBOwc0ys0C7g7wv1ZGEFioojbv9wnOLiUjdu828lNszbwEwTXt0gULNGwPgG9VGkkiiw9kweBO8IPnw2PE/6T/r12ZGgA1s3jrOdeHPfv1SMBVPVRR4W5M9CW1sbOjo60NDQgNWPl6OivAgVDy8k5BLmoLxEh/KyfBorQXV1NXbt2gWz2YzKp9dg63p/JvhAKlwy/gEi+BLveNfv6ZrSEFgsFvzTNjo6iuLlc2WRWqiiAw+EcS+KzEV6McLpKV8RCpvNBkVRzsHlckFVVXg8Hni93nNwu93gMQbrO51O+b1q5X1yae5eOMElEXCntuZpgfde16K0dCXYKBNxBNx8Pp8k5L4guC84zjo8bjQayfko1D0rTz1+jUzYAg+BUDRtuQZL7kxAYWE+Ghsb0d7eDqvVKqMJkrFjDocDJpMJO3fuREVFBfIWpqJ69dVoNkzlY5JfIZf0EGDP5NOnpjIC1q+yMHBgDlrfzkJzfRrqnrsBVY9NQ8Wq61C+MgkVpdej8vFk1L80g7J0s/8i6Z2L7bVJl/30CaZEPvby7pg00rWHrjq69pSBYqiDRfSqvAfOI/fQdVgMR2+RlNynWoswsH8BVXDcP3vsabVaTVRUVFhMTMyUhISEvJiYSFPhXeG/v7M9DY6eu6AMPkiPwMcIq+mbLvzeYhhbcvFA4bW/x159pck/J2YK22BbEy7u5MmTtRkZGUuzs7M35OTktBA+JLQRvqD+7sTERAfZO5s+I+zX3Nma3xjpM8J/jY2NPstjrMO6gTk8t4VtsU22Pa4D4eHhoampqXpSfoombSG8FSD/hORnAaP7SXYSugLgb+5jQtZhXSbluVvYFttk2xNGrqHKIsVJ0dHREbEUTnx8fBylj4JKTE5KSroxJSVlJiEtgJncx2Osw7o8h+eyDbZ1sfYHsWOgkP9IpnYAAAAASUVORK5CYII="); } .jsxc_smile { background: url("data:image/png;base64,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"); } .jsxc_grin { background: url("data:image/png;base64,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"); } .jsxc_sad { background: url("data:image/png;base64,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"); } .jsxc_wink { background: url("data:image/png;base64,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"); } .jsxc_tonguesmile { background: url("data:image/png;base64,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"); } .jsxc_surpised { background: url("../img/emotions/surpised.png"); } .jsxc_kiss { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAB10RVh0Q29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAAAGHRFWHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuMjBZn3ZRAAAG2ElEQVRIS+1WbVCUVRS+rMAqUrQEjCgRypgoEmtA4gqzuVrI+IEr60dZjaONY5o/1HTtS4sp1CA0LScjEXOaMafSQVFUDBUU0RUFlVklRtxcpdV1c9tpZ0l8OufuLowlaR8/e2eeufe959zz3HPuuedeIf7/uo9AHIkWKhTiu/g4cV7zlLBnpgp7wgBxnsdYRmCd/+xTBwWKspysgI7STwajtWEWHJfz4b5eDM/1z+G+ugp282zsKB6CqeMCOpRKUUbM6n/DHkST87NHifa6AxlwXCuF+9ZxeJy1uP2LF55bR+W/h/vUun7aAtOBTGTrRDvPJbCNv/X1ovDtXWlUoO3CXDiv74LLXg73zTJ4HLtw++ddsuV/13XCjXJvyyA9W/OrKHpbAYrUXmLt9aDMQUy6/gMBy7lc8rSEPNkMp3UT3D+VwGPbDM+NzXBdI9C442oJoRS2y5tk3+kbd140YPvHwk/+QJ7nGxcKmKrCYWtdBcePBbCez8PMl/VYMHcS3NYP4bpaAOeVQjgsBbBfLkD9sbcw44XJMC6eIsecV1hnNVyNKhS/J+AL+186rtZmiPbDuwXqq5NhvWiE45IR61frUVhYiLy8PHz75XTYLy2FrcUo0fbDMqx4U4+ioiIYjUZUls2S46zjaEyGu17A8Jzc8+4TjrN37zYiPShgrk2EzTwLzkuzYZg4DAaDQWLBnFS0URZbSSbbplnQjVJ3yo0Lh8PSxPJXYDUlwnFSoGmPgDJYZvs9v7icLNFhrhJoPSJgN4XD1TwR7uYcREX2RnR0tETm8Ei0NemJcBKs5yah9fREhPbuJWVRUVHIye5HuZFDx24immtVsNQItNUJOmqio7tzvrC4gBKKFHmVtxsJF5LgNmfyHnUicVAIrA0jYTmdibaGDJir0++SazVhcrz15FCc/Z68PSTQfFig9CNpg4vM3V8AVZ+z+wWsxwRcJi+xpyEQzsb+UAR0ESclKGE5lSBhOzMELUcG3kU8JrM3HGf6o7U6UBLzttXvE6irEPBVuLuJuQyyt3YKi+cMg87wiV70r0B0ZECnce2IYDTXRKL1eARsJyLlloT07JLP1PeAs14hI8fEpgMCx4i4Zq9A7GPi/J881qQq7Gu+GIFPt2ZjbUkmNiePx7aBWlp5MPRjH0JMTIzE/NkhqN+voPApYKtVwGFSQKd5pFO+YXmwXHxLdRcxk1aVC6Sohf1PxGnqIHt5XCr2xQ7zIiYZFX2H4uv+GiwyDoVOp4NWq8XWz3pID9gbf+Ksf1flk4+AuaLLWw4ze/yXxHzLbHlyHMri07Fh0zQUPj0D+6KHYnc/NSp3R2HR/FisWBolSeVx82U/Z6yFEmjJ3HgUrw6Xi2FZQ2VXmLkuHKY9vmeoeeOLnp6GCvJ2zaLnsWNVOvb1SUTxloGdhtiYJKQEZAJORCa20Sngvp+Q9WRi+ZKKPa7c2U1ycaqPnjwQ5Y+nSE/3RCdhd99kmCrD5XFgo7xvkqjWS8TkfrDcn0hMyP8M/wLWr+zmOPHhfn6C6CgseRbL1qnxWuIELE/ORUuNd8/8+8mJw8T8z54zeGFMwEfGv/9chI5949Ojvj67+wIi+BKvImVe6da1AmnJlBjbvURcVBh/9JYJ/CFmYvaaF7FyiYAu3avfQBnteyB0e1Gox2hFO0/ksO7fIpCVKTB+lMCGd2jPaFEcYibz77P/2FTtIJ1CgZnT6dgkCbw5j3R9WzN+9H0uCd9y8le8TqXucDCVw54wHwqGiRJjY57AnKnehWjJE51GYEwG9UcIaNKopf7sF0mPyJsOBsriw1j9huKBrkXm9j0EqOTVPE7oj+bjsbDVR8LVEEoFI1B6zZ527a0CdZVUWL4Ph/loDKwnB8iy+dW6cC6T/Ap5oIcAk8unz4ol5PGJYWg+OVJeDI5zI+FsyoC9MR3WU6mw1Kei5dRwmI9rqPXq2M6yfCQ25sf+7aePPwHkYy/rmR7tNeWJsDTkwNZkgONiLr0qp6Dt3BS6Fg2wNObKlscc5lw0HdFRBkf+s8deUFCQIjQ0NFilUj1M92yWStW7Tj9WeWfbxiHk5VjYLr5Ej8B5hAXUpwu/0YCyUg1m6PvciXj0oTrvHNXDbINt3fexFxISEpSUlDQhJSXl/bS0tFLCTsJ+wiEaP0WXhIXs3UwcFPwrXSq/MRIHKX+NiAi7yTLWYV3fHJ5byrbYJtvudgFKpTIwISFBS8qLadJawlYfeQW1B31Gj1BbTajxgfs8xoSsw7pMynPXsi22ybbv67mCMosUe4SFhfWMIHfoSRNJ4SOnYgbExsY+ER8fP5gwxIfBPMYy1mFdnsNz2Qbbutf3O/mFJW1ONGIpAAAAAElFTkSuQmCC"); } .jsxc_sunglassess { background: url("data:image/png;base64,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"); } .jsxc_crysad { background: url("data:image/png;base64,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"); } .jsxc_doubt { background: url("data:image/png;base64,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"); } .jsxc_zip { background: url("data:image/png;base64,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"); } .jsxc_thumbsup { background: url("data:image/png;base64,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"); } .jsxc_thumbsdown { background: url("data:image/png;base64,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"); } .jsxc_beer { background: url("data:image/png;base64,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"); } .jsxc_devil { background: url("data:image/png;base64,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"); } .jsxc_kissing { background: url("data:image/png;base64,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"); } .jsxc_rose { background: url("data:image/png;base64,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"); } .jsxc_music { background: url("data:image/png;base64,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"); } .jsxc_love { background: url("data:image/png;base64,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"); } .jsxc_tired { background: url("data:image/png;base64,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"); } .jsxc_surprised { background: url("data:image/png;base64,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"); } #jsxc_roster { position: fixed; top: 40px; bottom: 0; right: 0; overflow: visible; border-left: 24px solid #999999; z-index: 80; margin-left: 10px; box-shadow: 0px 0px 7px inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; background-color: #333333; } #jsxc_roster a { cursor: pointer; } #jsxc_roster .slimScrollDiv { left: -4px; margin-bottom: 30px; z-index: 40; } #jsxc_roster .jsxc_wait { position: absolute; top: 0; left: 0; bottom: 0; width: 160px; padding: 20px; background-color: #fff; z-index: 60; } #jsxc_roster .jsxc_wait img { padding: 5px; } #jsxc_roster .jsxc_wait h3 { margin-bottom: 5px; font-size: 1.13em; font-weight: bold; } #jsxc_roster input { position: absolute; top: 50%; left: 31px; width: 157px; height: 18px; margin-top: -11px; padding: 2px; border: 0; background-image: none; background-color: #fff; border-radius: 3px; box-shadow: inner 0 0 5px #666666; outline: none; } #jsxc_roster p { color: gray; padding: 10px; } #jsxc_roster p a { color: #b3b3b3; text-decoration: underline; } #jsxc_roster .jsxc_avatar { position: relative; cursor: pointer; } #jsxc_roster .jsxc_avatar img { cursor: pointer; } #jsxc_roster .jsxc_expand input { left: 51px; width: 137px; } #jsxc_roster.jsxc_noConnection .slimScrollDiv { display: none; } #jsxc_roster.jsxc_state_hidden #jsxc_toggleRoster:before { -webkit-transform: rotate(0deg); -ms-transform: rotate(0deg); transform: rotate(0deg); } #jsxc_toggleRoster { width: 34px; height: 100%; position: absolute; left: -34px !important; top: 0; z-index: 110; background-color: transparent; cursor: pointer; display: table; } #jsxc_toggleRoster:hover { background-color: rgba(153, 153, 153, 0.5); } #jsxc_toggleRoster:before { content: ''; position: absolute; display: block; width: 0; top: 50%; right: 10px; border-style: solid; border-width: 6px 4px 6px 0; border-color: transparent #333333; -webkit-transform: rotate(180deg); -ms-transform: rotate(180deg); transform: rotate(180deg); } #jsxc_roster > .jsxc_bottom { position: absolute; bottom: 0; height: 30px; width: 200px; border-left: 4px solid #999999; border-top: 1px solid gray; padding-left: 0; background-color: #1a1a1a; color: gray; cursor: pointer; line-height: 30px; z-index: 50; } #jsxc_roster > .jsxc_bottom ul { width: 190px; position: absolute; bottom: 30px; left: 0; display: none; border-top: 1px solid gray; padding-left: 10px; background-color: #1a1a1a; margin: 0; } #jsxc_roster > .jsxc_bottom ul li:last-child { border-bottom: 1px solid gray; } #jsxc_roster > .jsxc_bottom li { height: 30px; background-color: #1a1a1a; color: gray; cursor: pointer; width: 180px; padding-left: 10px; line-height: 30px; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } #jsxc_roster > .jsxc_bottom li.jsxc_disabled { color: #333333; cursor: default; } #jsxc_roster > .jsxc_bottom li:hover:not(.jsxc_disabled) { color: #fff; background-color: #3f8fba; } #jsxc_roster > .jsxc_bottom > div > span { cursor: pointer; } #jsxc_roster > .jsxc_bottom > div:hover { color: #fff; } .jsxc_windowItem.jsxc_groupchat .jsxc_bar .jsxc_avatar, li[data-type="groupchat"] .jsxc_avatar { text-indent: 999px; background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmlld0JveD0iMCAwIDEwMDAgMTAwMCIKICAgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pbllNaW4gbWVldCIKICAgd2lkdGg9IjEwMCUiCiAgIGhlaWdodD0iMTAwJSIKICAgc3R5bGU9IndpZHRoOiA1MTJweDsgaGVpZ2h0OiA1MTJweDsiCiAgIGlkPSJzdmcyIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlua3NjYXBlOnZlcnNpb249IjAuOTErZGV2ZWwgciIKICAgc29kaXBvZGk6ZG9jbmFtZT0iZ3JvdXBfd2hpdGUuc3ZnIj4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGExMCI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczgiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODU1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaWQ9Im5hbWVkdmlldzYiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIGlua3NjYXBlOnpvb209IjAuNjY3NTA4OCIKICAgICBpbmtzY2FwZTpjeD0iNTM4LjM5NTExIgogICAgIGlua3NjYXBlOmN5PSI0ODAuMjE5MDMiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjY1IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9InN2ZzIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDAuOTQ2MzA0NTYsNzYzLjA5NjMgYyAwLDIyLjIxMjAzIDkuMDg2NzM2NDQsMzMuMzE4MDQgMjcuMjYwMjA4NDQsMzMuMzE4MDQgbCAxMTIuMDY5NzQ3LDAgMCwtMTQyLjM1ODg3IGMgMCwtMTguMTczNDcgNC41NDM2MywtMzQuODMyMjIgMTMuNjMwODgsLTQ5Ljk3NjI3IDkuMDg3MjQsLTE1LjE0NDA1IDIxLjcwNzk3LC0yNi43NTUxMiAzNy44NjIxNiwtMzQuODMzMjYgbCAxMTUuMDk4NjYsLTU0LjUyMDQyIGMgMTAuMDk2MzcsLTYuMDU3ODIgMTguMTczNDcsLTEzLjEyNTI4IDI0LjIzMTI5LC0yMS4yMDIzOCAtMTIuMTE1NjQsLTE4LjE3MzQ3IC0yMi4yMTIwMiwtMzkuMzc1ODYgLTMwLjI4OTEyLC02My42MDcxNSAtOC4wNzcxLC0yNC4yMzEzIC0xMi4xMTU2NCwtNDkuNDcyMjMgLTEyLjExNTY0LC03NS43MjI4IDAsLTE2LjE1NDIgMi4wMTkyNywtMzIuMzA4NCA2LjA1NzgyLC00OC40NjI1OSA0LjAzODU1LC0xNi4xNTQyIDkuMDg2NzQsLTMxLjI5ODc2IDE1LjE0NDU2LC00NS40MzM2OCAtMjAuMTkyNzUsLTE0LjEzNDkzIC00MS4zOTUxMywtMjEuMjAyMzkgLTYzLjYwNzE1LC0yMS4yMDIzOSAtMzguMzY2MjIsMi4wMTkyOCAtNjguNjU1MzQsMTcuNjY4MzkgLTkwLjg2NzM2LDQ2Ljk0NzM2IC0yMi4yMTIwMSwyOS4yNzg5NyAtMzMuMzE4MDMsNjIuMDkyNDQgLTMzLjMxODAzLDk4LjQ0MDQyIDIuMDE5MjgsNjIuNTk3NTEgMjQuMjMxMywxMDcuMDIxNTUgNjYuNjM2MDYsMTMzLjI3MjEyIEwgMTYuMDkyNDE2LDU5Ni41MDYxNSBDIDUuOTk2MDQyMSw2MDIuNTYzOTcgMC45NDc4NTU0Niw2MTIuNjYwMzQgMC45NDc4NTU0Niw2MjYuNzk1MjcgbCAwLDEzNi4zMDEwMyB6IE0gMTkxLjc2Nzc1LDc5Ni40MTQzNCBjIC0yLjAxOTI3LDQyLjQwNDc2IDEwLjA5NjM3LDY0LjYxNjc4IDM2LjM0Njk1LDY2LjYzNjA2IGwgNTQyLjE3NTI0LDAgYyAxMi4xMTU2NSwtNC4wMzg1NSAyMC42OTc4MywtMTAuMDk2MzcgMjUuNzQ2NTMsLTE4LjE3MzQ3IDUuMDQ4NjksLTguMDc3MSA3LjU3MzA1LC0xNC42Mzk0OCA3LjU3MzA1LC0xOS42ODcxNiBsIDAsLTE3MS4xMzI3NSBjIDAsLTE4LjE3MzQ3IC03LjA2NzQ2LC0zMC4yODkxMiAtMjEuMjAyMzgsLTM2LjM0Njk0IEwgNjM3LjAxOTM2LDU0NS4wMTYxOSA1NzMuNDEyMjEsNTE0LjcyNzA3IGMgMzguMzY2MjIsLTIyLjIxMjAyIDYzLjYwNzE1LC02MC41NzgyNCA3NS43MjI4LC0xMTUuMDk4NjUgOC4wNzcxLC0zMC4yODkxMiA4LjA3NzEsLTYxLjU4Nzg4IDAsLTkzLjg5NjI3IC0xMC4wOTYzNywtMzYuMzQ2OTUgLTI4Ljc3NDQsLTY3LjE0MTE1IC01Ni4wMzQxLC05Mi4zODI1OSAtMjcuMjU5NjksLTI1LjI0MTQ1IC01OS4wNjM1MiwtMzguODcxODIgLTk1LjQxMTUsLTQwLjg5MTA5IC0zNi4zNDY5NCwyLjAxOTI3IC02Ny42NDU3LDE1LjY0OTY0IC05My44OTYyNyw0MC44OTEwOSAtMjYuMjUwNTcsMjUuMjQxNDQgLTQ0LjQyNDA0LDU1LjAyNjAxIC01NC41MjA0Miw4OS4zNTM2OCAtMTIuMTE1NjQsNDYuNDQzMzEgLTguMDc3MDksOTMuODk2MjcgMTIuMTE1NjUsMTQyLjM1ODg2IDE2LjE1NDIsMzAuMjg5MTIgMzcuMzU2NTgsNTQuNTIwNDEgNjMuNjA3MTUsNzIuNjkzODkgbCAtNTcuNTQ5MzIsMjcuMjYwMiAtMTUxLjQ0NTYsNjkuNjY0OTggYyAtMTYuMTU0Miw4LjA3NzEgLTI0LjIzMTMsMjEuMjAyMzggLTI0LjIzMTMsMzkuMzc1ODUgbCAwLDE0Mi4zNTg4NyB6IG0gNDc1LjUzOTE4LC0zMDIuODkxMiBjIDguMDc3MSw4LjA3NzEgMTguMTczNDcsMTYuMTU0MiAzMC4yODkxMiwyNC4yMzEyOSAxMi4xMTU2NSw4LjA3NzEgMjMuMjIxNjYsMTQuMTM0OTMgMzMuMzE4MDMsMTguMTczNDggMTAuMDk2MzgsNC4wMzg1NSAyMy4yMjE2Niw5LjU5MTgxIDM5LjM3NTg2LDE2LjY1OTc5IDE2LjE1NDIsNy4wNjc5NyAyOC4yNjk4NCwxMi42MjEyNCAzNi4zNDY5NCwxNi42NTk3OSAxNi4xNTQyLDguMDc3MSAyOC43NzQ5MywxOS42ODgxOSAzNy44NjIxOCwzNC44MzMyNiA5LjA4NzI0LDE1LjE0NTA3IDEzLjYzMDg4LDMxLjgwMzg0IDEzLjYzMDg4LDQ5Ljk3NjI3IGwgMCwxNDIuMzU4ODcgMTE1LjA5ODY1LDAgYyAxOC4xNzM0NywtMi4wMTkyOCAyNy4yNjAyMSwtMTMuMTI1MjkgMjcuMjYwMjEsLTMzLjMxODAzIGwgMCwtMTM2LjMwMTA0IGMgMCwtMTQuMTM0OTMgLTUuMDQ4MTksLTI0LjIzMTMgLTE1LjE0NDU2LC0zMC4yODkxMiBMIDgxNS43MjUxNyw1MTQuNzI3MDcgYyA0Mi40MDQ3NywtMzAuMjg5MTIgNjMuNjA3MTUsLTczLjcwMzUyIDYzLjYwNzE1LC0xMzAuMjQzMjEgMCwtMzguMzY2MjIgLTEyLjExNTY1LC03Mi4xODg4MSAtMzYuMzQ2OTQsLTEwMS40Njc3OCAtMjQuMjMxMywtMjkuMjc4OTcgLTUzLjUxMDc4LC00My45MTg5NiAtODcuODM4NDUsLTQzLjkyIC0yMi4yMTIwMiwwIC00NC40MjQwNCw3LjA2NzQ3IC02Ni42MzYwNiwyMS4yMDIzOSAxMi4xMTU2NCwzMC4yODkxMiAxOC4xNzM0Nyw2MS41ODc4NyAxOC4xNzM0Nyw5My44OTYyNyAwLDUwLjQ4MTg3IC0xMy4xMjUyOSw5Ni45MjUxOCAtMzkuMzc1ODYsMTM5LjMyOTk1IHoiCiAgICAgaWQ9InBhdGg0IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc29kaXBvZGk6bm9kZXR5cGVzPSJjc2Nzc2NjY3Nzc2Njc2NjY3NjY2NjY3Nzc2NjY2Njc2NzY2NjY2NzY2Njc3Nzc3NzY2Nzc2Njc3NjY3NjYyIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDoxLjU1MDkwMjEzIiAvPgo8L3N2Zz4K"); background-size: 70% 70% !important; background-repeat: no-repeat; } .jsxc_windowItem.jsxc_groupchat .jsxc_fade { padding-top: 30px; } .jsxc_windowItem.jsxc_groupchat .jsxc_video { display: none; } .jsxc_windowItem.jsxc_groupchat .jsxc_transfer { display: none; } .jsxc_windowItem.jsxc_groupchat .jsxc_fingerprints, .jsxc_windowItem.jsxc_groupchat .jsxc_verification, .jsxc_windowItem.jsxc_groupchat .jsxc_transfer { display: none; } .jsxc_windowItem.jsxc_groupchat .jsxc_members { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmlld0JveD0iMCAwIDEwMDAgMTAwMCIKICAgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pbllNaW4gbWVldCIKICAgd2lkdGg9IjEwMCUiCiAgIGhlaWdodD0iMTAwJSIKICAgc3R5bGU9IndpZHRoOiA1MTJweDsgaGVpZ2h0OiA1MTJweDsiCiAgIGlkPSJzdmcyIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlua3NjYXBlOnZlcnNpb249IjAuOTErZGV2ZWwgciIKICAgc29kaXBvZGk6ZG9jbmFtZT0iZ3JvdXBfZ3JleS5zdmciPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTEwIj4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZT48L2RjOnRpdGxlPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzOCIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgb2JqZWN0dG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBndWlkZXRvbGVyYW5jZT0iMTAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9Ijk4MCIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSI4ODgiCiAgICAgaWQ9Im5hbWVkdmlldzYiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIGlua3NjYXBlOnpvb209IjAuNjY3NTA4OCIKICAgICBpbmtzY2FwZTpjeD0iNTEyLjE3ODIzIgogICAgIGlua3NjYXBlOmN5PSI0ODAuMjE5MDMiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ijg4OSIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iODUiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMCIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmcyIiAvPgogIDxwYXRoCiAgICAgZD0ibSAwLjk0NjMwNDU2LDc2My4wOTYzIGMgMCwyMi4yMTIwMyA5LjA4NjczNjQ0LDMzLjMxODA0IDI3LjI2MDIwODQ0LDMzLjMxODA0IGwgMTEyLjA2OTc0NywwIDAsLTE0Mi4zNTg4NyBjIDAsLTE4LjE3MzQ3IDQuNTQzNjMsLTM0LjgzMjIyIDEzLjYzMDg4LC00OS45NzYyNyA5LjA4NzI0LC0xNS4xNDQwNSAyMS43MDc5NywtMjYuNzU1MTIgMzcuODYyMTYsLTM0LjgzMzI2IGwgMTE1LjA5ODY2LC01NC41MjA0MiBjIDEwLjA5NjM3LC02LjA1NzgyIDE4LjE3MzQ3LC0xMy4xMjUyOCAyNC4yMzEyOSwtMjEuMjAyMzggLTEyLjExNTY0LC0xOC4xNzM0NyAtMjIuMjEyMDIsLTM5LjM3NTg2IC0zMC4yODkxMiwtNjMuNjA3MTUgLTguMDc3MSwtMjQuMjMxMyAtMTIuMTE1NjQsLTQ5LjQ3MjIzIC0xMi4xMTU2NCwtNzUuNzIyOCAwLC0xNi4xNTQyIDIuMDE5MjcsLTMyLjMwODQgNi4wNTc4MiwtNDguNDYyNTkgNC4wMzg1NSwtMTYuMTU0MiA5LjA4Njc0LC0zMS4yOTg3NiAxNS4xNDQ1NiwtNDUuNDMzNjggLTIwLjE5Mjc1LC0xNC4xMzQ5MyAtNDEuMzk1MTMsLTIxLjIwMjM5IC02My42MDcxNSwtMjEuMjAyMzkgLTM4LjM2NjIyLDIuMDE5MjggLTY4LjY1NTM0LDE3LjY2ODM5IC05MC44NjczNiw0Ni45NDczNiAtMjIuMjEyMDEsMjkuMjc4OTcgLTMzLjMxODAzLDYyLjA5MjQ0IC0zMy4zMTgwMyw5OC40NDA0MiAyLjAxOTI4LDYyLjU5NzUxIDI0LjIzMTMsMTA3LjAyMTU1IDY2LjYzNjA2LDEzMy4yNzIxMiBMIDE2LjA5MjQxNiw1OTYuNTA2MTUgQyA1Ljk5NjA0MjEsNjAyLjU2Mzk3IDAuOTQ3ODU1NDYsNjEyLjY2MDM0IDAuOTQ3ODU1NDYsNjI2Ljc5NTI3IGwgMCwxMzYuMzAxMDMgeiBNIDE5MS43Njc3NSw3OTYuNDE0MzQgYyAtMi4wMTkyNyw0Mi40MDQ3NiAxMC4wOTYzNyw2NC42MTY3OCAzNi4zNDY5NSw2Ni42MzYwNiBsIDU0Mi4xNzUyNCwwIGMgMTIuMTE1NjUsLTQuMDM4NTUgMjAuNjk3ODMsLTEwLjA5NjM3IDI1Ljc0NjUzLC0xOC4xNzM0NyA1LjA0ODY5LC04LjA3NzEgNy41NzMwNSwtMTQuNjM5NDggNy41NzMwNSwtMTkuNjg3MTYgbCAwLC0xNzEuMTMyNzUgYyAwLC0xOC4xNzM0NyAtNy4wNjc0NiwtMzAuMjg5MTIgLTIxLjIwMjM4LC0zNi4zNDY5NCBMIDYzNy4wMTkzNiw1NDUuMDE2MTkgNTczLjQxMjIxLDUxNC43MjcwNyBjIDM4LjM2NjIyLC0yMi4yMTIwMiA2My42MDcxNSwtNjAuNTc4MjQgNzUuNzIyOCwtMTE1LjA5ODY1IDguMDc3MSwtMzAuMjg5MTIgOC4wNzcxLC02MS41ODc4OCAwLC05My44OTYyNyAtMTAuMDk2MzcsLTM2LjM0Njk1IC0yOC43NzQ0LC02Ny4xNDExNSAtNTYuMDM0MSwtOTIuMzgyNTkgLTI3LjI1OTY5LC0yNS4yNDE0NSAtNTkuMDYzNTIsLTM4Ljg3MTgyIC05NS40MTE1LC00MC44OTEwOSAtMzYuMzQ2OTQsMi4wMTkyNyAtNjcuNjQ1NywxNS42NDk2NCAtOTMuODk2MjcsNDAuODkxMDkgLTI2LjI1MDU3LDI1LjI0MTQ0IC00NC40MjQwNCw1NS4wMjYwMSAtNTQuNTIwNDIsODkuMzUzNjggLTEyLjExNTY0LDQ2LjQ0MzMxIC04LjA3NzA5LDkzLjg5NjI3IDEyLjExNTY1LDE0Mi4zNTg4NiAxNi4xNTQyLDMwLjI4OTEyIDM3LjM1NjU4LDU0LjUyMDQxIDYzLjYwNzE1LDcyLjY5Mzg5IGwgLTU3LjU0OTMyLDI3LjI2MDIgLTE1MS40NDU2LDY5LjY2NDk4IGMgLTE2LjE1NDIsOC4wNzcxIC0yNC4yMzEzLDIxLjIwMjM4IC0yNC4yMzEzLDM5LjM3NTg1IGwgMCwxNDIuMzU4ODcgeiBtIDQ3NS41MzkxOCwtMzAyLjg5MTIgYyA4LjA3NzEsOC4wNzcxIDE4LjE3MzQ3LDE2LjE1NDIgMzAuMjg5MTIsMjQuMjMxMjkgMTIuMTE1NjUsOC4wNzcxIDIzLjIyMTY2LDE0LjEzNDkzIDMzLjMxODAzLDE4LjE3MzQ4IDEwLjA5NjM4LDQuMDM4NTUgMjMuMjIxNjYsOS41OTE4MSAzOS4zNzU4NiwxNi42NTk3OSAxNi4xNTQyLDcuMDY3OTcgMjguMjY5ODQsMTIuNjIxMjQgMzYuMzQ2OTQsMTYuNjU5NzkgMTYuMTU0Miw4LjA3NzEgMjguNzc0OTMsMTkuNjg4MTkgMzcuODYyMTgsMzQuODMzMjYgOS4wODcyNCwxNS4xNDUwNyAxMy42MzA4OCwzMS44MDM4NCAxMy42MzA4OCw0OS45NzYyNyBsIDAsMTQyLjM1ODg3IDExNS4wOTg2NSwwIGMgMTguMTczNDcsLTIuMDE5MjggMjcuMjYwMjEsLTEzLjEyNTI5IDI3LjI2MDIxLC0zMy4zMTgwMyBsIDAsLTEzNi4zMDEwNCBjIDAsLTE0LjEzNDkzIC01LjA0ODE5LC0yNC4yMzEzIC0xNS4xNDQ1NiwtMzAuMjg5MTIgTCA4MTUuNzI1MTcsNTE0LjcyNzA3IGMgNDIuNDA0NzcsLTMwLjI4OTEyIDYzLjYwNzE1LC03My43MDM1MiA2My42MDcxNSwtMTMwLjI0MzIxIDAsLTM4LjM2NjIyIC0xMi4xMTU2NSwtNzIuMTg4ODEgLTM2LjM0Njk0LC0xMDEuNDY3NzggLTI0LjIzMTMsLTI5LjI3ODk3IC01My41MTA3OCwtNDMuOTE4OTYgLTg3LjgzODQ1LC00My45MiAtMjIuMjEyMDIsMCAtNDQuNDI0MDQsNy4wNjc0NyAtNjYuNjM2MDYsMjEuMjAyMzkgMTIuMTE1NjQsMzAuMjg5MTIgMTguMTczNDcsNjEuNTg3ODcgMTguMTczNDcsOTMuODk2MjcgMCw1MC40ODE4NyAtMTMuMTI1MjksOTYuOTI1MTggLTM5LjM3NTg2LDEzOS4zMjk5NSB6IgogICAgIGlkPSJwYXRoNCIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHNvZGlwb2RpOm5vZGV0eXBlcz0iY3Njc3NjY2Nzc3NjY3NjY2NzY2NjY2Nzc3NjY2NjY3Njc2NjY2Njc2NjY3Nzc3Nzc2Njc3NjY3NzY2NzY2MiCiAgICAgc3R5bGU9ImZpbGw6Izk5OTk5OTtzdHJva2Utd2lkdGg6MS41NTA5MDIxMztmaWxsLW9wYWNpdHk6MSIgLz4KPC9zdmc+Cg=="); background-size: 90%; background-repeat: no-repeat; background-position: center; } .jsxc_windowItem.jsxc_groupchat .jsxc_members:hover { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmlld0JveD0iMCAwIDEwMDAgMTAwMCIKICAgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pbllNaW4gbWVldCIKICAgd2lkdGg9IjEwMCUiCiAgIGhlaWdodD0iMTAwJSIKICAgc3R5bGU9IndpZHRoOiA1MTJweDsgaGVpZ2h0OiA1MTJweDsiCiAgIGlkPSJzdmcyIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlua3NjYXBlOnZlcnNpb249IjAuOTErZGV2ZWwgciIKICAgc29kaXBvZGk6ZG9jbmFtZT0iZ3JvdXBfd2hpdGUuc3ZnIj4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGExMCI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczgiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODU1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaWQ9Im5hbWVkdmlldzYiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIGlua3NjYXBlOnpvb209IjAuNjY3NTA4OCIKICAgICBpbmtzY2FwZTpjeD0iNTM4LjM5NTExIgogICAgIGlua3NjYXBlOmN5PSI0ODAuMjE5MDMiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjY1IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9InN2ZzIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDAuOTQ2MzA0NTYsNzYzLjA5NjMgYyAwLDIyLjIxMjAzIDkuMDg2NzM2NDQsMzMuMzE4MDQgMjcuMjYwMjA4NDQsMzMuMzE4MDQgbCAxMTIuMDY5NzQ3LDAgMCwtMTQyLjM1ODg3IGMgMCwtMTguMTczNDcgNC41NDM2MywtMzQuODMyMjIgMTMuNjMwODgsLTQ5Ljk3NjI3IDkuMDg3MjQsLTE1LjE0NDA1IDIxLjcwNzk3LC0yNi43NTUxMiAzNy44NjIxNiwtMzQuODMzMjYgbCAxMTUuMDk4NjYsLTU0LjUyMDQyIGMgMTAuMDk2MzcsLTYuMDU3ODIgMTguMTczNDcsLTEzLjEyNTI4IDI0LjIzMTI5LC0yMS4yMDIzOCAtMTIuMTE1NjQsLTE4LjE3MzQ3IC0yMi4yMTIwMiwtMzkuMzc1ODYgLTMwLjI4OTEyLC02My42MDcxNSAtOC4wNzcxLC0yNC4yMzEzIC0xMi4xMTU2NCwtNDkuNDcyMjMgLTEyLjExNTY0LC03NS43MjI4IDAsLTE2LjE1NDIgMi4wMTkyNywtMzIuMzA4NCA2LjA1NzgyLC00OC40NjI1OSA0LjAzODU1LC0xNi4xNTQyIDkuMDg2NzQsLTMxLjI5ODc2IDE1LjE0NDU2LC00NS40MzM2OCAtMjAuMTkyNzUsLTE0LjEzNDkzIC00MS4zOTUxMywtMjEuMjAyMzkgLTYzLjYwNzE1LC0yMS4yMDIzOSAtMzguMzY2MjIsMi4wMTkyOCAtNjguNjU1MzQsMTcuNjY4MzkgLTkwLjg2NzM2LDQ2Ljk0NzM2IC0yMi4yMTIwMSwyOS4yNzg5NyAtMzMuMzE4MDMsNjIuMDkyNDQgLTMzLjMxODAzLDk4LjQ0MDQyIDIuMDE5MjgsNjIuNTk3NTEgMjQuMjMxMywxMDcuMDIxNTUgNjYuNjM2MDYsMTMzLjI3MjEyIEwgMTYuMDkyNDE2LDU5Ni41MDYxNSBDIDUuOTk2MDQyMSw2MDIuNTYzOTcgMC45NDc4NTU0Niw2MTIuNjYwMzQgMC45NDc4NTU0Niw2MjYuNzk1MjcgbCAwLDEzNi4zMDEwMyB6IE0gMTkxLjc2Nzc1LDc5Ni40MTQzNCBjIC0yLjAxOTI3LDQyLjQwNDc2IDEwLjA5NjM3LDY0LjYxNjc4IDM2LjM0Njk1LDY2LjYzNjA2IGwgNTQyLjE3NTI0LDAgYyAxMi4xMTU2NSwtNC4wMzg1NSAyMC42OTc4MywtMTAuMDk2MzcgMjUuNzQ2NTMsLTE4LjE3MzQ3IDUuMDQ4NjksLTguMDc3MSA3LjU3MzA1LC0xNC42Mzk0OCA3LjU3MzA1LC0xOS42ODcxNiBsIDAsLTE3MS4xMzI3NSBjIDAsLTE4LjE3MzQ3IC03LjA2NzQ2LC0zMC4yODkxMiAtMjEuMjAyMzgsLTM2LjM0Njk0IEwgNjM3LjAxOTM2LDU0NS4wMTYxOSA1NzMuNDEyMjEsNTE0LjcyNzA3IGMgMzguMzY2MjIsLTIyLjIxMjAyIDYzLjYwNzE1LC02MC41NzgyNCA3NS43MjI4LC0xMTUuMDk4NjUgOC4wNzcxLC0zMC4yODkxMiA4LjA3NzEsLTYxLjU4Nzg4IDAsLTkzLjg5NjI3IC0xMC4wOTYzNywtMzYuMzQ2OTUgLTI4Ljc3NDQsLTY3LjE0MTE1IC01Ni4wMzQxLC05Mi4zODI1OSAtMjcuMjU5NjksLTI1LjI0MTQ1IC01OS4wNjM1MiwtMzguODcxODIgLTk1LjQxMTUsLTQwLjg5MTA5IC0zNi4zNDY5NCwyLjAxOTI3IC02Ny42NDU3LDE1LjY0OTY0IC05My44OTYyNyw0MC44OTEwOSAtMjYuMjUwNTcsMjUuMjQxNDQgLTQ0LjQyNDA0LDU1LjAyNjAxIC01NC41MjA0Miw4OS4zNTM2OCAtMTIuMTE1NjQsNDYuNDQzMzEgLTguMDc3MDksOTMuODk2MjcgMTIuMTE1NjUsMTQyLjM1ODg2IDE2LjE1NDIsMzAuMjg5MTIgMzcuMzU2NTgsNTQuNTIwNDEgNjMuNjA3MTUsNzIuNjkzODkgbCAtNTcuNTQ5MzIsMjcuMjYwMiAtMTUxLjQ0NTYsNjkuNjY0OTggYyAtMTYuMTU0Miw4LjA3NzEgLTI0LjIzMTMsMjEuMjAyMzggLTI0LjIzMTMsMzkuMzc1ODUgbCAwLDE0Mi4zNTg4NyB6IG0gNDc1LjUzOTE4LC0zMDIuODkxMiBjIDguMDc3MSw4LjA3NzEgMTguMTczNDcsMTYuMTU0MiAzMC4yODkxMiwyNC4yMzEyOSAxMi4xMTU2NSw4LjA3NzEgMjMuMjIxNjYsMTQuMTM0OTMgMzMuMzE4MDMsMTguMTczNDggMTAuMDk2MzgsNC4wMzg1NSAyMy4yMjE2Niw5LjU5MTgxIDM5LjM3NTg2LDE2LjY1OTc5IDE2LjE1NDIsNy4wNjc5NyAyOC4yNjk4NCwxMi42MjEyNCAzNi4zNDY5NCwxNi42NTk3OSAxNi4xNTQyLDguMDc3MSAyOC43NzQ5MywxOS42ODgxOSAzNy44NjIxOCwzNC44MzMyNiA5LjA4NzI0LDE1LjE0NTA3IDEzLjYzMDg4LDMxLjgwMzg0IDEzLjYzMDg4LDQ5Ljk3NjI3IGwgMCwxNDIuMzU4ODcgMTE1LjA5ODY1LDAgYyAxOC4xNzM0NywtMi4wMTkyOCAyNy4yNjAyMSwtMTMuMTI1MjkgMjcuMjYwMjEsLTMzLjMxODAzIGwgMCwtMTM2LjMwMTA0IGMgMCwtMTQuMTM0OTMgLTUuMDQ4MTksLTI0LjIzMTMgLTE1LjE0NDU2LC0zMC4yODkxMiBMIDgxNS43MjUxNyw1MTQuNzI3MDcgYyA0Mi40MDQ3NywtMzAuMjg5MTIgNjMuNjA3MTUsLTczLjcwMzUyIDYzLjYwNzE1LC0xMzAuMjQzMjEgMCwtMzguMzY2MjIgLTEyLjExNTY1LC03Mi4xODg4MSAtMzYuMzQ2OTQsLTEwMS40Njc3OCAtMjQuMjMxMywtMjkuMjc4OTcgLTUzLjUxMDc4LC00My45MTg5NiAtODcuODM4NDUsLTQzLjkyIC0yMi4yMTIwMiwwIC00NC40MjQwNCw3LjA2NzQ3IC02Ni42MzYwNiwyMS4yMDIzOSAxMi4xMTU2NCwzMC4yODkxMiAxOC4xNzM0Nyw2MS41ODc4NyAxOC4xNzM0Nyw5My44OTYyNyAwLDUwLjQ4MTg3IC0xMy4xMjUyOSw5Ni45MjUxOCAtMzkuMzc1ODYsMTM5LjMyOTk1IHoiCiAgICAgaWQ9InBhdGg0IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc29kaXBvZGk6bm9kZXR5cGVzPSJjc2Nzc2NjY3Nzc2Njc2NjY3NjY2NjY3Nzc2NjY2Njc2NzY2NjY2NzY2Njc3Nzc3NzY2Nzc2Njc3NjY3NjYyIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDoxLjU1MDkwMjEzIiAvPgo8L3N2Zz4K"); } .jsxc_windowItem.jsxc_groupchat .jsxc_chatmessage.jsxc_in { margin-left: 40px; } .jsxc_windowItem.jsxc_groupchat .jsxc_chatmessage.jsxc_in .jsxc_avatar { display: block; position: absolute; bottom: 0px; left: -37px; background-color: #777; } .jsxc_windowItem .jsxc_memberlist { height: 30px; width: 100%; background-color: #1a1a1a; overflow: hidden; position: absolute; top: 0px; -webkit-transition: height 400ms; transition: height 400ms; z-index: 100; } .jsxc_windowItem .jsxc_memberlist ul { white-space: nowrap; position: absolute; background-color: #1a1a1a; color: gray; overflow: hidden; -webkit-transition: left 400ms; transition: left 400ms; padding: 0px; } .jsxc_windowItem .jsxc_memberlist ul > li { display: inline-block; white-space: normal; } .jsxc_windowItem .jsxc_memberlist ul > li:last-child { margin-right: 2px; } .jsxc_windowItem .jsxc_memberlist ul > li .jsxc_name { display: none; } .jsxc_windowItem .jsxc_memberlist ul > li .jsxc_avatar { margin-left: 2px; margin-right: 0px; } .jsxc_windowItem .jsxc_memberlist.jsxc_expand ul { white-space: normal; } .jsxc_windowItem .jsxc_memberlist.jsxc_expand ul > li { display: block; width: 100%; height: 27px; line-height: 27px; } .jsxc_windowItem .jsxc_memberlist.jsxc_expand ul > li .jsxc_name { display: block; cursor: default; } .jsxc_windowItem .jsxc_memberlist.jsxc_expand ul > li .jsxc_name:hover { color: inherit; } .jsxc_windowItem .jsxc_memberlist.jsxc_expand ul > li .jsxc_avatar { margin-right: 4px; } li[data-type="groupchat"] .jsxc_video { display: none; } .jsxc_right { text-align: right; } .jsxc_center { text-align: center; } .jsxc_sep { border-top: 1px solid #000; } .jsxc_name { overflow: hidden; height: 30px; cursor: pointer; text-overflow: ellipsis; white-space: nowrap; } .jsxc_name:hover { color: #fff; } .jsxc_name a { cursor: pointer; } .jsxc_maxWidth { max-width: 500px; } #jsxc_dialog { padding: 20px; min-width: 320px; display: inline-block; text-align: left; position: relative; background: #FFF; width: auto; border-radius: 5px; } #jsxc_dialog * { box-sizing: border-box; } #jsxc_dialog ul { list-style: none; margin: 0; padding: 0; } #jsxc_dialog li { margin: 0; padding: 0; } #jsxc_dialog p { margin-bottom: 1em; } #jsxc_dialog p input { margin-bottom: 5px; width: 60%; outline: none; } #jsxc_dialog p input[type="submit"] { width: auto; } #jsxc_dialog hr { border: 0; border-top: 1px solid #eee; margin-top: 20px; margin-bottom: 20px; } #jsxc_dialog h3 { font-size: 120%; font-weight: bold; margin-bottom: 10px; margin-top: 20px; } #jsxc_dialog .jsxc_right { margin-top: 20px; } #jsxc_dialog form fieldset { margin-bottom: 30px; } #jsxc_dialog fieldset { border-bottom: 1px solid #eee; } #jsxc_dialog legend { border: 0; font-size: 20px; } #jsxc_dialog input { outline: none; } #jsxc_dialog input:invalid { border: 1px solid #f00; } #jsxc_dialog .btn-group button { margin-right: 0; } #jsxc_dialog input[type="range"] { display: inline; height: 34px; vertical-align: bottom; } #jsxc_dialog input[readonly] { background-color: #e6e6e6; } #jsxc_dialog .jsxc_inputinfo { padding-left: 30%; font-style: italic; margin-top: -1em; } #jsxc_dialog .jsxc_waiting:before { content: " "; width: 1em; height: 1em; display: inline-block; background-size: 100%; margin: 0 3px 0 0; background-image: url("data:image/gif;base64,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"); } #jsxc_dialog .jsxc_libraries { max-width: 300px; } .jsxc_avatar img { display: block; width: 25px; height: 25px; position: absolute; top: 0; left: 0; } ul.jsxc_vCard { min-width: 400px; } ul.jsxc_vCard ul { margin-left: 20px; } ul.jsxc_vCard li { cursor: default !important; } .jsxc_spot { display: inline-block; width: 10px; height: 10px; background-color: #fff; border-radius: 5px; text-indent: -99999em; margin-top: 3px; margin-right: 5px; border: 1px solid #000 !important; line-height: 100%; cursor: pointer; } .jsxc_spot.jsxc_online { background-color: #00bfff; } .jsxc_spot.jsxc_chat { background-color: #00bfff; } .jsxc_spot.jsxc_away { background-color: #ffa500; } .jsxc_spot.jsxc_xa { background-color: #ffa500; } .jsxc_spot.jsxc_dnd { background-color: #f00; } .jsxc_spot.jsxc_offline { background-color: #666666; } .jsxc_unread { display: none; } .jsxc_unreadMsg .jsxc_name { font-style: italic; } .jsxc_unreadMsg .jsxc_unread { display: block; background-color: #ffa500; border-radius: 11px; color: #000; font-size: 80%; padding: 2px; line-height: 15px; float: right; margin-right: 3px; margin-top: 4px; } #jsxc_menu { height: 30px; width: 30px; cursor: pointer; float: right; text-align: center; } #jsxc_menu:hover > span { opacity: 1; } #jsxc_avatar { height: 30px; width: 30px; float: left; margin: 0 2px; } #jsxc_notice { height: 30px; width: 30px; float: right; text-align: center; line-height: 30px; } #jsxc_notice span { background-color: #ffa500; border-radius: 11px; color: #000; font-size: 80%; padding: 2px; position: relative; -webkit-animation: bounce 2s 1s infinite; animation: bounce 2s 1s infinite; } #jsxc_menu > span { opacity: 0.5; display: block; width: 25px; height: 30px; margin-right: 4px; background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMjcyLjcwNTkzIgogICBoZWlnaHQ9IjI3NS4xOTQ0OSIKICAgaWQ9InN2ZzIiCiAgIHZlcnNpb249IjEuMSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC40OC4zLjEgcjk4ODYiCiAgIHNvZGlwb2RpOmRvY25hbWU9ImdlYXIuc3ZnIj4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iMC43IgogICAgIGlua3NjYXBlOmN4PSIxNTkuMTExMTgiCiAgICAgaW5rc2NhcGU6Y3k9Ijc1LjQ3NTkzNiIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0icHgiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjExMTEiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iODQwIgogICAgIGlua3NjYXBlOndpbmRvdy14PSIxOTEiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjI4IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjAiCiAgICAgZml0LW1hcmdpbi10b3A9IjAiCiAgICAgZml0LW1hcmdpbi1sZWZ0PSIwIgogICAgIGZpdC1tYXJnaW4tcmlnaHQ9IjAiCiAgICAgZml0LW1hcmdpbi1ib3R0b209IjAiIC8+CiAgPGRlZnMKICAgICBpZD0iZGVmczQiPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDQ2MTciPgogICAgICA8cGF0aAogICAgICAgICBzb2RpcG9kaTp0eXBlPSJhcmMiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNiM2IzYjM7c3Ryb2tlOm5vbmUiCiAgICAgICAgIGlkPSJwYXRoNDYxOSIKICAgICAgICAgc29kaXBvZGk6Y3g9IjE0MS40Mjg1NyIKICAgICAgICAgc29kaXBvZGk6Y3k9IjE0MC45MDg3NyIKICAgICAgICAgc29kaXBvZGk6cng9IjEyNC4yODU3MSIKICAgICAgICAgc29kaXBvZGk6cnk9IjEyNC4yODU3MSIKICAgICAgICAgZD0ibSAyNjUuNzE0MjksMTQwLjkwODc3IGEgMTI0LjI4NTcxLDEyNC4yODU3MSAwIDEgMSAtMjQ4LjU3MTQzLDAgMTI0LjI4NTcxLDEyNC4yODU3MSAwIDEgMSAyNDguNTcxNDMsMCB6IgogICAgICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzAuNDg2NTYsMjc1LjE0ODg4KSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgPC9kZWZzPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTciPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNzUuNTYyMTYsLTI3OC40NjA0KSI+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2IzYjNiMztzdHJva2U6bm9uZSIKICAgICAgIGQ9Im0gMzIyLjkwMDc3LDU1Mi4zNzYwOSBjIC0wLjgwMjUsLTEuMDMyNjUgLTQuMTI5OCwtNi43NzgxMiAtNy4zOTQsLTEyLjc2NzcxIC01LjY2MDYyLC0xMC4zODY4NiAtNS45MzQ5LC0xMS40NTk3MSAtNS45MzQ5LC0yMy4yMTQyOSAwLC02Ljc3ODI3IC0wLjE2MDcxLC0xMi4zMzQ3MSAtMC4zNTcxNCwtMTIuMzQ3NjQgLTAuMTk2NDMsLTAuMDEyOSAtNy4xMDcxNCwtMS4yNTM1MSAtMTUuMzU3MTQsLTIuNzU2ODYgLTguMjUsLTEuNTAzMzIgLTE1LjQyMDU0LC0yLjI5NjMyIC0xNS45MzQ1MywtMS43NjIyIC0wLjUxMzk5LDAuNTM0MTMgLTIuNjUwNjgsNS44NTIgLTQuNzQ4MiwxMS44MTc1IC0zLjI5Njc5LDkuMzc2MyAtNC45MTI3MSwxMS44MTMzOSAtMTEuOTIyNjEsMTcuOTgxMzUgLTEzLjE2Nzc2LDExLjU4NjE3IC0xMi43ODAyNCwxMS40NzQxOCAtMjEuODk4NjUsNi4zMjgwNyBsIC03LjkxODY3LC00LjQ2OTAyIDIuNTk0NzMsLTEzLjcwNDkyIGMgMi40OTM3NCwtMTMuMTcxNDggMi45MDIzMywtMTQuMDU1MjkgMTAuNDk3MDUsLTIyLjcwNTc5IDQuMzQ2MjcsLTQuOTUwNDcgNy45MDIzMSwtOS41NjY3NiA3LjkwMjMxLC0xMC4yNTg0IDAsLTEuNDc1NTkgLTE4LjMxMzM3LC0yMy44MDc5MyAtMjAuMDYxNjUsLTI0LjQ2NDMgLTAuNjU0MzMsLTAuMjQ1NjYgLTYuMzE3OTUsMi41MTEzMyAtMTIuNTg1ODMsNi4xMjY2NCBsIC0xMS4zOTYxNCw2LjU3MzI5IC0xMy4xMzEzMiwtMC40MTIzNCAtMTMuMTMxMzEsLTAuNDEyMzYgLTMuMjgwMywtOC43MzUzOSAtMy4yODAzMSwtOC43MzU0IDEwLjAwNjk2LC04LjE3NTE3IGMgMTAuODQxMzEsLTguODU2NzggMTIuNzE2MzUsLTkuNzAxNDggMjcuMjE3MDQsLTEyLjI2MTEzIGwgOS42NDI4NiwtMS43MDIxNCAwLC0xNi4xNjU1MyAwLC0xNi4xNjU1MyAtNy41LC0xLjQ3NzI2IGMgLTQuMTI1LC0wLjgxMjQ5IC05Ljg0MjUsLTEuODgxMSAtMTIuNzA1NTYsLTIuMzc0NjkgLTMuNDY0NjQsLTAuNTk3MyAtOC43NjIwMywtMy44NTQyOSAtMTUuODM5ODcsLTkuNzM4ODIgbCAtMTAuNjM0MzIsLTguODQxNCAzLjE3ODg1LC04LjUyODA2IDMuMTc4ODYsLTguNTI4MDUgMTMuNjA2MzgsLTAuNDA3MzYgMTMuNjA2MzcsLTAuNDA3MzUgMTAuOTU4NCw2LjQ3ODc4IGMgNi4wMjcxMiwzLjU2MzMzIDExLjM4NzQyLDYuNDQ4MDUgMTEuOTExNzgsNi40MTA0OCAxLjA3MjUzLC0wLjA3NjggMTkuMjU3NTEsLTIyLjE3MDk2IDIwLjAwNzIxLC0yNC4zMDgwNiAwLjI2NTMxLC0wLjc1NjMxIC0yLjY3ODE5LC01LjA2MzE2IC02LjU0MTEyLC05LjU3MDggLTkuMjM0MDUsLTEwLjc3NTE4IC04Ljk0Nzg5LC0xMC4xNzIwOSAtMTEuNzUxODQsLTI0Ljc2NzI0IGwgLTIuNDMyMzcsLTEyLjY2MTAyIDguMjMwNjYsLTQuOTAyOTcgOC4yMzA2NSwtNC45MDI5OCAxMC41OTI3Miw5LjA3NDQyIGMgOS45Njg4LDguNTM5OTMgMTAuODQ0NTgsOS43NzM3NSAxNC44NjksMjAuOTQ3ODMgMi43ODk4Niw3Ljc0NjI0IDQuOTc5MDcsMTEuNzg3MDYgNi4yOTgxLDExLjYyNSAxLjExMiwtMC4xMzY2MyA4LjI4OTY3LC0xLjMzNzU0IDE1Ljk1MDM4LC0yLjY2ODY5IGwgMTMuOTI4NTcsLTIuNDIwMjggMCwtMTIuMTg2NDEgYyAwLC0xMS43ODUyMSAwLjIxODU2LC0xMi41OTA5MyA2LjYzODg3LC0yNC40NzQxNiAzLjY1MTM5LC02Ljc1ODI3IDYuODM2NzgsLTEyLjUyNjcyIDcuMDc4NjUsLTEyLjgxODc4IDAuMjQxODcsLTAuMjkyMDYgNC42MTA2MywwLjI1NTk2IDkuNzA4MzQsMS4yMTc4MyAxMC4zNDQ0MSwxLjk1MTg2IDkuMjkyMTcsMC4zNDQ2IDEyLjM5NjI2LDE4LjkzNDUgMS41Mzc1MSw5LjIwNzkgMS40MTQzOCwxMC4xNTIzOCAtMi44NjU1LDIxLjk4MDM5IC0yLjQ1OTYyLDYuNzk3NDkgLTQuMjkxNzcsMTIuNDg4ODUgLTQuMDcxNDcsMTIuNjQ3NDYgNC43MTE3NywzLjM5MjI2IDI3LjEwMywxNS4xNzk1MyAyOC4xNTIwMiwxNC44MTk4OCAwLjc5ODI5LC0wLjI3MzY5IDQuODQ5NDMsLTQuNTgwMjMgOS4wMDI1NSwtOS41NzAwOCA2Ljk3NjEsLTguMzgxNjEgOC41MjI2MywtOS40MzggMjAuMzA5MzMsLTEzLjg3MjcyIGwgMTIuNzU4MjEsLTQuODAwMjUgNS4wODkyMyw1Ljg3ODY1IGMgMi43OTkwNywzLjIzMzI2IDUuNTM5MDQsNi42Mjg5OSA2LjA4ODgxLDcuNTQ2MDcgMC41NDk3NywwLjkxNzA5IC0yLjA0NDU1LDYuNzY0NDIgLTUuNzY1MTgsMTIuOTk0MDcgLTYuMTk0MTksMTAuMzcxMjYgLTcuNjkxNTYsMTEuODY4ODkgLTE3Ljc1MjE5LDE3Ljc1NTIyIC02LjA0MzA3LDMuNTM1NzEgLTExLjAwMjMsNy4wMDcyNCAtMTEuMDIwNTEsNy43MTQ1MSAtMC4wMTgzLDAuNzA3MjYgMi4zMTU2Myw3LjYxNzk4IDUuMTg2MzMsMTUuMzU3MTQgMy42MTg5NSw5Ljc1NjM4IDUuOTE4NzcsMTQuMDcwNjkgNy41LDE0LjA2OTUyIDEuMjU0MywtOS4zZS00IDYuOTcwNywtMC44OTYxNCAxMi43MDMxMSwtMS45ODkzNiAxMC40MjAwNiwtMS45ODcyIDEwLjQyNTc3LC0xLjk4NjU0IDIzLjU3MTQzLDIuNzAxNzYgbCAxMy4xNDg4Niw0LjY4OTQ0IDAuNDE5NTQsOS4zMTY3OSAwLjQxOTU0LDkuMzE2OCAtOC4xNTg4NywzLjA1MjYxIGMgLTE1Ljg5MjA3LDUuOTQ1OTkgLTE4Ljg3NDM3LDYuMzI2ODkgLTMyLjA1NjgxLDQuMDk0MiBsIC0xMi4yMzM3NiwtMi4wNzIgLTUuMjY2MjQsMTQuNTYxMjkgYyAtMi44OTY0NSw4LjAwODcxIC01LjI1NTk1LDE1LjEyIC01LjI0MzMzLDE1LjgwMjg3IDAuMDEyOCwwLjY4Mjg1IDQuOTk0NzUsMy45OTYxOCAxMS4wNzE0Myw3LjM2MjkzIDEwLjUwMDExLDUuODE3NTQgMTEuMzc5MjQsNi43MDE0NCAxNy43MTE5NywxNy44MDgyOCBsIDYuNjYzNDcsMTEuNjg2OTMgLTIuNzE4MSwzLjYyMDI5IGMgLTEuNDk0OTYsMS45OTExNSAtNC4xNzIwOSw1LjMzNTExIC01Ljk0OTE5LDcuNDMxMDIgbCAtMy4yMzEwOCwzLjgxMDc1IC0xMi44NTE2NSwtNC44NTc4MiBjIC0xMC41Nzc2MSwtMy45OTgyNSAtMTMuNzM3MzUsLTUuOTMyMzcgLTE3Ljg1NzE0LC0xMC45MzA1OCAtMi43NTMwMywtMy4zNDAwMyAtNi42MTI2NCwtNy44MjE1NyAtOC41NzY5MywtOS45NTkgbCAtMy41NzE0MywtMy44ODYyMyAtMTMuNTcxNDIsNy45MjU4MyBjIC03LjQ2NDI5LDQuMzU5MiAtMTMuNzQ5MTksOC4wOTY4NCAtMTMuOTY2NDYsOC4zMDU4NSAtMC4yMTcyNywwLjIwOTAzIDEuNjAzNzYsNS43NzM3IDQuMDQ2NzMsMTIuMzY1OTYgNC4zMjQ5LDExLjY3MDYyIDQuMzk4MDgsMTIuMjY3NzkgMi43ODIyMSwyMi43MDAyMiAtMi42NjgwMywxNy4yMjUzMiAtMi40MDI4OCwxNi43MDQ4NSAtOS4wNDc1MSwxNy43NjEwMiAtMy4yNzY4LDAuNTIwODYgLTcuMjkxMjUsMS4yNzkwMyAtOC45MjA5NywxLjY4NDgzIC0xLjYyOTczLDAuNDA1OCAtMy42MTk3NSwtMC4xMDcxNCAtNC40MjIyNSwtMS4xMzk3MyBsIDAsMCB6IG0gNS43NTYyMiwtOTEuMjEwOTEgYyA0MC42MzU2LC0xNS4yMDM3MSA0MC43MjA0NywtNzQuNjMyMzUgMC4xMjgyOCwtODkuODY2NDcgLTExLjYzNTEsLTQuMzY2NjIgLTI4LjE5ODAzLC0zLjc3Njc3IC0zOC4zNzYwMywxLjM2NjY5IC0zNy4yNzI2LDE4LjgzNTcyIC0zNS41MDEzMyw3Mi4wOTI0NCAyLjkyMzE1LDg3Ljg5MDQyIDEwLjg1MTY3LDQuNDYxNiAyNC40MDM2OCw0LjY5NTM3IDM1LjMyNDU0LDAuNjA5MzYgbCA2ZS01LDAgeiIKICAgICAgIGlkPSJwYXRoNDU4NCIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGg0NjE3KSIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTpub25lIgogICAgICAgZD0ibSAxMzcuNDA5MTUsMjU0LjgzMjUgYyAtMS4yNjM4OCwtMy4xNTg3NiAtMi4zMDY3NSwtOS43NDgwNSAtMi4zMTc0OCwtMTQuNjQyODYgLTAuMDMsLTEzLjY4MjQ5IC0wLjY2NzkzLC0xNC45MzI1MyAtOC40NzUwNywtMTYuNjA2ODYgLTMuNzI4MjIsLTAuNzk5NTcgLTEwLjg5NTY5LC0xLjg3MDk0IC0xNS45Mjc3MSwtMi4zODA4NiBsIC05LjE0OTE0LC0wLjkyNzExIC00LjAyNzc2NywxMC42MjkxNiBjIC0zLjkwNDkwOSwxMC4zMDQ5NCAtOS40MjE3NDIsMTguMjQzMTUgLTEyLjY3ODQ3MywxOC4yNDMxNSAtMS43MzY2MDYsMCAtMTcuMzg0NDQ3LC04LjY5ODg0IC0yMS42ODA3OSwtMTIuMDUyNjQgLTQuMjAxMzEsLTMuMjc5NjEgLTEuOTMxNjY3LC0xMC4xOTMyMyA2Ljk4MDU1OSwtMjEuMjYzNjMgbCA3Ljg0NTA4NCwtOS43NDQ4NCAtNi4zODU4MjQsLTguMTEyMyBjIC0zLjUxMjIwMywtNC40NjE3NyAtOC4yNDU5MjMsLTEwLjMwODU2IC0xMC41MTkzNzYsLTEyLjk5Mjg3IGwgLTQuMTMzNTUyLC00Ljg4MDU3IC0xMi4zMjkyMTQsNi42NjYyOCBjIC02Ljc4MTA2OCwzLjY2NjQ2IC0xMy42NTY2MDEsNi42NjYyOSAtMTUuMjc4OTY0LDYuNjY2MjkgLTMuMjcxNzMxLDAgLTguMzM4MDgyLC05LjU1MTEyIC0xMS42MTI0MjUsLTIxLjg5MTgyIC0xLjc2NzQ3LC02LjY2MTQyIC0xLjcxMDI5NywtNi45ODExMiAxLjcxMDM1OSwtOS41NjM1NSAxLjk0NjQyNiwtMS40Njk0NiA5LjE2Mzk1NiwtMy44MDk0NiAxNi4wMzg5NTYsLTUuMTk5OTkgbCAxMi41LC0yLjUyODIzIDAsLTE2LjcwNzA0IDAsLTE2LjcwNzA0IC0xMC4zNTcxNDMsLTEuNzg4MTQgYyAtNS42OTY0MjksLTAuOTgzNDggLTEyLjg0MzU4MSwtMy4wMjIxMyAtMTUuODgyNTYxLC00LjUzMDM0IC01LjAyMjUxMywtMi40OTI2IC01LjQ1ODQxNSwtMy4xNTUwNyAtNC43ODkyNTksLTcuMjc4NiAwLjQwNDg4NywtMi40OTUwMyAyLjU0Nzk1OCwtOS4xOTMzMjkgNC43NjIzOCwtMTQuODg1MTE3IDMuNTkyNTU3LC05LjIzNDA0NiA0LjQzNDQ4OCwtMTAuMzQ4NzA2IDcuODE2NjM5LC0xMC4zNDg3MDYgMi4wODQ3MjgsMCA5LjEwMDM0NSwzLjAwODQxIDE1LjU5MDI2LDYuNjg1MzU3IGwgMTEuNzk5ODQ1LDYuNjg1MzU2IDQuMTY2NjM5LC00Ljg5OTY0MiBjIDkuMDg4MTM0LC0xMC42ODY5MzUgMTUuNDY0NjI4LC0xOS41NDU0NzEgMTUuNDY0NjI4LC0yMS40ODQyMTQgMCwtMS4xMjE1NzcgLTIuNjI0MDQsLTUuMjE0NjgzIC01LjgzMTIwMSwtOS4wOTU3OSAtNi43OTQ3LC04LjIyMjUyNyAtOS44ODMwODQsLTEzLjc1OTQ1OSAtOS44ODMwODQsLTE3LjcxODYzOSAwLC0zLjIxMDEzMiAxOC45NzQ3NzUsLTE1Ljg4NjcxNCAyMy43Nzk4MiwtMTUuODg2NzE0IDMuNjI1NTQ4LDAgNy44OTU0NDUsNS44MjczOTMgMTIuNjgyNjUzLDE3LjMwODc5OSAyLjA5MTM4NCw1LjAxNTg3NSA0LjM0OTY5MSw5LjY5NDQzIDUuMDE4NDYxLDEwLjM5Njc4OCAwLjcxMTQyLDAuNzQ3MTQ1IDcuNzY5NTEsMC4yMjI2MjUgMTcuMDEwMzcsLTEuMjY0MTI0IGwgMTUuNzk0NDEsLTIuNTQxMTM5IDAsLTExLjkyMTI1MiBjIDAsLTcuNjIxNjkzIDAuODI4NzksLTEzLjk5MjYxNCAyLjI5Nzk3LC0xNy42NjQ0NDggMi4xNTQ1MiwtNS4zODQ2NjQgMi42NjAwMSwtNS43NDMxOTUgOC4wOTcyNywtNS43NDMxOTUgMy4xODk2MSwwIDkuODY5ODEsMC43MDg4NDkgMTQuODQ0ODksMS41NzUyMjEgbCA5LjA0NTU4LDEuNTc1MjIyIDAsNi45MjI0NjEgYyAwLDMuODA3MzU0IC0xLjY1NDExLDEyLjE1ODY3MSAtMy42NzU4MSwxOC41NTg0ODQgLTIuMDIxNyw2LjM5OTgxMyAtMy40NjgxMywxMS44MjkxOTkgLTMuMjE0MjksMTIuMDY1MzAyIDAuMjUzODUsMC4yMzYxMDMgNi44MjUxMiwzLjgyMDA5NSAxNC42MDI4Myw3Ljk2NDQzIGwgMTQuMTQxMjksNy41MzUxNTEgOC43MTU4NiwtOS40MzUxMDggYyA4LjIzNjMyLC04LjkxNjAyNSAxNS4zNjIyLC0xMy45MDQwMiAxOS44NjMzMiwtMTMuOTA0MDIgMS43ODUyMiwwIDE4LjEzODIzLDE4LjAyMDMzMiAxOC4xMzgyMywxOS45ODc1NjggMCwyLjY1NDEwNiAtMTAuNTE1NjMsMTIuNzA1OTMyIC0xOC45NDM3NCwxOC4xMDgyMjMgLTkuMTAyNDYsNS44MzQ1MjkgLTkuODIxMjcsNi42NTI2ODMgLTguOTM3NzYsMTAuMTcyOSAxLjU3MjQyLDYuMjY0OTc2IDkuNDA2MSwyNS45MDc3NTYgMTAuNjM1MTUsMjYuNjY3MzQ2IDAuNjI1NzgsMC4zODY3NSA2LjU1NDk3LC0wLjAyMTYgMTMuMTc1OTcsLTAuOTA3NTEgOS45OTY4MSwtMS4zMzc1NiAxMy4xMTg5MywtMS4yNTA0NCAxOC40MTE0MywwLjUxMzczIGwgNi4zNzMyNCwyLjEyNDQxIDAsMTMuMzg5NTYgMCwxMy4zODk1NiAtNi40Mjg1NywxLjg5NDI2IGMgLTUuMTc4NTcsMS41MjU5MyAtOC44NzMyOSwxLjU2NjIgLTE5LjAwMTQ1LDAuMjA3MTIgLTcuNDE4MSwtMC45OTU0MiAtMTMuMDU1ODIsLTEuMTYwNTkgLTEzLjc1MDg0LC0wLjQwMjg2IC0xLjk1Njk4LDIuMTMzNiAtMTAuMzc2NiwyOC45NzQ1NiAtOS41MjI0MSwzMC4zNTY2NSAwLjQzNzAxLDAuNzA3MTEgNS4xOTY3MSwzLjkwMDkxIDEwLjU3NzEsNy4wOTczNCA2LjI1MzgsMy43MTUzMiAxMS4xNzk2LDcuOTIyODMgMTMuNjU1NTgsMTEuNjY0MjkgbCAzLjg3MzA3LDUuODUyNiAtMi44NjI4OCwzLjYzOTU2IGMgLTQuMzg4NjQsNS41NzkyNyAtMTIuNDI0NjYsMTQuMzEyMTUgLTE0LjE1Mjk3LDE1LjM4MDMxIC0zLjI5OTgzLDIuMDM5NCAtMTIuNjkzMDUsLTMuODEzNDMgLTIxLjY3MjM1LC0xMy41MDM4NiBsIC05LjI4NTcxLC0xMC4wMjExMSAtMTMuNTcxNDMsOC4xMzExMyBjIC03LjQ2NDI4LDQuNDcyMTEgLTEzLjc5ODUxLDguMzExOTMgLTE0LjA3NjA2LDguNTMyOTEgLTAuMjc3NTUsMC4yMjEgMS4yMDYwMiw1LjUzODQ0IDMuMjk2ODIsMTEuODE2NTQgMi41NTUzNCw3LjY3MyAzLjY1NzMzLDEzLjY3MzM1IDMuMzYxNzgsMTguMzA0OSBsIC0wLjQzOTY4LDYuODkwMTUgLTcuODU3MTQsMS42NDc5NSBjIC00LjMyMTQzLDAuOTA2MzkgLTEwLjg0MDkyLDEuNzA5OTYgLTE0LjQ4Nzc1LDEuNzg1NzIgLTYuNDUwNTIsMC4xMzQgLTYuNjkzMDEsLTAuMDE4MyAtOC45Mjg1NywtNS42MDU0NCB6IG0gMTkuNjEwMzYsLTczLjM2NTIgYyAzNC4wNTQ0NiwtMTYuNjYxMjkgMzUuOTIwNjYsLTY3LjEzMDI4IDMuMTczODQsLTg1LjgzMjQ2NSAtMTIuNTgwNzMsLTcuMTg1MDM4IC0zMS4yNDg4MywtOC4xMTY4ODcgLTQ0LjYxODg0LC0yLjIyNzIyMiAtOC4yMzI1NiwzLjYyNjU1IC0xOC41NDgwMTYsMTMuNTA0MDE3IC0yMy4wOTExOCwyMi4xMTA3MjcgLTMuNDE2Nzc2LDYuNDcyODUgLTMuODAwNzIxLDguNzE1NSAtMy44MDA3MjEsMjIuMjAwMjEgMCwxMi45MDM0NCAwLjQ1NzkxMiwxNS44NTc2MSAzLjI3NjE2LDIxLjEzNTggNi45ODQ1NTIsMTMuMDgxMTIgMTguODI0MDgxLDIyLjQ1Nzk1IDMyLjc4OTQ0MSwyNS45NjkwNSA5LjMxMzM3LDIuMzQxNTEgMjMuNjc5NDcsMC44NDc0OCAzMi4yNzEzLC0zLjM1NjEgeiIKICAgICAgIGlkPSJwYXRoMjk4NSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzUuNTYyMTYsMjc4LjQ2MDQpIiAvPgogIDwvZz4KPC9zdmc+Cg=="); background-size: 18px 18px; background-repeat: no-repeat; background-position: center center; } @-webkit-keyframes bounce { 0% { bottom: 0; -webkit-animation-timing-function: ease-in; animation-timing-function: ease-in; } 12% { bottom: 5px; -webkit-animation-timing-function: ease-out; animation-timing-function: ease-out; } 25% { bottom: 0; -webkit-animation-timing-function: ease-in; animation-timing-function: ease-in; } 37% { bottom: 5px; -webkit-animation-timing-function: ease-out; animation-timing-function: ease-out; } 50% { bottom: 0; -webkit-animation-timing-function: ease-in; animation-timing-function: ease-in; } 100% { bottom: 0; } } @keyframes bounce { 0% { bottom: 0; -webkit-animation-timing-function: ease-in; animation-timing-function: ease-in; } 12% { bottom: 5px; -webkit-animation-timing-function: ease-out; animation-timing-function: ease-out; } 25% { bottom: 0; -webkit-animation-timing-function: ease-in; animation-timing-function: ease-in; } 37% { bottom: 5px; -webkit-animation-timing-function: ease-out; animation-timing-function: ease-out; } 50% { bottom: 0; -webkit-animation-timing-function: ease-in; animation-timing-function: ease-in; } 100% { bottom: 0; } } #jsxc_presence { cursor: pointer; padding-left: 2px; overflow: hidden; } #jsxc_windowList { position: fixed; bottom: 0; right: 235px; left: 0; z-index: 50; clip: rect(-10000px, 10000px, 30px, 30px); } #jsxc_windowList > ul { list-style: none; padding: 0; margin: 0; position: absolute; bottom: 0; right: 0; height: 30px; overflow: visible; white-space: nowrap; -webkit-transition: right 0.5s; transition: right 0.5s; } #jsxc_windowList > ul > li { padding: 0; margin: 0; display: inline-block; width: 250px; height: 30px; position: relative; overflow: visible; margin-right: 5px; cursor: pointer; white-space: normal; } #jsxc_windowList > ul > li.jsxc_min { width: 200px !important; } #jsxc_windowListSB { position: fixed; left: 0; bottom: 0; width: 30px; height: 30px; } #jsxc_windowListSB > div { box-sizing: border-box; width: 14px; height: 100%; background-color: #cccccc; color: gray; text-align: center; line-height: 30px; float: left; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #jsxc_windowListSB > div:hover { background-color: #b3b3b3; } #jsxc_windowListSB > .jsxc_disabled { background-color: #e6e6e6 !important; color: #cccccc; cursor: default !important; display: none; } .jsxc_bar { background-color: #1a1a1a; height: 30px; line-height: 26px; padding: 2px; color: gray; width: 100%; box-sizing: border-box; overflow: hidden; } .jsxc_bar #jsxc_window_name > a { target-new: tab; } .jsxc_window { position: absolute; bottom: 0; left: 0; right: 0; height: auto; background-color: #999999; z-index: 80; cursor: default; } .jsxc_window .jsxc_emoticons { height: 30px; width: 30px; position: absolute; top: 240px; right: 0; cursor: pointer; } .jsxc_window .jsxc_emoticons:after { content: ' '; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALHQAACx0BpBPQ5gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGtSURBVDiNrdS7a1RBFAbw3+7KKlYKamGI6D9gBGsfCFoogijia0k6LRURG0ufaAjE/Qds1CKFlTZaWUgIQgo7kfhCJVhYqEUUvBZzbhzu3l1Z8YOBmW++890zc8+Zhnqsxinsx1asDf4LXuAR7uJ7NbBRY3YSNzGC13iKz7G3DruwBR9xMYxr0cB1FJjFjn7C2JsN7Y0+ibkSgkm0BpiVaIW2wNXq5hH8CsGwmIrYwyWxSrqruSyzDbiM0zUGnchoNNYr8BwLWAnjkfbeLOhOcAX2ZPy2jH+Y8fuC6zRxAB/wJBP8yOZL2fxnBFb5x/gUXl7p/fVrcB5H9eIgLmB9hb+Pl/ANt2oCh8Ukvjb1qaF/RROL2PgfvEaw2MQ8dvqT6aj05/+GcWyKeUPqnvlyo5B6FKalQj03wOxsaLqx3h0eHVJhv5N6s4U2HoTgGSawPcZEcEVo2lJhz+FteBHOZR+XRzgjVX9RGQtSB5VXNJVnl6Or/nEYw6EYYxmfPw5dNWjhtuGfr24ce/loVZzANWw2+IF9g0u4N+DDy2jjGGbwXurbpZjP4HhoevAb11xtRVQWs+YAAAAASUVORK5CYII="); background-position: center center; background-repeat: no-repeat; height: 30px; width: 30px; opacity: 0.3; position: absolute; top: 0; left: 0; } .jsxc_window .jsxc_emoticons ul { display: none; position: absolute; bottom: 33px; right: 3px; width: 210px; background-color: rgba(51, 51, 51, 0.8); padding: 3px; border-radius: 3px; z-index: 200; list-style-type: none; } .jsxc_window .jsxc_emoticons ul:after { content: ''; position: absolute; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid rgba(51, 51, 51, 0.8); display: block; width: 0; z-index: 1; right: 6px; bottom: -6px; } .jsxc_window .jsxc_emoticons li { float: right; cursor: pointer; } .jsxc_window .jsxc_emoticons div { cursor: pointer; border-radius: 3px; background-size: 30px 30px; width: 30px; height: 30px; } .jsxc_window .jsxc_emoticons div:hover { background-color: rgba(255, 255, 255, 0.8); } .jsxc_window .jsxc_emoticons:hover:after { opacity: 0.5; } .jsxc_window .jsxc_fade { position: relative; } .jsxc_window .jsxc_gradient { display: none; position: absolute; top: 0; left: 0; right: 0; height: 15px; z-index: 100; background: -webkit-linear-gradient(top, #999999 0, rgba(0, 0, 0, 0) 100%); background: linear-gradient(to bottom, #999999 0, rgba(0, 0, 0, 0) 100%); } .jsxc_window .jsxc_avatar { margin-top: 1px; } .jsxc_window .jsxc_textarea { width: 100%; overflow: hidden; padding: 3px; } .jsxc_window .slimScrollDiv { margin: 0 0 6px 0; left: auto !important; top: auto !important; } .jsxc_window input.jsxc_textinput { width: 100%; height: 30px; margin: 0; padding: 3px; padding-right: 40px; outline: none; border-radius: 0; box-sizing: border-box; text-align: right; } .jsxc_window input::-webkit-input-placeholder { color: #000; opacity: 0.3; } .jsxc_window input::-moz-placeholder { color: #000; opacity: 0.3; } .jsxc_window input:-ms-input-placeholder { color: #000; opacity: 0.3; } .jsxc_window input::placeholder { color: #000; opacity: 0.3; } .jsxc_window .jsxc_tools { height: 26px; float: right; } .jsxc_window .jsxc_tools > div { width: 17px; height: 26px; display: block; float: left; color: gray; font-family: Arial, sans-serif; line-height: 26px; cursor: pointer; text-align: center; } .jsxc_window .jsxc_tools .jsxc_presence_badge { height: 14px; width: 14px; border-radius: 8px; margin: 6px; } .jsxc_window .jsxc_tools .jsxc_badge_online { background-color: #00bfff; } .jsxc_window .jsxc_tools .jsxc_badge_away { background-color: #ffa500; } .jsxc_window .jsxc_tools .jsxc_badge_dnd { background-color: #f00; } .jsxc_window .jsxc_tools .jsxc_badge_offline { background-color: #666666; } .jsxc_window .jsxc_close { font-size: 20px; } .jsxc_window .jsxc_close:hover { color: #fff; } .jsxc_window .jsxc_reduce { padding-left: 5px; } .jsxc_window .jsxc_restore { display: none; } .jsxc_window .ui-resizable-w { left: 0; } .jsxc_window .ui-resizable-nw { top: 0; left: 0; width: 15px; height: 15px; z-index: 95 !important; background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTUiCiAgIGhlaWdodD0iMTUiCiAgIGlkPSJzdmcyIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlua3NjYXBlOnZlcnNpb249IjAuNDguNCByOTkzOSIKICAgc29kaXBvZGk6ZG9jbmFtZT0icmVzaXplX2dyYXkuc3ZnIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzNCI+CiAgICA8Y2xpcFBhdGgKICAgICAgIGNsaXBQYXRoVW5pdHM9InVzZXJTcGFjZU9uVXNlIgogICAgICAgaWQ9ImNsaXBQYXRoMzgwMyI+CiAgICAgIDxyZWN0CiAgICAgICAgIHN0eWxlPSJzdHJva2U6bm9uZSIKICAgICAgICAgaWQ9InJlY3QzODA1IgogICAgICAgICB3aWR0aD0iMTYuMDkzNzUiCiAgICAgICAgIGhlaWdodD0iMTQuNzE4NzUiCiAgICAgICAgIHg9IjAuODQzNzUiCiAgICAgICAgIHk9IjEwMzguMTQzNCIgLz4KICAgIDwvY2xpcFBhdGg+CiAgPC9kZWZzPgogIDxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBpZD0iYmFzZSIKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgYm9yZGVyb3BhY2l0eT0iMS4wIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp6b29tPSIzMiIKICAgICBpbmtzY2FwZTpjeD0iNi45OTA5MDg4IgogICAgIGlua3NjYXBlOmN5PSI2LjU1NjQ4MTIiCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9InB4IgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODY1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjU1IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTciPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsLTEwMzcuMzYyMikiPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiNiZmJmYmY7c3Ryb2tlLXdpZHRoOjI7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46bWl0ZXI7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2Utb3BhY2l0eToxO3N0cm9rZS1kYXNoYXJyYXk6bm9uZSIKICAgICAgIGQ9Im0gMTAuNDY4NzUsMTAzMi4xNzQ3IC0xNC41LDE0LjI4MTMgeiBtIDMuNSwxLjI1MDEgLTE3LjMxMjUsMTcuMzEyNCB6IgogICAgICAgaWQ9InBhdGgyOTg1IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIGNsaXAtcGF0aD0idXJsKCNjbGlwUGF0aDM4MDMpIgogICAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC44MTI1LDAuNjg3NSkiCiAgICAgICBzb2RpcG9kaTpub2RldHlwZXM9ImNjY2NjYyIgLz4KICA8L2c+Cjwvc3ZnPgo="); } .jsxc_window .ui-resizable-n { position: absolute; top: 0; left: 0; right: 0; height: 15px; z-index: 100; background: -webkit-linear-gradient(top, #999999 0, rgba(40, 35, 35, 0) 100%); background: linear-gradient(to bottom, #999999 0, rgba(40, 35, 35, 0) 100%); } .jsxc_chatmessage { margin: 3px; padding: 4px; padding-right: 10px; max-width: 76%; word-wrap: break-word; background-color: #fff; position: relative; outline: none; clear: both; } .jsxc_chatmessage a { color: #00f; text-decoration: underline; } .jsxc_chatmessage img { width: 19px; height: 19px; background-size: 19px 19px; } .jsxc_chatmessage .jsxc_avatar { display: none; } .jsxc_timestamp { font-size: 8px; color: #999999; line-height: 8px; overflow: hidden; white-space: nowrap; max-width: 100%; text-overflow: ellipsis; } .jsxc_in { float: left; position: relative; margin-left: 10px; background: #f1f7fd; border: solid 1px #a6b8c9; border-radius: 3px; } .jsxc_in:after { content: ''; position: absolute; border-style: solid; border-width: 5px 6px 5px 0; border-color: transparent #f1f7fd; display: block; width: 0; z-index: 1; left: -6px; bottom: 10px; } .jsxc_in .jsxc_timestamp { float: left; } .jsxc_out { float: right; position: relative; margin-right: 10px; background: #e6ffd1; border: solid 1px #b4d89f; border-radius: 3px; } .jsxc_out:after { content: ''; position: absolute; border-style: solid; border-width: 5px 0 5px 6px; border-color: transparent #e6ffd1; display: block; width: 0; z-index: 1; right: -6px; bottom: 10px; } .jsxc_out.jsxc_received:before { content: '✓'; position: absolute; bottom: 2px; right: 2px; font-size: 12px; line-height: 12px; color: #008000; } .jsxc_out.jsxc_received .jsxc_timestamp { margin-right: 4px; } .jsxc_out .jsxc_timestamp { float: right; } .jsxc_sys { width: auto; max-width: none; padding-right: 4px; box-sizing: border-box; margin-right: 3px; border-radius: 3px; } div.jsxc_settings { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMjcyLjcwNTkzIgogICBoZWlnaHQ9IjI3NS4xOTQ0OSIKICAgaWQ9InN2ZzIiCiAgIHZlcnNpb249IjEuMSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC40OCtkZXZlbCByIgogICBzb2RpcG9kaTpkb2NuYW1lPSJnZWFyLnN2ZyI+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIGlkPSJiYXNlIgogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAuMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnpvb209IjIuOCIKICAgICBpbmtzY2FwZTpjeD0iMTQ2Ljg4MTU5IgogICAgIGlua3NjYXBlOmN5PSIxMzEuMDY2MzQiCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9InB4IgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxMTExIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9Ijg0MCIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iMTkxIgogICAgIGlua3NjYXBlOndpbmRvdy15PSIzNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIwIgogICAgIGZpdC1tYXJnaW4tdG9wPSIwIgogICAgIGZpdC1tYXJnaW4tbGVmdD0iMCIKICAgICBmaXQtbWFyZ2luLXJpZ2h0PSIwIgogICAgIGZpdC1tYXJnaW4tYm90dG9tPSIwIiAvPgogIDxkZWZzCiAgICAgaWQ9ImRlZnM0Ij4KICAgIDxjbGlwUGF0aAogICAgICAgY2xpcFBhdGhVbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgICBpZD0iY2xpcFBhdGg0NjE3Ij4KICAgICAgPHBhdGgKICAgICAgICAgc29kaXBvZGk6dHlwZT0iYXJjIgogICAgICAgICBzdHlsZT0iZmlsbDojYjNiM2IzO3N0cm9rZTpub25lIgogICAgICAgICBpZD0icGF0aDQ2MTkiCiAgICAgICAgIHNvZGlwb2RpOmN4PSIxNDEuNDI4NTciCiAgICAgICAgIHNvZGlwb2RpOmN5PSIxNDAuOTA4NzciCiAgICAgICAgIHNvZGlwb2RpOnJ4PSIxMjQuMjg1NzEiCiAgICAgICAgIHNvZGlwb2RpOnJ5PSIxMjQuMjg1NzEiCiAgICAgICAgIGQ9Im0gMjY1LjcxNDI5LDE0MC45MDg3NyBhIDEyNC4yODU3MSwxMjQuMjg1NzEgMCAxIDEgLTI0OC41NzE0MywwIDEyNC4yODU3MSwxMjQuMjg1NzEgMCAxIDEgMjQ4LjU3MTQzLDAgeiIKICAgICAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTcwLjQ4NjU2LDI3NS4xNDg4OCkiIC8+CiAgICA8L2NsaXBQYXRoPgogIDwvZGVmcz4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE3Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZT48L2RjOnRpdGxlPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZwogICAgIGlua3NjYXBlOmxhYmVsPSJMYXllciAxIgogICAgIGlua3NjYXBlOmdyb3VwbW9kZT0ibGF5ZXIiCiAgICAgaWQ9ImxheWVyMSIKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTc1LjU2MjE2LC0yNzguNDYwNCkiPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNiM2IzYjM7c3Ryb2tlOm5vbmUiCiAgICAgICBkPSJtIDMyMi45MDA3Nyw1NTIuMzc2MDkgYyAtMC44MDI1LC0xLjAzMjY1IC00LjEyOTgsLTYuNzc4MTIgLTcuMzk0LC0xMi43Njc3MSAtNS42NjA2MiwtMTAuMzg2ODYgLTUuOTM0OSwtMTEuNDU5NzEgLTUuOTM0OSwtMjMuMjE0MjkgMCwtNi43NzgyNyAtMC4xNjA3MSwtMTIuMzM0NzEgLTAuMzU3MTQsLTEyLjM0NzY0IC0wLjE5NjQzLC0wLjAxMjkgLTcuMTA3MTQsLTEuMjUzNTEgLTE1LjM1NzE0LC0yLjc1Njg2IC04LjI1LC0xLjUwMzMyIC0xNS40MjA1NCwtMi4yOTYzMiAtMTUuOTM0NTMsLTEuNzYyMiAtMC41MTM5OSwwLjUzNDEzIC0yLjY1MDY4LDUuODUyIC00Ljc0ODIsMTEuODE3NSAtMy4yOTY3OSw5LjM3NjMgLTQuOTEyNzEsMTEuODEzMzkgLTExLjkyMjYxLDE3Ljk4MTM1IC0xMy4xNjc3NiwxMS41ODYxNyAtMTIuNzgwMjQsMTEuNDc0MTggLTIxLjg5ODY1LDYuMzI4MDcgbCAtNy45MTg2NywtNC40NjkwMiAyLjU5NDczLC0xMy43MDQ5MiBjIDIuNDkzNzQsLTEzLjE3MTQ4IDIuOTAyMzMsLTE0LjA1NTI5IDEwLjQ5NzA1LC0yMi43MDU3OSA0LjM0NjI3LC00Ljk1MDQ3IDcuOTAyMzEsLTkuNTY2NzYgNy45MDIzMSwtMTAuMjU4NCAwLC0xLjQ3NTU5IC0xOC4zMTMzNywtMjMuODA3OTMgLTIwLjA2MTY1LC0yNC40NjQzIC0wLjY1NDMzLC0wLjI0NTY2IC02LjMxNzk1LDIuNTExMzMgLTEyLjU4NTgzLDYuMTI2NjQgbCAtMTEuMzk2MTQsNi41NzMyOSAtMTMuMTMxMzIsLTAuNDEyMzQgLTEzLjEzMTMxLC0wLjQxMjM2IC0zLjI4MDMsLTguNzM1MzkgLTMuMjgwMzEsLTguNzM1NCAxMC4wMDY5NiwtOC4xNzUxNyBjIDEwLjg0MTMxLC04Ljg1Njc4IDEyLjcxNjM1LC05LjcwMTQ4IDI3LjIxNzA0LC0xMi4yNjExMyBsIDkuNjQyODYsLTEuNzAyMTQgMCwtMTYuMTY1NTMgMCwtMTYuMTY1NTMgLTcuNSwtMS40NzcyNiBjIC00LjEyNSwtMC44MTI0OSAtOS44NDI1LC0xLjg4MTEgLTEyLjcwNTU2LC0yLjM3NDY5IC0zLjQ2NDY0LC0wLjU5NzMgLTguNzYyMDMsLTMuODU0MjkgLTE1LjgzOTg3LC05LjczODgyIGwgLTEwLjYzNDMyLC04Ljg0MTQgMy4xNzg4NSwtOC41MjgwNiAzLjE3ODg2LC04LjUyODA1IDEzLjYwNjM4LC0wLjQwNzM2IDEzLjYwNjM3LC0wLjQwNzM1IDEwLjk1ODQsNi40Nzg3OCBjIDYuMDI3MTIsMy41NjMzMyAxMS4zODc0Miw2LjQ0ODA1IDExLjkxMTc4LDYuNDEwNDggMS4wNzI1MywtMC4wNzY4IDE5LjI1NzUxLC0yMi4xNzA5NiAyMC4wMDcyMSwtMjQuMzA4MDYgMC4yNjUzMSwtMC43NTYzMSAtMi42NzgxOSwtNS4wNjMxNiAtNi41NDExMiwtOS41NzA4IC05LjIzNDA1LC0xMC43NzUxOCAtOC45NDc4OSwtMTAuMTcyMDkgLTExLjc1MTg0LC0yNC43NjcyNCBsIC0yLjQzMjM3LC0xMi42NjEwMiA4LjIzMDY2LC00LjkwMjk3IDguMjMwNjUsLTQuOTAyOTggMTAuNTkyNzIsOS4wNzQ0MiBjIDkuOTY4OCw4LjUzOTkzIDEwLjg0NDU4LDkuNzczNzUgMTQuODY5LDIwLjk0NzgzIDIuNzg5ODYsNy43NDYyNCA0Ljk3OTA3LDExLjc4NzA2IDYuMjk4MSwxMS42MjUgMS4xMTIsLTAuMTM2NjMgOC4yODk2NywtMS4zMzc1NCAxNS45NTAzOCwtMi42Njg2OSBsIDEzLjkyODU3LC0yLjQyMDI4IDAsLTEyLjE4NjQxIGMgMCwtMTEuNzg1MjEgMC4yMTg1NiwtMTIuNTkwOTMgNi42Mzg4NywtMjQuNDc0MTYgMy42NTEzOSwtNi43NTgyNyA2LjgzNjc4LC0xMi41MjY3MiA3LjA3ODY1LC0xMi44MTg3OCAwLjI0MTg3LC0wLjI5MjA2IDQuNjEwNjMsMC4yNTU5NiA5LjcwODM0LDEuMjE3ODMgMTAuMzQ0NDEsMS45NTE4NiA5LjI5MjE3LDAuMzQ0NiAxMi4zOTYyNiwxOC45MzQ1IDEuNTM3NTEsOS4yMDc5IDEuNDE0MzgsMTAuMTUyMzggLTIuODY1NSwyMS45ODAzOSAtMi40NTk2Miw2Ljc5NzQ5IC00LjI5MTc3LDEyLjQ4ODg1IC00LjA3MTQ3LDEyLjY0NzQ2IDQuNzExNzcsMy4zOTIyNiAyNy4xMDMsMTUuMTc5NTMgMjguMTUyMDIsMTQuODE5ODggMC43OTgyOSwtMC4yNzM2OSA0Ljg0OTQzLC00LjU4MDIzIDkuMDAyNTUsLTkuNTcwMDggNi45NzYxLC04LjM4MTYxIDguNTIyNjMsLTkuNDM4IDIwLjMwOTMzLC0xMy44NzI3MiBsIDEyLjc1ODIxLC00LjgwMDI1IDUuMDg5MjMsNS44Nzg2NSBjIDIuNzk5MDcsMy4yMzMyNiA1LjUzOTA0LDYuNjI4OTkgNi4wODg4MSw3LjU0NjA3IDAuNTQ5NzcsMC45MTcwOSAtMi4wNDQ1NSw2Ljc2NDQyIC01Ljc2NTE4LDEyLjk5NDA3IC02LjE5NDE5LDEwLjM3MTI2IC03LjY5MTU2LDExLjg2ODg5IC0xNy43NTIxOSwxNy43NTUyMiAtNi4wNDMwNywzLjUzNTcxIC0xMS4wMDIzLDcuMDA3MjQgLTExLjAyMDUxLDcuNzE0NTEgLTAuMDE4MywwLjcwNzI2IDIuMzE1NjMsNy42MTc5OCA1LjE4NjMzLDE1LjM1NzE0IDMuNjE4OTUsOS43NTYzOCA1LjkxODc3LDE0LjA3MDY5IDcuNSwxNC4wNjk1MiAxLjI1NDMsLTkuM2UtNCA2Ljk3MDcsLTAuODk2MTQgMTIuNzAzMTEsLTEuOTg5MzYgMTAuNDIwMDYsLTEuOTg3MiAxMC40MjU3NywtMS45ODY1NCAyMy41NzE0MywyLjcwMTc2IGwgMTMuMTQ4ODYsNC42ODk0NCAwLjQxOTU0LDkuMzE2NzkgMC40MTk1NCw5LjMxNjggLTguMTU4ODcsMy4wNTI2MSBjIC0xNS44OTIwNyw1Ljk0NTk5IC0xOC44NzQzNyw2LjMyNjg5IC0zMi4wNTY4MSw0LjA5NDIgbCAtMTIuMjMzNzYsLTIuMDcyIC01LjI2NjI0LDE0LjU2MTI5IGMgLTIuODk2NDUsOC4wMDg3MSAtNS4yNTU5NSwxNS4xMiAtNS4yNDMzMywxNS44MDI4NyAwLjAxMjgsMC42ODI4NSA0Ljk5NDc1LDMuOTk2MTggMTEuMDcxNDMsNy4zNjI5MyAxMC41MDAxMSw1LjgxNzU0IDExLjM3OTI0LDYuNzAxNDQgMTcuNzExOTcsMTcuODA4MjggbCA2LjY2MzQ3LDExLjY4NjkzIC0yLjcxODEsMy42MjAyOSBjIC0xLjQ5NDk2LDEuOTkxMTUgLTQuMTcyMDksNS4zMzUxMSAtNS45NDkxOSw3LjQzMTAyIGwgLTMuMjMxMDgsMy44MTA3NSAtMTIuODUxNjUsLTQuODU3ODIgYyAtMTAuNTc3NjEsLTMuOTk4MjUgLTEzLjczNzM1LC01LjkzMjM3IC0xNy44NTcxNCwtMTAuOTMwNTggLTIuNzUzMDMsLTMuMzQwMDMgLTYuNjEyNjQsLTcuODIxNTcgLTguNTc2OTMsLTkuOTU5IGwgLTMuNTcxNDMsLTMuODg2MjMgLTEzLjU3MTQyLDcuOTI1ODMgYyAtNy40NjQyOSw0LjM1OTIgLTEzLjc0OTE5LDguMDk2ODQgLTEzLjk2NjQ2LDguMzA1ODUgLTAuMjE3MjcsMC4yMDkwMyAxLjYwMzc2LDUuNzczNyA0LjA0NjczLDEyLjM2NTk2IDQuMzI0OSwxMS42NzA2MiA0LjM5ODA4LDEyLjI2Nzc5IDIuNzgyMjEsMjIuNzAwMjIgLTIuNjY4MDMsMTcuMjI1MzIgLTIuNDAyODgsMTYuNzA0ODUgLTkuMDQ3NTEsMTcuNzYxMDIgLTMuMjc2OCwwLjUyMDg2IC03LjI5MTI1LDEuMjc5MDMgLTguOTIwOTcsMS42ODQ4MyAtMS42Mjk3MywwLjQwNTggLTMuNjE5NzUsLTAuMTA3MTQgLTQuNDIyMjUsLTEuMTM5NzMgbCAwLDAgeiBtIDUuNzU2MjIsLTkxLjIxMDkxIGMgNDAuNjM1NiwtMTUuMjAzNzEgNDAuNzIwNDcsLTc0LjYzMjM1IDAuMTI4MjgsLTg5Ljg2NjQ3IC0xMS42MzUxLC00LjM2NjYyIC0yOC4xOTgwMywtMy43NzY3NyAtMzguMzc2MDMsMS4zNjY2OSAtMzcuMjcyNiwxOC44MzU3MiAtMzUuNTAxMzMsNzIuMDkyNDQgMi45MjMxNSw4Ny44OTA0MiAxMC44NTE2Nyw0LjQ2MTYgMjQuNDAzNjgsNC42OTUzNyAzNS4zMjQ1NCwwLjYwOTM2IGwgNmUtNSwwIHoiCiAgICAgICBpZD0icGF0aDQ1ODQiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgY2xpcC1wYXRoPSJ1cmwoI2NsaXBQYXRoNDYxNykiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6Izk5OTk5OTtzdHJva2U6bm9uZSIKICAgICAgIGQ9Im0gMTM3LjQwOTE1LDI1NC44MzI1IGMgLTEuMjYzODgsLTMuMTU4NzYgLTIuMzA2NzUsLTkuNzQ4MDUgLTIuMzE3NDgsLTE0LjY0Mjg2IC0wLjAzLC0xMy42ODI0OSAtMC42Njc5MywtMTQuOTMyNTMgLTguNDc1MDcsLTE2LjYwNjg2IC0zLjcyODIyLC0wLjc5OTU3IC0xMC44OTU2OSwtMS44NzA5NCAtMTUuOTI3NzEsLTIuMzgwODYgbCAtOS4xNDkxNCwtMC45MjcxMSAtNC4wMjc3NjcsMTAuNjI5MTYgYyAtMy45MDQ5MDksMTAuMzA0OTQgLTkuNDIxNzQyLDE4LjI0MzE1IC0xMi42Nzg0NzMsMTguMjQzMTUgLTEuNzM2NjA2LDAgLTE3LjM4NDQ0NywtOC42OTg4NCAtMjEuNjgwNzksLTEyLjA1MjY0IC00LjIwMTMxLC0zLjI3OTYxIC0xLjkzMTY2NywtMTAuMTkzMjMgNi45ODA1NTksLTIxLjI2MzYzIGwgNy44NDUwODQsLTkuNzQ0ODQgLTYuMzg1ODI0LC04LjExMjMgYyAtMy41MTIyMDMsLTQuNDYxNzcgLTguMjQ1OTIzLC0xMC4zMDg1NiAtMTAuNTE5Mzc2LC0xMi45OTI4NyBsIC00LjEzMzU1MiwtNC44ODA1NyAtMTIuMzI5MjE0LDYuNjY2MjggYyAtNi43ODEwNjgsMy42NjY0NiAtMTMuNjU2NjAxLDYuNjY2MjkgLTE1LjI3ODk2NCw2LjY2NjI5IC0zLjI3MTczMSwwIC04LjMzODA4MiwtOS41NTExMiAtMTEuNjEyNDI1LC0yMS44OTE4MiAtMS43Njc0NywtNi42NjE0MiAtMS43MTAyOTcsLTYuOTgxMTIgMS43MTAzNTksLTkuNTYzNTUgMS45NDY0MjYsLTEuNDY5NDYgOS4xNjM5NTYsLTMuODA5NDYgMTYuMDM4OTU2LC01LjE5OTk5IGwgMTIuNSwtMi41MjgyMyAwLC0xNi43MDcwNCAwLC0xNi43MDcwNCAtMTAuMzU3MTQzLC0xLjc4ODE0IGMgLTUuNjk2NDI5LC0wLjk4MzQ4IC0xMi44NDM1ODEsLTMuMDIyMTMgLTE1Ljg4MjU2MSwtNC41MzAzNCAtNS4wMjI1MTMsLTIuNDkyNiAtNS40NTg0MTUsLTMuMTU1MDcgLTQuNzg5MjU5LC03LjI3ODYgMC40MDQ4ODcsLTIuNDk1MDMgMi41NDc5NTgsLTkuMTkzMzI5IDQuNzYyMzgsLTE0Ljg4NTExNyAzLjU5MjU1NywtOS4yMzQwNDYgNC40MzQ0ODgsLTEwLjM0ODcwNiA3LjgxNjYzOSwtMTAuMzQ4NzA2IDIuMDg0NzI4LDAgOS4xMDAzNDUsMy4wMDg0MSAxNS41OTAyNiw2LjY4NTM1NyBsIDExLjc5OTg0NSw2LjY4NTM1NiA0LjE2NjYzOSwtNC44OTk2NDIgYyA5LjA4ODEzNCwtMTAuNjg2OTM1IDE1LjQ2NDYyOCwtMTkuNTQ1NDcxIDE1LjQ2NDYyOCwtMjEuNDg0MjE0IDAsLTEuMTIxNTc3IC0yLjYyNDA0LC01LjIxNDY4MyAtNS44MzEyMDEsLTkuMDk1NzkgLTYuNzk0NywtOC4yMjI1MjcgLTkuODgzMDg0LC0xMy43NTk0NTkgLTkuODgzMDg0LC0xNy43MTg2MzkgMCwtMy4yMTAxMzIgMTguOTc0Nzc1LC0xNS44ODY3MTQgMjMuNzc5ODIsLTE1Ljg4NjcxNCAzLjYyNTU0OCwwIDcuODk1NDQ1LDUuODI3MzkzIDEyLjY4MjY1MywxNy4zMDg3OTkgMi4wOTEzODQsNS4wMTU4NzUgNC4zNDk2OTEsOS42OTQ0MyA1LjAxODQ2MSwxMC4zOTY3ODggMC43MTE0MiwwLjc0NzE0NSA3Ljc2OTUxLDAuMjIyNjI1IDE3LjAxMDM3LC0xLjI2NDEyNCBsIDE1Ljc5NDQxLC0yLjU0MTEzOSAwLC0xMS45MjEyNTIgYyAwLC03LjYyMTY5MyAwLjgyODc5LC0xMy45OTI2MTQgMi4yOTc5NywtMTcuNjY0NDQ4IDIuMTU0NTIsLTUuMzg0NjY0IDIuNjYwMDEsLTUuNzQzMTk1IDguMDk3MjcsLTUuNzQzMTk1IDMuMTg5NjEsMCA5Ljg2OTgxLDAuNzA4ODQ5IDE0Ljg0NDg5LDEuNTc1MjIxIGwgOS4wNDU1OCwxLjU3NTIyMiAwLDYuOTIyNDYxIGMgMCwzLjgwNzM1NCAtMS42NTQxMSwxMi4xNTg2NzEgLTMuNjc1ODEsMTguNTU4NDg0IC0yLjAyMTcsNi4zOTk4MTMgLTMuNDY4MTMsMTEuODI5MTk5IC0zLjIxNDI5LDEyLjA2NTMwMiAwLjI1Mzg1LDAuMjM2MTAzIDYuODI1MTIsMy44MjAwOTUgMTQuNjAyODMsNy45NjQ0MyBsIDE0LjE0MTI5LDcuNTM1MTUxIDguNzE1ODYsLTkuNDM1MTA4IGMgOC4yMzYzMiwtOC45MTYwMjUgMTUuMzYyMiwtMTMuOTA0MDIgMTkuODYzMzIsLTEzLjkwNDAyIDEuNzg1MjIsMCAxOC4xMzgyMywxOC4wMjAzMzIgMTguMTM4MjMsMTkuOTg3NTY4IDAsMi42NTQxMDYgLTEwLjUxNTYzLDEyLjcwNTkzMiAtMTguOTQzNzQsMTguMTA4MjIzIC05LjEwMjQ2LDUuODM0NTI5IC05LjgyMTI3LDYuNjUyNjgzIC04LjkzNzc2LDEwLjE3MjkgMS41NzI0Miw2LjI2NDk3NiA5LjQwNjEsMjUuOTA3NzU2IDEwLjYzNTE1LDI2LjY2NzM0NiAwLjYyNTc4LDAuMzg2NzUgNi41NTQ5NywtMC4wMjE2IDEzLjE3NTk3LC0wLjkwNzUxIDkuOTk2ODEsLTEuMzM3NTYgMTMuMTE4OTMsLTEuMjUwNDQgMTguNDExNDMsMC41MTM3MyBsIDYuMzczMjQsMi4xMjQ0MSAwLDEzLjM4OTU2IDAsMTMuMzg5NTYgLTYuNDI4NTcsMS44OTQyNiBjIC01LjE3ODU3LDEuNTI1OTMgLTguODczMjksMS41NjYyIC0xOS4wMDE0NSwwLjIwNzEyIC03LjQxODEsLTAuOTk1NDIgLTEzLjA1NTgyLC0xLjE2MDU5IC0xMy43NTA4NCwtMC40MDI4NiAtMS45NTY5OCwyLjEzMzYgLTEwLjM3NjYsMjguOTc0NTYgLTkuNTIyNDEsMzAuMzU2NjUgMC40MzcwMSwwLjcwNzExIDUuMTk2NzEsMy45MDA5MSAxMC41NzcxLDcuMDk3MzQgNi4yNTM4LDMuNzE1MzIgMTEuMTc5Niw3LjkyMjgzIDEzLjY1NTU4LDExLjY2NDI5IGwgMy44NzMwNyw1Ljg1MjYgLTIuODYyODgsMy42Mzk1NiBjIC00LjM4ODY0LDUuNTc5MjcgLTEyLjQyNDY2LDE0LjMxMjE1IC0xNC4xNTI5NywxNS4zODAzMSAtMy4yOTk4MywyLjAzOTQgLTEyLjY5MzA1LC0zLjgxMzQzIC0yMS42NzIzNSwtMTMuNTAzODYgbCAtOS4yODU3MSwtMTAuMDIxMTEgLTEzLjU3MTQzLDguMTMxMTMgYyAtNy40NjQyOCw0LjQ3MjExIC0xMy43OTg1MSw4LjMxMTkzIC0xNC4wNzYwNiw4LjUzMjkxIC0wLjI3NzU1LDAuMjIxIDEuMjA2MDIsNS41Mzg0NCAzLjI5NjgyLDExLjgxNjU0IDIuNTU1MzQsNy42NzMgMy42NTczMywxMy42NzMzNSAzLjM2MTc4LDE4LjMwNDkgbCAtMC40Mzk2OCw2Ljg5MDE1IC03Ljg1NzE0LDEuNjQ3OTUgYyAtNC4zMjE0MywwLjkwNjM5IC0xMC44NDA5MiwxLjcwOTk2IC0xNC40ODc3NSwxLjc4NTcyIC02LjQ1MDUyLDAuMTM0IC02LjY5MzAxLC0wLjAxODMgLTguOTI4NTcsLTUuNjA1NDQgeiBtIDE5LjYxMDM2LC03My4zNjUyIGMgMzQuMDU0NDYsLTE2LjY2MTI5IDM1LjkyMDY2LC02Ny4xMzAyOCAzLjE3Mzg0LC04NS44MzI0NjUgLTEyLjU4MDczLC03LjE4NTAzOCAtMzEuMjQ4ODMsLTguMTE2ODg3IC00NC42MTg4NCwtMi4yMjcyMjIgLTguMjMyNTYsMy42MjY1NSAtMTguNTQ4MDE2LDEzLjUwNDAxNyAtMjMuMDkxMTgsMjIuMTEwNzI3IC0zLjQxNjc3Niw2LjQ3Mjg1IC0zLjgwMDcyMSw4LjcxNTUgLTMuODAwNzIxLDIyLjIwMDIxIDAsMTIuOTAzNDQgMC40NTc5MTIsMTUuODU3NjEgMy4yNzYxNiwyMS4xMzU4IDYuOTg0NTUyLDEzLjA4MTEyIDE4LjgyNDA4MSwyMi40NTc5NSAzMi43ODk0NDEsMjUuOTY5MDUgOS4zMTMzNywyLjM0MTUxIDIzLjY3OTQ3LDAuODQ3NDggMzIuMjcxMywtMy4zNTYxIHoiCiAgICAgICBpZD0icGF0aDI5ODUiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTc1LjU2MjE2LDI3OC40NjA0KSIgLz4KICA8L2c+Cjwvc3ZnPgo="); background-size: 15px 15px; background-repeat: no-repeat; background-position: center center; overflow: visible; } div.jsxc_settings:hover, div.jsxc_settings .hover { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMjcyLjcwNTkzIgogICBoZWlnaHQ9IjI3NS4xOTQ0OSIKICAgaWQ9InN2ZzIiCiAgIHZlcnNpb249IjEuMSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC40OC4zLjEgcjk4ODYiCiAgIHNvZGlwb2RpOmRvY25hbWU9ImdlYXIuc3ZnIj4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iMC43IgogICAgIGlua3NjYXBlOmN4PSIxNTkuMTExMTgiCiAgICAgaW5rc2NhcGU6Y3k9Ijc1LjQ3NTkzNiIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0icHgiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjExMTEiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iODQwIgogICAgIGlua3NjYXBlOndpbmRvdy14PSIxOTEiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjI4IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjAiCiAgICAgZml0LW1hcmdpbi10b3A9IjAiCiAgICAgZml0LW1hcmdpbi1sZWZ0PSIwIgogICAgIGZpdC1tYXJnaW4tcmlnaHQ9IjAiCiAgICAgZml0LW1hcmdpbi1ib3R0b209IjAiIC8+CiAgPGRlZnMKICAgICBpZD0iZGVmczQiPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDQ2MTciPgogICAgICA8cGF0aAogICAgICAgICBzb2RpcG9kaTp0eXBlPSJhcmMiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNiM2IzYjM7c3Ryb2tlOm5vbmUiCiAgICAgICAgIGlkPSJwYXRoNDYxOSIKICAgICAgICAgc29kaXBvZGk6Y3g9IjE0MS40Mjg1NyIKICAgICAgICAgc29kaXBvZGk6Y3k9IjE0MC45MDg3NyIKICAgICAgICAgc29kaXBvZGk6cng9IjEyNC4yODU3MSIKICAgICAgICAgc29kaXBvZGk6cnk9IjEyNC4yODU3MSIKICAgICAgICAgZD0ibSAyNjUuNzE0MjksMTQwLjkwODc3IGEgMTI0LjI4NTcxLDEyNC4yODU3MSAwIDEgMSAtMjQ4LjU3MTQzLDAgMTI0LjI4NTcxLDEyNC4yODU3MSAwIDEgMSAyNDguNTcxNDMsMCB6IgogICAgICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzAuNDg2NTYsMjc1LjE0ODg4KSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgPC9kZWZzPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTciPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNzUuNTYyMTYsLTI3OC40NjA0KSI+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2IzYjNiMztzdHJva2U6bm9uZSIKICAgICAgIGQ9Im0gMzIyLjkwMDc3LDU1Mi4zNzYwOSBjIC0wLjgwMjUsLTEuMDMyNjUgLTQuMTI5OCwtNi43NzgxMiAtNy4zOTQsLTEyLjc2NzcxIC01LjY2MDYyLC0xMC4zODY4NiAtNS45MzQ5LC0xMS40NTk3MSAtNS45MzQ5LC0yMy4yMTQyOSAwLC02Ljc3ODI3IC0wLjE2MDcxLC0xMi4zMzQ3MSAtMC4zNTcxNCwtMTIuMzQ3NjQgLTAuMTk2NDMsLTAuMDEyOSAtNy4xMDcxNCwtMS4yNTM1MSAtMTUuMzU3MTQsLTIuNzU2ODYgLTguMjUsLTEuNTAzMzIgLTE1LjQyMDU0LC0yLjI5NjMyIC0xNS45MzQ1MywtMS43NjIyIC0wLjUxMzk5LDAuNTM0MTMgLTIuNjUwNjgsNS44NTIgLTQuNzQ4MiwxMS44MTc1IC0zLjI5Njc5LDkuMzc2MyAtNC45MTI3MSwxMS44MTMzOSAtMTEuOTIyNjEsMTcuOTgxMzUgLTEzLjE2Nzc2LDExLjU4NjE3IC0xMi43ODAyNCwxMS40NzQxOCAtMjEuODk4NjUsNi4zMjgwNyBsIC03LjkxODY3LC00LjQ2OTAyIDIuNTk0NzMsLTEzLjcwNDkyIGMgMi40OTM3NCwtMTMuMTcxNDggMi45MDIzMywtMTQuMDU1MjkgMTAuNDk3MDUsLTIyLjcwNTc5IDQuMzQ2MjcsLTQuOTUwNDcgNy45MDIzMSwtOS41NjY3NiA3LjkwMjMxLC0xMC4yNTg0IDAsLTEuNDc1NTkgLTE4LjMxMzM3LC0yMy44MDc5MyAtMjAuMDYxNjUsLTI0LjQ2NDMgLTAuNjU0MzMsLTAuMjQ1NjYgLTYuMzE3OTUsMi41MTEzMyAtMTIuNTg1ODMsNi4xMjY2NCBsIC0xMS4zOTYxNCw2LjU3MzI5IC0xMy4xMzEzMiwtMC40MTIzNCAtMTMuMTMxMzEsLTAuNDEyMzYgLTMuMjgwMywtOC43MzUzOSAtMy4yODAzMSwtOC43MzU0IDEwLjAwNjk2LC04LjE3NTE3IGMgMTAuODQxMzEsLTguODU2NzggMTIuNzE2MzUsLTkuNzAxNDggMjcuMjE3MDQsLTEyLjI2MTEzIGwgOS42NDI4NiwtMS43MDIxNCAwLC0xNi4xNjU1MyAwLC0xNi4xNjU1MyAtNy41LC0xLjQ3NzI2IGMgLTQuMTI1LC0wLjgxMjQ5IC05Ljg0MjUsLTEuODgxMSAtMTIuNzA1NTYsLTIuMzc0NjkgLTMuNDY0NjQsLTAuNTk3MyAtOC43NjIwMywtMy44NTQyOSAtMTUuODM5ODcsLTkuNzM4ODIgbCAtMTAuNjM0MzIsLTguODQxNCAzLjE3ODg1LC04LjUyODA2IDMuMTc4ODYsLTguNTI4MDUgMTMuNjA2MzgsLTAuNDA3MzYgMTMuNjA2MzcsLTAuNDA3MzUgMTAuOTU4NCw2LjQ3ODc4IGMgNi4wMjcxMiwzLjU2MzMzIDExLjM4NzQyLDYuNDQ4MDUgMTEuOTExNzgsNi40MTA0OCAxLjA3MjUzLC0wLjA3NjggMTkuMjU3NTEsLTIyLjE3MDk2IDIwLjAwNzIxLC0yNC4zMDgwNiAwLjI2NTMxLC0wLjc1NjMxIC0yLjY3ODE5LC01LjA2MzE2IC02LjU0MTEyLC05LjU3MDggLTkuMjM0MDUsLTEwLjc3NTE4IC04Ljk0Nzg5LC0xMC4xNzIwOSAtMTEuNzUxODQsLTI0Ljc2NzI0IGwgLTIuNDMyMzcsLTEyLjY2MTAyIDguMjMwNjYsLTQuOTAyOTcgOC4yMzA2NSwtNC45MDI5OCAxMC41OTI3Miw5LjA3NDQyIGMgOS45Njg4LDguNTM5OTMgMTAuODQ0NTgsOS43NzM3NSAxNC44NjksMjAuOTQ3ODMgMi43ODk4Niw3Ljc0NjI0IDQuOTc5MDcsMTEuNzg3MDYgNi4yOTgxLDExLjYyNSAxLjExMiwtMC4xMzY2MyA4LjI4OTY3LC0xLjMzNzU0IDE1Ljk1MDM4LC0yLjY2ODY5IGwgMTMuOTI4NTcsLTIuNDIwMjggMCwtMTIuMTg2NDEgYyAwLC0xMS43ODUyMSAwLjIxODU2LC0xMi41OTA5MyA2LjYzODg3LC0yNC40NzQxNiAzLjY1MTM5LC02Ljc1ODI3IDYuODM2NzgsLTEyLjUyNjcyIDcuMDc4NjUsLTEyLjgxODc4IDAuMjQxODcsLTAuMjkyMDYgNC42MTA2MywwLjI1NTk2IDkuNzA4MzQsMS4yMTc4MyAxMC4zNDQ0MSwxLjk1MTg2IDkuMjkyMTcsMC4zNDQ2IDEyLjM5NjI2LDE4LjkzNDUgMS41Mzc1MSw5LjIwNzkgMS40MTQzOCwxMC4xNTIzOCAtMi44NjU1LDIxLjk4MDM5IC0yLjQ1OTYyLDYuNzk3NDkgLTQuMjkxNzcsMTIuNDg4ODUgLTQuMDcxNDcsMTIuNjQ3NDYgNC43MTE3NywzLjM5MjI2IDI3LjEwMywxNS4xNzk1MyAyOC4xNTIwMiwxNC44MTk4OCAwLjc5ODI5LC0wLjI3MzY5IDQuODQ5NDMsLTQuNTgwMjMgOS4wMDI1NSwtOS41NzAwOCA2Ljk3NjEsLTguMzgxNjEgOC41MjI2MywtOS40MzggMjAuMzA5MzMsLTEzLjg3MjcyIGwgMTIuNzU4MjEsLTQuODAwMjUgNS4wODkyMyw1Ljg3ODY1IGMgMi43OTkwNywzLjIzMzI2IDUuNTM5MDQsNi42Mjg5OSA2LjA4ODgxLDcuNTQ2MDcgMC41NDk3NywwLjkxNzA5IC0yLjA0NDU1LDYuNzY0NDIgLTUuNzY1MTgsMTIuOTk0MDcgLTYuMTk0MTksMTAuMzcxMjYgLTcuNjkxNTYsMTEuODY4ODkgLTE3Ljc1MjE5LDE3Ljc1NTIyIC02LjA0MzA3LDMuNTM1NzEgLTExLjAwMjMsNy4wMDcyNCAtMTEuMDIwNTEsNy43MTQ1MSAtMC4wMTgzLDAuNzA3MjYgMi4zMTU2Myw3LjYxNzk4IDUuMTg2MzMsMTUuMzU3MTQgMy42MTg5NSw5Ljc1NjM4IDUuOTE4NzcsMTQuMDcwNjkgNy41LDE0LjA2OTUyIDEuMjU0MywtOS4zZS00IDYuOTcwNywtMC44OTYxNCAxMi43MDMxMSwtMS45ODkzNiAxMC40MjAwNiwtMS45ODcyIDEwLjQyNTc3LC0xLjk4NjU0IDIzLjU3MTQzLDIuNzAxNzYgbCAxMy4xNDg4Niw0LjY4OTQ0IDAuNDE5NTQsOS4zMTY3OSAwLjQxOTU0LDkuMzE2OCAtOC4xNTg4NywzLjA1MjYxIGMgLTE1Ljg5MjA3LDUuOTQ1OTkgLTE4Ljg3NDM3LDYuMzI2ODkgLTMyLjA1NjgxLDQuMDk0MiBsIC0xMi4yMzM3NiwtMi4wNzIgLTUuMjY2MjQsMTQuNTYxMjkgYyAtMi44OTY0NSw4LjAwODcxIC01LjI1NTk1LDE1LjEyIC01LjI0MzMzLDE1LjgwMjg3IDAuMDEyOCwwLjY4Mjg1IDQuOTk0NzUsMy45OTYxOCAxMS4wNzE0Myw3LjM2MjkzIDEwLjUwMDExLDUuODE3NTQgMTEuMzc5MjQsNi43MDE0NCAxNy43MTE5NywxNy44MDgyOCBsIDYuNjYzNDcsMTEuNjg2OTMgLTIuNzE4MSwzLjYyMDI5IGMgLTEuNDk0OTYsMS45OTExNSAtNC4xNzIwOSw1LjMzNTExIC01Ljk0OTE5LDcuNDMxMDIgbCAtMy4yMzEwOCwzLjgxMDc1IC0xMi44NTE2NSwtNC44NTc4MiBjIC0xMC41Nzc2MSwtMy45OTgyNSAtMTMuNzM3MzUsLTUuOTMyMzcgLTE3Ljg1NzE0LC0xMC45MzA1OCAtMi43NTMwMywtMy4zNDAwMyAtNi42MTI2NCwtNy44MjE1NyAtOC41NzY5MywtOS45NTkgbCAtMy41NzE0MywtMy44ODYyMyAtMTMuNTcxNDIsNy45MjU4MyBjIC03LjQ2NDI5LDQuMzU5MiAtMTMuNzQ5MTksOC4wOTY4NCAtMTMuOTY2NDYsOC4zMDU4NSAtMC4yMTcyNywwLjIwOTAzIDEuNjAzNzYsNS43NzM3IDQuMDQ2NzMsMTIuMzY1OTYgNC4zMjQ5LDExLjY3MDYyIDQuMzk4MDgsMTIuMjY3NzkgMi43ODIyMSwyMi43MDAyMiAtMi42NjgwMywxNy4yMjUzMiAtMi40MDI4OCwxNi43MDQ4NSAtOS4wNDc1MSwxNy43NjEwMiAtMy4yNzY4LDAuNTIwODYgLTcuMjkxMjUsMS4yNzkwMyAtOC45MjA5NywxLjY4NDgzIC0xLjYyOTczLDAuNDA1OCAtMy42MTk3NSwtMC4xMDcxNCAtNC40MjIyNSwtMS4xMzk3MyBsIDAsMCB6IG0gNS43NTYyMiwtOTEuMjEwOTEgYyA0MC42MzU2LC0xNS4yMDM3MSA0MC43MjA0NywtNzQuNjMyMzUgMC4xMjgyOCwtODkuODY2NDcgLTExLjYzNTEsLTQuMzY2NjIgLTI4LjE5ODAzLC0zLjc3Njc3IC0zOC4zNzYwMywxLjM2NjY5IC0zNy4yNzI2LDE4LjgzNTcyIC0zNS41MDEzMyw3Mi4wOTI0NCAyLjkyMzE1LDg3Ljg5MDQyIDEwLjg1MTY3LDQuNDYxNiAyNC40MDM2OCw0LjY5NTM3IDM1LjMyNDU0LDAuNjA5MzYgbCA2ZS01LDAgeiIKICAgICAgIGlkPSJwYXRoNDU4NCIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGg0NjE3KSIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTpub25lIgogICAgICAgZD0ibSAxMzcuNDA5MTUsMjU0LjgzMjUgYyAtMS4yNjM4OCwtMy4xNTg3NiAtMi4zMDY3NSwtOS43NDgwNSAtMi4zMTc0OCwtMTQuNjQyODYgLTAuMDMsLTEzLjY4MjQ5IC0wLjY2NzkzLC0xNC45MzI1MyAtOC40NzUwNywtMTYuNjA2ODYgLTMuNzI4MjIsLTAuNzk5NTcgLTEwLjg5NTY5LC0xLjg3MDk0IC0xNS45Mjc3MSwtMi4zODA4NiBsIC05LjE0OTE0LC0wLjkyNzExIC00LjAyNzc2NywxMC42MjkxNiBjIC0zLjkwNDkwOSwxMC4zMDQ5NCAtOS40MjE3NDIsMTguMjQzMTUgLTEyLjY3ODQ3MywxOC4yNDMxNSAtMS43MzY2MDYsMCAtMTcuMzg0NDQ3LC04LjY5ODg0IC0yMS42ODA3OSwtMTIuMDUyNjQgLTQuMjAxMzEsLTMuMjc5NjEgLTEuOTMxNjY3LC0xMC4xOTMyMyA2Ljk4MDU1OSwtMjEuMjYzNjMgbCA3Ljg0NTA4NCwtOS43NDQ4NCAtNi4zODU4MjQsLTguMTEyMyBjIC0zLjUxMjIwMywtNC40NjE3NyAtOC4yNDU5MjMsLTEwLjMwODU2IC0xMC41MTkzNzYsLTEyLjk5Mjg3IGwgLTQuMTMzNTUyLC00Ljg4MDU3IC0xMi4zMjkyMTQsNi42NjYyOCBjIC02Ljc4MTA2OCwzLjY2NjQ2IC0xMy42NTY2MDEsNi42NjYyOSAtMTUuMjc4OTY0LDYuNjY2MjkgLTMuMjcxNzMxLDAgLTguMzM4MDgyLC05LjU1MTEyIC0xMS42MTI0MjUsLTIxLjg5MTgyIC0xLjc2NzQ3LC02LjY2MTQyIC0xLjcxMDI5NywtNi45ODExMiAxLjcxMDM1OSwtOS41NjM1NSAxLjk0NjQyNiwtMS40Njk0NiA5LjE2Mzk1NiwtMy44MDk0NiAxNi4wMzg5NTYsLTUuMTk5OTkgbCAxMi41LC0yLjUyODIzIDAsLTE2LjcwNzA0IDAsLTE2LjcwNzA0IC0xMC4zNTcxNDMsLTEuNzg4MTQgYyAtNS42OTY0MjksLTAuOTgzNDggLTEyLjg0MzU4MSwtMy4wMjIxMyAtMTUuODgyNTYxLC00LjUzMDM0IC01LjAyMjUxMywtMi40OTI2IC01LjQ1ODQxNSwtMy4xNTUwNyAtNC43ODkyNTksLTcuMjc4NiAwLjQwNDg4NywtMi40OTUwMyAyLjU0Nzk1OCwtOS4xOTMzMjkgNC43NjIzOCwtMTQuODg1MTE3IDMuNTkyNTU3LC05LjIzNDA0NiA0LjQzNDQ4OCwtMTAuMzQ4NzA2IDcuODE2NjM5LC0xMC4zNDg3MDYgMi4wODQ3MjgsMCA5LjEwMDM0NSwzLjAwODQxIDE1LjU5MDI2LDYuNjg1MzU3IGwgMTEuNzk5ODQ1LDYuNjg1MzU2IDQuMTY2NjM5LC00Ljg5OTY0MiBjIDkuMDg4MTM0LC0xMC42ODY5MzUgMTUuNDY0NjI4LC0xOS41NDU0NzEgMTUuNDY0NjI4LC0yMS40ODQyMTQgMCwtMS4xMjE1NzcgLTIuNjI0MDQsLTUuMjE0NjgzIC01LjgzMTIwMSwtOS4wOTU3OSAtNi43OTQ3LC04LjIyMjUyNyAtOS44ODMwODQsLTEzLjc1OTQ1OSAtOS44ODMwODQsLTE3LjcxODYzOSAwLC0zLjIxMDEzMiAxOC45NzQ3NzUsLTE1Ljg4NjcxNCAyMy43Nzk4MiwtMTUuODg2NzE0IDMuNjI1NTQ4LDAgNy44OTU0NDUsNS44MjczOTMgMTIuNjgyNjUzLDE3LjMwODc5OSAyLjA5MTM4NCw1LjAxNTg3NSA0LjM0OTY5MSw5LjY5NDQzIDUuMDE4NDYxLDEwLjM5Njc4OCAwLjcxMTQyLDAuNzQ3MTQ1IDcuNzY5NTEsMC4yMjI2MjUgMTcuMDEwMzcsLTEuMjY0MTI0IGwgMTUuNzk0NDEsLTIuNTQxMTM5IDAsLTExLjkyMTI1MiBjIDAsLTcuNjIxNjkzIDAuODI4NzksLTEzLjk5MjYxNCAyLjI5Nzk3LC0xNy42NjQ0NDggMi4xNTQ1MiwtNS4zODQ2NjQgMi42NjAwMSwtNS43NDMxOTUgOC4wOTcyNywtNS43NDMxOTUgMy4xODk2MSwwIDkuODY5ODEsMC43MDg4NDkgMTQuODQ0ODksMS41NzUyMjEgbCA5LjA0NTU4LDEuNTc1MjIyIDAsNi45MjI0NjEgYyAwLDMuODA3MzU0IC0xLjY1NDExLDEyLjE1ODY3MSAtMy42NzU4MSwxOC41NTg0ODQgLTIuMDIxNyw2LjM5OTgxMyAtMy40NjgxMywxMS44MjkxOTkgLTMuMjE0MjksMTIuMDY1MzAyIDAuMjUzODUsMC4yMzYxMDMgNi44MjUxMiwzLjgyMDA5NSAxNC42MDI4Myw3Ljk2NDQzIGwgMTQuMTQxMjksNy41MzUxNTEgOC43MTU4NiwtOS40MzUxMDggYyA4LjIzNjMyLC04LjkxNjAyNSAxNS4zNjIyLC0xMy45MDQwMiAxOS44NjMzMiwtMTMuOTA0MDIgMS43ODUyMiwwIDE4LjEzODIzLDE4LjAyMDMzMiAxOC4xMzgyMywxOS45ODc1NjggMCwyLjY1NDEwNiAtMTAuNTE1NjMsMTIuNzA1OTMyIC0xOC45NDM3NCwxOC4xMDgyMjMgLTkuMTAyNDYsNS44MzQ1MjkgLTkuODIxMjcsNi42NTI2ODMgLTguOTM3NzYsMTAuMTcyOSAxLjU3MjQyLDYuMjY0OTc2IDkuNDA2MSwyNS45MDc3NTYgMTAuNjM1MTUsMjYuNjY3MzQ2IDAuNjI1NzgsMC4zODY3NSA2LjU1NDk3LC0wLjAyMTYgMTMuMTc1OTcsLTAuOTA3NTEgOS45OTY4MSwtMS4zMzc1NiAxMy4xMTg5MywtMS4yNTA0NCAxOC40MTE0MywwLjUxMzczIGwgNi4zNzMyNCwyLjEyNDQxIDAsMTMuMzg5NTYgMCwxMy4zODk1NiAtNi40Mjg1NywxLjg5NDI2IGMgLTUuMTc4NTcsMS41MjU5MyAtOC44NzMyOSwxLjU2NjIgLTE5LjAwMTQ1LDAuMjA3MTIgLTcuNDE4MSwtMC45OTU0MiAtMTMuMDU1ODIsLTEuMTYwNTkgLTEzLjc1MDg0LC0wLjQwMjg2IC0xLjk1Njk4LDIuMTMzNiAtMTAuMzc2NiwyOC45NzQ1NiAtOS41MjI0MSwzMC4zNTY2NSAwLjQzNzAxLDAuNzA3MTEgNS4xOTY3MSwzLjkwMDkxIDEwLjU3NzEsNy4wOTczNCA2LjI1MzgsMy43MTUzMiAxMS4xNzk2LDcuOTIyODMgMTMuNjU1NTgsMTEuNjY0MjkgbCAzLjg3MzA3LDUuODUyNiAtMi44NjI4OCwzLjYzOTU2IGMgLTQuMzg4NjQsNS41NzkyNyAtMTIuNDI0NjYsMTQuMzEyMTUgLTE0LjE1Mjk3LDE1LjM4MDMxIC0zLjI5OTgzLDIuMDM5NCAtMTIuNjkzMDUsLTMuODEzNDMgLTIxLjY3MjM1LC0xMy41MDM4NiBsIC05LjI4NTcxLC0xMC4wMjExMSAtMTMuNTcxNDMsOC4xMzExMyBjIC03LjQ2NDI4LDQuNDcyMTEgLTEzLjc5ODUxLDguMzExOTMgLTE0LjA3NjA2LDguNTMyOTEgLTAuMjc3NTUsMC4yMjEgMS4yMDYwMiw1LjUzODQ0IDMuMjk2ODIsMTEuODE2NTQgMi41NTUzNCw3LjY3MyAzLjY1NzMzLDEzLjY3MzM1IDMuMzYxNzgsMTguMzA0OSBsIC0wLjQzOTY4LDYuODkwMTUgLTcuODU3MTQsMS42NDc5NSBjIC00LjMyMTQzLDAuOTA2MzkgLTEwLjg0MDkyLDEuNzA5OTYgLTE0LjQ4Nzc1LDEuNzg1NzIgLTYuNDUwNTIsMC4xMzQgLTYuNjkzMDEsLTAuMDE4MyAtOC45Mjg1NywtNS42MDU0NCB6IG0gMTkuNjEwMzYsLTczLjM2NTIgYyAzNC4wNTQ0NiwtMTYuNjYxMjkgMzUuOTIwNjYsLTY3LjEzMDI4IDMuMTczODQsLTg1LjgzMjQ2NSAtMTIuNTgwNzMsLTcuMTg1MDM4IC0zMS4yNDg4MywtOC4xMTY4ODcgLTQ0LjYxODg0LC0yLjIyNzIyMiAtOC4yMzI1NiwzLjYyNjU1IC0xOC41NDgwMTYsMTMuNTA0MDE3IC0yMy4wOTExOCwyMi4xMTA3MjcgLTMuNDE2Nzc2LDYuNDcyODUgLTMuODAwNzIxLDguNzE1NSAtMy44MDA3MjEsMjIuMjAwMjEgMCwxMi45MDM0NCAwLjQ1NzkxMiwxNS44NTc2MSAzLjI3NjE2LDIxLjEzNTggNi45ODQ1NTIsMTMuMDgxMTIgMTguODI0MDgxLDIyLjQ1Nzk1IDMyLjc4OTQ0MSwyNS45NjkwNSA5LjMxMzM3LDIuMzQxNTEgMjMuNjc5NDcsMC44NDc0OCAzMi4yNzEzLC0zLjM1NjEgeiIKICAgICAgIGlkPSJwYXRoMjk4NSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzUuNTYyMTYsMjc4LjQ2MDQpIiAvPgogIDwvZz4KPC9zdmc+Cg=="); } div.jsxc_settings ul { list-style: none; padding: 0; margin: 0; position: absolute; top: 30px; left: 0; box-shadow: 0 5px 5px -5px inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; z-index: 110; overflow: visible; background-color: #1a1a1a; display: none; } div.jsxc_settings li { width: 170px; margin-left: 20px; padding-left: 10px; height: 30px; line-height: 30px; text-align: left; cursor: pointer; } div.jsxc_settings li:first-child { border-top: 1px solid #cccccc; } div.jsxc_settings li.jsxc_disabled { color: #4d4d4d; cursor: default; } div.jsxc_settings li:hover:not(.jsxc_disabled) { color: #fff; background-color: #3f8fba; } div.jsxc_transfer:hover { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICBpZD0ic3ZnMzA0MSIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4LjMuMSByOTg4NiIKICAgd2lkdGg9IjE1IgogICBoZWlnaHQ9IjE1IgogICBzb2RpcG9kaTpkb2NuYW1lPSJwYWRsb2NrX29wZW4td2hpdGUuc3ZnIj4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGEzMDQ3Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZT48L2RjOnRpdGxlPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzMzA0NSIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgb2JqZWN0dG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBndWlkZXRvbGVyYW5jZT0iMTAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE0NDQiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iNzg3IgogICAgIGlkPSJuYW1lZHZpZXczMDQzIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp6b29tPSI0NC41MDA1ODciCiAgICAgaW5rc2NhcGU6Y3g9IjkuMjEzNDU4MyIKICAgICBpbmtzY2FwZTpjeT0iOC4wMjMyMzU2IgogICAgIGlua3NjYXBlOndpbmRvdy14PSI2NSIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iMjQiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMCIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmczMDQxIiAvPgogIDxyZWN0CiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2ZmZmZmZiIKICAgICBpZD0icmVjdDMwNTEiCiAgICAgd2lkdGg9IjExLjA1OTMyMiIKICAgICBoZWlnaHQ9IjYuOTkxNTI1NyIKICAgICB4PSIyLjE2MTAxNzIiCiAgICAgeT0iOC4wMDg0NzQzIiAvPgogIDxwYXRoCiAgICAgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MS44OTk5OTk5ODAwMDAwMDAwMztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1vcGFjaXR5OjE7c3Ryb2tlLWRhc2hhcnJheTpub25lIgogICAgIGQ9Im0gMy4wODI2MjgsNS4wMjExODY0IGMgMCwwIC0wLjEyNzExOSwtNC4wNjc3OTY1MiA0LjQ0OTE1MiwtNC4wNjc3OTY1MiA0LjU3NjI2OCwwIDQuNzAzMzg2LDMuOTQwNjc3ODIgNC43MDMzODYsMy45NDA2Nzc4MiBsIDAuMDYzNTYsNS41OTMyMTkzIDAsMCIKICAgICBpZD0icGF0aDM4NDgiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KPC9zdmc+Cg=="); } div.jsxc_transfer.jsxc_fin { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICBpZD0ic3ZnMzA0MSIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4K2RldmVsIHIiCiAgIHdpZHRoPSIxNSIKICAgaGVpZ2h0PSIxNSIKICAgc29kaXBvZGk6ZG9jbmFtZT0icGFkbG9ja19jbG9zZV9ncmV5LnN2ZyI+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhMzA0NyI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczMwNDUiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODU1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaWQ9Im5hbWVkdmlldzMwNDMiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIGlua3NjYXBlOnpvb209IjMyIgogICAgIGlua3NjYXBlOmN4PSIxMi43OTIxMTciCiAgICAgaW5rc2NhcGU6Y3k9IjguOTQ0OTIzOCIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iNjUiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjI0IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMzA0MSIKICAgICBib3JkZXJsYXllcj0idHJ1ZSIgLz4KICA8cmVjdAogICAgIHN0eWxlPSJmaWxsOiM4MDgwODA7c3Ryb2tlOiM4MDgwODA7c3Ryb2tlLXdpZHRoOjAuOTI1MjI3OTQiCiAgICAgaWQ9InJlY3QzMDUxIgogICAgIHdpZHRoPSIxMC4yMzIzOTQiCiAgICAgaGVpZ2h0PSI2LjQ2ODc1NDgiCiAgICAgeD0iMi41NTM0Mjc1IgogICAgIHk9IjguMDc0MjU1IiAvPgogIDxhCiAgICAgaWQ9ImE0MTU3IgogICAgIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiM4MDgwODAiPgogICAgPHBhdGgKICAgICAgIHNvZGlwb2RpOm9wZW49InRydWUiCiAgICAgICBkPSJNIDMuMTM3MjQ3Niw2Ljc5Mjg0ODkgQSA0LjUzNDEzMyw0LjUzMDE3MTQgMCAwIDEgNy42NzEzODA2LDIuMjYyNjc3NyA0LjUzNDEzMyw0LjUzMDE3MTQgMCAwIDEgMTIuMjA1NTEzLDYuNzkyODQ5MSIKICAgICAgIHNvZGlwb2RpOmVuZD0iMCIKICAgICAgIHNvZGlwb2RpOnN0YXJ0PSIzLjE0MTU5MjciCiAgICAgICBzb2RpcG9kaTpyeT0iNC41MzAxNzE0IgogICAgICAgc29kaXBvZGk6cng9IjQuNTM0MTMzIgogICAgICAgc29kaXBvZGk6Y3k9IjYuNzkyODQ5MSIKICAgICAgIHNvZGlwb2RpOmN4PSI3LjY3MTM4MDUiCiAgICAgICBzb2RpcG9kaTp0eXBlPSJhcmMiCiAgICAgICBpZD0icGF0aDQxMDEiCiAgICAgICBzdHlsZT0iZmlsbDpub25lO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTojODA4MDgwO3N0cm9rZS13aWR0aDoyLjA4ODI3NTE5O3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiIC8+CiAgPC9hPgogIDxnCiAgICAgaWQ9Imc0MTcwIgogICAgIHN0eWxlPSJmaWxsOiM4MDgwODAiPgogICAgPHJlY3QKICAgICAgIHk9IjYuNzU1NDQzMSIKICAgICAgIHg9IjIuMDkxMzgwNCIKICAgICAgIGhlaWdodD0iMS4wOTg0ODkyIgogICAgICAgd2lkdGg9IjIuMDkwNjc2OCIKICAgICAgIGlkPSJyZWN0NDE1MyIKICAgICAgIHN0eWxlPSJmaWxsOiM4MDgwODA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuMzk1MjYwODE7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIgLz4KICAgIDxyZWN0CiAgICAgICBzdHlsZT0iZmlsbDojODA4MDgwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjM5NTI2MDgxO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICBpZD0icmVjdDQxNTUiCiAgICAgICB3aWR0aD0iMi4wOTA2NzY4IgogICAgICAgaGVpZ2h0PSIxLjA5ODQ4OTIiCiAgICAgICB4PSIxMS4xNTc3ODYiCiAgICAgICB5PSI2Ljc2MzI1NTYiIC8+CiAgPC9nPgo8L3N2Zz4K"); } div.jsxc_transfer.jsxc_enc { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICBpZD0ic3ZnMzA0MSIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4K2RldmVsIHIiCiAgIHdpZHRoPSIxNSIKICAgaGVpZ2h0PSIxNSIKICAgc29kaXBvZGk6ZG9jbmFtZT0icGFkbG9ja19jbG9zZV9vcmFuZ2Uuc3ZnIj4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGEzMDQ3Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZT48L2RjOnRpdGxlPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzMzA0NSIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgb2JqZWN0dG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBndWlkZXRvbGVyYW5jZT0iMTAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE4NTUiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTA1NiIKICAgICBpZD0ibmFtZWR2aWV3MzA0MyIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMzIiCiAgICAgaW5rc2NhcGU6Y3g9IjEyLjc5MjExNyIKICAgICBpbmtzY2FwZTpjeT0iOC45NDQ5MjM4IgogICAgIGlua3NjYXBlOndpbmRvdy14PSI2NSIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iMjQiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmczMDQxIgogICAgIGJvcmRlcmxheWVyPSJ0cnVlIiAvPgogIDxyZWN0CiAgICAgc3R5bGU9ImZpbGw6I2ZmN2YyYTtzdHJva2U6I2ZmN2YyYTtzdHJva2Utd2lkdGg6MC45MjUyMjc5NCIKICAgICBpZD0icmVjdDMwNTEiCiAgICAgd2lkdGg9IjEwLjIzMjM5NCIKICAgICBoZWlnaHQ9IjYuNDY4NzU0OCIKICAgICB4PSIyLjU1MzQyNzUiCiAgICAgeT0iOC4wNzQyNTUiIC8+CiAgPGEKICAgICBpZD0iYTQxNTciCiAgICAgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2ZmN2YyYSI+CiAgICA8cGF0aAogICAgICAgc29kaXBvZGk6b3Blbj0idHJ1ZSIKICAgICAgIGQ9Ik0gMy4xMzcyNDc2LDYuNzkyODQ4OSBBIDQuNTM0MTMzLDQuNTMwMTcxNCAwIDAgMSA3LjY3MTM4MDYsMi4yNjI2Nzc3IDQuNTM0MTMzLDQuNTMwMTcxNCAwIDAgMSAxMi4yMDU1MTMsNi43OTI4NDkxIgogICAgICAgc29kaXBvZGk6ZW5kPSIwIgogICAgICAgc29kaXBvZGk6c3RhcnQ9IjMuMTQxNTkyNyIKICAgICAgIHNvZGlwb2RpOnJ5PSI0LjUzMDE3MTQiCiAgICAgICBzb2RpcG9kaTpyeD0iNC41MzQxMzMiCiAgICAgICBzb2RpcG9kaTpjeT0iNi43OTI4NDkxIgogICAgICAgc29kaXBvZGk6Y3g9IjcuNjcxMzgwNSIKICAgICAgIHNvZGlwb2RpOnR5cGU9ImFyYyIKICAgICAgIGlkPSJwYXRoNDEwMSIKICAgICAgIHN0eWxlPSJmaWxsOm5vbmU7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiNmZjdmMmE7c3Ryb2tlLXdpZHRoOjIuMDg4Mjc1MTk7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIgLz4KICA8L2E+CiAgPGcKICAgICBpZD0iZzQxNzAiCiAgICAgc3R5bGU9ImZpbGw6I2ZmN2YyYSI+CiAgICA8cmVjdAogICAgICAgeT0iNi43NTU0NDMxIgogICAgICAgeD0iMi4wOTEzODA0IgogICAgICAgaGVpZ2h0PSIxLjA5ODQ4OTIiCiAgICAgICB3aWR0aD0iMi4wOTA2NzY4IgogICAgICAgaWQ9InJlY3Q0MTUzIgogICAgICAgc3R5bGU9ImZpbGw6I2ZmN2YyYTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS4zOTUyNjA4MTtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZjdmMmE7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuMzk1MjYwODE7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0NDE1NSIKICAgICAgIHdpZHRoPSIyLjA5MDY3NjgiCiAgICAgICBoZWlnaHQ9IjEuMDk4NDg5MiIKICAgICAgIHg9IjExLjE1Nzc4NiIKICAgICAgIHk9IjYuNzYzMjU1NiIgLz4KICA8L2c+Cjwvc3ZnPgo="); } div.jsxc_transfer.jsxc_enc.jsxc_trust { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICBpZD0ic3ZnMzA0MSIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4K2RldmVsIHIiCiAgIHdpZHRoPSIxNSIKICAgaGVpZ2h0PSIxNSIKICAgc29kaXBvZGk6ZG9jbmFtZT0icGFkbG9ja19jbG9zZV9ncmVlbi5zdmciPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTMwNDciPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxkZWZzCiAgICAgaWQ9ImRlZnMzMDQ1IiAvPgogIDxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgYm9yZGVyb3BhY2l0eT0iMSIKICAgICBvYmplY3R0b2xlcmFuY2U9IjEwIgogICAgIGdyaWR0b2xlcmFuY2U9IjEwIgogICAgIGd1aWRldG9sZXJhbmNlPSIxMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTg1NSIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMDU2IgogICAgIGlkPSJuYW1lZHZpZXczMDQzIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp6b29tPSIzMiIKICAgICBpbmtzY2FwZTpjeD0iMTIuODIzMzY3IgogICAgIGlua3NjYXBlOmN5PSI4Ljk0NDkyMzgiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjY1IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9InN2ZzMwNDEiCiAgICAgYm9yZGVybGF5ZXI9InRydWUiIC8+CiAgPHJlY3QKICAgICBzdHlsZT0iZmlsbDojNDRhYTAwO3N0cm9rZTojNDRhYTAwO3N0cm9rZS13aWR0aDowLjkyNTIyNzk0IgogICAgIGlkPSJyZWN0MzA1MSIKICAgICB3aWR0aD0iMTAuMjMyMzk0IgogICAgIGhlaWdodD0iNi40Njg3NTQ4IgogICAgIHg9IjIuNTUzNDI3NSIKICAgICB5PSI4LjA3NDI1NSIgLz4KICA8cGF0aAogICAgIHN0eWxlPSJmaWxsOm5vbmU7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiM0NGFhMDA7c3Ryb2tlLXdpZHRoOjIuMDg4Mjc1MTk7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICBpZD0icGF0aDQxMDEiCiAgICAgc29kaXBvZGk6dHlwZT0iYXJjIgogICAgIHNvZGlwb2RpOmN4PSI3LjY3MTM4MDUiCiAgICAgc29kaXBvZGk6Y3k9IjYuNzkyODQ5MSIKICAgICBzb2RpcG9kaTpyeD0iNC41MzQxMzMiCiAgICAgc29kaXBvZGk6cnk9IjQuNTMwMTcxNCIKICAgICBzb2RpcG9kaTpzdGFydD0iMy4xNDE1OTI3IgogICAgIHNvZGlwb2RpOmVuZD0iMCIKICAgICBkPSJNIDMuMTM3MjQ3Niw2Ljc5Mjg0ODkgQSA0LjUzNDEzMyw0LjUzMDE3MTQgMCAwIDEgNy42NzEzODA2LDIuMjYyNjc3NyA0LjUzNDEzMyw0LjUzMDE3MTQgMCAwIDEgMTIuMjA1NTEzLDYuNzkyODQ5MSIKICAgICBzb2RpcG9kaTpvcGVuPSJ0cnVlIiAvPgogIDxyZWN0CiAgICAgc3R5bGU9ImZpbGw6IzQ0YWEwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS4zOTUyNjA4MTtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgIGlkPSJyZWN0NDE1MyIKICAgICB3aWR0aD0iMi4wOTA2NzY4IgogICAgIGhlaWdodD0iMS4wOTg0ODkyIgogICAgIHg9IjIuMDkxMzgwNCIKICAgICB5PSI2Ljc1NTQ0MzEiIC8+CiAgPHJlY3QKICAgICB5PSI2Ljc2MzI1NTYiCiAgICAgeD0iMTEuMTU3Nzg2IgogICAgIGhlaWdodD0iMS4wOTg0ODkyIgogICAgIHdpZHRoPSIyLjA5MDY3NjgiCiAgICAgaWQ9InJlY3Q0MTU1IgogICAgIHN0eWxlPSJmaWxsOiM0NGFhMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuMzk1MjYwODE7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIgLz4KPC9zdmc+Cg=="); } #colorbox { outline: none; } #cboxWrapper { outline: none; } .jsxc_loading { margin: 0 auto; width: 32px; height: 32px; border: 0; background-size: 32px 32px !important; background: url("data:image/gif;base64,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"); } /* @TODO: check */ #jsxc_loginForm input[type="submit"] { height: 34px; display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 14px; font-weight: normal; line-height: 1.428571429; text-align: center; white-space: nowrap; vertical-align: middle; cursor: pointer; border: 1px solid transparent; border-radius: 4px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; color: #fff; background-color: #5cb85c; border-color: #4cae4c; } #jsxc_notice > span:empty { display: none; } .jsxc_oneway .jsxc_avatar { -webkit-filter: grayscale(100%); filter: grayscale(100%); } .jsxc_min .jsxc_tools { display: none; } .jsxc_tools > .jsxc_disabled { opacity: 0.5; cursor: default !important; } img.jsxc_vCard { float: right; max-width: 200px; max-height: 200px; border: 5px solid #fff; border-radius: 2px; } .jsxc_alert { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; } .jsxc_alert.jsxc_alert-warning { color: #8a6d3b; background-color: #fcf8e3; border-color: #faebcc; } .jsxc_btn { width: auto; min-width: 25px; padding: 5px; background-color: rgba(240, 240, 240, 0.9); font-weight: bold; color: #555; border: 1px solid rgba(190, 190, 190, 0.9); cursor: pointer; } .jsxc_btn.jsxc_btn-primary { color: #fff; background-color: #337ab7; border-color: #2e6da4; } .jsxc_btn[disabled], .jsxc_btn[disabled]:hover { opacity: 0.65; cursor: not-allowed; color: #fff; background-color: #337ab7; border-color: #2e6da4; } rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/stylesheets/diaspora_jsxc/jsxc.webrtc.scss0000644000076400007640000003064112572247340031604 0ustar pravipravi.jsxc_remotevideo, .jsxc_noRemoteVideo { width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 9000; background-color: #999999; } .jsxc_webrtc { width: 900px; } .jsxc_webrtc .jsxc_status { z-index: 9999; border-radius: 20px; display: none; position: absolute; top: 30px; left: 50%; background-color: rgba(0, 0, 0, 0.5); color: #fff; padding: 15px; font-weight: bold; text-align: center; } .jsxc_webrtc .slimScrollDiv { opacity: 1 !important; } .jsxc_webrtc li .jsxc_name { cursor: auto; } .jsxc_webrtc li .jsxc_name:hover { color: gray; } .jsxc_videoContainer { width: 640px; height: 480px; position: relative; background-color: #999999; } .jsxc_videoContainer video { display: none; } .jsxc_videoContainer .jsxc_noRemoteVideo { display: none; } .jsxc_noRemoteVideo p { position: absolute; bottom: 0; left: 0; text-align: center; color: #fff; width: 100%; z-index: 100; } .jsxc_noRemoteVideo > div { width: 200px; height: 200px; overflow: hidden; position: absolute; top: 50%; margin-top: -100px; left: 50%; margin-left: -100px; } .jsxc_noRemoteVideo > div > div { background-color: #4d4d4d; } .jsxc_noRemoteVideo > div > div:first-child { width: 50%; height: 50%; border-radius: 50%; position: absolute; left: 50%; margin-left: -25%; top: 10%; } .jsxc_noRemoteVideo > div > div:last-child { position: absolute; bottom: -50%; width: 100%; height: 100%; border-radius: 50%; } .jsxc_localvideo { width: 160px; height: 120px; position: absolute; right: 10px; bottom: 10px; z-index: 9990; background-color: #000; cursor: pointer; } div:full-screen { width: 100%; height: 100%; background-color: #000; } div:full-screen.jsxc_localvideo { border: 1px solid #fff; } div:-webkit-full-screen { width: 100%; height: 100%; background-color: #000; } div:-moz-full-screen { width: 100%; height: 100%; background-color: #000; } div:-ms-fullscreen { width: 100%; height: 100%; background-color: #000; } div:fullscreen { width: 100%; height: 100%; background-color: #000; } div:-webkit-full-screen.jsxc_localvideo { border: 1px solid #fff; } div:-moz-full-screen.jsxc_localvideo { border: 1px solid #fff; } div:-ms-fullscreen.jsxc_localvideo { border: 1px solid #fff; } div:fullscreen.jsxc_localvideo { border: 1px solid #fff; } div.jsxc_video { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnMiIKICAgd2lkdGg9IjIwIgogICBoZWlnaHQ9IjIwIj4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGExMCI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczgiIC8+CiAgPGcKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0ibWF0cml4KDAuMDM3ODg1OTQsMCwwLDAuMDM3ODg1OTQsLTAuNDEzNDA3OTMsLTIuNjMxMDcxNikiPgogICAgPHBhdGgKICAgICAgIGlkPSJwYXRoMzkwNiIKICAgICAgIHN0eWxlPSJmaWxsOiM4MDgwODA7c3Ryb2tlOm5vbmUiCiAgICAgICBkPSJtIDM2MS42NTE0OCwzMTMuNTE3NjggMTc3LjE2MDc0LC0xMzEuNzg1MTYgMCwzMDIuMjI5OTkgTCAzNTguOTczMzgsMzUwLjE4NTE3IFogTSAxMC45MTE5MjIsMTgyLjQwNjM0IGwgMzc4LjM3MjY3OCwwIDAsMzAyLjY1NTgyIC0zNzguMzcyNjc4LDAgeiIgLz4KICA8L2c+Cjwvc3ZnPgo="); background-repeat: no-repeat; background-position: center center; background-size: 15px 15px; } div.jsxc_video:not(.jsxc_disabled):hover { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iNTM1LjAwNDU4IgogICBoZWlnaHQ9IjUxMC40MzY4IgogICBpZD0ic3ZnMzg5NiIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4K2RldmVsIHIiCiAgIHNvZGlwb2RpOmRvY25hbWU9ImNhbWVyYV9pY29uX3doaXRlLnN2ZyI+CiAgPGRlZnMKICAgICBpZD0iZGVmczM4OTgiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIGlkPSJiYXNlIgogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAuMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnpvb209IjAuOTg5OTQ5NDkiCiAgICAgaW5rc2NhcGU6Y3g9IjM1My45MTkzNCIKICAgICBpbmtzY2FwZTpjeT0iMjMzLjg0NTYiCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9InB4IgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgZml0LW1hcmdpbi10b3A9IjAiCiAgICAgZml0LW1hcmdpbi1sZWZ0PSIwIgogICAgIGZpdC1tYXJnaW4tcmlnaHQ9IjAiCiAgICAgZml0LW1hcmdpbi1ib3R0b209IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODU1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjY1IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTM5MDEiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjcxNDI3NzEsLTcyLjM2MjE3NykiPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNjE3MjY5NDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgaWQ9InJlY3QzOTA0IgogICAgICAgd2lkdGg9IjM3OC4zNzI2OCIKICAgICAgIGhlaWdodD0iMzAyLjY1NTgyIgogICAgICAgeD0iMTAuOTExOTIyIgogICAgICAgeT0iMTgyLjQwNjM0IiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOm5vbmUiCiAgICAgICBkPSJtIDM2MS42NTE0OCwzMTMuNTE3NjggMTc3LjE2MDc0LC0xMzEuNzg1MTYgMCwzMDIuMjI5OTkgLTE3OS44Mzg4NCwtMTMzLjc3NzM0IHoiCiAgICAgICBpZD0icGF0aDM5MDYiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogIDwvZz4KPC9zdmc+Cg=="); } .jsxc_controlbar { width: 640px; margin-top: 10px; } .jsxc_controlbar .jsxc_showchat { float: right; } .jsxc_multi > div { display: none; } .jsxc_snapshotbar { width: 100%; display: none; } .jsxc_snapshotbar img { height: 50px; } .jsxc_buttongroup { display: inline; } .jsxc_buttongroup button:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; margin-right: 0; } .jsxc_buttongroup button:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: 0; } .jsxc_chatarea { position: relative; float: right; height: 480px; width: 250px; background-color: #999999; } .jsxc_chatarea .jsxc_settings { display: none !important; } .jsxc_chatarea .jsxc_close { display: none !important; } .jsxc_chatarea .jsxc_video { display: none !important; } .jsxc_chatarea .jsxc_window { bottom: 0; box-shadow: none; } .jsxc_chatarea > ul { width: 250px; height: 480px; list-style: none; padding: 0; } .bubblingG { text-align: center; width: 129px; height: 80px; position: absolute; top: 40%; left: 50%; margin-left: -64px; } .bubblingG span { display: inline-block; vertical-align: middle; width: 16px; height: 16px; margin: 40px auto; background: #000; border-radius: 81px; -webkit-animation: bubblingG 1.3s infinite alternate; animation: bubblingG 1.3s infinite alternate; } #bubblingG_1 { -webkit-animation-delay: 0s; animation-delay: 0s; } #bubblingG_2 { -webkit-animation-delay: 0.39s; animation-delay: 0.39s; } #bubblingG_3 { -webkit-animation-delay: 0.78s; animation-delay: 0.78s; } @-webkit-keyframes bubblingG { 0% { width: 16px; height: 16px; background-color: #000; -webkit-transform: translateY(0); transform: translateY(0); } 100% { width: 39px; height: 39px; background-color: #fff; -webkit-transform: translateY(-34px); transform: translateY(-34px); } } @keyframes bubblingG { 0% { width: 16px; height: 16px; background-color: #000; -webkit-transform: translateY(0); transform: translateY(0); } 100% { width: 39px; height: 39px; background-color: #fff; -webkit-transform: translateY(-34px); transform: translateY(-34px); } } .jsxc_fullscreen.jsxc_localvideo { border: 1px solid #fff; } .jsxc_videoSuitable .jsxc_name { font-style: italic; } #jsxc_buddylist .jsxc_options .jsxc_video { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iNTM1LjAwNDU4IgogICBoZWlnaHQ9IjUxMC40MzY4IgogICBpZD0ic3ZnMzg5NiIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4K2RldmVsIHIiCiAgIHNvZGlwb2RpOmRvY25hbWU9ImNhbWVyYV9pY29uX3doaXRlLnN2ZyI+CiAgPGRlZnMKICAgICBpZD0iZGVmczM4OTgiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIGlkPSJiYXNlIgogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAuMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnpvb209IjAuOTg5OTQ5NDkiCiAgICAgaW5rc2NhcGU6Y3g9IjM1My45MTkzNCIKICAgICBpbmtzY2FwZTpjeT0iMjMzLjg0NTYiCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9InB4IgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgZml0LW1hcmdpbi10b3A9IjAiCiAgICAgZml0LW1hcmdpbi1sZWZ0PSIwIgogICAgIGZpdC1tYXJnaW4tcmlnaHQ9IjAiCiAgICAgZml0LW1hcmdpbi1ib3R0b209IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODU1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwNTYiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjY1IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTM5MDEiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjcxNDI3NzEsLTcyLjM2MjE3NykiPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNjE3MjY5NDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgaWQ9InJlY3QzOTA0IgogICAgICAgd2lkdGg9IjM3OC4zNzI2OCIKICAgICAgIGhlaWdodD0iMzAyLjY1NTgyIgogICAgICAgeD0iMTAuOTExOTIyIgogICAgICAgeT0iMTgyLjQwNjM0IiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOm5vbmUiCiAgICAgICBkPSJtIDM2MS42NTE0OCwzMTMuNTE3NjggMTc3LjE2MDc0LC0xMzEuNzg1MTYgMCwzMDIuMjI5OTkgLTE3OS44Mzg4NCwtMTMzLjc3NzM0IHoiCiAgICAgICBpZD0icGF0aDM5MDYiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogIDwvZz4KPC9zdmc+Cg=="); } #jsxc_buddylist .jsxc_options .jsxc_video.jsxc_disabled { opacity: 0.2; } rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/stylesheets/diaspora_jsxc.scss0000644000076400007640000000011512572247340027341 0ustar pravipravi@import 'diaspora_jsxc/jsxc.scss'; @import 'diaspora_jsxc/jsxc.webrtc.scss'; rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/0000755000076400007640000000000012572247340023573 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc.js0000644000076400007640000000012012572247340026753 0ustar pravipravi//= require diaspora_jsxc/lib/jsxc.dep.js //= require diaspora_jsxc/jsxc.min.js rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/0000755000076400007640000000000012572247340026424 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/0000755000076400007640000000000012572247340027172 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/translation.js0000644000076400007640000030674112572247340032101 0ustar pravipravivar I18next = {"de":{"translation":{"Logging_in":"Login läuft…","your_connection_is_unencrypted":"Deine Verbindung ist unverschlüsselt.","your_connection_is_encrypted":"Deine Verbindung ist verschlüsselt.","your_buddy_closed_the_private_connection":"Dein Kontakt hat die private Verbindung getrennt.","start_private":"Privat starten","close_private":"Privat abbrechen","your_buddy_is_verificated":"Dein Kontakt ist verifiziert.","you_have_only_a_subscription_in_one_way":"Der Kontaktstatus ist einseitig.","authentication_query_sent":"Authentifizierungsanfrage gesendet.","your_message_wasnt_send_please_end_your_private_conversation":"Deine Nachricht wurde nicht gesendet. Bitte beende die private Konversation.","unencrypted_message_received":"Unverschlüsselte Nachricht erhalten.","not_available":"Nicht verfügbar.","no_connection":"Keine Verbindung.","relogin":"Neu anmelden.","trying_to_start_private_conversation":"Versuche private Konversation zu starten.","Verified":"Verifiziert","Unverified":"Unverifiziert","private_conversation_aborted":"Private Konversation abgebrochen.","your_buddy_closed_the_private_conversation_you_should_do_the_same":"Dein Kontakt hat die private Konversation beendet. Das solltest du auch tun!","conversation_is_now_verified":"Konversation ist jetzt verifiziert","authentication_failed":"Authentifizierung fehlgeschlagen.","Creating_your_private_key_":"Wir werden jetzt deinen privaten Schlüssel generieren. Das kann einige Zeit in Anspruch nehmen.","Authenticating_a_buddy_helps_":"Einen Kontakt zu authentifizieren hilft sicherzustellen, dass die Person mit der du sprichst auch die ist die sie sagt.","How_do_you_want_to_authenticate_your_buddy":"Wie willst du {{bid_name}} ({{bid_jid}}) authentifizieren?","Select_method":"Wähle...","Manual":"Manual","Question":"Frage","Secret":"Geheimnis","To_verify_the_fingerprint_":"Um den Fingerprint zu verifizieren kontaktiere dein Kontakt über einen anderen Kommunikationsweg. Zum Beispiel per Telefonanruf.","Your_fingerprint":"Dein Fingerprint","Buddy_fingerprint":"Sein/Ihr Fingerprint","Close":"Schließen","Compared":"Verglichen","To_authenticate_using_a_question_":"Um die Authentifizierung per Frage durchzuführen, wähle eine Frage bei welcher nur dein Kontakt die Antwort kennt.","Ask":"Frage","To_authenticate_pick_a_secret_":"Um deinen Kontakt zu authentifizieren, wähle ein Geheimnis welches nur deinem Kontakt und dir bekannt ist.","Compare":"Vergleiche","Fingerprints":"Fingerprints","Authentication":"Authentifizierung","Message":"Nachricht","Add_buddy":"Kontakt hinzufügen","rename_buddy":"Kontakt umbenennen","delete_buddy":"Kontakt löschen","Login":"Anmeldung","Username":"Benutzername","Password":"Passwort","Cancel":"Abbrechen","Connect":"Verbinden","Type_in_the_full_username_":"Gib bitte den vollen Benutzernamen und optional ein Alias an.","Alias":"Alias","Add":"Hinzufügen","Subscription_request":"Kontaktanfrage","You_have_a_request_from":"Du hast eine Anfrage von","Deny":"Ablehnen","Approve":"Bestätigen","Remove_buddy":"Kontakt entfernen","You_are_about_to_remove_":"Du bist gerade dabei {{bid_name}} ({{bid_jid}}) von deiner Kontaktliste zu entfernen. Alle Chats werden geschlossen.","Continue_without_chat":"Weiter ohne Chat","Please_wait":"Bitte warten","Login_failed":"Chat-Anmeldung fehlgeschlagen","Sorry_we_cant_authentikate_":"Der Chatserver hat die Anmeldung abgelehnt. Falsches Passwort?","Retry":"Zurück","clear_history":"Lösche Verlauf","New_message_from":"Neue Nachricht von __name__","Should_we_notify_you_":"Sollen wir dich in Zukunft über eingehende Nachrichten informieren, auch wenn dieser Tab nicht im Vordergrund ist?","Please_accept_":"Bitte klick auf den \"Zulassen\" Button oben.","Hide_offline":"Offline ausblenden","Show_offline":"Offline einblenden","About":"Über","dnd":"Beschäftigt","Mute":"Ton aus","Unmute":"Ton an","Subscription":"Bezug","both":"beidseitig","Status":"Status","online":"online","chat":"chat","away":"abwesend","xa":"länger abwesend","offline":"offline","none":"keine","Unknown_instance_tag":"Unbekannter instance tag.","Not_one_of_our_latest_keys":"Nicht einer unserer letzten Schlüssel.","Received_an_unreadable_encrypted_message":"Eine unlesbare verschlüsselte Nachricht erhalten.","Online":"Online","Chatty":"Gesprächig","Away":"Abwesend","Extended_away":"Länger abwesend","Offline":"Offline","Friendship_request":"Kontaktanfrage","Confirm":"Bestätigen","Dismiss":"Ablehnen","Remove":"Löschen","Online_help":"Online Hilfe","FN":"Name","N":" ","FAMILY":"Familienname","GIVEN":"Vorname","NICKNAME":"Spitzname","URL":"URL","ADR":"Adresse","STREET":"Straße","EXTADD":"Zusätzliche Adresse","LOCALITY":"Ortschaft","REGION":"Region","PCODE":"Postleitzahl","CTRY":"Land","TEL":"Telefon","NUMBER":"Nummer","EMAIL":"E-Mail","USERID":" ","ORG":"Organisation","ORGNAME":"Name","ORGUNIT":"Abteilung","TITLE":"Titel","ROLE":"Rolle","BDAY":"Geburtstag","DESC":"Beschreibung","PHOTO":" ","send_message":"Sende Nachricht","get_info":"Benutzerinformationen","Settings":"Einstellungen","Priority":"Priorität","Save":"Speichern","User_settings":"Benutzereinstellungen","A_fingerprint_":"Ein Fingerabdruck wird dazu benutzt deinen Gesprächspartner zu identifizieren.","is":"ist","Login_options":"Anmeldeoptionen","BOSH_url":"BOSH url","Domain":"Domain","Resource":"Ressource","On_login":"Beim Anmelden","Received_an_unencrypted_message":"Unverschlüsselte Nachricht empfangen","Sorry_your_buddy_doesnt_provide_any_information":"Dein Kontakt stellt leider keine Informationen bereit.","Info_about":"Info über","Authentication_aborted":"Authentifizierung abgebrochen.","Authentication_request_received":"Authentifizierungsanfrage empfangen.","Log_in_without_chat":"Anmelden ohne Chat","has_come_online":"ist online gekommen","Unknown_sender":"Unbekannter Sender","Please_allow_access_to_microphone_and_camera":"Bitte klick auf den \"Zulassen\" Button oben, um den Zugriff auf Kamera und Mikrofon zu erlauben.","Incoming_call":"Eingehender Anruf","from":"von","Do_you_want_to_accept_the_call_from":"Möchtest Du den Anruf annehmen von","Reject":"Ablehnen","Accept":"Annehmen","hang_up":"Auflegen","snapshot":"Schnappschuss","mute_my_audio":"Mein Ton aus","pause_my_video":"Mein Video pausieren","fullscreen":"Vollbild","Info":"Info","Local_IP":"Lokale IP","Remote_IP":"Remote IP","Local_Fingerprint":"Lokaler Fingerprint","Remote_Fingerprint":"Remote Fingerprint","Video_call_not_possible":"Videoanruf nicht verfügbar. Dein Gesprächspartner unterstützt keine Videotelefonie.","Start_video_call":"Starte Videoanruf","Join_chat":"Gruppe beitreten","Join":"Betreten","Room":"Gruppe","Nickname":"Nickname","left_the_building":"__nickname__ hat die Gruppe verlassen","entered_the_room":"__nickname__ ist der Gruppe beigetreten","is_now_known_as":"__oldNickname__ ist nun unter __newNickname__ bekannt","This_room_is":"Diese Gruppe ist","muc_hidden":{"keyword":"versteckt","description":"kann durch die Suche nicht gefunden werden"},"muc_membersonly":{"keyword":"nur für Mitglieder","description":"du musst auf der Mitgliederliste stehen"},"muc_moderated":{"keyword":"moderiert","description":"Nur Personen die \"Mitspracherecht\" haben dürfen Nachrichten senden"},"muc_nonanonymous":{"keyword":"nicht anonym","description":"deine Jabber ID wird für alle Mitglieder sichtbar sein"},"muc_open":{"keyword":"offen","description":"jeder darf dieser Gruppe beitreten"},"muc_passwordprotected":{"keyword":"passwortgeschützt","description":"du benötigst das korrekte Passwort"},"muc_persistent":{"keyword":"permanent","description":"wird nicht geschlossen, wenn das letzte Mitglied die Gruppe verlässt"},"muc_public":{"keyword":"öffentlich","description":"kann durch die Suche gefunden werden"},"muc_semianonymous":{"keyword":"teilweise anonym","description":"deine Jabber ID wird nur für die Gruppen Administratoren sichtbar sein"},"muc_temporary":{"keyword":"temporär","description":"wird geschlossen, wenn das letzte Mitglied die Gruppe verlässt"},"muc_unmoderated":{"keyword":"nicht moderiert","description":"jeder darf Nachrichten senden"},"muc_unsecured":{"keyword":"ungesichert","description":"es wird kein Passwort benötigt"},"Continue":"Weiter","Server":"Server","Rooms_are_loaded":"Gruppen werden geladen","Could_load_only":"Es konnten nur __count__ Gruppen für die Autovervollständigung geladen werden","muc_explanation":"Bitte trage den Gruppennamen und optional ein Nickname und Passwort ein um einer Gruppe beizutreten","You_already_joined_this_room":"Du bist dieser Gruppe bereits beigetreten","This_room_will_be_closed":"Diese Gruppe wird geschlossen","Room_not_found_":"Es wird eine neue Gruppe erstellt","Loading_room_information":"Informationen über Gruppe werden geladen","Destroy":"Auflösen","Leave":"Verlassen","changed_subject_to":"__nickname__ hat das Thema auf __subject__ geändert","muc_removed_kicked":"Du wurdest aus der Gruppe entfernt","muc_removed_info_kicked":"__nickname__ wurde aus der Gruppe entfernt","muc_removed_banned":"Du wurdest aus der Gruppe ausgeschlossen","muc_removed_info_banned":"__nickname__ wurde aus der Gruppe ausgeschlossen","muc_removed_affiliation":"Du wurdest aus der Gruppe entfernt wegen einer Änderung deines Mitgliedstatus","muc_removed_info_affiliation":"__nickname__ wurde aus der Gruppe entfernt wegen einer Änderung seines Mitgliedstatus","muc_removed_membersonly":"Diese Gruppe erlaubt jetzt nur noch eingetragene Mitglieder und da du nicht dazugehörst, wurdest du aus der Gruppen entfernt","muc_removed_info_membersonly":"Diese Gruppe erlaubt jetzt nur noch eingetragene Mitglieder und __nickname__ gehört nicht dazu, daher wurde er aus der Gruppe entfernt","muc_removed_shutdown":"Du wurdest aus der Gruppe entfernt, da der MUC Server heruntergefahren wird","Reason":"Grund","message_not_send":"Deine Nachricht wurde aufgrund eines Fehlers nicht versandt","message_not_send_item-not-found":"Deine Nachricht wurde nicht versandt, da der Raum nicht mehr existiert","message_not_send_forbidden":"Deine Nachricht wurde nicht versandt, da du kein \"Mitspracherecht\" hast","message_not_send_not-acceptable":"Deine Nachricht wurde nicht versandt, da du kein Mitglied dieser Gruppe bist","This_room_has_been_closed":"Diese Gruppe wurde geschlossen","Room_logging_is_enabled":"Gesprächsverlauf kann öffentlich einsehbar sein","A_password_is_required":"Es wird ein Passwort benötigt","You_are_not_on_the_member_list":"Du bist kein eingetragenes Mitglied","You_are_banned_from_this_room":"Du wurdest von dieser Gruppe ausgeschlossen","Your_desired_nickname_":"Dein gewünschter Nickname wird bereits verwendet. Bitte wähle einen anderen.","The_maximum_number_":"Die maximale Anzahl der Mitglieder wurde erreicht.","This_room_is_locked_":"Diese Gruppe ist gesperrt","You_are_not_allowed_to_create_":"Du darfst keine neue Gruppe erstellen","Alert":"Alarm","Call_started":"Anruf gestarted","Call_terminated":"Anruf beendet","Carbon_copy":null,"Enable":"Aktivieren","jingle_reason_busy":"beschäftigt","jingle_reason_decline":"abgelehnt","jingle_reason_success":"aufgelegt","Media_failure":"Gerätefehler","No_local_audio_device":"Kein eigenes Audio Gerät","No_local_video_device":"Keine eigene Webcam","Ok":"Ok","PermissionDeniedError":"Du oder dein Browser haben die Audio/Video Berechtigung verweigert","Use_local_audio_device":"Nutze eigenes Audio Gerät","Use_local_video_device":"Benutze eigene Webcam","is_":"ist __status__","You_received_a_message_from_an_unknown_sender_":"Du hast eine Nachricht von einem unbekannten Sender erhalten (__sender__) Möchtest du sie sehen?","Your_roster_is_empty_add_":"Deine Kontaktliste ist leer, füge einen neuen Kontakt hinzu","onsmp_explanation_question":"Dein Kontakt versucht herauszufinden ob er wirklich mit dir redet. Um dich gegenüber deinem Kontakt zu verifizieren gib die Antwort ein und klick auf Antworten.","onsmp_explanation_secret":"Dein Kontakt versucht herauszufinden ob er wirklich mit dir redet. Um dich gegenüber deinem Kontakt zu verifizieren gib das Geheimnis ein.","from_sender":"von __sender__","Verified_private_conversation_started":"Verifiziert Private Konversation gestartet.","Unverified_private_conversation_started":"Unverifiziert Private Konversation gestartet."}},"el":{"translation":{"Logging_in":null,"your_connection_is_unencrypted":null,"your_connection_is_encrypted":null,"your_buddy_closed_the_private_connection":null,"start_private":null,"close_private":null,"your_buddy_is_verificated":null,"you_have_only_a_subscription_in_one_way":null,"authentication_query_sent":null,"your_message_wasnt_send_please_end_your_private_conversation":null,"unencrypted_message_received":null,"not_available":null,"no_connection":null,"relogin":null,"trying_to_start_private_conversation":null,"Verified":null,"Unverified":null,"private_conversation_aborted":null,"your_buddy_closed_the_private_conversation_you_should_do_the_same":null,"conversation_is_now_verified":null,"authentication_failed":null,"Creating_your_private_key_":null,"Authenticating_a_buddy_helps_":null,"How_do_you_want_to_authenticate_your_buddy":null,"Select_method":null,"Manual":null,"Question":null,"Secret":null,"To_verify_the_fingerprint_":null,"Your_fingerprint":null,"Buddy_fingerprint":null,"Close":null,"Compared":null,"To_authenticate_using_a_question_":null,"Ask":null,"To_authenticate_pick_a_secret_":null,"Compare":null,"Fingerprints":null,"Authentication":null,"Message":null,"Add_buddy":null,"rename_buddy":null,"delete_buddy":null,"Login":null,"Username":null,"Password":null,"Cancel":null,"Connect":null,"Type_in_the_full_username_":null,"Alias":null,"Add":null,"Subscription_request":null,"You_have_a_request_from":null,"Deny":null,"Approve":null,"Remove_buddy":null,"You_are_about_to_remove_":null,"Continue_without_chat":null,"Please_wait":null,"Login_failed":null,"Sorry_we_cant_authentikate_":null,"Retry":null,"clear_history":null,"New_message_from":null,"Should_we_notify_you_":null,"Please_accept_":null,"Hide_offline":null,"Show_offline":null,"About":null,"dnd":null,"Mute":null,"Unmute":null,"Subscription":null,"both":null,"Status":null,"online":null,"chat":null,"away":null,"xa":null,"offline":null,"none":null,"Unknown_instance_tag":null,"Not_one_of_our_latest_keys":null,"Received_an_unreadable_encrypted_message":null,"Online":null,"Chatty":null,"Away":null,"Extended_away":null,"Offline":null,"Friendship_request":null,"Confirm":null,"Dismiss":null,"Remove":null,"Online_help":null,"FN":null,"N":null,"FAMILY":null,"GIVEN":null,"NICKNAME":null,"URL":null,"ADR":null,"STREET":null,"EXTADD":null,"LOCALITY":null,"REGION":null,"PCODE":null,"CTRY":null,"TEL":null,"NUMBER":null,"EMAIL":null,"USERID":null,"ORG":null,"ORGNAME":null,"ORGUNIT":null,"TITLE":null,"ROLE":null,"BDAY":null,"DESC":null,"PHOTO":null,"send_message":null,"get_info":null,"Settings":null,"Priority":null,"Save":null,"User_settings":null,"A_fingerprint_":null,"is":null,"Login_options":null,"BOSH_url":null,"Domain":null,"Resource":null,"On_login":null,"Received_an_unencrypted_message":null,"Sorry_your_buddy_doesnt_provide_any_information":null,"Info_about":null,"Authentication_aborted":null,"Authentication_request_received":null,"Log_in_without_chat":null,"has_come_online":null,"Unknown_sender":null,"Please_allow_access_to_microphone_and_camera":null,"Incoming_call":null,"from":null,"Do_you_want_to_accept_the_call_from":null,"Reject":null,"Accept":null,"hang_up":null,"snapshot":null,"mute_my_audio":null,"pause_my_video":null,"fullscreen":null,"Info":null,"Local_IP":null,"Remote_IP":null,"Local_Fingerprint":null,"Remote_Fingerprint":null,"Video_call_not_possible":null,"Start_video_call":null,"Join_chat":null,"Join":null,"Room":null,"Nickname":null,"left_the_building":null,"entered_the_room":null,"is_now_known_as":null,"This_room_is":null,"muc_hidden":{"keyword":null,"description":null},"muc_membersonly":{"keyword":null,"description":null},"muc_moderated":{"keyword":null,"description":null},"muc_nonanonymous":{"keyword":null,"description":null},"muc_open":{"keyword":null,"description":null},"muc_passwordprotected":{"keyword":null,"description":null},"muc_persistent":{"keyword":null,"description":null},"muc_public":{"keyword":null,"description":null},"muc_semianonymous":{"keyword":null,"description":null},"muc_temporary":{"keyword":null,"description":null},"muc_unmoderated":{"keyword":null,"description":null},"muc_unsecured":{"keyword":null,"description":null},"Continue":null,"Server":null,"Rooms_are_loaded":null,"Could_load_only":null,"muc_explanation":null,"You_already_joined_this_room":null,"This_room_will_be_closed":null,"Room_not_found_":null,"Loading_room_information":null,"Destroy":null,"Leave":null,"changed_subject_to":null,"muc_removed_kicked":null,"muc_removed_info_kicked":null,"muc_removed_banned":null,"muc_removed_info_banned":null,"muc_removed_affiliation":null,"muc_removed_info_affiliation":null,"muc_removed_membersonly":null,"muc_removed_info_membersonly":null,"muc_removed_shutdown":null,"Reason":null,"message_not_send":null,"message_not_send_item-not-found":null,"message_not_send_forbidden":null,"message_not_send_not-acceptable":null,"This_room_has_been_closed":null,"Room_logging_is_enabled":null,"A_password_is_required":null,"You_are_not_on_the_member_list":null,"You_are_banned_from_this_room":null,"Your_desired_nickname_":null,"The_maximum_number_":null,"This_room_is_locked_":null,"You_are_not_allowed_to_create_":null,"Alert":null,"Call_started":null,"Call_terminated":null,"Carbon_copy":null,"Enable":null,"jingle_reason_busy":null,"jingle_reason_decline":null,"jingle_reason_success":null,"Media_failure":null,"No_local_audio_device":null,"No_local_video_device":null,"Ok":null,"PermissionDeniedError":null,"Use_local_audio_device":null,"Use_local_video_device":null,"is_":null,"You_received_a_message_from_an_unknown_sender_":null,"Your_roster_is_empty_add_":null,"onsmp_explanation_question":null,"onsmp_explanation_secret":null,"from_sender":null,"Verified_private_conversation_started":null,"Unverified_private_conversation_started":null}},"en":{"translation":{"Logging_in":"Logging in…","your_connection_is_unencrypted":"Your connection is unencrypted.","your_connection_is_encrypted":"Your connection is encrypted.","your_buddy_closed_the_private_connection":"Your contact closed the private connection.","start_private":"Start private","close_private":"Close private","your_buddy_is_verificated":"Your contact is verified.","you_have_only_a_subscription_in_one_way":"You only have a one-way subscription.","authentication_query_sent":"Authentication query sent.","your_message_wasnt_send_please_end_your_private_conversation":"Your message was not sent. Please end your private conversation.","unencrypted_message_received":"Unencrypted message received","not_available":"Not available","no_connection":"No connection!","relogin":"relogin","trying_to_start_private_conversation":"Trying to start private conversation!","Verified":"Verified","Unverified":"Unverified","private_conversation_aborted":"Private conversation aborted!","your_buddy_closed_the_private_conversation_you_should_do_the_same":"Your contact closed the private conversation! You should do the same.","conversation_is_now_verified":"Conversation is now verified.","authentication_failed":"Authentication failed.","Creating_your_private_key_":"Creating your private key; this may take a while.","Authenticating_a_buddy_helps_":"Authenticating a contact helps ensure that the person you are talking to is really the one they claim to be.","How_do_you_want_to_authenticate_your_buddy":"How do you want to authenticate {{bid_name}} ({{bid_jid}})?","Select_method":"Select method...","Manual":"Manual","Question":"Question","Secret":"Secret","To_verify_the_fingerprint_":"To verify the fingerprint, contact your contact via some other trustworthy channel, such as the telephone.","Your_fingerprint":"Your fingerprint","Buddy_fingerprint":"Contact fingerprint","Close":"Close","Compared":"Compared","To_authenticate_using_a_question_":"To authenticate using a question, pick a question whose answer is known only you and your contact.","Ask":"Ask","To_authenticate_pick_a_secret_":"To authenticate, pick a secret known only to you and your contact.","Compare":"Compare","Fingerprints":"Fingerprints","Authentication":"Authentication","Message":"Message","Add_buddy":"Add contact","rename_buddy":"rename contact","delete_buddy":"delete contact","Login":"Login","Username":"Username","Password":"Password","Cancel":"Cancel","Connect":"Connect","Type_in_the_full_username_":"Type in the full username and an optional alias.","Alias":"Alias","Add":"Add","Subscription_request":"Subscription request","You_have_a_request_from":"You have a request from","Deny":"Deny","Approve":"Approve","Remove_buddy":"Remove contact","You_are_about_to_remove_":"You are about to remove {{bid_name}} ({{bid_jid}}) from your contact list. All related chats will be closed.","Continue_without_chat":"Continue without chat","Please_wait":"Please wait","Login_failed":"Chat login failed","Sorry_we_cant_authentikate_":"Authentication failed with the chat server. Maybe the password is wrong?","Retry":"Back","clear_history":"Clear history","New_message_from":"New message from __name__","Should_we_notify_you_":"Should we notify you about new messages in the future?","Please_accept_":"Please click the \"Allow\" button at the top.","Hide_offline":"Hide offline contacts","Show_offline":"Show offline contacts","About":"About","dnd":"Do Not Disturb","Mute":"Mute","Unmute":"Unmute","Subscription":"Subscription","both":"both","Status":"Status","online":"online","chat":"chat","away":"away","xa":"extended away","offline":"offline","none":"none","Unknown_instance_tag":"Unknown instance tag.","Not_one_of_our_latest_keys":"Not one of our latest keys.","Received_an_unreadable_encrypted_message":"Received an unreadable encrypted message.","Online":"Online","Chatty":"Chatty","Away":"Away","Extended_away":"Extended away","Offline":"Offline","Friendship_request":"Contact request","Confirm":"Confirm","Dismiss":"Dismiss","Remove":"Remove","Online_help":"Online help","FN":"Full name","N":" ","FAMILY":"Family name","GIVEN":"Given name","NICKNAME":"Nickname","URL":"URL","ADR":"Address","STREET":"Street Address","EXTADD":"Extended Address","LOCALITY":"Locality","REGION":"Region","PCODE":"Postal Code","CTRY":"Country","TEL":"Telephone","NUMBER":"Number","EMAIL":"Email","USERID":" ","ORG":"Organization","ORGNAME":"Name","ORGUNIT":"Unit","TITLE":"Job title","ROLE":"Role","BDAY":"Birthday","DESC":"Description","PHOTO":" ","send_message":"Send message","get_info":"Show information","Settings":"Settings","Priority":"Priority","Save":"Save","User_settings":"User settings","A_fingerprint_":"A fingerprint is used to make sure that the person you are talking to is who he or she is saying.","is":"is","Login_options":"Login options","BOSH_url":"BOSH URL","Domain":"Domain","Resource":"Resource","On_login":"On login","Received_an_unencrypted_message":"Received an unencrypted message","Sorry_your_buddy_doesnt_provide_any_information":"Sorry, your contact does not provide any information.","Info_about":"Info about","Authentication_aborted":"Authentication aborted.","Authentication_request_received":"Authentication request received.","Log_in_without_chat":"Log in without chat","has_come_online":"has come online","Unknown_sender":"Unknown sender","Please_allow_access_to_microphone_and_camera":"Please click the \"Allow\" button at the top, to allow access to microphone and camera.","Incoming_call":"Incoming call","from":"from","Do_you_want_to_accept_the_call_from":"Do you want to accept the call from","Reject":"Reject","Accept":"Accept","hang_up":"hang up","snapshot":"snapshot","mute_my_audio":"mute my audio","pause_my_video":"pause my video","fullscreen":"fullscreen","Info":"Info","Local_IP":"Local IP","Remote_IP":"Remote IP","Local_Fingerprint":"Local fingerprint","Remote_Fingerprint":"Remote fingerprint","Video_call_not_possible":"Video call not possible. Your contact does not support video calls.","Start_video_call":"Start video call","Join_chat":"Join chat","Join":"Join","Room":"Room","Nickname":"Nickname","left_the_building":"__nickname__ left the building","entered_the_room":"__nickname__ entered the room","is_now_known_as":"__oldNickname__ is now known as __newNickname__","This_room_is":"This room is","muc_hidden":{"keyword":"hidden","description":"can not be found through search"},"muc_membersonly":{"keyword":"members-only","description":"you need to be on the member list"},"muc_moderated":{"keyword":"moderated","description":"only persons with \"voice\" are allowed to send messages"},"muc_nonanonymous":{"keyword":"non-anonymous","description":"your jabber id is exposed to all other occupants"},"muc_open":{"keyword":"open","description":"everyone is allowed to join"},"muc_passwordprotected":{"keyword":"password-protected","description":"you need to provide the correct password"},"muc_persistent":{"keyword":"persistent","description":"will not be destroyed if the last occupant left"},"muc_public":{"keyword":"public","description":"can be found through search"},"muc_semianonymous":{"keyword":"semi-anonymous","description":"your jabber id is only exposed to room admins"},"muc_temporary":{"keyword":"temporary","description":"will be destroyed if the last occupant left"},"muc_unmoderated":{"keyword":"unmoderated","description":"everyone is allowed to send messages"},"muc_unsecured":{"keyword":"unsecured","description":"you need no password to enter"},"Continue":"Continue","Server":"Server","Rooms_are_loaded":"Rooms are loaded","Could_load_only":"Could load only __count__ rooms for autocomplete","muc_explanation":"Please enter room name and optional a nickname and password to join a chat","You_already_joined_this_room":"You already joined this room","This_room_will_be_closed":"This room will be closed","Room_not_found_":"A new room will be created","Loading_room_information":"Loading room information","Destroy":"Destroy","Leave":"Leave","changed_subject_to":"__nickname__ changed the room subject to \"__subject__\"","muc_removed_kicked":"You have been kicked from the room","muc_removed_info_kicked":"__nickname__ has been kicked from the room","muc_removed_banned":"You have been banned from the room","muc_removed_info_banned":"__nickname__ has been banned from the room","muc_removed_affiliation":"You have been removed from the room, because of an affiliation change","muc_removed_info_affiliation":"__nickname__ has been removed from the room, because of an affiliation change","muc_removed_membersonly":"You have been removed from the room, because the room has been changed to members-only and you are no member","muc_removed_info_membersonly":"__nickname__ has been removed from the room, because the room has been changed to members-only and you are no member","muc_removed_shutdown":"You have been removed from the room, because the MUC service is being shut down","Reason":"Reason","message_not_send":"Your message was not send because of an error","message_not_send_item-not-found":"Your message was not send because this room does not exist","message_not_send_forbidden":"Your message was not send because you have no voice in this room","message_not_send_not-acceptable":"Your message was not send because you are no occupant of this room","This_room_has_been_closed":"This room has been closed","Room_logging_is_enabled":"Room logging is enabled","A_password_is_required":"A password is required","You_are_not_on_the_member_list":"You are not on the member list","You_are_banned_from_this_room":"You are banned from this room","Your_desired_nickname_":"Your desired nickname is already in use. Please choose another","The_maximum_number_":"The maximum number of user is reached in this room","This_room_is_locked_":"This room is locked","You_are_not_allowed_to_create_":"You are not allowed to create a room","Alert":"Alert","Call_started":"Call started","Call_terminated":"Call terminated","Carbon_copy":"Carbon copy","Enable":"Enable","jingle_reason_busy":"busy","jingle_reason_decline":"decline","jingle_reason_success":"hung up","Media_failure":"Media failure","No_local_audio_device":"No local audio device.","No_local_video_device":"No local video device.","Ok":"Ok","PermissionDeniedError":"You or your browser denied audio/video permission","Use_local_audio_device":"Use local audio device.","Use_local_video_device":"Use local video device.","is_":"is __status__","You_received_a_message_from_an_unknown_sender_":"You received a message from an unknown sender (__sender__) Do you want to display them?","Your_roster_is_empty_add_":"Your roster is empty, add a new contact","onsmp_explanation_question":"You contact is attempting to determine if they are really talking to you. To authenticate to your contact, enter the answer and click Answer.","onsmp_explanation_secret":"You contact is attempting to determine if they are really talking to you. To authenticate to your contact, enter the secret.","from_sender":"from __sender__","Verified_private_conversation_started":"Verified Private conversation started.","Unverified_private_conversation_started":"Unverified Private conversation started.","Bookmark":"Bookmark","Auto-join":"Auto-join","Edit_bookmark":"Edit bookmark","Room_logging_is_disabled":"Room logging is disabled","Room_is_now_non-anoymous":"Room is now non-anonymous","Room_is_now_semi-anonymous":"Room is now semi-anonymous","Do_you_want_to_change_the_default_room_configuration":"Do you want to change the default room configuration?","Default":"Default","Change":"Change"}},"es":{"translation":{"Logging_in":"Por favor, espere...","your_connection_is_unencrypted":"Su conexión no está cifrada.","your_connection_is_encrypted":"Su conexión está cifrada.","your_buddy_closed_the_private_connection":"Su amigo ha cerrado la conexión privada.","start_private":"Iniciar privado","close_private":"Cerrar privado","your_buddy_is_verificated":"Tu amigo está verificado.","you_have_only_a_subscription_in_one_way":"Sólo tienes una suscripción de un modo.","authentication_query_sent":"Consulta de verificación enviada.","your_message_wasnt_send_please_end_your_private_conversation":"Su mensaje no fue enviado. Por favor, termine su conversación privada.","unencrypted_message_received":"Mensaje no cifrado recibido:","not_available":"No disponible","no_connection":"Sin conexión!","relogin":"iniciar sesión nuevamente","trying_to_start_private_conversation":"Intentando iniciar una conversación privada!","Verified":"Verificado","Unverified":"No verificado","private_conversation_aborted":"Conversación privada abortada!","your_buddy_closed_the_private_conversation_you_should_do_the_same":"Su amigo cerró la conversación privada! Usted debería hacer lo mismo.","conversation_is_now_verified":"La conversación es ahora verificada.","authentication_failed":"Fallo la verificación.","Creating_your_private_key_":"Ahora vamos a crear su clave privada. Esto puede tomar algún tiempo.","Authenticating_a_buddy_helps_":"Autenticación de un amigo ayuda a garantizar que la persona que está hablando es quien él o ella está diciendo.","How_do_you_want_to_authenticate_your_buddy":"¿Cómo desea autenticar {{bid_name}} ({{bid_jid}})?","Select_method":"Escoja un método...","Manual":"Manual","Question":"Pregunta","Secret":"Secreto","To_verify_the_fingerprint_":"Para verificar la firma digital, póngase en contacto con su amigo a través de algún otro canal autenticado, como el teléfono.","Your_fingerprint":"Tu firma digital","Buddy_fingerprint":"firma digital de tu amigo","Close":"Cerrar","Compared":"Comparado","To_authenticate_using_a_question_":"Para autenticar mediante una pregunta, elegir una pregunta cuya respuesta se conoce sólo usted y su amigo.","Ask":"Preguntar","To_authenticate_pick_a_secret_":"Para autenticar, elija un secreto conocido sólo por usted y su amigo.","Compare":"Comparar","Fingerprints":"Firmas digitales","Authentication":"Autenticación","Message":"Mensaje","Add_buddy":"Añadir amigo","rename_buddy":"renombrar amigo","delete_buddy":"eliminar amigo","Login":"Iniciar Sesión","Username":"Usuario","Password":"Contraseña","Cancel":"Cancelar","Connect":"Conectar","Type_in_the_full_username_":"Escriba el usuario completo y un alias opcional.","Alias":"Alias","Add":"Añadir","Subscription_request":"Solicitud de suscripción","You_have_a_request_from":"Tienes una petición de","Deny":"Rechazar","Approve":"Aprobar","Remove_buddy":"Eliminar amigo","You_are_about_to_remove_":"Vas a eliminar a {{bid_name}} ({{bid_jid}}) de tu lista de amigos. Todas las conversaciones relacionadas serán cerradas.","Continue_without_chat":"Continuar","Please_wait":"Espere por favor","Login_failed":"Fallo el inicio de sesión","Sorry_we_cant_authentikate_":"Lo sentimos, no podemos autentificarlo en nuestro servidor de chat. ¿Tal vez la contraseña es incorrecta?","Retry":"Reintentar","clear_history":"Borrar el historial","New_message_from":"Nuevo mensaje de __name__","Should_we_notify_you_":"¿Debemos notificarle sobre nuevos mensajes en el futuro?","Please_accept_":"Por favor, haga clic en el botón \"Permitir\" en la parte superior.","Hide_offline":"Ocultar contactos desconectados","Show_offline":"Mostrar contactos desconectados","About":"Acerca de","dnd":"No Molestar","Mute":"Desactivar sonido","Unmute":"Activar sonido","Subscription":"Suscripción","both":"ambos","Status":"Estado","online":"en línea","chat":"chat","away":"ausente","xa":"mas ausente","offline":"desconectado","none":"nadie","Unknown_instance_tag":"Etiqueta de instancia desconocida.","Not_one_of_our_latest_keys":"No de nuestra ultima tecla.","Received_an_unreadable_encrypted_message":"Se recibió un mensaje cifrado ilegible.","Online":"En linea","Chatty":"Hablador","Away":"Ausente","Extended_away":"Mas ausente","Offline":"Desconectado","Friendship_request":"Solicitud de amistad","Confirm":"Confirmar","Dismiss":"Rechazar","Remove":"Eliminar","Online_help":"Ayuda en línea","FN":"Nombre completo ","N":" ","FAMILY":"Apellido","GIVEN":"Nombre","NICKNAME":"Apodar","URL":"URL","ADR":"Dirección","STREET":"Calle","EXTADD":"Extendido dirección","LOCALITY":"Población","REGION":"Región","PCODE":"Código postal","CTRY":"País","TEL":"Teléfono","NUMBER":"Número","EMAIL":"Emilio","USERID":" ","ORG":"Organización","ORGNAME":"Nombre","ORGUNIT":"Departamento","TITLE":"Título","ROLE":"Rol","BDAY":"Cumpleaños","DESC":"Descripción","PHOTO":" ","send_message":"mandar un texto","get_info":"obtener información","Settings":"Ajustes","Priority":"Prioridad","Save":"Guardar","User_settings":"Configuración de usuario","A_fingerprint_":"La huella digital se utiliza para que puedas estar seguro que la persona con la que estas hablando es quien realmente dice ser","is":"es","Login_options":"Opciones de login","BOSH_url":"BOSH url","Domain":"Dominio","Resource":"Recurso","On_login":"Iniciar sesión","Received_an_unencrypted_message":"Recibe un mensaje no cifrado","Sorry_your_buddy_doesnt_provide_any_information":"Lo sentimos, su amigo no provee ninguna información.","Info_about":"Info acerca de","Authentication_aborted":"Autenticación abortada","Authentication_request_received":"Pedido de autenticación recibido.","Log_in_without_chat":"Ingresar sin chat","has_come_online":"se ha conectado","Unknown_sender":"Remitente desconocido","Please_allow_access_to_microphone_and_camera":"Por favor, permitir el acceso al micrófono y la cámara.","Incoming_call":"Llamada entrante","from":"de","Do_you_want_to_accept_the_call_from":"Desea aceptar la llamada de","Reject":"Rechazar","Accept":"Aceptar","hang_up":"colgar","snapshot":"instantánea","mute_my_audio":"silenciar mi audio","pause_my_video":"pausar mi vídeo","fullscreen":"pantalla completa","Info":"Info","Local_IP":"IP local","Remote_IP":"IP remota","Local_Fingerprint":"Firma digital local","Remote_Fingerprint":"Firma digital remota","Video_call_not_possible":"Llamada de vídeo no es posible","Start_video_call":"Iniciar llamada de vídeo","Join_chat":null,"Join":null,"Room":null,"Nickname":null,"left_the_building":null,"entered_the_room":null,"is_now_known_as":null,"This_room_is":null,"muc_hidden":{"keyword":null,"description":null},"muc_membersonly":{"keyword":null,"description":null},"muc_moderated":{"keyword":null,"description":null},"muc_nonanonymous":{"keyword":null,"description":null},"muc_open":{"keyword":null,"description":null},"muc_passwordprotected":{"keyword":null,"description":null},"muc_persistent":{"keyword":null,"description":null},"muc_public":{"keyword":null,"description":null},"muc_semianonymous":{"keyword":null,"description":null},"muc_temporary":{"keyword":null,"description":null},"muc_unmoderated":{"keyword":null,"description":null},"muc_unsecured":{"keyword":null,"description":null},"Continue":null,"Server":null,"Rooms_are_loaded":null,"Could_load_only":null,"muc_explanation":null,"You_already_joined_this_room":null,"This_room_will_be_closed":null,"Room_not_found_":null,"Loading_room_information":null,"Destroy":null,"Leave":null,"changed_subject_to":null,"muc_removed_kicked":null,"muc_removed_info_kicked":null,"muc_removed_banned":null,"muc_removed_info_banned":null,"muc_removed_affiliation":null,"muc_removed_info_affiliation":null,"muc_removed_membersonly":null,"muc_removed_info_membersonly":null,"muc_removed_shutdown":null,"Reason":null,"message_not_send":null,"message_not_send_item-not-found":null,"message_not_send_forbidden":null,"message_not_send_not-acceptable":null,"This_room_has_been_closed":null,"Room_logging_is_enabled":null,"A_password_is_required":null,"You_are_not_on_the_member_list":null,"You_are_banned_from_this_room":null,"Your_desired_nickname_":null,"The_maximum_number_":null,"This_room_is_locked_":null,"You_are_not_allowed_to_create_":null,"Alert":null,"Call_started":null,"Call_terminated":null,"Carbon_copy":null,"Enable":"Activar","jingle_reason_busy":null,"jingle_reason_decline":null,"jingle_reason_success":null,"Media_failure":null,"No_local_audio_device":null,"No_local_video_device":null,"Ok":null,"PermissionDeniedError":null,"Use_local_audio_device":null,"Use_local_video_device":null,"is_":"es __status__","You_received_a_message_from_an_unknown_sender_":"Ha recibido un mensaje de un remitente desconocido (__sender__) ¿Quiere mostrarlos?","Your_roster_is_empty_add_":"Tu lista de amigos esta vacia Nuevo amigo","onsmp_explanation_question":"Tu amigo está tratando de determinar si él o ella está realmente hablando con usted. Para autenticar a su amigo, introduce la respuesta y haga clic en Contestar.","onsmp_explanation_secret":"Tu amigo está tratando de determinar si él o ella está realmente hablando con usted. Para autenticar a su amigo, especifique el secreto.","from_sender":"de __sender__","Verified_private_conversation_started":"Verificado se inició una conversación privada.","Unverified_private_conversation_started":"No verificado se inició una conversación privada."}},"fr":{"translation":{"Logging_in":"Connexion...","your_connection_is_unencrypted":"Connexion non chiffrée.","your_connection_is_encrypted":"Connexion chiffrée.","your_buddy_closed_the_private_connection":"Votre ami a fermé la connexion privée.","start_private":"Démarrer une conversation privé","close_private":"Clôturer une conversation privée","your_buddy_is_verificated":"Votre contact est vérifié.","you_have_only_a_subscription_in_one_way":"Vous ne pouvez souscrire qu'une fois.","authentication_query_sent":"Requête d’authentification envoyée.","your_message_wasnt_send_please_end_your_private_conversation":"Votre message n'a pas été envoyé. Veuillez terminer votre conversation privée.","unencrypted_message_received":"Message non chiffré reçu","not_available":"Pas disponible","no_connection":"Pas de connexion !","relogin":"Re-connexion","trying_to_start_private_conversation":"Essai de démarrage d'une conversation privée !","Verified":"Vérifié","Unverified":"Non vérifié","private_conversation_aborted":"Conversation privée interrompue !","your_buddy_closed_the_private_conversation_you_should_do_the_same":"Votre ami a fermé la conversation privée ! Vous devriez faire de même.","conversation_is_now_verified":"La conversation est maintenant vérifiée.","authentication_failed":"L'authentification a échoué.","Creating_your_private_key_":"Création de votre clé privée; cela peut prendre un moment.","Authenticating_a_buddy_helps_":"L'authentification d'un ami permet de s'assurer que la personne à qui vous parlez est vraiment celui qu'il ou elle prétend être.","How_do_you_want_to_authenticate_your_buddy":"Comment voulez-vous vous authentifier {{bid_name}} ({{bid_jid}})?","Select_method":"Sélection de la méthode...","Manual":"Manuel","Question":"Question","Secret":"Sécurité","To_verify_the_fingerprint_":"Pour vérifier l'empreinte, contactez votre ami via un autre canal digne de confiance, tel que le téléphone.","Your_fingerprint":"Votre empreinte","Buddy_fingerprint":"Empreinte de l'ami","Close":"Fermer","Compared":"Comparé","To_authenticate_using_a_question_":"Pour s'authentifier à l'aide d'une question, choisissez une question dont la réponse n'est connue que vous et de votre ami.","Ask":"Demander","To_authenticate_pick_a_secret_":"Pour vous authentifier, choisissez un secret connu seulement de vous et de votre ami.","Compare":"Comparer","Fingerprints":"Empreintes","Authentication":"Authentification","Message":"Message","Add_buddy":"Ajouter comme ami","rename_buddy":"Renommer l'ami","delete_buddy":"Supprimer l'ami","Login":"Connexion","Username":"Nom d'utilisateur","Password":"Mot de passe","Cancel":"Annuler","Connect":"Connecter","Type_in_the_full_username_":"Tapez un nom d'utilisateur complet et un alias(optionnel).","Alias":"Alias","Add":"Ajouter","Subscription_request":"Demande d'abonnement","You_have_a_request_from":"Vous avez une requête de ","Deny":"Refuser","Approve":"Approuver","Remove_buddy":"Supprimer l'ami","You_are_about_to_remove_":"Vous allez retirer {{bid_name}} ({{bid_jid}}) de votre liste d'amis. Toutes les fenêtres de chat en lien avec celui-ci seront fermées.","Continue_without_chat":"Continuer sans tchat","Please_wait":"Merci de patienter","Login_failed":"Authentification échouée","Sorry_we_cant_authentikate_":"La connexion avec le serveur de tchat a échoué. Vérifiez le mot de passe.","Retry":"Retour","clear_history":"Effacer l’historique","New_message_from":"Nouveau message de __name__","Should_we_notify_you_":"Dans le futur, devrons-nous vous notifier les nouveaux messages ?","Please_accept_":"Merci de cliquer sur le bouton \"autoriser\" en haut de page","Hide_offline":"Masquer les contacts non connectés","Show_offline":"Afficher les contacts non connectés","About":"À propos","dnd":"Ne pas déranger","Mute":"Muet","Unmute":"Son actif","Subscription":"Abonnement","both":"Les deux","Status":"Status","online":"En ligne","chat":"tchat","away":"Absent","xa":"Options étendues","offline":"Hors ligne","none":"Aucun","Unknown_instance_tag":"Tag inconnu","Not_one_of_our_latest_keys":"Ce n'est pas l'une des dernières touches","Received_an_unreadable_encrypted_message":"Message chiffré non lisible","Online":"En ligne","Chatty":"tchatty","Away":"Absent","Extended_away":"Options étendues","Offline":"Hors ligne","Friendship_request":"Demande d'amitié","Confirm":"Valider","Dismiss":"Rejeter","Remove":"Supprimer","Online_help":"Aide en ligne","FN":"Nom","N":" N ","FAMILY":"Nom de famille","GIVEN":"prénom","NICKNAME":"Surnom","URL":"URL","ADR":"Adresse","STREET":"Rue","EXTADD":"Adresse (suite)","LOCALITY":"Localité","REGION":"Région","PCODE":"Code Postal","CTRY":"Pays","TEL":"Téléphone","NUMBER":"Numéro","EMAIL":"Courriel","USERID":" USERID ","ORG":"Organisation","ORGNAME":"Nom","ORGUNIT":"Unité","TITLE":"Qualité:","ROLE":"Rôle","BDAY":"Date de naissance","DESC":"Description","PHOTO":"Photo","send_message":"Envoyer le message","get_info":"Montrer les informations","Settings":"Réglages","Priority":"Priorité","Save":"Enregistrer","User_settings":"Paramètres utilisateur","A_fingerprint_":"Une empreinte est utilisée pour s'assurer de l'identité de la personne à qui vous parlez","is":"est","Login_options":"Options d'identification","BOSH_url":"URL BOSH","Domain":"Domaine","Resource":"Ressource","On_login":"Après authentification","Received_an_unencrypted_message":"Reçu un message non chiffré","Sorry_your_buddy_doesnt_provide_any_information":"Désolé, votre ami n'a pas fourni d'informations","Info_about":"A propos de","Authentication_aborted":"Authentification interrompue.","Authentication_request_received":"Requête d'authentification reçue.","Log_in_without_chat":"S'identifier sans tchat","has_come_online":"vient d'arriver","Unknown_sender":"Expéditeur inconnu","Please_allow_access_to_microphone_and_camera":"Veuillez cliquez sur le bouton \"Autoriser\" en haut, pour permettre l'accès au micro et à la caméra.","Incoming_call":"Appel entrant","from":"de","Do_you_want_to_accept_the_call_from":"Voulez-vous accepter l'appel de","Reject":"Rejeté","Accept":"Accepté","hang_up":"Décrochez","snapshot":"Capture d’écran","mute_my_audio":"Couper l'audio","pause_my_video":"Mettre ma vidéo en pause","fullscreen":"Plein écran","Info":"Info","Local_IP":"IP locale","Remote_IP":"IP distante","Local_Fingerprint":"Empreinte locale","Remote_Fingerprint":"Empreinte distante","Video_call_not_possible":"L'appel vidéo n'est possible. Votre ami ne supporte pas les appels vidéo.","Start_video_call":"Démarrer l'appel vidéo","Join_chat":"Joindre la discution","Join":"Joindre","Room":"Salon","Nickname":"Surnom","left_the_building":"__nickname__ a quitté l'immeuble","entered_the_room":"__nickname__ entre dans le salon","is_now_known_as":null,"This_room_is":"Ce salon est","muc_hidden":{"keyword":"caché","description":null},"muc_membersonly":{"keyword":"pour les membres seulement","description":"Vous devez être sur la liste des membres"},"muc_moderated":{"keyword":"modéré","description":"Seulement les personnes avec la \"voix\" sont autorisés à envoyer des messages"},"muc_nonanonymous":{"keyword":"non anonyme","description":"Votre identifiant Jabber est visible de tous les autres occupants"},"muc_open":{"keyword":"ouvert","description":"Tout le monde est autorisé à se connecter"},"muc_passwordprotected":{"keyword":"protégé par un mot de passe","description":"Vous devez fournir un mot de passe correct"},"muc_persistent":{"keyword":"persistent","description":null},"muc_public":{"keyword":"public","description":null},"muc_semianonymous":{"keyword":"semi-anonyme","description":"Votre identifiant Jabber est seulement visible aux administrateurs de ce salon"},"muc_temporary":{"keyword":"temporaire","description":"sera détruit au départ de son dernier occupant"},"muc_unmoderated":{"keyword":"non modéré","description":"Tout le monde est autorisé à envoyer des messages"},"muc_unsecured":{"keyword":"non sécurisé","description":"un mot de passe n'est pas nécessaire pour entrer"},"Continue":"Continuer","Server":"Serveur","Rooms_are_loaded":"Les salons sont chargés","Could_load_only":null,"muc_explanation":"Veuillez saisir le nom du salon, un surnom (optionnel) et un mot de passe pour joindre la conversation","You_already_joined_this_room":"Vous avez déjà rejoins ce salon","This_room_will_be_closed":"Ce salon va être fermé","Room_not_found_":"Un nouveau salon va être créé","Loading_room_information":"Chargement des informations du salon","Destroy":"Détruire","Leave":"Quitter","changed_subject_to":"__nickname__ a changé le sujet du salon à \"__subject__\"","muc_removed_kicked":"Vous avez été éjecté de ce salon","muc_removed_info_kicked":"__nickname__ a été éjecté de ce salon","muc_removed_banned":"Vous avez été banni de ce salon","muc_removed_info_banned":"__nickname__ a été banni de ce salon","muc_removed_affiliation":null,"muc_removed_info_affiliation":null,"muc_removed_membersonly":null,"muc_removed_info_membersonly":null,"muc_removed_shutdown":null,"Reason":"Raison","message_not_send":null,"message_not_send_item-not-found":null,"message_not_send_forbidden":null,"message_not_send_not-acceptable":"Votre message n'a pas été envoyé car il n'y a personne dans ce salon","This_room_has_been_closed":"Ce salon a été fermé","Room_logging_is_enabled":null,"A_password_is_required":"Un mot de passe est requis","You_are_not_on_the_member_list":"Vous n'êtes pas sur la liste des membres","You_are_banned_from_this_room":"Vous avez été banni de ce salon","Your_desired_nickname_":"Votre Surnom souhaité est déjà utilisé.Veuillez en choisir un autre","The_maximum_number_":"Le nombre maximum d'utilisateur est atteint dans ce salon","This_room_is_locked_":"Ce salon est vérouillé","You_are_not_allowed_to_create_":"Vous n'êtes pas autorisé à créer un salon","Alert":null,"Call_started":null,"Call_terminated":null,"Carbon_copy":null,"Enable":null,"jingle_reason_busy":null,"jingle_reason_decline":null,"jingle_reason_success":null,"Media_failure":null,"No_local_audio_device":null,"No_local_video_device":null,"Ok":null,"PermissionDeniedError":null,"Use_local_audio_device":null,"Use_local_video_device":null,"is_":"est __status__","You_received_a_message_from_an_unknown_sender_":"Vous avez reçu un message d'un expéditeur inconnu (__sender__) Voulez-vous les afficher ?","Your_roster_is_empty_add_":"Votre liste est vide, ajouter Nouvel ami","onsmp_explanation_question":"Votre ami tente de déterminer si il ou elle parle vraiment à vous. Vous authentifier à votre ami, Saisissez une réponse et cliquer sur Répondre.","onsmp_explanation_secret":"Votre ami tente de déterminer si il ou elle parle vraiment à vous. Vous authentifier à votre ami, Entrez le mot secret","from_sender":"de __sender__","Verified_private_conversation_started":"Vérifié Conversation privé démarrée.","Unverified_private_conversation_started":"Non vérifié Conversation privé démarrée."}},"it":{"translation":{"Logging_in":"login…","your_connection_is_unencrypted":"La sua connessione è non cifrata.","your_connection_is_encrypted":"La sua connessione è cifrata.","your_buddy_closed_the_private_connection":"La sua connessione privata è stato chiuso dal suo compagno.","start_private":"Inizia privata","close_private":"Chiude privata","your_buddy_is_verificated":"Il tuo compagno è stato verificato","you_have_only_a_subscription_in_one_way":"Hai solo una one-way inscrizione.","authentication_query_sent":"Domanda d'autenticità inviata.","your_message_wasnt_send_please_end_your_private_conversation":"Il tuo messaggio non è stato inviato. Si prega di finire la sua conversazione privata.","unencrypted_message_received":"Messaggio non cifrato ricevuto","not_available":"non disponibile","no_connection":"nessun collegamento!","relogin":"nuovo login","trying_to_start_private_conversation":"Cercando di avviare una conversazione privata!","Verified":"verificato","Unverified":"non verificato","private_conversation_aborted":"Conversazione privata abortito!","your_buddy_closed_the_private_conversation_you_should_do_the_same":"Il tuo compagno ha chiuso la conversazione privata! Si dovrebbe fare lo stesso.","conversation_is_now_verified":"Conversazione è ora verificato.","authentication_failed":"autenticazione fallita.","Creating_your_private_key_":"Creare la propria chiave privata; questo potrebbe richiedere un po'.","Authenticating_a_buddy_helps_":"Autenticazione un compagno aiuta a garantire che la persona si sta parlando è davvero quello che lui o lei sostiene di essere.","How_do_you_want_to_authenticate_your_buddy":"Come si desidera autenticare {{bid_name}} ({{bid_jid}})?","Select_method":"Seleziona metodo ..","Manual":"manuale","Question":"domanda","Secret":"segreto","To_verify_the_fingerprint_":"Per verificare l'impronta digitale, contattare il proprio compagno attraverso qualche altro canale affidabile, come il telefono.","Your_fingerprint":"il tuo impronta digitale","Buddy_fingerprint":"impronta digitale da compagno","Close":"chiude","Compared":"comparato","To_authenticate_using_a_question_":"Per autenticare tramite una questione, scegli una questione la cui risposta è nota solo voi e il tuo compagno","Ask":"chiedi","To_authenticate_pick_a_secret_":"Per autenticare, scegli un segreto noto solo a te e il tuo compagno.","Compare":"Comparare","Fingerprints":"Impronta digitale","Authentication":"Autenticazione","Message":"Messagio","Add_buddy":"Aggiungi un compagno","rename_buddy":"rinomina compagno","delete_buddy":"elimina compagno","Login":"Login","Username":"Identificazione dell'utente","Password":"Password","Cancel":"Cancella","Connect":"Collega","Type_in_the_full_username_":"Digita l'identificazione utente completo e un alias opzionale.","Alias":"Alias","Add":"Aggiungi","Subscription_request":"Rrichiesta di sottoscrizione","You_have_a_request_from":"Hai una richiesta da","Deny":"Refiuta","Approve":"Approva","Remove_buddy":"Rimuova il compagno","You_are_about_to_remove_":"Stai rimovendo {{bid_name}} ({{bid_jid}}) del suo lista di compagni. Tutte le chat appartenente saranno chiuse.","Continue_without_chat":"Continua senza chat","Please_wait":"Si prega d'attendere","Login_failed":"Chat login è fallito","Sorry_we_cant_authentikate_":"Autenticazione non riuscita con il server di chat. Forse la password è sbagliata?","Retry":"Indietro","clear_history":"Cancella la cronologia","New_message_from":"Nuovo messaggio da __name__","Should_we_notify_you_":"Vuoi ricevere una notifica di nuovi messaggi in futuro?","Please_accept_":"Si prega di fare clic sul bottone \"Autorizzazione\" sopra.","Hide_offline":"Nascondere i contatti non in linea","Show_offline":"Mostra i contatti non in linea","About":"Informazione legale","dnd":"Non disturbare","Mute":"Muto attivo","Unmute":"Muto inattivo","Subscription":"Sottoscrizione","both":"etrambi","Status":"Status","online":"In linea","chat":"chat","away":"via","xa":"via estensivo","offline":"non in linea","none":"nessuno","Unknown_instance_tag":"Instance tag sconosciuta.","Not_one_of_our_latest_keys":"Non è una delle nostre ultime chiavi.","Received_an_unreadable_encrypted_message":"Ricevuto un messaggio crittografato illeggibile.","Online":"In linea","Chatty":"Chiacchierino","Away":"Via","Extended_away":"Via estensivo","Offline":"Non in linea","Friendship_request":"Amicizia richiesto","Confirm":"Conferma","Dismiss":"Rifiuta","Remove":"Rimuovi","Online_help":"Guida in linea","FN":"Nome e cognome","N":null,"FAMILY":"Cognome","GIVEN":"Nome","NICKNAME":"Soprannome","URL":"URL","ADR":"Indirizzo","STREET":"Via","EXTADD":"Esteso Indirizzo","LOCALITY":"Località","REGION":"Regione","PCODE":"Codice Postale","CTRY":"Paese","TEL":"Telefono","NUMBER":"Numero","EMAIL":"E-mail","USERID":null,"ORG":"Organizzazione","ORGNAME":"Nome","ORGUNIT":"Unità","TITLE":"Titolo di lavoro","ROLE":"Funzione","BDAY":"Compleanno","DESC":"Descrizione","PHOTO":null,"send_message":"Messagio inviato","get_info":"Mostra informazioni","Settings":"Impostazione","Priority":"Priorità","Save":"Salva","User_settings":"Impostazione dell'utente","A_fingerprint_":"Una impronta digitale è usato per assicurarsi che la persona con cui stai parlando è lui o lei che sta dicendo.","is":"è","Login_options":"Opzioni di login","BOSH_url":"BOSH URL","Domain":"Domain","Resource":"Risorsa","On_login":"Login on","Received_an_unencrypted_message":"Ricevuto un messaggio non crittografato","Sorry_your_buddy_doesnt_provide_any_information":"Spiace, il tuo compagno non fornisce alcuna informazione.","Info_about":"Informazioni","Authentication_aborted":"Autenticazione interrotta","Authentication_request_received":"Richiesta di autenticazione ricevuto.","Log_in_without_chat":"Log in senza chat","has_come_online":"È venuto in linea","Unknown_sender":"Mittente sconosciuto","Please_allow_access_to_microphone_and_camera":"Si prega di fare clic sul bottone \"Autorizzazione\" sopra per autorizzazione del l'accesso al microfono e fotocamera.","Incoming_call":"Chiamata in arrivo","from":"di","Do_you_want_to_accept_the_call_from":"Vuoi accettare la chiamata di","Reject":"Rifiuta","Accept":"Accetta","hang_up":"Riattacca","snapshot":"istantanea","mute_my_audio":"disattiva il mio audio","pause_my_video":"pausa il mio audio","fullscreen":"schermo intero","Info":"Informazione","Local_IP":"IP locale","Remote_IP":"IP remoto","Local_Fingerprint":"Impronta digitale locale","Remote_Fingerprint":"Impronta digitale remoto","Video_call_not_possible":"Videochiamata non è possibile. Il tuo compagno non può effettuare videochiamate.","Start_video_call":"Inizia videochiamata","Join_chat":null,"Join":null,"Room":null,"Nickname":null,"left_the_building":null,"entered_the_room":null,"is_now_known_as":null,"This_room_is":null,"muc_hidden":{"keyword":null,"description":null},"muc_membersonly":{"keyword":null,"description":null},"muc_moderated":{"keyword":null,"description":null},"muc_nonanonymous":{"keyword":null,"description":null},"muc_open":{"keyword":null,"description":null},"muc_passwordprotected":{"keyword":null,"description":null},"muc_persistent":{"keyword":null,"description":null},"muc_public":{"keyword":null,"description":null},"muc_semianonymous":{"keyword":null,"description":null},"muc_temporary":{"keyword":null,"description":null},"muc_unmoderated":{"keyword":null,"description":null},"muc_unsecured":{"keyword":null,"description":null},"Continue":null,"Server":null,"Rooms_are_loaded":null,"Could_load_only":null,"muc_explanation":null,"You_already_joined_this_room":null,"This_room_will_be_closed":null,"Room_not_found_":null,"Loading_room_information":null,"Destroy":null,"Leave":null,"changed_subject_to":null,"muc_removed_kicked":null,"muc_removed_info_kicked":null,"muc_removed_banned":null,"muc_removed_info_banned":null,"muc_removed_affiliation":null,"muc_removed_info_affiliation":null,"muc_removed_membersonly":null,"muc_removed_info_membersonly":null,"muc_removed_shutdown":null,"Reason":null,"message_not_send":null,"message_not_send_item-not-found":null,"message_not_send_forbidden":null,"message_not_send_not-acceptable":null,"This_room_has_been_closed":null,"Room_logging_is_enabled":null,"A_password_is_required":null,"You_are_not_on_the_member_list":null,"You_are_banned_from_this_room":null,"Your_desired_nickname_":null,"The_maximum_number_":null,"This_room_is_locked_":null,"You_are_not_allowed_to_create_":null,"Alert":null,"Call_started":null,"Call_terminated":null,"Carbon_copy":null,"Enable":null,"jingle_reason_busy":null,"jingle_reason_decline":null,"jingle_reason_success":null,"Media_failure":null,"No_local_audio_device":null,"No_local_video_device":null,"Ok":null,"PermissionDeniedError":null,"Use_local_audio_device":null,"Use_local_video_device":null,"is_":"è __status__","You_received_a_message_from_an_unknown_sender_":"Hai ricevuto un messaggio da un mittente sconosciuto (__sender__) Vuoi che venga visualizzato?","Your_roster_is_empty_add_":"Il suo elenco è vuoto, aggiungi un compagno nuovo","onsmp_explanation_question":"Il tuo compagno sta cercando di determinare se lui o lei sta davvero parlando con te. Per autenticare a il tuo compagno. inserisci la risposta e fare click su risposta.","onsmp_explanation_secret":"Il tuo compagno sta cercando di determinare se lui o lei sta davvero parlando con te. Per autenticare a il tuo compagno. inserire il segreto.","from_sender":"di __sender__","Verified_private_conversation_started":"verificato Conversazione privata iniziato.","Unverified_private_conversation_started":"non verificato Conversazione privata iniziato."}},"nds":{"translation":{"Logging_in":null,"your_connection_is_unencrypted":null,"your_connection_is_encrypted":null,"your_buddy_closed_the_private_connection":null,"start_private":null,"close_private":null,"your_buddy_is_verificated":null,"you_have_only_a_subscription_in_one_way":null,"authentication_query_sent":null,"your_message_wasnt_send_please_end_your_private_conversation":null,"unencrypted_message_received":null,"not_available":null,"no_connection":null,"relogin":null,"trying_to_start_private_conversation":null,"Verified":null,"Unverified":null,"private_conversation_aborted":null,"your_buddy_closed_the_private_conversation_you_should_do_the_same":null,"conversation_is_now_verified":null,"authentication_failed":null,"Creating_your_private_key_":null,"Authenticating_a_buddy_helps_":null,"How_do_you_want_to_authenticate_your_buddy":null,"Select_method":null,"Manual":null,"Question":null,"Secret":null,"To_verify_the_fingerprint_":null,"Your_fingerprint":null,"Buddy_fingerprint":null,"Close":null,"Compared":null,"To_authenticate_using_a_question_":null,"Ask":null,"To_authenticate_pick_a_secret_":null,"Compare":null,"Fingerprints":null,"Authentication":null,"Message":null,"Add_buddy":null,"rename_buddy":null,"delete_buddy":null,"Login":null,"Username":null,"Password":null,"Cancel":null,"Connect":null,"Type_in_the_full_username_":null,"Alias":null,"Add":null,"Subscription_request":null,"You_have_a_request_from":null,"Deny":null,"Approve":null,"Remove_buddy":null,"You_are_about_to_remove_":null,"Continue_without_chat":null,"Please_wait":null,"Login_failed":null,"Sorry_we_cant_authentikate_":null,"Retry":null,"clear_history":null,"New_message_from":null,"Should_we_notify_you_":null,"Please_accept_":null,"Hide_offline":null,"Show_offline":null,"About":null,"dnd":null,"Mute":null,"Unmute":null,"Subscription":null,"both":null,"Status":null,"online":null,"chat":null,"away":null,"xa":null,"offline":null,"none":null,"Unknown_instance_tag":null,"Not_one_of_our_latest_keys":null,"Received_an_unreadable_encrypted_message":null,"Online":null,"Chatty":null,"Away":null,"Extended_away":null,"Offline":null,"Friendship_request":null,"Confirm":null,"Dismiss":null,"Remove":null,"Online_help":null,"FN":null,"N":null,"FAMILY":null,"GIVEN":null,"NICKNAME":null,"URL":null,"ADR":null,"STREET":null,"EXTADD":null,"LOCALITY":null,"REGION":null,"PCODE":null,"CTRY":null,"TEL":null,"NUMBER":null,"EMAIL":null,"USERID":null,"ORG":null,"ORGNAME":null,"ORGUNIT":null,"TITLE":null,"ROLE":null,"BDAY":null,"DESC":null,"PHOTO":null,"send_message":null,"get_info":null,"Settings":null,"Priority":null,"Save":null,"User_settings":null,"A_fingerprint_":null,"is":null,"Login_options":null,"BOSH_url":null,"Domain":null,"Resource":null,"On_login":null,"Received_an_unencrypted_message":null,"Sorry_your_buddy_doesnt_provide_any_information":null,"Info_about":null,"Authentication_aborted":null,"Authentication_request_received":null,"Log_in_without_chat":null,"has_come_online":null,"Unknown_sender":null,"Please_allow_access_to_microphone_and_camera":null,"Incoming_call":null,"from":null,"Do_you_want_to_accept_the_call_from":null,"Reject":null,"Accept":null,"hang_up":null,"snapshot":null,"mute_my_audio":null,"pause_my_video":null,"fullscreen":null,"Info":null,"Local_IP":null,"Remote_IP":null,"Local_Fingerprint":null,"Remote_Fingerprint":null,"Video_call_not_possible":null,"Start_video_call":null,"Join_chat":null,"Join":null,"Room":null,"Nickname":null,"left_the_building":null,"entered_the_room":null,"is_now_known_as":null,"This_room_is":null,"muc_hidden":{"keyword":null,"description":null},"muc_membersonly":{"keyword":null,"description":null},"muc_moderated":{"keyword":null,"description":null},"muc_nonanonymous":{"keyword":null,"description":null},"muc_open":{"keyword":null,"description":null},"muc_passwordprotected":{"keyword":null,"description":null},"muc_persistent":{"keyword":null,"description":null},"muc_public":{"keyword":null,"description":null},"muc_semianonymous":{"keyword":null,"description":null},"muc_temporary":{"keyword":null,"description":null},"muc_unmoderated":{"keyword":null,"description":null},"muc_unsecured":{"keyword":null,"description":null},"Continue":null,"Server":null,"Rooms_are_loaded":null,"Could_load_only":null,"muc_explanation":null,"You_already_joined_this_room":null,"This_room_will_be_closed":null,"Room_not_found_":null,"Loading_room_information":null,"Destroy":null,"Leave":null,"changed_subject_to":null,"muc_removed_kicked":null,"muc_removed_info_kicked":null,"muc_removed_banned":null,"muc_removed_info_banned":null,"muc_removed_affiliation":null,"muc_removed_info_affiliation":null,"muc_removed_membersonly":null,"muc_removed_info_membersonly":null,"muc_removed_shutdown":null,"Reason":null,"message_not_send":null,"message_not_send_item-not-found":null,"message_not_send_forbidden":null,"message_not_send_not-acceptable":null,"This_room_has_been_closed":null,"Room_logging_is_enabled":null,"A_password_is_required":null,"You_are_not_on_the_member_list":null,"You_are_banned_from_this_room":null,"Your_desired_nickname_":null,"The_maximum_number_":null,"This_room_is_locked_":null,"You_are_not_allowed_to_create_":null,"Alert":null,"Call_started":null,"Call_terminated":null,"Carbon_copy":null,"Enable":null,"jingle_reason_busy":null,"jingle_reason_decline":null,"jingle_reason_success":null,"Media_failure":null,"No_local_audio_device":null,"No_local_video_device":null,"Ok":null,"PermissionDeniedError":null,"Use_local_audio_device":null,"Use_local_video_device":null,"is_":null,"You_received_a_message_from_an_unknown_sender_":null,"Your_roster_is_empty_add_":null,"onsmp_explanation_question":null,"onsmp_explanation_secret":null,"from_sender":null,"Verified_private_conversation_started":null,"Unverified_private_conversation_started":null}},"pl":{"translation":{"Logging_in":"Logowanie...","your_connection_is_unencrypted":"Twoje połączenie nie jest szyfrowane.","your_connection_is_encrypted":"Twoje połączenie jest szyfrowane.","your_buddy_closed_the_private_connection":"Twój rozmówca zamknął połączenie.","start_private":"Rozpocznij rozmowę.","close_private":"Zakończ rozmowę.","your_buddy_is_verificated":"Twój rozmówca został zweryfikowany.","you_have_only_a_subscription_in_one_way":"Masz jednostronną subskrypcję.","authentication_query_sent":"Wysłano proźbę o autentykację.","your_message_wasnt_send_please_end_your_private_conversation":"Twoja wiadomość nie została wysłana. Proszę, zamknij rozmowę.","unencrypted_message_received":"Zwrotna niezaszyfrowana wiadomość.","not_available":"Niedostępny.","no_connection":"Brak połączenia!","relogin":"Połącz ponownie","trying_to_start_private_conversation":"Rozpocznij rozmowę!","Verified":"Zweryfikowano","Unverified":"Niezweryfikowano","private_conversation_aborted":"Anulowano rozmowę!","your_buddy_closed_the_private_conversation_you_should_do_the_same":"Rozmówca przerwał połączenie!","conversation_is_now_verified":"Zweryfikowano połączenie.","authentication_failed":"Weryfikacja się nie powiodła.","Creating_your_private_key_":"Tworzenie klucza prywatnego; może to chwilę potrwać","Authenticating_a_buddy_helps_":"Autoryzacja pomoże w ustaleniu faktycznej tożsamości rozmówcy ;).","How_do_you_want_to_authenticate_your_buddy":"Jakiej autoryzacji chcesz użyć {{bid_name}} ({{bid_jid}})?","Select_method":"Wybierz sposób...","Manual":"Ręcznie","Question":"Pytanie","Secret":"Hasło","To_verify_the_fingerprint_":"Aby zweryfikować kod najpierw skontaktuj się z rozmówcą np. za pomocą telefonu.","Your_fingerprint":"Twój kod:","Buddy_fingerprint":"Kod rozmówcy","Close":"Zamknij","Compared":"Porównano","To_authenticate_using_a_question_":"Aby autoryzować za pomocą pytania, wybierz pytanie na które tylko Twój rozmówca zna odpowiedź.","Ask":"Zadaj pytanie","To_authenticate_pick_a_secret_":"Aby autoryzować za pomocą hasła, wybierz hasło na które zna tylko Twój rozmówca.","Compare":"Dopasuj","Fingerprints":"Kody autoryzacyjne","Authentication":"Autoryzacja","Message":"Wiadomość","Add_buddy":"Dodaj kontakt","rename_buddy":"Zmień nazwę","delete_buddy":"Usuń kontakt","Login":"Login","Username":"Nazwa Użytkownika","Password":"Hasło","Cancel":"Anuluj","Connect":"Połączenie","Type_in_the_full_username_":"Wpisz pełną nazwę użytkownika (np. imię.nazwisko@zajezdnia.local) oraz jego nazwę wyświetlaną (Alias).","Alias":"Alias","Add":"Dodaj","Subscription_request":"Potwierdzenie subskrypcji","You_have_a_request_from":"Masz potwierdzenie od","Deny":"Odmów","Approve":"Zatwierdź","Remove_buddy":"Usuń rozmówcę","You_are_about_to_remove_":"Twój rozmówca {{bid_name}} ({{bid_jid}}) usunął Cię ze swojej listy kontaktów.","Continue_without_chat":"Kontynuuj bez komunikatora","Please_wait":"Proszę czekać","Login_failed":"Błędne logowanie","Sorry_we_cant_authentikate_":"Błędna autoryzacja z serwerem. Może hasło jest nieprawidłowe?","Retry":"Powrót","clear_history":"Wyczyść historię","New_message_from":"Nowa wiadomość od __name__","Should_we_notify_you_":"Czy chcesz otrzymywać powiadomienia o nowych wiadomościach w przyszłości?","Please_accept_":"Kliknij \"Zezwól\" na górze.","Hide_offline":"Schowaj niedostępne kontakty","Show_offline":"Pokaż niedostępne kontakty","About":"Info","dnd":"Nie przeszkadzać","Mute":"Wycisz","Unmute":"Włącz dźwięk","Subscription":"Subskrybcja","both":"obustronna","Status":"Status","online":"Dostępny","chat":"czat","away":"z dala od kompa","xa":"hen hen...","offline":"niedostępny","none":"brak","Unknown_instance_tag":"Nieznany przypadek.","Not_one_of_our_latest_keys":"Not one of our latest keys.","Received_an_unreadable_encrypted_message":"Otrzymano nieczytelną, zaszyfrowaną wiadomość.","Online":"Połączony","Chatty":"Pogawędzimy?","Away":"Daleko","Extended_away":"Hen Hen...","Offline":"Niedostępny","Friendship_request":"Zapytanie od znajomego?","Confirm":"Potwierdzenie","Dismiss":"Odwołaj","Remove":"Usuń","Online_help":"Pomoc Online","FN":"Pełna nazwa","N":" ","FAMILY":"Nazwisko","GIVEN":"Imię","NICKNAME":"Pseudonim","URL":"Strona WWW","ADR":"Adres","STREET":"Ulica","EXTADD":"Pełny adres","LOCALITY":"Lokalizacja","REGION":"Region","PCODE":"Kod pocztowy","CTRY":"Kraj","TEL":"Telefon","NUMBER":"Numer","EMAIL":"Email","USERID":" ","ORG":"Organizacja","ORGNAME":"Nazwa","ORGUNIT":"Jednostka","TITLE":"Stanowisko","ROLE":"Rola","BDAY":"Data urodzin","DESC":"Opis","PHOTO":" ","send_message":"Wyślij wiadomość","get_info":"Pokaż informację","Settings":"Ustawienia","Priority":"Priorytet","Save":"Zapisz","User_settings":"Ustawienia Użytkownika","A_fingerprint_":"Kod służy do autoryzacji Twojego rozmówcy aby potwierdzić jego tożsamość.","is":"jest","Login_options":"opcje logowania","BOSH_url":"Adres BOSH","Domain":"Domena","Resource":"Źródło","On_login":"Na login","Received_an_unencrypted_message":"Zatwierdzono nieszyfrowaną wiadomość.","Sorry_your_buddy_doesnt_provide_any_information":"Twój rozmówca nie posiada żadnych informacji.","Info_about":"Informacja o...","Authentication_aborted":"Autoryzacja anulowana.","Authentication_request_received":"Prośba o autoryzację została przyjęta.","Log_in_without_chat":"Zaloguj bez komunikatora","has_come_online":"jest teraz dostępny","Unknown_sender":"Nieznany nadawca","Please_allow_access_to_microphone_and_camera":"Kliknij \"Potwierdź\" na górze, aby móc korzystać z mikrofonu oraz kamery.","Incoming_call":"Przychodzące połączenie","from":"z","Do_you_want_to_accept_the_call_from":"Akceptujesz połączenie od","Reject":"Odrzuć","Accept":"Zaakceptuj","hang_up":"odbierz","snapshot":"zrób zdjęcie","mute_my_audio":"wycisz dźwięk","pause_my_video":"zatrzymaj moje wideo","fullscreen":"Pełny ekran","Info":"Informacja","Local_IP":"Adres IP","Remote_IP":"Zdalny adres IP","Local_Fingerprint":"Kod lokalny","Remote_Fingerprint":"Zdalny kod","Video_call_not_possible":"Rozmowa wideo jest niemożliwa. Twój rozmówca nie ma możliwości prowadzenia takich rozmów.","Start_video_call":"Rozpocznij rozmowę wideo","Join_chat":"Dołącz do czata","Join":"Dołącz","Room":"Pokój","Nickname":"Nazwa użytkownika","left_the_building":"__nickname__ wyszedł","entered_the_room":"__nickname__ wszedł do pokoju","is_now_known_as":"__oldNickname__ zmienił nazwę na __newNickname__","This_room_is":"Ten pokój jest","muc_hidden":{"keyword":"ukryty","description":"nie można odnaleźć elementów wyszukiwania"},"muc_membersonly":{"keyword":"tylko zalogowani","description":"musisz być członkiem listy"},"muc_moderated":{"keyword":"moderowano","description":"tylko osoby z opcją \"głos\" mogą wysyłać wiadomość"},"muc_nonanonymous":{"keyword":"nie-anonimowy","description":"Twój identyfikator jabber jest widoczny dla wszystkich innych osób"},"muc_open":{"keyword":"otwarty","description":"wszyscy mają pozwolenie aby dołączyć"},"muc_passwordprotected":{"keyword":"ograniczone hasłem","description":"musisz wpisać prawidłowe hasło"},"muc_persistent":{"keyword":"trwale","description":"nie zostaną zniszczone, jeśli ostatnia osoba wyszła"},"muc_public":{"keyword":"publiczny","description":"wyszukawno"},"muc_semianonymous":{"keyword":"pół-anonimowy","description":"Twój identyfikator jabber jest widoczny w pokoju adminów"},"muc_temporary":{"keyword":"tymczasowy","description":"zostanie usunięty jeżeli ostatnia osoba wyjdzie"},"muc_unmoderated":{"keyword":"niemoderowany","description":"wszyscy są uprawnieni do pisania wiadomości"},"muc_unsecured":{"keyword":"niezabezpieczone","description":"nie musisz wpisywać hasła"},"Continue":"Kontynuuj","Server":"Serwer","Rooms_are_loaded":"Pokoje zostały załadowane","Could_load_only":"Nie załadowano __count__ pokoi","muc_explanation":"Aby się zalogować, wpisz nazwę pokoju oraz opcjonalnie nazwę użytkownika i hasło","You_already_joined_this_room":"Już dołączyłeś do tego pokoju","This_room_will_be_closed":"Ten pokój będzie zamknięty","Room_not_found_":"Nowy pokój będzie stworzony","Loading_room_information":"Ładowani informacji o pokoju","Destroy":"Zniszczony","Leave":"Opuść","changed_subject_to":"__nickname__ zmienił temat pokoju na \"__subject__\"","muc_removed_kicked":"Zostałeś wyrzucony z pokoju","muc_removed_info_kicked":"__nickname__ został wyrzucony z pokoju","muc_removed_banned":"Zostałeś zbanowany","muc_removed_info_banned":"__nickname__ został zbanowany","muc_removed_affiliation":"Zostałeś usunięty z pokoju ze względu na zmianę przynależnosci","muc_removed_info_affiliation":"__nickname__ został usunięty z pokoju ze względu na zmianę przynależnosci","muc_removed_membersonly":"Zostałeś usunięty z pokoju ze względu na zmianę pokoju tylko dla członków, a Ty nie jesteś członkiem...","muc_removed_info_membersonly":"__nickname__ został usunięty z pokoju ze względu na zmianę pokoju na tylko dla członków","muc_removed_shutdown":"Zostałeś usunięty z pokoju ze względu na zamknięcie usługi","Reason":"Powód","message_not_send":"Wystąpił błąd i twoja wiadomość nie została wysłana.","message_not_send_item-not-found":"Twoja wiadomość nie została wysłana ponieważ ten pokój nie istnieje","message_not_send_forbidden":"Twoja wiadomość nie została wysłana ponieważ nie masz głosu w tym pokoju","message_not_send_not-acceptable":"Twoja wiadomość nie została wysłana ponieważ nie jesteś właścicielem tego pokoju","This_room_has_been_closed":"Ten pokój został zamknięty","Room_logging_is_enabled":"Logowanie do pokoju jest włączone","A_password_is_required":"Hasło jest wymagane","You_are_not_on_the_member_list":"Nie jesteś na liście członków","You_are_banned_from_this_room":"Zostałeś zbanowany w tym pokoju","Your_desired_nickname_":"Twoja nazwa użytkownika jest już użyta. Spróbuj wybrać inną","The_maximum_number_":"Została osiągnięta maksymalna liczba użytkowników w tym pokoju","This_room_is_locked_":"Ten pokój jest zablokowany","You_are_not_allowed_to_create_":"Nie masz uprawnień do tworzenia pokoju","Alert":"Alarm","Call_started":null,"Call_terminated":null,"Carbon_copy":"Do wiadomości","Enable":"Włączone","jingle_reason_busy":null,"jingle_reason_decline":null,"jingle_reason_success":null,"Media_failure":null,"No_local_audio_device":null,"No_local_video_device":null,"Ok":"Ok","PermissionDeniedError":null,"Use_local_audio_device":null,"Use_local_video_device":null,"is_":"jest __status__","You_received_a_message_from_an_unknown_sender_":"Masz wiadomość od nieznanego nadawcy. (__sender__) Chcesz to wyświetlić?","Your_roster_is_empty_add_":"Twoja lista jest pusta, dodaj kontakty Nowy kontakt","onsmp_explanation_question":"Twój rozmówca próbuje się z Tobą połączyć. Autoryzacja z rozmówcą, napisz odpowiedź.","onsmp_explanation_secret":"Twój rozmówca próbuje się z Tobą połączyć. Autoryzacja z rozmówcą, wpisz hasło.","from_sender":"z __sender__","Verified_private_conversation_started":"Zweryfikowano Rozmowa prywatna rozpoczęta.","Unverified_private_conversation_started":"Niezweryfikowano Rozmowa prywatna rozpoczęta."}},"pt-BR":{"translation":{"Logging_in":"Entrando...","your_connection_is_unencrypted":"Sua conexão não é encriptada","your_connection_is_encrypted":"Sua conexão é encriptada","your_buddy_closed_the_private_connection":"Seu contato fechou a conexão privada","start_private":"Iniciar conversa privada","close_private":"Fechar conversa privada","your_buddy_is_verificated":"Seu contato está verificado","you_have_only_a_subscription_in_one_way":"Você só tem a inscrição one-way","authentication_query_sent":"Pergunta de autenticação enviada","your_message_wasnt_send_please_end_your_private_conversation":"Sua mensagem não foi enviada. Por favor finalize sua conversa privada","unencrypted_message_received":"Mensagem não encriptada recebida","not_available":"Indisponível","no_connection":"Sem conexão!","relogin":"reentrar","trying_to_start_private_conversation":"Tentando iniciar conversa privada","Verified":"Verificado","Unverified":"Não verificado","private_conversation_aborted":"Conversa privada abortada!","your_buddy_closed_the_private_conversation_you_should_do_the_same":"Seu contato encerrou a conversa privada! Você deveria fazer o mesmo.","conversation_is_now_verified":"Conversa verificada.","authentication_failed":"Autenticação falhou.","Creating_your_private_key_":"Criando sua chave privada: isso pode demorar um pouco.","Authenticating_a_buddy_helps_":"Autenticar seu contato ajuda a garantir que a pessoa com a qual você está falando é realmente a pessoa que ela alega ser.","How_do_you_want_to_authenticate_your_buddy":"Como você gostaria de se autenticar {{bid_name}} ({{bid_jid}})?","Select_method":"Selecione o método...","Manual":"Manual","Question":"Pergunta","Secret":"Senha","To_verify_the_fingerprint_":"Para verificar o fingerprint, entre em contato com seu contato usando outro meio, de preferência seguro, como o telefone.","Your_fingerprint":"Seu fingerprint","Buddy_fingerprint":"Fingerprint do contato","Close":"Fechar","Compared":"Comparado","To_authenticate_using_a_question_":"Para autenticar seu contato faça uma pergunta, mas escolha que só ele saiba a resposta.","Ask":"Pergunta","To_authenticate_pick_a_secret_":"Para autenticar, escolha um segredo que somente você e seu contato saibam.","Compare":"Compare","Fingerprints":"Fingerprints","Authentication":"Autenticação","Message":"Mensagem","Add_buddy":"Adicionar contato","rename_buddy":"renomear contato","delete_buddy":"remover contato","Login":"Entrar","Username":"Usuário","Password":"Senha","Cancel":"Cancelar","Connect":"Conectar","Type_in_the_full_username_":"Digite seu nome completo e um apelido opcional.","Alias":"Apelido","Add":"Adicionar","Subscription_request":"Pedido de inscrição","You_have_a_request_from":"Você tem um pedido de","Deny":"Negar","Approve":"Aprovar","Remove_buddy":"Remover contato","You_are_about_to_remove_":"Você está prestes a remover {{bid_name}} ({{bid_jid}}) de sua lista de contatos. Todas as conversas serão fechadas.","Continue_without_chat":"Continue sem converar","Please_wait":"Por favor aguarde","Login_failed":"Autenticação da conversa falhou","Sorry_we_cant_authentikate_":"A autenticação com o servidor falhou. Talvez seja a senha errada?","Retry":"Voltar","clear_history":"Limpar histórico","New_message_from":"Nova mensagem de __name__","Should_we_notify_you_":"Devemos continuar notificando sobre novas mensagens no futuro?","Please_accept_":"Por favor clique no botão \"Permitir\" na parte superior.","Hide_offline":"Esconder contatos desconectados","Show_offline":"Mostrar contatos desconectados","About":"Sobre","dnd":"Não perturbe","Mute":"Mudo","Unmute":"Ligar","Subscription":"Inscrição","both":"ambos","Status":"Status","online":"online","chat":"conversa","away":"ausente","xa":"ausente por mais tempo","offline":"desativado","none":"nenhum","Unknown_instance_tag":"Marcação desconhecida da instância","Not_one_of_our_latest_keys":"Nenhuma de nossas ultimas chaves.","Received_an_unreadable_encrypted_message":"Mensagem encriptada ilegível foi recebida.","Online":"Online","Chatty":"Tagarela","Away":"Ausente","Extended_away":"Ausente por mais tempo","Offline":"Desativado","Friendship_request":"Pedido de amizade","Confirm":"Confirmar","Dismiss":"Ignorar","Remove":"Remover","Online_help":"Ajuda online","FN":"Nome completo","N":" ","FAMILY":"Sobrenome","GIVEN":"Nome","NICKNAME":"Apelido","URL":"URL","ADR":"Endereço","STREET":"Rua, Av, etc","EXTADD":"Complemento","LOCALITY":"Localidade","REGION":"Região","PCODE":"CEP","CTRY":"País","TEL":"Telefone","NUMBER":"Número","EMAIL":"Email","USERID":" ","ORG":"Empresa","ORGNAME":"Nome","ORGUNIT":"Unidade","TITLE":"Cargo","ROLE":"Rol","BDAY":"Data de nascimento","DESC":"Descrição","PHOTO":" ","send_message":"Enviar mensagem","get_info":"Exibir informações","Settings":"Configurações","Priority":"Prioridade","Save":"Salvar","User_settings":"Configurações do usuário","A_fingerprint_":"O fingerprint é usado para certificar que a pessoa com a qual se está falando é que ela diz ser.","is":"é","Login_options":"Opções de login","BOSH_url":"BOSH URL","Domain":"Domínio","Resource":"Recurso","On_login":"Ao autenticar","Received_an_unencrypted_message":"Mensagem não encriptada recebida","Sorry_your_buddy_doesnt_provide_any_information":"Desculpe, seu contato não forneceu nenhuma informação","Info_about":"Informações sobre","Authentication_aborted":"Autenticação encerrada.","Authentication_request_received":"Pedido de autenticação recebido","Log_in_without_chat":"Entrar sem conversar","has_come_online":"ficou online","Unknown_sender":"Emissor desconhecido","Please_allow_access_to_microphone_and_camera":"Por favor clique no botão \"Permitir\" no topo, para conceder acesso ao seu microfone e câmera.","Incoming_call":"Recebendo chamada","from":"de","Do_you_want_to_accept_the_call_from":"Você aceita a chamada de","Reject":"Negar","Accept":"Aceitar","hang_up":"desligar","snapshot":"registrar imagem","mute_my_audio":"mudo","pause_my_video":"pausar vídeo","fullscreen":"tela cheia","Info":"Informações","Local_IP":"IP local","Remote_IP":"IP remoto","Local_Fingerprint":"Fingerprint local","Remote_Fingerprint":"Fingerprint remoto","Video_call_not_possible":"Chamada de vídeo impossível. Seu contato não suporta chamadas desse tipo.","Start_video_call":"Iniciar chamada de vídeo","Join_chat":null,"Join":null,"Room":null,"Nickname":null,"left_the_building":null,"entered_the_room":null,"is_now_known_as":null,"This_room_is":null,"muc_hidden":{"keyword":null,"description":null},"muc_membersonly":{"keyword":null,"description":null},"muc_moderated":{"keyword":null,"description":null},"muc_nonanonymous":{"keyword":null,"description":null},"muc_open":{"keyword":null,"description":null},"muc_passwordprotected":{"keyword":null,"description":null},"muc_persistent":{"keyword":null,"description":null},"muc_public":{"keyword":null,"description":null},"muc_semianonymous":{"keyword":null,"description":null},"muc_temporary":{"keyword":null,"description":null},"muc_unmoderated":{"keyword":null,"description":null},"muc_unsecured":{"keyword":null,"description":null},"Continue":null,"Server":null,"Rooms_are_loaded":null,"Could_load_only":null,"muc_explanation":null,"You_already_joined_this_room":null,"This_room_will_be_closed":null,"Room_not_found_":null,"Loading_room_information":null,"Destroy":null,"Leave":null,"changed_subject_to":null,"muc_removed_kicked":null,"muc_removed_info_kicked":null,"muc_removed_banned":null,"muc_removed_info_banned":null,"muc_removed_affiliation":null,"muc_removed_info_affiliation":null,"muc_removed_membersonly":null,"muc_removed_info_membersonly":null,"muc_removed_shutdown":null,"Reason":null,"message_not_send":null,"message_not_send_item-not-found":null,"message_not_send_forbidden":null,"message_not_send_not-acceptable":null,"This_room_has_been_closed":null,"Room_logging_is_enabled":null,"A_password_is_required":null,"You_are_not_on_the_member_list":null,"You_are_banned_from_this_room":null,"Your_desired_nickname_":null,"The_maximum_number_":null,"This_room_is_locked_":null,"You_are_not_allowed_to_create_":null,"Alert":null,"Call_started":null,"Call_terminated":null,"Carbon_copy":null,"Enable":null,"jingle_reason_busy":null,"jingle_reason_decline":null,"jingle_reason_success":null,"Media_failure":null,"No_local_audio_device":null,"No_local_video_device":null,"Ok":null,"PermissionDeniedError":null,"Use_local_audio_device":null,"Use_local_video_device":null,"is_":"é __status__","You_received_a_message_from_an_unknown_sender_":"Você recebeu uma mensagem de um emissor desconhecido (__sender__) Você quer mostrá-los?","Your_roster_is_empty_add_":"Sua lista está vazia, adicione um novo contato","onsmp_explanation_question":"Seu contato está tentando determinar se ele realmente está falando contigo. Para autenticar seu contato, entre com a resposta e clique em Responder.","onsmp_explanation_secret":"Seu contato está tentando determinar se ele realmente está falando contigo. Para autenticar seu contato, escreva a senha.","from_sender":"de __sender__","Verified_private_conversation_started":"Verificado Conversa privada iniciada.","Unverified_private_conversation_started":"Não verificado Conversa privada iniciada."}},"ro":{"translation":{"Logging_in":null,"your_connection_is_unencrypted":null,"your_connection_is_encrypted":null,"your_buddy_closed_the_private_connection":null,"start_private":null,"close_private":null,"your_buddy_is_verificated":null,"you_have_only_a_subscription_in_one_way":null,"authentication_query_sent":null,"your_message_wasnt_send_please_end_your_private_conversation":null,"unencrypted_message_received":null,"not_available":null,"no_connection":null,"relogin":null,"trying_to_start_private_conversation":null,"Verified":null,"Unverified":null,"private_conversation_aborted":null,"your_buddy_closed_the_private_conversation_you_should_do_the_same":null,"conversation_is_now_verified":null,"authentication_failed":null,"Creating_your_private_key_":null,"Authenticating_a_buddy_helps_":null,"How_do_you_want_to_authenticate_your_buddy":null,"Select_method":null,"Manual":null,"Question":null,"Secret":null,"To_verify_the_fingerprint_":null,"Your_fingerprint":null,"Buddy_fingerprint":null,"Close":null,"Compared":null,"To_authenticate_using_a_question_":null,"Ask":null,"To_authenticate_pick_a_secret_":null,"Compare":null,"Fingerprints":null,"Authentication":null,"Message":null,"Add_buddy":null,"rename_buddy":null,"delete_buddy":null,"Login":null,"Username":null,"Password":null,"Cancel":null,"Connect":null,"Type_in_the_full_username_":null,"Alias":null,"Add":null,"Subscription_request":null,"You_have_a_request_from":null,"Deny":null,"Approve":null,"Remove_buddy":null,"You_are_about_to_remove_":null,"Continue_without_chat":null,"Please_wait":null,"Login_failed":null,"Sorry_we_cant_authentikate_":null,"Retry":null,"clear_history":null,"New_message_from":null,"Should_we_notify_you_":null,"Please_accept_":null,"Hide_offline":null,"Show_offline":null,"About":null,"dnd":null,"Mute":null,"Unmute":null,"Subscription":null,"both":null,"Status":null,"online":null,"chat":null,"away":null,"xa":null,"offline":null,"none":null,"Unknown_instance_tag":null,"Not_one_of_our_latest_keys":null,"Received_an_unreadable_encrypted_message":null,"Online":null,"Chatty":null,"Away":null,"Extended_away":null,"Offline":null,"Friendship_request":null,"Confirm":null,"Dismiss":null,"Remove":null,"Online_help":null,"FN":null,"N":null,"FAMILY":null,"GIVEN":null,"NICKNAME":null,"URL":null,"ADR":null,"STREET":null,"EXTADD":null,"LOCALITY":null,"REGION":null,"PCODE":null,"CTRY":null,"TEL":null,"NUMBER":null,"EMAIL":null,"USERID":null,"ORG":null,"ORGNAME":null,"ORGUNIT":null,"TITLE":null,"ROLE":null,"BDAY":null,"DESC":null,"PHOTO":null,"send_message":null,"get_info":null,"Settings":null,"Priority":null,"Save":null,"User_settings":null,"A_fingerprint_":null,"is":null,"Login_options":null,"BOSH_url":null,"Domain":null,"Resource":null,"On_login":null,"Received_an_unencrypted_message":null,"Sorry_your_buddy_doesnt_provide_any_information":null,"Info_about":null,"Authentication_aborted":null,"Authentication_request_received":null,"Log_in_without_chat":null,"has_come_online":null,"Unknown_sender":null,"Please_allow_access_to_microphone_and_camera":null,"Incoming_call":null,"from":null,"Do_you_want_to_accept_the_call_from":null,"Reject":null,"Accept":null,"hang_up":null,"snapshot":null,"mute_my_audio":null,"pause_my_video":null,"fullscreen":null,"Info":null,"Local_IP":null,"Remote_IP":null,"Local_Fingerprint":null,"Remote_Fingerprint":null,"Video_call_not_possible":null,"Start_video_call":null,"Join_chat":null,"Join":null,"Room":null,"Nickname":null,"left_the_building":null,"entered_the_room":null,"is_now_known_as":null,"This_room_is":null,"muc_hidden":{"keyword":null,"description":null},"muc_membersonly":{"keyword":null,"description":null},"muc_moderated":{"keyword":null,"description":null},"muc_nonanonymous":{"keyword":null,"description":null},"muc_open":{"keyword":null,"description":null},"muc_passwordprotected":{"keyword":null,"description":null},"muc_persistent":{"keyword":null,"description":null},"muc_public":{"keyword":null,"description":null},"muc_semianonymous":{"keyword":null,"description":null},"muc_temporary":{"keyword":null,"description":null},"muc_unmoderated":{"keyword":null,"description":null},"muc_unsecured":{"keyword":null,"description":null},"Continue":null,"Server":null,"Rooms_are_loaded":null,"Could_load_only":null,"muc_explanation":null,"You_already_joined_this_room":null,"This_room_will_be_closed":null,"Room_not_found_":null,"Loading_room_information":null,"Destroy":null,"Leave":null,"changed_subject_to":null,"muc_removed_kicked":null,"muc_removed_info_kicked":null,"muc_removed_banned":null,"muc_removed_info_banned":null,"muc_removed_affiliation":null,"muc_removed_info_affiliation":null,"muc_removed_membersonly":null,"muc_removed_info_membersonly":null,"muc_removed_shutdown":null,"Reason":null,"message_not_send":null,"message_not_send_item-not-found":null,"message_not_send_forbidden":null,"message_not_send_not-acceptable":null,"This_room_has_been_closed":null,"Room_logging_is_enabled":null,"A_password_is_required":null,"You_are_not_on_the_member_list":null,"You_are_banned_from_this_room":null,"Your_desired_nickname_":null,"The_maximum_number_":null,"This_room_is_locked_":null,"You_are_not_allowed_to_create_":null,"Alert":null,"Call_started":null,"Call_terminated":null,"Carbon_copy":null,"Enable":null,"jingle_reason_busy":null,"jingle_reason_decline":null,"jingle_reason_success":null,"Media_failure":null,"No_local_audio_device":null,"No_local_video_device":null,"Ok":null,"PermissionDeniedError":null,"Use_local_audio_device":null,"Use_local_video_device":null,"is_":null,"You_received_a_message_from_an_unknown_sender_":null,"Your_roster_is_empty_add_":null,"onsmp_explanation_question":null,"onsmp_explanation_secret":null,"from_sender":null,"Verified_private_conversation_started":null,"Unverified_private_conversation_started":null}},"ru":{"translation":{"Logging_in":"Вход в систему...","your_connection_is_unencrypted":"Ваше соединение не зашифровано.","your_connection_is_encrypted":"Ваше соединение зашифровано.","your_buddy_closed_the_private_connection":"Ваш собеседник закончил зашифрованное соединение.","start_private":"Начать зашифрованный чат","close_private":"Закончить зашифрованный чат","your_buddy_is_verificated":"Собеседник подтвержден.","you_have_only_a_subscription_in_one_way":"У вас только односторонняя подписка.","authentication_query_sent":null,"your_message_wasnt_send_please_end_your_private_conversation":"Сообщение не отправлено. Завершите зашифрованный чат, пожалуйста.","unencrypted_message_received":"Получено незашифрованное сообщение","not_available":"Не доступен","no_connection":"Нет соединения!","relogin":"переподключиться","trying_to_start_private_conversation":"Попытка начать зашифрованный чат!","Verified":"Подтверждено","Unverified":"Не подтверждено","private_conversation_aborted":"Зашифрованный чат отклонен!","your_buddy_closed_the_private_conversation_you_should_do_the_same":"Ваш собеседник завершил зашифрованный чат! Вы должны сделать тоже самое.","conversation_is_now_verified":"Чат теперь утвержден.","authentication_failed":"Ошибка авторизации.","Creating_your_private_key_":null,"Authenticating_a_buddy_helps_":null,"How_do_you_want_to_authenticate_your_buddy":null,"Select_method":"Выберите метод...","Manual":"Вручную","Question":"Вопрос","Secret":"Пароль","To_verify_the_fingerprint_":null,"Your_fingerprint":"Ваш отпечаток","Buddy_fingerprint":"Отпечаток собеседника","Close":"Закрыть","Compared":"Сравнение завершено","To_authenticate_using_a_question_":"Для авторизации с помощью вопроса выберите вопрос, ответ на который знаете только Вы и собеседник.","Ask":null,"To_authenticate_pick_a_secret_":"Для авторизации выберите пароль, который знаете только Вы и собеседник.","Compare":"Сравнить","Fingerprints":"Отпечатки","Authentication":"Авторизация","Message":"Сообщение","Add_buddy":"Добавить контакт","rename_buddy":"переименовать контакт","delete_buddy":"удалить контакт","Login":"Вход","Username":"Логин","Password":"Пароль","Cancel":"Отмена","Connect":"Подключить","Type_in_the_full_username_":null,"Alias":"Псевдоним","Add":"Добавить","Subscription_request":"Запрос подписки","You_have_a_request_from":"Получен запрос от","Deny":"Отказ","Approve":"Подтвердить","Remove_buddy":"Удалить контакт","You_are_about_to_remove_":null,"Continue_without_chat":"Продолжить без чата","Please_wait":"Подождите…","Login_failed":"Неудачный вход в чат","Sorry_we_cant_authentikate_":null,"Retry":null,"clear_history":"Очистить историю","New_message_from":"Новое сообщение от __name__","Should_we_notify_you_":"Уведомлять о новых сообщениях в будущем?","Please_accept_":null,"Hide_offline":"Спрятать отключенных","Show_offline":"Показать отключенных","About":"О проекте","dnd":"Не беспокоить","Mute":"Выкл. уведомления","Unmute":"Вкл. уведомления","Subscription":"Подписка","both":"оба","Status":"Статус","online":"в сети","chat":"готов общаться","away":"отошел","xa":"отсутствую","offline":"не в сети","none":"нет","Unknown_instance_tag":"Неизвестный тег.","Not_one_of_our_latest_keys":null,"Received_an_unreadable_encrypted_message":null,"Online":"В сети","Chatty":"Готов общаться","Away":"Отошел","Extended_away":"Отсутствую","Offline":"Не в сети","Friendship_request":null,"Confirm":"Подтвердить","Dismiss":"Отклонить","Remove":"Удалить","Online_help":"Онлайн помощь","FN":"Полное имя","N":null,"FAMILY":"Фамилия","GIVEN":null,"NICKNAME":"Ник","URL":null,"ADR":"Адрес","STREET":"Улица","EXTADD":"Дополнительный адрес","LOCALITY":null,"REGION":null,"PCODE":"Индекс","CTRY":"Страна","TEL":"Телефон","NUMBER":"Номер","EMAIL":"Почта","USERID":null,"ORG":"Организация","ORGNAME":"Название","ORGUNIT":"Отдел","TITLE":"Должность","ROLE":"Обязанности","BDAY":"День рождения","DESC":"Описание","PHOTO":null,"send_message":"Отправить сообщение","get_info":"Показать информацию","Settings":"Настройки","Priority":"Приоритет","Save":"Сохранить","User_settings":"Пользовательские настройки","A_fingerprint_":null,"is":null,"Login_options":"Параметры входа","BOSH_url":null,"Domain":"Домен","Resource":"Ресурс","On_login":"Автоматически подключаться","Received_an_unencrypted_message":null,"Sorry_your_buddy_doesnt_provide_any_information":null,"Info_about":"Информация о","Authentication_aborted":null,"Authentication_request_received":null,"Log_in_without_chat":"Вход без чата","has_come_online":"появился в сети","Unknown_sender":"Неизвестный отправитель","Please_allow_access_to_microphone_and_camera":null,"Incoming_call":"Входящий вызов","from":"от","Do_you_want_to_accept_the_call_from":null,"Reject":null,"Accept":null,"hang_up":null,"snapshot":null,"mute_my_audio":null,"pause_my_video":null,"fullscreen":null,"Info":null,"Local_IP":null,"Remote_IP":null,"Local_Fingerprint":null,"Remote_Fingerprint":null,"Video_call_not_possible":null,"Start_video_call":null,"Join_chat":null,"Join":null,"Room":null,"Nickname":null,"left_the_building":null,"entered_the_room":null,"is_now_known_as":null,"This_room_is":null,"muc_hidden":{"keyword":null,"description":null},"muc_membersonly":{"keyword":null,"description":null},"muc_moderated":{"keyword":null,"description":null},"muc_nonanonymous":{"keyword":null,"description":null},"muc_open":{"keyword":null,"description":null},"muc_passwordprotected":{"keyword":null,"description":null},"muc_persistent":{"keyword":null,"description":null},"muc_public":{"keyword":null,"description":null},"muc_semianonymous":{"keyword":null,"description":null},"muc_temporary":{"keyword":null,"description":null},"muc_unmoderated":{"keyword":null,"description":null},"muc_unsecured":{"keyword":null,"description":null},"Continue":null,"Server":null,"Rooms_are_loaded":null,"Could_load_only":null,"muc_explanation":null,"You_already_joined_this_room":null,"This_room_will_be_closed":null,"Room_not_found_":null,"Loading_room_information":null,"Destroy":null,"Leave":null,"changed_subject_to":null,"muc_removed_kicked":null,"muc_removed_info_kicked":null,"muc_removed_banned":null,"muc_removed_info_banned":null,"muc_removed_affiliation":null,"muc_removed_info_affiliation":null,"muc_removed_membersonly":null,"muc_removed_info_membersonly":null,"muc_removed_shutdown":null,"Reason":null,"message_not_send":null,"message_not_send_item-not-found":null,"message_not_send_forbidden":null,"message_not_send_not-acceptable":null,"This_room_has_been_closed":null,"Room_logging_is_enabled":null,"A_password_is_required":null,"You_are_not_on_the_member_list":null,"You_are_banned_from_this_room":null,"Your_desired_nickname_":null,"The_maximum_number_":null,"This_room_is_locked_":null,"You_are_not_allowed_to_create_":null,"Alert":null,"Call_started":null,"Call_terminated":null,"Carbon_copy":null,"Enable":"Включить","jingle_reason_busy":null,"jingle_reason_decline":null,"jingle_reason_success":null,"Media_failure":null,"No_local_audio_device":null,"No_local_video_device":null,"Ok":null,"PermissionDeniedError":null,"Use_local_audio_device":null,"Use_local_video_device":null,"is_":null,"You_received_a_message_from_an_unknown_sender_":"Вы получили сообщение от неизвестного отправителя (__sender__)","Your_roster_is_empty_add_":"Ваш список контактов пуст, добавить новый контакт","onsmp_explanation_question":"Собеседник пытается определить, что общается действительно с Вами.","onsmp_explanation_secret":"Собеседник пытается определить, что общается действительно с Вами. введите пароль.","from_sender":"от __sender__","Verified_private_conversation_started":"Подтверждено Зашифрованный чат начат.","Unverified_private_conversation_started":"Не подтверждено Зашифрованный чат начат."}}};rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/strophe.muc.js0000644000076400007640000007542112572247340032010 0ustar pravipravi// Generated by CoffeeScript 1.3.3 /* *Plugin to implement the MUC extension. http://xmpp.org/extensions/xep-0045.html *Previous Author: Nathan Zorn *Complete CoffeeScript rewrite: Andreas Guth */ var Occupant, RoomConfig, XmppRoom, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; Strophe.addConnectionPlugin('muc', { _connection: null, rooms: {}, roomNames: [], /*Function Initialize the MUC plugin. Sets the correct connection object and extends the namesace. */ init: function(conn) { this._connection = conn; this._muc_handler = null; Strophe.addNamespace('MUC_OWNER', Strophe.NS.MUC + "#owner"); Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC + "#admin"); Strophe.addNamespace('MUC_USER', Strophe.NS.MUC + "#user"); return Strophe.addNamespace('MUC_ROOMCONF', Strophe.NS.MUC + "#roomconfig"); }, /*Function Join a multi-user chat room Parameters: (String) room - The multi-user chat room to join. (String) nick - The nickname to use in the chat room. Optional (Function) msg_handler_cb - The function call to handle messages from the specified chat room. (Function) pres_handler_cb - The function call back to handle presence in the chat room. (Function) roster_cb - The function call to handle roster info in the chat room (String) password - The optional password to use. (password protected rooms only) (Object) history_attrs - Optional attributes for retrieving history (XML DOM Element) extended_presence - Optional XML for extending presence */ join: function(room, nick, msg_handler_cb, pres_handler_cb, roster_cb, password, history_attrs, extended_presence) { var msg, room_nick, _ref, _this = this; room_nick = this.test_append_nick(room, nick); msg = $pres({ from: this._connection.jid, to: room_nick }).c("x", { xmlns: Strophe.NS.MUC }); if (history_attrs != null) { msg = msg.c("history", history_attrs).up(); } if (password != null) { msg.cnode(Strophe.xmlElement("password", [], password)); } if (extended_presence != null) { msg.up().cnode(extended_presence); } if ((_ref = this._muc_handler) == null) { this._muc_handler = this._connection.addHandler(function(stanza) { var from, handler, handlers, id, roomname, x, xmlns, xquery, _i, _len; from = stanza.getAttribute('from'); if (!from) { return true; } roomname = from.split("/")[0]; if (!_this.rooms[roomname]) { return true; } room = _this.rooms[roomname]; handlers = {}; if (stanza.nodeName === "message") { handlers = room._message_handlers; } else if (stanza.nodeName === "presence") { xquery = stanza.getElementsByTagName("x"); if (xquery.length > 0) { for (_i = 0, _len = xquery.length; _i < _len; _i++) { x = xquery[_i]; xmlns = x.getAttribute("xmlns"); if (xmlns && xmlns.match(Strophe.NS.MUC)) { handlers = room._presence_handlers; break; } } } } for (id in handlers) { handler = handlers[id]; if (!handler(stanza, room)) { delete handlers[id]; } } return true; }); } if (!this.rooms.hasOwnProperty(room)) { this.rooms[room] = new XmppRoom(this, room, nick, password); this.roomNames.push(room); } if (pres_handler_cb) { this.rooms[room].addHandler('presence', pres_handler_cb); } if (msg_handler_cb) { this.rooms[room].addHandler('message', msg_handler_cb); } if (roster_cb) { this.rooms[room].addHandler('roster', roster_cb); } return this._connection.send(msg); }, /*Function Leave a multi-user chat room Parameters: (String) room - The multi-user chat room to leave. (String) nick - The nick name used in the room. (Function) handler_cb - Optional function to handle the successful leave. (String) exit_msg - optional exit message. Returns: iqid - The unique id for the room leave. */ leave: function(room, nick, handler_cb, exit_msg) { var id, presence, presenceid, room_nick; id = this.roomNames.indexOf(room); delete this.rooms[room]; if (id >= 0) { this.roomNames.splice(id, 1); if (this.roomNames.length === 0) { this._connection.deleteHandler(this._muc_handler); this._muc_handler = null; } } room_nick = this.test_append_nick(room, nick); presenceid = this._connection.getUniqueId(); presence = $pres({ type: "unavailable", id: presenceid, from: this._connection.jid, to: room_nick }); if (exit_msg != null) { presence.c("status", exit_msg); } if (handler_cb != null) { this._connection.addHandler(handler_cb, null, "presence", null, presenceid); } this._connection.send(presence); return presenceid; }, /*Function Parameters: (String) room - The multi-user chat room name. (String) nick - The nick name used in the chat room. (String) message - The plaintext message to send to the room. (String) html_message - The message to send to the room with html markup. (String) type - "groupchat" for group chat messages o "chat" for private chat messages Returns: msgiq - the unique id used to send the message */ message: function(room, nick, message, html_message, type) { var msg, msgid, parent, room_nick; room_nick = this.test_append_nick(room, nick); type = type || (nick != null ? "chat" : "groupchat"); msgid = this._connection.getUniqueId(); msg = $msg({ to: room_nick, from: this._connection.jid, type: type, id: msgid }).c("body", { xmlns: Strophe.NS.CLIENT }).t(message); msg.up(); if (html_message != null) { msg.c("html", { xmlns: Strophe.NS.XHTML_IM }).c("body", { xmlns: Strophe.NS.XHTML }).t(html_message); if (msg.node.childNodes.length === 0) { parent = msg.node.parentNode; msg.up().up(); msg.node.removeChild(parent); } else { msg.up().up(); } } msg.c("x", { xmlns: "jabber:x:event" }).c("composing"); this._connection.send(msg); return msgid; }, /*Function Convenience Function to send a Message to all Occupants Parameters: (String) room - The multi-user chat room name. (String) message - The plaintext message to send to the room. (String) html_message - The message to send to the room with html markup. Returns: msgiq - the unique id used to send the message */ groupchat: function(room, message, html_message) { return this.message(room, null, message, html_message); }, /*Function Send a mediated invitation. Parameters: (String) room - The multi-user chat room name. (String) receiver - The invitation's receiver. (String) reason - Optional reason for joining the room. Returns: msgiq - the unique id used to send the invitation */ invite: function(room, receiver, reason) { var invitation, msgid; msgid = this._connection.getUniqueId(); invitation = $msg({ from: this._connection.jid, to: room, id: msgid }).c('x', { xmlns: Strophe.NS.MUC_USER }).c('invite', { to: receiver }); if (reason != null) { invitation.c('reason', reason); } this._connection.send(invitation); return msgid; }, /*Function Send a direct invitation. Parameters: (String) room - The multi-user chat room name. (String) receiver - The invitation's receiver. (String) reason - Optional reason for joining the room. (String) password - Optional password for the room. Returns: msgiq - the unique id used to send the invitation */ directInvite: function(room, receiver, reason, password) { var attrs, invitation, msgid; msgid = this._connection.getUniqueId(); attrs = { xmlns: 'jabber:x:conference', jid: room }; if (reason != null) { attrs.reason = reason; } if (password != null) { attrs.password = password; } invitation = $msg({ from: this._connection.jid, to: receiver, id: msgid }).c('x', attrs); this._connection.send(invitation); return msgid; }, /*Function Queries a room for a list of occupants (String) room - The multi-user chat room name. (Function) success_cb - Optional function to handle the info. (Function) error_cb - Optional function to handle an error. Returns: id - the unique id used to send the info request */ queryOccupants: function(room, success_cb, error_cb) { var attrs, info; attrs = { xmlns: Strophe.NS.DISCO_ITEMS }; info = $iq({ from: this._connection.jid, to: room, type: 'get' }).c('query', attrs); return this._connection.sendIQ(info, success_cb, error_cb); }, /*Function Start a room configuration. Parameters: (String) room - The multi-user chat room name. (Function) handler_cb - Optional function to handle the config form. Returns: id - the unique id used to send the configuration request */ configure: function(room, handler_cb, error_cb) { var config, stanza; config = $iq({ to: room, type: "get" }).c("query", { xmlns: Strophe.NS.MUC_OWNER }); stanza = config.tree(); return this._connection.sendIQ(stanza, handler_cb, error_cb); }, /*Function Cancel the room configuration Parameters: (String) room - The multi-user chat room name. Returns: id - the unique id used to cancel the configuration. */ cancelConfigure: function(room) { var config, stanza; config = $iq({ to: room, type: "set" }).c("query", { xmlns: Strophe.NS.MUC_OWNER }).c("x", { xmlns: "jabber:x:data", type: "cancel" }); stanza = config.tree(); return this._connection.sendIQ(stanza); }, /*Function Save a room configuration. Parameters: (String) room - The multi-user chat room name. (Array) config- Form Object or an array of form elements used to configure the room. Returns: id - the unique id used to save the configuration. */ saveConfiguration: function(room, config, success_cb, error_cb) { var conf, iq, stanza, _i, _len; iq = $iq({ to: room, type: "set" }).c("query", { xmlns: Strophe.NS.MUC_OWNER }); if (Strophe.x && config instanceof Strophe.x.Form) { config.type = "submit"; iq.cnode(config.toXML()); } else { iq.c("x", { xmlns: "jabber:x:data", type: "submit" }); for (_i = 0, _len = config.length; _i < _len; _i++) { conf = config[_i]; iq.cnode(conf).up(); } } stanza = iq.tree(); return this._connection.sendIQ(stanza, success_cb, error_cb); }, /*Function Parameters: (String) room - The multi-user chat room name. Returns: id - the unique id used to create the chat room. */ createInstantRoom: function(room, success_cb, error_cb) { var roomiq; roomiq = $iq({ to: room, type: "set" }).c("query", { xmlns: Strophe.NS.MUC_OWNER }).c("x", { xmlns: "jabber:x:data", type: "submit" }); return this._connection.sendIQ(roomiq.tree(), success_cb, error_cb); }, /*Function Set the topic of the chat room. Parameters: (String) room - The multi-user chat room name. (String) topic - Topic message. */ setTopic: function(room, topic) { var msg; msg = $msg({ to: room, from: this._connection.jid, type: "groupchat" }).c("subject", { xmlns: "jabber:client" }).t(topic); return this._connection.send(msg.tree()); }, /*Function Internal Function that Changes the role or affiliation of a member of a MUC room. This function is used by modifyRole and modifyAffiliation. The modification can only be done by a room moderator. An error will be returned if the user doesn't have permission. Parameters: (String) room - The multi-user chat room name. (Object) item - Object with nick and role or jid and affiliation attribute (String) reason - Optional reason for the change. (Function) handler_cb - Optional callback for success (Function) error_cb - Optional callback for error Returns: iq - the id of the mode change request. */ _modifyPrivilege: function(room, item, reason, handler_cb, error_cb) { var iq; iq = $iq({ to: room, type: "set" }).c("query", { xmlns: Strophe.NS.MUC_ADMIN }).cnode(item.node); if (reason != null) { iq.c("reason", reason); } return this._connection.sendIQ(iq.tree(), handler_cb, error_cb); }, /*Function Changes the role of a member of a MUC room. The modification can only be done by a room moderator. An error will be returned if the user doesn't have permission. Parameters: (String) room - The multi-user chat room name. (String) nick - The nick name of the user to modify. (String) role - The new role of the user. (String) affiliation - The new affiliation of the user. (String) reason - Optional reason for the change. (Function) handler_cb - Optional callback for success (Function) error_cb - Optional callback for error Returns: iq - the id of the mode change request. */ modifyRole: function(room, nick, role, reason, handler_cb, error_cb) { var item; item = $build("item", { nick: nick, role: role }); return this._modifyPrivilege(room, item, reason, handler_cb, error_cb); }, kick: function(room, nick, reason, handler_cb, error_cb) { return this.modifyRole(room, nick, 'none', reason, handler_cb, error_cb); }, voice: function(room, nick, reason, handler_cb, error_cb) { return this.modifyRole(room, nick, 'participant', reason, handler_cb, error_cb); }, mute: function(room, nick, reason, handler_cb, error_cb) { return this.modifyRole(room, nick, 'visitor', reason, handler_cb, error_cb); }, op: function(room, nick, reason, handler_cb, error_cb) { return this.modifyRole(room, nick, 'moderator', reason, handler_cb, error_cb); }, deop: function(room, nick, reason, handler_cb, error_cb) { return this.modifyRole(room, nick, 'participant', reason, handler_cb, error_cb); }, /*Function Changes the affiliation of a member of a MUC room. The modification can only be done by a room moderator. An error will be returned if the user doesn't have permission. Parameters: (String) room - The multi-user chat room name. (String) jid - The jid of the user to modify. (String) affiliation - The new affiliation of the user. (String) reason - Optional reason for the change. (Function) handler_cb - Optional callback for success (Function) error_cb - Optional callback for error Returns: iq - the id of the mode change request. */ modifyAffiliation: function(room, jid, affiliation, reason, handler_cb, error_cb) { var item; item = $build("item", { jid: jid, affiliation: affiliation }); return this._modifyPrivilege(room, item, reason, handler_cb, error_cb); }, ban: function(room, jid, reason, handler_cb, error_cb) { return this.modifyAffiliation(room, jid, 'outcast', reason, handler_cb, error_cb); }, member: function(room, jid, reason, handler_cb, error_cb) { return this.modifyAffiliation(room, jid, 'member', reason, handler_cb, error_cb); }, revoke: function(room, jid, reason, handler_cb, error_cb) { return this.modifyAffiliation(room, jid, 'none', reason, handler_cb, error_cb); }, owner: function(room, jid, reason, handler_cb, error_cb) { return this.modifyAffiliation(room, jid, 'owner', reason, handler_cb, error_cb); }, admin: function(room, jid, reason, handler_cb, error_cb) { return this.modifyAffiliation(room, jid, 'admin', reason, handler_cb, error_cb); }, /*Function Change the current users nick name. Parameters: (String) room - The multi-user chat room name. (String) user - The new nick name. */ changeNick: function(room, user) { var presence, room_nick; room_nick = this.test_append_nick(room, user); presence = $pres({ from: this._connection.jid, to: room_nick, id: this._connection.getUniqueId() }); return this._connection.send(presence.tree()); }, /*Function Change the current users status. Parameters: (String) room - The multi-user chat room name. (String) user - The current nick. (String) show - The new show-text. (String) status - The new status-text. */ setStatus: function(room, user, show, status) { var presence, room_nick; room_nick = this.test_append_nick(room, user); presence = $pres({ from: this._connection.jid, to: room_nick }); if (show != null) { presence.c('show', show).up(); } if (status != null) { presence.c('status', status); } return this._connection.send(presence.tree()); }, /*Function List all chat room available on a server. Parameters: (String) server - name of chat server. (String) handle_cb - Function to call for room list return. (String) error_cb - Function to call on error. */ listRooms: function(server, handle_cb, error_cb) { var iq; iq = $iq({ to: server, from: this._connection.jid, type: "get" }).c("query", { xmlns: Strophe.NS.DISCO_ITEMS }); return this._connection.sendIQ(iq, handle_cb, error_cb); }, test_append_nick: function(room, nick) { return room + (nick != null ? "/" + (Strophe.escapeNode(nick)) : ""); } }); XmppRoom = (function() { function XmppRoom(client, name, nick, password) { this.client = client; this.name = name; this.nick = nick; this.password = password; this._roomRosterHandler = __bind(this._roomRosterHandler, this); this._addOccupant = __bind(this._addOccupant, this); this.roster = {}; this._message_handlers = {}; this._presence_handlers = {}; this._roster_handlers = {}; this._handler_ids = 0; if (client.muc) { this.client = client.muc; } this.name = Strophe.getBareJidFromJid(name); this.addHandler('presence', this._roomRosterHandler); } XmppRoom.prototype.join = function(msg_handler_cb, pres_handler_cb, roster_cb) { return this.client.join(this.name, this.nick, msg_handler_cb, pres_handler_cb, roster_cb, this.password); }; XmppRoom.prototype.leave = function(handler_cb, message) { this.client.leave(this.name, this.nick, handler_cb, message); return delete this.client.rooms[this.name]; }; XmppRoom.prototype.message = function(nick, message, html_message, type) { return this.client.message(this.name, nick, message, html_message, type); }; XmppRoom.prototype.groupchat = function(message, html_message) { return this.client.groupchat(this.name, message, html_message); }; XmppRoom.prototype.invite = function(receiver, reason) { return this.client.invite(this.name, receiver, reason); }; XmppRoom.prototype.directInvite = function(receiver, reason) { return this.client.directInvite(this.name, receiver, reason, this.password); }; XmppRoom.prototype.configure = function(handler_cb) { return this.client.configure(this.name, handler_cb); }; XmppRoom.prototype.cancelConfigure = function() { return this.client.cancelConfigure(this.name); }; XmppRoom.prototype.saveConfiguration = function(config) { return this.client.saveConfiguration(this.name, config); }; XmppRoom.prototype.queryOccupants = function(success_cb, error_cb) { return this.client.queryOccupants(this.name, success_cb, error_cb); }; XmppRoom.prototype.setTopic = function(topic) { return this.client.setTopic(this.name, topic); }; XmppRoom.prototype.modifyRole = function(nick, role, reason, success_cb, error_cb) { return this.client.modifyRole(this.name, nick, role, reason, success_cb, error_cb); }; XmppRoom.prototype.kick = function(nick, reason, handler_cb, error_cb) { return this.client.kick(this.name, nick, reason, handler_cb, error_cb); }; XmppRoom.prototype.voice = function(nick, reason, handler_cb, error_cb) { return this.client.voice(this.name, nick, reason, handler_cb, error_cb); }; XmppRoom.prototype.mute = function(nick, reason, handler_cb, error_cb) { return this.client.mute(this.name, nick, reason, handler_cb, error_cb); }; XmppRoom.prototype.op = function(nick, reason, handler_cb, error_cb) { return this.client.op(this.name, nick, reason, handler_cb, error_cb); }; XmppRoom.prototype.deop = function(nick, reason, handler_cb, error_cb) { return this.client.deop(this.name, nick, reason, handler_cb, error_cb); }; XmppRoom.prototype.modifyAffiliation = function(jid, affiliation, reason, success_cb, error_cb) { return this.client.modifyAffiliation(this.name, jid, affiliation, reason, success_cb, error_cb); }; XmppRoom.prototype.ban = function(jid, reason, handler_cb, error_cb) { return this.client.ban(this.name, jid, reason, handler_cb, error_cb); }; XmppRoom.prototype.member = function(jid, reason, handler_cb, error_cb) { return this.client.member(this.name, jid, reason, handler_cb, error_cb); }; XmppRoom.prototype.revoke = function(jid, reason, handler_cb, error_cb) { return this.client.revoke(this.name, jid, reason, handler_cb, error_cb); }; XmppRoom.prototype.owner = function(jid, reason, handler_cb, error_cb) { return this.client.owner(this.name, jid, reason, handler_cb, error_cb); }; XmppRoom.prototype.admin = function(jid, reason, handler_cb, error_cb) { return this.client.admin(this.name, jid, reason, handler_cb, error_cb); }; XmppRoom.prototype.changeNick = function(nick) { this.nick = nick; return this.client.changeNick(this.name, nick); }; XmppRoom.prototype.setStatus = function(show, status) { return this.client.setStatus(this.name, this.nick, show, status); }; /*Function Adds a handler to the MUC room. Parameters: (String) handler_type - 'message', 'presence' or 'roster'. (Function) handler - The handler function. Returns: id - the id of handler. */ XmppRoom.prototype.addHandler = function(handler_type, handler) { var id; id = this._handler_ids++; switch (handler_type) { case 'presence': this._presence_handlers[id] = handler; break; case 'message': this._message_handlers[id] = handler; break; case 'roster': this._roster_handlers[id] = handler; break; default: this._handler_ids--; return null; } return id; }; /*Function Removes a handler from the MUC room. This function takes ONLY ids returned by the addHandler function of this room. passing handler ids returned by connection.addHandler may brake things! Parameters: (number) id - the id of the handler */ XmppRoom.prototype.removeHandler = function(id) { delete this._presence_handlers[id]; delete this._message_handlers[id]; return delete this._roster_handlers[id]; }; /*Function Creates and adds an Occupant to the Room Roster. Parameters: (Object) data - the data the Occupant is filled with Returns: occ - the created Occupant. */ XmppRoom.prototype._addOccupant = function(data) { var occ; occ = new Occupant(data, this); this.roster[occ.nick] = occ; return occ; }; /*Function The standard handler that managed the Room Roster. Parameters: (Object) pres - the presence stanza containing user information */ XmppRoom.prototype._roomRosterHandler = function(pres) { var data, handler, id, newnick, nick, _ref; data = XmppRoom._parsePresence(pres); nick = data.nick; newnick = data.newnick || null; switch (data.type) { case 'error': return; case 'unavailable': if (newnick) { data.nick = newnick; if (this.roster[nick] && this.roster[newnick]) { this.roster[nick].update(this.roster[newnick]); this.roster[newnick] = this.roster[nick]; } if (this.roster[nick] && !this.roster[newnick]) { this.roster[newnick] = this.roster[nick].update(data); } } delete this.roster[nick]; break; default: if (this.roster[nick]) { this.roster[nick].update(data); } else { this._addOccupant(data); } } _ref = this._roster_handlers; for (id in _ref) { handler = _ref[id]; if (!handler(this.roster, this)) { delete this._roster_handlers[id]; } } return true; }; /*Function Parses a presence stanza Parameters: (Object) data - the data extracted from the presence stanza */ XmppRoom._parsePresence = function(pres) { var a, c, c2, data, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; data = {}; a = pres.attributes; data.nick = Strophe.getResourceFromJid(a.from.textContent); data.type = ((_ref = a.type) != null ? _ref.textContent : void 0) || null; data.states = []; _ref1 = pres.childNodes; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { c = _ref1[_i]; switch (c.nodeName) { case "status": data.status = c.textContent || null; break; case "show": data.show = c.textContent || null; break; case "x": a = c.attributes; if (((_ref2 = a.xmlns) != null ? _ref2.textContent : void 0) === Strophe.NS.MUC_USER) { _ref3 = c.childNodes; for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { c2 = _ref3[_j]; switch (c2.nodeName) { case "item": a = c2.attributes; data.affiliation = ((_ref4 = a.affiliation) != null ? _ref4.textContent : void 0) || null; data.role = ((_ref5 = a.role) != null ? _ref5.textContent : void 0) || null; data.jid = ((_ref6 = a.jid) != null ? _ref6.textContent : void 0) || null; data.newnick = ((_ref7 = a.nick) != null ? _ref7.textContent : void 0) || null; break; case "status": if (c2.attributes.code) { data.states.push(c2.attributes.code.textContent); } } } } } } return data; }; return XmppRoom; })(); RoomConfig = (function() { function RoomConfig(info) { this.parse = __bind(this.parse, this); if (info != null) { this.parse(info); } } RoomConfig.prototype.parse = function(result) { var attr, attrs, child, field, identity, query, _i, _j, _k, _len, _len1, _len2, _ref; query = result.getElementsByTagName("query")[0].childNodes; this.identities = []; this.features = []; this.x = []; for (_i = 0, _len = query.length; _i < _len; _i++) { child = query[_i]; attrs = child.attributes; switch (child.nodeName) { case "identity": identity = {}; for (_j = 0, _len1 = attrs.length; _j < _len1; _j++) { attr = attrs[_j]; identity[attr.name] = attr.textContent; } this.identities.push(identity); break; case "feature": this.features.push(attrs["var"].textContent); break; case "x": attrs = child.childNodes[0].attributes; if ((!attrs["var"].textContent === 'FORM_TYPE') || (!attrs.type.textContent === 'hidden')) { break; } _ref = child.childNodes; for (_k = 0, _len2 = _ref.length; _k < _len2; _k++) { field = _ref[_k]; if (!(!field.attributes.type)) { continue; } attrs = field.attributes; this.x.push({ "var": attrs["var"].textContent, label: attrs.label.textContent || "", value: field.firstChild.textContent || "" }); } } } return { "identities": this.identities, "features": this.features, "x": this.x }; }; return RoomConfig; })(); Occupant = (function() { function Occupant(data, room) { this.room = room; this.update = __bind(this.update, this); this.admin = __bind(this.admin, this); this.owner = __bind(this.owner, this); this.revoke = __bind(this.revoke, this); this.member = __bind(this.member, this); this.ban = __bind(this.ban, this); this.modifyAffiliation = __bind(this.modifyAffiliation, this); this.deop = __bind(this.deop, this); this.op = __bind(this.op, this); this.mute = __bind(this.mute, this); this.voice = __bind(this.voice, this); this.kick = __bind(this.kick, this); this.modifyRole = __bind(this.modifyRole, this); this.update(data); } Occupant.prototype.modifyRole = function(role, reason, success_cb, error_cb) { return this.room.modifyRole(this.nick, role, reason, success_cb, error_cb); }; Occupant.prototype.kick = function(reason, handler_cb, error_cb) { return this.room.kick(this.nick, reason, handler_cb, error_cb); }; Occupant.prototype.voice = function(reason, handler_cb, error_cb) { return this.room.voice(this.nick, reason, handler_cb, error_cb); }; Occupant.prototype.mute = function(reason, handler_cb, error_cb) { return this.room.mute(this.nick, reason, handler_cb, error_cb); }; Occupant.prototype.op = function(reason, handler_cb, error_cb) { return this.room.op(this.nick, reason, handler_cb, error_cb); }; Occupant.prototype.deop = function(reason, handler_cb, error_cb) { return this.room.deop(this.nick, reason, handler_cb, error_cb); }; Occupant.prototype.modifyAffiliation = function(affiliation, reason, success_cb, error_cb) { return this.room.modifyAffiliation(this.jid, affiliation, reason, success_cb, error_cb); }; Occupant.prototype.ban = function(reason, handler_cb, error_cb) { return this.room.ban(this.jid, reason, handler_cb, error_cb); }; Occupant.prototype.member = function(reason, handler_cb, error_cb) { return this.room.member(this.jid, reason, handler_cb, error_cb); }; Occupant.prototype.revoke = function(reason, handler_cb, error_cb) { return this.room.revoke(this.jid, reason, handler_cb, error_cb); }; Occupant.prototype.owner = function(reason, handler_cb, error_cb) { return this.room.owner(this.jid, reason, handler_cb, error_cb); }; Occupant.prototype.admin = function(reason, handler_cb, error_cb) { return this.room.admin(this.jid, reason, handler_cb, error_cb); }; Occupant.prototype.update = function(data) { this.nick = data.nick || null; this.affiliation = data.affiliation || null; this.role = data.role || null; this.jid = data.jid || null; this.status = data.status || null; this.show = data.show || null; return this; }; return Occupant; })(); rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/0000755000076400007640000000000012572247340027776 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/vendor/0000755000076400007640000000000012572247340031273 5ustar pravipravi././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/vendor/crypto.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/vendor/crypto.0000644000076400007640000022607412572247340032627 0ustar pravipravi;(function (root, factory) { if (typeof define === "function" && define.amd) { define(factory) } else if (typeof module !== 'undefined' && module.exports) { module.exports = factory() } else { root.CryptoJS = factory() } }(this, function () { /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** * CryptoJS core components. */ var CryptoJS = CryptoJS || (function (Math, undefined) { /** * CryptoJS namespace. */ var C = {}; /** * Library namespace. */ var C_lib = C.lib = {}; /** * Base object for prototypal inheritance. */ var Base = C_lib.Base = (function () { function F() {} return { /** * Creates a new object that inherits from this object. * * @param {Object} overrides Properties to copy into the new object. * * @return {Object} The new object. * * @static * * @example * * var MyType = CryptoJS.lib.Base.extend({ * field: 'value', * * method: function () { * } * }); */ extend: function (overrides) { // Spawn F.prototype = this; var subtype = new F(); // Augment if (overrides) { subtype.mixIn(overrides); } // Create default initializer if (!subtype.hasOwnProperty('init')) { subtype.init = function () { subtype.$super.init.apply(this, arguments); }; } // Initializer's prototype is the subtype object subtype.init.prototype = subtype; // Reference supertype subtype.$super = this; return subtype; }, /** * Extends this object and runs the init method. * Arguments to create() will be passed to init(). * * @return {Object} The new object. * * @static * * @example * * var instance = MyType.create(); */ create: function () { var instance = this.extend(); instance.init.apply(instance, arguments); return instance; }, /** * Initializes a newly created object. * Override this method to add some logic when your objects are created. * * @example * * var MyType = CryptoJS.lib.Base.extend({ * init: function () { * // ... * } * }); */ init: function () { }, /** * Copies properties into this object. * * @param {Object} properties The properties to mix in. * * @example * * MyType.mixIn({ * field: 'value' * }); */ mixIn: function (properties) { for (var propertyName in properties) { if (properties.hasOwnProperty(propertyName)) { this[propertyName] = properties[propertyName]; } } // IE won't copy toString using the loop above if (properties.hasOwnProperty('toString')) { this.toString = properties.toString; } }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = instance.clone(); */ clone: function () { return this.init.prototype.extend(this); } }; }()); /** * An array of 32-bit words. * * @property {Array} words The array of 32-bit words. * @property {number} sigBytes The number of significant bytes in this word array. */ var WordArray = C_lib.WordArray = Base.extend({ /** * Initializes a newly created word array. * * @param {Array} words (Optional) An array of 32-bit words. * @param {number} sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.lib.WordArray.create(); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); */ init: function (words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 4; } }, /** * Converts this word array to a string. * * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex * * @return {string} The stringified word array. * * @example * * var string = wordArray + ''; * var string = wordArray.toString(); * var string = wordArray.toString(CryptoJS.enc.Utf8); */ toString: function (encoder) { return (encoder || Hex).stringify(this); }, /** * Concatenates a word array to this word array. * * @param {WordArray} wordArray The word array to append. * * @return {WordArray} This word array. * * @example * * wordArray1.concat(wordArray2); */ concat: function (wordArray) { // Shortcuts var thisWords = this.words; var thatWords = wordArray.words; var thisSigBytes = this.sigBytes; var thatSigBytes = wordArray.sigBytes; // Clamp excess bits this.clamp(); // Concat if (thisSigBytes % 4) { // Copy one byte at a time for (var i = 0; i < thatSigBytes; i++) { var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); } } else if (thatWords.length > 0xffff) { // Copy one word at a time for (var i = 0; i < thatSigBytes; i += 4) { thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; } } else { // Copy all words at once thisWords.push.apply(thisWords, thatWords); } this.sigBytes += thatSigBytes; // Chainable return this; }, /** * Removes insignificant bits. * * @example * * wordArray.clamp(); */ clamp: function () { // Shortcuts var words = this.words; var sigBytes = this.sigBytes; // Clamp words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); words.length = Math.ceil(sigBytes / 4); }, /** * Creates a copy of this word array. * * @return {WordArray} The clone. * * @example * * var clone = wordArray.clone(); */ clone: function () { var clone = Base.clone.call(this); clone.words = this.words.slice(0); return clone; }, /** * Creates a word array filled with random bytes. * * @param {number} nBytes The number of random bytes to generate. * * @return {WordArray} The random word array. * * @static * * @example * * var wordArray = CryptoJS.lib.WordArray.random(16); */ random: function (nBytes) { var words = []; for (var i = 0; i < nBytes; i += 4) { words.push((Math.random() * 0x100000000) | 0); } return new WordArray.init(words, nBytes); } }); /** * Encoder namespace. */ var C_enc = C.enc = {}; /** * Hex encoding strategy. */ var Hex = C_enc.Hex = { /** * Converts a word array to a hex string. * * @param {WordArray} wordArray The word array. * * @return {string} The hex string. * * @static * * @example * * var hexString = CryptoJS.enc.Hex.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var hexChars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; hexChars.push((bite >>> 4).toString(16)); hexChars.push((bite & 0x0f).toString(16)); } return hexChars.join(''); }, /** * Converts a hex string to a word array. * * @param {string} hexStr The hex string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Hex.parse(hexString); */ parse: function (hexStr) { // Shortcut var hexStrLength = hexStr.length; // Convert var words = []; for (var i = 0; i < hexStrLength; i += 2) { words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); } return new WordArray.init(words, hexStrLength / 2); } }; /** * Latin1 encoding strategy. */ var Latin1 = C_enc.Latin1 = { /** * Converts a word array to a Latin1 string. * * @param {WordArray} wordArray The word array. * * @return {string} The Latin1 string. * * @static * * @example * * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var latin1Chars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; latin1Chars.push(String.fromCharCode(bite)); } return latin1Chars.join(''); }, /** * Converts a Latin1 string to a word array. * * @param {string} latin1Str The Latin1 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); */ parse: function (latin1Str) { // Shortcut var latin1StrLength = latin1Str.length; // Convert var words = []; for (var i = 0; i < latin1StrLength; i++) { words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); } return new WordArray.init(words, latin1StrLength); } }; /** * UTF-8 encoding strategy. */ var Utf8 = C_enc.Utf8 = { /** * Converts a word array to a UTF-8 string. * * @param {WordArray} wordArray The word array. * * @return {string} The UTF-8 string. * * @static * * @example * * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); */ stringify: function (wordArray) { try { return decodeURIComponent(escape(Latin1.stringify(wordArray))); } catch (e) { throw new Error('Malformed UTF-8 data'); } }, /** * Converts a UTF-8 string to a word array. * * @param {string} utf8Str The UTF-8 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); */ parse: function (utf8Str) { return Latin1.parse(unescape(encodeURIComponent(utf8Str))); } }; /** * Abstract buffered block algorithm template. * * The property blockSize must be implemented in a concrete subtype. * * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 */ var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ /** * Resets this block algorithm's data buffer to its initial state. * * @example * * bufferedBlockAlgorithm.reset(); */ reset: function () { // Initial values this._data = new WordArray.init(); this._nDataBytes = 0; }, /** * Adds new data to this block algorithm's buffer. * * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. * * @example * * bufferedBlockAlgorithm._append('data'); * bufferedBlockAlgorithm._append(wordArray); */ _append: function (data) { // Convert string to WordArray, else assume WordArray already if (typeof data == 'string') { data = Utf8.parse(data); } // Append this._data.concat(data); this._nDataBytes += data.sigBytes; }, /** * Processes available data blocks. * * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. * * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. * * @return {WordArray} The processed data. * * @example * * var processedData = bufferedBlockAlgorithm._process(); * var processedData = bufferedBlockAlgorithm._process(!!'flush'); */ _process: function (doFlush) { // Shortcuts var data = this._data; var dataWords = data.words; var dataSigBytes = data.sigBytes; var blockSize = this.blockSize; var blockSizeBytes = blockSize * 4; // Count blocks ready var nBlocksReady = dataSigBytes / blockSizeBytes; if (doFlush) { // Round up to include partial blocks nBlocksReady = Math.ceil(nBlocksReady); } else { // Round down to include only full blocks, // less the number of blocks that must remain in the buffer nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); } // Count words ready var nWordsReady = nBlocksReady * blockSize; // Count bytes ready var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); // Process blocks if (nWordsReady) { for (var offset = 0; offset < nWordsReady; offset += blockSize) { // Perform concrete-algorithm logic this._doProcessBlock(dataWords, offset); } // Remove processed words var processedWords = dataWords.splice(0, nWordsReady); data.sigBytes -= nBytesReady; } // Return processed words return new WordArray.init(processedWords, nBytesReady); }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = bufferedBlockAlgorithm.clone(); */ clone: function () { var clone = Base.clone.call(this); clone._data = this._data.clone(); return clone; }, _minBufferSize: 0 }); /** * Abstract hasher template. * * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) */ var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ /** * Configuration options. */ cfg: Base.extend(), /** * Initializes a newly created hasher. * * @param {Object} cfg (Optional) The configuration options to use for this hash computation. * * @example * * var hasher = CryptoJS.algo.SHA256.create(); */ init: function (cfg) { // Apply config defaults this.cfg = this.cfg.extend(cfg); // Set initial values this.reset(); }, /** * Resets this hasher to its initial state. * * @example * * hasher.reset(); */ reset: function () { // Reset data buffer BufferedBlockAlgorithm.reset.call(this); // Perform concrete-hasher logic this._doReset(); }, /** * Updates this hasher with a message. * * @param {WordArray|string} messageUpdate The message to append. * * @return {Hasher} This hasher. * * @example * * hasher.update('message'); * hasher.update(wordArray); */ update: function (messageUpdate) { // Append this._append(messageUpdate); // Update the hash this._process(); // Chainable return this; }, /** * Finalizes the hash computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} messageUpdate (Optional) A final message update. * * @return {WordArray} The hash. * * @example * * var hash = hasher.finalize(); * var hash = hasher.finalize('message'); * var hash = hasher.finalize(wordArray); */ finalize: function (messageUpdate) { // Final message update if (messageUpdate) { this._append(messageUpdate); } // Perform concrete-hasher logic var hash = this._doFinalize(); return hash; }, blockSize: 512/32, /** * Creates a shortcut function to a hasher's object interface. * * @param {Hasher} hasher The hasher to create a helper for. * * @return {Function} The shortcut function. * * @static * * @example * * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); */ _createHelper: function (hasher) { return function (message, cfg) { return new hasher.init(cfg).finalize(message); }; }, /** * Creates a shortcut function to the HMAC's object interface. * * @param {Hasher} hasher The hasher to use in this HMAC helper. * * @return {Function} The shortcut function. * * @static * * @example * * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); */ _createHmacHelper: function (hasher) { return function (message, key) { return new C_algo.HMAC.init(hasher, key).finalize(message); }; } }); /** * Algorithm namespace. */ var C_algo = C.algo = {}; return C; }(Math)); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_enc = C.enc; /** * Base64 encoding strategy. */ var Base64 = C_enc.Base64 = { /** * Converts a word array to a Base64 string. * * @param {WordArray} wordArray The word array. * * @return {string} The Base64 string. * * @static * * @example * * var base64String = CryptoJS.enc.Base64.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; var map = this._map; // Clamp excess bits wordArray.clamp(); // Convert var base64Chars = []; for (var i = 0; i < sigBytes; i += 3) { var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; var triplet = (byte1 << 16) | (byte2 << 8) | byte3; for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); } } // Add padding var paddingChar = map.charAt(64); if (paddingChar) { while (base64Chars.length % 4) { base64Chars.push(paddingChar); } } return base64Chars.join(''); }, /** * Converts a Base64 string to a word array. * * @param {string} base64Str The Base64 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Base64.parse(base64String); */ parse: function (base64Str) { // Shortcuts var base64StrLength = base64Str.length; var map = this._map; // Ignore padding var paddingChar = map.charAt(64); if (paddingChar) { var paddingIndex = base64Str.indexOf(paddingChar); if (paddingIndex != -1) { base64StrLength = paddingIndex; } } // Convert var words = []; var nBytes = 0; for (var i = 0; i < base64StrLength; i++) { if (i % 4) { var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2); var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2); words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); nBytes++; } } return WordArray.create(words, nBytes); }, _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' }; }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** * Cipher core components. */ CryptoJS.lib.Cipher || (function (undefined) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var WordArray = C_lib.WordArray; var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; var C_enc = C.enc; var Utf8 = C_enc.Utf8; var Base64 = C_enc.Base64; var C_algo = C.algo; var EvpKDF = C_algo.EvpKDF; /** * Abstract base cipher template. * * @property {number} keySize This cipher's key size. Default: 4 (128 bits) * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. */ var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ /** * Configuration options. * * @property {WordArray} iv The IV to use for this operation. */ cfg: Base.extend(), /** * Creates this cipher in encryption mode. * * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {Cipher} A cipher instance. * * @static * * @example * * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); */ createEncryptor: function (key, cfg) { return this.create(this._ENC_XFORM_MODE, key, cfg); }, /** * Creates this cipher in decryption mode. * * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {Cipher} A cipher instance. * * @static * * @example * * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); */ createDecryptor: function (key, cfg) { return this.create(this._DEC_XFORM_MODE, key, cfg); }, /** * Initializes a newly created cipher. * * @param {number} xformMode Either the encryption or decryption transormation mode constant. * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @example * * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); */ init: function (xformMode, key, cfg) { // Apply config defaults this.cfg = this.cfg.extend(cfg); // Store transform mode and key this._xformMode = xformMode; this._key = key; // Set initial values this.reset(); }, /** * Resets this cipher to its initial state. * * @example * * cipher.reset(); */ reset: function () { // Reset data buffer BufferedBlockAlgorithm.reset.call(this); // Perform concrete-cipher logic this._doReset(); }, /** * Adds data to be encrypted or decrypted. * * @param {WordArray|string} dataUpdate The data to encrypt or decrypt. * * @return {WordArray} The data after processing. * * @example * * var encrypted = cipher.process('data'); * var encrypted = cipher.process(wordArray); */ process: function (dataUpdate) { // Append this._append(dataUpdate); // Process available blocks return this._process(); }, /** * Finalizes the encryption or decryption process. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt. * * @return {WordArray} The data after final processing. * * @example * * var encrypted = cipher.finalize(); * var encrypted = cipher.finalize('data'); * var encrypted = cipher.finalize(wordArray); */ finalize: function (dataUpdate) { // Final data update if (dataUpdate) { this._append(dataUpdate); } // Perform concrete-cipher logic var finalProcessedData = this._doFinalize(); return finalProcessedData; }, keySize: 128/32, ivSize: 128/32, _ENC_XFORM_MODE: 1, _DEC_XFORM_MODE: 2, /** * Creates shortcut functions to a cipher's object interface. * * @param {Cipher} cipher The cipher to create a helper for. * * @return {Object} An object with encrypt and decrypt shortcut functions. * * @static * * @example * * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); */ _createHelper: (function () { function selectCipherStrategy(key) { if (typeof key == 'string') { return PasswordBasedCipher; } else { return SerializableCipher; } } return function (cipher) { return { encrypt: function (message, key, cfg) { return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); }, decrypt: function (ciphertext, key, cfg) { return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); } }; }; }()) }); /** * Abstract base stream cipher template. * * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) */ var StreamCipher = C_lib.StreamCipher = Cipher.extend({ _doFinalize: function () { // Process partial blocks var finalProcessedBlocks = this._process(!!'flush'); return finalProcessedBlocks; }, blockSize: 1 }); /** * Mode namespace. */ var C_mode = C.mode = {}; /** * Abstract base block cipher mode template. */ var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ /** * Creates this mode for encryption. * * @param {Cipher} cipher A block cipher instance. * @param {Array} iv The IV words. * * @static * * @example * * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); */ createEncryptor: function (cipher, iv) { return this.Encryptor.create(cipher, iv); }, /** * Creates this mode for decryption. * * @param {Cipher} cipher A block cipher instance. * @param {Array} iv The IV words. * * @static * * @example * * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); */ createDecryptor: function (cipher, iv) { return this.Decryptor.create(cipher, iv); }, /** * Initializes a newly created mode. * * @param {Cipher} cipher A block cipher instance. * @param {Array} iv The IV words. * * @example * * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); */ init: function (cipher, iv) { this._cipher = cipher; this._iv = iv; } }); /** * Cipher Block Chaining mode. */ var CBC = C_mode.CBC = (function () { /** * Abstract base CBC mode. */ var CBC = BlockCipherMode.extend(); /** * CBC encryptor. */ CBC.Encryptor = CBC.extend({ /** * Processes the data block at offset. * * @param {Array} words The data words to operate on. * @param {number} offset The offset where the block starts. * * @example * * mode.processBlock(data.words, offset); */ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher; var blockSize = cipher.blockSize; // XOR and encrypt xorBlock.call(this, words, offset, blockSize); cipher.encryptBlock(words, offset); // Remember this block to use with next block this._prevBlock = words.slice(offset, offset + blockSize); } }); /** * CBC decryptor. */ CBC.Decryptor = CBC.extend({ /** * Processes the data block at offset. * * @param {Array} words The data words to operate on. * @param {number} offset The offset where the block starts. * * @example * * mode.processBlock(data.words, offset); */ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher; var blockSize = cipher.blockSize; // Remember this block to use with next block var thisBlock = words.slice(offset, offset + blockSize); // Decrypt and XOR cipher.decryptBlock(words, offset); xorBlock.call(this, words, offset, blockSize); // This block becomes the previous block this._prevBlock = thisBlock; } }); function xorBlock(words, offset, blockSize) { // Shortcut var iv = this._iv; // Choose mixing block if (iv) { var block = iv; // Remove IV for subsequent blocks this._iv = undefined; } else { var block = this._prevBlock; } // XOR blocks for (var i = 0; i < blockSize; i++) { words[offset + i] ^= block[i]; } } return CBC; }()); /** * Padding namespace. */ var C_pad = C.pad = {}; /** * PKCS #5/7 padding strategy. */ var Pkcs7 = C_pad.Pkcs7 = { /** * Pads data using the algorithm defined in PKCS #5/7. * * @param {WordArray} data The data to pad. * @param {number} blockSize The multiple that the data should be padded to. * * @static * * @example * * CryptoJS.pad.Pkcs7.pad(wordArray, 4); */ pad: function (data, blockSize) { // Shortcut var blockSizeBytes = blockSize * 4; // Count padding bytes var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; // Create padding word var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes; // Create padding var paddingWords = []; for (var i = 0; i < nPaddingBytes; i += 4) { paddingWords.push(paddingWord); } var padding = WordArray.create(paddingWords, nPaddingBytes); // Add padding data.concat(padding); }, /** * Unpads data that had been padded using the algorithm defined in PKCS #5/7. * * @param {WordArray} data The data to unpad. * * @static * * @example * * CryptoJS.pad.Pkcs7.unpad(wordArray); */ unpad: function (data) { // Get number of padding bytes from last byte var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; // Remove padding data.sigBytes -= nPaddingBytes; } }; /** * Abstract base block cipher template. * * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) */ var BlockCipher = C_lib.BlockCipher = Cipher.extend({ /** * Configuration options. * * @property {Mode} mode The block mode to use. Default: CBC * @property {Padding} padding The padding strategy to use. Default: Pkcs7 */ cfg: Cipher.cfg.extend({ mode: CBC, padding: Pkcs7 }), reset: function () { // Reset cipher Cipher.reset.call(this); // Shortcuts var cfg = this.cfg; var iv = cfg.iv; var mode = cfg.mode; // Reset block mode if (this._xformMode == this._ENC_XFORM_MODE) { var modeCreator = mode.createEncryptor; } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { var modeCreator = mode.createDecryptor; // Keep at least one block in the buffer for unpadding this._minBufferSize = 1; } this._mode = modeCreator.call(mode, this, iv && iv.words); }, _doProcessBlock: function (words, offset) { this._mode.processBlock(words, offset); }, _doFinalize: function () { // Shortcut var padding = this.cfg.padding; // Finalize if (this._xformMode == this._ENC_XFORM_MODE) { // Pad data padding.pad(this._data, this.blockSize); // Process final blocks var finalProcessedBlocks = this._process(!!'flush'); } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { // Process final blocks var finalProcessedBlocks = this._process(!!'flush'); // Unpad data padding.unpad(finalProcessedBlocks); } return finalProcessedBlocks; }, blockSize: 128/32 }); /** * A collection of cipher parameters. * * @property {WordArray} ciphertext The raw ciphertext. * @property {WordArray} key The key to this ciphertext. * @property {WordArray} iv The IV used in the ciphering operation. * @property {WordArray} salt The salt used with a key derivation function. * @property {Cipher} algorithm The cipher algorithm. * @property {Mode} mode The block mode used in the ciphering operation. * @property {Padding} padding The padding scheme used in the ciphering operation. * @property {number} blockSize The block size of the cipher. * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. */ var CipherParams = C_lib.CipherParams = Base.extend({ /** * Initializes a newly created cipher params object. * * @param {Object} cipherParams An object with any of the possible cipher parameters. * * @example * * var cipherParams = CryptoJS.lib.CipherParams.create({ * ciphertext: ciphertextWordArray, * key: keyWordArray, * iv: ivWordArray, * salt: saltWordArray, * algorithm: CryptoJS.algo.AES, * mode: CryptoJS.mode.CBC, * padding: CryptoJS.pad.PKCS7, * blockSize: 4, * formatter: CryptoJS.format.OpenSSL * }); */ init: function (cipherParams) { this.mixIn(cipherParams); }, /** * Converts this cipher params object to a string. * * @param {Format} formatter (Optional) The formatting strategy to use. * * @return {string} The stringified cipher params. * * @throws Error If neither the formatter nor the default formatter is set. * * @example * * var string = cipherParams + ''; * var string = cipherParams.toString(); * var string = cipherParams.toString(CryptoJS.format.OpenSSL); */ toString: function (formatter) { return (formatter || this.formatter).stringify(this); } }); /** * Format namespace. */ var C_format = C.format = {}; /** * OpenSSL formatting strategy. */ var OpenSSLFormatter = C_format.OpenSSL = { /** * Converts a cipher params object to an OpenSSL-compatible string. * * @param {CipherParams} cipherParams The cipher params object. * * @return {string} The OpenSSL-compatible string. * * @static * * @example * * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); */ stringify: function (cipherParams) { // Shortcuts var ciphertext = cipherParams.ciphertext; var salt = cipherParams.salt; // Format if (salt) { var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); } else { var wordArray = ciphertext; } return wordArray.toString(Base64); }, /** * Converts an OpenSSL-compatible string to a cipher params object. * * @param {string} openSSLStr The OpenSSL-compatible string. * * @return {CipherParams} The cipher params object. * * @static * * @example * * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); */ parse: function (openSSLStr) { // Parse base64 var ciphertext = Base64.parse(openSSLStr); // Shortcut var ciphertextWords = ciphertext.words; // Test for salt if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { // Extract salt var salt = WordArray.create(ciphertextWords.slice(2, 4)); // Remove salt from ciphertext ciphertextWords.splice(0, 4); ciphertext.sigBytes -= 16; } return CipherParams.create({ ciphertext: ciphertext, salt: salt }); } }; /** * A cipher wrapper that returns ciphertext as a serializable cipher params object. */ var SerializableCipher = C_lib.SerializableCipher = Base.extend({ /** * Configuration options. * * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL */ cfg: Base.extend({ format: OpenSSLFormatter }), /** * Encrypts a message. * * @param {Cipher} cipher The cipher algorithm to use. * @param {WordArray|string} message The message to encrypt. * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {CipherParams} A cipher params object. * * @static * * @example * * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); */ encrypt: function (cipher, message, key, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Encrypt var encryptor = cipher.createEncryptor(key, cfg); var ciphertext = encryptor.finalize(message); // Shortcut var cipherCfg = encryptor.cfg; // Create and return serializable cipher params return CipherParams.create({ ciphertext: ciphertext, key: key, iv: cipherCfg.iv, algorithm: cipher, mode: cipherCfg.mode, padding: cipherCfg.padding, blockSize: cipher.blockSize, formatter: cfg.format }); }, /** * Decrypts serialized ciphertext. * * @param {Cipher} cipher The cipher algorithm to use. * @param {CipherParams|string} ciphertext The ciphertext to decrypt. * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {WordArray} The plaintext. * * @static * * @example * * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); */ decrypt: function (cipher, ciphertext, key, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Convert string to CipherParams ciphertext = this._parse(ciphertext, cfg.format); // Decrypt var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); return plaintext; }, /** * Converts serialized ciphertext to CipherParams, * else assumed CipherParams already and returns ciphertext unchanged. * * @param {CipherParams|string} ciphertext The ciphertext. * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext. * * @return {CipherParams} The unserialized ciphertext. * * @static * * @example * * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); */ _parse: function (ciphertext, format) { if (typeof ciphertext == 'string') { return format.parse(ciphertext, this); } else { return ciphertext; } } }); /** * Key derivation function namespace. */ var C_kdf = C.kdf = {}; /** * OpenSSL key derivation function. */ var OpenSSLKdf = C_kdf.OpenSSL = { /** * Derives a key and IV from a password. * * @param {string} password The password to derive from. * @param {number} keySize The size in words of the key to generate. * @param {number} ivSize The size in words of the IV to generate. * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. * * @return {CipherParams} A cipher params object with the key, IV, and salt. * * @static * * @example * * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); */ execute: function (password, keySize, ivSize, salt) { // Generate random salt if (!salt) { salt = WordArray.random(64/8); } // Derive key and IV var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); // Separate key and IV var iv = WordArray.create(key.words.slice(keySize), ivSize * 4); key.sigBytes = keySize * 4; // Return params return CipherParams.create({ key: key, iv: iv, salt: salt }); } }; /** * A serializable cipher wrapper that derives the key from a password, * and returns ciphertext as a serializable cipher params object. */ var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ /** * Configuration options. * * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL */ cfg: SerializableCipher.cfg.extend({ kdf: OpenSSLKdf }), /** * Encrypts a message using a password. * * @param {Cipher} cipher The cipher algorithm to use. * @param {WordArray|string} message The message to encrypt. * @param {string} password The password. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {CipherParams} A cipher params object. * * @static * * @example * * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); */ encrypt: function (cipher, message, password, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Derive key and other params var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize); // Add IV to config cfg.iv = derivedParams.iv; // Encrypt var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); // Mix in derived params ciphertext.mixIn(derivedParams); return ciphertext; }, /** * Decrypts serialized ciphertext using a password. * * @param {Cipher} cipher The cipher algorithm to use. * @param {CipherParams|string} ciphertext The ciphertext to decrypt. * @param {string} password The password. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {WordArray} The plaintext. * * @static * * @example * * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); */ decrypt: function (cipher, ciphertext, password, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Convert string to CipherParams ciphertext = this._parse(ciphertext, cfg.format); // Derive key and other params var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt); // Add IV to config cfg.iv = derivedParams.iv; // Decrypt var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); return plaintext; } }); }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var BlockCipher = C_lib.BlockCipher; var C_algo = C.algo; // Lookup tables var SBOX = []; var INV_SBOX = []; var SUB_MIX_0 = []; var SUB_MIX_1 = []; var SUB_MIX_2 = []; var SUB_MIX_3 = []; var INV_SUB_MIX_0 = []; var INV_SUB_MIX_1 = []; var INV_SUB_MIX_2 = []; var INV_SUB_MIX_3 = []; // Compute lookup tables (function () { // Compute double table var d = []; for (var i = 0; i < 256; i++) { if (i < 128) { d[i] = i << 1; } else { d[i] = (i << 1) ^ 0x11b; } } // Walk GF(2^8) var x = 0; var xi = 0; for (var i = 0; i < 256; i++) { // Compute sbox var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; SBOX[x] = sx; INV_SBOX[sx] = x; // Compute multiplication var x2 = d[x]; var x4 = d[x2]; var x8 = d[x4]; // Compute sub bytes, mix columns tables var t = (d[sx] * 0x101) ^ (sx * 0x1010100); SUB_MIX_0[x] = (t << 24) | (t >>> 8); SUB_MIX_1[x] = (t << 16) | (t >>> 16); SUB_MIX_2[x] = (t << 8) | (t >>> 24); SUB_MIX_3[x] = t; // Compute inv sub bytes, inv mix columns tables var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8); INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16); INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24); INV_SUB_MIX_3[sx] = t; // Compute next counter if (!x) { x = xi = 1; } else { x = x2 ^ d[d[d[x8 ^ x2]]]; xi ^= d[d[xi]]; } } }()); // Precomputed Rcon lookup var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; /** * AES block cipher algorithm. */ var AES = C_algo.AES = BlockCipher.extend({ _doReset: function () { // Shortcuts var key = this._key; var keyWords = key.words; var keySize = key.sigBytes / 4; // Compute number of rounds var nRounds = this._nRounds = keySize + 6 // Compute number of key schedule rows var ksRows = (nRounds + 1) * 4; // Compute key schedule var keySchedule = this._keySchedule = []; for (var ksRow = 0; ksRow < ksRows; ksRow++) { if (ksRow < keySize) { keySchedule[ksRow] = keyWords[ksRow]; } else { var t = keySchedule[ksRow - 1]; if (!(ksRow % keySize)) { // Rot word t = (t << 8) | (t >>> 24); // Sub word t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; // Mix Rcon t ^= RCON[(ksRow / keySize) | 0] << 24; } else if (keySize > 6 && ksRow % keySize == 4) { // Sub word t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; } keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; } } // Compute inv key schedule var invKeySchedule = this._invKeySchedule = []; for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) { var ksRow = ksRows - invKsRow; if (invKsRow % 4) { var t = keySchedule[ksRow]; } else { var t = keySchedule[ksRow - 4]; } if (invKsRow < 4 || ksRow <= 4) { invKeySchedule[invKsRow] = t; } else { invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^ INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]]; } } }, encryptBlock: function (M, offset) { this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); }, decryptBlock: function (M, offset) { // Swap 2nd and 4th rows var t = M[offset + 1]; M[offset + 1] = M[offset + 3]; M[offset + 3] = t; this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); // Inv swap 2nd and 4th rows var t = M[offset + 1]; M[offset + 1] = M[offset + 3]; M[offset + 3] = t; }, _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { // Shortcut var nRounds = this._nRounds; // Get input, add round key var s0 = M[offset] ^ keySchedule[0]; var s1 = M[offset + 1] ^ keySchedule[1]; var s2 = M[offset + 2] ^ keySchedule[2]; var s3 = M[offset + 3] ^ keySchedule[3]; // Key schedule row counter var ksRow = 4; // Rounds for (var round = 1; round < nRounds; round++) { // Shift rows, sub bytes, mix columns, add round key var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++]; var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++]; var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++]; var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++]; // Update state s0 = t0; s1 = t1; s2 = t2; s3 = t3; } // Shift rows, sub bytes, add round key var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; // Set output M[offset] = t0; M[offset + 1] = t1; M[offset + 2] = t2; M[offset + 3] = t3; }, keySize: 256/32 }); /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); */ C.AES = BlockCipher._createHelper(AES); }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; // Reusable object var W = []; /** * SHA-1 hash algorithm. */ var SHA1 = C_algo.SHA1 = Hasher.extend({ _doReset: function () { this._hash = new WordArray.init([ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]); }, _doProcessBlock: function (M, offset) { // Shortcut var H = this._hash.words; // Working variables var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; // Computation for (var i = 0; i < 80; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; W[i] = (n << 1) | (n >>> 31); } var t = ((a << 5) | (a >>> 27)) + e + W[i]; if (i < 20) { t += ((b & c) | (~b & d)) + 0x5a827999; } else if (i < 40) { t += (b ^ c ^ d) + 0x6ed9eba1; } else if (i < 60) { t += ((b & c) | (b & d) | (c & d)) - 0x70e44324; } else /* if (i < 80) */ { t += (b ^ c ^ d) - 0x359d3e2a; } e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t; } // Intermediate hash value H[0] = (H[0] + a) | 0; H[1] = (H[1] + b) | 0; H[2] = (H[2] + c) | 0; H[3] = (H[3] + d) | 0; H[4] = (H[4] + e) | 0; }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; // Add padding dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; // Hash final blocks this._process(); // Return final computed hash return this._hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA1('message'); * var hash = CryptoJS.SHA1(wordArray); */ C.SHA1 = Hasher._createHelper(SHA1); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA1(message, key); */ C.HmacSHA1 = Hasher._createHmacHelper(SHA1); }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function (Math) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; // Initialization and round constants tables var H = []; var K = []; // Compute constants (function () { function isPrime(n) { var sqrtN = Math.sqrt(n); for (var factor = 2; factor <= sqrtN; factor++) { if (!(n % factor)) { return false; } } return true; } function getFractionalBits(n) { return ((n - (n | 0)) * 0x100000000) | 0; } var n = 2; var nPrime = 0; while (nPrime < 64) { if (isPrime(n)) { if (nPrime < 8) { H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2)); } K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3)); nPrime++; } n++; } }()); // Reusable object var W = []; /** * SHA-256 hash algorithm. */ var SHA256 = C_algo.SHA256 = Hasher.extend({ _doReset: function () { this._hash = new WordArray.init(H.slice(0)); }, _doProcessBlock: function (M, offset) { // Shortcut var H = this._hash.words; // Working variables var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; var f = H[5]; var g = H[6]; var h = H[7]; // Computation for (var i = 0; i < 64; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var gamma0x = W[i - 15]; var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ ((gamma0x << 14) | (gamma0x >>> 18)) ^ (gamma0x >>> 3); var gamma1x = W[i - 2]; var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ ((gamma1x << 13) | (gamma1x >>> 19)) ^ (gamma1x >>> 10); W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]; } var ch = (e & f) ^ (~e & g); var maj = (a & b) ^ (a & c) ^ (b & c); var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22)); var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25)); var t1 = h + sigma1 + ch + K[i] + W[i]; var t2 = sigma0 + maj; h = g; g = f; f = e; e = (d + t1) | 0; d = c; c = b; b = a; a = (t1 + t2) | 0; } // Intermediate hash value H[0] = (H[0] + a) | 0; H[1] = (H[1] + b) | 0; H[2] = (H[2] + c) | 0; H[3] = (H[3] + d) | 0; H[4] = (H[4] + e) | 0; H[5] = (H[5] + f) | 0; H[6] = (H[6] + g) | 0; H[7] = (H[7] + h) | 0; }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; // Add padding dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; // Hash final blocks this._process(); // Return final computed hash return this._hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA256('message'); * var hash = CryptoJS.SHA256(wordArray); */ C.SHA256 = Hasher._createHelper(SHA256); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA256(message, key); */ C.HmacSHA256 = Hasher._createHmacHelper(SHA256); }(Math)); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var C_enc = C.enc; var Utf8 = C_enc.Utf8; var C_algo = C.algo; /** * HMAC algorithm. */ var HMAC = C_algo.HMAC = Base.extend({ /** * Initializes a newly created HMAC. * * @param {Hasher} hasher The hash algorithm to use. * @param {WordArray|string} key The secret key. * * @example * * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); */ init: function (hasher, key) { // Init hasher hasher = this._hasher = new hasher.init(); // Convert string to WordArray, else assume WordArray already if (typeof key == 'string') { key = Utf8.parse(key); } // Shortcuts var hasherBlockSize = hasher.blockSize; var hasherBlockSizeBytes = hasherBlockSize * 4; // Allow arbitrary length keys if (key.sigBytes > hasherBlockSizeBytes) { key = hasher.finalize(key); } // Clamp excess bits key.clamp(); // Clone key for inner and outer pads var oKey = this._oKey = key.clone(); var iKey = this._iKey = key.clone(); // Shortcuts var oKeyWords = oKey.words; var iKeyWords = iKey.words; // XOR keys with pad constants for (var i = 0; i < hasherBlockSize; i++) { oKeyWords[i] ^= 0x5c5c5c5c; iKeyWords[i] ^= 0x36363636; } oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; // Set initial values this.reset(); }, /** * Resets this HMAC to its initial state. * * @example * * hmacHasher.reset(); */ reset: function () { // Shortcut var hasher = this._hasher; // Reset hasher.reset(); hasher.update(this._iKey); }, /** * Updates this HMAC with a message. * * @param {WordArray|string} messageUpdate The message to append. * * @return {HMAC} This HMAC instance. * * @example * * hmacHasher.update('message'); * hmacHasher.update(wordArray); */ update: function (messageUpdate) { this._hasher.update(messageUpdate); // Chainable return this; }, /** * Finalizes the HMAC computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} messageUpdate (Optional) A final message update. * * @return {WordArray} The HMAC. * * @example * * var hmac = hmacHasher.finalize(); * var hmac = hmacHasher.finalize('message'); * var hmac = hmacHasher.finalize(wordArray); */ finalize: function (messageUpdate) { // Shortcut var hasher = this._hasher; // Compute HMAC var innerHash = hasher.finalize(messageUpdate); hasher.reset(); var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); return hmac; } }); }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** * A noop padding strategy. */ CryptoJS.pad.NoPadding = { pad: function () { }, unpad: function () { } }; /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** * Counter block mode. */ CryptoJS.mode.CTR = (function () { var CTR = CryptoJS.lib.BlockCipherMode.extend(); var Encryptor = CTR.Encryptor = CTR.extend({ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher var blockSize = cipher.blockSize; var iv = this._iv; var counter = this._counter; // Generate keystream if (iv) { counter = this._counter = iv.slice(0); // Remove IV for subsequent blocks this._iv = undefined; } var keystream = counter.slice(0); cipher.encryptBlock(keystream, 0); // Increment counter counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0 // Encrypt for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } }); CTR.Decryptor = Encryptor; return CTR; }()); return CryptoJS }))././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/vendor/salsa20.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/vendor/salsa200000644000076400007640000002347612572247340032477 0ustar pravipravi// Salsa20 implementation // Contributed to Cryptocat by Dmitry Chestnykh // 21-01-2013 ;(function (root, factory) { if (typeof define === 'function' && define.amd) { define(factory) } else if (typeof module !== 'undefined' && module.exports) { module.exports = factory() } else { root.Salsa20 = factory() } }(this, function () { function Salsa20(key, nonce) { // Constants. this.rounds = 20; // number of Salsa rounds this.sigmaWords = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]; // State. this.keyWords = []; // key words this.nonceWords = [0, 0]; // nonce words this.counterWords = [0, 0]; // block counter words // Output buffer. this.block = []; // output block of 64 bytes this.blockUsed = 64; // number of block bytes used this.setKey(key); this.setNonce(nonce); } // setKey sets the key to the given 32-byte array. Salsa20.prototype.setKey = function(key) { for (var i = 0, j = 0; i < 8; i++, j += 4) { this.keyWords[i] = (key[j] & 0xff) | ((key[j+1] & 0xff)<<8) | ((key[j+2] & 0xff)<<16) | ((key[j+3] & 0xff)<<24); } this._reset(); }; // setNonce sets the nonce to the given 8-byte array. Salsa20.prototype.setNonce = function(nonce) { this.nonceWords[0] = (nonce[0] & 0xff) | ((nonce[1] & 0xff)<<8) | ((nonce[2] & 0xff)<<16) | ((nonce[3] & 0xff)<<24); this.nonceWords[1] = (nonce[4] & 0xff) | ((nonce[5] & 0xff)<<8) | ((nonce[6] & 0xff)<<16) | ((nonce[7] & 0xff)<<24); this._reset(); }; // getBytes returns the next numberOfBytes bytes of stream. Salsa20.prototype.getBytes = function(numberOfBytes) { var out = new Array(numberOfBytes); for (var i = 0; i < numberOfBytes; i++) { if (this.blockUsed == 64) { this._generateBlock(); this._incrementCounter(); this.blockUsed = 0; } out[i] = this.block[this.blockUsed]; this.blockUsed++; } return out; }; Salsa20.prototype.getHexString = function(numberOfBytes) { var hex=['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']; var out = []; var bytes = this.getBytes(numberOfBytes); for(var i = 0; i < bytes.length; i++) { out.push(hex[(bytes[i] >> 4) & 15]); out.push(hex[bytes[i] & 15]); } return out.join(''); }; // Private methods. Salsa20.prototype._reset = function() { this.counterWords[0] = 0; this.counterWords[1] = 0; this.blockUsed = 64; }; // _incrementCounter increments block counter. Salsa20.prototype._incrementCounter = function() { // Note: maximum 2^64 blocks. this.counterWords[0] = (this.counterWords[0] + 1) & 0xffffffff; if (this.counterWords[0] == 0) { this.counterWords[1] = (this.counterWords[1] + 1) & 0xffffffff; } }; // _generateBlock generates 64 bytes from key, nonce, and counter, // and puts the result into this.block. Salsa20.prototype._generateBlock = function() { var j0 = this.sigmaWords[0], j1 = this.keyWords[0], j2 = this.keyWords[1], j3 = this.keyWords[2], j4 = this.keyWords[3], j5 = this.sigmaWords[1], j6 = this.nonceWords[0], j7 = this.nonceWords[1], j8 = this.counterWords[0], j9 = this.counterWords[1], j10 = this.sigmaWords[2], j11 = this.keyWords[4], j12 = this.keyWords[5], j13 = this.keyWords[6], j14 = this.keyWords[7], j15 = this.sigmaWords[3]; var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15; var u; for (var i = 0; i < this.rounds; i += 2) { u = x0 + x12; x4 ^= (u<<7) | (u>>>(32-7)); u = x4 + x0; x8 ^= (u<<9) | (u>>>(32-9)); u = x8 + x4; x12 ^= (u<<13) | (u>>>(32-13)); u = x12 + x8; x0 ^= (u<<18) | (u>>>(32-18)); u = x5 + x1; x9 ^= (u<<7) | (u>>>(32-7)); u = x9 + x5; x13 ^= (u<<9) | (u>>>(32-9)); u = x13 + x9; x1 ^= (u<<13) | (u>>>(32-13)); u = x1 + x13; x5 ^= (u<<18) | (u>>>(32-18)); u = x10 + x6; x14 ^= (u<<7) | (u>>>(32-7)); u = x14 + x10; x2 ^= (u<<9) | (u>>>(32-9)); u = x2 + x14; x6 ^= (u<<13) | (u>>>(32-13)); u = x6 + x2; x10 ^= (u<<18) | (u>>>(32-18)); u = x15 + x11; x3 ^= (u<<7) | (u>>>(32-7)); u = x3 + x15; x7 ^= (u<<9) | (u>>>(32-9)); u = x7 + x3; x11 ^= (u<<13) | (u>>>(32-13)); u = x11 + x7; x15 ^= (u<<18) | (u>>>(32-18)); u = x0 + x3; x1 ^= (u<<7) | (u>>>(32-7)); u = x1 + x0; x2 ^= (u<<9) | (u>>>(32-9)); u = x2 + x1; x3 ^= (u<<13) | (u>>>(32-13)); u = x3 + x2; x0 ^= (u<<18) | (u>>>(32-18)); u = x5 + x4; x6 ^= (u<<7) | (u>>>(32-7)); u = x6 + x5; x7 ^= (u<<9) | (u>>>(32-9)); u = x7 + x6; x4 ^= (u<<13) | (u>>>(32-13)); u = x4 + x7; x5 ^= (u<<18) | (u>>>(32-18)); u = x10 + x9; x11 ^= (u<<7) | (u>>>(32-7)); u = x11 + x10; x8 ^= (u<<9) | (u>>>(32-9)); u = x8 + x11; x9 ^= (u<<13) | (u>>>(32-13)); u = x9 + x8; x10 ^= (u<<18) | (u>>>(32-18)); u = x15 + x14; x12 ^= (u<<7) | (u>>>(32-7)); u = x12 + x15; x13 ^= (u<<9) | (u>>>(32-9)); u = x13 + x12; x14 ^= (u<<13) | (u>>>(32-13)); u = x14 + x13; x15 ^= (u<<18) | (u>>>(32-18)); } x0 += j0; x1 += j1; x2 += j2; x3 += j3; x4 += j4; x5 += j5; x6 += j6; x7 += j7; x8 += j8; x9 += j9; x10 += j10; x11 += j11; x12 += j12; x13 += j13; x14 += j14; x15 += j15; this.block[ 0] = ( x0 >>> 0) & 0xff; this.block[ 1] = ( x0 >>> 8) & 0xff; this.block[ 2] = ( x0 >>> 16) & 0xff; this.block[ 3] = ( x0 >>> 24) & 0xff; this.block[ 4] = ( x1 >>> 0) & 0xff; this.block[ 5] = ( x1 >>> 8) & 0xff; this.block[ 6] = ( x1 >>> 16) & 0xff; this.block[ 7] = ( x1 >>> 24) & 0xff; this.block[ 8] = ( x2 >>> 0) & 0xff; this.block[ 9] = ( x2 >>> 8) & 0xff; this.block[10] = ( x2 >>> 16) & 0xff; this.block[11] = ( x2 >>> 24) & 0xff; this.block[12] = ( x3 >>> 0) & 0xff; this.block[13] = ( x3 >>> 8) & 0xff; this.block[14] = ( x3 >>> 16) & 0xff; this.block[15] = ( x3 >>> 24) & 0xff; this.block[16] = ( x4 >>> 0) & 0xff; this.block[17] = ( x4 >>> 8) & 0xff; this.block[18] = ( x4 >>> 16) & 0xff; this.block[19] = ( x4 >>> 24) & 0xff; this.block[20] = ( x5 >>> 0) & 0xff; this.block[21] = ( x5 >>> 8) & 0xff; this.block[22] = ( x5 >>> 16) & 0xff; this.block[23] = ( x5 >>> 24) & 0xff; this.block[24] = ( x6 >>> 0) & 0xff; this.block[25] = ( x6 >>> 8) & 0xff; this.block[26] = ( x6 >>> 16) & 0xff; this.block[27] = ( x6 >>> 24) & 0xff; this.block[28] = ( x7 >>> 0) & 0xff; this.block[29] = ( x7 >>> 8) & 0xff; this.block[30] = ( x7 >>> 16) & 0xff; this.block[31] = ( x7 >>> 24) & 0xff; this.block[32] = ( x8 >>> 0) & 0xff; this.block[33] = ( x8 >>> 8) & 0xff; this.block[34] = ( x8 >>> 16) & 0xff; this.block[35] = ( x8 >>> 24) & 0xff; this.block[36] = ( x9 >>> 0) & 0xff; this.block[37] = ( x9 >>> 8) & 0xff; this.block[38] = ( x9 >>> 16) & 0xff; this.block[39] = ( x9 >>> 24) & 0xff; this.block[40] = (x10 >>> 0) & 0xff; this.block[41] = (x10 >>> 8) & 0xff; this.block[42] = (x10 >>> 16) & 0xff; this.block[43] = (x10 >>> 24) & 0xff; this.block[44] = (x11 >>> 0) & 0xff; this.block[45] = (x11 >>> 8) & 0xff; this.block[46] = (x11 >>> 16) & 0xff; this.block[47] = (x11 >>> 24) & 0xff; this.block[48] = (x12 >>> 0) & 0xff; this.block[49] = (x12 >>> 8) & 0xff; this.block[50] = (x12 >>> 16) & 0xff; this.block[51] = (x12 >>> 24) & 0xff; this.block[52] = (x13 >>> 0) & 0xff; this.block[53] = (x13 >>> 8) & 0xff; this.block[54] = (x13 >>> 16) & 0xff; this.block[55] = (x13 >>> 24) & 0xff; this.block[56] = (x14 >>> 0) & 0xff; this.block[57] = (x14 >>> 8) & 0xff; this.block[58] = (x14 >>> 16) & 0xff; this.block[59] = (x14 >>> 24) & 0xff; this.block[60] = (x15 >>> 0) & 0xff; this.block[61] = (x15 >>> 8) & 0xff; this.block[62] = (x15 >>> 16) & 0xff; this.block[63] = (x15 >>> 24) & 0xff; }; return Salsa20 }))././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/vendor/eventemitter.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/vendor/eventem0000644000076400007640000003643312572247340032672 0ustar pravipravi/*! * EventEmitter v4.2.3 - git.io/ee * Oliver Caldwell * MIT license * @preserve */ (function () { 'use strict'; /** * Class for managing events. * Can be extended to provide event functionality in other classes. * * @class EventEmitter Manages event registering and emitting. */ function EventEmitter() {} // Shortcuts to improve speed and size // Easy access to the prototype var proto = EventEmitter.prototype; /** * Finds the index of the listener for the event in it's storage array. * * @param {Function[]} listeners Array of listeners to search through. * @param {Function} listener Method to look for. * @return {Number} Index of the specified listener, -1 if not found * @api private */ function indexOfListener(listeners, listener) { var i = listeners.length; while (i--) { if (listeners[i].listener === listener) { return i; } } return -1; } /** * Alias a method while keeping the context correct, to allow for overwriting of target method. * * @param {String} name The name of the target method. * @return {Function} The aliased method * @api private */ function alias(name) { return function aliasClosure() { return this[name].apply(this, arguments); }; } /** * Returns the listener array for the specified event. * Will initialise the event object and listener arrays if required. * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. * Each property in the object response is an array of listener functions. * * @param {String|RegExp} evt Name of the event to return the listeners from. * @return {Function[]|Object} All listener functions for the event. */ proto.getListeners = function getListeners(evt) { var events = this._getEvents(); var response; var key; // Return a concatenated array of all matching events if // the selector is a regular expression. if (typeof evt === 'object') { response = {}; for (key in events) { if (events.hasOwnProperty(key) && evt.test(key)) { response[key] = events[key]; } } } else { response = events[evt] || (events[evt] = []); } return response; }; /** * Takes a list of listener objects and flattens it into a list of listener functions. * * @param {Object[]} listeners Raw listener objects. * @return {Function[]} Just the listener functions. */ proto.flattenListeners = function flattenListeners(listeners) { var flatListeners = []; var i; for (i = 0; i < listeners.length; i += 1) { flatListeners.push(listeners[i].listener); } return flatListeners; }; /** * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. * * @param {String|RegExp} evt Name of the event to return the listeners from. * @return {Object} All listener functions for an event in an object. */ proto.getListenersAsObject = function getListenersAsObject(evt) { var listeners = this.getListeners(evt); var response; if (listeners instanceof Array) { response = {}; response[evt] = listeners; } return response || listeners; }; /** * Adds a listener function to the specified event. * The listener will not be added if it is a duplicate. * If the listener returns true then it will be removed after it is called. * If you pass a regular expression as the event name then the listener will be added to all events that match it. * * @param {String|RegExp} evt Name of the event to attach the listener to. * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. * @return {Object} Current instance of EventEmitter for chaining. */ proto.addListener = function addListener(evt, listener) { var listeners = this.getListenersAsObject(evt); var listenerIsWrapped = typeof listener === 'object'; var key; for (key in listeners) { if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { listeners[key].push(listenerIsWrapped ? listener : { listener: listener, once: false }); } } return this; }; /** * Alias of addListener */ proto.on = alias('addListener'); /** * Semi-alias of addListener. It will add a listener that will be * automatically removed after it's first execution. * * @param {String|RegExp} evt Name of the event to attach the listener to. * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. * @return {Object} Current instance of EventEmitter for chaining. */ proto.addOnceListener = function addOnceListener(evt, listener) { return this.addListener(evt, { listener: listener, once: true }); }; /** * Alias of addOnceListener. */ proto.once = alias('addOnceListener'); /** * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. * You need to tell it what event names should be matched by a regex. * * @param {String} evt Name of the event to create. * @return {Object} Current instance of EventEmitter for chaining. */ proto.defineEvent = function defineEvent(evt) { this.getListeners(evt); return this; }; /** * Uses defineEvent to define multiple events. * * @param {String[]} evts An array of event names to define. * @return {Object} Current instance of EventEmitter for chaining. */ proto.defineEvents = function defineEvents(evts) { for (var i = 0; i < evts.length; i += 1) { this.defineEvent(evts[i]); } return this; }; /** * Removes a listener function from the specified event. * When passed a regular expression as the event name, it will remove the listener from all events that match it. * * @param {String|RegExp} evt Name of the event to remove the listener from. * @param {Function} listener Method to remove from the event. * @return {Object} Current instance of EventEmitter for chaining. */ proto.removeListener = function removeListener(evt, listener) { var listeners = this.getListenersAsObject(evt); var index; var key; for (key in listeners) { if (listeners.hasOwnProperty(key)) { index = indexOfListener(listeners[key], listener); if (index !== -1) { listeners[key].splice(index, 1); } } } return this; }; /** * Alias of removeListener */ proto.off = alias('removeListener'); /** * Adds listeners in bulk using the manipulateListeners method. * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. * You can also pass it a regular expression to add the array of listeners to all events that match it. * Yeah, this function does quite a bit. That's probably a bad thing. * * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. * @param {Function[]} [listeners] An optional array of listener functions to add. * @return {Object} Current instance of EventEmitter for chaining. */ proto.addListeners = function addListeners(evt, listeners) { // Pass through to manipulateListeners return this.manipulateListeners(false, evt, listeners); }; /** * Removes listeners in bulk using the manipulateListeners method. * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. * You can also pass it an event name and an array of listeners to be removed. * You can also pass it a regular expression to remove the listeners from all events that match it. * * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. * @param {Function[]} [listeners] An optional array of listener functions to remove. * @return {Object} Current instance of EventEmitter for chaining. */ proto.removeListeners = function removeListeners(evt, listeners) { // Pass through to manipulateListeners return this.manipulateListeners(true, evt, listeners); }; /** * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. * The first argument will determine if the listeners are removed (true) or added (false). * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. * You can also pass it an event name and an array of listeners to be added/removed. * You can also pass it a regular expression to manipulate the listeners of all events that match it. * * @param {Boolean} remove True if you want to remove listeners, false if you want to add. * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. * @param {Function[]} [listeners] An optional array of listener functions to add/remove. * @return {Object} Current instance of EventEmitter for chaining. */ proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { var i; var value; var single = remove ? this.removeListener : this.addListener; var multiple = remove ? this.removeListeners : this.addListeners; // If evt is an object then pass each of it's properties to this method if (typeof evt === 'object' && !(evt instanceof RegExp)) { for (i in evt) { if (evt.hasOwnProperty(i) && (value = evt[i])) { // Pass the single listener straight through to the singular method if (typeof value === 'function') { single.call(this, i, value); } else { // Otherwise pass back to the multiple function multiple.call(this, i, value); } } } } else { // So evt must be a string // And listeners must be an array of listeners // Loop over it and pass each one to the multiple method i = listeners.length; while (i--) { single.call(this, evt, listeners[i]); } } return this; }; /** * Removes all listeners from a specified event. * If you do not specify an event then all listeners will be removed. * That means every event will be emptied. * You can also pass a regex to remove all events that match it. * * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. * @return {Object} Current instance of EventEmitter for chaining. */ proto.removeEvent = function removeEvent(evt) { var type = typeof evt; var events = this._getEvents(); var key; // Remove different things depending on the state of evt if (type === 'string') { // Remove all listeners for the specified event delete events[evt]; } else if (type === 'object') { // Remove all events matching the regex. for (key in events) { if (events.hasOwnProperty(key) && evt.test(key)) { delete events[key]; } } } else { // Remove all listeners in all events delete this._events; } return this; }; /** * Emits an event of your choice. * When emitted, every listener attached to that event will be executed. * If you pass the optional argument array then those arguments will be passed to every listener upon execution. * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. * So they will not arrive within the array on the other side, they will be separate. * You can also pass a regular expression to emit to all events that match it. * * @param {String|RegExp} evt Name of the event to emit and execute listeners for. * @param {Array} [args] Optional array of arguments to be passed to each listener. * @return {Object} Current instance of EventEmitter for chaining. */ proto.emitEvent = function emitEvent(evt, args) { var listeners = this.getListenersAsObject(evt); var listener; var i; var key; var response; for (key in listeners) { if (listeners.hasOwnProperty(key)) { i = listeners[key].length; while (i--) { // If the listener returns true then it shall be removed from the event // The function is executed either with a basic call or an apply if there is an args array listener = listeners[key][i]; if (listener.once === true) { this.removeListener(evt, listener.listener); } response = listener.listener.apply(this, args || []); if (response === this._getOnceReturnValue()) { this.removeListener(evt, listener.listener); } } } } return this; }; /** * Alias of emitEvent */ proto.trigger = alias('emitEvent'); /** * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. * * @param {String|RegExp} evt Name of the event to emit and execute listeners for. * @param {...*} Optional additional arguments to be passed to each listener. * @return {Object} Current instance of EventEmitter for chaining. */ proto.emit = function emit(evt) { var args = Array.prototype.slice.call(arguments, 1); return this.emitEvent(evt, args); }; /** * Sets the current value to check against when executing listeners. If a * listeners return value matches the one set here then it will be removed * after execution. This value defaults to true. * * @param {*} value The new value to check for when executing listeners. * @return {Object} Current instance of EventEmitter for chaining. */ proto.setOnceReturnValue = function setOnceReturnValue(value) { this._onceReturnValue = value; return this; }; /** * Fetches the current value to check against when executing listeners. If * the listeners return value matches this one then it should be removed * automatically. It will return true by default. * * @return {*|Boolean} The current value to check for or the default, true. * @api private */ proto._getOnceReturnValue = function _getOnceReturnValue() { if (this.hasOwnProperty('_onceReturnValue')) { return this._onceReturnValue; } else { return true; } }; /** * Fetches the events object and creates one if required. * * @return {Object} The events storage object. * @api private */ proto._getEvents = function _getEvents() { return this._events || (this._events = {}); }; // Expose the class either via AMD, CommonJS or the global object if (typeof define === 'function' && define.amd) { define(function () { return EventEmitter; }); } else if (typeof module === 'object' && module.exports){ module.exports = EventEmitter; } else { this.EventEmitter = EventEmitter; } }.call(this)); ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/vendor/bigint.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/vendor/bigint.0000644000076400007640000015600312572247340032555 0ustar pravipravi;(function (root, factory) { if (typeof define === 'function' && define.amd) { define(factory.bind(root, root.crypto || root.msCrypto)) } else if (typeof module !== 'undefined' && module.exports) { module.exports = factory(require('crypto')) } else { root.BigInt = factory(root.crypto || root.msCrypto) } }(this, function (crypto) { //////////////////////////////////////////////////////////////////////////////////////// // Big Integer Library v. 5.5 // Created 2000, last modified 2013 // Leemon Baird // www.leemon.com // // Version history: // v 5.5 17 Mar 2013 // - two lines of a form like "if (x<0) x+=n" had the "if" changed to "while" to // handle the case when x<-n. (Thanks to James Ansell for finding that bug) // v 5.4 3 Oct 2009 // - added "var i" to greaterShift() so i is not global. (Thanks to Péter Szabó for finding that bug) // // v 5.3 21 Sep 2009 // - added randProbPrime(k) for probable primes // - unrolled loop in mont_ (slightly faster) // - millerRabin now takes a bigInt parameter rather than an int // // v 5.2 15 Sep 2009 // - fixed capitalization in call to int2bigInt in randBigInt // (thanks to Emili Evripidou, Reinhold Behringer, and Samuel Macaleese for finding that bug) // // v 5.1 8 Oct 2007 // - renamed inverseModInt_ to inverseModInt since it doesn't change its parameters // - added functions GCD and randBigInt, which call GCD_ and randBigInt_ // - fixed a bug found by Rob Visser (see comment with his name below) // - improved comments // // This file is public domain. You can use it for any purpose without restriction. // I do not guarantee that it is correct, so use it at your own risk. If you use // it for something interesting, I'd appreciate hearing about it. If you find // any bugs or make any improvements, I'd appreciate hearing about those too. // It would also be nice if my name and URL were left in the comments. But none // of that is required. // // This code defines a bigInt library for arbitrary-precision integers. // A bigInt is an array of integers storing the value in chunks of bpe bits, // little endian (buff[0] is the least significant word). // Negative bigInts are stored two's complement. Almost all the functions treat // bigInts as nonnegative. The few that view them as two's complement say so // in their comments. Some functions assume their parameters have at least one // leading zero element. Functions with an underscore at the end of the name put // their answer into one of the arrays passed in, and have unpredictable behavior // in case of overflow, so the caller must make sure the arrays are big enough to // hold the answer. But the average user should never have to call any of the // underscored functions. Each important underscored function has a wrapper function // of the same name without the underscore that takes care of the details for you. // For each underscored function where a parameter is modified, that same variable // must not be used as another argument too. So, you cannot square x by doing // multMod_(x,x,n). You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n). // Or simply use the multMod(x,x,n) function without the underscore, where // such issues never arise, because non-underscored functions never change // their parameters; they always allocate new memory for the answer that is returned. // // These functions are designed to avoid frequent dynamic memory allocation in the inner loop. // For most functions, if it needs a BigInt as a local variable it will actually use // a global, and will only allocate to it only when it's not the right size. This ensures // that when a function is called repeatedly with same-sized parameters, it only allocates // memory on the first call. // // Note that for cryptographic purposes, the calls to Math.random() must // be replaced with calls to a better pseudorandom number generator. // // In the following, "bigInt" means a bigInt with at least one leading zero element, // and "integer" means a nonnegative integer less than radix. In some cases, integer // can be negative. Negative bigInts are 2s complement. // // The following functions do not modify their inputs. // Those returning a bigInt, string, or Array will dynamically allocate memory for that value. // Those returning a boolean will return the integer 0 (false) or 1 (true). // Those returning boolean or int will not allocate memory except possibly on the first // time they're called with a given parameter size. // // bigInt add(x,y) //return (x+y) for bigInts x and y. // bigInt addInt(x,n) //return (x+n) where x is a bigInt and n is an integer. // string bigInt2str(x,base) //return a string form of bigInt x in a given base, with 2 <= base <= 95 // int bitSize(x) //return how many bits long the bigInt x is, not counting leading zeros // bigInt dup(x) //return a copy of bigInt x // boolean equals(x,y) //is the bigInt x equal to the bigint y? // boolean equalsInt(x,y) //is bigint x equal to integer y? // bigInt expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed // Array findPrimes(n) //return array of all primes less than integer n // bigInt GCD(x,y) //return greatest common divisor of bigInts x and y (each with same number of elements). // boolean greater(x,y) //is x>y? (x and y are nonnegative bigInts) // boolean greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y? // bigInt int2bigInt(t,n,m) //return a bigInt equal to integer t, with at least n bits and m array elements // bigInt inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null // int inverseModInt(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse // boolean isZero(x) //is the bigInt x equal to zero? // boolean millerRabin(x,b) //does one round of Miller-Rabin base integer b say that bigInt x is possibly prime? (b is bigInt, 1=1). If s=1, then the most significant of those n bits is set to 1. // bigInt randTruePrime(k) //return a new, random, k-bit, true prime bigInt using Maurer's algorithm. // bigInt randProbPrime(k) //return a new, random, k-bit, probable prime bigInt (probability it's composite less than 2^-80). // bigInt str2bigInt(s,b,n,m) //return a bigInt for number represented in string s in base b with at least n bits and m array elements // bigInt sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement // bigInt trim(x,k) //return a copy of x with exactly k leading zero elements // // // The following functions each have a non-underscored version, which most users should call instead. // These functions each write to a single parameter, and the caller is responsible for ensuring the array // passed in is large enough to hold the result. // // void addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer // void add_(x,y) //do x=x+y for bigInts x and y // void copy_(x,y) //do x=y on bigInts x and y // void copyInt_(x,n) //do x=n on bigInt x and integer n // void GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed). (This never overflows its array). // boolean inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist // void mod_(x,n) //do x=x mod n for bigInts x and n. (This never overflows its array). // void mult_(x,y) //do x=x*y for bigInts x and y. // void multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n. // void powMod_(x,y,n) //do x=x**y mod n, where x,y,n are bigInts (n is odd) and ** is exponentiation. 0**0=1. // void randBigInt_(b,n,s) //do b = an n-bit random BigInt. if s=1, then nth bit (most significant bit) is set to 1. n>=1. // void randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb. // void sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement. // // The following functions do NOT have a non-underscored version. // They each write a bigInt result to one or more parameters. The caller is responsible for // ensuring the arrays passed in are large enough to hold the results. // // void addShift_(x,y,ys) //do x=x+(y<<(ys*bpe)) // void carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits. // void divide_(x,y,q,r) //divide x by y giving quotient q and remainder r // int divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder. (This never overflows its array). // int eGCD_(x,y,d,a,b) //sets a,b,d to positive bigInts such that d = GCD_(x,y) = a*x-b*y // void halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement. (This never overflows its array). // void leftShift_(x,n) //left shift bigInt x by n bits. n64 multiplier, but not with JavaScript's 32*32->32) // - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square // followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that // method would be slower. This is unfortunate because the code currently spends almost all of its time // doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring // would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded // sentences that seem to imply it's faster to do a non-modular square followed by a single // Montgomery reduction, but that's obviously wrong. //////////////////////////////////////////////////////////////////////////////////////// //globals // The number of significant bits in the fraction of a JavaScript // floating-point number is 52, independent of platform. // See: https://github.com/arlolra/otr/issues/41 var bpe = 26; // bits stored per array element var radix = 1 << bpe; // equals 2^bpe var mask = radix - 1; // AND this with an array element to chop it down to bpe bits //the digits for converting to different bases var digitsStr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-'; var one=int2bigInt(1,1,1); //constant used in powMod_() //the following global variables are scratchpad memory to //reduce dynamic memory allocation in the inner loop var t=new Array(0); var ss=t; //used in mult_() var s0=t; //used in multMod_(), squareMod_() var s1=t; //used in powMod_(), multMod_(), squareMod_() var s2=t; //used in powMod_(), multMod_() var s3=t; //used in powMod_() var s4=t, s5=t; //used in mod_() var s6=t; //used in bigInt2str() var s7=t; //used in powMod_() var T=t; //used in GCD_() var sa=t; //used in mont_() var mr_x1=t, mr_r=t, mr_a=t; //used in millerRabin() var eg_v=t, eg_u=t, eg_A=t, eg_B=t, eg_C=t, eg_D=t; //used in eGCD_(), inverseMod_() var md_q1=t, md_q2=t, md_q3=t, md_r=t, md_r1=t, md_r2=t, md_tt=t; //used in mod_() var primes=t, pows=t, s_i=t, s_i2=t, s_R=t, s_rm=t, s_q=t, s_n1=t; var s_a=t, s_r2=t, s_n=t, s_b=t, s_d=t, s_x1=t, s_x2=t, s_aa=t; //used in randTruePrime_() var rpprb=t; //used in randProbPrimeRounds() (which also uses "primes") //////////////////////////////////////////////////////////////////////////////////////// //return array of all primes less than integer n function findPrimes(n) { var i,s,p,ans; s=new Array(n); for (i=0;i0); j--); for (z=0,w=x[j]; w; (w>>=1),z++); z+=bpe*j; return z; } //return a copy of x with at least n elements, adding leading zeros if needed function expand(x,n) { var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0); copy_(ans,x); return ans; } //return a k-bit true random prime using Maurer's algorithm. function randTruePrime(k) { var ans=int2bigInt(0,k,0); randTruePrime_(ans,k); return trim(ans,1); } //return a k-bit random probable prime with probability of error < 2^-80 function randProbPrime(k) { if (k>=600) return randProbPrimeRounds(k,2); //numbers from HAC table 4.3 if (k>=550) return randProbPrimeRounds(k,4); if (k>=500) return randProbPrimeRounds(k,5); if (k>=400) return randProbPrimeRounds(k,6); if (k>=350) return randProbPrimeRounds(k,7); if (k>=300) return randProbPrimeRounds(k,9); if (k>=250) return randProbPrimeRounds(k,12); //numbers from HAC table 4.4 if (k>=200) return randProbPrimeRounds(k,15); if (k>=150) return randProbPrimeRounds(k,18); if (k>=100) return randProbPrimeRounds(k,27); return randProbPrimeRounds(k,40); //number from HAC remark 4.26 (only an estimate) } //return a k-bit probable random prime using n rounds of Miller Rabin (after trial division with small primes) function randProbPrimeRounds(k,n) { var ans, i, divisible, B; B=30000; //B is largest prime to use in trial division ans=int2bigInt(0,k,0); //optimization: try larger and smaller B to find the best limit. if (primes.length==0) primes=findPrimes(30000); //check for divisibility by primes <=30000 if (rpprb.length!=ans.length) rpprb=dup(ans); for (;;) { //keep trying random values for ans until one appears to be prime //optimization: pick a random number times L=2*3*5*...*p, plus a // random element of the list of all numbers in [0,L) not divisible by any prime up to p. // This can reduce the amount of random number generation. randBigInt_(ans,k,0); //ans = a random odd number to check ans[0] |= 1; divisible=0; //check ans for divisibility by small primes up to B for (i=0; (iy.length ? x.length+1 : y.length+1)); sub_(ans,y); return trim(ans,1); } //return (x+y) for bigInts x and y. function add(x,y) { var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1)); add_(ans,y); return trim(ans,1); } //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null function inverseMod(x,n) { var ans=expand(x,n.length); var s; s=inverseMod_(ans,n); return s ? trim(ans,1) : null; } //return (x*y mod n) for bigInts x,y,n. For greater speed, let y= 2 if (s_i2.length!=ans.length) { s_i2=dup(ans); s_R =dup(ans); s_n1=dup(ans); s_r2=dup(ans); s_d =dup(ans); s_x1=dup(ans); s_x2=dup(ans); s_b =dup(ans); s_n =dup(ans); s_i =dup(ans); s_rm=dup(ans); s_q =dup(ans); s_a =dup(ans); s_aa=dup(ans); } if (k <= recLimit) { //generate small random primes by trial division up to its square root pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k) copyInt_(ans,0); for (dd=1;dd;) { dd=0; ans[0]= 1 | (1<<(k-1)) | randomBitInt(k); //random, k-bit, odd integer, with msb 1 for (j=1;(j2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits for (r=1; k-k*r<=m; ) r=pows[randomBitInt(9)]; //r=Math.pow(2,Math.random()-1); else r=0.5; //simulation suggests the more complex algorithm using r=.333 is only slightly faster. recSize=Math.floor(r*k)+1; randTruePrime_(s_q,recSize); copyInt_(s_i2,0); s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2) divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q)) z=bitSize(s_i); for (;;) { for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1] randBigInt_(s_R,z,0); if (greater(s_i,s_R)) break; } //now s_R is in the range [0,s_i-1] addInt_(s_R,1); //now s_R is in the range [1,s_i] add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i] copy_(s_n,s_q); mult_(s_n,s_R); multInt_(s_n,2); addInt_(s_n,1); //s_n=2*s_R*s_q+1 copy_(s_r2,s_R); multInt_(s_r2,2); //s_r2=2*s_R //check s_n for divisibility by small primes up to B for (divisible=0,j=0; (j0); j--); //strip leading zeros for (zz=0,w=s_n[j]; w; (w>>=1),zz++); zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1] randBigInt_(s_a,zz,0); if (greater(s_n,s_a)) break; } //now s_a is in the range [0,s_n-1] addInt_(s_n,3); //now s_a is in the range [0,s_n-4] addInt_(s_a,2); //now s_a is in the range [2,s_n-2] copy_(s_b,s_a); copy_(s_n1,s_n); addInt_(s_n1,-1); powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n addInt_(s_b,-1); if (isZero(s_b)) { copy_(s_b,s_a); powMod_(s_b,s_r2,s_n); addInt_(s_b,-1); copy_(s_aa,s_n); copy_(s_d,s_b); GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime if (equalsInt(s_d,1)) { copy_(ans,s_aa); return; //if we've made it this far, then s_n is absolutely guaranteed to be prime } } } } } //Return an n-bit random BigInt (n>=1). If s=1, then the most significant of those n bits is set to 1. function randBigInt(n,s) { var a,b; a=Math.floor((n-1)/bpe)+2; //# array elements to hold the BigInt with a leading 0 element b=int2bigInt(0,0,a); randBigInt_(b,n,s); return b; } //Set b to an n-bit random BigInt. If s=1, then the most significant of those n bits is set to 1. //Array b must be big enough to hold the result. Must have n>=1 function randBigInt_(b,n,s) { var i,a; for (i=0;i=0;i--); //find most significant element of x xp=x[i]; yp=y[i]; A=1; B=0; C=0; D=1; while ((yp+C) && (yp+D)) { q =Math.floor((xp+A)/(yp+C)); qp=Math.floor((xp+B)/(yp+D)); if (q!=qp) break; t= A-q*C; A=C; C=t; // do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp) t= B-q*D; B=D; D=t; t=xp-q*yp; xp=yp; yp=t; } if (B) { copy_(T,x); linComb_(x,y,A,B); //x=A*x+B*y linComb_(y,T,D,C); //y=D*y+C*T } else { mod_(x,y); copy_(T,x); copy_(x,y); copy_(y,T); } } if (y[0]==0) return; t=modInt(x,y[0]); copyInt_(x,y[0]); y[0]=t; while (y[0]) { x[0]%=y[0]; t=x[0]; x[0]=y[0]; y[0]=t; } } //do x=x**(-1) mod n, for bigInts x and n. //If no inverse exists, it sets x to zero and returns 0, else it returns 1. //The x array must be at least as large as the n array. function inverseMod_(x,n) { var k=1+2*Math.max(x.length,n.length); if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist copyInt_(x,0); return 0; } if (eg_u.length!=k) { eg_u=new Array(k); eg_v=new Array(k); eg_A=new Array(k); eg_B=new Array(k); eg_C=new Array(k); eg_D=new Array(k); } copy_(eg_u,x); copy_(eg_v,n); copyInt_(eg_A,1); copyInt_(eg_B,0); copyInt_(eg_C,0); copyInt_(eg_D,1); for (;;) { while(!(eg_u[0]&1)) { //while eg_u is even halve_(eg_u); if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2 halve_(eg_A); halve_(eg_B); } else { add_(eg_A,n); halve_(eg_A); sub_(eg_B,x); halve_(eg_B); } } while (!(eg_v[0]&1)) { //while eg_v is even halve_(eg_v); if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2 halve_(eg_C); halve_(eg_D); } else { add_(eg_C,n); halve_(eg_C); sub_(eg_D,x); halve_(eg_D); } } if (!greater(eg_v,eg_u)) { //eg_v <= eg_u sub_(eg_u,eg_v); sub_(eg_A,eg_C); sub_(eg_B,eg_D); } else { //eg_v > eg_u sub_(eg_v,eg_u); sub_(eg_C,eg_A); sub_(eg_D,eg_B); } if (equalsInt(eg_u,0)) { while (negative(eg_C)) //make sure answer is nonnegative add_(eg_C,n); copy_(x,eg_C); if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse copyInt_(x,0); return 0; } return 1; } } } //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse function inverseModInt(x,n) { var a=1,b=0,t; for (;;) { if (x==1) return a; if (x==0) return 0; b-=a*Math.floor(n/x); n%=x; if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to += if (n==0) return 0; a-=b*Math.floor(x/n); x%=n; } } //this deprecated function is for backward compatibility only. function inverseModInt_(x,n) { return inverseModInt(x,n); } //Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that: // v = GCD_(x,y) = a*x-b*y //The bigInts v, a, b, must have exactly as many elements as the larger of x and y. function eGCD_(x,y,v,a,b) { var g=0; var k=Math.max(x.length,y.length); if (eg_u.length!=k) { eg_u=new Array(k); eg_A=new Array(k); eg_B=new Array(k); eg_C=new Array(k); eg_D=new Array(k); } while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even halve_(x); halve_(y); g++; } copy_(eg_u,x); copy_(v,y); copyInt_(eg_A,1); copyInt_(eg_B,0); copyInt_(eg_C,0); copyInt_(eg_D,1); for (;;) { while(!(eg_u[0]&1)) { //while u is even halve_(eg_u); if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2 halve_(eg_A); halve_(eg_B); } else { add_(eg_A,y); halve_(eg_A); sub_(eg_B,x); halve_(eg_B); } } while (!(v[0]&1)) { //while v is even halve_(v); if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2 halve_(eg_C); halve_(eg_D); } else { add_(eg_C,y); halve_(eg_C); sub_(eg_D,x); halve_(eg_D); } } if (!greater(v,eg_u)) { //v<=u sub_(eg_u,v); sub_(eg_A,eg_C); sub_(eg_B,eg_D); } else { //v>u sub_(v,eg_u); sub_(eg_C,eg_A); sub_(eg_D,eg_B); } if (equalsInt(eg_u,0)) { while (negative(eg_C)) { //make sure a (C) is nonnegative add_(eg_C,y); sub_(eg_D,x); } multInt_(eg_D,-1); ///make sure b (D) is nonnegative copy_(a,eg_C); copy_(b,eg_D); leftShift_(v,g); return; } } } //is bigInt x negative? function negative(x) { return ((x[x.length-1]>>(bpe-1))&1); } //is (x << (shift*bpe)) > y? //x and y are nonnegative bigInts //shift is a nonnegative integer function greaterShift(x,y,shift) { var i, kx=x.length, ky=y.length; var k=((kx+shift)=0; i++) if (x[i]>0) return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger for (i=kx-1+shift; i0) return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger for (i=k-1; i>=shift; i--) if (x[i-shift]>y[i]) return 1; else if (x[i-shift] y? (x and y both nonnegative) function greater(x,y) { var i; var k=(x.length=0;i--) if (x[i]>y[i]) return 1; else if (x[i]= y.length >= 2. function divide_(x,y,q,r) { var kx, ky; var i,j,y1,y2,c,a,b; copy_(r,x); for (ky=y.length;y[ky-1]==0;ky--); //ky is number of elements in y, not including leading zeros //normalize: ensure the most significant element of y has its highest bit set b=y[ky-1]; for (a=0; b; a++) b>>=1; a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element leftShift_(y,a); //multiply both by 1<ky;kx--); //kx is number of elements in normalized x, not including leading zeros copyInt_(q,0); // q=0 while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) { subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky) q[kx-ky]++; // q[kx-ky]++; } // } for (i=kx-1; i>=ky; i--) { if (r[i]==y[ky-1]) q[i-ky]=mask; else q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]); //The following for(;;) loop is equivalent to the commented while loop, //except that the uncommented version avoids overflow. //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0 // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2]) // q[i-ky]--; for (;;) { y2=(ky>1 ? y[ky-2] : 0)*q[i-ky]; c=y2; y2=y2 & mask; c = (c - y2) / radix; y1=c+q[i-ky]*y[ky-1]; c=y1; y1=y1 & mask; c = (c - y1) / radix; if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i]) q[i-ky]--; else break; } linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky) if (negative(r)) { addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky) q[i-ky]--; } } rightShift_(y,a); //undo the normalization step rightShift_(r,a); //undo the normalization step } //do carries and borrows so each element of the bigInt x fits in bpe bits. function carry_(x) { var i,k,c,b; k=x.length; c=0; for (i=0;i=0; i--) c=(c*radix+x[i])%n; return c; } //convert the integer t into a bigInt with at least the given number of bits. //the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word) //Pad the array with leading zeros so that it has at least minSize elements. //There will always be at least one leading 0 element. function int2bigInt(t,bits,minSize) { var i,k, buff; k=Math.ceil(bits/bpe)+1; k=minSize>k ? minSize : k; buff=new Array(k); copyInt_(buff,t); return buff; } //return the bigInt given a string representation in a given base. //Pad the array with leading zeros so that it has at least minSize elements. //If base=-1, then it reads in a space-separated list of array elements in decimal. //The array will always have at least one leading zero, unless base=-1. function str2bigInt(s,base,minSize) { var d, i, j, x, y, kk; var k=s.length; if (base==-1) { //comma-separated list of array elements in decimal x=new Array(0); for (;;) { y=new Array(x.length+1); for (i=0;i 1) { if (bb & 1) p = 1; b += k; bb >>= 1; } b += p*k; x=int2bigInt(0,b,0); for (i=0;i=36) //convert lowercase to uppercase if base<=36 d-=26; if (d>=base || d<0) { //stop at first illegal character break; } multInt_(x,base); addInt_(x,d); } for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros k=minSize>k+1 ? minSize : k+1; y=new Array(k); kk=ky.length) { for (;i0;i--) s+=x[i]+','; s+=x[0]; } else { //return it in the given base while (!isZero(s6)) { t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base); s=digitsStr.substring(t,t+1)+s; } } if (s.length==0) s="0"; return s; } //returns a duplicate of bigInt x function dup(x) { var i, buff; buff=new Array(x.length); copy_(buff,x); return buff; } //do x=y on bigInts x and y. x must be an array at least as big as y (not counting the leading zeros in y). function copy_(x,y) { var i; var k=x.length>=bpe; } } //do x=x+n where x is a bigInt and n is an integer. //x must be large enough to hold the result. function addInt_(x,n) { var i,k,c,b; x[0]+=n; k=x.length; c=0; for (i=0;i>n)); } x[i]>>=n; } //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement function halve_(x) { var i; for (i=0;i>1)); } x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same } //left shift bigInt x by n bits. function leftShift_(x,n) { var i; var k=Math.floor(n/bpe); if (k) { for (i=x.length; i>=k; i--) //left shift x by k elements x[i]=x[i-k]; for (;i>=0;i--) x[i]=0; n%=bpe; } if (!n) return; for (i=x.length-1;i>0;i--) { x[i]=mask & ((x[i]<>(bpe-n))); } x[i]=mask & (x[i]<=0;i--) { s=r*radix+x[i]; x[i]=Math.floor(s/n); r=s%n; } return r; } //do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b. //x must be large enough to hold the answer. function linComb_(x,y,a,b) { var i,c,k,kk; k=x.length0 && !x[kx-1]; kx--); //ignore leading zeros in x k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n if (s0.length!=k) s0=new Array(k); copyInt_(s0,0); for (i=0;i0 && !x[i-1]; i--); y=new Array(i+k); copy_(y,x); return y; } //do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1. //this is faster when n is odd. x usually needs to have as many elements as n. function powMod_(x,y,n) { var k1,k2,kn,np; if(s7.length!=n.length) s7=dup(n); //for even modulus, use a simple square-and-multiply algorithm, //rather than using the more complex Montgomery algorithm. if ((n[0]&1)==0) { copy_(s7,x); copyInt_(x,1); while(!equalsInt(y,0)) { if (y[0]&1) multMod_(x,s7,n); divInt_(y,2); squareMod_(s7,n); } return; } //calculate np from n for the Montgomery multiplications copyInt_(s7,0); for (kn=n.length;kn>0 && !n[kn-1];kn--); np=radix-inverseModInt(modInt(n,radix),radix); s7[kn]=1; multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n if (s3.length!=x.length) s3=dup(x); else copy_(s3,x); for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y if (y[k1]==0) { //anything to the 0th power is 1 copyInt_(x,1); return; } for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1] for (;;) { if (!(k2>>=1)) { //look at next bit of y k1--; if (k1<0) { mont_(x,one,n,np); return; } k2=1<<(bpe-1); } mont_(x,x,n,np); if (k2 & y[k1]) //if next bit is a 1 mont_(x,s3,n,np); } } //do x=x*y*Ri mod n for bigInts x,y,n, // where Ri = 2**(-kn*bpe) mod n, and kn is the // number of elements in the n array, not // counting leading zeros. //x array must have at least as many elemnts as the n array //It's OK if x and y are the same variable. //must have: // x,y < n // n is odd // np = -(n^(-1)) mod radix function mont_(x,y,n,np) { var i,j,c,ui,t,t2,ks; var kn=n.length; var ky=y.length; if (sa.length!=kn) sa=new Array(kn); copyInt_(sa,0); for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y ks=sa.length-1; //sa will never have more than this many nonzero elements. //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large numbers for (i=0; i "\00" } return _num2bin }()) // serialize a bigInt to an ascii string // padded up to pad length function bigInt2bits(bi, pad) { pad || (pad = 0) bi = dup(bi) var ba = '' while (!isZero(bi)) { ba = _num2bin[bi[0] & 0xff] + ba rightShift_(bi, 8) } while (ba.length < pad) { ba = '\x00' + ba } return ba } // converts a byte array to a bigInt function ba2bigInt(data) { var mpi = str2bigInt('0', 10, data.length) data.forEach(function (d, i) { if (i) leftShift_(mpi, 8) mpi[0] |= d }) return mpi } // returns a function that returns an array of n bytes var randomBytes = (function () { // in node if ( typeof crypto !== 'undefined' && typeof crypto.randomBytes === 'function' ) { return function (n) { try { var buf = crypto.randomBytes(n) } catch (e) { throw e } return Array.prototype.slice.call(buf, 0) } } // in browser else if ( typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function' ) { return function (n) { var buf = new Uint8Array(n) crypto.getRandomValues(buf) return Array.prototype.slice.call(buf, 0) } } // err else { throw new Error('Keys should not be generated without CSPRNG.') } }()) // Salsa 20 in webworker needs a 40 byte seed function getSeed() { return randomBytes(40) } // returns a single random byte function randomByte() { return randomBytes(1)[0] } // returns a k-bit random integer function randomBitInt(k) { if (k > 31) throw new Error("Too many bits.") var i = 0, r = 0 var b = Math.floor(k / 8) var mask = (1 << (k % 8)) - 1 if (mask) r = randomByte() & mask for (; i < b; i++) r = (256 * r) + randomByte() return r } return { str2bigInt : str2bigInt , bigInt2str : bigInt2str , int2bigInt : int2bigInt , multMod : multMod , powMod : powMod , inverseMod : inverseMod , randBigInt : randBigInt , randBigInt_ : randBigInt_ , equals : equals , equalsInt : equalsInt , sub : sub , mod : mod , modInt : modInt , mult : mult , divInt_ : divInt_ , rightShift_ : rightShift_ , dup : dup , greater : greater , add : add , isZero : isZero , bitSize : bitSize , millerRabin : millerRabin , divide_ : divide_ , trim : trim , primes : primes , findPrimes : findPrimes , getSeed : getSeed , divMod : divMod , subMod : subMod , twoToThe : twoToThe , bigInt2bits : bigInt2bits , ba2bigInt : ba2bigInt } }))rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/lib/0000755000076400007640000000000012572247340030544 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/lib/const.js0000644000076400007640000000314412572247340032232 0ustar pravipravi;(function () { "use strict"; var root = this var CONST = { // diffie-heilman N : 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF' , G : '2' // otr message states , MSGSTATE_PLAINTEXT : 0 , MSGSTATE_ENCRYPTED : 1 , MSGSTATE_FINISHED : 2 // otr auth states , AUTHSTATE_NONE : 0 , AUTHSTATE_AWAITING_DHKEY : 1 , AUTHSTATE_AWAITING_REVEALSIG : 2 , AUTHSTATE_AWAITING_SIG : 3 // whitespace tags , WHITESPACE_TAG : '\x20\x09\x20\x20\x09\x09\x09\x09\x20\x09\x20\x09\x20\x09\x20\x20' , WHITESPACE_TAG_V2 : '\x20\x20\x09\x09\x20\x20\x09\x20' , WHITESPACE_TAG_V3 : '\x20\x20\x09\x09\x20\x20\x09\x09' // otr tags , OTR_TAG : '?OTR' , OTR_VERSION_1 : '\x00\x01' , OTR_VERSION_2 : '\x00\x02' , OTR_VERSION_3 : '\x00\x03' // smp machine states , SMPSTATE_EXPECT0 : 0 , SMPSTATE_EXPECT1 : 1 , SMPSTATE_EXPECT2 : 2 , SMPSTATE_EXPECT3 : 3 , SMPSTATE_EXPECT4 : 4 // unstandard status codes , STATUS_SEND_QUERY : 0 , STATUS_AKE_INIT : 1 , STATUS_AKE_SUCCESS : 2 , STATUS_END_OTR : 3 } if (typeof module !== 'undefined' && module.exports) { module.exports = CONST } else { root.OTR.CONST = CONST } }).call(this)././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/lib/sm-webworker.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/lib/sm-webwork0000644000076400007640000000245412572247340032571 0ustar pravipravi;(function (root) { "use strict"; root.OTR = {} root.crypto = { randomBytes: function () { throw new Error("Haven't seeded yet.") } } // default imports var imports = [ 'vendor/salsa20.js' , 'vendor/bigint.js' , 'vendor/crypto.js' , 'vendor/eventemitter.js' , 'lib/const.js' , 'lib/helpers.js' , 'lib/sm.js' ] function wrapPostMessage(method) { return function () { postMessage({ method: method , args: Array.prototype.slice.call(arguments, 0) }) } } var sm onmessage = function (e) { var data = e.data switch (data.type) { case 'seed': if (data.imports) imports = data.imports importScripts.apply(root, imports) // use salsa20 since there's no prng in webworkers var state = new root.Salsa20( data.seed.slice(0, 32), data.seed.slice(32) ) root.crypto.randomBytes = function (n) { return state.getBytes(n) } break case 'init': sm = new root.OTR.SM(data.reqs) ;['trust','question', 'send', 'abort'].forEach(function (m) { sm.on(m, wrapPostMessage(m)); }) break case 'method': sm[data.method].apply(sm, data.args) break } } }(this))rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/lib/helpers.js0000644000076400007640000002133312572247340032546 0ustar pravipravi;(function () { "use strict"; var root = this var HLP = {}, CryptoJS, BigInt if (typeof module !== 'undefined' && module.exports) { module.exports = HLP = {} CryptoJS = require('../vendor/crypto.js') BigInt = require('../vendor/bigint.js') } else { if (root.OTR) root.OTR.HLP = HLP if (root.DSA) root.DSA.HLP = HLP CryptoJS = root.CryptoJS BigInt = root.BigInt } // data types (byte lengths) var DTS = { BYTE : 1 , SHORT : 2 , INT : 4 , CTR : 8 , MAC : 20 , SIG : 40 } // otr message wrapper begin and end var WRAPPER_BEGIN = "?OTR" , WRAPPER_END = "." var TWO = BigInt.str2bigInt('2', 10) HLP.debug = function (msg) { // used as HLP.debug.call(ctx, msg) if ( this.debug && typeof this.debug !== 'function' && typeof console !== 'undefined' ) console.log(msg) } HLP.extend = function (child, parent) { for (var key in parent) { if (Object.hasOwnProperty.call(parent, key)) child[key] = parent[key] } function Ctor() { this.constructor = child } Ctor.prototype = parent.prototype child.prototype = new Ctor() child.__super__ = parent.prototype } // assumes 32-bit function intCompare(x, y) { var z = ~(x ^ y) z &= z >> 16 z &= z >> 8 z &= z >> 4 z &= z >> 2 z &= z >> 1 return z & 1 } // constant-time string comparison HLP.compare = function (str1, str2) { if (str1.length !== str2.length) return false var i = 0, result = 0 for (; i < str1.length; i++) result |= str1[i].charCodeAt(0) ^ str2[i].charCodeAt(0) return intCompare(result, 0) } HLP.randomExponent = function () { return BigInt.randBigInt(1536) } HLP.smpHash = function (version, fmpi, smpi) { var sha256 = CryptoJS.algo.SHA256.create() sha256.update(CryptoJS.enc.Latin1.parse(HLP.packBytes(version, DTS.BYTE))) sha256.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(fmpi))) if (smpi) sha256.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(smpi))) var hash = sha256.finalize() return HLP.bits2bigInt(hash.toString(CryptoJS.enc.Latin1)) } HLP.makeMac = function (aesctr, m) { var pass = CryptoJS.enc.Latin1.parse(m) var mac = CryptoJS.HmacSHA256(CryptoJS.enc.Latin1.parse(aesctr), pass) return HLP.mask(mac.toString(CryptoJS.enc.Latin1), 0, 160) } HLP.make1Mac = function (aesctr, m) { var pass = CryptoJS.enc.Latin1.parse(m) var mac = CryptoJS.HmacSHA1(CryptoJS.enc.Latin1.parse(aesctr), pass) return mac.toString(CryptoJS.enc.Latin1) } HLP.encryptAes = function (msg, c, iv) { var opts = { mode: CryptoJS.mode.CTR , iv: CryptoJS.enc.Latin1.parse(iv) , padding: CryptoJS.pad.NoPadding } var aesctr = CryptoJS.AES.encrypt( msg , CryptoJS.enc.Latin1.parse(c) , opts ) var aesctr_decoded = CryptoJS.enc.Base64.parse(aesctr.toString()) return CryptoJS.enc.Latin1.stringify(aesctr_decoded) } HLP.decryptAes = function (msg, c, iv) { msg = CryptoJS.enc.Latin1.parse(msg) var opts = { mode: CryptoJS.mode.CTR , iv: CryptoJS.enc.Latin1.parse(iv) , padding: CryptoJS.pad.NoPadding } return CryptoJS.AES.decrypt( CryptoJS.enc.Base64.stringify(msg) , CryptoJS.enc.Latin1.parse(c) , opts ) } HLP.multPowMod = function (a, b, c, d, e) { return BigInt.multMod(BigInt.powMod(a, b, e), BigInt.powMod(c, d, e), e) } HLP.ZKP = function (v, c, d, e) { return BigInt.equals(c, HLP.smpHash(v, d, e)) } // greater than, or equal HLP.GTOE = function (a, b) { return (BigInt.equals(a, b) || BigInt.greater(a, b)) } HLP.between = function (x, a, b) { return (BigInt.greater(x, a) && BigInt.greater(b, x)) } HLP.checkGroup = function (g, N_MINUS_2) { return HLP.GTOE(g, TWO) && HLP.GTOE(N_MINUS_2, g) } HLP.h1 = function (b, secbytes) { var sha1 = CryptoJS.algo.SHA1.create() sha1.update(CryptoJS.enc.Latin1.parse(b)) sha1.update(CryptoJS.enc.Latin1.parse(secbytes)) return (sha1.finalize()).toString(CryptoJS.enc.Latin1) } HLP.h2 = function (b, secbytes) { var sha256 = CryptoJS.algo.SHA256.create() sha256.update(CryptoJS.enc.Latin1.parse(b)) sha256.update(CryptoJS.enc.Latin1.parse(secbytes)) return (sha256.finalize()).toString(CryptoJS.enc.Latin1) } HLP.mask = function (bytes, start, n) { return bytes.substr(start / 8, n / 8) } var _toString = String.fromCharCode; HLP.packBytes = function (val, bytes) { val = val.toString(16) var nex, res = '' // big-endian, unsigned long for (; bytes > 0; bytes--) { nex = val.length ? val.substr(-2, 2) : '0' val = val.substr(0, val.length - 2) res = _toString(parseInt(nex, 16)) + res } return res } HLP.packINT = function (d) { return HLP.packBytes(d, DTS.INT) } HLP.packCtr = function (d) { return HLP.padCtr(HLP.packBytes(d, DTS.CTR)) } HLP.padCtr = function (ctr) { return ctr + '\x00\x00\x00\x00\x00\x00\x00\x00' } HLP.unpackCtr = function (d) { d = HLP.toByteArray(d.substring(0, 8)) return HLP.unpack(d) } HLP.unpack = function (arr) { var val = 0, i = 0, len = arr.length for (; i < len; i++) { val = (val * 256) + arr[i] } return val } HLP.packData = function (d) { return HLP.packINT(d.length) + d } HLP.bits2bigInt = function (bits) { bits = HLP.toByteArray(bits) return BigInt.ba2bigInt(bits) } HLP.packMPI = function (mpi) { return HLP.packData(BigInt.bigInt2bits(BigInt.trim(mpi, 0))) } HLP.packSHORT = function (short) { return HLP.packBytes(short, DTS.SHORT) } HLP.unpackSHORT = function (short) { short = HLP.toByteArray(short) return HLP.unpack(short) } HLP.packTLV = function (type, value) { return HLP.packSHORT(type) + HLP.packSHORT(value.length) + value } HLP.readLen = function (msg) { msg = HLP.toByteArray(msg.substring(0, 4)) return HLP.unpack(msg) } HLP.readData = function (data) { var n = HLP.unpack(data.splice(0, 4)) return [n, data] } HLP.readMPI = function (data) { data = HLP.toByteArray(data) data = HLP.readData(data) return BigInt.ba2bigInt(data[1]) } HLP.packMPIs = function (arr) { return arr.reduce(function (prv, cur) { return prv + HLP.packMPI(cur) }, '') } HLP.unpackMPIs = function (num, mpis) { var i = 0, arr = [] for (; i < num; i++) arr.push('MPI') return (HLP.splitype(arr, mpis)).map(function (m) { return HLP.readMPI(m) }) } HLP.wrapMsg = function (msg, fs, v3, our_it, their_it) { msg = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Latin1.parse(msg)) msg = WRAPPER_BEGIN + ":" + msg + WRAPPER_END var its if (v3) { its = '|' its += (HLP.readLen(our_it)).toString(16) its += '|' its += (HLP.readLen(their_it)).toString(16) } if (!fs) return [null, msg] var n = Math.ceil(msg.length / fs) if (n > 65535) return ['Too many fragments'] if (n == 1) return [null, msg] var k, bi, ei, frag, mf, mfs = [] for (k = 1; k <= n; k++) { bi = (k - 1) * fs ei = k * fs frag = msg.slice(bi, ei) mf = WRAPPER_BEGIN if (v3) mf += its mf += ',' + k + ',' mf += n + ',' mf += frag + ',' mfs.push(mf) } return [null, mfs] } HLP.splitype = function splitype(arr, msg) { var data = [] arr.forEach(function (a) { var str switch (a) { case 'PUBKEY': str = splitype(['SHORT', 'MPI', 'MPI', 'MPI', 'MPI'], msg).join('') break case 'DATA': // falls through case 'MPI': str = msg.substring(0, HLP.readLen(msg) + 4) break default: str = msg.substring(0, DTS[a]) } data.push(str) msg = msg.substring(str.length) }) return data } // https://github.com/msgpack/msgpack-javascript/blob/master/msgpack.js var _bin2num = (function () { var i = 0, _bin2num = {} for (; i < 0x100; ++i) { _bin2num[String.fromCharCode(i)] = i // "\00" -> 0x00 } for (i = 0x80; i < 0x100; ++i) { // [Webkit][Gecko] _bin2num[String.fromCharCode(0xf700 + i)] = i // "\f780" -> 0x80 } return _bin2num }()) HLP.toByteArray = function (data) { var rv = [] , ary = data.split("") , i = -1 , iz = ary.length , remain = iz % 8 while (remain--) { ++i rv[i] = _bin2num[ary[i]] } remain = iz >> 3 while (remain--) { rv.push(_bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]]) } return rv } }).call(this)././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/lib/dsa-webworker.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/lib/dsa-webwor0000644000076400007640000000217112572247340032542 0ustar pravipravi;(function (root) { "use strict"; root.OTR = {} root.DSA = {} root.crypto = { randomBytes: function () { throw new Error("Haven't seeded yet.") } } // default imports var imports = [ 'vendor/salsa20.js' , 'vendor/bigint.js' , 'vendor/crypto.js' , 'vendor/eventemitter.js' , 'lib/const.js' , 'lib/helpers.js' , 'lib/dsa.js' ] function sendMsg(type, val) { postMessage({ type: type, val: val }) } onmessage = function (e) { var data = e.data; if (data.imports) imports = data.imports importScripts.apply(root, imports); // use salsa20 since there's no prng in webworkers var state = new root.Salsa20(data.seed.slice(0, 32), data.seed.slice(32)) root.crypto.randomBytes = function (n) { return state.getBytes(n) } if (data.debug) sendMsg('debug', 'DSA key creation started') var dsa try { dsa = new root.DSA() } catch (e) { if (data.debug) sendMsg('debug', e.toString()) return } if (data.debug) sendMsg('debug', 'DSA key creation finished') sendMsg('data', dsa.packPrivate()) } }(this))rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/lib/dsa.js0000644000076400007640000002372512572247340031662 0ustar pravipravi;(function () { "use strict"; var root = this var CryptoJS, BigInt, Worker, WWPath, HLP if (typeof module !== 'undefined' && module.exports) { module.exports = DSA CryptoJS = require('../vendor/crypto.js') BigInt = require('../vendor/bigint.js') WWPath = require('path').join(__dirname, '/dsa-webworker.js') HLP = require('./helpers.js') } else { // copy over and expose internals Object.keys(root.DSA).forEach(function (k) { DSA[k] = root.DSA[k] }) root.DSA = DSA CryptoJS = root.CryptoJS BigInt = root.BigInt Worker = root.Worker WWPath = 'dsa-webworker.js' HLP = DSA.HLP } var ZERO = BigInt.str2bigInt('0', 10) , ONE = BigInt.str2bigInt('1', 10) , TWO = BigInt.str2bigInt('2', 10) , KEY_TYPE = '\x00\x00' var DEBUG = false function timer() { var start = (new Date()).getTime() return function (s) { if (!DEBUG || typeof console === 'undefined') return var t = (new Date()).getTime() console.log(s + ': ' + (t - start)) start = t } } function makeRandom(min, max) { var c = BigInt.randBigInt(BigInt.bitSize(max)) if (!HLP.between(c, min, max)) return makeRandom(min, max) return c } // altered BigInt.randProbPrime() // n rounds of Miller Rabin (after trial division with small primes) var rpprb = [] function isProbPrime(k, n) { var i, B = 30000, l = BigInt.bitSize(k) var primes = BigInt.primes if (primes.length === 0) primes = BigInt.findPrimes(B) if (rpprb.length != k.length) rpprb = BigInt.dup(k) // check ans for divisibility by small primes up to B for (i = 0; (i < primes.length) && (primes[i] <= B); i++) if (BigInt.modInt(k, primes[i]) === 0 && !BigInt.equalsInt(k, primes[i])) return 0 // do n rounds of Miller Rabin, with random bases less than k for (i = 0; i < n; i++) { BigInt.randBigInt_(rpprb, l, 0) while(!BigInt.greater(k, rpprb)) // pick a random rpprb that's < k BigInt.randBigInt_(rpprb, l, 0) if (!BigInt.millerRabin(k, rpprb)) return 0 } return 1 } var bit_lengths = { '1024': { N: 160, repeat: 40 } // 40x should give 2^-80 confidence , '2048': { N: 224, repeat: 56 } } var primes = {} // follows go lang http://golang.org/src/pkg/crypto/dsa/dsa.go // fips version was removed in 0c99af0df3e7 function generatePrimes(bit_length) { var t = timer() // for debugging // number of MR tests to perform var repeat = bit_lengths[bit_length].repeat var N = bit_lengths[bit_length].N var LM1 = BigInt.twoToThe(bit_length - 1) var bl4 = 4 * bit_length var brk = false var q, p, rem, counter for (;;) { q = BigInt.randBigInt(N, 1) q[0] |= 1 if (!isProbPrime(q, repeat)) continue t('q') for (counter = 0; counter < bl4; counter++) { p = BigInt.randBigInt(bit_length, 1) p[0] |= 1 rem = BigInt.mod(p, q) rem = BigInt.sub(rem, ONE) p = BigInt.sub(p, rem) if (BigInt.greater(LM1, p)) continue if (!isProbPrime(p, repeat)) continue t('p') primes[bit_length] = { p: p, q: q } brk = true break } if (brk) break } var h = BigInt.dup(TWO) var pm1 = BigInt.sub(p, ONE) var e = BigInt.multMod(pm1, BigInt.inverseMod(q, p), p) var g for (;;) { g = BigInt.powMod(h, e, p) if (BigInt.equals(g, ONE)) { h = BigInt.add(h, ONE) continue } primes[bit_length].g = g t('g') return } throw new Error('Unreachable!') } function DSA(obj, opts) { if (!(this instanceof DSA)) return new DSA(obj, opts) // options opts = opts || {} // inherit if (obj) { var self = this ;['p', 'q', 'g', 'y', 'x'].forEach(function (prop) { self[prop] = obj[prop] }) this.type = obj.type || KEY_TYPE return } // default to 1024 var bit_length = parseInt(opts.bit_length ? opts.bit_length : 1024, 10) if (!bit_lengths[bit_length]) throw new Error('Unsupported bit length.') // set primes if (!primes[bit_length]) generatePrimes(bit_length) this.p = primes[bit_length].p this.q = primes[bit_length].q this.g = primes[bit_length].g // key type this.type = KEY_TYPE // private key this.x = makeRandom(ZERO, this.q) // public keys (p, q, g, y) this.y = BigInt.powMod(this.g, this.x, this.p) // nocache? if (opts.nocache) primes[bit_length] = null } DSA.prototype = { constructor: DSA, packPublic: function () { var str = this.type str += HLP.packMPI(this.p) str += HLP.packMPI(this.q) str += HLP.packMPI(this.g) str += HLP.packMPI(this.y) return str }, packPrivate: function () { var str = this.packPublic() + HLP.packMPI(this.x) str = CryptoJS.enc.Latin1.parse(str) return str.toString(CryptoJS.enc.Base64) }, // http://www.imperialviolet.org/2013/06/15/suddendeathentropy.html generateNonce: function (m) { var priv = BigInt.bigInt2bits(BigInt.trim(this.x, 0)) var rand = BigInt.bigInt2bits(BigInt.randBigInt(256)) var sha256 = CryptoJS.algo.SHA256.create() sha256.update(CryptoJS.enc.Latin1.parse(priv)) sha256.update(m) sha256.update(CryptoJS.enc.Latin1.parse(rand)) var hash = sha256.finalize() hash = HLP.bits2bigInt(hash.toString(CryptoJS.enc.Latin1)) BigInt.rightShift_(hash, 256 - BigInt.bitSize(this.q)) return HLP.between(hash, ZERO, this.q) ? hash : this.generateNonce(m) }, sign: function (m) { m = CryptoJS.enc.Latin1.parse(m) var b = BigInt.str2bigInt(m.toString(CryptoJS.enc.Hex), 16) var k, r = ZERO, s = ZERO while (BigInt.isZero(s) || BigInt.isZero(r)) { k = this.generateNonce(m) r = BigInt.mod(BigInt.powMod(this.g, k, this.p), this.q) if (BigInt.isZero(r)) continue s = BigInt.inverseMod(k, this.q) s = BigInt.mult(s, BigInt.add(b, BigInt.mult(this.x, r))) s = BigInt.mod(s, this.q) } return [r, s] }, fingerprint: function () { var pk = this.packPublic() if (this.type === KEY_TYPE) pk = pk.substring(2) pk = CryptoJS.enc.Latin1.parse(pk) return CryptoJS.SHA1(pk).toString(CryptoJS.enc.Hex) } } DSA.parsePublic = function (str, priv) { var fields = ['SHORT', 'MPI', 'MPI', 'MPI', 'MPI'] if (priv) fields.push('MPI') str = HLP.splitype(fields, str) var obj = { type: str[0] , p: HLP.readMPI(str[1]) , q: HLP.readMPI(str[2]) , g: HLP.readMPI(str[3]) , y: HLP.readMPI(str[4]) } if (priv) obj.x = HLP.readMPI(str[5]) return new DSA(obj) } function tokenizeStr(str) { var start, end start = str.indexOf("(") end = str.lastIndexOf(")") if (start < 0 || end < 0) throw new Error("Malformed S-Expression") str = str.substring(start + 1, end) var splt = str.search(/\s/) var obj = { type: str.substring(0, splt) , val: [] } str = str.substring(splt + 1, end) start = str.indexOf("(") if (start < 0) obj.val.push(str) else { var i, len, ss, es while (start > -1) { i = start + 1 len = str.length for (ss = 1, es = 0; i < len && es < ss; i++) { if (str[i] === "(") ss++ if (str[i] === ")") es++ } obj.val.push(tokenizeStr(str.substring(start, ++i))) str = str.substring(++i) start = str.indexOf("(") } } return obj } function parseLibotr(obj) { if (!obj.type) throw new Error("Parse error.") var o, val if (obj.type === "privkeys") { o = [] obj.val.forEach(function (i) { o.push(parseLibotr(i)) }) return o } o = {} obj.val.forEach(function (i) { val = i.val[0] if (typeof val === "string") { if (val.indexOf("#") === 0) { val = val.substring(1, val.lastIndexOf("#")) val = BigInt.str2bigInt(val, 16) } } else { val = parseLibotr(i) } o[i.type] = val }) return o } DSA.parsePrivate = function (str, libotr) { if (!libotr) { str = CryptoJS.enc.Base64.parse(str) str = str.toString(CryptoJS.enc.Latin1) return DSA.parsePublic(str, true) } // only returning the first key found return parseLibotr(tokenizeStr(str))[0]["private-key"].dsa } DSA.verify = function (key, m, r, s) { if (!HLP.between(r, ZERO, key.q) || !HLP.between(s, ZERO, key.q)) return false var hm = CryptoJS.enc.Latin1.parse(m) // CryptoJS.SHA1(m) hm = BigInt.str2bigInt(hm.toString(CryptoJS.enc.Hex), 16) var w = BigInt.inverseMod(s, key.q) var u1 = BigInt.multMod(hm, w, key.q) var u2 = BigInt.multMod(r, w, key.q) u1 = BigInt.powMod(key.g, u1, key.p) u2 = BigInt.powMod(key.y, u2, key.p) var v = BigInt.mod(BigInt.multMod(u1, u2, key.p), key.q) return BigInt.equals(v, r) } DSA.createInWebWorker = function (options, cb) { var opts = { path: WWPath , seed: BigInt.getSeed } if (options && typeof options === 'object') Object.keys(options).forEach(function (k) { opts[k] = options[k] }) // load optional dep. in node if (typeof module !== 'undefined' && module.exports) Worker = require('webworker-threads').Worker var worker = new Worker(opts.path) worker.onmessage = function (e) { var data = e.data switch (data.type) { case "debug": if (!DEBUG || typeof console === 'undefined') return console.log(data.val) break; case "data": worker.terminate() cb(DSA.parsePrivate(data.val)) break; default: throw new Error("Unrecognized type.") } } worker.postMessage({ seed: opts.seed() , imports: opts.imports , debug: DEBUG }) } }).call(this)rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/0000755000076400007640000000000012572247340031075 5ustar pravipravirails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dep/0000755000076400007640000000000012572247340031645 5ustar pravipravi././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dep/crypto.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dep/cryp0000644000076400007640000022607412572247340032560 0ustar pravipravi;(function (root, factory) { if (typeof define === "function" && define.amd) { define(factory) } else if (typeof module !== 'undefined' && module.exports) { module.exports = factory() } else { root.CryptoJS = factory() } }(this, function () { /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** * CryptoJS core components. */ var CryptoJS = CryptoJS || (function (Math, undefined) { /** * CryptoJS namespace. */ var C = {}; /** * Library namespace. */ var C_lib = C.lib = {}; /** * Base object for prototypal inheritance. */ var Base = C_lib.Base = (function () { function F() {} return { /** * Creates a new object that inherits from this object. * * @param {Object} overrides Properties to copy into the new object. * * @return {Object} The new object. * * @static * * @example * * var MyType = CryptoJS.lib.Base.extend({ * field: 'value', * * method: function () { * } * }); */ extend: function (overrides) { // Spawn F.prototype = this; var subtype = new F(); // Augment if (overrides) { subtype.mixIn(overrides); } // Create default initializer if (!subtype.hasOwnProperty('init')) { subtype.init = function () { subtype.$super.init.apply(this, arguments); }; } // Initializer's prototype is the subtype object subtype.init.prototype = subtype; // Reference supertype subtype.$super = this; return subtype; }, /** * Extends this object and runs the init method. * Arguments to create() will be passed to init(). * * @return {Object} The new object. * * @static * * @example * * var instance = MyType.create(); */ create: function () { var instance = this.extend(); instance.init.apply(instance, arguments); return instance; }, /** * Initializes a newly created object. * Override this method to add some logic when your objects are created. * * @example * * var MyType = CryptoJS.lib.Base.extend({ * init: function () { * // ... * } * }); */ init: function () { }, /** * Copies properties into this object. * * @param {Object} properties The properties to mix in. * * @example * * MyType.mixIn({ * field: 'value' * }); */ mixIn: function (properties) { for (var propertyName in properties) { if (properties.hasOwnProperty(propertyName)) { this[propertyName] = properties[propertyName]; } } // IE won't copy toString using the loop above if (properties.hasOwnProperty('toString')) { this.toString = properties.toString; } }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = instance.clone(); */ clone: function () { return this.init.prototype.extend(this); } }; }()); /** * An array of 32-bit words. * * @property {Array} words The array of 32-bit words. * @property {number} sigBytes The number of significant bytes in this word array. */ var WordArray = C_lib.WordArray = Base.extend({ /** * Initializes a newly created word array. * * @param {Array} words (Optional) An array of 32-bit words. * @param {number} sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.lib.WordArray.create(); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); */ init: function (words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 4; } }, /** * Converts this word array to a string. * * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex * * @return {string} The stringified word array. * * @example * * var string = wordArray + ''; * var string = wordArray.toString(); * var string = wordArray.toString(CryptoJS.enc.Utf8); */ toString: function (encoder) { return (encoder || Hex).stringify(this); }, /** * Concatenates a word array to this word array. * * @param {WordArray} wordArray The word array to append. * * @return {WordArray} This word array. * * @example * * wordArray1.concat(wordArray2); */ concat: function (wordArray) { // Shortcuts var thisWords = this.words; var thatWords = wordArray.words; var thisSigBytes = this.sigBytes; var thatSigBytes = wordArray.sigBytes; // Clamp excess bits this.clamp(); // Concat if (thisSigBytes % 4) { // Copy one byte at a time for (var i = 0; i < thatSigBytes; i++) { var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); } } else if (thatWords.length > 0xffff) { // Copy one word at a time for (var i = 0; i < thatSigBytes; i += 4) { thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; } } else { // Copy all words at once thisWords.push.apply(thisWords, thatWords); } this.sigBytes += thatSigBytes; // Chainable return this; }, /** * Removes insignificant bits. * * @example * * wordArray.clamp(); */ clamp: function () { // Shortcuts var words = this.words; var sigBytes = this.sigBytes; // Clamp words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); words.length = Math.ceil(sigBytes / 4); }, /** * Creates a copy of this word array. * * @return {WordArray} The clone. * * @example * * var clone = wordArray.clone(); */ clone: function () { var clone = Base.clone.call(this); clone.words = this.words.slice(0); return clone; }, /** * Creates a word array filled with random bytes. * * @param {number} nBytes The number of random bytes to generate. * * @return {WordArray} The random word array. * * @static * * @example * * var wordArray = CryptoJS.lib.WordArray.random(16); */ random: function (nBytes) { var words = []; for (var i = 0; i < nBytes; i += 4) { words.push((Math.random() * 0x100000000) | 0); } return new WordArray.init(words, nBytes); } }); /** * Encoder namespace. */ var C_enc = C.enc = {}; /** * Hex encoding strategy. */ var Hex = C_enc.Hex = { /** * Converts a word array to a hex string. * * @param {WordArray} wordArray The word array. * * @return {string} The hex string. * * @static * * @example * * var hexString = CryptoJS.enc.Hex.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var hexChars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; hexChars.push((bite >>> 4).toString(16)); hexChars.push((bite & 0x0f).toString(16)); } return hexChars.join(''); }, /** * Converts a hex string to a word array. * * @param {string} hexStr The hex string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Hex.parse(hexString); */ parse: function (hexStr) { // Shortcut var hexStrLength = hexStr.length; // Convert var words = []; for (var i = 0; i < hexStrLength; i += 2) { words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); } return new WordArray.init(words, hexStrLength / 2); } }; /** * Latin1 encoding strategy. */ var Latin1 = C_enc.Latin1 = { /** * Converts a word array to a Latin1 string. * * @param {WordArray} wordArray The word array. * * @return {string} The Latin1 string. * * @static * * @example * * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var latin1Chars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; latin1Chars.push(String.fromCharCode(bite)); } return latin1Chars.join(''); }, /** * Converts a Latin1 string to a word array. * * @param {string} latin1Str The Latin1 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); */ parse: function (latin1Str) { // Shortcut var latin1StrLength = latin1Str.length; // Convert var words = []; for (var i = 0; i < latin1StrLength; i++) { words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); } return new WordArray.init(words, latin1StrLength); } }; /** * UTF-8 encoding strategy. */ var Utf8 = C_enc.Utf8 = { /** * Converts a word array to a UTF-8 string. * * @param {WordArray} wordArray The word array. * * @return {string} The UTF-8 string. * * @static * * @example * * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); */ stringify: function (wordArray) { try { return decodeURIComponent(escape(Latin1.stringify(wordArray))); } catch (e) { throw new Error('Malformed UTF-8 data'); } }, /** * Converts a UTF-8 string to a word array. * * @param {string} utf8Str The UTF-8 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); */ parse: function (utf8Str) { return Latin1.parse(unescape(encodeURIComponent(utf8Str))); } }; /** * Abstract buffered block algorithm template. * * The property blockSize must be implemented in a concrete subtype. * * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 */ var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ /** * Resets this block algorithm's data buffer to its initial state. * * @example * * bufferedBlockAlgorithm.reset(); */ reset: function () { // Initial values this._data = new WordArray.init(); this._nDataBytes = 0; }, /** * Adds new data to this block algorithm's buffer. * * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. * * @example * * bufferedBlockAlgorithm._append('data'); * bufferedBlockAlgorithm._append(wordArray); */ _append: function (data) { // Convert string to WordArray, else assume WordArray already if (typeof data == 'string') { data = Utf8.parse(data); } // Append this._data.concat(data); this._nDataBytes += data.sigBytes; }, /** * Processes available data blocks. * * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. * * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. * * @return {WordArray} The processed data. * * @example * * var processedData = bufferedBlockAlgorithm._process(); * var processedData = bufferedBlockAlgorithm._process(!!'flush'); */ _process: function (doFlush) { // Shortcuts var data = this._data; var dataWords = data.words; var dataSigBytes = data.sigBytes; var blockSize = this.blockSize; var blockSizeBytes = blockSize * 4; // Count blocks ready var nBlocksReady = dataSigBytes / blockSizeBytes; if (doFlush) { // Round up to include partial blocks nBlocksReady = Math.ceil(nBlocksReady); } else { // Round down to include only full blocks, // less the number of blocks that must remain in the buffer nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); } // Count words ready var nWordsReady = nBlocksReady * blockSize; // Count bytes ready var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); // Process blocks if (nWordsReady) { for (var offset = 0; offset < nWordsReady; offset += blockSize) { // Perform concrete-algorithm logic this._doProcessBlock(dataWords, offset); } // Remove processed words var processedWords = dataWords.splice(0, nWordsReady); data.sigBytes -= nBytesReady; } // Return processed words return new WordArray.init(processedWords, nBytesReady); }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = bufferedBlockAlgorithm.clone(); */ clone: function () { var clone = Base.clone.call(this); clone._data = this._data.clone(); return clone; }, _minBufferSize: 0 }); /** * Abstract hasher template. * * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) */ var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ /** * Configuration options. */ cfg: Base.extend(), /** * Initializes a newly created hasher. * * @param {Object} cfg (Optional) The configuration options to use for this hash computation. * * @example * * var hasher = CryptoJS.algo.SHA256.create(); */ init: function (cfg) { // Apply config defaults this.cfg = this.cfg.extend(cfg); // Set initial values this.reset(); }, /** * Resets this hasher to its initial state. * * @example * * hasher.reset(); */ reset: function () { // Reset data buffer BufferedBlockAlgorithm.reset.call(this); // Perform concrete-hasher logic this._doReset(); }, /** * Updates this hasher with a message. * * @param {WordArray|string} messageUpdate The message to append. * * @return {Hasher} This hasher. * * @example * * hasher.update('message'); * hasher.update(wordArray); */ update: function (messageUpdate) { // Append this._append(messageUpdate); // Update the hash this._process(); // Chainable return this; }, /** * Finalizes the hash computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} messageUpdate (Optional) A final message update. * * @return {WordArray} The hash. * * @example * * var hash = hasher.finalize(); * var hash = hasher.finalize('message'); * var hash = hasher.finalize(wordArray); */ finalize: function (messageUpdate) { // Final message update if (messageUpdate) { this._append(messageUpdate); } // Perform concrete-hasher logic var hash = this._doFinalize(); return hash; }, blockSize: 512/32, /** * Creates a shortcut function to a hasher's object interface. * * @param {Hasher} hasher The hasher to create a helper for. * * @return {Function} The shortcut function. * * @static * * @example * * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); */ _createHelper: function (hasher) { return function (message, cfg) { return new hasher.init(cfg).finalize(message); }; }, /** * Creates a shortcut function to the HMAC's object interface. * * @param {Hasher} hasher The hasher to use in this HMAC helper. * * @return {Function} The shortcut function. * * @static * * @example * * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); */ _createHmacHelper: function (hasher) { return function (message, key) { return new C_algo.HMAC.init(hasher, key).finalize(message); }; } }); /** * Algorithm namespace. */ var C_algo = C.algo = {}; return C; }(Math)); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_enc = C.enc; /** * Base64 encoding strategy. */ var Base64 = C_enc.Base64 = { /** * Converts a word array to a Base64 string. * * @param {WordArray} wordArray The word array. * * @return {string} The Base64 string. * * @static * * @example * * var base64String = CryptoJS.enc.Base64.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; var map = this._map; // Clamp excess bits wordArray.clamp(); // Convert var base64Chars = []; for (var i = 0; i < sigBytes; i += 3) { var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; var triplet = (byte1 << 16) | (byte2 << 8) | byte3; for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); } } // Add padding var paddingChar = map.charAt(64); if (paddingChar) { while (base64Chars.length % 4) { base64Chars.push(paddingChar); } } return base64Chars.join(''); }, /** * Converts a Base64 string to a word array. * * @param {string} base64Str The Base64 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Base64.parse(base64String); */ parse: function (base64Str) { // Shortcuts var base64StrLength = base64Str.length; var map = this._map; // Ignore padding var paddingChar = map.charAt(64); if (paddingChar) { var paddingIndex = base64Str.indexOf(paddingChar); if (paddingIndex != -1) { base64StrLength = paddingIndex; } } // Convert var words = []; var nBytes = 0; for (var i = 0; i < base64StrLength; i++) { if (i % 4) { var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2); var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2); words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); nBytes++; } } return WordArray.create(words, nBytes); }, _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' }; }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** * Cipher core components. */ CryptoJS.lib.Cipher || (function (undefined) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var WordArray = C_lib.WordArray; var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; var C_enc = C.enc; var Utf8 = C_enc.Utf8; var Base64 = C_enc.Base64; var C_algo = C.algo; var EvpKDF = C_algo.EvpKDF; /** * Abstract base cipher template. * * @property {number} keySize This cipher's key size. Default: 4 (128 bits) * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. */ var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ /** * Configuration options. * * @property {WordArray} iv The IV to use for this operation. */ cfg: Base.extend(), /** * Creates this cipher in encryption mode. * * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {Cipher} A cipher instance. * * @static * * @example * * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); */ createEncryptor: function (key, cfg) { return this.create(this._ENC_XFORM_MODE, key, cfg); }, /** * Creates this cipher in decryption mode. * * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {Cipher} A cipher instance. * * @static * * @example * * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); */ createDecryptor: function (key, cfg) { return this.create(this._DEC_XFORM_MODE, key, cfg); }, /** * Initializes a newly created cipher. * * @param {number} xformMode Either the encryption or decryption transormation mode constant. * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @example * * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); */ init: function (xformMode, key, cfg) { // Apply config defaults this.cfg = this.cfg.extend(cfg); // Store transform mode and key this._xformMode = xformMode; this._key = key; // Set initial values this.reset(); }, /** * Resets this cipher to its initial state. * * @example * * cipher.reset(); */ reset: function () { // Reset data buffer BufferedBlockAlgorithm.reset.call(this); // Perform concrete-cipher logic this._doReset(); }, /** * Adds data to be encrypted or decrypted. * * @param {WordArray|string} dataUpdate The data to encrypt or decrypt. * * @return {WordArray} The data after processing. * * @example * * var encrypted = cipher.process('data'); * var encrypted = cipher.process(wordArray); */ process: function (dataUpdate) { // Append this._append(dataUpdate); // Process available blocks return this._process(); }, /** * Finalizes the encryption or decryption process. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt. * * @return {WordArray} The data after final processing. * * @example * * var encrypted = cipher.finalize(); * var encrypted = cipher.finalize('data'); * var encrypted = cipher.finalize(wordArray); */ finalize: function (dataUpdate) { // Final data update if (dataUpdate) { this._append(dataUpdate); } // Perform concrete-cipher logic var finalProcessedData = this._doFinalize(); return finalProcessedData; }, keySize: 128/32, ivSize: 128/32, _ENC_XFORM_MODE: 1, _DEC_XFORM_MODE: 2, /** * Creates shortcut functions to a cipher's object interface. * * @param {Cipher} cipher The cipher to create a helper for. * * @return {Object} An object with encrypt and decrypt shortcut functions. * * @static * * @example * * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); */ _createHelper: (function () { function selectCipherStrategy(key) { if (typeof key == 'string') { return PasswordBasedCipher; } else { return SerializableCipher; } } return function (cipher) { return { encrypt: function (message, key, cfg) { return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); }, decrypt: function (ciphertext, key, cfg) { return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); } }; }; }()) }); /** * Abstract base stream cipher template. * * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) */ var StreamCipher = C_lib.StreamCipher = Cipher.extend({ _doFinalize: function () { // Process partial blocks var finalProcessedBlocks = this._process(!!'flush'); return finalProcessedBlocks; }, blockSize: 1 }); /** * Mode namespace. */ var C_mode = C.mode = {}; /** * Abstract base block cipher mode template. */ var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ /** * Creates this mode for encryption. * * @param {Cipher} cipher A block cipher instance. * @param {Array} iv The IV words. * * @static * * @example * * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); */ createEncryptor: function (cipher, iv) { return this.Encryptor.create(cipher, iv); }, /** * Creates this mode for decryption. * * @param {Cipher} cipher A block cipher instance. * @param {Array} iv The IV words. * * @static * * @example * * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); */ createDecryptor: function (cipher, iv) { return this.Decryptor.create(cipher, iv); }, /** * Initializes a newly created mode. * * @param {Cipher} cipher A block cipher instance. * @param {Array} iv The IV words. * * @example * * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); */ init: function (cipher, iv) { this._cipher = cipher; this._iv = iv; } }); /** * Cipher Block Chaining mode. */ var CBC = C_mode.CBC = (function () { /** * Abstract base CBC mode. */ var CBC = BlockCipherMode.extend(); /** * CBC encryptor. */ CBC.Encryptor = CBC.extend({ /** * Processes the data block at offset. * * @param {Array} words The data words to operate on. * @param {number} offset The offset where the block starts. * * @example * * mode.processBlock(data.words, offset); */ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher; var blockSize = cipher.blockSize; // XOR and encrypt xorBlock.call(this, words, offset, blockSize); cipher.encryptBlock(words, offset); // Remember this block to use with next block this._prevBlock = words.slice(offset, offset + blockSize); } }); /** * CBC decryptor. */ CBC.Decryptor = CBC.extend({ /** * Processes the data block at offset. * * @param {Array} words The data words to operate on. * @param {number} offset The offset where the block starts. * * @example * * mode.processBlock(data.words, offset); */ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher; var blockSize = cipher.blockSize; // Remember this block to use with next block var thisBlock = words.slice(offset, offset + blockSize); // Decrypt and XOR cipher.decryptBlock(words, offset); xorBlock.call(this, words, offset, blockSize); // This block becomes the previous block this._prevBlock = thisBlock; } }); function xorBlock(words, offset, blockSize) { // Shortcut var iv = this._iv; // Choose mixing block if (iv) { var block = iv; // Remove IV for subsequent blocks this._iv = undefined; } else { var block = this._prevBlock; } // XOR blocks for (var i = 0; i < blockSize; i++) { words[offset + i] ^= block[i]; } } return CBC; }()); /** * Padding namespace. */ var C_pad = C.pad = {}; /** * PKCS #5/7 padding strategy. */ var Pkcs7 = C_pad.Pkcs7 = { /** * Pads data using the algorithm defined in PKCS #5/7. * * @param {WordArray} data The data to pad. * @param {number} blockSize The multiple that the data should be padded to. * * @static * * @example * * CryptoJS.pad.Pkcs7.pad(wordArray, 4); */ pad: function (data, blockSize) { // Shortcut var blockSizeBytes = blockSize * 4; // Count padding bytes var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; // Create padding word var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes; // Create padding var paddingWords = []; for (var i = 0; i < nPaddingBytes; i += 4) { paddingWords.push(paddingWord); } var padding = WordArray.create(paddingWords, nPaddingBytes); // Add padding data.concat(padding); }, /** * Unpads data that had been padded using the algorithm defined in PKCS #5/7. * * @param {WordArray} data The data to unpad. * * @static * * @example * * CryptoJS.pad.Pkcs7.unpad(wordArray); */ unpad: function (data) { // Get number of padding bytes from last byte var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; // Remove padding data.sigBytes -= nPaddingBytes; } }; /** * Abstract base block cipher template. * * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) */ var BlockCipher = C_lib.BlockCipher = Cipher.extend({ /** * Configuration options. * * @property {Mode} mode The block mode to use. Default: CBC * @property {Padding} padding The padding strategy to use. Default: Pkcs7 */ cfg: Cipher.cfg.extend({ mode: CBC, padding: Pkcs7 }), reset: function () { // Reset cipher Cipher.reset.call(this); // Shortcuts var cfg = this.cfg; var iv = cfg.iv; var mode = cfg.mode; // Reset block mode if (this._xformMode == this._ENC_XFORM_MODE) { var modeCreator = mode.createEncryptor; } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { var modeCreator = mode.createDecryptor; // Keep at least one block in the buffer for unpadding this._minBufferSize = 1; } this._mode = modeCreator.call(mode, this, iv && iv.words); }, _doProcessBlock: function (words, offset) { this._mode.processBlock(words, offset); }, _doFinalize: function () { // Shortcut var padding = this.cfg.padding; // Finalize if (this._xformMode == this._ENC_XFORM_MODE) { // Pad data padding.pad(this._data, this.blockSize); // Process final blocks var finalProcessedBlocks = this._process(!!'flush'); } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { // Process final blocks var finalProcessedBlocks = this._process(!!'flush'); // Unpad data padding.unpad(finalProcessedBlocks); } return finalProcessedBlocks; }, blockSize: 128/32 }); /** * A collection of cipher parameters. * * @property {WordArray} ciphertext The raw ciphertext. * @property {WordArray} key The key to this ciphertext. * @property {WordArray} iv The IV used in the ciphering operation. * @property {WordArray} salt The salt used with a key derivation function. * @property {Cipher} algorithm The cipher algorithm. * @property {Mode} mode The block mode used in the ciphering operation. * @property {Padding} padding The padding scheme used in the ciphering operation. * @property {number} blockSize The block size of the cipher. * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. */ var CipherParams = C_lib.CipherParams = Base.extend({ /** * Initializes a newly created cipher params object. * * @param {Object} cipherParams An object with any of the possible cipher parameters. * * @example * * var cipherParams = CryptoJS.lib.CipherParams.create({ * ciphertext: ciphertextWordArray, * key: keyWordArray, * iv: ivWordArray, * salt: saltWordArray, * algorithm: CryptoJS.algo.AES, * mode: CryptoJS.mode.CBC, * padding: CryptoJS.pad.PKCS7, * blockSize: 4, * formatter: CryptoJS.format.OpenSSL * }); */ init: function (cipherParams) { this.mixIn(cipherParams); }, /** * Converts this cipher params object to a string. * * @param {Format} formatter (Optional) The formatting strategy to use. * * @return {string} The stringified cipher params. * * @throws Error If neither the formatter nor the default formatter is set. * * @example * * var string = cipherParams + ''; * var string = cipherParams.toString(); * var string = cipherParams.toString(CryptoJS.format.OpenSSL); */ toString: function (formatter) { return (formatter || this.formatter).stringify(this); } }); /** * Format namespace. */ var C_format = C.format = {}; /** * OpenSSL formatting strategy. */ var OpenSSLFormatter = C_format.OpenSSL = { /** * Converts a cipher params object to an OpenSSL-compatible string. * * @param {CipherParams} cipherParams The cipher params object. * * @return {string} The OpenSSL-compatible string. * * @static * * @example * * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); */ stringify: function (cipherParams) { // Shortcuts var ciphertext = cipherParams.ciphertext; var salt = cipherParams.salt; // Format if (salt) { var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); } else { var wordArray = ciphertext; } return wordArray.toString(Base64); }, /** * Converts an OpenSSL-compatible string to a cipher params object. * * @param {string} openSSLStr The OpenSSL-compatible string. * * @return {CipherParams} The cipher params object. * * @static * * @example * * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); */ parse: function (openSSLStr) { // Parse base64 var ciphertext = Base64.parse(openSSLStr); // Shortcut var ciphertextWords = ciphertext.words; // Test for salt if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { // Extract salt var salt = WordArray.create(ciphertextWords.slice(2, 4)); // Remove salt from ciphertext ciphertextWords.splice(0, 4); ciphertext.sigBytes -= 16; } return CipherParams.create({ ciphertext: ciphertext, salt: salt }); } }; /** * A cipher wrapper that returns ciphertext as a serializable cipher params object. */ var SerializableCipher = C_lib.SerializableCipher = Base.extend({ /** * Configuration options. * * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL */ cfg: Base.extend({ format: OpenSSLFormatter }), /** * Encrypts a message. * * @param {Cipher} cipher The cipher algorithm to use. * @param {WordArray|string} message The message to encrypt. * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {CipherParams} A cipher params object. * * @static * * @example * * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); */ encrypt: function (cipher, message, key, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Encrypt var encryptor = cipher.createEncryptor(key, cfg); var ciphertext = encryptor.finalize(message); // Shortcut var cipherCfg = encryptor.cfg; // Create and return serializable cipher params return CipherParams.create({ ciphertext: ciphertext, key: key, iv: cipherCfg.iv, algorithm: cipher, mode: cipherCfg.mode, padding: cipherCfg.padding, blockSize: cipher.blockSize, formatter: cfg.format }); }, /** * Decrypts serialized ciphertext. * * @param {Cipher} cipher The cipher algorithm to use. * @param {CipherParams|string} ciphertext The ciphertext to decrypt. * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {WordArray} The plaintext. * * @static * * @example * * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); */ decrypt: function (cipher, ciphertext, key, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Convert string to CipherParams ciphertext = this._parse(ciphertext, cfg.format); // Decrypt var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); return plaintext; }, /** * Converts serialized ciphertext to CipherParams, * else assumed CipherParams already and returns ciphertext unchanged. * * @param {CipherParams|string} ciphertext The ciphertext. * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext. * * @return {CipherParams} The unserialized ciphertext. * * @static * * @example * * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); */ _parse: function (ciphertext, format) { if (typeof ciphertext == 'string') { return format.parse(ciphertext, this); } else { return ciphertext; } } }); /** * Key derivation function namespace. */ var C_kdf = C.kdf = {}; /** * OpenSSL key derivation function. */ var OpenSSLKdf = C_kdf.OpenSSL = { /** * Derives a key and IV from a password. * * @param {string} password The password to derive from. * @param {number} keySize The size in words of the key to generate. * @param {number} ivSize The size in words of the IV to generate. * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. * * @return {CipherParams} A cipher params object with the key, IV, and salt. * * @static * * @example * * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); */ execute: function (password, keySize, ivSize, salt) { // Generate random salt if (!salt) { salt = WordArray.random(64/8); } // Derive key and IV var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); // Separate key and IV var iv = WordArray.create(key.words.slice(keySize), ivSize * 4); key.sigBytes = keySize * 4; // Return params return CipherParams.create({ key: key, iv: iv, salt: salt }); } }; /** * A serializable cipher wrapper that derives the key from a password, * and returns ciphertext as a serializable cipher params object. */ var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ /** * Configuration options. * * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL */ cfg: SerializableCipher.cfg.extend({ kdf: OpenSSLKdf }), /** * Encrypts a message using a password. * * @param {Cipher} cipher The cipher algorithm to use. * @param {WordArray|string} message The message to encrypt. * @param {string} password The password. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {CipherParams} A cipher params object. * * @static * * @example * * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); */ encrypt: function (cipher, message, password, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Derive key and other params var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize); // Add IV to config cfg.iv = derivedParams.iv; // Encrypt var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); // Mix in derived params ciphertext.mixIn(derivedParams); return ciphertext; }, /** * Decrypts serialized ciphertext using a password. * * @param {Cipher} cipher The cipher algorithm to use. * @param {CipherParams|string} ciphertext The ciphertext to decrypt. * @param {string} password The password. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {WordArray} The plaintext. * * @static * * @example * * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); */ decrypt: function (cipher, ciphertext, password, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Convert string to CipherParams ciphertext = this._parse(ciphertext, cfg.format); // Derive key and other params var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt); // Add IV to config cfg.iv = derivedParams.iv; // Decrypt var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); return plaintext; } }); }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var BlockCipher = C_lib.BlockCipher; var C_algo = C.algo; // Lookup tables var SBOX = []; var INV_SBOX = []; var SUB_MIX_0 = []; var SUB_MIX_1 = []; var SUB_MIX_2 = []; var SUB_MIX_3 = []; var INV_SUB_MIX_0 = []; var INV_SUB_MIX_1 = []; var INV_SUB_MIX_2 = []; var INV_SUB_MIX_3 = []; // Compute lookup tables (function () { // Compute double table var d = []; for (var i = 0; i < 256; i++) { if (i < 128) { d[i] = i << 1; } else { d[i] = (i << 1) ^ 0x11b; } } // Walk GF(2^8) var x = 0; var xi = 0; for (var i = 0; i < 256; i++) { // Compute sbox var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; SBOX[x] = sx; INV_SBOX[sx] = x; // Compute multiplication var x2 = d[x]; var x4 = d[x2]; var x8 = d[x4]; // Compute sub bytes, mix columns tables var t = (d[sx] * 0x101) ^ (sx * 0x1010100); SUB_MIX_0[x] = (t << 24) | (t >>> 8); SUB_MIX_1[x] = (t << 16) | (t >>> 16); SUB_MIX_2[x] = (t << 8) | (t >>> 24); SUB_MIX_3[x] = t; // Compute inv sub bytes, inv mix columns tables var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8); INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16); INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24); INV_SUB_MIX_3[sx] = t; // Compute next counter if (!x) { x = xi = 1; } else { x = x2 ^ d[d[d[x8 ^ x2]]]; xi ^= d[d[xi]]; } } }()); // Precomputed Rcon lookup var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; /** * AES block cipher algorithm. */ var AES = C_algo.AES = BlockCipher.extend({ _doReset: function () { // Shortcuts var key = this._key; var keyWords = key.words; var keySize = key.sigBytes / 4; // Compute number of rounds var nRounds = this._nRounds = keySize + 6 // Compute number of key schedule rows var ksRows = (nRounds + 1) * 4; // Compute key schedule var keySchedule = this._keySchedule = []; for (var ksRow = 0; ksRow < ksRows; ksRow++) { if (ksRow < keySize) { keySchedule[ksRow] = keyWords[ksRow]; } else { var t = keySchedule[ksRow - 1]; if (!(ksRow % keySize)) { // Rot word t = (t << 8) | (t >>> 24); // Sub word t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; // Mix Rcon t ^= RCON[(ksRow / keySize) | 0] << 24; } else if (keySize > 6 && ksRow % keySize == 4) { // Sub word t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; } keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; } } // Compute inv key schedule var invKeySchedule = this._invKeySchedule = []; for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) { var ksRow = ksRows - invKsRow; if (invKsRow % 4) { var t = keySchedule[ksRow]; } else { var t = keySchedule[ksRow - 4]; } if (invKsRow < 4 || ksRow <= 4) { invKeySchedule[invKsRow] = t; } else { invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^ INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]]; } } }, encryptBlock: function (M, offset) { this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); }, decryptBlock: function (M, offset) { // Swap 2nd and 4th rows var t = M[offset + 1]; M[offset + 1] = M[offset + 3]; M[offset + 3] = t; this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); // Inv swap 2nd and 4th rows var t = M[offset + 1]; M[offset + 1] = M[offset + 3]; M[offset + 3] = t; }, _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { // Shortcut var nRounds = this._nRounds; // Get input, add round key var s0 = M[offset] ^ keySchedule[0]; var s1 = M[offset + 1] ^ keySchedule[1]; var s2 = M[offset + 2] ^ keySchedule[2]; var s3 = M[offset + 3] ^ keySchedule[3]; // Key schedule row counter var ksRow = 4; // Rounds for (var round = 1; round < nRounds; round++) { // Shift rows, sub bytes, mix columns, add round key var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++]; var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++]; var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++]; var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++]; // Update state s0 = t0; s1 = t1; s2 = t2; s3 = t3; } // Shift rows, sub bytes, add round key var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; // Set output M[offset] = t0; M[offset + 1] = t1; M[offset + 2] = t2; M[offset + 3] = t3; }, keySize: 256/32 }); /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); */ C.AES = BlockCipher._createHelper(AES); }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; // Reusable object var W = []; /** * SHA-1 hash algorithm. */ var SHA1 = C_algo.SHA1 = Hasher.extend({ _doReset: function () { this._hash = new WordArray.init([ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]); }, _doProcessBlock: function (M, offset) { // Shortcut var H = this._hash.words; // Working variables var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; // Computation for (var i = 0; i < 80; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; W[i] = (n << 1) | (n >>> 31); } var t = ((a << 5) | (a >>> 27)) + e + W[i]; if (i < 20) { t += ((b & c) | (~b & d)) + 0x5a827999; } else if (i < 40) { t += (b ^ c ^ d) + 0x6ed9eba1; } else if (i < 60) { t += ((b & c) | (b & d) | (c & d)) - 0x70e44324; } else /* if (i < 80) */ { t += (b ^ c ^ d) - 0x359d3e2a; } e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t; } // Intermediate hash value H[0] = (H[0] + a) | 0; H[1] = (H[1] + b) | 0; H[2] = (H[2] + c) | 0; H[3] = (H[3] + d) | 0; H[4] = (H[4] + e) | 0; }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; // Add padding dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; // Hash final blocks this._process(); // Return final computed hash return this._hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA1('message'); * var hash = CryptoJS.SHA1(wordArray); */ C.SHA1 = Hasher._createHelper(SHA1); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA1(message, key); */ C.HmacSHA1 = Hasher._createHmacHelper(SHA1); }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function (Math) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; // Initialization and round constants tables var H = []; var K = []; // Compute constants (function () { function isPrime(n) { var sqrtN = Math.sqrt(n); for (var factor = 2; factor <= sqrtN; factor++) { if (!(n % factor)) { return false; } } return true; } function getFractionalBits(n) { return ((n - (n | 0)) * 0x100000000) | 0; } var n = 2; var nPrime = 0; while (nPrime < 64) { if (isPrime(n)) { if (nPrime < 8) { H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2)); } K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3)); nPrime++; } n++; } }()); // Reusable object var W = []; /** * SHA-256 hash algorithm. */ var SHA256 = C_algo.SHA256 = Hasher.extend({ _doReset: function () { this._hash = new WordArray.init(H.slice(0)); }, _doProcessBlock: function (M, offset) { // Shortcut var H = this._hash.words; // Working variables var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; var f = H[5]; var g = H[6]; var h = H[7]; // Computation for (var i = 0; i < 64; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var gamma0x = W[i - 15]; var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ ((gamma0x << 14) | (gamma0x >>> 18)) ^ (gamma0x >>> 3); var gamma1x = W[i - 2]; var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ ((gamma1x << 13) | (gamma1x >>> 19)) ^ (gamma1x >>> 10); W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]; } var ch = (e & f) ^ (~e & g); var maj = (a & b) ^ (a & c) ^ (b & c); var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22)); var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25)); var t1 = h + sigma1 + ch + K[i] + W[i]; var t2 = sigma0 + maj; h = g; g = f; f = e; e = (d + t1) | 0; d = c; c = b; b = a; a = (t1 + t2) | 0; } // Intermediate hash value H[0] = (H[0] + a) | 0; H[1] = (H[1] + b) | 0; H[2] = (H[2] + c) | 0; H[3] = (H[3] + d) | 0; H[4] = (H[4] + e) | 0; H[5] = (H[5] + f) | 0; H[6] = (H[6] + g) | 0; H[7] = (H[7] + h) | 0; }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; // Add padding dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; // Hash final blocks this._process(); // Return final computed hash return this._hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA256('message'); * var hash = CryptoJS.SHA256(wordArray); */ C.SHA256 = Hasher._createHelper(SHA256); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA256(message, key); */ C.HmacSHA256 = Hasher._createHmacHelper(SHA256); }(Math)); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var C_enc = C.enc; var Utf8 = C_enc.Utf8; var C_algo = C.algo; /** * HMAC algorithm. */ var HMAC = C_algo.HMAC = Base.extend({ /** * Initializes a newly created HMAC. * * @param {Hasher} hasher The hash algorithm to use. * @param {WordArray|string} key The secret key. * * @example * * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); */ init: function (hasher, key) { // Init hasher hasher = this._hasher = new hasher.init(); // Convert string to WordArray, else assume WordArray already if (typeof key == 'string') { key = Utf8.parse(key); } // Shortcuts var hasherBlockSize = hasher.blockSize; var hasherBlockSizeBytes = hasherBlockSize * 4; // Allow arbitrary length keys if (key.sigBytes > hasherBlockSizeBytes) { key = hasher.finalize(key); } // Clamp excess bits key.clamp(); // Clone key for inner and outer pads var oKey = this._oKey = key.clone(); var iKey = this._iKey = key.clone(); // Shortcuts var oKeyWords = oKey.words; var iKeyWords = iKey.words; // XOR keys with pad constants for (var i = 0; i < hasherBlockSize; i++) { oKeyWords[i] ^= 0x5c5c5c5c; iKeyWords[i] ^= 0x36363636; } oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; // Set initial values this.reset(); }, /** * Resets this HMAC to its initial state. * * @example * * hmacHasher.reset(); */ reset: function () { // Shortcut var hasher = this._hasher; // Reset hasher.reset(); hasher.update(this._iKey); }, /** * Updates this HMAC with a message. * * @param {WordArray|string} messageUpdate The message to append. * * @return {HMAC} This HMAC instance. * * @example * * hmacHasher.update('message'); * hmacHasher.update(wordArray); */ update: function (messageUpdate) { this._hasher.update(messageUpdate); // Chainable return this; }, /** * Finalizes the HMAC computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} messageUpdate (Optional) A final message update. * * @return {WordArray} The HMAC. * * @example * * var hmac = hmacHasher.finalize(); * var hmac = hmacHasher.finalize('message'); * var hmac = hmacHasher.finalize(wordArray); */ finalize: function (messageUpdate) { // Shortcut var hasher = this._hasher; // Compute HMAC var innerHash = hasher.finalize(messageUpdate); hasher.reset(); var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); return hmac; } }); }()); /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** * A noop padding strategy. */ CryptoJS.pad.NoPadding = { pad: function () { }, unpad: function () { } }; /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** * Counter block mode. */ CryptoJS.mode.CTR = (function () { var CTR = CryptoJS.lib.BlockCipherMode.extend(); var Encryptor = CTR.Encryptor = CTR.extend({ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher var blockSize = cipher.blockSize; var iv = this._iv; var counter = this._counter; // Generate keystream if (iv) { counter = this._counter = iv.slice(0); // Remove IV for subsequent blocks this._iv = undefined; } var keystream = counter.slice(0); cipher.encryptBlock(keystream, 0); // Increment counter counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0 // Encrypt for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } }); CTR.Decryptor = Encryptor; return CTR; }()); return CryptoJS }))././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dep/salsa20.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dep/sals0000644000076400007640000002347612572247340032546 0ustar pravipravi// Salsa20 implementation // Contributed to Cryptocat by Dmitry Chestnykh // 21-01-2013 ;(function (root, factory) { if (typeof define === 'function' && define.amd) { define(factory) } else if (typeof module !== 'undefined' && module.exports) { module.exports = factory() } else { root.Salsa20 = factory() } }(this, function () { function Salsa20(key, nonce) { // Constants. this.rounds = 20; // number of Salsa rounds this.sigmaWords = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]; // State. this.keyWords = []; // key words this.nonceWords = [0, 0]; // nonce words this.counterWords = [0, 0]; // block counter words // Output buffer. this.block = []; // output block of 64 bytes this.blockUsed = 64; // number of block bytes used this.setKey(key); this.setNonce(nonce); } // setKey sets the key to the given 32-byte array. Salsa20.prototype.setKey = function(key) { for (var i = 0, j = 0; i < 8; i++, j += 4) { this.keyWords[i] = (key[j] & 0xff) | ((key[j+1] & 0xff)<<8) | ((key[j+2] & 0xff)<<16) | ((key[j+3] & 0xff)<<24); } this._reset(); }; // setNonce sets the nonce to the given 8-byte array. Salsa20.prototype.setNonce = function(nonce) { this.nonceWords[0] = (nonce[0] & 0xff) | ((nonce[1] & 0xff)<<8) | ((nonce[2] & 0xff)<<16) | ((nonce[3] & 0xff)<<24); this.nonceWords[1] = (nonce[4] & 0xff) | ((nonce[5] & 0xff)<<8) | ((nonce[6] & 0xff)<<16) | ((nonce[7] & 0xff)<<24); this._reset(); }; // getBytes returns the next numberOfBytes bytes of stream. Salsa20.prototype.getBytes = function(numberOfBytes) { var out = new Array(numberOfBytes); for (var i = 0; i < numberOfBytes; i++) { if (this.blockUsed == 64) { this._generateBlock(); this._incrementCounter(); this.blockUsed = 0; } out[i] = this.block[this.blockUsed]; this.blockUsed++; } return out; }; Salsa20.prototype.getHexString = function(numberOfBytes) { var hex=['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']; var out = []; var bytes = this.getBytes(numberOfBytes); for(var i = 0; i < bytes.length; i++) { out.push(hex[(bytes[i] >> 4) & 15]); out.push(hex[bytes[i] & 15]); } return out.join(''); }; // Private methods. Salsa20.prototype._reset = function() { this.counterWords[0] = 0; this.counterWords[1] = 0; this.blockUsed = 64; }; // _incrementCounter increments block counter. Salsa20.prototype._incrementCounter = function() { // Note: maximum 2^64 blocks. this.counterWords[0] = (this.counterWords[0] + 1) & 0xffffffff; if (this.counterWords[0] == 0) { this.counterWords[1] = (this.counterWords[1] + 1) & 0xffffffff; } }; // _generateBlock generates 64 bytes from key, nonce, and counter, // and puts the result into this.block. Salsa20.prototype._generateBlock = function() { var j0 = this.sigmaWords[0], j1 = this.keyWords[0], j2 = this.keyWords[1], j3 = this.keyWords[2], j4 = this.keyWords[3], j5 = this.sigmaWords[1], j6 = this.nonceWords[0], j7 = this.nonceWords[1], j8 = this.counterWords[0], j9 = this.counterWords[1], j10 = this.sigmaWords[2], j11 = this.keyWords[4], j12 = this.keyWords[5], j13 = this.keyWords[6], j14 = this.keyWords[7], j15 = this.sigmaWords[3]; var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15; var u; for (var i = 0; i < this.rounds; i += 2) { u = x0 + x12; x4 ^= (u<<7) | (u>>>(32-7)); u = x4 + x0; x8 ^= (u<<9) | (u>>>(32-9)); u = x8 + x4; x12 ^= (u<<13) | (u>>>(32-13)); u = x12 + x8; x0 ^= (u<<18) | (u>>>(32-18)); u = x5 + x1; x9 ^= (u<<7) | (u>>>(32-7)); u = x9 + x5; x13 ^= (u<<9) | (u>>>(32-9)); u = x13 + x9; x1 ^= (u<<13) | (u>>>(32-13)); u = x1 + x13; x5 ^= (u<<18) | (u>>>(32-18)); u = x10 + x6; x14 ^= (u<<7) | (u>>>(32-7)); u = x14 + x10; x2 ^= (u<<9) | (u>>>(32-9)); u = x2 + x14; x6 ^= (u<<13) | (u>>>(32-13)); u = x6 + x2; x10 ^= (u<<18) | (u>>>(32-18)); u = x15 + x11; x3 ^= (u<<7) | (u>>>(32-7)); u = x3 + x15; x7 ^= (u<<9) | (u>>>(32-9)); u = x7 + x3; x11 ^= (u<<13) | (u>>>(32-13)); u = x11 + x7; x15 ^= (u<<18) | (u>>>(32-18)); u = x0 + x3; x1 ^= (u<<7) | (u>>>(32-7)); u = x1 + x0; x2 ^= (u<<9) | (u>>>(32-9)); u = x2 + x1; x3 ^= (u<<13) | (u>>>(32-13)); u = x3 + x2; x0 ^= (u<<18) | (u>>>(32-18)); u = x5 + x4; x6 ^= (u<<7) | (u>>>(32-7)); u = x6 + x5; x7 ^= (u<<9) | (u>>>(32-9)); u = x7 + x6; x4 ^= (u<<13) | (u>>>(32-13)); u = x4 + x7; x5 ^= (u<<18) | (u>>>(32-18)); u = x10 + x9; x11 ^= (u<<7) | (u>>>(32-7)); u = x11 + x10; x8 ^= (u<<9) | (u>>>(32-9)); u = x8 + x11; x9 ^= (u<<13) | (u>>>(32-13)); u = x9 + x8; x10 ^= (u<<18) | (u>>>(32-18)); u = x15 + x14; x12 ^= (u<<7) | (u>>>(32-7)); u = x12 + x15; x13 ^= (u<<9) | (u>>>(32-9)); u = x13 + x12; x14 ^= (u<<13) | (u>>>(32-13)); u = x14 + x13; x15 ^= (u<<18) | (u>>>(32-18)); } x0 += j0; x1 += j1; x2 += j2; x3 += j3; x4 += j4; x5 += j5; x6 += j6; x7 += j7; x8 += j8; x9 += j9; x10 += j10; x11 += j11; x12 += j12; x13 += j13; x14 += j14; x15 += j15; this.block[ 0] = ( x0 >>> 0) & 0xff; this.block[ 1] = ( x0 >>> 8) & 0xff; this.block[ 2] = ( x0 >>> 16) & 0xff; this.block[ 3] = ( x0 >>> 24) & 0xff; this.block[ 4] = ( x1 >>> 0) & 0xff; this.block[ 5] = ( x1 >>> 8) & 0xff; this.block[ 6] = ( x1 >>> 16) & 0xff; this.block[ 7] = ( x1 >>> 24) & 0xff; this.block[ 8] = ( x2 >>> 0) & 0xff; this.block[ 9] = ( x2 >>> 8) & 0xff; this.block[10] = ( x2 >>> 16) & 0xff; this.block[11] = ( x2 >>> 24) & 0xff; this.block[12] = ( x3 >>> 0) & 0xff; this.block[13] = ( x3 >>> 8) & 0xff; this.block[14] = ( x3 >>> 16) & 0xff; this.block[15] = ( x3 >>> 24) & 0xff; this.block[16] = ( x4 >>> 0) & 0xff; this.block[17] = ( x4 >>> 8) & 0xff; this.block[18] = ( x4 >>> 16) & 0xff; this.block[19] = ( x4 >>> 24) & 0xff; this.block[20] = ( x5 >>> 0) & 0xff; this.block[21] = ( x5 >>> 8) & 0xff; this.block[22] = ( x5 >>> 16) & 0xff; this.block[23] = ( x5 >>> 24) & 0xff; this.block[24] = ( x6 >>> 0) & 0xff; this.block[25] = ( x6 >>> 8) & 0xff; this.block[26] = ( x6 >>> 16) & 0xff; this.block[27] = ( x6 >>> 24) & 0xff; this.block[28] = ( x7 >>> 0) & 0xff; this.block[29] = ( x7 >>> 8) & 0xff; this.block[30] = ( x7 >>> 16) & 0xff; this.block[31] = ( x7 >>> 24) & 0xff; this.block[32] = ( x8 >>> 0) & 0xff; this.block[33] = ( x8 >>> 8) & 0xff; this.block[34] = ( x8 >>> 16) & 0xff; this.block[35] = ( x8 >>> 24) & 0xff; this.block[36] = ( x9 >>> 0) & 0xff; this.block[37] = ( x9 >>> 8) & 0xff; this.block[38] = ( x9 >>> 16) & 0xff; this.block[39] = ( x9 >>> 24) & 0xff; this.block[40] = (x10 >>> 0) & 0xff; this.block[41] = (x10 >>> 8) & 0xff; this.block[42] = (x10 >>> 16) & 0xff; this.block[43] = (x10 >>> 24) & 0xff; this.block[44] = (x11 >>> 0) & 0xff; this.block[45] = (x11 >>> 8) & 0xff; this.block[46] = (x11 >>> 16) & 0xff; this.block[47] = (x11 >>> 24) & 0xff; this.block[48] = (x12 >>> 0) & 0xff; this.block[49] = (x12 >>> 8) & 0xff; this.block[50] = (x12 >>> 16) & 0xff; this.block[51] = (x12 >>> 24) & 0xff; this.block[52] = (x13 >>> 0) & 0xff; this.block[53] = (x13 >>> 8) & 0xff; this.block[54] = (x13 >>> 16) & 0xff; this.block[55] = (x13 >>> 24) & 0xff; this.block[56] = (x14 >>> 0) & 0xff; this.block[57] = (x14 >>> 8) & 0xff; this.block[58] = (x14 >>> 16) & 0xff; this.block[59] = (x14 >>> 24) & 0xff; this.block[60] = (x15 >>> 0) & 0xff; this.block[61] = (x15 >>> 8) & 0xff; this.block[62] = (x15 >>> 16) & 0xff; this.block[63] = (x15 >>> 24) & 0xff; }; return Salsa20 }))././@LongLink0000644000000000000000000000016000000000000011600 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dep/eventemitter.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dep/even0000644000076400007640000003643312572247340032536 0ustar pravipravi/*! * EventEmitter v4.2.3 - git.io/ee * Oliver Caldwell * MIT license * @preserve */ (function () { 'use strict'; /** * Class for managing events. * Can be extended to provide event functionality in other classes. * * @class EventEmitter Manages event registering and emitting. */ function EventEmitter() {} // Shortcuts to improve speed and size // Easy access to the prototype var proto = EventEmitter.prototype; /** * Finds the index of the listener for the event in it's storage array. * * @param {Function[]} listeners Array of listeners to search through. * @param {Function} listener Method to look for. * @return {Number} Index of the specified listener, -1 if not found * @api private */ function indexOfListener(listeners, listener) { var i = listeners.length; while (i--) { if (listeners[i].listener === listener) { return i; } } return -1; } /** * Alias a method while keeping the context correct, to allow for overwriting of target method. * * @param {String} name The name of the target method. * @return {Function} The aliased method * @api private */ function alias(name) { return function aliasClosure() { return this[name].apply(this, arguments); }; } /** * Returns the listener array for the specified event. * Will initialise the event object and listener arrays if required. * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. * Each property in the object response is an array of listener functions. * * @param {String|RegExp} evt Name of the event to return the listeners from. * @return {Function[]|Object} All listener functions for the event. */ proto.getListeners = function getListeners(evt) { var events = this._getEvents(); var response; var key; // Return a concatenated array of all matching events if // the selector is a regular expression. if (typeof evt === 'object') { response = {}; for (key in events) { if (events.hasOwnProperty(key) && evt.test(key)) { response[key] = events[key]; } } } else { response = events[evt] || (events[evt] = []); } return response; }; /** * Takes a list of listener objects and flattens it into a list of listener functions. * * @param {Object[]} listeners Raw listener objects. * @return {Function[]} Just the listener functions. */ proto.flattenListeners = function flattenListeners(listeners) { var flatListeners = []; var i; for (i = 0; i < listeners.length; i += 1) { flatListeners.push(listeners[i].listener); } return flatListeners; }; /** * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. * * @param {String|RegExp} evt Name of the event to return the listeners from. * @return {Object} All listener functions for an event in an object. */ proto.getListenersAsObject = function getListenersAsObject(evt) { var listeners = this.getListeners(evt); var response; if (listeners instanceof Array) { response = {}; response[evt] = listeners; } return response || listeners; }; /** * Adds a listener function to the specified event. * The listener will not be added if it is a duplicate. * If the listener returns true then it will be removed after it is called. * If you pass a regular expression as the event name then the listener will be added to all events that match it. * * @param {String|RegExp} evt Name of the event to attach the listener to. * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. * @return {Object} Current instance of EventEmitter for chaining. */ proto.addListener = function addListener(evt, listener) { var listeners = this.getListenersAsObject(evt); var listenerIsWrapped = typeof listener === 'object'; var key; for (key in listeners) { if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { listeners[key].push(listenerIsWrapped ? listener : { listener: listener, once: false }); } } return this; }; /** * Alias of addListener */ proto.on = alias('addListener'); /** * Semi-alias of addListener. It will add a listener that will be * automatically removed after it's first execution. * * @param {String|RegExp} evt Name of the event to attach the listener to. * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. * @return {Object} Current instance of EventEmitter for chaining. */ proto.addOnceListener = function addOnceListener(evt, listener) { return this.addListener(evt, { listener: listener, once: true }); }; /** * Alias of addOnceListener. */ proto.once = alias('addOnceListener'); /** * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. * You need to tell it what event names should be matched by a regex. * * @param {String} evt Name of the event to create. * @return {Object} Current instance of EventEmitter for chaining. */ proto.defineEvent = function defineEvent(evt) { this.getListeners(evt); return this; }; /** * Uses defineEvent to define multiple events. * * @param {String[]} evts An array of event names to define. * @return {Object} Current instance of EventEmitter for chaining. */ proto.defineEvents = function defineEvents(evts) { for (var i = 0; i < evts.length; i += 1) { this.defineEvent(evts[i]); } return this; }; /** * Removes a listener function from the specified event. * When passed a regular expression as the event name, it will remove the listener from all events that match it. * * @param {String|RegExp} evt Name of the event to remove the listener from. * @param {Function} listener Method to remove from the event. * @return {Object} Current instance of EventEmitter for chaining. */ proto.removeListener = function removeListener(evt, listener) { var listeners = this.getListenersAsObject(evt); var index; var key; for (key in listeners) { if (listeners.hasOwnProperty(key)) { index = indexOfListener(listeners[key], listener); if (index !== -1) { listeners[key].splice(index, 1); } } } return this; }; /** * Alias of removeListener */ proto.off = alias('removeListener'); /** * Adds listeners in bulk using the manipulateListeners method. * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. * You can also pass it a regular expression to add the array of listeners to all events that match it. * Yeah, this function does quite a bit. That's probably a bad thing. * * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. * @param {Function[]} [listeners] An optional array of listener functions to add. * @return {Object} Current instance of EventEmitter for chaining. */ proto.addListeners = function addListeners(evt, listeners) { // Pass through to manipulateListeners return this.manipulateListeners(false, evt, listeners); }; /** * Removes listeners in bulk using the manipulateListeners method. * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. * You can also pass it an event name and an array of listeners to be removed. * You can also pass it a regular expression to remove the listeners from all events that match it. * * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. * @param {Function[]} [listeners] An optional array of listener functions to remove. * @return {Object} Current instance of EventEmitter for chaining. */ proto.removeListeners = function removeListeners(evt, listeners) { // Pass through to manipulateListeners return this.manipulateListeners(true, evt, listeners); }; /** * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. * The first argument will determine if the listeners are removed (true) or added (false). * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. * You can also pass it an event name and an array of listeners to be added/removed. * You can also pass it a regular expression to manipulate the listeners of all events that match it. * * @param {Boolean} remove True if you want to remove listeners, false if you want to add. * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. * @param {Function[]} [listeners] An optional array of listener functions to add/remove. * @return {Object} Current instance of EventEmitter for chaining. */ proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { var i; var value; var single = remove ? this.removeListener : this.addListener; var multiple = remove ? this.removeListeners : this.addListeners; // If evt is an object then pass each of it's properties to this method if (typeof evt === 'object' && !(evt instanceof RegExp)) { for (i in evt) { if (evt.hasOwnProperty(i) && (value = evt[i])) { // Pass the single listener straight through to the singular method if (typeof value === 'function') { single.call(this, i, value); } else { // Otherwise pass back to the multiple function multiple.call(this, i, value); } } } } else { // So evt must be a string // And listeners must be an array of listeners // Loop over it and pass each one to the multiple method i = listeners.length; while (i--) { single.call(this, evt, listeners[i]); } } return this; }; /** * Removes all listeners from a specified event. * If you do not specify an event then all listeners will be removed. * That means every event will be emptied. * You can also pass a regex to remove all events that match it. * * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. * @return {Object} Current instance of EventEmitter for chaining. */ proto.removeEvent = function removeEvent(evt) { var type = typeof evt; var events = this._getEvents(); var key; // Remove different things depending on the state of evt if (type === 'string') { // Remove all listeners for the specified event delete events[evt]; } else if (type === 'object') { // Remove all events matching the regex. for (key in events) { if (events.hasOwnProperty(key) && evt.test(key)) { delete events[key]; } } } else { // Remove all listeners in all events delete this._events; } return this; }; /** * Emits an event of your choice. * When emitted, every listener attached to that event will be executed. * If you pass the optional argument array then those arguments will be passed to every listener upon execution. * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. * So they will not arrive within the array on the other side, they will be separate. * You can also pass a regular expression to emit to all events that match it. * * @param {String|RegExp} evt Name of the event to emit and execute listeners for. * @param {Array} [args] Optional array of arguments to be passed to each listener. * @return {Object} Current instance of EventEmitter for chaining. */ proto.emitEvent = function emitEvent(evt, args) { var listeners = this.getListenersAsObject(evt); var listener; var i; var key; var response; for (key in listeners) { if (listeners.hasOwnProperty(key)) { i = listeners[key].length; while (i--) { // If the listener returns true then it shall be removed from the event // The function is executed either with a basic call or an apply if there is an args array listener = listeners[key][i]; if (listener.once === true) { this.removeListener(evt, listener.listener); } response = listener.listener.apply(this, args || []); if (response === this._getOnceReturnValue()) { this.removeListener(evt, listener.listener); } } } } return this; }; /** * Alias of emitEvent */ proto.trigger = alias('emitEvent'); /** * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. * * @param {String|RegExp} evt Name of the event to emit and execute listeners for. * @param {...*} Optional additional arguments to be passed to each listener. * @return {Object} Current instance of EventEmitter for chaining. */ proto.emit = function emit(evt) { var args = Array.prototype.slice.call(arguments, 1); return this.emitEvent(evt, args); }; /** * Sets the current value to check against when executing listeners. If a * listeners return value matches the one set here then it will be removed * after execution. This value defaults to true. * * @param {*} value The new value to check for when executing listeners. * @return {Object} Current instance of EventEmitter for chaining. */ proto.setOnceReturnValue = function setOnceReturnValue(value) { this._onceReturnValue = value; return this; }; /** * Fetches the current value to check against when executing listeners. If * the listeners return value matches this one then it should be removed * automatically. It will return true by default. * * @return {*|Boolean} The current value to check for or the default, true. * @api private */ proto._getOnceReturnValue = function _getOnceReturnValue() { if (this.hasOwnProperty('_onceReturnValue')) { return this._onceReturnValue; } else { return true; } }; /** * Fetches the events object and creates one if required. * * @return {Object} The events storage object. * @api private */ proto._getEvents = function _getEvents() { return this._events || (this._events = {}); }; // Expose the class either via AMD, CommonJS or the global object if (typeof define === 'function' && define.amd) { define(function () { return EventEmitter; }); } else if (typeof module === 'object' && module.exports){ module.exports = EventEmitter; } else { this.EventEmitter = EventEmitter; } }.call(this)); ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dep/bigint.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dep/bigi0000644000076400007640000015600312572247340032507 0ustar pravipravi;(function (root, factory) { if (typeof define === 'function' && define.amd) { define(factory.bind(root, root.crypto || root.msCrypto)) } else if (typeof module !== 'undefined' && module.exports) { module.exports = factory(require('crypto')) } else { root.BigInt = factory(root.crypto || root.msCrypto) } }(this, function (crypto) { //////////////////////////////////////////////////////////////////////////////////////// // Big Integer Library v. 5.5 // Created 2000, last modified 2013 // Leemon Baird // www.leemon.com // // Version history: // v 5.5 17 Mar 2013 // - two lines of a form like "if (x<0) x+=n" had the "if" changed to "while" to // handle the case when x<-n. (Thanks to James Ansell for finding that bug) // v 5.4 3 Oct 2009 // - added "var i" to greaterShift() so i is not global. (Thanks to Péter Szabó for finding that bug) // // v 5.3 21 Sep 2009 // - added randProbPrime(k) for probable primes // - unrolled loop in mont_ (slightly faster) // - millerRabin now takes a bigInt parameter rather than an int // // v 5.2 15 Sep 2009 // - fixed capitalization in call to int2bigInt in randBigInt // (thanks to Emili Evripidou, Reinhold Behringer, and Samuel Macaleese for finding that bug) // // v 5.1 8 Oct 2007 // - renamed inverseModInt_ to inverseModInt since it doesn't change its parameters // - added functions GCD and randBigInt, which call GCD_ and randBigInt_ // - fixed a bug found by Rob Visser (see comment with his name below) // - improved comments // // This file is public domain. You can use it for any purpose without restriction. // I do not guarantee that it is correct, so use it at your own risk. If you use // it for something interesting, I'd appreciate hearing about it. If you find // any bugs or make any improvements, I'd appreciate hearing about those too. // It would also be nice if my name and URL were left in the comments. But none // of that is required. // // This code defines a bigInt library for arbitrary-precision integers. // A bigInt is an array of integers storing the value in chunks of bpe bits, // little endian (buff[0] is the least significant word). // Negative bigInts are stored two's complement. Almost all the functions treat // bigInts as nonnegative. The few that view them as two's complement say so // in their comments. Some functions assume their parameters have at least one // leading zero element. Functions with an underscore at the end of the name put // their answer into one of the arrays passed in, and have unpredictable behavior // in case of overflow, so the caller must make sure the arrays are big enough to // hold the answer. But the average user should never have to call any of the // underscored functions. Each important underscored function has a wrapper function // of the same name without the underscore that takes care of the details for you. // For each underscored function where a parameter is modified, that same variable // must not be used as another argument too. So, you cannot square x by doing // multMod_(x,x,n). You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n). // Or simply use the multMod(x,x,n) function without the underscore, where // such issues never arise, because non-underscored functions never change // their parameters; they always allocate new memory for the answer that is returned. // // These functions are designed to avoid frequent dynamic memory allocation in the inner loop. // For most functions, if it needs a BigInt as a local variable it will actually use // a global, and will only allocate to it only when it's not the right size. This ensures // that when a function is called repeatedly with same-sized parameters, it only allocates // memory on the first call. // // Note that for cryptographic purposes, the calls to Math.random() must // be replaced with calls to a better pseudorandom number generator. // // In the following, "bigInt" means a bigInt with at least one leading zero element, // and "integer" means a nonnegative integer less than radix. In some cases, integer // can be negative. Negative bigInts are 2s complement. // // The following functions do not modify their inputs. // Those returning a bigInt, string, or Array will dynamically allocate memory for that value. // Those returning a boolean will return the integer 0 (false) or 1 (true). // Those returning boolean or int will not allocate memory except possibly on the first // time they're called with a given parameter size. // // bigInt add(x,y) //return (x+y) for bigInts x and y. // bigInt addInt(x,n) //return (x+n) where x is a bigInt and n is an integer. // string bigInt2str(x,base) //return a string form of bigInt x in a given base, with 2 <= base <= 95 // int bitSize(x) //return how many bits long the bigInt x is, not counting leading zeros // bigInt dup(x) //return a copy of bigInt x // boolean equals(x,y) //is the bigInt x equal to the bigint y? // boolean equalsInt(x,y) //is bigint x equal to integer y? // bigInt expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed // Array findPrimes(n) //return array of all primes less than integer n // bigInt GCD(x,y) //return greatest common divisor of bigInts x and y (each with same number of elements). // boolean greater(x,y) //is x>y? (x and y are nonnegative bigInts) // boolean greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y? // bigInt int2bigInt(t,n,m) //return a bigInt equal to integer t, with at least n bits and m array elements // bigInt inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null // int inverseModInt(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse // boolean isZero(x) //is the bigInt x equal to zero? // boolean millerRabin(x,b) //does one round of Miller-Rabin base integer b say that bigInt x is possibly prime? (b is bigInt, 1=1). If s=1, then the most significant of those n bits is set to 1. // bigInt randTruePrime(k) //return a new, random, k-bit, true prime bigInt using Maurer's algorithm. // bigInt randProbPrime(k) //return a new, random, k-bit, probable prime bigInt (probability it's composite less than 2^-80). // bigInt str2bigInt(s,b,n,m) //return a bigInt for number represented in string s in base b with at least n bits and m array elements // bigInt sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement // bigInt trim(x,k) //return a copy of x with exactly k leading zero elements // // // The following functions each have a non-underscored version, which most users should call instead. // These functions each write to a single parameter, and the caller is responsible for ensuring the array // passed in is large enough to hold the result. // // void addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer // void add_(x,y) //do x=x+y for bigInts x and y // void copy_(x,y) //do x=y on bigInts x and y // void copyInt_(x,n) //do x=n on bigInt x and integer n // void GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed). (This never overflows its array). // boolean inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist // void mod_(x,n) //do x=x mod n for bigInts x and n. (This never overflows its array). // void mult_(x,y) //do x=x*y for bigInts x and y. // void multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n. // void powMod_(x,y,n) //do x=x**y mod n, where x,y,n are bigInts (n is odd) and ** is exponentiation. 0**0=1. // void randBigInt_(b,n,s) //do b = an n-bit random BigInt. if s=1, then nth bit (most significant bit) is set to 1. n>=1. // void randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb. // void sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement. // // The following functions do NOT have a non-underscored version. // They each write a bigInt result to one or more parameters. The caller is responsible for // ensuring the arrays passed in are large enough to hold the results. // // void addShift_(x,y,ys) //do x=x+(y<<(ys*bpe)) // void carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits. // void divide_(x,y,q,r) //divide x by y giving quotient q and remainder r // int divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder. (This never overflows its array). // int eGCD_(x,y,d,a,b) //sets a,b,d to positive bigInts such that d = GCD_(x,y) = a*x-b*y // void halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement. (This never overflows its array). // void leftShift_(x,n) //left shift bigInt x by n bits. n64 multiplier, but not with JavaScript's 32*32->32) // - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square // followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that // method would be slower. This is unfortunate because the code currently spends almost all of its time // doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring // would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded // sentences that seem to imply it's faster to do a non-modular square followed by a single // Montgomery reduction, but that's obviously wrong. //////////////////////////////////////////////////////////////////////////////////////// //globals // The number of significant bits in the fraction of a JavaScript // floating-point number is 52, independent of platform. // See: https://github.com/arlolra/otr/issues/41 var bpe = 26; // bits stored per array element var radix = 1 << bpe; // equals 2^bpe var mask = radix - 1; // AND this with an array element to chop it down to bpe bits //the digits for converting to different bases var digitsStr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-'; var one=int2bigInt(1,1,1); //constant used in powMod_() //the following global variables are scratchpad memory to //reduce dynamic memory allocation in the inner loop var t=new Array(0); var ss=t; //used in mult_() var s0=t; //used in multMod_(), squareMod_() var s1=t; //used in powMod_(), multMod_(), squareMod_() var s2=t; //used in powMod_(), multMod_() var s3=t; //used in powMod_() var s4=t, s5=t; //used in mod_() var s6=t; //used in bigInt2str() var s7=t; //used in powMod_() var T=t; //used in GCD_() var sa=t; //used in mont_() var mr_x1=t, mr_r=t, mr_a=t; //used in millerRabin() var eg_v=t, eg_u=t, eg_A=t, eg_B=t, eg_C=t, eg_D=t; //used in eGCD_(), inverseMod_() var md_q1=t, md_q2=t, md_q3=t, md_r=t, md_r1=t, md_r2=t, md_tt=t; //used in mod_() var primes=t, pows=t, s_i=t, s_i2=t, s_R=t, s_rm=t, s_q=t, s_n1=t; var s_a=t, s_r2=t, s_n=t, s_b=t, s_d=t, s_x1=t, s_x2=t, s_aa=t; //used in randTruePrime_() var rpprb=t; //used in randProbPrimeRounds() (which also uses "primes") //////////////////////////////////////////////////////////////////////////////////////// //return array of all primes less than integer n function findPrimes(n) { var i,s,p,ans; s=new Array(n); for (i=0;i0); j--); for (z=0,w=x[j]; w; (w>>=1),z++); z+=bpe*j; return z; } //return a copy of x with at least n elements, adding leading zeros if needed function expand(x,n) { var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0); copy_(ans,x); return ans; } //return a k-bit true random prime using Maurer's algorithm. function randTruePrime(k) { var ans=int2bigInt(0,k,0); randTruePrime_(ans,k); return trim(ans,1); } //return a k-bit random probable prime with probability of error < 2^-80 function randProbPrime(k) { if (k>=600) return randProbPrimeRounds(k,2); //numbers from HAC table 4.3 if (k>=550) return randProbPrimeRounds(k,4); if (k>=500) return randProbPrimeRounds(k,5); if (k>=400) return randProbPrimeRounds(k,6); if (k>=350) return randProbPrimeRounds(k,7); if (k>=300) return randProbPrimeRounds(k,9); if (k>=250) return randProbPrimeRounds(k,12); //numbers from HAC table 4.4 if (k>=200) return randProbPrimeRounds(k,15); if (k>=150) return randProbPrimeRounds(k,18); if (k>=100) return randProbPrimeRounds(k,27); return randProbPrimeRounds(k,40); //number from HAC remark 4.26 (only an estimate) } //return a k-bit probable random prime using n rounds of Miller Rabin (after trial division with small primes) function randProbPrimeRounds(k,n) { var ans, i, divisible, B; B=30000; //B is largest prime to use in trial division ans=int2bigInt(0,k,0); //optimization: try larger and smaller B to find the best limit. if (primes.length==0) primes=findPrimes(30000); //check for divisibility by primes <=30000 if (rpprb.length!=ans.length) rpprb=dup(ans); for (;;) { //keep trying random values for ans until one appears to be prime //optimization: pick a random number times L=2*3*5*...*p, plus a // random element of the list of all numbers in [0,L) not divisible by any prime up to p. // This can reduce the amount of random number generation. randBigInt_(ans,k,0); //ans = a random odd number to check ans[0] |= 1; divisible=0; //check ans for divisibility by small primes up to B for (i=0; (iy.length ? x.length+1 : y.length+1)); sub_(ans,y); return trim(ans,1); } //return (x+y) for bigInts x and y. function add(x,y) { var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1)); add_(ans,y); return trim(ans,1); } //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null function inverseMod(x,n) { var ans=expand(x,n.length); var s; s=inverseMod_(ans,n); return s ? trim(ans,1) : null; } //return (x*y mod n) for bigInts x,y,n. For greater speed, let y= 2 if (s_i2.length!=ans.length) { s_i2=dup(ans); s_R =dup(ans); s_n1=dup(ans); s_r2=dup(ans); s_d =dup(ans); s_x1=dup(ans); s_x2=dup(ans); s_b =dup(ans); s_n =dup(ans); s_i =dup(ans); s_rm=dup(ans); s_q =dup(ans); s_a =dup(ans); s_aa=dup(ans); } if (k <= recLimit) { //generate small random primes by trial division up to its square root pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k) copyInt_(ans,0); for (dd=1;dd;) { dd=0; ans[0]= 1 | (1<<(k-1)) | randomBitInt(k); //random, k-bit, odd integer, with msb 1 for (j=1;(j2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits for (r=1; k-k*r<=m; ) r=pows[randomBitInt(9)]; //r=Math.pow(2,Math.random()-1); else r=0.5; //simulation suggests the more complex algorithm using r=.333 is only slightly faster. recSize=Math.floor(r*k)+1; randTruePrime_(s_q,recSize); copyInt_(s_i2,0); s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2) divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q)) z=bitSize(s_i); for (;;) { for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1] randBigInt_(s_R,z,0); if (greater(s_i,s_R)) break; } //now s_R is in the range [0,s_i-1] addInt_(s_R,1); //now s_R is in the range [1,s_i] add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i] copy_(s_n,s_q); mult_(s_n,s_R); multInt_(s_n,2); addInt_(s_n,1); //s_n=2*s_R*s_q+1 copy_(s_r2,s_R); multInt_(s_r2,2); //s_r2=2*s_R //check s_n for divisibility by small primes up to B for (divisible=0,j=0; (j0); j--); //strip leading zeros for (zz=0,w=s_n[j]; w; (w>>=1),zz++); zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1] randBigInt_(s_a,zz,0); if (greater(s_n,s_a)) break; } //now s_a is in the range [0,s_n-1] addInt_(s_n,3); //now s_a is in the range [0,s_n-4] addInt_(s_a,2); //now s_a is in the range [2,s_n-2] copy_(s_b,s_a); copy_(s_n1,s_n); addInt_(s_n1,-1); powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n addInt_(s_b,-1); if (isZero(s_b)) { copy_(s_b,s_a); powMod_(s_b,s_r2,s_n); addInt_(s_b,-1); copy_(s_aa,s_n); copy_(s_d,s_b); GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime if (equalsInt(s_d,1)) { copy_(ans,s_aa); return; //if we've made it this far, then s_n is absolutely guaranteed to be prime } } } } } //Return an n-bit random BigInt (n>=1). If s=1, then the most significant of those n bits is set to 1. function randBigInt(n,s) { var a,b; a=Math.floor((n-1)/bpe)+2; //# array elements to hold the BigInt with a leading 0 element b=int2bigInt(0,0,a); randBigInt_(b,n,s); return b; } //Set b to an n-bit random BigInt. If s=1, then the most significant of those n bits is set to 1. //Array b must be big enough to hold the result. Must have n>=1 function randBigInt_(b,n,s) { var i,a; for (i=0;i=0;i--); //find most significant element of x xp=x[i]; yp=y[i]; A=1; B=0; C=0; D=1; while ((yp+C) && (yp+D)) { q =Math.floor((xp+A)/(yp+C)); qp=Math.floor((xp+B)/(yp+D)); if (q!=qp) break; t= A-q*C; A=C; C=t; // do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp) t= B-q*D; B=D; D=t; t=xp-q*yp; xp=yp; yp=t; } if (B) { copy_(T,x); linComb_(x,y,A,B); //x=A*x+B*y linComb_(y,T,D,C); //y=D*y+C*T } else { mod_(x,y); copy_(T,x); copy_(x,y); copy_(y,T); } } if (y[0]==0) return; t=modInt(x,y[0]); copyInt_(x,y[0]); y[0]=t; while (y[0]) { x[0]%=y[0]; t=x[0]; x[0]=y[0]; y[0]=t; } } //do x=x**(-1) mod n, for bigInts x and n. //If no inverse exists, it sets x to zero and returns 0, else it returns 1. //The x array must be at least as large as the n array. function inverseMod_(x,n) { var k=1+2*Math.max(x.length,n.length); if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist copyInt_(x,0); return 0; } if (eg_u.length!=k) { eg_u=new Array(k); eg_v=new Array(k); eg_A=new Array(k); eg_B=new Array(k); eg_C=new Array(k); eg_D=new Array(k); } copy_(eg_u,x); copy_(eg_v,n); copyInt_(eg_A,1); copyInt_(eg_B,0); copyInt_(eg_C,0); copyInt_(eg_D,1); for (;;) { while(!(eg_u[0]&1)) { //while eg_u is even halve_(eg_u); if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2 halve_(eg_A); halve_(eg_B); } else { add_(eg_A,n); halve_(eg_A); sub_(eg_B,x); halve_(eg_B); } } while (!(eg_v[0]&1)) { //while eg_v is even halve_(eg_v); if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2 halve_(eg_C); halve_(eg_D); } else { add_(eg_C,n); halve_(eg_C); sub_(eg_D,x); halve_(eg_D); } } if (!greater(eg_v,eg_u)) { //eg_v <= eg_u sub_(eg_u,eg_v); sub_(eg_A,eg_C); sub_(eg_B,eg_D); } else { //eg_v > eg_u sub_(eg_v,eg_u); sub_(eg_C,eg_A); sub_(eg_D,eg_B); } if (equalsInt(eg_u,0)) { while (negative(eg_C)) //make sure answer is nonnegative add_(eg_C,n); copy_(x,eg_C); if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse copyInt_(x,0); return 0; } return 1; } } } //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse function inverseModInt(x,n) { var a=1,b=0,t; for (;;) { if (x==1) return a; if (x==0) return 0; b-=a*Math.floor(n/x); n%=x; if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to += if (n==0) return 0; a-=b*Math.floor(x/n); x%=n; } } //this deprecated function is for backward compatibility only. function inverseModInt_(x,n) { return inverseModInt(x,n); } //Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that: // v = GCD_(x,y) = a*x-b*y //The bigInts v, a, b, must have exactly as many elements as the larger of x and y. function eGCD_(x,y,v,a,b) { var g=0; var k=Math.max(x.length,y.length); if (eg_u.length!=k) { eg_u=new Array(k); eg_A=new Array(k); eg_B=new Array(k); eg_C=new Array(k); eg_D=new Array(k); } while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even halve_(x); halve_(y); g++; } copy_(eg_u,x); copy_(v,y); copyInt_(eg_A,1); copyInt_(eg_B,0); copyInt_(eg_C,0); copyInt_(eg_D,1); for (;;) { while(!(eg_u[0]&1)) { //while u is even halve_(eg_u); if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2 halve_(eg_A); halve_(eg_B); } else { add_(eg_A,y); halve_(eg_A); sub_(eg_B,x); halve_(eg_B); } } while (!(v[0]&1)) { //while v is even halve_(v); if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2 halve_(eg_C); halve_(eg_D); } else { add_(eg_C,y); halve_(eg_C); sub_(eg_D,x); halve_(eg_D); } } if (!greater(v,eg_u)) { //v<=u sub_(eg_u,v); sub_(eg_A,eg_C); sub_(eg_B,eg_D); } else { //v>u sub_(v,eg_u); sub_(eg_C,eg_A); sub_(eg_D,eg_B); } if (equalsInt(eg_u,0)) { while (negative(eg_C)) { //make sure a (C) is nonnegative add_(eg_C,y); sub_(eg_D,x); } multInt_(eg_D,-1); ///make sure b (D) is nonnegative copy_(a,eg_C); copy_(b,eg_D); leftShift_(v,g); return; } } } //is bigInt x negative? function negative(x) { return ((x[x.length-1]>>(bpe-1))&1); } //is (x << (shift*bpe)) > y? //x and y are nonnegative bigInts //shift is a nonnegative integer function greaterShift(x,y,shift) { var i, kx=x.length, ky=y.length; var k=((kx+shift)=0; i++) if (x[i]>0) return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger for (i=kx-1+shift; i0) return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger for (i=k-1; i>=shift; i--) if (x[i-shift]>y[i]) return 1; else if (x[i-shift] y? (x and y both nonnegative) function greater(x,y) { var i; var k=(x.length=0;i--) if (x[i]>y[i]) return 1; else if (x[i]= y.length >= 2. function divide_(x,y,q,r) { var kx, ky; var i,j,y1,y2,c,a,b; copy_(r,x); for (ky=y.length;y[ky-1]==0;ky--); //ky is number of elements in y, not including leading zeros //normalize: ensure the most significant element of y has its highest bit set b=y[ky-1]; for (a=0; b; a++) b>>=1; a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element leftShift_(y,a); //multiply both by 1<ky;kx--); //kx is number of elements in normalized x, not including leading zeros copyInt_(q,0); // q=0 while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) { subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky) q[kx-ky]++; // q[kx-ky]++; } // } for (i=kx-1; i>=ky; i--) { if (r[i]==y[ky-1]) q[i-ky]=mask; else q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]); //The following for(;;) loop is equivalent to the commented while loop, //except that the uncommented version avoids overflow. //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0 // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2]) // q[i-ky]--; for (;;) { y2=(ky>1 ? y[ky-2] : 0)*q[i-ky]; c=y2; y2=y2 & mask; c = (c - y2) / radix; y1=c+q[i-ky]*y[ky-1]; c=y1; y1=y1 & mask; c = (c - y1) / radix; if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i]) q[i-ky]--; else break; } linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky) if (negative(r)) { addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky) q[i-ky]--; } } rightShift_(y,a); //undo the normalization step rightShift_(r,a); //undo the normalization step } //do carries and borrows so each element of the bigInt x fits in bpe bits. function carry_(x) { var i,k,c,b; k=x.length; c=0; for (i=0;i=0; i--) c=(c*radix+x[i])%n; return c; } //convert the integer t into a bigInt with at least the given number of bits. //the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word) //Pad the array with leading zeros so that it has at least minSize elements. //There will always be at least one leading 0 element. function int2bigInt(t,bits,minSize) { var i,k, buff; k=Math.ceil(bits/bpe)+1; k=minSize>k ? minSize : k; buff=new Array(k); copyInt_(buff,t); return buff; } //return the bigInt given a string representation in a given base. //Pad the array with leading zeros so that it has at least minSize elements. //If base=-1, then it reads in a space-separated list of array elements in decimal. //The array will always have at least one leading zero, unless base=-1. function str2bigInt(s,base,minSize) { var d, i, j, x, y, kk; var k=s.length; if (base==-1) { //comma-separated list of array elements in decimal x=new Array(0); for (;;) { y=new Array(x.length+1); for (i=0;i 1) { if (bb & 1) p = 1; b += k; bb >>= 1; } b += p*k; x=int2bigInt(0,b,0); for (i=0;i=36) //convert lowercase to uppercase if base<=36 d-=26; if (d>=base || d<0) { //stop at first illegal character break; } multInt_(x,base); addInt_(x,d); } for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros k=minSize>k+1 ? minSize : k+1; y=new Array(k); kk=ky.length) { for (;i0;i--) s+=x[i]+','; s+=x[0]; } else { //return it in the given base while (!isZero(s6)) { t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base); s=digitsStr.substring(t,t+1)+s; } } if (s.length==0) s="0"; return s; } //returns a duplicate of bigInt x function dup(x) { var i, buff; buff=new Array(x.length); copy_(buff,x); return buff; } //do x=y on bigInts x and y. x must be an array at least as big as y (not counting the leading zeros in y). function copy_(x,y) { var i; var k=x.length>=bpe; } } //do x=x+n where x is a bigInt and n is an integer. //x must be large enough to hold the result. function addInt_(x,n) { var i,k,c,b; x[0]+=n; k=x.length; c=0; for (i=0;i>n)); } x[i]>>=n; } //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement function halve_(x) { var i; for (i=0;i>1)); } x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same } //left shift bigInt x by n bits. function leftShift_(x,n) { var i; var k=Math.floor(n/bpe); if (k) { for (i=x.length; i>=k; i--) //left shift x by k elements x[i]=x[i-k]; for (;i>=0;i--) x[i]=0; n%=bpe; } if (!n) return; for (i=x.length-1;i>0;i--) { x[i]=mask & ((x[i]<>(bpe-n))); } x[i]=mask & (x[i]<=0;i--) { s=r*radix+x[i]; x[i]=Math.floor(s/n); r=s%n; } return r; } //do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b. //x must be large enough to hold the answer. function linComb_(x,y,a,b) { var i,c,k,kk; k=x.length0 && !x[kx-1]; kx--); //ignore leading zeros in x k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n if (s0.length!=k) s0=new Array(k); copyInt_(s0,0); for (i=0;i0 && !x[i-1]; i--); y=new Array(i+k); copy_(y,x); return y; } //do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1. //this is faster when n is odd. x usually needs to have as many elements as n. function powMod_(x,y,n) { var k1,k2,kn,np; if(s7.length!=n.length) s7=dup(n); //for even modulus, use a simple square-and-multiply algorithm, //rather than using the more complex Montgomery algorithm. if ((n[0]&1)==0) { copy_(s7,x); copyInt_(x,1); while(!equalsInt(y,0)) { if (y[0]&1) multMod_(x,s7,n); divInt_(y,2); squareMod_(s7,n); } return; } //calculate np from n for the Montgomery multiplications copyInt_(s7,0); for (kn=n.length;kn>0 && !n[kn-1];kn--); np=radix-inverseModInt(modInt(n,radix),radix); s7[kn]=1; multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n if (s3.length!=x.length) s3=dup(x); else copy_(s3,x); for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y if (y[k1]==0) { //anything to the 0th power is 1 copyInt_(x,1); return; } for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1] for (;;) { if (!(k2>>=1)) { //look at next bit of y k1--; if (k1<0) { mont_(x,one,n,np); return; } k2=1<<(bpe-1); } mont_(x,x,n,np); if (k2 & y[k1]) //if next bit is a 1 mont_(x,s3,n,np); } } //do x=x*y*Ri mod n for bigInts x,y,n, // where Ri = 2**(-kn*bpe) mod n, and kn is the // number of elements in the n array, not // counting leading zeros. //x array must have at least as many elemnts as the n array //It's OK if x and y are the same variable. //must have: // x,y < n // n is odd // np = -(n^(-1)) mod radix function mont_(x,y,n,np) { var i,j,c,ui,t,t2,ks; var kn=n.length; var ky=y.length; if (sa.length!=kn) sa=new Array(kn); copyInt_(sa,0); for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y ks=sa.length-1; //sa will never have more than this many nonzero elements. //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large numbers for (i=0; i "\00" } return _num2bin }()) // serialize a bigInt to an ascii string // padded up to pad length function bigInt2bits(bi, pad) { pad || (pad = 0) bi = dup(bi) var ba = '' while (!isZero(bi)) { ba = _num2bin[bi[0] & 0xff] + ba rightShift_(bi, 8) } while (ba.length < pad) { ba = '\x00' + ba } return ba } // converts a byte array to a bigInt function ba2bigInt(data) { var mpi = str2bigInt('0', 10, data.length) data.forEach(function (d, i) { if (i) leftShift_(mpi, 8) mpi[0] |= d }) return mpi } // returns a function that returns an array of n bytes var randomBytes = (function () { // in node if ( typeof crypto !== 'undefined' && typeof crypto.randomBytes === 'function' ) { return function (n) { try { var buf = crypto.randomBytes(n) } catch (e) { throw e } return Array.prototype.slice.call(buf, 0) } } // in browser else if ( typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function' ) { return function (n) { var buf = new Uint8Array(n) crypto.getRandomValues(buf) return Array.prototype.slice.call(buf, 0) } } // err else { throw new Error('Keys should not be generated without CSPRNG.') } }()) // Salsa 20 in webworker needs a 40 byte seed function getSeed() { return randomBytes(40) } // returns a single random byte function randomByte() { return randomBytes(1)[0] } // returns a k-bit random integer function randomBitInt(k) { if (k > 31) throw new Error("Too many bits.") var i = 0, r = 0 var b = Math.floor(k / 8) var mask = (1 << (k % 8)) - 1 if (mask) r = randomByte() & mask for (; i < b; i++) r = (256 * r) + randomByte() return r } return { str2bigInt : str2bigInt , bigInt2str : bigInt2str , int2bigInt : int2bigInt , multMod : multMod , powMod : powMod , inverseMod : inverseMod , randBigInt : randBigInt , randBigInt_ : randBigInt_ , equals : equals , equalsInt : equalsInt , sub : sub , mod : mod , modInt : modInt , mult : mult , divInt_ : divInt_ , rightShift_ : rightShift_ , dup : dup , greater : greater , add : add , isZero : isZero , bitSize : bitSize , millerRabin : millerRabin , divide_ : divide_ , trim : trim , primes : primes , findPrimes : findPrimes , getSeed : getSeed , divMod : divMod , subMod : subMod , twoToThe : twoToThe , bigInt2bits : bigInt2bits , ba2bigInt : ba2bigInt } }))rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/otr.js0000644000076400007640000021111412572247340032237 0ustar pravipravi/*! otr.js v0.2.14 - 2015-01-16 (c) 2015 - Arlo Breault Freely distributed under the MPL v2.0 license. This file is concatenated for the browser. Please see: https://github.com/arlolra/otr */ ;(function (root, factory) { if (typeof define === 'function' && define.amd) { define([ "bigint" , "crypto" , "eventemitter" ], function (BigInt, CryptoJS, EventEmitter) { var root = { BigInt: BigInt , CryptoJS: CryptoJS , EventEmitter: EventEmitter , OTR: {} , DSA: {} } return factory.call(root) }) } else { root.OTR = {} root.DSA = {} factory.call(root) } }(this, function () { ;(function () { "use strict"; var root = this var CONST = { // diffie-heilman N : 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF' , G : '2' // otr message states , MSGSTATE_PLAINTEXT : 0 , MSGSTATE_ENCRYPTED : 1 , MSGSTATE_FINISHED : 2 // otr auth states , AUTHSTATE_NONE : 0 , AUTHSTATE_AWAITING_DHKEY : 1 , AUTHSTATE_AWAITING_REVEALSIG : 2 , AUTHSTATE_AWAITING_SIG : 3 // whitespace tags , WHITESPACE_TAG : '\x20\x09\x20\x20\x09\x09\x09\x09\x20\x09\x20\x09\x20\x09\x20\x20' , WHITESPACE_TAG_V2 : '\x20\x20\x09\x09\x20\x20\x09\x20' , WHITESPACE_TAG_V3 : '\x20\x20\x09\x09\x20\x20\x09\x09' // otr tags , OTR_TAG : '?OTR' , OTR_VERSION_1 : '\x00\x01' , OTR_VERSION_2 : '\x00\x02' , OTR_VERSION_3 : '\x00\x03' // smp machine states , SMPSTATE_EXPECT0 : 0 , SMPSTATE_EXPECT1 : 1 , SMPSTATE_EXPECT2 : 2 , SMPSTATE_EXPECT3 : 3 , SMPSTATE_EXPECT4 : 4 // unstandard status codes , STATUS_SEND_QUERY : 0 , STATUS_AKE_INIT : 1 , STATUS_AKE_SUCCESS : 2 , STATUS_END_OTR : 3 } if (typeof module !== 'undefined' && module.exports) { module.exports = CONST } else { root.OTR.CONST = CONST } }).call(this) ;(function () { "use strict"; var root = this var HLP = {}, CryptoJS, BigInt if (typeof module !== 'undefined' && module.exports) { module.exports = HLP = {} CryptoJS = require('../vendor/crypto.js') BigInt = require('../vendor/bigint.js') } else { if (root.OTR) root.OTR.HLP = HLP if (root.DSA) root.DSA.HLP = HLP CryptoJS = root.CryptoJS BigInt = root.BigInt } // data types (byte lengths) var DTS = { BYTE : 1 , SHORT : 2 , INT : 4 , CTR : 8 , MAC : 20 , SIG : 40 } // otr message wrapper begin and end var WRAPPER_BEGIN = "?OTR" , WRAPPER_END = "." var TWO = BigInt.str2bigInt('2', 10) HLP.debug = function (msg) { // used as HLP.debug.call(ctx, msg) if ( this.debug && typeof this.debug !== 'function' && typeof console !== 'undefined' ) console.log(msg) } HLP.extend = function (child, parent) { for (var key in parent) { if (Object.hasOwnProperty.call(parent, key)) child[key] = parent[key] } function Ctor() { this.constructor = child } Ctor.prototype = parent.prototype child.prototype = new Ctor() child.__super__ = parent.prototype } // assumes 32-bit function intCompare(x, y) { var z = ~(x ^ y) z &= z >> 16 z &= z >> 8 z &= z >> 4 z &= z >> 2 z &= z >> 1 return z & 1 } // constant-time string comparison HLP.compare = function (str1, str2) { if (str1.length !== str2.length) return false var i = 0, result = 0 for (; i < str1.length; i++) result |= str1[i].charCodeAt(0) ^ str2[i].charCodeAt(0) return intCompare(result, 0) } HLP.randomExponent = function () { return BigInt.randBigInt(1536) } HLP.smpHash = function (version, fmpi, smpi) { var sha256 = CryptoJS.algo.SHA256.create() sha256.update(CryptoJS.enc.Latin1.parse(HLP.packBytes(version, DTS.BYTE))) sha256.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(fmpi))) if (smpi) sha256.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(smpi))) var hash = sha256.finalize() return HLP.bits2bigInt(hash.toString(CryptoJS.enc.Latin1)) } HLP.makeMac = function (aesctr, m) { var pass = CryptoJS.enc.Latin1.parse(m) var mac = CryptoJS.HmacSHA256(CryptoJS.enc.Latin1.parse(aesctr), pass) return HLP.mask(mac.toString(CryptoJS.enc.Latin1), 0, 160) } HLP.make1Mac = function (aesctr, m) { var pass = CryptoJS.enc.Latin1.parse(m) var mac = CryptoJS.HmacSHA1(CryptoJS.enc.Latin1.parse(aesctr), pass) return mac.toString(CryptoJS.enc.Latin1) } HLP.encryptAes = function (msg, c, iv) { var opts = { mode: CryptoJS.mode.CTR , iv: CryptoJS.enc.Latin1.parse(iv) , padding: CryptoJS.pad.NoPadding } var aesctr = CryptoJS.AES.encrypt( msg , CryptoJS.enc.Latin1.parse(c) , opts ) var aesctr_decoded = CryptoJS.enc.Base64.parse(aesctr.toString()) return CryptoJS.enc.Latin1.stringify(aesctr_decoded) } HLP.decryptAes = function (msg, c, iv) { msg = CryptoJS.enc.Latin1.parse(msg) var opts = { mode: CryptoJS.mode.CTR , iv: CryptoJS.enc.Latin1.parse(iv) , padding: CryptoJS.pad.NoPadding } return CryptoJS.AES.decrypt( CryptoJS.enc.Base64.stringify(msg) , CryptoJS.enc.Latin1.parse(c) , opts ) } HLP.multPowMod = function (a, b, c, d, e) { return BigInt.multMod(BigInt.powMod(a, b, e), BigInt.powMod(c, d, e), e) } HLP.ZKP = function (v, c, d, e) { return BigInt.equals(c, HLP.smpHash(v, d, e)) } // greater than, or equal HLP.GTOE = function (a, b) { return (BigInt.equals(a, b) || BigInt.greater(a, b)) } HLP.between = function (x, a, b) { return (BigInt.greater(x, a) && BigInt.greater(b, x)) } HLP.checkGroup = function (g, N_MINUS_2) { return HLP.GTOE(g, TWO) && HLP.GTOE(N_MINUS_2, g) } HLP.h1 = function (b, secbytes) { var sha1 = CryptoJS.algo.SHA1.create() sha1.update(CryptoJS.enc.Latin1.parse(b)) sha1.update(CryptoJS.enc.Latin1.parse(secbytes)) return (sha1.finalize()).toString(CryptoJS.enc.Latin1) } HLP.h2 = function (b, secbytes) { var sha256 = CryptoJS.algo.SHA256.create() sha256.update(CryptoJS.enc.Latin1.parse(b)) sha256.update(CryptoJS.enc.Latin1.parse(secbytes)) return (sha256.finalize()).toString(CryptoJS.enc.Latin1) } HLP.mask = function (bytes, start, n) { return bytes.substr(start / 8, n / 8) } var _toString = String.fromCharCode; HLP.packBytes = function (val, bytes) { val = val.toString(16) var nex, res = '' // big-endian, unsigned long for (; bytes > 0; bytes--) { nex = val.length ? val.substr(-2, 2) : '0' val = val.substr(0, val.length - 2) res = _toString(parseInt(nex, 16)) + res } return res } HLP.packINT = function (d) { return HLP.packBytes(d, DTS.INT) } HLP.packCtr = function (d) { return HLP.padCtr(HLP.packBytes(d, DTS.CTR)) } HLP.padCtr = function (ctr) { return ctr + '\x00\x00\x00\x00\x00\x00\x00\x00' } HLP.unpackCtr = function (d) { d = HLP.toByteArray(d.substring(0, 8)) return HLP.unpack(d) } HLP.unpack = function (arr) { var val = 0, i = 0, len = arr.length for (; i < len; i++) { val = (val * 256) + arr[i] } return val } HLP.packData = function (d) { return HLP.packINT(d.length) + d } HLP.bits2bigInt = function (bits) { bits = HLP.toByteArray(bits) return BigInt.ba2bigInt(bits) } HLP.packMPI = function (mpi) { return HLP.packData(BigInt.bigInt2bits(BigInt.trim(mpi, 0))) } HLP.packSHORT = function (short) { return HLP.packBytes(short, DTS.SHORT) } HLP.unpackSHORT = function (short) { short = HLP.toByteArray(short) return HLP.unpack(short) } HLP.packTLV = function (type, value) { return HLP.packSHORT(type) + HLP.packSHORT(value.length) + value } HLP.readLen = function (msg) { msg = HLP.toByteArray(msg.substring(0, 4)) return HLP.unpack(msg) } HLP.readData = function (data) { var n = HLP.unpack(data.splice(0, 4)) return [n, data] } HLP.readMPI = function (data) { data = HLP.toByteArray(data) data = HLP.readData(data) return BigInt.ba2bigInt(data[1]) } HLP.packMPIs = function (arr) { return arr.reduce(function (prv, cur) { return prv + HLP.packMPI(cur) }, '') } HLP.unpackMPIs = function (num, mpis) { var i = 0, arr = [] for (; i < num; i++) arr.push('MPI') return (HLP.splitype(arr, mpis)).map(function (m) { return HLP.readMPI(m) }) } HLP.wrapMsg = function (msg, fs, v3, our_it, their_it) { msg = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Latin1.parse(msg)) msg = WRAPPER_BEGIN + ":" + msg + WRAPPER_END var its if (v3) { its = '|' its += (HLP.readLen(our_it)).toString(16) its += '|' its += (HLP.readLen(their_it)).toString(16) } if (!fs) return [null, msg] var n = Math.ceil(msg.length / fs) if (n > 65535) return ['Too many fragments'] if (n == 1) return [null, msg] var k, bi, ei, frag, mf, mfs = [] for (k = 1; k <= n; k++) { bi = (k - 1) * fs ei = k * fs frag = msg.slice(bi, ei) mf = WRAPPER_BEGIN if (v3) mf += its mf += ',' + k + ',' mf += n + ',' mf += frag + ',' mfs.push(mf) } return [null, mfs] } HLP.splitype = function splitype(arr, msg) { var data = [] arr.forEach(function (a) { var str switch (a) { case 'PUBKEY': str = splitype(['SHORT', 'MPI', 'MPI', 'MPI', 'MPI'], msg).join('') break case 'DATA': // falls through case 'MPI': str = msg.substring(0, HLP.readLen(msg) + 4) break default: str = msg.substring(0, DTS[a]) } data.push(str) msg = msg.substring(str.length) }) return data } // https://github.com/msgpack/msgpack-javascript/blob/master/msgpack.js var _bin2num = (function () { var i = 0, _bin2num = {} for (; i < 0x100; ++i) { _bin2num[String.fromCharCode(i)] = i // "\00" -> 0x00 } for (i = 0x80; i < 0x100; ++i) { // [Webkit][Gecko] _bin2num[String.fromCharCode(0xf700 + i)] = i // "\f780" -> 0x80 } return _bin2num }()) HLP.toByteArray = function (data) { var rv = [] , ary = data.split("") , i = -1 , iz = ary.length , remain = iz % 8 while (remain--) { ++i rv[i] = _bin2num[ary[i]] } remain = iz >> 3 while (remain--) { rv.push(_bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]], _bin2num[ary[++i]]) } return rv } }).call(this) ;(function () { "use strict"; var root = this var CryptoJS, BigInt, Worker, WWPath, HLP if (typeof module !== 'undefined' && module.exports) { module.exports = DSA CryptoJS = require('../vendor/crypto.js') BigInt = require('../vendor/bigint.js') WWPath = require('path').join(__dirname, '/dsa-webworker.js') HLP = require('./helpers.js') } else { // copy over and expose internals Object.keys(root.DSA).forEach(function (k) { DSA[k] = root.DSA[k] }) root.DSA = DSA CryptoJS = root.CryptoJS BigInt = root.BigInt Worker = root.Worker WWPath = 'dsa-webworker.js' HLP = DSA.HLP } var ZERO = BigInt.str2bigInt('0', 10) , ONE = BigInt.str2bigInt('1', 10) , TWO = BigInt.str2bigInt('2', 10) , KEY_TYPE = '\x00\x00' var DEBUG = false function timer() { var start = (new Date()).getTime() return function (s) { if (!DEBUG || typeof console === 'undefined') return var t = (new Date()).getTime() console.log(s + ': ' + (t - start)) start = t } } function makeRandom(min, max) { var c = BigInt.randBigInt(BigInt.bitSize(max)) if (!HLP.between(c, min, max)) return makeRandom(min, max) return c } // altered BigInt.randProbPrime() // n rounds of Miller Rabin (after trial division with small primes) var rpprb = [] function isProbPrime(k, n) { var i, B = 30000, l = BigInt.bitSize(k) var primes = BigInt.primes if (primes.length === 0) primes = BigInt.findPrimes(B) if (rpprb.length != k.length) rpprb = BigInt.dup(k) // check ans for divisibility by small primes up to B for (i = 0; (i < primes.length) && (primes[i] <= B); i++) if (BigInt.modInt(k, primes[i]) === 0 && !BigInt.equalsInt(k, primes[i])) return 0 // do n rounds of Miller Rabin, with random bases less than k for (i = 0; i < n; i++) { BigInt.randBigInt_(rpprb, l, 0) while(!BigInt.greater(k, rpprb)) // pick a random rpprb that's < k BigInt.randBigInt_(rpprb, l, 0) if (!BigInt.millerRabin(k, rpprb)) return 0 } return 1 } var bit_lengths = { '1024': { N: 160, repeat: 40 } // 40x should give 2^-80 confidence , '2048': { N: 224, repeat: 56 } } var primes = {} // follows go lang http://golang.org/src/pkg/crypto/dsa/dsa.go // fips version was removed in 0c99af0df3e7 function generatePrimes(bit_length) { var t = timer() // for debugging // number of MR tests to perform var repeat = bit_lengths[bit_length].repeat var N = bit_lengths[bit_length].N var LM1 = BigInt.twoToThe(bit_length - 1) var bl4 = 4 * bit_length var brk = false var q, p, rem, counter for (;;) { q = BigInt.randBigInt(N, 1) q[0] |= 1 if (!isProbPrime(q, repeat)) continue t('q') for (counter = 0; counter < bl4; counter++) { p = BigInt.randBigInt(bit_length, 1) p[0] |= 1 rem = BigInt.mod(p, q) rem = BigInt.sub(rem, ONE) p = BigInt.sub(p, rem) if (BigInt.greater(LM1, p)) continue if (!isProbPrime(p, repeat)) continue t('p') primes[bit_length] = { p: p, q: q } brk = true break } if (brk) break } var h = BigInt.dup(TWO) var pm1 = BigInt.sub(p, ONE) var e = BigInt.multMod(pm1, BigInt.inverseMod(q, p), p) var g for (;;) { g = BigInt.powMod(h, e, p) if (BigInt.equals(g, ONE)) { h = BigInt.add(h, ONE) continue } primes[bit_length].g = g t('g') return } throw new Error('Unreachable!') } function DSA(obj, opts) { if (!(this instanceof DSA)) return new DSA(obj, opts) // options opts = opts || {} // inherit if (obj) { var self = this ;['p', 'q', 'g', 'y', 'x'].forEach(function (prop) { self[prop] = obj[prop] }) this.type = obj.type || KEY_TYPE return } // default to 1024 var bit_length = parseInt(opts.bit_length ? opts.bit_length : 1024, 10) if (!bit_lengths[bit_length]) throw new Error('Unsupported bit length.') // set primes if (!primes[bit_length]) generatePrimes(bit_length) this.p = primes[bit_length].p this.q = primes[bit_length].q this.g = primes[bit_length].g // key type this.type = KEY_TYPE // private key this.x = makeRandom(ZERO, this.q) // public keys (p, q, g, y) this.y = BigInt.powMod(this.g, this.x, this.p) // nocache? if (opts.nocache) primes[bit_length] = null } DSA.prototype = { constructor: DSA, packPublic: function () { var str = this.type str += HLP.packMPI(this.p) str += HLP.packMPI(this.q) str += HLP.packMPI(this.g) str += HLP.packMPI(this.y) return str }, packPrivate: function () { var str = this.packPublic() + HLP.packMPI(this.x) str = CryptoJS.enc.Latin1.parse(str) return str.toString(CryptoJS.enc.Base64) }, // http://www.imperialviolet.org/2013/06/15/suddendeathentropy.html generateNonce: function (m) { var priv = BigInt.bigInt2bits(BigInt.trim(this.x, 0)) var rand = BigInt.bigInt2bits(BigInt.randBigInt(256)) var sha256 = CryptoJS.algo.SHA256.create() sha256.update(CryptoJS.enc.Latin1.parse(priv)) sha256.update(m) sha256.update(CryptoJS.enc.Latin1.parse(rand)) var hash = sha256.finalize() hash = HLP.bits2bigInt(hash.toString(CryptoJS.enc.Latin1)) BigInt.rightShift_(hash, 256 - BigInt.bitSize(this.q)) return HLP.between(hash, ZERO, this.q) ? hash : this.generateNonce(m) }, sign: function (m) { m = CryptoJS.enc.Latin1.parse(m) var b = BigInt.str2bigInt(m.toString(CryptoJS.enc.Hex), 16) var k, r = ZERO, s = ZERO while (BigInt.isZero(s) || BigInt.isZero(r)) { k = this.generateNonce(m) r = BigInt.mod(BigInt.powMod(this.g, k, this.p), this.q) if (BigInt.isZero(r)) continue s = BigInt.inverseMod(k, this.q) s = BigInt.mult(s, BigInt.add(b, BigInt.mult(this.x, r))) s = BigInt.mod(s, this.q) } return [r, s] }, fingerprint: function () { var pk = this.packPublic() if (this.type === KEY_TYPE) pk = pk.substring(2) pk = CryptoJS.enc.Latin1.parse(pk) return CryptoJS.SHA1(pk).toString(CryptoJS.enc.Hex) } } DSA.parsePublic = function (str, priv) { var fields = ['SHORT', 'MPI', 'MPI', 'MPI', 'MPI'] if (priv) fields.push('MPI') str = HLP.splitype(fields, str) var obj = { type: str[0] , p: HLP.readMPI(str[1]) , q: HLP.readMPI(str[2]) , g: HLP.readMPI(str[3]) , y: HLP.readMPI(str[4]) } if (priv) obj.x = HLP.readMPI(str[5]) return new DSA(obj) } function tokenizeStr(str) { var start, end start = str.indexOf("(") end = str.lastIndexOf(")") if (start < 0 || end < 0) throw new Error("Malformed S-Expression") str = str.substring(start + 1, end) var splt = str.search(/\s/) var obj = { type: str.substring(0, splt) , val: [] } str = str.substring(splt + 1, end) start = str.indexOf("(") if (start < 0) obj.val.push(str) else { var i, len, ss, es while (start > -1) { i = start + 1 len = str.length for (ss = 1, es = 0; i < len && es < ss; i++) { if (str[i] === "(") ss++ if (str[i] === ")") es++ } obj.val.push(tokenizeStr(str.substring(start, ++i))) str = str.substring(++i) start = str.indexOf("(") } } return obj } function parseLibotr(obj) { if (!obj.type) throw new Error("Parse error.") var o, val if (obj.type === "privkeys") { o = [] obj.val.forEach(function (i) { o.push(parseLibotr(i)) }) return o } o = {} obj.val.forEach(function (i) { val = i.val[0] if (typeof val === "string") { if (val.indexOf("#") === 0) { val = val.substring(1, val.lastIndexOf("#")) val = BigInt.str2bigInt(val, 16) } } else { val = parseLibotr(i) } o[i.type] = val }) return o } DSA.parsePrivate = function (str, libotr) { if (!libotr) { str = CryptoJS.enc.Base64.parse(str) str = str.toString(CryptoJS.enc.Latin1) return DSA.parsePublic(str, true) } // only returning the first key found return parseLibotr(tokenizeStr(str))[0]["private-key"].dsa } DSA.verify = function (key, m, r, s) { if (!HLP.between(r, ZERO, key.q) || !HLP.between(s, ZERO, key.q)) return false var hm = CryptoJS.enc.Latin1.parse(m) // CryptoJS.SHA1(m) hm = BigInt.str2bigInt(hm.toString(CryptoJS.enc.Hex), 16) var w = BigInt.inverseMod(s, key.q) var u1 = BigInt.multMod(hm, w, key.q) var u2 = BigInt.multMod(r, w, key.q) u1 = BigInt.powMod(key.g, u1, key.p) u2 = BigInt.powMod(key.y, u2, key.p) var v = BigInt.mod(BigInt.multMod(u1, u2, key.p), key.q) return BigInt.equals(v, r) } DSA.createInWebWorker = function (options, cb) { var opts = { path: WWPath , seed: BigInt.getSeed } if (options && typeof options === 'object') Object.keys(options).forEach(function (k) { opts[k] = options[k] }) // load optional dep. in node if (typeof module !== 'undefined' && module.exports) Worker = require('webworker-threads').Worker var worker = new Worker(opts.path) worker.onmessage = function (e) { var data = e.data switch (data.type) { case "debug": if (!DEBUG || typeof console === 'undefined') return console.log(data.val) break; case "data": worker.terminate() cb(DSA.parsePrivate(data.val)) break; default: throw new Error("Unrecognized type.") } } worker.postMessage({ seed: opts.seed() , imports: opts.imports , debug: DEBUG }) } }).call(this) ;(function () { "use strict"; var root = this var Parse = {}, CryptoJS, CONST, HLP if (typeof module !== 'undefined' && module.exports) { module.exports = Parse CryptoJS = require('../vendor/crypto.js') CONST = require('./const.js') HLP = require('./helpers.js') } else { root.OTR.Parse = Parse CryptoJS = root.CryptoJS CONST = root.OTR.CONST HLP = root.OTR.HLP } // whitespace tags var tags = {} tags[CONST.WHITESPACE_TAG_V2] = CONST.OTR_VERSION_2 tags[CONST.WHITESPACE_TAG_V3] = CONST.OTR_VERSION_3 Parse.parseMsg = function (otr, msg) { var ver = [] // is this otr? var start = msg.indexOf(CONST.OTR_TAG) if (!~start) { // restart fragments this.initFragment(otr) // whitespace tags ind = msg.indexOf(CONST.WHITESPACE_TAG) if (~ind) { msg = msg.split('') msg.splice(ind, 16) var tag, len = msg.length for (; ind < len;) { tag = msg.slice(ind, ind + 8).join('') if (Object.hasOwnProperty.call(tags, tag)) { msg.splice(ind, 8) ver.push(tags[tag]) continue } ind += 8 } msg = msg.join('') } return { msg: msg, ver: ver } } var ind = start + CONST.OTR_TAG.length var com = msg[ind] // message fragment if (com === ',' || com === '|') { return this.msgFragment(otr, msg.substring(ind + 1), (com === '|')) } this.initFragment(otr) // query message if (~['?', 'v'].indexOf(com)) { // version 1 if (msg[ind] === '?') { ver.push(CONST.OTR_VERSION_1) ind += 1 } // other versions var vers = { '2': CONST.OTR_VERSION_2 , '3': CONST.OTR_VERSION_3 } var qs = msg.substring(ind + 1) var qi = qs.indexOf('?') if (qi >= 1) { qs = qs.substring(0, qi).split('') if (msg[ind] === 'v') { qs.forEach(function (q) { if (Object.hasOwnProperty.call(vers, q)) ver.push(vers[q]) }) } } return { cls: 'query', ver: ver } } // otr message if (com === ':') { ind += 1 var info = msg.substring(ind, ind + 4) if (info.length < 4) return { msg: msg } info = CryptoJS.enc.Base64.parse(info).toString(CryptoJS.enc.Latin1) var version = info.substring(0, 2) var type = info.substring(2) // supporting otr versions 2 and 3 if (!otr['ALLOW_V' + HLP.unpackSHORT(version)]) return { msg: msg } ind += 4 var end = msg.substring(ind).indexOf('.') if (!~end) return { msg: msg } msg = CryptoJS.enc.Base64.parse(msg.substring(ind, ind + end)) msg = CryptoJS.enc.Latin1.stringify(msg) // instance tags var instance_tags if (version === CONST.OTR_VERSION_3) { instance_tags = msg.substring(0, 8) msg = msg.substring(8) } var cls if (~['\x02', '\x0a', '\x11', '\x12'].indexOf(type)) { cls = 'ake' } else if (type === '\x03') { cls = 'data' } return { version: version , type: type , msg: msg , cls: cls , instance_tags: instance_tags } } // error message if (msg.substring(ind, ind + 7) === ' Error:') { if (otr.ERROR_START_AKE) { otr.sendQueryMsg() } return { msg: msg.substring(ind + 7), cls: 'error' } } return { msg: msg } } Parse.initFragment = function (otr) { otr.fragment = { s: '', j: 0, k: 0 } } Parse.msgFragment = function (otr, msg, v3) { msg = msg.split(',') // instance tags if (v3) { var its = msg.shift().split('|') var their_it = HLP.packINT(parseInt(its[0], 16)) var our_it = HLP.packINT(parseInt(its[1], 16)) if (otr.checkInstanceTags(their_it + our_it)) return // ignore } if (msg.length < 4 || isNaN(parseInt(msg[0], 10)) || isNaN(parseInt(msg[1], 10)) ) return var k = parseInt(msg[0], 10) var n = parseInt(msg[1], 10) msg = msg[2] if (n < k || n === 0 || k === 0) { this.initFragment(otr) return } if (k === 1) { this.initFragment(otr) otr.fragment = { k: 1, n: n, s: msg } } else if (n === otr.fragment.n && k === (otr.fragment.k + 1)) { otr.fragment.s += msg otr.fragment.k += 1 } else { this.initFragment(otr) } if (n === k) { msg = otr.fragment.s this.initFragment(otr) return this.parseMsg(otr, msg) } return } }).call(this) ;(function () { "use strict"; var root = this var CryptoJS, BigInt, CONST, HLP, DSA if (typeof module !== 'undefined' && module.exports) { module.exports = AKE CryptoJS = require('../vendor/crypto.js') BigInt = require('../vendor/bigint.js') CONST = require('./const.js') HLP = require('./helpers.js') DSA = require('./dsa.js') } else { root.OTR.AKE = AKE CryptoJS = root.CryptoJS BigInt = root.BigInt CONST = root.OTR.CONST HLP = root.OTR.HLP DSA = root.DSA } // diffie-hellman modulus // see group 5, RFC 3526 var N = BigInt.str2bigInt(CONST.N, 16) var N_MINUS_2 = BigInt.sub(N, BigInt.str2bigInt('2', 10)) function hMac(gx, gy, pk, kid, m) { var pass = CryptoJS.enc.Latin1.parse(m) var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, pass) hmac.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(gx))) hmac.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(gy))) hmac.update(CryptoJS.enc.Latin1.parse(pk)) hmac.update(CryptoJS.enc.Latin1.parse(kid)) return (hmac.finalize()).toString(CryptoJS.enc.Latin1) } // AKE constructor function AKE(otr) { if (!(this instanceof AKE)) return new AKE(otr) // otr instance this.otr = otr // our keys this.our_dh = otr.our_old_dh this.our_keyid = otr.our_keyid - 1 // their keys this.their_y = null this.their_keyid = null this.their_priv_pk = null // state this.ssid = null this.transmittedRS = false this.r = null // bind methods var self = this ;['sendMsg'].forEach(function (meth) { self[meth] = self[meth].bind(self) }) } AKE.prototype = { constructor: AKE, createKeys: function(g) { var s = BigInt.powMod(g, this.our_dh.privateKey, N) var secbytes = HLP.packMPI(s) this.ssid = HLP.mask(HLP.h2('\x00', secbytes), 0, 64) // first 64-bits var tmp = HLP.h2('\x01', secbytes) this.c = HLP.mask(tmp, 0, 128) // first 128-bits this.c_prime = HLP.mask(tmp, 128, 128) // second 128-bits this.m1 = HLP.h2('\x02', secbytes) this.m2 = HLP.h2('\x03', secbytes) this.m1_prime = HLP.h2('\x04', secbytes) this.m2_prime = HLP.h2('\x05', secbytes) }, verifySignMac: function (mac, aesctr, m2, c, their_y, our_dh_pk, m1, ctr) { // verify mac var vmac = HLP.makeMac(aesctr, m2) if (!HLP.compare(mac, vmac)) return ['MACs do not match.'] // decrypt x var x = HLP.decryptAes(aesctr.substring(4), c, ctr) x = HLP.splitype(['PUBKEY', 'INT', 'SIG'], x.toString(CryptoJS.enc.Latin1)) var m = hMac(their_y, our_dh_pk, x[0], x[1], m1) var pub = DSA.parsePublic(x[0]) var r = HLP.bits2bigInt(x[2].substring(0, 20)) var s = HLP.bits2bigInt(x[2].substring(20)) // verify sign m if (!DSA.verify(pub, m, r, s)) return ['Cannot verify signature of m.'] return [null, HLP.readLen(x[1]), pub] }, makeM: function (their_y, m1, c, m2) { var pk = this.otr.priv.packPublic() var kid = HLP.packINT(this.our_keyid) var m = hMac(this.our_dh.publicKey, their_y, pk, kid, m1) m = this.otr.priv.sign(m) var msg = pk + kid msg += BigInt.bigInt2bits(m[0], 20) // pad to 20 bytes msg += BigInt.bigInt2bits(m[1], 20) msg = CryptoJS.enc.Latin1.parse(msg) var aesctr = HLP.packData(HLP.encryptAes(msg, c, HLP.packCtr(0))) var mac = HLP.makeMac(aesctr, m2) return aesctr + mac }, akeSuccess: function (version) { HLP.debug.call(this.otr, 'success') if (BigInt.equals(this.their_y, this.our_dh.publicKey)) return this.otr.error('equal keys - we have a problem.') this.otr.our_old_dh = this.our_dh this.otr.their_priv_pk = this.their_priv_pk if (!( (this.their_keyid === this.otr.their_keyid && BigInt.equals(this.their_y, this.otr.their_y)) || (this.their_keyid === (this.otr.their_keyid - 1) && BigInt.equals(this.their_y, this.otr.their_old_y)) )) { this.otr.their_y = this.their_y this.otr.their_old_y = null this.otr.their_keyid = this.their_keyid // rotate keys this.otr.sessKeys[0] = [ new this.otr.DHSession( this.otr.our_dh , this.otr.their_y ), null ] this.otr.sessKeys[1] = [ new this.otr.DHSession( this.otr.our_old_dh , this.otr.their_y ), null ] } // ake info this.otr.ssid = this.ssid this.otr.transmittedRS = this.transmittedRS this.otr_version = version // go encrypted this.otr.authstate = CONST.AUTHSTATE_NONE this.otr.msgstate = CONST.MSGSTATE_ENCRYPTED // null out values this.r = null this.myhashed = null this.dhcommit = null this.encrypted = null this.hashed = null this.otr.trigger('status', [CONST.STATUS_AKE_SUCCESS]) // send stored msgs this.otr.sendStored() }, handleAKE: function (msg) { var send, vsm, type var version = msg.version switch (msg.type) { case '\x02': HLP.debug.call(this.otr, 'd-h key message') msg = HLP.splitype(['DATA', 'DATA'], msg.msg) if (this.otr.authstate === CONST.AUTHSTATE_AWAITING_DHKEY) { var ourHash = HLP.readMPI(this.myhashed) var theirHash = HLP.readMPI(msg[1]) if (BigInt.greater(ourHash, theirHash)) { type = '\x02' send = this.dhcommit break // ignore } else { // forget this.our_dh = this.otr.dh() this.otr.authstate = CONST.AUTHSTATE_NONE this.r = null this.myhashed = null } } else if ( this.otr.authstate === CONST.AUTHSTATE_AWAITING_SIG ) this.our_dh = this.otr.dh() this.otr.authstate = CONST.AUTHSTATE_AWAITING_REVEALSIG this.encrypted = msg[0].substring(4) this.hashed = msg[1].substring(4) type = '\x0a' send = HLP.packMPI(this.our_dh.publicKey) break case '\x0a': HLP.debug.call(this.otr, 'reveal signature message') msg = HLP.splitype(['MPI'], msg.msg) if (this.otr.authstate !== CONST.AUTHSTATE_AWAITING_DHKEY) { if (this.otr.authstate === CONST.AUTHSTATE_AWAITING_SIG) { if (!BigInt.equals(this.their_y, HLP.readMPI(msg[0]))) return } else { return // ignore } } this.otr.authstate = CONST.AUTHSTATE_AWAITING_SIG this.their_y = HLP.readMPI(msg[0]) // verify gy is legal 2 <= gy <= N-2 if (!HLP.checkGroup(this.their_y, N_MINUS_2)) return this.otr.error('Illegal g^y.') this.createKeys(this.their_y) type = '\x11' send = HLP.packMPI(this.r) send += this.makeM(this.their_y, this.m1, this.c, this.m2) this.m1 = null this.m2 = null this.c = null break case '\x11': HLP.debug.call(this.otr, 'signature message') if (this.otr.authstate !== CONST.AUTHSTATE_AWAITING_REVEALSIG) return // ignore msg = HLP.splitype(['DATA', 'DATA', 'MAC'], msg.msg) this.r = HLP.readMPI(msg[0]) // decrypt their_y var key = CryptoJS.enc.Hex.parse(BigInt.bigInt2str(this.r, 16)) key = CryptoJS.enc.Latin1.stringify(key) var gxmpi = HLP.decryptAes(this.encrypted, key, HLP.packCtr(0)) gxmpi = gxmpi.toString(CryptoJS.enc.Latin1) this.their_y = HLP.readMPI(gxmpi) // verify hash var hash = CryptoJS.SHA256(CryptoJS.enc.Latin1.parse(gxmpi)) if (!HLP.compare(this.hashed, hash.toString(CryptoJS.enc.Latin1))) return this.otr.error('Hashed g^x does not match.') // verify gx is legal 2 <= g^x <= N-2 if (!HLP.checkGroup(this.their_y, N_MINUS_2)) return this.otr.error('Illegal g^x.') this.createKeys(this.their_y) vsm = this.verifySignMac( msg[2] , msg[1] , this.m2 , this.c , this.their_y , this.our_dh.publicKey , this.m1 , HLP.packCtr(0) ) if (vsm[0]) return this.otr.error(vsm[0]) // store their key this.their_keyid = vsm[1] this.their_priv_pk = vsm[2] send = this.makeM( this.their_y , this.m1_prime , this.c_prime , this.m2_prime ) this.m1 = null this.m2 = null this.m1_prime = null this.m2_prime = null this.c = null this.c_prime = null this.sendMsg(version, '\x12', send) this.akeSuccess(version) return case '\x12': HLP.debug.call(this.otr, 'data message') if (this.otr.authstate !== CONST.AUTHSTATE_AWAITING_SIG) return // ignore msg = HLP.splitype(['DATA', 'MAC'], msg.msg) vsm = this.verifySignMac( msg[1] , msg[0] , this.m2_prime , this.c_prime , this.their_y , this.our_dh.publicKey , this.m1_prime , HLP.packCtr(0) ) if (vsm[0]) return this.otr.error(vsm[0]) // store their key this.their_keyid = vsm[1] this.their_priv_pk = vsm[2] this.m1_prime = null this.m2_prime = null this.c_prime = null this.transmittedRS = true this.akeSuccess(version) return default: return // ignore } this.sendMsg(version, type, send) }, sendMsg: function (version, type, msg) { var send = version + type var v3 = (version === CONST.OTR_VERSION_3) // instance tags for v3 if (v3) { HLP.debug.call(this.otr, 'instance tags') send += this.otr.our_instance_tag send += this.otr.their_instance_tag } send += msg // fragment message if necessary send = HLP.wrapMsg( send , this.otr.fragment_size , v3 , this.otr.our_instance_tag , this.otr.their_instance_tag ) if (send[0]) return this.otr.error(send[0]) this.otr.io(send[1]) }, initiateAKE: function (version) { HLP.debug.call(this.otr, 'd-h commit message') this.otr.trigger('status', [CONST.STATUS_AKE_INIT]) this.otr.authstate = CONST.AUTHSTATE_AWAITING_DHKEY var gxmpi = HLP.packMPI(this.our_dh.publicKey) gxmpi = CryptoJS.enc.Latin1.parse(gxmpi) this.r = BigInt.randBigInt(128) var key = CryptoJS.enc.Hex.parse(BigInt.bigInt2str(this.r, 16)) key = CryptoJS.enc.Latin1.stringify(key) this.myhashed = CryptoJS.SHA256(gxmpi) this.myhashed = HLP.packData(this.myhashed.toString(CryptoJS.enc.Latin1)) this.dhcommit = HLP.packData(HLP.encryptAes(gxmpi, key, HLP.packCtr(0))) this.dhcommit += this.myhashed this.sendMsg(version, '\x02', this.dhcommit) } } }).call(this) ;(function () { "use strict"; var root = this var CryptoJS, BigInt, EventEmitter, CONST, HLP if (typeof module !== 'undefined' && module.exports) { module.exports = SM CryptoJS = require('../vendor/crypto.js') BigInt = require('../vendor/bigint.js') EventEmitter = require('../vendor/eventemitter.js') CONST = require('./const.js') HLP = require('./helpers.js') } else { root.OTR.SM = SM CryptoJS = root.CryptoJS BigInt = root.BigInt EventEmitter = root.EventEmitter CONST = root.OTR.CONST HLP = root.OTR.HLP } // diffie-hellman modulus and generator // see group 5, RFC 3526 var G = BigInt.str2bigInt(CONST.G, 10) var N = BigInt.str2bigInt(CONST.N, 16) var N_MINUS_2 = BigInt.sub(N, BigInt.str2bigInt('2', 10)) // to calculate D's for zero-knowledge proofs var Q = BigInt.sub(N, BigInt.str2bigInt('1', 10)) BigInt.divInt_(Q, 2) // meh function SM(reqs) { if (!(this instanceof SM)) return new SM(reqs) this.version = 1 this.our_fp = reqs.our_fp this.their_fp = reqs.their_fp this.ssid = reqs.ssid this.debug = !!reqs.debug // initial state this.init() } // inherit from EE HLP.extend(SM, EventEmitter) // set the initial values // also used when aborting SM.prototype.init = function () { this.smpstate = CONST.SMPSTATE_EXPECT1 this.secret = null } SM.prototype.makeSecret = function (our, secret) { var sha256 = CryptoJS.algo.SHA256.create() sha256.update(CryptoJS.enc.Latin1.parse(HLP.packBytes(this.version, 1))) sha256.update(CryptoJS.enc.Hex.parse(our ? this.our_fp : this.their_fp)) sha256.update(CryptoJS.enc.Hex.parse(our ? this.their_fp : this.our_fp)) sha256.update(CryptoJS.enc.Latin1.parse(this.ssid)) sha256.update(CryptoJS.enc.Latin1.parse(secret)) var hash = sha256.finalize() this.secret = HLP.bits2bigInt(hash.toString(CryptoJS.enc.Latin1)) } SM.prototype.makeG2s = function () { this.a2 = HLP.randomExponent() this.a3 = HLP.randomExponent() this.g2a = BigInt.powMod(G, this.a2, N) this.g3a = BigInt.powMod(G, this.a3, N) if ( !HLP.checkGroup(this.g2a, N_MINUS_2) || !HLP.checkGroup(this.g3a, N_MINUS_2) ) this.makeG2s() } SM.prototype.computeGs = function (g2a, g3a) { this.g2 = BigInt.powMod(g2a, this.a2, N) this.g3 = BigInt.powMod(g3a, this.a3, N) } SM.prototype.computePQ = function (r) { this.p = BigInt.powMod(this.g3, r, N) this.q = HLP.multPowMod(G, r, this.g2, this.secret, N) } SM.prototype.computeR = function () { this.r = BigInt.powMod(this.QoQ, this.a3, N) } SM.prototype.computeRab = function (r) { return BigInt.powMod(r, this.a3, N) } SM.prototype.computeC = function (v, r) { return HLP.smpHash(v, BigInt.powMod(G, r, N)) } SM.prototype.computeD = function (r, a, c) { return BigInt.subMod(r, BigInt.multMod(a, c, Q), Q) } // the bulk of the work SM.prototype.handleSM = function (msg) { var send, r2, r3, r7, t1, t2, t3, t4, rab, tmp2, cR, d7, ms, trust var expectStates = { 2: CONST.SMPSTATE_EXPECT1 , 3: CONST.SMPSTATE_EXPECT2 , 4: CONST.SMPSTATE_EXPECT3 , 5: CONST.SMPSTATE_EXPECT4 , 7: CONST.SMPSTATE_EXPECT1 } if (msg.type === 6) { this.init() this.trigger('abort') return } // abort! there was an error if (this.smpstate !== expectStates[msg.type]) return this.abort() switch (this.smpstate) { case CONST.SMPSTATE_EXPECT1: HLP.debug.call(this, 'smp tlv 2') // user specified question var ind, question if (msg.type === 7) { ind = msg.msg.indexOf('\x00') question = msg.msg.substring(0, ind) msg.msg = msg.msg.substring(ind + 1) } // 0:g2a, 1:c2, 2:d2, 3:g3a, 4:c3, 5:d3 ms = HLP.readLen(msg.msg.substr(0, 4)) if (ms !== 6) return this.abort() msg = HLP.unpackMPIs(6, msg.msg.substring(4)) if ( !HLP.checkGroup(msg[0], N_MINUS_2) || !HLP.checkGroup(msg[3], N_MINUS_2) ) return this.abort() // verify znp's if (!HLP.ZKP(1, msg[1], HLP.multPowMod(G, msg[2], msg[0], msg[1], N))) return this.abort() if (!HLP.ZKP(2, msg[4], HLP.multPowMod(G, msg[5], msg[3], msg[4], N))) return this.abort() this.g3ao = msg[3] // save for later this.makeG2s() // zero-knowledge proof that the exponents // associated with g2a & g3a are known r2 = HLP.randomExponent() r3 = HLP.randomExponent() this.c2 = this.computeC(3, r2) this.c3 = this.computeC(4, r3) this.d2 = this.computeD(r2, this.a2, this.c2) this.d3 = this.computeD(r3, this.a3, this.c3) this.computeGs(msg[0], msg[3]) this.smpstate = CONST.SMPSTATE_EXPECT0 if (question) { // assume utf8 question question = CryptoJS.enc.Latin1 .parse(question) .toString(CryptoJS.enc.Utf8) } // invoke question this.trigger('question', [question]) return case CONST.SMPSTATE_EXPECT2: HLP.debug.call(this, 'smp tlv 3') // 0:g2a, 1:c2, 2:d2, 3:g3a, 4:c3, 5:d3, 6:p, 7:q, 8:cP, 9:d5, 10:d6 ms = HLP.readLen(msg.msg.substr(0, 4)) if (ms !== 11) return this.abort() msg = HLP.unpackMPIs(11, msg.msg.substring(4)) if ( !HLP.checkGroup(msg[0], N_MINUS_2) || !HLP.checkGroup(msg[3], N_MINUS_2) || !HLP.checkGroup(msg[6], N_MINUS_2) || !HLP.checkGroup(msg[7], N_MINUS_2) ) return this.abort() // verify znp of c3 / c3 if (!HLP.ZKP(3, msg[1], HLP.multPowMod(G, msg[2], msg[0], msg[1], N))) return this.abort() if (!HLP.ZKP(4, msg[4], HLP.multPowMod(G, msg[5], msg[3], msg[4], N))) return this.abort() this.g3ao = msg[3] // save for later this.computeGs(msg[0], msg[3]) // verify znp of cP t1 = HLP.multPowMod(this.g3, msg[9], msg[6], msg[8], N) t2 = HLP.multPowMod(G, msg[9], this.g2, msg[10], N) t2 = BigInt.multMod(t2, BigInt.powMod(msg[7], msg[8], N), N) if (!HLP.ZKP(5, msg[8], t1, t2)) return this.abort() var r4 = HLP.randomExponent() this.computePQ(r4) // zero-knowledge proof that P & Q // were generated according to the protocol var r5 = HLP.randomExponent() var r6 = HLP.randomExponent() var tmp = HLP.multPowMod(G, r5, this.g2, r6, N) var cP = HLP.smpHash(6, BigInt.powMod(this.g3, r5, N), tmp) var d5 = this.computeD(r5, r4, cP) var d6 = this.computeD(r6, this.secret, cP) // store these this.QoQ = BigInt.divMod(this.q, msg[7], N) this.PoP = BigInt.divMod(this.p, msg[6], N) this.computeR() // zero-knowledge proof that R // was generated according to the protocol r7 = HLP.randomExponent() tmp2 = BigInt.powMod(this.QoQ, r7, N) cR = HLP.smpHash(7, BigInt.powMod(G, r7, N), tmp2) d7 = this.computeD(r7, this.a3, cR) this.smpstate = CONST.SMPSTATE_EXPECT4 send = HLP.packINT(8) + HLP.packMPIs([ this.p , this.q , cP , d5 , d6 , this.r , cR , d7 ]) // TLV send = HLP.packTLV(4, send) break case CONST.SMPSTATE_EXPECT3: HLP.debug.call(this, 'smp tlv 4') // 0:p, 1:q, 2:cP, 3:d5, 4:d6, 5:r, 6:cR, 7:d7 ms = HLP.readLen(msg.msg.substr(0, 4)) if (ms !== 8) return this.abort() msg = HLP.unpackMPIs(8, msg.msg.substring(4)) if ( !HLP.checkGroup(msg[0], N_MINUS_2) || !HLP.checkGroup(msg[1], N_MINUS_2) || !HLP.checkGroup(msg[5], N_MINUS_2) ) return this.abort() // verify znp of cP t1 = HLP.multPowMod(this.g3, msg[3], msg[0], msg[2], N) t2 = HLP.multPowMod(G, msg[3], this.g2, msg[4], N) t2 = BigInt.multMod(t2, BigInt.powMod(msg[1], msg[2], N), N) if (!HLP.ZKP(6, msg[2], t1, t2)) return this.abort() // verify znp of cR t3 = HLP.multPowMod(G, msg[7], this.g3ao, msg[6], N) this.QoQ = BigInt.divMod(msg[1], this.q, N) // save Q over Q t4 = HLP.multPowMod(this.QoQ, msg[7], msg[5], msg[6], N) if (!HLP.ZKP(7, msg[6], t3, t4)) return this.abort() this.computeR() // zero-knowledge proof that R // was generated according to the protocol r7 = HLP.randomExponent() tmp2 = BigInt.powMod(this.QoQ, r7, N) cR = HLP.smpHash(8, BigInt.powMod(G, r7, N), tmp2) d7 = this.computeD(r7, this.a3, cR) send = HLP.packINT(3) + HLP.packMPIs([ this.r, cR, d7 ]) send = HLP.packTLV(5, send) rab = this.computeRab(msg[5]) trust = !!BigInt.equals(rab, BigInt.divMod(msg[0], this.p, N)) this.trigger('trust', [trust, 'answered']) this.init() break case CONST.SMPSTATE_EXPECT4: HLP.debug.call(this, 'smp tlv 5') // 0:r, 1:cR, 2:d7 ms = HLP.readLen(msg.msg.substr(0, 4)) if (ms !== 3) return this.abort() msg = HLP.unpackMPIs(3, msg.msg.substring(4)) if (!HLP.checkGroup(msg[0], N_MINUS_2)) return this.abort() // verify znp of cR t3 = HLP.multPowMod(G, msg[2], this.g3ao, msg[1], N) t4 = HLP.multPowMod(this.QoQ, msg[2], msg[0], msg[1], N) if (!HLP.ZKP(8, msg[1], t3, t4)) return this.abort() rab = this.computeRab(msg[0]) trust = !!BigInt.equals(rab, this.PoP) this.trigger('trust', [trust, 'asked']) this.init() return } this.sendMsg(send) } // send a message SM.prototype.sendMsg = function (send) { this.trigger('send', [this.ssid, '\x00' + send]) } SM.prototype.rcvSecret = function (secret, question) { HLP.debug.call(this, 'receive secret') var fn, our = false if (this.smpstate === CONST.SMPSTATE_EXPECT0) { fn = this.answer } else { fn = this.initiate our = true } this.makeSecret(our, secret) fn.call(this, question) } SM.prototype.answer = function () { HLP.debug.call(this, 'smp answer') var r4 = HLP.randomExponent() this.computePQ(r4) // zero-knowledge proof that P & Q // were generated according to the protocol var r5 = HLP.randomExponent() var r6 = HLP.randomExponent() var tmp = HLP.multPowMod(G, r5, this.g2, r6, N) var cP = HLP.smpHash(5, BigInt.powMod(this.g3, r5, N), tmp) var d5 = this.computeD(r5, r4, cP) var d6 = this.computeD(r6, this.secret, cP) this.smpstate = CONST.SMPSTATE_EXPECT3 var send = HLP.packINT(11) + HLP.packMPIs([ this.g2a , this.c2 , this.d2 , this.g3a , this.c3 , this.d3 , this.p , this.q , cP , d5 , d6 ]) this.sendMsg(HLP.packTLV(3, send)) } SM.prototype.initiate = function (question) { HLP.debug.call(this, 'smp initiate') if (this.smpstate !== CONST.SMPSTATE_EXPECT1) this.abort() // abort + restart this.makeG2s() // zero-knowledge proof that the exponents // associated with g2a & g3a are known var r2 = HLP.randomExponent() var r3 = HLP.randomExponent() this.c2 = this.computeC(1, r2) this.c3 = this.computeC(2, r3) this.d2 = this.computeD(r2, this.a2, this.c2) this.d3 = this.computeD(r3, this.a3, this.c3) // set the next expected state this.smpstate = CONST.SMPSTATE_EXPECT2 var send = '' var type = 2 if (question) { send += question send += '\x00' type = 7 } send += HLP.packINT(6) + HLP.packMPIs([ this.g2a , this.c2 , this.d2 , this.g3a , this.c3 , this.d3 ]) this.sendMsg(HLP.packTLV(type, send)) } SM.prototype.abort = function () { this.init() this.sendMsg(HLP.packTLV(6, '')) this.trigger('abort') } }).call(this) ;(function () { "use strict"; var root = this var CryptoJS, BigInt, EventEmitter, Worker, SMWPath , CONST, HLP, Parse, AKE, SM, DSA if (typeof module !== 'undefined' && module.exports) { module.exports = OTR CryptoJS = require('../vendor/crypto.js') BigInt = require('../vendor/bigint.js') EventEmitter = require('../vendor/eventemitter.js') SMWPath = require('path').join(__dirname, '/sm-webworker.js') CONST = require('./const.js') HLP = require('./helpers.js') Parse = require('./parse.js') AKE = require('./ake.js') SM = require('./sm.js') DSA = require('./dsa.js') // expose CONST for consistency with docs OTR.CONST = CONST } else { // copy over and expose internals Object.keys(root.OTR).forEach(function (k) { OTR[k] = root.OTR[k] }) root.OTR = OTR CryptoJS = root.CryptoJS BigInt = root.BigInt EventEmitter = root.EventEmitter Worker = root.Worker SMWPath = 'sm-webworker.js' CONST = OTR.CONST HLP = OTR.HLP Parse = OTR.Parse AKE = OTR.AKE SM = OTR.SM DSA = root.DSA } // diffie-hellman modulus and generator // see group 5, RFC 3526 var G = BigInt.str2bigInt(CONST.G, 10) var N = BigInt.str2bigInt(CONST.N, 16) // JavaScript integers var MAX_INT = Math.pow(2, 53) - 1 // doubles var MAX_UINT = Math.pow(2, 31) - 1 // bitwise operators // an internal callback function OTRCB(cb) { this.cb = cb } // OTR contructor function OTR(options) { if (!(this instanceof OTR)) return new OTR(options) // options options = options || {} // private keys if (options.priv && !(options.priv instanceof DSA)) throw new Error('Requires long-lived DSA key.') this.priv = options.priv ? options.priv : new DSA() this.fragment_size = options.fragment_size || 0 if (this.fragment_size < 0) throw new Error('Fragment size must be a positive integer.') this.send_interval = options.send_interval || 0 if (this.send_interval < 0) throw new Error('Send interval must be a positive integer.') this.outgoing = [] // instance tag this.our_instance_tag = options.instance_tag || OTR.makeInstanceTag() // debug this.debug = !!options.debug // smp in webworker options // this is still experimental and undocumented this.smw = options.smw // init vals this.init() // bind methods var self = this ;['sendMsg', 'receiveMsg'].forEach(function (meth) { self[meth] = self[meth].bind(self) }) EventEmitter.call(this) } // inherit from EE HLP.extend(OTR, EventEmitter) // add to prototype OTR.prototype.init = function () { this.msgstate = CONST.MSGSTATE_PLAINTEXT this.authstate = CONST.AUTHSTATE_NONE this.ALLOW_V2 = true this.ALLOW_V3 = true this.REQUIRE_ENCRYPTION = false this.SEND_WHITESPACE_TAG = false this.WHITESPACE_START_AKE = false this.ERROR_START_AKE = false Parse.initFragment(this) // their keys this.their_y = null this.their_old_y = null this.their_keyid = 0 this.their_priv_pk = null this.their_instance_tag = '\x00\x00\x00\x00' // our keys this.our_dh = this.dh() this.our_old_dh = this.dh() this.our_keyid = 2 // session keys this.sessKeys = [ new Array(2), new Array(2) ] // saved this.storedMgs = [] this.oldMacKeys = [] // smp this.sm = null // initialized after AKE // when ake is complete // save their keys and the session this._akeInit() // receive plaintext message since switching to plaintext // used to decide when to stop sending pt tags when SEND_WHITESPACE_TAG this.receivedPlaintext = false } OTR.prototype._akeInit = function () { this.ake = new AKE(this) this.transmittedRS = false this.ssid = null } // smp over webworker OTR.prototype._SMW = function (otr, reqs) { this.otr = otr var opts = { path: SMWPath , seed: BigInt.getSeed } if (typeof otr.smw === 'object') Object.keys(otr.smw).forEach(function (k) { opts[k] = otr.smw[k] }) // load optional dep. in node if (typeof module !== 'undefined' && module.exports) Worker = require('webworker-threads').Worker this.worker = new Worker(opts.path) var self = this this.worker.onmessage = function (e) { var d = e.data if (!d) return self.trigger(d.method, d.args) } this.worker.postMessage({ type: 'seed' , seed: opts.seed() , imports: opts.imports }) this.worker.postMessage({ type: 'init' , reqs: reqs }) } // inherit from EE HLP.extend(OTR.prototype._SMW, EventEmitter) // shim sm methods ;['handleSM', 'rcvSecret', 'abort'].forEach(function (m) { OTR.prototype._SMW.prototype[m] = function () { this.worker.postMessage({ type: 'method' , method: m , args: Array.prototype.slice.call(arguments, 0) }) } }) OTR.prototype._smInit = function () { var reqs = { ssid: this.ssid , our_fp: this.priv.fingerprint() , their_fp: this.their_priv_pk.fingerprint() , debug: this.debug } if (this.smw) { if (this.sm) this.sm.worker.terminate() // destroy prev webworker this.sm = new this._SMW(this, reqs) } else { this.sm = new SM(reqs) } var self = this ;['trust', 'abort', 'question'].forEach(function (e) { self.sm.on(e, function () { self.trigger('smp', [e].concat(Array.prototype.slice.call(arguments))) }) }) this.sm.on('send', function (ssid, send) { if (self.ssid === ssid) { send = self.prepareMsg(send) self.io(send) } }) } OTR.prototype.io = function (msg, meta) { // buffer msg = ([].concat(msg)).map(function(m){ return { msg: m, meta: meta } }) this.outgoing = this.outgoing.concat(msg) var self = this ;(function send(first) { if (!first) { if (!self.outgoing.length) return var elem = self.outgoing.shift(), cb = null if (elem.meta instanceof OTRCB) { cb = elem.meta.cb elem.meta = null } self.trigger('io', [elem.msg, elem.meta]) if (cb) cb() } setTimeout(send, first ? 0 : self.send_interval) }(true)) } OTR.prototype.dh = function dh() { var keys = { privateKey: BigInt.randBigInt(320) } keys.publicKey = BigInt.powMod(G, keys.privateKey, N) return keys } // session constructor OTR.prototype.DHSession = function DHSession(our_dh, their_y) { if (!(this instanceof DHSession)) return new DHSession(our_dh, their_y) // shared secret var s = BigInt.powMod(their_y, our_dh.privateKey, N) var secbytes = HLP.packMPI(s) // session id this.id = HLP.mask(HLP.h2('\x00', secbytes), 0, 64) // first 64-bits // are we the high or low end of the connection? var sq = BigInt.greater(our_dh.publicKey, their_y) var sendbyte = sq ? '\x01' : '\x02' var rcvbyte = sq ? '\x02' : '\x01' // sending and receiving keys this.sendenc = HLP.mask(HLP.h1(sendbyte, secbytes), 0, 128) // f16 bytes this.sendmac = CryptoJS.SHA1(CryptoJS.enc.Latin1.parse(this.sendenc)) this.sendmac = this.sendmac.toString(CryptoJS.enc.Latin1) this.rcvenc = HLP.mask(HLP.h1(rcvbyte, secbytes), 0, 128) this.rcvmac = CryptoJS.SHA1(CryptoJS.enc.Latin1.parse(this.rcvenc)) this.rcvmac = this.rcvmac.toString(CryptoJS.enc.Latin1) this.rcvmacused = false // extra symmetric key this.extra_symkey = HLP.h2('\xff', secbytes) // counters this.send_counter = 0 this.rcv_counter = 0 } OTR.prototype.rotateOurKeys = function () { // reveal old mac keys var self = this this.sessKeys[1].forEach(function (sk) { if (sk && sk.rcvmacused) self.oldMacKeys.push(sk.rcvmac) }) // rotate our keys this.our_old_dh = this.our_dh this.our_dh = this.dh() this.our_keyid += 1 this.sessKeys[1][0] = this.sessKeys[0][0] this.sessKeys[1][1] = this.sessKeys[0][1] this.sessKeys[0] = [ this.their_y ? new this.DHSession(this.our_dh, this.their_y) : null , this.their_old_y ? new this.DHSession(this.our_dh, this.their_old_y) : null ] } OTR.prototype.rotateTheirKeys = function (their_y) { // increment their keyid this.their_keyid += 1 // reveal old mac keys var self = this this.sessKeys.forEach(function (sk) { if (sk[1] && sk[1].rcvmacused) self.oldMacKeys.push(sk[1].rcvmac) }) // rotate their keys / session this.their_old_y = this.their_y this.sessKeys[0][1] = this.sessKeys[0][0] this.sessKeys[1][1] = this.sessKeys[1][0] // new keys / sessions this.their_y = their_y this.sessKeys[0][0] = new this.DHSession(this.our_dh, this.their_y) this.sessKeys[1][0] = new this.DHSession(this.our_old_dh, this.their_y) } OTR.prototype.prepareMsg = function (msg, esk) { if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED || this.their_keyid === 0) return this.notify('Not ready to encrypt.') var sessKeys = this.sessKeys[1][0] if (sessKeys.send_counter >= MAX_INT) return this.notify('Should have rekeyed by now.') sessKeys.send_counter += 1 var ctr = HLP.packCtr(sessKeys.send_counter) var send = this.ake.otr_version + '\x03' // version and type var v3 = (this.ake.otr_version === CONST.OTR_VERSION_3) if (v3) { send += this.our_instance_tag send += this.their_instance_tag } send += '\x00' // flag send += HLP.packINT(this.our_keyid - 1) send += HLP.packINT(this.their_keyid) send += HLP.packMPI(this.our_dh.publicKey) send += ctr.substring(0, 8) if (Math.ceil(msg.length / 8) >= MAX_UINT) // * 16 / 128 return this.notify('Message is too long.') var aes = HLP.encryptAes( CryptoJS.enc.Latin1.parse(msg) , sessKeys.sendenc , ctr ) send += HLP.packData(aes) send += HLP.make1Mac(send, sessKeys.sendmac) send += HLP.packData(this.oldMacKeys.splice(0).join('')) send = HLP.wrapMsg( send , this.fragment_size , v3 , this.our_instance_tag , this.their_instance_tag ) if (send[0]) return this.notify(send[0]) // emit extra symmetric key if (esk) this.trigger('file', ['send', sessKeys.extra_symkey, esk]) return send[1] } OTR.prototype.handleDataMsg = function (msg) { var vt = msg.version + msg.type if (this.ake.otr_version === CONST.OTR_VERSION_3) vt += msg.instance_tags var types = ['BYTE', 'INT', 'INT', 'MPI', 'CTR', 'DATA', 'MAC', 'DATA'] msg = HLP.splitype(types, msg.msg) // ignore flag var ign = (msg[0] === '\x01') if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED || msg.length !== 8) { if (!ign) this.error('Received an unreadable encrypted message.') return } var our_keyid = this.our_keyid - HLP.readLen(msg[2]) var their_keyid = this.their_keyid - HLP.readLen(msg[1]) if (our_keyid < 0 || our_keyid > 1) { if (!ign) this.error('Not of our latest keys.') return } if (their_keyid < 0 || their_keyid > 1) { if (!ign) this.error('Not of your latest keys.') return } var their_y = their_keyid ? this.their_old_y : this.their_y if (their_keyid === 1 && !their_y) { if (!ign) this.error('Do not have that key.') return } var sessKeys = this.sessKeys[our_keyid][their_keyid] var ctr = HLP.unpackCtr(msg[4]) if (ctr <= sessKeys.rcv_counter) { if (!ign) this.error('Counter in message is not larger.') return } sessKeys.rcv_counter = ctr // verify mac vt += msg.slice(0, 6).join('') var vmac = HLP.make1Mac(vt, sessKeys.rcvmac) if (!HLP.compare(msg[6], vmac)) { if (!ign) this.error('MACs do not match.') return } sessKeys.rcvmacused = true var out = HLP.decryptAes( msg[5].substring(4) , sessKeys.rcvenc , HLP.padCtr(msg[4]) ) out = out.toString(CryptoJS.enc.Latin1) if (!our_keyid) this.rotateOurKeys() if (!their_keyid) this.rotateTheirKeys(HLP.readMPI(msg[3])) // parse TLVs var ind = out.indexOf('\x00') if (~ind) { this.handleTLVs(out.substring(ind + 1), sessKeys) out = out.substring(0, ind) } out = CryptoJS.enc.Latin1.parse(out) return out.toString(CryptoJS.enc.Utf8) } OTR.prototype.handleTLVs = function (tlvs, sessKeys) { var type, len, msg for (; tlvs.length; ) { type = HLP.unpackSHORT(tlvs.substr(0, 2)) len = HLP.unpackSHORT(tlvs.substr(2, 2)) msg = tlvs.substr(4, len) // TODO: handle pathological cases better if (msg.length < len) break switch (type) { case 1: // Disconnected this.msgstate = CONST.MSGSTATE_FINISHED this.trigger('status', [CONST.STATUS_END_OTR]) break case 2: case 3: case 4: case 5: case 6: case 7: // SMP if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED) { if (this.sm) this.sm.abort() return } if (!this.sm) this._smInit() this.sm.handleSM({ msg: msg, type: type }) break case 8: // utf8 filenames msg = msg.substring(4) // remove 4-byte indication msg = CryptoJS.enc.Latin1.parse(msg) msg = msg.toString(CryptoJS.enc.Utf8) // Extra Symkey this.trigger('file', ['receive', sessKeys.extra_symkey, msg]) break } tlvs = tlvs.substring(4 + len) } } OTR.prototype.smpSecret = function (secret, question) { if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED) return this.notify('Must be encrypted for SMP.') if (typeof secret !== 'string' || secret.length < 1) return this.notify('Secret is required.') if (!this.sm) this._smInit() // utf8 inputs secret = CryptoJS.enc.Utf8.parse(secret).toString(CryptoJS.enc.Latin1) if (question) question = CryptoJS.enc.Utf8.parse(question).toString(CryptoJS.enc.Latin1) this.sm.rcvSecret(secret, question) } OTR.prototype.sendQueryMsg = function () { var versions = {} , msg = CONST.OTR_TAG if (this.ALLOW_V2) versions['2'] = true if (this.ALLOW_V3) versions['3'] = true // but we don't allow v1 // if (versions['1']) msg += '?' var vs = Object.keys(versions) if (vs.length) { msg += 'v' vs.forEach(function (v) { if (v !== '1') msg += v }) msg += '?' } this.io(msg) this.trigger('status', [CONST.STATUS_SEND_QUERY]) } OTR.prototype.sendMsg = function (msg, meta) { if ( this.REQUIRE_ENCRYPTION || this.msgstate !== CONST.MSGSTATE_PLAINTEXT ) { msg = CryptoJS.enc.Utf8.parse(msg) msg = msg.toString(CryptoJS.enc.Latin1) } switch (this.msgstate) { case CONST.MSGSTATE_PLAINTEXT: if (this.REQUIRE_ENCRYPTION) { this.storedMgs.push({msg: msg, meta: meta}) this.sendQueryMsg() return } if (this.SEND_WHITESPACE_TAG && !this.receivedPlaintext) { msg += CONST.WHITESPACE_TAG // 16 byte tag if (this.ALLOW_V3) msg += CONST.WHITESPACE_TAG_V3 if (this.ALLOW_V2) msg += CONST.WHITESPACE_TAG_V2 } break case CONST.MSGSTATE_FINISHED: this.storedMgs.push({msg: msg, meta: meta}) this.notify('Message cannot be sent at this time.', 'warn') return case CONST.MSGSTATE_ENCRYPTED: msg = this.prepareMsg(msg) break default: throw new Error('Unknown message state.') } if (msg) this.io(msg, meta) } OTR.prototype.receiveMsg = function (msg, meta) { // parse type msg = Parse.parseMsg(this, msg) if (!msg) return switch (msg.cls) { case 'error': this.notify(msg.msg) return case 'ake': if ( msg.version === CONST.OTR_VERSION_3 && this.checkInstanceTags(msg.instance_tags) ) { this.notify( 'Received a message intended for a different session.', 'warn') return // ignore } this.ake.handleAKE(msg) return case 'data': if ( msg.version === CONST.OTR_VERSION_3 && this.checkInstanceTags(msg.instance_tags) ) { this.notify( 'Received a message intended for a different session.', 'warn') return // ignore } msg.msg = this.handleDataMsg(msg) msg.encrypted = true break case 'query': if (this.msgstate === CONST.MSGSTATE_ENCRYPTED) this._akeInit() this.doAKE(msg) break default: // check for encrypted if ( this.REQUIRE_ENCRYPTION || this.msgstate !== CONST.MSGSTATE_PLAINTEXT ) this.notify('Received an unencrypted message.', 'warn') // received a plaintext message // stop sending the whitespace tag this.receivedPlaintext = true // received a whitespace tag if (this.WHITESPACE_START_AKE && msg.ver.length > 0) this.doAKE(msg) } if (msg.msg) this.trigger('ui', [msg.msg, !!msg.encrypted, meta]) } OTR.prototype.checkInstanceTags = function (it) { var their_it = HLP.readLen(it.substr(0, 4)) var our_it = HLP.readLen(it.substr(4, 4)) if (our_it && our_it !== HLP.readLen(this.our_instance_tag)) return true if (HLP.readLen(this.their_instance_tag)) { if (HLP.readLen(this.their_instance_tag) !== their_it) return true } else { if (their_it < 100) return true this.their_instance_tag = HLP.packINT(their_it) } } OTR.prototype.doAKE = function (msg) { if (this.ALLOW_V3 && ~msg.ver.indexOf(CONST.OTR_VERSION_3)) { this.ake.initiateAKE(CONST.OTR_VERSION_3) } else if (this.ALLOW_V2 && ~msg.ver.indexOf(CONST.OTR_VERSION_2)) { this.ake.initiateAKE(CONST.OTR_VERSION_2) } else { this.notify('OTR conversation requested, ' + 'but no compatible protocol version found.', 'warn') } } OTR.prototype.error = function (err) { if (!this.debug) err = 'An OTR error has occurred.' this.io('?OTR Error:' + err) this.notify(err) } OTR.prototype.notify = function (err, severity) { this.trigger('error', [err, severity || 'error']) } OTR.prototype.sendStored = function () { var self = this ;(this.storedMgs.splice(0)).forEach(function (elem) { var msg = self.prepareMsg(elem.msg) self.io(msg, elem.meta) }) } OTR.prototype.sendFile = function (filename) { if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED) return this.notify('Not ready to encrypt.') if (this.ake.otr_version !== CONST.OTR_VERSION_3) return this.notify('Protocol v3 required.') if (!filename) return this.notify('Please specify a filename.') // utf8 filenames var l1name = CryptoJS.enc.Utf8.parse(filename) l1name = l1name.toString(CryptoJS.enc.Latin1) if (l1name.length >= 65532) return this.notify('Filename is too long.') var msg = '\x00' // null byte msg += '\x00\x08' // type 8 tlv msg += HLP.packSHORT(4 + l1name.length) // length of value msg += '\x00\x00\x00\x01' // four bytes indicating file msg += l1name msg = this.prepareMsg(msg, filename) this.io(msg) } OTR.prototype.endOtr = function (cb) { if (this.msgstate === CONST.MSGSTATE_ENCRYPTED) { if (typeof cb === 'function') cb = new OTRCB(cb) this.sendMsg('\x00\x00\x01\x00\x00', cb) if (this.sm) { if (this.smw) this.sm.worker.terminate() // destroy webworker this.sm = null } } this.msgstate = CONST.MSGSTATE_PLAINTEXT this.receivedPlaintext = false this.trigger('status', [CONST.STATUS_END_OTR]) } // attach methods OTR.makeInstanceTag = function () { var num = BigInt.randBigInt(32) if (BigInt.greater(BigInt.str2bigInt('100', 16), num)) return OTR.makeInstanceTag() return HLP.packINT(parseInt(BigInt.bigInt2str(num, 10), 10)) } }).call(this) return { OTR: this.OTR , DSA: this.DSA } }))././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/sm-webworker.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/sm-webwo0000644000076400007640000000245412572247340032565 0ustar pravipravi;(function (root) { "use strict"; root.OTR = {} root.crypto = { randomBytes: function () { throw new Error("Haven't seeded yet.") } } // default imports var imports = [ 'vendor/salsa20.js' , 'vendor/bigint.js' , 'vendor/crypto.js' , 'vendor/eventemitter.js' , 'lib/const.js' , 'lib/helpers.js' , 'lib/sm.js' ] function wrapPostMessage(method) { return function () { postMessage({ method: method , args: Array.prototype.slice.call(arguments, 0) }) } } var sm onmessage = function (e) { var data = e.data switch (data.type) { case 'seed': if (data.imports) imports = data.imports importScripts.apply(root, imports) // use salsa20 since there's no prng in webworkers var state = new root.Salsa20( data.seed.slice(0, 32), data.seed.slice(32) ) root.crypto.randomBytes = function (n) { return state.getBytes(n) } break case 'init': sm = new root.OTR.SM(data.reqs) ;['trust','question', 'send', 'abort'].forEach(function (m) { sm.on(m, wrapPostMessage(m)); }) break case 'method': sm[data.method].apply(sm, data.args) break } } }(this))././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dsa-webworker.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/otr/build/dsa-webw0000644000076400007640000000217112572247340032532 0ustar pravipravi;(function (root) { "use strict"; root.OTR = {} root.DSA = {} root.crypto = { randomBytes: function () { throw new Error("Haven't seeded yet.") } } // default imports var imports = [ 'vendor/salsa20.js' , 'vendor/bigint.js' , 'vendor/crypto.js' , 'vendor/eventemitter.js' , 'lib/const.js' , 'lib/helpers.js' , 'lib/dsa.js' ] function sendMsg(type, val) { postMessage({ type: type, val: val }) } onmessage = function (e) { var data = e.data; if (data.imports) imports = data.imports importScripts.apply(root, imports); // use salsa20 since there's no prng in webworkers var state = new root.Salsa20(data.seed.slice(0, 32), data.seed.slice(32)) root.crypto.randomBytes = function (n) { return state.getBytes(n) } if (data.debug) sendMsg('debug', 'DSA key creation started') var dsa try { dsa = new root.DSA() } catch (e) { if (data.debug) sendMsg('debug', e.toString()) return } if (data.debug) sendMsg('debug', 'DSA key creation finished') sendMsg('data', dsa.packPrivate()) } }(this))rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/strophe.vcard.js0000644000076400007640000000276212572247340032321 0ustar pravipravi// Generated by CoffeeScript 1.3.3 /* Plugin to implement the vCard extension. http://xmpp.org/extensions/xep-0054.html Author: Nathan Zorn (nathan.zorn@gmail.com) CoffeeScript port: Andreas Guth (guth@dbis.rwth-aachen.de) */ /* jslint configuration: */ /* global document, window, setTimeout, clearTimeout, console, XMLHttpRequest, ActiveXObject, Base64, MD5, Strophe, $build, $msg, $iq, $pres */ var buildIq; buildIq = function(type, jid, vCardEl) { var iq; iq = $iq(jid ? { type: type, to: jid } : { type: type }); iq.c("vCard", { xmlns: Strophe.NS.VCARD }); if (vCardEl) { iq.cnode(vCardEl); } return iq; }; Strophe.addConnectionPlugin('vcard', { _connection: null, init: function(conn) { this._connection = conn; return Strophe.addNamespace('VCARD', 'vcard-temp'); }, /*Function Retrieve a vCard for a JID/Entity Parameters: (Function) handler_cb - The callback function used to handle the request. (String) jid - optional - The name of the entity to request the vCard If no jid is given, this function retrieves the current user's vcard. */ get: function(handler_cb, jid, error_cb) { var iq; iq = buildIq("get", jid); return this._connection.sendIQ(iq, handler_cb, error_cb); }, /* Function Set an entity's vCard. */ set: function(handler_cb, vCardEl, jid, error_cb) { var iq; iq = buildIq("set", jid, vCardEl); return this._connection.sendIQ(iq, handler_cb, error_rb); } });rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/magnific-popup/0000755000076400007640000000000012572247340032110 5ustar pravipravi././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/magnific-popup/dist/rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/magnific-popup/dis0000755000076400007640000000000012572247340032610 5ustar pravipravi././@LongLink0000644000000000000000000000017700000000000011610 Lustar rootrootrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/magnific-popup/dist/jquery.magnific-popup.jsrails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/magnific-popup/dis0000644000076400007640000013231112572247340032613 0ustar pravipravi/*! Magnific Popup - v1.0.0 - 2015-01-03 * http://dimsemenov.com/plugins/magnific-popup/ * Copyright (c) 2015 Dmitry Semenov; */ ;(function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof exports === 'object') { // Node/CommonJS factory(require('jquery')); } else { // Browser globals factory(window.jQuery || window.Zepto); } }(function($) { /*>>core*/ /** * * Magnific Popup Core JS file * */ /** * Private static constants */ var CLOSE_EVENT = 'Close', BEFORE_CLOSE_EVENT = 'BeforeClose', AFTER_CLOSE_EVENT = 'AfterClose', BEFORE_APPEND_EVENT = 'BeforeAppend', MARKUP_PARSE_EVENT = 'MarkupParse', OPEN_EVENT = 'Open', CHANGE_EVENT = 'Change', NS = 'mfp', EVENT_NS = '.' + NS, READY_CLASS = 'mfp-ready', REMOVING_CLASS = 'mfp-removing', PREVENT_CLOSE_CLASS = 'mfp-prevent-close'; /** * Private vars */ /*jshint -W079 */ var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this' MagnificPopup = function(){}, _isJQ = !!(window.jQuery), _prevStatus, _window = $(window), _document, _prevContentType, _wrapClasses, _currPopupType; /** * Private functions */ var _mfpOn = function(name, f) { mfp.ev.on(NS + name + EVENT_NS, f); }, _getEl = function(className, appendTo, html, raw) { var el = document.createElement('div'); el.className = 'mfp-'+className; if(html) { el.innerHTML = html; } if(!raw) { el = $(el); if(appendTo) { el.appendTo(appendTo); } } else if(appendTo) { appendTo.appendChild(el); } return el; }, _mfpTrigger = function(e, data) { mfp.ev.triggerHandler(NS + e, data); if(mfp.st.callbacks) { // converts "mfpEventName" to "eventName" callback and triggers it if it's present e = e.charAt(0).toLowerCase() + e.slice(1); if(mfp.st.callbacks[e]) { mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]); } } }, _getCloseBtn = function(type) { if(type !== _currPopupType || !mfp.currTemplate.closeBtn) { mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) ); _currPopupType = type; } return mfp.currTemplate.closeBtn; }, // Initialize Magnific Popup only when called at least once _checkInstance = function() { if(!$.magnificPopup.instance) { /*jshint -W020 */ mfp = new MagnificPopup(); mfp.init(); $.magnificPopup.instance = mfp; } }, // CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr supportsTransitions = function() { var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist v = ['ms','O','Moz','Webkit']; // 'v' for vendor if( s['transition'] !== undefined ) { return true; } while( v.length ) { if( v.pop() + 'Transition' in s ) { return true; } } return false; }; /** * Public functions */ MagnificPopup.prototype = { constructor: MagnificPopup, /** * Initializes Magnific Popup plugin. * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed */ init: function() { var appVersion = navigator.appVersion; mfp.isIE7 = appVersion.indexOf("MSIE 7.") !== -1; mfp.isIE8 = appVersion.indexOf("MSIE 8.") !== -1; mfp.isLowIE = mfp.isIE7 || mfp.isIE8; mfp.isAndroid = (/android/gi).test(appVersion); mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion); mfp.supportsTransition = supportsTransitions(); // We disable fixed positioned lightbox on devices that don't handle it nicely. // If you know a better way of detecting this - let me know. mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) ); _document = $(document); mfp.popupsCache = {}; }, /** * Opens popup * @param data [description] */ open: function(data) { var i; if(data.isObj === false) { // convert jQuery collection to array to avoid conflicts later mfp.items = data.items.toArray(); mfp.index = 0; var items = data.items, item; for(i = 0; i < items.length; i++) { item = items[i]; if(item.parsed) { item = item.el[0]; } if(item === data.el[0]) { mfp.index = i; break; } } } else { mfp.items = $.isArray(data.items) ? data.items : [data.items]; mfp.index = data.index || 0; } // if popup is already opened - we just update the content if(mfp.isOpen) { mfp.updateItemHTML(); return; } mfp.types = []; _wrapClasses = ''; if(data.mainEl && data.mainEl.length) { mfp.ev = data.mainEl.eq(0); } else { mfp.ev = _document; } if(data.key) { if(!mfp.popupsCache[data.key]) { mfp.popupsCache[data.key] = {}; } mfp.currTemplate = mfp.popupsCache[data.key]; } else { mfp.currTemplate = {}; } mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos; if(mfp.st.modal) { mfp.st.closeOnContentClick = false; mfp.st.closeOnBgClick = false; mfp.st.showCloseBtn = false; mfp.st.enableEscapeKey = false; } // Building markup // main containers are created only once if(!mfp.bgOverlay) { // Dark overlay mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() { mfp.close(); }); mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) { if(mfp._checkIfClose(e.target)) { mfp.close(); } }); mfp.container = _getEl('container', mfp.wrap); } mfp.contentContainer = _getEl('content'); if(mfp.st.preloader) { mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading); } // Initializing modules var modules = $.magnificPopup.modules; for(i = 0; i < modules.length; i++) { var n = modules[i]; n = n.charAt(0).toUpperCase() + n.slice(1); mfp['init'+n].call(mfp); } _mfpTrigger('BeforeOpen'); if(mfp.st.showCloseBtn) { // Close button if(!mfp.st.closeBtnInside) { mfp.wrap.append( _getCloseBtn() ); } else { _mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) { values.close_replaceWith = _getCloseBtn(item.type); }); _wrapClasses += ' mfp-close-btn-in'; } } if(mfp.st.alignTop) { _wrapClasses += ' mfp-align-top'; } if(mfp.fixedContentPos) { mfp.wrap.css({ overflow: mfp.st.overflowY, overflowX: 'hidden', overflowY: mfp.st.overflowY }); } else { mfp.wrap.css({ top: _window.scrollTop(), position: 'absolute' }); } if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) { mfp.bgOverlay.css({ height: _document.height(), position: 'absolute' }); } if(mfp.st.enableEscapeKey) { // Close on ESC key _document.on('keyup' + EVENT_NS, function(e) { if(e.keyCode === 27) { mfp.close(); } }); } _window.on('resize' + EVENT_NS, function() { mfp.updateSize(); }); if(!mfp.st.closeOnContentClick) { _wrapClasses += ' mfp-auto-cursor'; } if(_wrapClasses) mfp.wrap.addClass(_wrapClasses); // this triggers recalculation of layout, so we get it once to not to trigger twice var windowHeight = mfp.wH = _window.height(); var windowStyles = {}; if( mfp.fixedContentPos ) { if(mfp._hasScrollBar(windowHeight)){ var s = mfp._getScrollbarSize(); if(s) { windowStyles.marginRight = s; } } } if(mfp.fixedContentPos) { if(!mfp.isIE7) { windowStyles.overflow = 'hidden'; } else { // ie7 double-scroll bug $('body, html').css('overflow', 'hidden'); } } var classesToadd = mfp.st.mainClass; if(mfp.isIE7) { classesToadd += ' mfp-ie7'; } if(classesToadd) { mfp._addClassToMFP( classesToadd ); } // add content mfp.updateItemHTML(); _mfpTrigger('BuildControls'); // remove scrollbar, add margin e.t.c $('html').css(windowStyles); // add everything to DOM mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) ); // Save last focused element mfp._lastFocusedEl = document.activeElement; // Wait for next cycle to allow CSS transition setTimeout(function() { if(mfp.content) { mfp._addClassToMFP(READY_CLASS); mfp._setFocus(); } else { // if content is not defined (not loaded e.t.c) we add class only for BG mfp.bgOverlay.addClass(READY_CLASS); } // Trap the focus in popup _document.on('focusin' + EVENT_NS, mfp._onFocusIn); }, 16); mfp.isOpen = true; mfp.updateSize(windowHeight); _mfpTrigger(OPEN_EVENT); return data; }, /** * Closes the popup */ close: function() { if(!mfp.isOpen) return; _mfpTrigger(BEFORE_CLOSE_EVENT); mfp.isOpen = false; // for CSS3 animation if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition ) { mfp._addClassToMFP(REMOVING_CLASS); setTimeout(function() { mfp._close(); }, mfp.st.removalDelay); } else { mfp._close(); } }, /** * Helper for close() function */ _close: function() { _mfpTrigger(CLOSE_EVENT); var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' '; mfp.bgOverlay.detach(); mfp.wrap.detach(); mfp.container.empty(); if(mfp.st.mainClass) { classesToRemove += mfp.st.mainClass + ' '; } mfp._removeClassFromMFP(classesToRemove); if(mfp.fixedContentPos) { var windowStyles = {marginRight: ''}; if(mfp.isIE7) { $('body, html').css('overflow', ''); } else { windowStyles.overflow = ''; } $('html').css(windowStyles); } _document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS); mfp.ev.off(EVENT_NS); // clean up DOM elements that aren't removed mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style'); mfp.bgOverlay.attr('class', 'mfp-bg'); mfp.container.attr('class', 'mfp-container'); // remove close button from target element if(mfp.st.showCloseBtn && (!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) { if(mfp.currTemplate.closeBtn) mfp.currTemplate.closeBtn.detach(); } if(mfp._lastFocusedEl) { $(mfp._lastFocusedEl).focus(); // put tab focus back } mfp.currItem = null; mfp.content = null; mfp.currTemplate = null; mfp.prevHeight = 0; _mfpTrigger(AFTER_CLOSE_EVENT); }, updateSize: function(winHeight) { if(mfp.isIOS) { // fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2 var zoomLevel = document.documentElement.clientWidth / window.innerWidth; var height = window.innerHeight * zoomLevel; mfp.wrap.css('height', height); mfp.wH = height; } else { mfp.wH = winHeight || _window.height(); } // Fixes #84: popup incorrectly positioned with position:relative on body if(!mfp.fixedContentPos) { mfp.wrap.css('height', mfp.wH); } _mfpTrigger('Resize'); }, /** * Set content of popup based on current index */ updateItemHTML: function() { var item = mfp.items[mfp.index]; // Detach and perform modifications mfp.contentContainer.detach(); if(mfp.content) mfp.content.detach(); if(!item.parsed) { item = mfp.parseEl( mfp.index ); } var type = item.type; _mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]); // BeforeChange event works like so: // _mfpOn('BeforeChange', function(e, prevType, newType) { }); mfp.currItem = item; if(!mfp.currTemplate[type]) { var markup = mfp.st[type] ? mfp.st[type].markup : false; // allows to modify markup _mfpTrigger('FirstMarkupParse', markup); if(markup) { mfp.currTemplate[type] = $(markup); } else { // if there is no markup found we just define that template is parsed mfp.currTemplate[type] = true; } } if(_prevContentType && _prevContentType !== item.type) { mfp.container.removeClass('mfp-'+_prevContentType+'-holder'); } var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]); mfp.appendContent(newContent, type); item.preloaded = true; _mfpTrigger(CHANGE_EVENT, item); _prevContentType = item.type; // Append container back after its content changed mfp.container.prepend(mfp.contentContainer); _mfpTrigger('AfterChange'); }, /** * Set HTML content of popup */ appendContent: function(newContent, type) { mfp.content = newContent; if(newContent) { if(mfp.st.showCloseBtn && mfp.st.closeBtnInside && mfp.currTemplate[type] === true) { // if there is no markup, we just append close button element inside if(!mfp.content.find('.mfp-close').length) { mfp.content.append(_getCloseBtn()); } } else { mfp.content = newContent; } } else { mfp.content = ''; } _mfpTrigger(BEFORE_APPEND_EVENT); mfp.container.addClass('mfp-'+type+'-holder'); mfp.contentContainer.append(mfp.content); }, /** * Creates Magnific Popup data object based on given data * @param {int} index Index of item to parse */ parseEl: function(index) { var item = mfp.items[index], type; if(item.tagName) { item = { el: $(item) }; } else { type = item.type; item = { data: item, src: item.src }; } if(item.el) { var types = mfp.types; // check for 'mfp-TYPE' class for(var i = 0; i < types.length; i++) { if( item.el.hasClass('mfp-'+types[i]) ) { type = types[i]; break; } } item.src = item.el.attr('data-mfp-src'); if(!item.src) { item.src = item.el.attr('href'); } } item.type = type || mfp.st.type || 'inline'; item.index = index; item.parsed = true; mfp.items[index] = item; _mfpTrigger('ElementParse', item); return mfp.items[index]; }, /** * Initializes single popup or a group of popups */ addGroup: function(el, options) { var eHandler = function(e) { e.mfpEl = this; mfp._openClick(e, el, options); }; if(!options) { options = {}; } var eName = 'click.magnificPopup'; options.mainEl = el; if(options.items) { options.isObj = true; el.off(eName).on(eName, eHandler); } else { options.isObj = false; if(options.delegate) { el.off(eName).on(eName, options.delegate , eHandler); } else { options.items = el; el.off(eName).on(eName, eHandler); } } }, _openClick: function(e, el, options) { var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick; if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey ) ) { return; } var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn; if(disableOn) { if($.isFunction(disableOn)) { if( !disableOn.call(mfp) ) { return true; } } else { // else it's number if( _window.width() < disableOn ) { return true; } } } if(e.type) { e.preventDefault(); // This will prevent popup from closing if element is inside and popup is already opened if(mfp.isOpen) { e.stopPropagation(); } } options.el = $(e.mfpEl); if(options.delegate) { options.items = el.find(options.delegate); } mfp.open(options); }, /** * Updates text on preloader */ updateStatus: function(status, text) { if(mfp.preloader) { if(_prevStatus !== status) { mfp.container.removeClass('mfp-s-'+_prevStatus); } if(!text && status === 'loading') { text = mfp.st.tLoading; } var data = { status: status, text: text }; // allows to modify status _mfpTrigger('UpdateStatus', data); status = data.status; text = data.text; mfp.preloader.html(text); mfp.preloader.find('a').on('click', function(e) { e.stopImmediatePropagation(); }); mfp.container.addClass('mfp-s-'+status); _prevStatus = status; } }, /* "Private" helpers that aren't private at all */ // Check to close popup or not // "target" is an element that was clicked _checkIfClose: function(target) { if($(target).hasClass(PREVENT_CLOSE_CLASS)) { return; } var closeOnContent = mfp.st.closeOnContentClick; var closeOnBg = mfp.st.closeOnBgClick; if(closeOnContent && closeOnBg) { return true; } else { // We close the popup if click is on close button or on preloader. Or if there is no content. if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) { return true; } // if click is outside the content if( (target !== mfp.content[0] && !$.contains(mfp.content[0], target)) ) { if(closeOnBg) { // last check, if the clicked element is in DOM, (in case it's removed onclick) if( $.contains(document, target) ) { return true; } } } else if(closeOnContent) { return true; } } return false; }, _addClassToMFP: function(cName) { mfp.bgOverlay.addClass(cName); mfp.wrap.addClass(cName); }, _removeClassFromMFP: function(cName) { this.bgOverlay.removeClass(cName); mfp.wrap.removeClass(cName); }, _hasScrollBar: function(winHeight) { return ( (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) ); }, _setFocus: function() { (mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus(); }, _onFocusIn: function(e) { if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) { mfp._setFocus(); return false; } }, _parseMarkup: function(template, values, item) { var arr; if(item.data) { values = $.extend(item.data, values); } _mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] ); $.each(values, function(key, value) { if(value === undefined || value === false) { return true; } arr = key.split('_'); if(arr.length > 1) { var el = template.find(EVENT_NS + '-'+arr[0]); if(el.length > 0) { var attr = arr[1]; if(attr === 'replaceWith') { if(el[0] !== value[0]) { el.replaceWith(value); } } else if(attr === 'img') { if(el.is('img')) { el.attr('src', value); } else { el.replaceWith( '' ); } } else { el.attr(arr[1], value); } } } else { template.find(EVENT_NS + '-'+key).html(value); } }); }, _getScrollbarSize: function() { // thx David if(mfp.scrollbarSize === undefined) { var scrollDiv = document.createElement("div"); scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;'; document.body.appendChild(scrollDiv); mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth; document.body.removeChild(scrollDiv); } return mfp.scrollbarSize; } }; /* MagnificPopup core prototype end */ /** * Public static functions */ $.magnificPopup = { instance: null, proto: MagnificPopup.prototype, modules: [], open: function(options, index) { _checkInstance(); if(!options) { options = {}; } else { options = $.extend(true, {}, options); } options.isObj = true; options.index = index || 0; return this.instance.open(options); }, close: function() { return $.magnificPopup.instance && $.magnificPopup.instance.close(); }, registerModule: function(name, module) { if(module.options) { $.magnificPopup.defaults[name] = module.options; } $.extend(this.proto, module.proto); this.modules.push(name); }, defaults: { // Info about options is in docs: // http://dimsemenov.com/plugins/magnific-popup/documentation.html#options disableOn: 0, key: null, midClick: false, mainClass: '', preloader: true, focus: '', // CSS selector of input to focus after popup is opened closeOnContentClick: false, closeOnBgClick: true, closeBtnInside: true, showCloseBtn: true, enableEscapeKey: true, modal: false, alignTop: false, removalDelay: 0, prependTo: null, fixedContentPos: 'auto', fixedBgPos: 'auto', overflowY: 'auto', closeMarkup: '', tClose: 'Close (Esc)', tLoading: 'Loading...' } }; $.fn.magnificPopup = function(options) { _checkInstance(); var jqEl = $(this); // We call some API method of first param is a string if (typeof options === "string" ) { if(options === 'open') { var items, itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup, index = parseInt(arguments[1], 10) || 0; if(itemOpts.items) { items = itemOpts.items[index]; } else { items = jqEl; if(itemOpts.delegate) { items = items.find(itemOpts.delegate); } items = items.eq( index ); } mfp._openClick({mfpEl:items}, jqEl, itemOpts); } else { if(mfp.isOpen) mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1)); } } else { // clone options obj options = $.extend(true, {}, options); /* * As Zepto doesn't support .data() method for objects * and it works only in normal browsers * we assign "options" object directly to the DOM element. FTW! */ if(_isJQ) { jqEl.data('magnificPopup', options); } else { jqEl[0].magnificPopup = options; } mfp.addGroup(jqEl, options); } return jqEl; }; //Quick benchmark /* var start = performance.now(), i, rounds = 1000; for(i = 0; i < rounds; i++) { } console.log('Test #1:', performance.now() - start); start = performance.now(); for(i = 0; i < rounds; i++) { } console.log('Test #2:', performance.now() - start); */ /*>>core*/ /*>>inline*/ var INLINE_NS = 'inline', _hiddenClass, _inlinePlaceholder, _lastInlineElement, _putInlineElementsBack = function() { if(_lastInlineElement) { _inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach(); _lastInlineElement = null; } }; $.magnificPopup.registerModule(INLINE_NS, { options: { hiddenClass: 'hide', // will be appended with `mfp-` prefix markup: '', tNotFound: 'Content not found' }, proto: { initInline: function() { mfp.types.push(INLINE_NS); _mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() { _putInlineElementsBack(); }); }, getInline: function(item, template) { _putInlineElementsBack(); if(item.src) { var inlineSt = mfp.st.inline, el = $(item.src); if(el.length) { // If target element has parent - we replace it with placeholder and put it back after popup is closed var parent = el[0].parentNode; if(parent && parent.tagName) { if(!_inlinePlaceholder) { _hiddenClass = inlineSt.hiddenClass; _inlinePlaceholder = _getEl(_hiddenClass); _hiddenClass = 'mfp-'+_hiddenClass; } // replace target inline element with placeholder _lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass); } mfp.updateStatus('ready'); } else { mfp.updateStatus('error', inlineSt.tNotFound); el = $('
'); } item.inlineElement = el; return el; } mfp.updateStatus('ready'); mfp._parseMarkup(template, {}, item); return template; } } }); /*>>inline*/ /*>>ajax*/ var AJAX_NS = 'ajax', _ajaxCur, _removeAjaxCursor = function() { if(_ajaxCur) { $(document.body).removeClass(_ajaxCur); } }, _destroyAjaxRequest = function() { _removeAjaxCursor(); if(mfp.req) { mfp.req.abort(); } }; $.magnificPopup.registerModule(AJAX_NS, { options: { settings: null, cursor: 'mfp-ajax-cur', tError: 'The content could not be loaded.' }, proto: { initAjax: function() { mfp.types.push(AJAX_NS); _ajaxCur = mfp.st.ajax.cursor; _mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest); _mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest); }, getAjax: function(item) { if(_ajaxCur) { $(document.body).addClass(_ajaxCur); } mfp.updateStatus('loading'); var opts = $.extend({ url: item.src, success: function(data, textStatus, jqXHR) { var temp = { data:data, xhr:jqXHR }; _mfpTrigger('ParseAjax', temp); mfp.appendContent( $(temp.data), AJAX_NS ); item.finished = true; _removeAjaxCursor(); mfp._setFocus(); setTimeout(function() { mfp.wrap.addClass(READY_CLASS); }, 16); mfp.updateStatus('ready'); _mfpTrigger('AjaxContentAdded'); }, error: function() { _removeAjaxCursor(); item.finished = item.loadError = true; mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src)); } }, mfp.st.ajax.settings); mfp.req = $.ajax(opts); return ''; } } }); /*>>ajax*/ /*>>image*/ var _imgInterval, _getTitle = function(item) { if(item.data && item.data.title !== undefined) return item.data.title; var src = mfp.st.image.titleSrc; if(src) { if($.isFunction(src)) { return src.call(mfp, item); } else if(item.el) { return item.el.attr(src) || ''; } } return ''; }; $.magnificPopup.registerModule('image', { options: { markup: '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
', cursor: 'mfp-zoom-out-cur', titleSrc: 'title', verticalFit: true, tError: 'The image could not be loaded.' }, proto: { initImage: function() { var imgSt = mfp.st.image, ns = '.image'; mfp.types.push('image'); _mfpOn(OPEN_EVENT+ns, function() { if(mfp.currItem.type === 'image' && imgSt.cursor) { $(document.body).addClass(imgSt.cursor); } }); _mfpOn(CLOSE_EVENT+ns, function() { if(imgSt.cursor) { $(document.body).removeClass(imgSt.cursor); } _window.off('resize' + EVENT_NS); }); _mfpOn('Resize'+ns, mfp.resizeImage); if(mfp.isLowIE) { _mfpOn('AfterChange', mfp.resizeImage); } }, resizeImage: function() { var item = mfp.currItem; if(!item || !item.img) return; if(mfp.st.image.verticalFit) { var decr = 0; // fix box-sizing in ie7/8 if(mfp.isLowIE) { decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10); } item.img.css('max-height', mfp.wH-decr); } }, _onImageHasSize: function(item) { if(item.img) { item.hasSize = true; if(_imgInterval) { clearInterval(_imgInterval); } item.isCheckingImgSize = false; _mfpTrigger('ImageHasSize', item); if(item.imgHidden) { if(mfp.content) mfp.content.removeClass('mfp-loading'); item.imgHidden = false; } } }, /** * Function that loops until the image has size to display elements that rely on it asap */ findImageSize: function(item) { var counter = 0, img = item.img[0], mfpSetInterval = function(delay) { if(_imgInterval) { clearInterval(_imgInterval); } // decelerating interval that checks for size of an image _imgInterval = setInterval(function() { if(img.naturalWidth > 0) { mfp._onImageHasSize(item); return; } if(counter > 200) { clearInterval(_imgInterval); } counter++; if(counter === 3) { mfpSetInterval(10); } else if(counter === 40) { mfpSetInterval(50); } else if(counter === 100) { mfpSetInterval(500); } }, delay); }; mfpSetInterval(1); }, getImage: function(item, template) { var guard = 0, // image load complete handler onLoadComplete = function() { if(item) { if (item.img[0].complete) { item.img.off('.mfploader'); if(item === mfp.currItem){ mfp._onImageHasSize(item); mfp.updateStatus('ready'); } item.hasSize = true; item.loaded = true; _mfpTrigger('ImageLoadComplete'); } else { // if image complete check fails 200 times (20 sec), we assume that there was an error. guard++; if(guard < 200) { setTimeout(onLoadComplete,100); } else { onLoadError(); } } } }, // image error handler onLoadError = function() { if(item) { item.img.off('.mfploader'); if(item === mfp.currItem){ mfp._onImageHasSize(item); mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); } item.hasSize = true; item.loaded = true; item.loadError = true; } }, imgSt = mfp.st.image; var el = template.find('.mfp-img'); if(el.length) { var img = document.createElement('img'); img.className = 'mfp-img'; if(item.el && item.el.find('img').length) { img.alt = item.el.find('img').attr('alt'); } item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError); img.src = item.src; // without clone() "error" event is not firing when IMG is replaced by new IMG // TODO: find a way to avoid such cloning if(el.is('img')) { item.img = item.img.clone(); } img = item.img[0]; if(img.naturalWidth > 0) { item.hasSize = true; } else if(!img.width) { item.hasSize = false; } } mfp._parseMarkup(template, { title: _getTitle(item), img_replaceWith: item.img }, item); mfp.resizeImage(); if(item.hasSize) { if(_imgInterval) clearInterval(_imgInterval); if(item.loadError) { template.addClass('mfp-loading'); mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); } else { template.removeClass('mfp-loading'); mfp.updateStatus('ready'); } return template; } mfp.updateStatus('loading'); item.loading = true; if(!item.hasSize) { item.imgHidden = true; template.addClass('mfp-loading'); mfp.findImageSize(item); } return template; } } }); /*>>image*/ /*>>zoom*/ var hasMozTransform, getHasMozTransform = function() { if(hasMozTransform === undefined) { hasMozTransform = document.createElement('p').style.MozTransform !== undefined; } return hasMozTransform; }; $.magnificPopup.registerModule('zoom', { options: { enabled: false, easing: 'ease-in-out', duration: 300, opener: function(element) { return element.is('img') ? element : element.find('img'); } }, proto: { initZoom: function() { var zoomSt = mfp.st.zoom, ns = '.zoom', image; if(!zoomSt.enabled || !mfp.supportsTransition) { return; } var duration = zoomSt.duration, getElToAnimate = function(image) { var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'), transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing, cssObj = { position: 'fixed', zIndex: 9999, left: 0, top: 0, '-webkit-backface-visibility': 'hidden' }, t = 'transition'; cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition; newImg.css(cssObj); return newImg; }, showMainContent = function() { mfp.content.css('visibility', 'visible'); }, openTimeout, animatedImg; _mfpOn('BuildControls'+ns, function() { if(mfp._allowZoom()) { clearTimeout(openTimeout); mfp.content.css('visibility', 'hidden'); // Basically, all code below does is clones existing image, puts in on top of the current one and animated it image = mfp._getItemToZoom(); if(!image) { showMainContent(); return; } animatedImg = getElToAnimate(image); animatedImg.css( mfp._getOffset() ); mfp.wrap.append(animatedImg); openTimeout = setTimeout(function() { animatedImg.css( mfp._getOffset( true ) ); openTimeout = setTimeout(function() { showMainContent(); setTimeout(function() { animatedImg.remove(); image = animatedImg = null; _mfpTrigger('ZoomAnimationEnded'); }, 16); // avoid blink when switching images }, duration); // this timeout equals animation duration }, 16); // by adding this timeout we avoid short glitch at the beginning of animation // Lots of timeouts... } }); _mfpOn(BEFORE_CLOSE_EVENT+ns, function() { if(mfp._allowZoom()) { clearTimeout(openTimeout); mfp.st.removalDelay = duration; if(!image) { image = mfp._getItemToZoom(); if(!image) { return; } animatedImg = getElToAnimate(image); } animatedImg.css( mfp._getOffset(true) ); mfp.wrap.append(animatedImg); mfp.content.css('visibility', 'hidden'); setTimeout(function() { animatedImg.css( mfp._getOffset() ); }, 16); } }); _mfpOn(CLOSE_EVENT+ns, function() { if(mfp._allowZoom()) { showMainContent(); if(animatedImg) { animatedImg.remove(); } image = null; } }); }, _allowZoom: function() { return mfp.currItem.type === 'image'; }, _getItemToZoom: function() { if(mfp.currItem.hasSize) { return mfp.currItem.img; } else { return false; } }, // Get element postion relative to viewport _getOffset: function(isLarge) { var el; if(isLarge) { el = mfp.currItem.img; } else { el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem); } var offset = el.offset(); var paddingTop = parseInt(el.css('padding-top'),10); var paddingBottom = parseInt(el.css('padding-bottom'),10); offset.top -= ( $(window).scrollTop() - paddingTop ); /* Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa. */ var obj = { width: el.width(), // fix Zepto height+padding issue height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop }; // I hate to do this, but there is no another option if( getHasMozTransform() ) { obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)'; } else { obj.left = offset.left; obj.top = offset.top; } return obj; } } }); /*>>zoom*/ /*>>iframe*/ var IFRAME_NS = 'iframe', _emptyPage = '//about:blank', _fixIframeBugs = function(isShowing) { if(mfp.currTemplate[IFRAME_NS]) { var el = mfp.currTemplate[IFRAME_NS].find('iframe'); if(el.length) { // reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug if(!isShowing) { el[0].src = _emptyPage; } // IE8 black screen bug fix if(mfp.isIE8) { el.css('display', isShowing ? 'block' : 'none'); } } } }; $.magnificPopup.registerModule(IFRAME_NS, { options: { markup: '
'+ '
'+ ''+ '
', srcAction: 'iframe_src', // we don't care and support only one default type of URL by default patterns: { youtube: { index: 'youtube.com', id: 'v=', src: '//www.youtube.com/embed/%id%?autoplay=1' }, vimeo: { index: 'vimeo.com/', id: '/', src: '//player.vimeo.com/video/%id%?autoplay=1' }, gmaps: { index: '//maps.google.', src: '%id%&output=embed' } } }, proto: { initIframe: function() { mfp.types.push(IFRAME_NS); _mfpOn('BeforeChange', function(e, prevType, newType) { if(prevType !== newType) { if(prevType === IFRAME_NS) { _fixIframeBugs(); // iframe if removed } else if(newType === IFRAME_NS) { _fixIframeBugs(true); // iframe is showing } }// else { // iframe source is switched, don't do anything //} }); _mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() { _fixIframeBugs(); }); }, getIframe: function(item, template) { var embedSrc = item.src; var iframeSt = mfp.st.iframe; $.each(iframeSt.patterns, function() { if(embedSrc.indexOf( this.index ) > -1) { if(this.id) { if(typeof this.id === 'string') { embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length); } else { embedSrc = this.id.call( this, embedSrc ); } } embedSrc = this.src.replace('%id%', embedSrc ); return false; // break; } }); var dataObj = {}; if(iframeSt.srcAction) { dataObj[iframeSt.srcAction] = embedSrc; } mfp._parseMarkup(template, dataObj, item); mfp.updateStatus('ready'); return template; } } }); /*>>iframe*/ /*>>gallery*/ /** * Get looped index depending on number of slides */ var _getLoopedId = function(index) { var numSlides = mfp.items.length; if(index > numSlides - 1) { return index - numSlides; } else if(index < 0) { return numSlides + index; } return index; }, _replaceCurrTotal = function(text, curr, total) { return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total); }; $.magnificPopup.registerModule('gallery', { options: { enabled: false, arrowMarkup: '', preload: [0,2], navigateByImgClick: true, arrows: true, tPrev: 'Previous (Left arrow key)', tNext: 'Next (Right arrow key)', tCounter: '%curr% of %total%' }, proto: { initGallery: function() { var gSt = mfp.st.gallery, ns = '.mfp-gallery', supportsFastClick = Boolean($.fn.mfpFastClick); mfp.direction = true; // true - next, false - prev if(!gSt || !gSt.enabled ) return false; _wrapClasses += ' mfp-gallery'; _mfpOn(OPEN_EVENT+ns, function() { if(gSt.navigateByImgClick) { mfp.wrap.on('click'+ns, '.mfp-img', function() { if(mfp.items.length > 1) { mfp.next(); return false; } }); } _document.on('keydown'+ns, function(e) { if (e.keyCode === 37) { mfp.prev(); } else if (e.keyCode === 39) { mfp.next(); } }); }); _mfpOn('UpdateStatus'+ns, function(e, data) { if(data.text) { data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length); } }); _mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) { var l = mfp.items.length; values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : ''; }); _mfpOn('BuildControls' + ns, function() { if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) { var markup = gSt.arrowMarkup, arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS), arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS); var eName = supportsFastClick ? 'mfpFastClick' : 'click'; arrowLeft[eName](function() { mfp.prev(); }); arrowRight[eName](function() { mfp.next(); }); // Polyfill for :before and :after (adds elements with classes mfp-a and mfp-b) if(mfp.isIE7) { _getEl('b', arrowLeft[0], false, true); _getEl('a', arrowLeft[0], false, true); _getEl('b', arrowRight[0], false, true); _getEl('a', arrowRight[0], false, true); } mfp.container.append(arrowLeft.add(arrowRight)); } }); _mfpOn(CHANGE_EVENT+ns, function() { if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout); mfp._preloadTimeout = setTimeout(function() { mfp.preloadNearbyImages(); mfp._preloadTimeout = null; }, 16); }); _mfpOn(CLOSE_EVENT+ns, function() { _document.off(ns); mfp.wrap.off('click'+ns); if(mfp.arrowLeft && supportsFastClick) { mfp.arrowLeft.add(mfp.arrowRight).destroyMfpFastClick(); } mfp.arrowRight = mfp.arrowLeft = null; }); }, next: function() { mfp.direction = true; mfp.index = _getLoopedId(mfp.index + 1); mfp.updateItemHTML(); }, prev: function() { mfp.direction = false; mfp.index = _getLoopedId(mfp.index - 1); mfp.updateItemHTML(); }, goTo: function(newIndex) { mfp.direction = (newIndex >= mfp.index); mfp.index = newIndex; mfp.updateItemHTML(); }, preloadNearbyImages: function() { var p = mfp.st.gallery.preload, preloadBefore = Math.min(p[0], mfp.items.length), preloadAfter = Math.min(p[1], mfp.items.length), i; for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) { mfp._preloadItem(mfp.index+i); } for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) { mfp._preloadItem(mfp.index-i); } }, _preloadItem: function(index) { index = _getLoopedId(index); if(mfp.items[index].preloaded) { return; } var item = mfp.items[index]; if(!item.parsed) { item = mfp.parseEl( index ); } _mfpTrigger('LazyLoad', item); if(item.type === 'image') { item.img = $('').on('load.mfploader', function() { item.hasSize = true; }).on('error.mfploader', function() { item.hasSize = true; item.loadError = true; _mfpTrigger('LazyLoadError', item); }).attr('src', item.src); } item.preloaded = true; } } }); /* Touch Support that might be implemented some day addSwipeGesture: function() { var startX, moved, multipleTouches; return; var namespace = '.mfp', addEventNames = function(pref, down, move, up, cancel) { mfp._tStart = pref + down + namespace; mfp._tMove = pref + move + namespace; mfp._tEnd = pref + up + namespace; mfp._tCancel = pref + cancel + namespace; }; if(window.navigator.msPointerEnabled) { addEventNames('MSPointer', 'Down', 'Move', 'Up', 'Cancel'); } else if('ontouchstart' in window) { addEventNames('touch', 'start', 'move', 'end', 'cancel'); } else { return; } _window.on(mfp._tStart, function(e) { var oE = e.originalEvent; multipleTouches = moved = false; startX = oE.pageX || oE.changedTouches[0].pageX; }).on(mfp._tMove, function(e) { if(e.originalEvent.touches.length > 1) { multipleTouches = e.originalEvent.touches.length; } else { //e.preventDefault(); moved = true; } }).on(mfp._tEnd + ' ' + mfp._tCancel, function(e) { if(moved && !multipleTouches) { var oE = e.originalEvent, diff = startX - (oE.pageX || oE.changedTouches[0].pageX); if(diff > 20) { mfp.next(); } else if(diff < -20) { mfp.prev(); } } }); }, */ /*>>gallery*/ /*>>retina*/ var RETINA_NS = 'retina'; $.magnificPopup.registerModule(RETINA_NS, { options: { replaceSrc: function(item) { return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; }); }, ratio: 1 // Function or number. Set to 1 to disable. }, proto: { initRetina: function() { if(window.devicePixelRatio > 1) { var st = mfp.st.retina, ratio = st.ratio; ratio = !isNaN(ratio) ? ratio : ratio(); if(ratio > 1) { _mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) { item.img.css({ 'max-width': item.img[0].naturalWidth / ratio, 'width': '100%' }); }); _mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) { item.src = st.replaceSrc(item, ratio); }); } } } } }); /*>>retina*/ /*>>fastclick*/ /** * FastClick event implementation. (removes 300ms delay on touch devices) * Based on https://developers.google.com/mobile/articles/fast_buttons * * You may use it outside the Magnific Popup by calling just: * * $('.your-el').mfpFastClick(function() { * console.log('Clicked!'); * }); * * To unbind: * $('.your-el').destroyMfpFastClick(); * * * Note that it's a very basic and simple implementation, it blocks ghost click on the same element where it was bound. * If you need something more advanced, use plugin by FT Labs https://github.com/ftlabs/fastclick * */ (function() { var ghostClickDelay = 1000, supportsTouch = 'ontouchstart' in window, unbindTouchMove = function() { _window.off('touchmove'+ns+' touchend'+ns); }, eName = 'mfpFastClick', ns = '.'+eName; // As Zepto.js doesn't have an easy way to add custom events (like jQuery), so we implement it in this way $.fn.mfpFastClick = function(callback) { return $(this).each(function() { var elem = $(this), lock; if( supportsTouch ) { var timeout, startX, startY, pointerMoved, point, numPointers; elem.on('touchstart' + ns, function(e) { pointerMoved = false; numPointers = 1; point = e.originalEvent ? e.originalEvent.touches[0] : e.touches[0]; startX = point.clientX; startY = point.clientY; _window.on('touchmove'+ns, function(e) { point = e.originalEvent ? e.originalEvent.touches : e.touches; numPointers = point.length; point = point[0]; if (Math.abs(point.clientX - startX) > 10 || Math.abs(point.clientY - startY) > 10) { pointerMoved = true; unbindTouchMove(); } }).on('touchend'+ns, function(e) { unbindTouchMove(); if(pointerMoved || numPointers > 1) { return; } lock = true; e.preventDefault(); clearTimeout(timeout); timeout = setTimeout(function() { lock = false; }, ghostClickDelay); callback(); }); }); } elem.on('click' + ns, function() { if(!lock) { callback(); } }); }); }; $.fn.destroyMfpFastClick = function() { $(this).off('touchstart' + ns + ' click' + ns); if(supportsTouch) _window.off('touchmove'+ns+' touchend'+ns); }; })(); /*>>fastclick*/ _checkInstance(); }));rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/dsa-ww.js0000644000076400007640000000172212572247340030734 0ustar pravipravi; (function(root) { "use strict"; root.OTR = {} root.crypto = {} root.DSA = {}; // default imports var imports = [ 'build/dep/salsa20.js', 'build/dep/bigint.js', 'build/dep/crypto.js', 'build/dep/eventemitter.js', 'lib/const.js', 'lib/helpers.js', 'lib/dsa.js', ] function sendMsg(type, data) { postMessage({ type: type, data: data, }) } self.onmessage = function(e) { var data = e.data; root.crypto = { getRandomValues: function() { var buf = data.random; } }; if (data.imports) imports = data.imports importScripts.apply(self, imports); sendMsg('debug', 'DSA key creation started') var dsa = new DSA() sendMsg('debug', 'DSA key creation finished') sendMsg('data', {key: dsa.packPrivate()}) } }(this))rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/strophe.caps.js0000644000076400007640000002230412572247340032142 0ustar pravipravi/** * Entity Capabilities (XEP-0115) * * Depends on disco plugin. * * See: http://xmpp.org/extensions/xep-0115.html * * Authors: - Michael Weibel - Klaus Herberth * Copyright: - Michael Weibel * * @license MIT */ (function($) { Strophe.addConnectionPlugin('caps', { /** * Constant: HASH Hash used * * Currently only sha-1 is supported. */ HASH: 'sha-1', /** * Variable: node Client which is being used. * * Can be overwritten as soon as Strophe has been initialized. */ node: 'http://strophe.im/strophejs/', /** * PrivateVariable: _ver Own generated version string */ _ver: '', /** * PrivateVariable: _connection Strophe connection */ _connection: null, /** * PrivateVariable: _knownCapabilities A hashtable containing * version-strings and their capabilities, serialized as string. * * TODO: Maybe those caps shouldn't be serialized. */ _knownCapabilities: JSON.parse(localStorage.getItem('strophe.caps._knownCapabilities')) || {}, /** * PrivateVariable: _jidVerIndex A hashtable containing jids and their * versions for better lookup of capabilities. */ _jidVerIndex: JSON.parse(localStorage.getItem('strophe.caps._jidVerIndex')) || {}, /** * Function: init Initialize plugin: - Add caps namespace - Add caps * feature to disco plugin - Add handler for caps stanzas * * Parameters: (Strophe.Connection) conn - Strophe connection */ init: function(conn) { this._connection = conn; Strophe.addNamespace('CAPS', 'http://jabber.org/protocol/caps'); if (!this._connection.disco) { throw "Caps plugin requires the disco plugin to be installed."; } this._connection.disco.addFeature(Strophe.NS.CAPS); this._connection.addHandler(this._delegateCapabilities.bind(this), Strophe.NS.CAPS); }, /** * Function: generateCapsAttrs Returns the attributes for generating the * "c"-stanza containing the own version * * Returns: (Object) - attributes */ generateCapsAttrs: function() { return { 'xmlns': Strophe.NS.CAPS, 'hash': this.HASH, 'node': this.node, 'ver': this.generateVer() }; }, /** * Function: generateVer Returns the base64 encoded version string * (encoded itself with sha1) * * Returns: (String) - version */ generateVer: function() { if (this._ver !== "") { return this._ver; } var ver = "", identities = this._connection.disco._identities.sort(this._sortIdentities), identitiesLen = identities.length, features = this._connection.disco._features.sort(), featuresLen = features.length; for (var i = 0; i < identitiesLen; i++) { var curIdent = identities[i]; ver += curIdent.category + "/" + curIdent.type + "/" + curIdent.lang + "/" + curIdent.name + "<"; } for (var i = 0; i < featuresLen; i++) { ver += features[i] + '<'; } this._ver = b64_sha1(ver); return this._ver; }, /** * Function: getCapabilitiesByJid Returns serialized capabilities of a jid * (if available). Otherwise null. * * Parameters: (String) jid - Jabber id * * Returns: (String|null) - capabilities, serialized; or null when not * available. */ getCapabilitiesByJid: function(jid) { if (this._jidVerIndex[jid]) { return this._knownCapabilities[this._jidVerIndex[jid]]; } return null; }, hasFeatureByJid: function(jid, feature) { if (this._jidVerIndex[jid] && feature !== null && typeof feature !== 'undefined') { if(!$.isArray(feature)){ feature = $.makeArray(feature); }; var i; for (i = 0; i < feature.length; i++) { if (this._knownCapabilities[this._jidVerIndex[jid]]['features'].indexOf(feature[i]) < 0) return false; } return true; } return false; }, /** * PrivateFunction: _delegateCapabilities Checks if the version has * already been saved. If yes: do nothing. If no: Request capabilities * * Parameters: (Strophe.Builder) stanza - Stanza * * Returns: (Boolean) */ _delegateCapabilities: function(stanza) { var from = stanza.getAttribute('from'), c = stanza.querySelector('c'), ver = c.getAttribute('ver'), node = c.getAttribute('node'); if (!this._knownCapabilities[ver]) { return this._requestCapabilities(from, node, ver); } else { this._jidVerIndex[from] = ver; } if (!this._jidVerIndex[from] || !this._jidVerIndex[from] !== ver) { this._jidVerIndex[from] = ver; } localStorage.setItem('strophe.caps._jidVerIndex', JSON.stringify(this._jidVerIndex)); $(document).trigger('caps.strophe', [ from ]); return true; }, /** * PrivateFunction: _requestCapabilities Requests capabilities from the * one which sent the caps-info stanza. This is done using disco info. * * Additionally, it registers a handler for handling the reply. * * Parameters: (String) to - Destination jid (String) node - Node * attribute of the caps-stanza (String) ver - Version of the caps-stanza * * Returns: (Boolean) - true */ _requestCapabilities: function(to, node, ver) { if (to !== this._connection.jid) { var id = this._connection.disco.info(to, node + '#' + ver); this._connection.addHandler(this._handleDiscoInfoReply.bind(this), Strophe.NS.DISCO_INFO, 'iq', 'result', id, to); } return true; }, /** * PrivateFunction: _handleDiscoInfoReply Parses the disco info reply and * adds the version & it's capabilities to the _knownCapabilities * variable. Additionally, it adds the jid & the version to the * _jidVerIndex variable for a better lookup. * * Parameters: (Strophe.Builder) stanza - Disco info stanza * * Returns: (Boolean) - false, to automatically remove the handler. */ _handleDiscoInfoReply: function(stanza) { var query = stanza.querySelector('query'); var from = stanza.getAttribute('from'); var node = query.getAttribute('node'); var ver = (node)? node.split('#')[1] : this._jidVerIndex[from]; //fix open prosody issue if (!this._knownCapabilities[ver]) { var childNodes = query.childNodes, childNodesLen = childNodes.length; this._knownCapabilities[ver] = { features: [], identities: [] }; for (var i = 0; i < childNodesLen; i++) { var node = childNodes[i]; if (node.nodeName == 'feature') { this._knownCapabilities[ver]['features'].push(node.getAttribute('var')); } else if (node.nodeName == 'identity') { this._knownCapabilities[ver]['identities'].push(this._attributesToJsObject(node.attributes)); } else { if (typeof this._knownCapabilities[ver][node.nodeName] === 'undefined') this._knownCapabilities[ver][node.nodeName] = []; this._knownCapabilities[ver][node.nodeName].push(this._attributesToJsObject(node.attributes)); } } this._jidVerIndex[from] = ver; } else if (!this._jidVerIndex[from] || !this._jidVerIndex[from] !== ver) { this._jidVerIndex[from] = ver; } localStorage.setItem('strophe.caps._jidVerIndex', JSON.stringify(this._jidVerIndex)); localStorage.setItem('strophe.caps._knownCapabilities', JSON.stringify(this._knownCapabilities)); $(document).trigger('caps.strophe', [ from ]); return false; }, _attributesToJsObject: function(attr) { var obj = {}; for (i = 0; i < attr.length; i++) obj[attr[i].name] = attr[i].value; return obj; }, /** * PrivateFunction: _sortIdentities Sorts two identities according the * sorting requirements in XEP-0115. * * Parameters: (Object) a - Identity a (Object) b - Identity b * * Returns: (Integer) - 1, 0 or -1; according to which one's greater. */ _sortIdentities: function(a, b) { if (a.category > b.category) { return 1; } if (a.category < b.category) { return -1; } if (a.type > b.type) { return 1; } if (a.type < b.type) { return -1; } if (a.lang > b.lang) { return 1; } if (a.lang < b.lang) { return -1; } return 0; } }); }(jQuery)); rails-assets-diaspora-jsxc-0.1.4.alpha.1/app/assets/javascripts/diaspora_jsxc/lib/strophe.disco.js0000644000076400007640000001511612572247340032320 0ustar pravipravi/* Copyright 2010, François de Metz */ /** * Disco Strophe Plugin * Implement http://xmpp.org/extensions/xep-0030.html * TODO: manage node hierarchies, and node on info request */ Strophe.addConnectionPlugin('disco', { _connection: null, _identities : [], _features : [], _items : [], /** Function: init * Plugin init * * Parameters: * (Strophe.Connection) conn - Strophe connection */ init: function(conn) { this._connection = conn; this._identities = []; this._features = []; this._items = []; // disco info conn.addHandler(this._onDiscoInfo.bind(this), Strophe.NS.DISCO_INFO, 'iq', 'get', null, null); // disco items conn.addHandler(this._onDiscoItems.bind(this), Strophe.NS.DISCO_ITEMS, 'iq', 'get', null, null); }, /** Function: addIdentity * See http://xmpp.org/registrar/disco-categories.html * Parameters: * (String) category - category of identity (like client, automation, etc ...) * (String) type - type of identity (like pc, web, bot , etc ...) * (String) name - name of identity in natural language * (String) lang - lang of name parameter * * Returns: * Boolean */ addIdentity: function(category, type, name, lang) { for (var i=0; i * @license MIT */ var base64 = require('base64-js') var ieee754 = require('ieee754') var isArray = require('is-array') exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer exports.INSPECT_MAX_BYTES = 50 Buffer.poolSize = 8192 // not used by this implementation var kMaxLength = 0x3fffffff var rootParent = {} /** * If `Buffer.TYPED_ARRAY_SUPPORT`: * === true Use Uint8Array implementation (fastest) * === false Use Object implementation (most compatible, even IE6) * * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, * Opera 11.6+, iOS 4.2+. * * Note: * * - Implementation must support adding new properties to `Uint8Array` instances. * Firefox 4-29 lacked support, fixed in Firefox 30+. * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. * * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. * * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of * incorrect length in some situations. * * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will * get the Object implementation, which is slower but will work correctly. */ Buffer.TYPED_ARRAY_SUPPORT = (function () { try { var buf = new ArrayBuffer(0) var arr = new Uint8Array(buf) arr.foo = function () { return 42 } return arr.foo() === 42 && // typed array instances can be augmented typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` } catch (e) { return false } })() /** * Class: Buffer * ============= * * The Buffer constructor returns instances of `Uint8Array` that are augmented * with function properties for all the node `Buffer` API functions. We use * `Uint8Array` so that square bracket notation works as expected -- it returns * a single octet. * * By augmenting the instances, we can avoid modifying the `Uint8Array` * prototype. */ function Buffer (arg) { if (!(this instanceof Buffer)) { // Avoid going through an ArgumentsAdaptorTrampoline in the common case. if (arguments.length > 1) return new Buffer(arg, arguments[1]) return new Buffer(arg) } this.length = 0 this.parent = undefined // Common case. if (typeof arg === 'number') { return fromNumber(this, arg) } // Slightly less common case. if (typeof arg === 'string') { return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') } // Unusual. return fromObject(this, arg) } function fromNumber (that, length) { that = allocate(that, length < 0 ? 0 : checked(length) | 0) if (!Buffer.TYPED_ARRAY_SUPPORT) { for (var i = 0; i < length; i++) { that[i] = 0 } } return that } function fromString (that, string, encoding) { if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' // Assumption: byteLength() return value is always < kMaxLength. var length = byteLength(string, encoding) | 0 that = allocate(that, length) that.write(string, encoding) return that } function fromObject (that, object) { if (Buffer.isBuffer(object)) return fromBuffer(that, object) if (isArray(object)) return fromArray(that, object) if (object == null) { throw new TypeError('must start with number, buffer, array or string') } if (typeof ArrayBuffer !== 'undefined' && object.buffer instanceof ArrayBuffer) { return fromTypedArray(that, object) } if (object.length) return fromArrayLike(that, object) return fromJsonObject(that, object) } function fromBuffer (that, buffer) { var length = checked(buffer.length) | 0 that = allocate(that, length) buffer.copy(that, 0, 0, length) return that } function fromArray (that, array) { var length = checked(array.length) | 0 that = allocate(that, length) for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } // Duplicate of fromArray() to keep fromArray() monomorphic. function fromTypedArray (that, array) { var length = checked(array.length) | 0 that = allocate(that, length) // Truncating the elements is probably not what people expect from typed // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior // of the old Buffer constructor. for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } function fromArrayLike (that, array) { var length = checked(array.length) | 0 that = allocate(that, length) for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. // Returns a zero-length buffer for inputs that don't conform to the spec. function fromJsonObject (that, object) { var array var length = 0 if (object.type === 'Buffer' && isArray(object.data)) { array = object.data length = checked(array.length) | 0 } that = allocate(that, length) for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } function allocate (that, length) { if (Buffer.TYPED_ARRAY_SUPPORT) { // Return an augmented `Uint8Array` instance, for best performance that = Buffer._augment(new Uint8Array(length)) } else { // Fallback: Return an object instance of the Buffer class that.length = length that._isBuffer = true } var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 if (fromPool) that.parent = rootParent return that } function checked (length) { // Note: cannot use `length < kMaxLength` here because that fails when // length is NaN (which is otherwise coerced to zero.) if (length >= kMaxLength) { throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + kMaxLength.toString(16) + ' bytes') } return length | 0 } function SlowBuffer (subject, encoding) { if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) var buf = new Buffer(subject, encoding) delete buf.parent return buf } Buffer.isBuffer = function isBuffer (b) { return !!(b != null && b._isBuffer) } Buffer.compare = function compare (a, b) { if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { throw new TypeError('Arguments must be Buffers') } if (a === b) return 0 var x = a.length var y = b.length var i = 0 var len = Math.min(x, y) while (i < len) { if (a[i] !== b[i]) break ++i } if (i !== len) { x = a[i] y = b[i] } if (x < y) return -1 if (y < x) return 1 return 0 } Buffer.isEncoding = function isEncoding (encoding) { switch (String(encoding).toLowerCase()) { case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'raw': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return true default: return false } } Buffer.concat = function concat (list, length) { if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') if (list.length === 0) { return new Buffer(0) } else if (list.length === 1) { return list[0] } var i if (length === undefined) { length = 0 for (i = 0; i < list.length; i++) { length += list[i].length } } var buf = new Buffer(length) var pos = 0 for (i = 0; i < list.length; i++) { var item = list[i] item.copy(buf, pos) pos += item.length } return buf } function byteLength (string, encoding) { if (typeof string !== 'string') string = String(string) if (string.length === 0) return 0 switch (encoding || 'utf8') { case 'ascii': case 'binary': case 'raw': return string.length case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return string.length * 2 case 'hex': return string.length >>> 1 case 'utf8': case 'utf-8': return utf8ToBytes(string).length case 'base64': return base64ToBytes(string).length default: return string.length } } Buffer.byteLength = byteLength // pre-set for values that may exist in the future Buffer.prototype.length = undefined Buffer.prototype.parent = undefined // toString(encoding, start=0, end=buffer.length) Buffer.prototype.toString = function toString (encoding, start, end) { var loweredCase = false start = start | 0 end = end === undefined || end === Infinity ? this.length : end | 0 if (!encoding) encoding = 'utf8' if (start < 0) start = 0 if (end > this.length) end = this.length if (end <= start) return '' while (true) { switch (encoding) { case 'hex': return hexSlice(this, start, end) case 'utf8': case 'utf-8': return utf8Slice(this, start, end) case 'ascii': return asciiSlice(this, start, end) case 'binary': return binarySlice(this, start, end) case 'base64': return base64Slice(this, start, end) case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return utf16leSlice(this, start, end) default: if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) encoding = (encoding + '').toLowerCase() loweredCase = true } } } Buffer.prototype.equals = function equals (b) { if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') if (this === b) return true return Buffer.compare(this, b) === 0 } Buffer.prototype.inspect = function inspect () { var str = '' var max = exports.INSPECT_MAX_BYTES if (this.length > 0) { str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') if (this.length > max) str += ' ... ' } return '' } Buffer.prototype.compare = function compare (b) { if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') if (this === b) return 0 return Buffer.compare(this, b) } Buffer.prototype.indexOf = function indexOf (val, byteOffset) { if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff else if (byteOffset < -0x80000000) byteOffset = -0x80000000 byteOffset >>= 0 if (this.length === 0) return -1 if (byteOffset >= this.length) return -1 // Negative offsets start from the end of the buffer if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) if (typeof val === 'string') { if (val.length === 0) return -1 // special case: looking for empty string always fails return String.prototype.indexOf.call(this, val, byteOffset) } if (Buffer.isBuffer(val)) { return arrayIndexOf(this, val, byteOffset) } if (typeof val === 'number') { if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { return Uint8Array.prototype.indexOf.call(this, val, byteOffset) } return arrayIndexOf(this, [ val ], byteOffset) } function arrayIndexOf (arr, val, byteOffset) { var foundIndex = -1 for (var i = 0; byteOffset + i < arr.length; i++) { if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { if (foundIndex === -1) foundIndex = i if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex } else { foundIndex = -1 } } return -1 } throw new TypeError('val must be string, number or Buffer') } // `get` will be removed in Node 0.13+ Buffer.prototype.get = function get (offset) { console.log('.get() is deprecated. Access using array indexes instead.') return this.readUInt8(offset) } // `set` will be removed in Node 0.13+ Buffer.prototype.set = function set (v, offset) { console.log('.set() is deprecated. Access using array indexes instead.') return this.writeUInt8(v, offset) } function hexWrite (buf, string, offset, length) { offset = Number(offset) || 0 var remaining = buf.length - offset if (!length) { length = remaining } else { length = Number(length) if (length > remaining) { length = remaining } } // must be an even number of digits var strLen = string.length if (strLen % 2 !== 0) throw new Error('Invalid hex string') if (length > strLen / 2) { length = strLen / 2 } for (var i = 0; i < length; i++) { var parsed = parseInt(string.substr(i * 2, 2), 16) if (isNaN(parsed)) throw new Error('Invalid hex string') buf[offset + i] = parsed } return i } function utf8Write (buf, string, offset, length) { return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) } function asciiWrite (buf, string, offset, length) { return blitBuffer(asciiToBytes(string), buf, offset, length) } function binaryWrite (buf, string, offset, length) { return asciiWrite(buf, string, offset, length) } function base64Write (buf, string, offset, length) { return blitBuffer(base64ToBytes(string), buf, offset, length) } function ucs2Write (buf, string, offset, length) { return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) } Buffer.prototype.write = function write (string, offset, length, encoding) { // Buffer#write(string) if (offset === undefined) { encoding = 'utf8' length = this.length offset = 0 // Buffer#write(string, encoding) } else if (length === undefined && typeof offset === 'string') { encoding = offset length = this.length offset = 0 // Buffer#write(string, offset[, length][, encoding]) } else if (isFinite(offset)) { offset = offset | 0 if (isFinite(length)) { length = length | 0 if (encoding === undefined) encoding = 'utf8' } else { encoding = length length = undefined } // legacy write(string, encoding, offset, length) - remove in v0.13 } else { var swap = encoding encoding = offset offset = length | 0 length = swap } var remaining = this.length - offset if (length === undefined || length > remaining) length = remaining if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { throw new RangeError('attempt to write outside buffer bounds') } if (!encoding) encoding = 'utf8' var loweredCase = false for (;;) { switch (encoding) { case 'hex': return hexWrite(this, string, offset, length) case 'utf8': case 'utf-8': return utf8Write(this, string, offset, length) case 'ascii': return asciiWrite(this, string, offset, length) case 'binary': return binaryWrite(this, string, offset, length) case 'base64': // Warning: maxLength not taken into account in base64Write return base64Write(this, string, offset, length) case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return ucs2Write(this, string, offset, length) default: if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) encoding = ('' + encoding).toLowerCase() loweredCase = true } } } Buffer.prototype.toJSON = function toJSON () { return { type: 'Buffer', data: Array.prototype.slice.call(this._arr || this, 0) } } function base64Slice (buf, start, end) { if (start === 0 && end === buf.length) { return base64.fromByteArray(buf) } else { return base64.fromByteArray(buf.slice(start, end)) } } function utf8Slice (buf, start, end) { var res = '' var tmp = '' end = Math.min(buf.length, end) for (var i = start; i < end; i++) { if (buf[i] <= 0x7F) { res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) tmp = '' } else { tmp += '%' + buf[i].toString(16) } } return res + decodeUtf8Char(tmp) } function asciiSlice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) for (var i = start; i < end; i++) { ret += String.fromCharCode(buf[i] & 0x7F) } return ret } function binarySlice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) for (var i = start; i < end; i++) { ret += String.fromCharCode(buf[i]) } return ret } function hexSlice (buf, start, end) { var len = buf.length if (!start || start < 0) start = 0 if (!end || end < 0 || end > len) end = len var out = '' for (var i = start; i < end; i++) { out += toHex(buf[i]) } return out } function utf16leSlice (buf, start, end) { var bytes = buf.slice(start, end) var res = '' for (var i = 0; i < bytes.length; i += 2) { res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) } return res } Buffer.prototype.slice = function slice (start, end) { var len = this.length start = ~~start end = end === undefined ? len : ~~end if (start < 0) { start += len if (start < 0) start = 0 } else if (start > len) { start = len } if (end < 0) { end += len if (end < 0) end = 0 } else if (end > len) { end = len } if (end < start) end = start var newBuf if (Buffer.TYPED_ARRAY_SUPPORT) { newBuf = Buffer._augment(this.subarray(start, end)) } else { var sliceLen = end - start newBuf = new Buffer(sliceLen, undefined) for (var i = 0; i < sliceLen; i++) { newBuf[i] = this[i + start] } } if (newBuf.length) newBuf.parent = this.parent || this return newBuf } /* * Need to make sure that buffer isn't trying to write out of bounds. */ function checkOffset (offset, ext, length) { if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') } Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < byteLength && (mul *= 0x100)) { val += this[offset + i] * mul } return val } Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) { checkOffset(offset, byteLength, this.length) } var val = this[offset + --byteLength] var mul = 1 while (byteLength > 0 && (mul *= 0x100)) { val += this[offset + --byteLength] * mul } return val } Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { if (!noAssert) checkOffset(offset, 1, this.length) return this[offset] } Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) return this[offset] | (this[offset + 1] << 8) } Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) return (this[offset] << 8) | this[offset + 1] } Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ((this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16)) + (this[offset + 3] * 0x1000000) } Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] * 0x1000000) + ((this[offset + 1] << 16) | (this[offset + 2] << 8) | this[offset + 3]) } Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < byteLength && (mul *= 0x100)) { val += this[offset + i] * mul } mul *= 0x80 if (val >= mul) val -= Math.pow(2, 8 * byteLength) return val } Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var i = byteLength var mul = 1 var val = this[offset + --i] while (i > 0 && (mul *= 0x100)) { val += this[offset + --i] * mul } mul *= 0x80 if (val >= mul) val -= Math.pow(2, 8 * byteLength) return val } Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { if (!noAssert) checkOffset(offset, 1, this.length) if (!(this[offset] & 0x80)) return (this[offset]) return ((0xff - this[offset] + 1) * -1) } Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset] | (this[offset + 1] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset + 1] | (this[offset] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16) | (this[offset + 3] << 24) } Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] << 24) | (this[offset + 1] << 16) | (this[offset + 2] << 8) | (this[offset + 3]) } Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, true, 23, 4) } Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, false, 23, 4) } Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, true, 52, 8) } Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, false, 52, 8) } function checkInt (buf, value, offset, ext, max, min) { if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') if (value > max || value < min) throw new RangeError('value is out of bounds') if (offset + ext > buf.length) throw new RangeError('index out of range') } Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) var mul = 1 var i = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF } return offset + byteLength } Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) var i = byteLength - 1 var mul = 1 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF } return offset + byteLength } Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) this[offset] = value return offset + 1 } function objectWriteUInt16 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffff + value + 1 for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> (littleEndian ? i : 1 - i) * 8 } } Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = value this[offset + 1] = (value >>> 8) } else { objectWriteUInt16(this, value, offset, true) } return offset + 2 } Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 8) this[offset + 1] = value } else { objectWriteUInt16(this, value, offset, false) } return offset + 2 } function objectWriteUInt32 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffffffff + value + 1 for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff } } Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset + 3] = (value >>> 24) this[offset + 2] = (value >>> 16) this[offset + 1] = (value >>> 8) this[offset] = value } else { objectWriteUInt32(this, value, offset, true) } return offset + 4 } Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = value } else { objectWriteUInt32(this, value, offset, false) } return offset + 4 } Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 if (!noAssert) { var limit = Math.pow(2, 8 * byteLength - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } var i = 0 var mul = 1 var sub = value < 0 ? 1 : 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } return offset + byteLength } Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 if (!noAssert) { var limit = Math.pow(2, 8 * byteLength - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } var i = byteLength - 1 var mul = 1 var sub = value < 0 ? 1 : 0 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } return offset + byteLength } Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) if (value < 0) value = 0xff + value + 1 this[offset] = value return offset + 1 } Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = value this[offset + 1] = (value >>> 8) } else { objectWriteUInt16(this, value, offset, true) } return offset + 2 } Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 8) this[offset + 1] = value } else { objectWriteUInt16(this, value, offset, false) } return offset + 2 } Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = value this[offset + 1] = (value >>> 8) this[offset + 2] = (value >>> 16) this[offset + 3] = (value >>> 24) } else { objectWriteUInt32(this, value, offset, true) } return offset + 4 } Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) if (value < 0) value = 0xffffffff + value + 1 if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = value } else { objectWriteUInt32(this, value, offset, false) } return offset + 4 } function checkIEEE754 (buf, value, offset, ext, max, min) { if (value > max || value < min) throw new RangeError('value is out of bounds') if (offset + ext > buf.length) throw new RangeError('index out of range') if (offset < 0) throw new RangeError('index out of range') } function writeFloat (buf, value, offset, littleEndian, noAssert) { if (!noAssert) { checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) } ieee754.write(buf, value, offset, littleEndian, 23, 4) return offset + 4 } Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { return writeFloat(this, value, offset, true, noAssert) } Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { return writeFloat(this, value, offset, false, noAssert) } function writeDouble (buf, value, offset, littleEndian, noAssert) { if (!noAssert) { checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) } ieee754.write(buf, value, offset, littleEndian, 52, 8) return offset + 8 } Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { return writeDouble(this, value, offset, true, noAssert) } Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { return writeDouble(this, value, offset, false, noAssert) } // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) Buffer.prototype.copy = function copy (target, targetStart, start, end) { if (!start) start = 0 if (!end && end !== 0) end = this.length if (targetStart >= target.length) targetStart = target.length if (!targetStart) targetStart = 0 if (end > 0 && end < start) end = start // Copy 0 bytes; we're done if (end === start) return 0 if (target.length === 0 || this.length === 0) return 0 // Fatal error conditions if (targetStart < 0) { throw new RangeError('targetStart out of bounds') } if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') if (end < 0) throw new RangeError('sourceEnd out of bounds') // Are we oob? if (end > this.length) end = this.length if (target.length - targetStart < end - start) { end = target.length - targetStart + start } var len = end - start if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { for (var i = 0; i < len; i++) { target[i + targetStart] = this[i + start] } } else { target._set(this.subarray(start, start + len), targetStart) } return len } // fill(value, start=0, end=buffer.length) Buffer.prototype.fill = function fill (value, start, end) { if (!value) value = 0 if (!start) start = 0 if (!end) end = this.length if (end < start) throw new RangeError('end < start') // Fill 0 bytes; we're done if (end === start) return if (this.length === 0) return if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') if (end < 0 || end > this.length) throw new RangeError('end out of bounds') var i if (typeof value === 'number') { for (i = start; i < end; i++) { this[i] = value } } else { var bytes = utf8ToBytes(value.toString()) var len = bytes.length for (i = start; i < end; i++) { this[i] = bytes[i % len] } } return this } /** * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. * Added in Node 0.12. Only available in browsers that support ArrayBuffer. */ Buffer.prototype.toArrayBuffer = function toArrayBuffer () { if (typeof Uint8Array !== 'undefined') { if (Buffer.TYPED_ARRAY_SUPPORT) { return (new Buffer(this)).buffer } else { var buf = new Uint8Array(this.length) for (var i = 0, len = buf.length; i < len; i += 1) { buf[i] = this[i] } return buf.buffer } } else { throw new TypeError('Buffer.toArrayBuffer not supported in this browser') } } // HELPER FUNCTIONS // ================ var BP = Buffer.prototype /** * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods */ Buffer._augment = function _augment (arr) { arr.constructor = Buffer arr._isBuffer = true // save reference to original Uint8Array set method before overwriting arr._set = arr.set // deprecated, will be removed in node 0.13+ arr.get = BP.get arr.set = BP.set arr.write = BP.write arr.toString = BP.toString arr.toLocaleString = BP.toString arr.toJSON = BP.toJSON arr.equals = BP.equals arr.compare = BP.compare arr.indexOf = BP.indexOf arr.copy = BP.copy arr.slice = BP.slice arr.readUIntLE = BP.readUIntLE arr.readUIntBE = BP.readUIntBE arr.readUInt8 = BP.readUInt8 arr.readUInt16LE = BP.readUInt16LE arr.readUInt16BE = BP.readUInt16BE arr.readUInt32LE = BP.readUInt32LE arr.readUInt32BE = BP.readUInt32BE arr.readIntLE = BP.readIntLE arr.readIntBE = BP.readIntBE arr.readInt8 = BP.readInt8 arr.readInt16LE = BP.readInt16LE arr.readInt16BE = BP.readInt16BE arr.readInt32LE = BP.readInt32LE arr.readInt32BE = BP.readInt32BE arr.readFloatLE = BP.readFloatLE arr.readFloatBE = BP.readFloatBE arr.readDoubleLE = BP.readDoubleLE arr.readDoubleBE = BP.readDoubleBE arr.writeUInt8 = BP.writeUInt8 arr.writeUIntLE = BP.writeUIntLE arr.writeUIntBE = BP.writeUIntBE arr.writeUInt16LE = BP.writeUInt16LE arr.writeUInt16BE = BP.writeUInt16BE arr.writeUInt32LE = BP.writeUInt32LE arr.writeUInt32BE = BP.writeUInt32BE arr.writeIntLE = BP.writeIntLE arr.writeIntBE = BP.writeIntBE arr.writeInt8 = BP.writeInt8 arr.writeInt16LE = BP.writeInt16LE arr.writeInt16BE = BP.writeInt16BE arr.writeInt32LE = BP.writeInt32LE arr.writeInt32BE = BP.writeInt32BE arr.writeFloatLE = BP.writeFloatLE arr.writeFloatBE = BP.writeFloatBE arr.writeDoubleLE = BP.writeDoubleLE arr.writeDoubleBE = BP.writeDoubleBE arr.fill = BP.fill arr.inspect = BP.inspect arr.toArrayBuffer = BP.toArrayBuffer return arr } var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g function base64clean (str) { // Node strips out invalid characters like \n and \t from the string, base64-js does not str = stringtrim(str).replace(INVALID_BASE64_RE, '') // Node converts strings with length < 2 to '' if (str.length < 2) return '' // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not while (str.length % 4 !== 0) { str = str + '=' } return str } function stringtrim (str) { if (str.trim) return str.trim() return str.replace(/^\s+|\s+$/g, '') } function toHex (n) { if (n < 16) return '0' + n.toString(16) return n.toString(16) } function utf8ToBytes (string, units) { units = units || Infinity var codePoint var length = string.length var leadSurrogate = null var bytes = [] var i = 0 for (; i < length; i++) { codePoint = string.charCodeAt(i) // is surrogate component if (codePoint > 0xD7FF && codePoint < 0xE000) { // last char was a lead if (leadSurrogate) { // 2 leads in a row if (codePoint < 0xDC00) { if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) leadSurrogate = codePoint continue } else { // valid surrogate pair codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 leadSurrogate = null } } else { // no lead yet if (codePoint > 0xDBFF) { // unexpected trail if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) continue } else if (i + 1 === length) { // unpaired lead if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) continue } else { // valid lead leadSurrogate = codePoint continue } } } else if (leadSurrogate) { // valid bmp char, but last char was a lead if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) leadSurrogate = null } // encode utf8 if (codePoint < 0x80) { if ((units -= 1) < 0) break bytes.push(codePoint) } else if (codePoint < 0x800) { if ((units -= 2) < 0) break bytes.push( codePoint >> 0x6 | 0xC0, codePoint & 0x3F | 0x80 ) } else if (codePoint < 0x10000) { if ((units -= 3) < 0) break bytes.push( codePoint >> 0xC | 0xE0, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80 ) } else if (codePoint < 0x200000) { if ((units -= 4) < 0) break bytes.push( codePoint >> 0x12 | 0xF0, codePoint >> 0xC & 0x3F | 0x80, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80 ) } else { throw new Error('Invalid code point') } } return bytes } function asciiToBytes (str) { var byteArray = [] for (var i = 0; i < str.length; i++) { // Node's code seems to be doing this and not & 0x7F.. byteArray.push(str.charCodeAt(i) & 0xFF) } return byteArray } function utf16leToBytes (str, units) { var c, hi, lo var byteArray = [] for (var i = 0; i < str.length; i++) { if ((units -= 2) < 0) break c = str.charCodeAt(i) hi = c >> 8 lo = c % 256 byteArray.push(lo) byteArray.push(hi) } return byteArray } function base64ToBytes (str) { return base64.toByteArray(base64clean(str)) } function blitBuffer (src, dst, offset, length) { for (var i = 0; i < length; i++) { if ((i + offset >= dst.length) || (i >= src.length)) break dst[i + offset] = src[i] } return i } function decodeUtf8Char (str) { try { return decodeURIComponent(str) } catch (err) { return String.fromCharCode(0xFFFD) // UTF 8 invalid char } } },{"base64-js":3,"ieee754":4,"is-array":5}],3:[function(require,module,exports){ var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; ;(function (exports) { 'use strict'; var Arr = (typeof Uint8Array !== 'undefined') ? Uint8Array : Array var PLUS = '+'.charCodeAt(0) var SLASH = '/'.charCodeAt(0) var NUMBER = '0'.charCodeAt(0) var LOWER = 'a'.charCodeAt(0) var UPPER = 'A'.charCodeAt(0) var PLUS_URL_SAFE = '-'.charCodeAt(0) var SLASH_URL_SAFE = '_'.charCodeAt(0) function decode (elt) { var code = elt.charCodeAt(0) if (code === PLUS || code === PLUS_URL_SAFE) return 62 // '+' if (code === SLASH || code === SLASH_URL_SAFE) return 63 // '/' if (code < NUMBER) return -1 //no match if (code < NUMBER + 10) return code - NUMBER + 26 + 26 if (code < UPPER + 26) return code - UPPER if (code < LOWER + 26) return code - LOWER + 26 } function b64ToByteArray (b64) { var i, j, l, tmp, placeHolders, arr if (b64.length % 4 > 0) { throw new Error('Invalid string. Length must be a multiple of 4') } // the number of equal signs (place holders) // if there are two placeholders, than the two characters before it // represent one byte // if there is only one, then the three characters before it represent 2 bytes // this is just a cheap hack to not do indexOf twice var len = b64.length placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 // base64 is 4/3 + up to two characters of the original data arr = new Arr(b64.length * 3 / 4 - placeHolders) // if there are placeholders, only get up to the last complete 4 chars l = placeHolders > 0 ? b64.length - 4 : b64.length var L = 0 function push (v) { arr[L++] = v } for (i = 0, j = 0; i < l; i += 4, j += 3) { tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) push((tmp & 0xFF0000) >> 16) push((tmp & 0xFF00) >> 8) push(tmp & 0xFF) } if (placeHolders === 2) { tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) push(tmp & 0xFF) } else if (placeHolders === 1) { tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) push((tmp >> 8) & 0xFF) push(tmp & 0xFF) } return arr } function uint8ToBase64 (uint8) { var i, extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes output = "", temp, length function encode (num) { return lookup.charAt(num) } function tripletToBase64 (num) { return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) } // go through the array every three bytes, we'll deal with trailing stuff later for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) output += tripletToBase64(temp) } // pad the end with zeros, but make sure to not forget the extra bytes switch (extraBytes) { case 1: temp = uint8[uint8.length - 1] output += encode(temp >> 2) output += encode((temp << 4) & 0x3F) output += '==' break case 2: temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) output += encode(temp >> 10) output += encode((temp >> 4) & 0x3F) output += encode((temp << 2) & 0x3F) output += '=' break } return output } exports.toByteArray = b64ToByteArray exports.fromByteArray = uint8ToBase64 }(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) },{}],4:[function(require,module,exports){ exports.read = function (buffer, offset, isLE, mLen, nBytes) { var e, m var eLen = nBytes * 8 - mLen - 1 var eMax = (1 << eLen) - 1 var eBias = eMax >> 1 var nBits = -7 var i = isLE ? (nBytes - 1) : 0 var d = isLE ? -1 : 1 var s = buffer[offset + i] i += d e = s & ((1 << (-nBits)) - 1) s >>= (-nBits) nBits += eLen for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} m = e & ((1 << (-nBits)) - 1) e >>= (-nBits) nBits += mLen for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} if (e === 0) { e = 1 - eBias } else if (e === eMax) { return m ? NaN : ((s ? -1 : 1) * Infinity) } else { m = m + Math.pow(2, mLen) e = e - eBias } return (s ? -1 : 1) * m * Math.pow(2, e - mLen) } exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { var e, m, c var eLen = nBytes * 8 - mLen - 1 var eMax = (1 << eLen) - 1 var eBias = eMax >> 1 var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) var i = isLE ? 0 : (nBytes - 1) var d = isLE ? 1 : -1 var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 value = Math.abs(value) if (isNaN(value) || value === Infinity) { m = isNaN(value) ? 1 : 0 e = eMax } else { e = Math.floor(Math.log(value) / Math.LN2) if (value * (c = Math.pow(2, -e)) < 1) { e-- c *= 2 } if (e + eBias >= 1) { value += rt / c } else { value += rt * Math.pow(2, 1 - eBias) } if (value * c >= 2) { e++ c /= 2 } if (e + eBias >= eMax) { m = 0 e = eMax } else if (e + eBias >= 1) { m = (value * c - 1) * Math.pow(2, mLen) e = e + eBias } else { m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) e = 0 } } for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} e = (e << mLen) | m eLen += mLen for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} buffer[offset + i - d] |= s * 128 } },{}],5:[function(require,module,exports){ /** * isArray */ var isArray = Array.isArray; /** * toString */ var str = Object.prototype.toString; /** * Whether or not the given `val` * is an array. * * example: * * isArray([]); * // > true * isArray(arguments); * // > false * isArray(''); * // > false * * @param {mixed} val * @return {bool} */ module.exports = isArray || function (val) { return !! val && '[object Array]' == str.call(val); }; },{}],6:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function(n) { if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; }; EventEmitter.prototype.emit = function(type) { var er, handler, len, args, i, listeners; if (!this._events) this._events = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || (isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } throw TypeError('Uncaught, unspecified "error" event.'); } } handler = this._events[type]; if (isUndefined(handler)) return false; if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; handler.apply(this, args); } } else if (isObject(handler)) { len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } return true; }; EventEmitter.prototype.addListener = function(type, listener) { var m; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { var m; if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; } if (m && m > 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {}; else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; else if (isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); return ret; }; EventEmitter.listenerCount = function(emitter, type) { var ret; if (!emitter._events || !emitter._events[type]) ret = 0; else if (isFunction(emitter._events[type])) ret = 1; else ret = emitter._events[type].length; return ret; }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } },{}],7:[function(require,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { ctor.super_ = superCtor ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; } else { // old school shim for old browsers module.exports = function inherits(ctor, superCtor) { ctor.super_ = superCtor var TempCtor = function () {} TempCtor.prototype = superCtor.prototype ctor.prototype = new TempCtor() ctor.prototype.constructor = ctor } } },{}],8:[function(require,module,exports){ module.exports = Array.isArray || function (arr) { return Object.prototype.toString.call(arr) == '[object Array]'; }; },{}],9:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = setTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { currentQueue[queueIndex].run(); } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; clearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { setTimeout(drainQueue, 0); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); }; // TODO(shtylman) process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],10:[function(require,module,exports){ module.exports = require("./lib/_stream_duplex.js") },{"./lib/_stream_duplex.js":11}],11:[function(require,module,exports){ (function (process){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // a duplex stream is just a stream that is both readable and writable. // Since JS doesn't have multiple prototypal inheritance, this class // prototypally inherits from Readable, and then parasitically from // Writable. module.exports = Duplex; /**/ var objectKeys = Object.keys || function (obj) { var keys = []; for (var key in obj) keys.push(key); return keys; } /**/ /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ var Readable = require('./_stream_readable'); var Writable = require('./_stream_writable'); util.inherits(Duplex, Readable); forEach(objectKeys(Writable.prototype), function(method) { if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; }); function Duplex(options) { if (!(this instanceof Duplex)) return new Duplex(options); Readable.call(this, options); Writable.call(this, options); if (options && options.readable === false) this.readable = false; if (options && options.writable === false) this.writable = false; this.allowHalfOpen = true; if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; this.once('end', onend); } // the no-half-open enforcer function onend() { // if we allow half-open state, or if the writable side ended, // then we're ok. if (this.allowHalfOpen || this._writableState.ended) return; // no more data can be written. // But allow more writes to happen in this tick. process.nextTick(this.end.bind(this)); } function forEach (xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } }).call(this,require('_process')) },{"./_stream_readable":13,"./_stream_writable":15,"_process":9,"core-util-is":16,"inherits":7}],12:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // a passthrough stream. // basically just the most minimal sort of Transform stream. // Every written chunk gets output as-is. module.exports = PassThrough; var Transform = require('./_stream_transform'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ util.inherits(PassThrough, Transform); function PassThrough(options) { if (!(this instanceof PassThrough)) return new PassThrough(options); Transform.call(this, options); } PassThrough.prototype._transform = function(chunk, encoding, cb) { cb(null, chunk); }; },{"./_stream_transform":14,"core-util-is":16,"inherits":7}],13:[function(require,module,exports){ (function (process){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. module.exports = Readable; /**/ var isArray = require('isarray'); /**/ /**/ var Buffer = require('buffer').Buffer; /**/ Readable.ReadableState = ReadableState; var EE = require('events').EventEmitter; /**/ if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { return emitter.listeners(type).length; }; /**/ var Stream = require('stream'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ var StringDecoder; /**/ var debug = require('util'); if (debug && debug.debuglog) { debug = debug.debuglog('stream'); } else { debug = function () {}; } /**/ util.inherits(Readable, Stream); function ReadableState(options, stream) { var Duplex = require('./_stream_duplex'); options = options || {}; // the point at which it stops calling _read() to fill the buffer // Note: 0 is a valid value, means "don't call _read preemptively ever" var hwm = options.highWaterMark; var defaultHwm = options.objectMode ? 16 : 16 * 1024; this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; // cast to ints. this.highWaterMark = ~~this.highWaterMark; this.buffer = []; this.length = 0; this.pipes = null; this.pipesCount = 0; this.flowing = null; this.ended = false; this.endEmitted = false; this.reading = false; // a flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. this.sync = true; // whenever we return null, then we set a flag to say // that we're awaiting a 'readable' event emission. this.needReadable = false; this.emittedReadable = false; this.readableListening = false; // object stream flag. Used to make read(n) ignore n and to // make all the buffer merging and length checks go away this.objectMode = !!options.objectMode; if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; // when piping, we only care about 'readable' events that happen // after read()ing all the bytes and not getting any pushback. this.ranOut = false; // the number of writers that are awaiting a drain event in .pipe()s this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled this.readingMore = false; this.decoder = null; this.encoding = null; if (options.encoding) { if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; this.decoder = new StringDecoder(options.encoding); this.encoding = options.encoding; } } function Readable(options) { var Duplex = require('./_stream_duplex'); if (!(this instanceof Readable)) return new Readable(options); this._readableState = new ReadableState(options, this); // legacy this.readable = true; Stream.call(this); } // Manually shove something into the read() buffer. // This returns true if the highWaterMark has not been hit yet, // similar to how Writable.write() returns true if you should // write() some more. Readable.prototype.push = function(chunk, encoding) { var state = this._readableState; if (util.isString(chunk) && !state.objectMode) { encoding = encoding || state.defaultEncoding; if (encoding !== state.encoding) { chunk = new Buffer(chunk, encoding); encoding = ''; } } return readableAddChunk(this, state, chunk, encoding, false); }; // Unshift should *always* be something directly out of read() Readable.prototype.unshift = function(chunk) { var state = this._readableState; return readableAddChunk(this, state, chunk, '', true); }; function readableAddChunk(stream, state, chunk, encoding, addToFront) { var er = chunkInvalid(state, chunk); if (er) { stream.emit('error', er); } else if (util.isNullOrUndefined(chunk)) { state.reading = false; if (!state.ended) onEofChunk(stream, state); } else if (state.objectMode || chunk && chunk.length > 0) { if (state.ended && !addToFront) { var e = new Error('stream.push() after EOF'); stream.emit('error', e); } else if (state.endEmitted && addToFront) { var e = new Error('stream.unshift() after end event'); stream.emit('error', e); } else { if (state.decoder && !addToFront && !encoding) chunk = state.decoder.write(chunk); if (!addToFront) state.reading = false; // if we want the data now, just emit it. if (state.flowing && state.length === 0 && !state.sync) { stream.emit('data', chunk); stream.read(0); } else { // update the buffer info. state.length += state.objectMode ? 1 : chunk.length; if (addToFront) state.buffer.unshift(chunk); else state.buffer.push(chunk); if (state.needReadable) emitReadable(stream); } maybeReadMore(stream, state); } } else if (!addToFront) { state.reading = false; } return needMoreData(state); } // if it's past the high water mark, we can push in some more. // Also, if we have no data yet, we can stand some // more bytes. This is to work around cases where hwm=0, // such as the repl. Also, if the push() triggered a // readable event, and the user called read(largeNumber) such that // needReadable was set, then we ought to push more, so that another // 'readable' event will be triggered. function needMoreData(state) { return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); } // backwards compatibility. Readable.prototype.setEncoding = function(enc) { if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; this._readableState.decoder = new StringDecoder(enc); this._readableState.encoding = enc; return this; }; // Don't raise the hwm > 128MB var MAX_HWM = 0x800000; function roundUpToNextPowerOf2(n) { if (n >= MAX_HWM) { n = MAX_HWM; } else { // Get the next highest power of 2 n--; for (var p = 1; p < 32; p <<= 1) n |= n >> p; n++; } return n; } function howMuchToRead(n, state) { if (state.length === 0 && state.ended) return 0; if (state.objectMode) return n === 0 ? 0 : 1; if (isNaN(n) || util.isNull(n)) { // only flow one buffer at a time if (state.flowing && state.buffer.length) return state.buffer[0].length; else return state.length; } if (n <= 0) return 0; // If we're asking for more than the target buffer level, // then raise the water mark. Bump up to the next highest // power of 2, to prevent increasing it excessively in tiny // amounts. if (n > state.highWaterMark) state.highWaterMark = roundUpToNextPowerOf2(n); // don't have that much. return null, unless we've ended. if (n > state.length) { if (!state.ended) { state.needReadable = true; return 0; } else return state.length; } return n; } // you can override either this method, or the async _read(n) below. Readable.prototype.read = function(n) { debug('read', n); var state = this._readableState; var nOrig = n; if (!util.isNumber(n) || n > 0) state.emittedReadable = false; // if we're doing read(0) to trigger a readable event, but we // already have a bunch of data in the buffer, then just trigger // the 'readable' event and move on. if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { debug('read: emitReadable', state.length, state.ended); if (state.length === 0 && state.ended) endReadable(this); else emitReadable(this); return null; } n = howMuchToRead(n, state); // if we've ended, and we're now clear, then finish it up. if (n === 0 && state.ended) { if (state.length === 0) endReadable(this); return null; } // All the actual chunk generation logic needs to be // *below* the call to _read. The reason is that in certain // synthetic stream cases, such as passthrough streams, _read // may be a completely synchronous operation which may change // the state of the read buffer, providing enough data when // before there was *not* enough. // // So, the steps are: // 1. Figure out what the state of things will be after we do // a read from the buffer. // // 2. If that resulting state will trigger a _read, then call _read. // Note that this may be asynchronous, or synchronous. Yes, it is // deeply ugly to write APIs this way, but that still doesn't mean // that the Readable class should behave improperly, as streams are // designed to be sync/async agnostic. // Take note if the _read call is sync or async (ie, if the read call // has returned yet), so that we know whether or not it's safe to emit // 'readable' etc. // // 3. Actually pull the requested chunks out of the buffer and return. // if we need a readable event, then we need to do some reading. var doRead = state.needReadable; debug('need readable', doRead); // if we currently have less than the highWaterMark, then also read some if (state.length === 0 || state.length - n < state.highWaterMark) { doRead = true; debug('length less than watermark', doRead); } // however, if we've ended, then there's no point, and if we're already // reading, then it's unnecessary. if (state.ended || state.reading) { doRead = false; debug('reading or ended', doRead); } if (doRead) { debug('do read'); state.reading = true; state.sync = true; // if the length is currently zero, then we *need* a readable event. if (state.length === 0) state.needReadable = true; // call internal read method this._read(state.highWaterMark); state.sync = false; } // If _read pushed data synchronously, then `reading` will be false, // and we need to re-evaluate how much data we can return to the user. if (doRead && !state.reading) n = howMuchToRead(nOrig, state); var ret; if (n > 0) ret = fromList(n, state); else ret = null; if (util.isNull(ret)) { state.needReadable = true; n = 0; } state.length -= n; // If we have nothing in the buffer, then we want to know // as soon as we *do* get something into the buffer. if (state.length === 0 && !state.ended) state.needReadable = true; // If we tried to read() past the EOF, then emit end on the next tick. if (nOrig !== n && state.ended && state.length === 0) endReadable(this); if (!util.isNull(ret)) this.emit('data', ret); return ret; }; function chunkInvalid(state, chunk) { var er = null; if (!util.isBuffer(chunk) && !util.isString(chunk) && !util.isNullOrUndefined(chunk) && !state.objectMode) { er = new TypeError('Invalid non-string/buffer chunk'); } return er; } function onEofChunk(stream, state) { if (state.decoder && !state.ended) { var chunk = state.decoder.end(); if (chunk && chunk.length) { state.buffer.push(chunk); state.length += state.objectMode ? 1 : chunk.length; } } state.ended = true; // emit 'readable' now to make sure it gets picked up. emitReadable(stream); } // Don't emit readable right away in sync mode, because this can trigger // another read() call => stack overflow. This way, it might trigger // a nextTick recursion warning, but that's not so bad. function emitReadable(stream) { var state = stream._readableState; state.needReadable = false; if (!state.emittedReadable) { debug('emitReadable', state.flowing); state.emittedReadable = true; if (state.sync) process.nextTick(function() { emitReadable_(stream); }); else emitReadable_(stream); } } function emitReadable_(stream) { debug('emit readable'); stream.emit('readable'); flow(stream); } // at this point, the user has presumably seen the 'readable' event, // and called read() to consume some data. that may have triggered // in turn another _read(n) call, in which case reading = true if // it's in progress. // However, if we're not ended, or reading, and the length < hwm, // then go ahead and try to read some more preemptively. function maybeReadMore(stream, state) { if (!state.readingMore) { state.readingMore = true; process.nextTick(function() { maybeReadMore_(stream, state); }); } } function maybeReadMore_(stream, state) { var len = state.length; while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { debug('maybeReadMore read 0'); stream.read(0); if (len === state.length) // didn't get any data, stop spinning. break; else len = state.length; } state.readingMore = false; } // abstract method. to be overridden in specific implementation classes. // call cb(er, data) where data is <= n in length. // for virtual (non-string, non-buffer) streams, "length" is somewhat // arbitrary, and perhaps not very meaningful. Readable.prototype._read = function(n) { this.emit('error', new Error('not implemented')); }; Readable.prototype.pipe = function(dest, pipeOpts) { var src = this; var state = this._readableState; switch (state.pipesCount) { case 0: state.pipes = dest; break; case 1: state.pipes = [state.pipes, dest]; break; default: state.pipes.push(dest); break; } state.pipesCount += 1; debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; var endFn = doEnd ? onend : cleanup; if (state.endEmitted) process.nextTick(endFn); else src.once('end', endFn); dest.on('unpipe', onunpipe); function onunpipe(readable) { debug('onunpipe'); if (readable === src) { cleanup(); } } function onend() { debug('onend'); dest.end(); } // when the dest drains, it reduces the awaitDrain counter // on the source. This would be more elegant with a .once() // handler in flow(), but adding and removing repeatedly is // too slow. var ondrain = pipeOnDrain(src); dest.on('drain', ondrain); function cleanup() { debug('cleanup'); // cleanup event handlers once the pipe is broken dest.removeListener('close', onclose); dest.removeListener('finish', onfinish); dest.removeListener('drain', ondrain); dest.removeListener('error', onerror); dest.removeListener('unpipe', onunpipe); src.removeListener('end', onend); src.removeListener('end', cleanup); src.removeListener('data', ondata); // if the reader is waiting for a drain event from this // specific writer, then it would cause it to never start // flowing again. // So, if this is awaiting a drain, then we just call it now. // If we don't know, then assume that we are waiting for one. if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); } src.on('data', ondata); function ondata(chunk) { debug('ondata'); var ret = dest.write(chunk); if (false === ret) { debug('false write response, pause', src._readableState.awaitDrain); src._readableState.awaitDrain++; src.pause(); } } // if the dest has an error, then stop piping into it. // however, don't suppress the throwing behavior for this. function onerror(er) { debug('onerror', er); unpipe(); dest.removeListener('error', onerror); if (EE.listenerCount(dest, 'error') === 0) dest.emit('error', er); } // This is a brutally ugly hack to make sure that our error handler // is attached before any userland ones. NEVER DO THIS. if (!dest._events || !dest._events.error) dest.on('error', onerror); else if (isArray(dest._events.error)) dest._events.error.unshift(onerror); else dest._events.error = [onerror, dest._events.error]; // Both close and finish should trigger unpipe, but only once. function onclose() { dest.removeListener('finish', onfinish); unpipe(); } dest.once('close', onclose); function onfinish() { debug('onfinish'); dest.removeListener('close', onclose); unpipe(); } dest.once('finish', onfinish); function unpipe() { debug('unpipe'); src.unpipe(dest); } // tell the dest that it's being piped to dest.emit('pipe', src); // start the flow if it hasn't been started already. if (!state.flowing) { debug('pipe resume'); src.resume(); } return dest; }; function pipeOnDrain(src) { return function() { var state = src._readableState; debug('pipeOnDrain', state.awaitDrain); if (state.awaitDrain) state.awaitDrain--; if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { state.flowing = true; flow(src); } }; } Readable.prototype.unpipe = function(dest) { var state = this._readableState; // if we're not piping anywhere, then do nothing. if (state.pipesCount === 0) return this; // just one destination. most common case. if (state.pipesCount === 1) { // passed in one, but it's not the right one. if (dest && dest !== state.pipes) return this; if (!dest) dest = state.pipes; // got a match. state.pipes = null; state.pipesCount = 0; state.flowing = false; if (dest) dest.emit('unpipe', this); return this; } // slow case. multiple pipe destinations. if (!dest) { // remove all. var dests = state.pipes; var len = state.pipesCount; state.pipes = null; state.pipesCount = 0; state.flowing = false; for (var i = 0; i < len; i++) dests[i].emit('unpipe', this); return this; } // try to find the right one. var i = indexOf(state.pipes, dest); if (i === -1) return this; state.pipes.splice(i, 1); state.pipesCount -= 1; if (state.pipesCount === 1) state.pipes = state.pipes[0]; dest.emit('unpipe', this); return this; }; // set up data events if they are asked for // Ensure readable listeners eventually get something Readable.prototype.on = function(ev, fn) { var res = Stream.prototype.on.call(this, ev, fn); // If listening to data, and it has not explicitly been paused, // then call resume to start the flow of data on the next tick. if (ev === 'data' && false !== this._readableState.flowing) { this.resume(); } if (ev === 'readable' && this.readable) { var state = this._readableState; if (!state.readableListening) { state.readableListening = true; state.emittedReadable = false; state.needReadable = true; if (!state.reading) { var self = this; process.nextTick(function() { debug('readable nexttick read 0'); self.read(0); }); } else if (state.length) { emitReadable(this, state); } } } return res; }; Readable.prototype.addListener = Readable.prototype.on; // pause() and resume() are remnants of the legacy readable stream API // If the user uses them, then switch into old mode. Readable.prototype.resume = function() { var state = this._readableState; if (!state.flowing) { debug('resume'); state.flowing = true; if (!state.reading) { debug('resume read 0'); this.read(0); } resume(this, state); } return this; }; function resume(stream, state) { if (!state.resumeScheduled) { state.resumeScheduled = true; process.nextTick(function() { resume_(stream, state); }); } } function resume_(stream, state) { state.resumeScheduled = false; stream.emit('resume'); flow(stream); if (state.flowing && !state.reading) stream.read(0); } Readable.prototype.pause = function() { debug('call pause flowing=%j', this._readableState.flowing); if (false !== this._readableState.flowing) { debug('pause'); this._readableState.flowing = false; this.emit('pause'); } return this; }; function flow(stream) { var state = stream._readableState; debug('flow', state.flowing); if (state.flowing) { do { var chunk = stream.read(); } while (null !== chunk && state.flowing); } } // wrap an old-style stream as the async data source. // This is *not* part of the readable stream interface. // It is an ugly unfortunate mess of history. Readable.prototype.wrap = function(stream) { var state = this._readableState; var paused = false; var self = this; stream.on('end', function() { debug('wrapped end'); if (state.decoder && !state.ended) { var chunk = state.decoder.end(); if (chunk && chunk.length) self.push(chunk); } self.push(null); }); stream.on('data', function(chunk) { debug('wrapped data'); if (state.decoder) chunk = state.decoder.write(chunk); if (!chunk || !state.objectMode && !chunk.length) return; var ret = self.push(chunk); if (!ret) { paused = true; stream.pause(); } }); // proxy all the other methods. // important when wrapping filters and duplexes. for (var i in stream) { if (util.isFunction(stream[i]) && util.isUndefined(this[i])) { this[i] = function(method) { return function() { return stream[method].apply(stream, arguments); }}(i); } } // proxy certain important events. var events = ['error', 'close', 'destroy', 'pause', 'resume']; forEach(events, function(ev) { stream.on(ev, self.emit.bind(self, ev)); }); // when we try to consume some more bytes, simply unpause the // underlying stream. self._read = function(n) { debug('wrapped _read', n); if (paused) { paused = false; stream.resume(); } }; return self; }; // exposed for testing purposes only. Readable._fromList = fromList; // Pluck off n bytes from an array of buffers. // Length is the combined lengths of all the buffers in the list. function fromList(n, state) { var list = state.buffer; var length = state.length; var stringMode = !!state.decoder; var objectMode = !!state.objectMode; var ret; // nothing in the list, definitely empty. if (list.length === 0) return null; if (length === 0) ret = null; else if (objectMode) ret = list.shift(); else if (!n || n >= length) { // read it all, truncate the array. if (stringMode) ret = list.join(''); else ret = Buffer.concat(list, length); list.length = 0; } else { // read just some of it. if (n < list[0].length) { // just take a part of the first list item. // slice is the same for buffers and strings. var buf = list[0]; ret = buf.slice(0, n); list[0] = buf.slice(n); } else if (n === list[0].length) { // first list is a perfect match ret = list.shift(); } else { // complex case. // we have enough to cover it, but it spans past the first buffer. if (stringMode) ret = ''; else ret = new Buffer(n); var c = 0; for (var i = 0, l = list.length; i < l && c < n; i++) { var buf = list[0]; var cpy = Math.min(n - c, buf.length); if (stringMode) ret += buf.slice(0, cpy); else buf.copy(ret, c, 0, cpy); if (cpy < buf.length) list[0] = buf.slice(cpy); else list.shift(); c += cpy; } } } return ret; } function endReadable(stream) { var state = stream._readableState; // If we get here before consuming all the bytes, then that is a // bug in node. Should never happen. if (state.length > 0) throw new Error('endReadable called on non-empty stream'); if (!state.endEmitted) { state.ended = true; process.nextTick(function() { // Check that we didn't get one last unshift. if (!state.endEmitted && state.length === 0) { state.endEmitted = true; stream.readable = false; stream.emit('end'); } }); } } function forEach (xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } function indexOf (xs, x) { for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) return i; } return -1; } }).call(this,require('_process')) },{"./_stream_duplex":11,"_process":9,"buffer":2,"core-util-is":16,"events":6,"inherits":7,"isarray":8,"stream":21,"string_decoder/":22,"util":1}],14:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // a transform stream is a readable/writable stream where you do // something with the data. Sometimes it's called a "filter", // but that's not a great name for it, since that implies a thing where // some bits pass through, and others are simply ignored. (That would // be a valid example of a transform, of course.) // // While the output is causally related to the input, it's not a // necessarily symmetric or synchronous transformation. For example, // a zlib stream might take multiple plain-text writes(), and then // emit a single compressed chunk some time in the future. // // Here's how this works: // // The Transform stream has all the aspects of the readable and writable // stream classes. When you write(chunk), that calls _write(chunk,cb) // internally, and returns false if there's a lot of pending writes // buffered up. When you call read(), that calls _read(n) until // there's enough pending readable data buffered up. // // In a transform stream, the written data is placed in a buffer. When // _read(n) is called, it transforms the queued up data, calling the // buffered _write cb's as it consumes chunks. If consuming a single // written chunk would result in multiple output chunks, then the first // outputted bit calls the readcb, and subsequent chunks just go into // the read buffer, and will cause it to emit 'readable' if necessary. // // This way, back-pressure is actually determined by the reading side, // since _read has to be called to start processing a new chunk. However, // a pathological inflate type of transform can cause excessive buffering // here. For example, imagine a stream where every byte of input is // interpreted as an integer from 0-255, and then results in that many // bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in // 1kb of data being output. In this case, you could write a very small // amount of input, and end up with a very large amount of output. In // such a pathological inflating mechanism, there'd be no way to tell // the system to stop doing the transform. A single 4MB write could // cause the system to run out of memory. // // However, even in such a pathological case, only a single written chunk // would be consumed, and then the rest would wait (un-transformed) until // the results of the previous transformed chunk were consumed. module.exports = Transform; var Duplex = require('./_stream_duplex'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ util.inherits(Transform, Duplex); function TransformState(options, stream) { this.afterTransform = function(er, data) { return afterTransform(stream, er, data); }; this.needTransform = false; this.transforming = false; this.writecb = null; this.writechunk = null; } function afterTransform(stream, er, data) { var ts = stream._transformState; ts.transforming = false; var cb = ts.writecb; if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); ts.writechunk = null; ts.writecb = null; if (!util.isNullOrUndefined(data)) stream.push(data); if (cb) cb(er); var rs = stream._readableState; rs.reading = false; if (rs.needReadable || rs.length < rs.highWaterMark) { stream._read(rs.highWaterMark); } } function Transform(options) { if (!(this instanceof Transform)) return new Transform(options); Duplex.call(this, options); this._transformState = new TransformState(options, this); // when the writable side finishes, then flush out anything remaining. var stream = this; // start out asking for a readable event once data is transformed. this._readableState.needReadable = true; // we have implemented the _read method, and done the other things // that Readable wants before the first _read call, so unset the // sync guard flag. this._readableState.sync = false; this.once('prefinish', function() { if (util.isFunction(this._flush)) this._flush(function(er) { done(stream, er); }); else done(stream); }); } Transform.prototype.push = function(chunk, encoding) { this._transformState.needTransform = false; return Duplex.prototype.push.call(this, chunk, encoding); }; // This is the part where you do stuff! // override this function in implementation classes. // 'chunk' is an input chunk. // // Call `push(newChunk)` to pass along transformed output // to the readable side. You may call 'push' zero or more times. // // Call `cb(err)` when you are done with this chunk. If you pass // an error, then that'll put the hurt on the whole operation. If you // never call cb(), then you'll never get another chunk. Transform.prototype._transform = function(chunk, encoding, cb) { throw new Error('not implemented'); }; Transform.prototype._write = function(chunk, encoding, cb) { var ts = this._transformState; ts.writecb = cb; ts.writechunk = chunk; ts.writeencoding = encoding; if (!ts.transforming) { var rs = this._readableState; if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); } }; // Doesn't matter what the args are here. // _transform does all the work. // That we got here means that the readable side wants more data. Transform.prototype._read = function(n) { var ts = this._transformState; if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) { ts.transforming = true; this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); } else { // mark that we need a transform, so that any data that comes in // will get processed, now that we've asked for it. ts.needTransform = true; } }; function done(stream, er) { if (er) return stream.emit('error', er); // if there's nothing in the write buffer, then that means // that nothing more will ever be provided var ws = stream._writableState; var ts = stream._transformState; if (ws.length) throw new Error('calling transform done when ws.length != 0'); if (ts.transforming) throw new Error('calling transform done when still transforming'); return stream.push(null); } },{"./_stream_duplex":11,"core-util-is":16,"inherits":7}],15:[function(require,module,exports){ (function (process){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // A bit simpler than readable streams. // Implement an async ._write(chunk, cb), and it'll handle all // the drain event emission and buffering. module.exports = Writable; /**/ var Buffer = require('buffer').Buffer; /**/ Writable.WritableState = WritableState; /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ var Stream = require('stream'); util.inherits(Writable, Stream); function WriteReq(chunk, encoding, cb) { this.chunk = chunk; this.encoding = encoding; this.callback = cb; } function WritableState(options, stream) { var Duplex = require('./_stream_duplex'); options = options || {}; // the point at which write() starts returning false // Note: 0 is a valid value, means that we always return false if // the entire buffer is not flushed immediately on write() var hwm = options.highWaterMark; var defaultHwm = options.objectMode ? 16 : 16 * 1024; this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; // object stream flag to indicate whether or not this stream // contains buffers or objects. this.objectMode = !!options.objectMode; if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // cast to ints. this.highWaterMark = ~~this.highWaterMark; this.needDrain = false; // at the start of calling end() this.ending = false; // when end() has been called, and returned this.ended = false; // when 'finish' is emitted this.finished = false; // should we decode strings into buffers before passing to _write? // this is here so that some node-core streams can optimize string // handling at a lower level. var noDecode = options.decodeStrings === false; this.decodeStrings = !noDecode; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; // not an actual buffer we keep track of, but a measurement // of how much we're waiting to get pushed to some underlying // socket or file. this.length = 0; // a flag to see when we're in the middle of a write. this.writing = false; // when true all writes will be buffered until .uncork() call this.corked = 0; // a flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. this.sync = true; // a flag to know if we're processing previously buffered items, which // may call the _write() callback in the same tick, so that we don't // end up in an overlapped onwrite situation. this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb) this.onwrite = function(er) { onwrite(stream, er); }; // the callback that the user supplies to write(chunk,encoding,cb) this.writecb = null; // the amount that is being written when _write is called. this.writelen = 0; this.buffer = []; // number of pending user-supplied write callbacks // this must be 0 before 'finish' can be emitted this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs // This is relevant for synchronous Transform streams this.prefinished = false; // True if the error was already emitted and should not be thrown again this.errorEmitted = false; } function Writable(options) { var Duplex = require('./_stream_duplex'); // Writable ctor is applied to Duplexes, though they're not // instanceof Writable, they're instanceof Readable. if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options); this._writableState = new WritableState(options, this); // legacy. this.writable = true; Stream.call(this); } // Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function() { this.emit('error', new Error('Cannot pipe. Not readable.')); }; function writeAfterEnd(stream, state, cb) { var er = new Error('write after end'); // TODO: defer error events consistently everywhere, not just the cb stream.emit('error', er); process.nextTick(function() { cb(er); }); } // If we get something that is not a buffer, string, null, or undefined, // and we're not in objectMode, then that's an error. // Otherwise stream chunks are all considered to be of length=1, and the // watermarks determine how many objects to keep in the buffer, rather than // how many bytes or characters. function validChunk(stream, state, chunk, cb) { var valid = true; if (!util.isBuffer(chunk) && !util.isString(chunk) && !util.isNullOrUndefined(chunk) && !state.objectMode) { var er = new TypeError('Invalid non-string/buffer chunk'); stream.emit('error', er); process.nextTick(function() { cb(er); }); valid = false; } return valid; } Writable.prototype.write = function(chunk, encoding, cb) { var state = this._writableState; var ret = false; if (util.isFunction(encoding)) { cb = encoding; encoding = null; } if (util.isBuffer(chunk)) encoding = 'buffer'; else if (!encoding) encoding = state.defaultEncoding; if (!util.isFunction(cb)) cb = function() {}; if (state.ended) writeAfterEnd(this, state, cb); else if (validChunk(this, state, chunk, cb)) { state.pendingcb++; ret = writeOrBuffer(this, state, chunk, encoding, cb); } return ret; }; Writable.prototype.cork = function() { var state = this._writableState; state.corked++; }; Writable.prototype.uncork = function() { var state = this._writableState; if (state.corked) { state.corked--; if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.buffer.length) clearBuffer(this, state); } }; function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && util.isString(chunk)) { chunk = new Buffer(chunk, encoding); } return chunk; } // if we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. function writeOrBuffer(stream, state, chunk, encoding, cb) { chunk = decodeChunk(state, chunk, encoding); if (util.isBuffer(chunk)) encoding = 'buffer'; var len = state.objectMode ? 1 : chunk.length; state.length += len; var ret = state.length < state.highWaterMark; // we must ensure that previous needDrain will not be reset to false. if (!ret) state.needDrain = true; if (state.writing || state.corked) state.buffer.push(new WriteReq(chunk, encoding, cb)); else doWrite(stream, state, false, len, chunk, encoding, cb); return ret; } function doWrite(stream, state, writev, len, chunk, encoding, cb) { state.writelen = len; state.writecb = cb; state.writing = true; state.sync = true; if (writev) stream._writev(chunk, state.onwrite); else stream._write(chunk, encoding, state.onwrite); state.sync = false; } function onwriteError(stream, state, sync, er, cb) { if (sync) process.nextTick(function() { state.pendingcb--; cb(er); }); else { state.pendingcb--; cb(er); } stream._writableState.errorEmitted = true; stream.emit('error', er); } function onwriteStateUpdate(state) { state.writing = false; state.writecb = null; state.length -= state.writelen; state.writelen = 0; } function onwrite(stream, er) { var state = stream._writableState; var sync = state.sync; var cb = state.writecb; onwriteStateUpdate(state); if (er) onwriteError(stream, state, sync, er, cb); else { // Check if we're actually ready to finish, but don't emit yet var finished = needFinish(stream, state); if (!finished && !state.corked && !state.bufferProcessing && state.buffer.length) { clearBuffer(stream, state); } if (sync) { process.nextTick(function() { afterWrite(stream, state, finished, cb); }); } else { afterWrite(stream, state, finished, cb); } } } function afterWrite(stream, state, finished, cb) { if (!finished) onwriteDrain(stream, state); state.pendingcb--; cb(); finishMaybe(stream, state); } // Must force callback to be called on nextTick, so that we don't // emit 'drain' before the write() consumer gets the 'false' return // value, and has a chance to attach a 'drain' listener. function onwriteDrain(stream, state) { if (state.length === 0 && state.needDrain) { state.needDrain = false; stream.emit('drain'); } } // if there's something in the buffer waiting, then process it function clearBuffer(stream, state) { state.bufferProcessing = true; if (stream._writev && state.buffer.length > 1) { // Fast case, write everything using _writev() var cbs = []; for (var c = 0; c < state.buffer.length; c++) cbs.push(state.buffer[c].callback); // count the one we are adding, as well. // TODO(isaacs) clean this up state.pendingcb++; doWrite(stream, state, true, state.length, state.buffer, '', function(err) { for (var i = 0; i < cbs.length; i++) { state.pendingcb--; cbs[i](err); } }); // Clear buffer state.buffer = []; } else { // Slow case, write chunks one-by-one for (var c = 0; c < state.buffer.length; c++) { var entry = state.buffer[c]; var chunk = entry.chunk; var encoding = entry.encoding; var cb = entry.callback; var len = state.objectMode ? 1 : chunk.length; doWrite(stream, state, false, len, chunk, encoding, cb); // if we didn't call the onwrite immediately, then // it means that we need to wait until it does. // also, that means that the chunk and cb are currently // being processed, so move the buffer counter past them. if (state.writing) { c++; break; } } if (c < state.buffer.length) state.buffer = state.buffer.slice(c); else state.buffer.length = 0; } state.bufferProcessing = false; } Writable.prototype._write = function(chunk, encoding, cb) { cb(new Error('not implemented')); }; Writable.prototype._writev = null; Writable.prototype.end = function(chunk, encoding, cb) { var state = this._writableState; if (util.isFunction(chunk)) { cb = chunk; chunk = null; encoding = null; } else if (util.isFunction(encoding)) { cb = encoding; encoding = null; } if (!util.isNullOrUndefined(chunk)) this.write(chunk, encoding); // .end() fully uncorks if (state.corked) { state.corked = 1; this.uncork(); } // ignore unnecessary end() calls. if (!state.ending && !state.finished) endWritable(this, state, cb); }; function needFinish(stream, state) { return (state.ending && state.length === 0 && !state.finished && !state.writing); } function prefinish(stream, state) { if (!state.prefinished) { state.prefinished = true; stream.emit('prefinish'); } } function finishMaybe(stream, state) { var need = needFinish(stream, state); if (need) { if (state.pendingcb === 0) { prefinish(stream, state); state.finished = true; stream.emit('finish'); } else prefinish(stream, state); } return need; } function endWritable(stream, state, cb) { state.ending = true; finishMaybe(stream, state); if (cb) { if (state.finished) process.nextTick(cb); else stream.once('finish', cb); } state.ended = true; } }).call(this,require('_process')) },{"./_stream_duplex":11,"_process":9,"buffer":2,"core-util-is":16,"inherits":7,"stream":21}],16:[function(require,module,exports){ (function (Buffer){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // NOTE: These type checking functions intentionally don't use `instanceof` // because it is fragile and can be easily faked with `Object.create()`. function isArray(ar) { return Array.isArray(ar); } exports.isArray = isArray; function isBoolean(arg) { return typeof arg === 'boolean'; } exports.isBoolean = isBoolean; function isNull(arg) { return arg === null; } exports.isNull = isNull; function isNullOrUndefined(arg) { return arg == null; } exports.isNullOrUndefined = isNullOrUndefined; function isNumber(arg) { return typeof arg === 'number'; } exports.isNumber = isNumber; function isString(arg) { return typeof arg === 'string'; } exports.isString = isString; function isSymbol(arg) { return typeof arg === 'symbol'; } exports.isSymbol = isSymbol; function isUndefined(arg) { return arg === void 0; } exports.isUndefined = isUndefined; function isRegExp(re) { return isObject(re) && objectToString(re) === '[object RegExp]'; } exports.isRegExp = isRegExp; function isObject(arg) { return typeof arg === 'object' && arg !== null; } exports.isObject = isObject; function isDate(d) { return isObject(d) && objectToString(d) === '[object Date]'; } exports.isDate = isDate; function isError(e) { return isObject(e) && (objectToString(e) === '[object Error]' || e instanceof Error); } exports.isError = isError; function isFunction(arg) { return typeof arg === 'function'; } exports.isFunction = isFunction; function isPrimitive(arg) { return arg === null || typeof arg === 'boolean' || typeof arg === 'number' || typeof arg === 'string' || typeof arg === 'symbol' || // ES6 symbol typeof arg === 'undefined'; } exports.isPrimitive = isPrimitive; function isBuffer(arg) { return Buffer.isBuffer(arg); } exports.isBuffer = isBuffer; function objectToString(o) { return Object.prototype.toString.call(o); } }).call(this,require("buffer").Buffer) },{"buffer":2}],17:[function(require,module,exports){ module.exports = require("./lib/_stream_passthrough.js") },{"./lib/_stream_passthrough.js":12}],18:[function(require,module,exports){ exports = module.exports = require('./lib/_stream_readable.js'); exports.Stream = require('stream'); exports.Readable = exports; exports.Writable = require('./lib/_stream_writable.js'); exports.Duplex = require('./lib/_stream_duplex.js'); exports.Transform = require('./lib/_stream_transform.js'); exports.PassThrough = require('./lib/_stream_passthrough.js'); },{"./lib/_stream_duplex.js":11,"./lib/_stream_passthrough.js":12,"./lib/_stream_readable.js":13,"./lib/_stream_transform.js":14,"./lib/_stream_writable.js":15,"stream":21}],19:[function(require,module,exports){ module.exports = require("./lib/_stream_transform.js") },{"./lib/_stream_transform.js":14}],20:[function(require,module,exports){ module.exports = require("./lib/_stream_writable.js") },{"./lib/_stream_writable.js":15}],21:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. module.exports = Stream; var EE = require('events').EventEmitter; var inherits = require('inherits'); inherits(Stream, EE); Stream.Readable = require('readable-stream/readable.js'); Stream.Writable = require('readable-stream/writable.js'); Stream.Duplex = require('readable-stream/duplex.js'); Stream.Transform = require('readable-stream/transform.js'); Stream.PassThrough = require('readable-stream/passthrough.js'); // Backwards-compat with node 0.4.x Stream.Stream = Stream; // old-style streams. Note that the pipe method (the only relevant // part of this class) is overridden in the Readable class. function Stream() { EE.call(this); } Stream.prototype.pipe = function(dest, options) { var source = this; function ondata(chunk) { if (dest.writable) { if (false === dest.write(chunk) && source.pause) { source.pause(); } } } source.on('data', ondata); function ondrain() { if (source.readable && source.resume) { source.resume(); } } dest.on('drain', ondrain); // If the 'end' option is not supplied, dest.end() will be called when // source gets the 'end' or 'close' events. Only dest.end() once. if (!dest._isStdio && (!options || options.end !== false)) { source.on('end', onend); source.on('close', onclose); } var didOnEnd = false; function onend() { if (didOnEnd) return; didOnEnd = true; dest.end(); } function onclose() { if (didOnEnd) return; didOnEnd = true; if (typeof dest.destroy === 'function') dest.destroy(); } // don't leave dangling pipes when there are errors. function onerror(er) { cleanup(); if (EE.listenerCount(this, 'error') === 0) { throw er; // Unhandled stream error in pipe. } } source.on('error', onerror); dest.on('error', onerror); // remove all the event listeners that were added. function cleanup() { source.removeListener('data', ondata); dest.removeListener('drain', ondrain); source.removeListener('end', onend); source.removeListener('close', onclose); source.removeListener('error', onerror); dest.removeListener('error', onerror); source.removeListener('end', cleanup); source.removeListener('close', cleanup); dest.removeListener('close', cleanup); } source.on('end', cleanup); source.on('close', cleanup); dest.on('close', cleanup); dest.emit('pipe', source); // Allow for unix-like usage: A.pipe(B).pipe(C) return dest; }; },{"events":6,"inherits":7,"readable-stream/duplex.js":10,"readable-stream/passthrough.js":17,"readable-stream/readable.js":18,"readable-stream/transform.js":19,"readable-stream/writable.js":20}],22:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. var Buffer = require('buffer').Buffer; var isBufferEncoding = Buffer.isEncoding || function(encoding) { switch (encoding && encoding.toLowerCase()) { case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; default: return false; } } function assertEncoding(encoding) { if (encoding && !isBufferEncoding(encoding)) { throw new Error('Unknown encoding: ' + encoding); } } // StringDecoder provides an interface for efficiently splitting a series of // buffers into a series of JS strings without breaking apart multi-byte // characters. CESU-8 is handled as part of the UTF-8 encoding. // // @TODO Handling all encodings inside a single object makes it very difficult // to reason about this code, so it should be split up in the future. // @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code // points as used by CESU-8. var StringDecoder = exports.StringDecoder = function(encoding) { this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); assertEncoding(encoding); switch (this.encoding) { case 'utf8': // CESU-8 represents each of Surrogate Pair by 3-bytes this.surrogateSize = 3; break; case 'ucs2': case 'utf16le': // UTF-16 represents each of Surrogate Pair by 2-bytes this.surrogateSize = 2; this.detectIncompleteChar = utf16DetectIncompleteChar; break; case 'base64': // Base-64 stores 3 bytes in 4 chars, and pads the remainder. this.surrogateSize = 3; this.detectIncompleteChar = base64DetectIncompleteChar; break; default: this.write = passThroughWrite; return; } // Enough space to store all bytes of a single character. UTF-8 needs 4 // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). this.charBuffer = new Buffer(6); // Number of bytes received for the current incomplete multi-byte character. this.charReceived = 0; // Number of bytes expected for the current incomplete multi-byte character. this.charLength = 0; }; // write decodes the given buffer and returns it as JS string that is // guaranteed to not contain any partial multi-byte characters. Any partial // character found at the end of the buffer is buffered up, and will be // returned when calling write again with the remaining bytes. // // Note: Converting a Buffer containing an orphan surrogate to a String // currently works, but converting a String to a Buffer (via `new Buffer`, or // Buffer#write) will replace incomplete surrogates with the unicode // replacement character. See https://codereview.chromium.org/121173009/ . StringDecoder.prototype.write = function(buffer) { var charStr = ''; // if our last write ended with an incomplete multibyte character while (this.charLength) { // determine how many remaining bytes this buffer has to offer for this char var available = (buffer.length >= this.charLength - this.charReceived) ? this.charLength - this.charReceived : buffer.length; // add the new bytes to the char buffer buffer.copy(this.charBuffer, this.charReceived, 0, available); this.charReceived += available; if (this.charReceived < this.charLength) { // still not enough chars in this buffer? wait for more ... return ''; } // remove bytes belonging to the current character from the buffer buffer = buffer.slice(available, buffer.length); // get the character that was split charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character var charCode = charStr.charCodeAt(charStr.length - 1); if (charCode >= 0xD800 && charCode <= 0xDBFF) { this.charLength += this.surrogateSize; charStr = ''; continue; } this.charReceived = this.charLength = 0; // if there are no more bytes in this buffer, just emit our char if (buffer.length === 0) { return charStr; } break; } // determine and set charLength / charReceived this.detectIncompleteChar(buffer); var end = buffer.length; if (this.charLength) { // buffer the incomplete character bytes we got buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); end -= this.charReceived; } charStr += buffer.toString(this.encoding, 0, end); var end = charStr.length - 1; var charCode = charStr.charCodeAt(end); // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character if (charCode >= 0xD800 && charCode <= 0xDBFF) { var size = this.surrogateSize; this.charLength += size; this.charReceived += size; this.charBuffer.copy(this.charBuffer, size, 0, size); buffer.copy(this.charBuffer, 0, 0, size); return charStr.substring(0, end); } // or just emit the charStr return charStr; }; // detectIncompleteChar determines if there is an incomplete UTF-8 character at // the end of the given buffer. If so, it sets this.charLength to the byte // length that character, and sets this.charReceived to the number of bytes // that are available for this character. StringDecoder.prototype.detectIncompleteChar = function(buffer) { // determine how many bytes we have to check at the end of this buffer var i = (buffer.length >= 3) ? 3 : buffer.length; // Figure out if one of the last i bytes of our buffer announces an // incomplete char. for (; i > 0; i--) { var c = buffer[buffer.length - i]; // See http://en.wikipedia.org/wiki/UTF-8#Description // 110XXXXX if (i == 1 && c >> 5 == 0x06) { this.charLength = 2; break; } // 1110XXXX if (i <= 2 && c >> 4 == 0x0E) { this.charLength = 3; break; } // 11110XXX if (i <= 3 && c >> 3 == 0x1E) { this.charLength = 4; break; } } this.charReceived = i; }; StringDecoder.prototype.end = function(buffer) { var res = ''; if (buffer && buffer.length) res = this.write(buffer); if (this.charReceived) { var cr = this.charReceived; var buf = this.charBuffer; var enc = this.encoding; res += buf.slice(0, cr).toString(enc); } return res; }; function passThroughWrite(buffer) { return buffer.toString(this.encoding); } function utf16DetectIncompleteChar(buffer) { this.charReceived = buffer.length % 2; this.charLength = this.charReceived ? 2 : 0; } function base64DetectIncompleteChar(buffer) { this.charReceived = buffer.length % 3; this.charLength = this.charReceived ? 3 : 0; } },{"buffer":2}],23:[function(require,module,exports){ module.exports = function isBuffer(arg) { return arg && typeof arg === 'object' && typeof arg.copy === 'function' && typeof arg.fill === 'function' && typeof arg.readUInt8 === 'function'; } },{}],24:[function(require,module,exports){ (function (process,global){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. var formatRegExp = /%[sdj%]/g; exports.format = function(f) { if (!isString(f)) { var objects = []; for (var i = 0; i < arguments.length; i++) { objects.push(inspect(arguments[i])); } return objects.join(' '); } var i = 1; var args = arguments; var len = args.length; var str = String(f).replace(formatRegExp, function(x) { if (x === '%%') return '%'; if (i >= len) return x; switch (x) { case '%s': return String(args[i++]); case '%d': return Number(args[i++]); case '%j': try { return JSON.stringify(args[i++]); } catch (_) { return '[Circular]'; } default: return x; } }); for (var x = args[i]; i < len; x = args[++i]) { if (isNull(x) || !isObject(x)) { str += ' ' + x; } else { str += ' ' + inspect(x); } } return str; }; // Mark that a method should not be used. // Returns a modified function which warns once by default. // If --no-deprecation is set, then it is a no-op. exports.deprecate = function(fn, msg) { // Allow for deprecating things in the process of starting up. if (isUndefined(global.process)) { return function() { return exports.deprecate(fn, msg).apply(this, arguments); }; } if (process.noDeprecation === true) { return fn; } var warned = false; function deprecated() { if (!warned) { if (process.throwDeprecation) { throw new Error(msg); } else if (process.traceDeprecation) { console.trace(msg); } else { console.error(msg); } warned = true; } return fn.apply(this, arguments); } return deprecated; }; var debugs = {}; var debugEnviron; exports.debuglog = function(set) { if (isUndefined(debugEnviron)) debugEnviron = process.env.NODE_DEBUG || ''; set = set.toUpperCase(); if (!debugs[set]) { if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { var pid = process.pid; debugs[set] = function() { var msg = exports.format.apply(exports, arguments); console.error('%s %d: %s', set, pid, msg); }; } else { debugs[set] = function() {}; } } return debugs[set]; }; /** * Echos the value of a value. Trys to print the value out * in the best way possible given the different types. * * @param {Object} obj The object to print out. * @param {Object} opts Optional options object that alters the output. */ /* legacy: obj, showHidden, depth, colors*/ function inspect(obj, opts) { // default options var ctx = { seen: [], stylize: stylizeNoColor }; // legacy... if (arguments.length >= 3) ctx.depth = arguments[2]; if (arguments.length >= 4) ctx.colors = arguments[3]; if (isBoolean(opts)) { // legacy... ctx.showHidden = opts; } else if (opts) { // got an "options" object exports._extend(ctx, opts); } // set default options if (isUndefined(ctx.showHidden)) ctx.showHidden = false; if (isUndefined(ctx.depth)) ctx.depth = 2; if (isUndefined(ctx.colors)) ctx.colors = false; if (isUndefined(ctx.customInspect)) ctx.customInspect = true; if (ctx.colors) ctx.stylize = stylizeWithColor; return formatValue(ctx, obj, ctx.depth); } exports.inspect = inspect; // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics inspect.colors = { 'bold' : [1, 22], 'italic' : [3, 23], 'underline' : [4, 24], 'inverse' : [7, 27], 'white' : [37, 39], 'grey' : [90, 39], 'black' : [30, 39], 'blue' : [34, 39], 'cyan' : [36, 39], 'green' : [32, 39], 'magenta' : [35, 39], 'red' : [31, 39], 'yellow' : [33, 39] }; // Don't use 'blue' not visible on cmd.exe inspect.styles = { 'special': 'cyan', 'number': 'yellow', 'boolean': 'yellow', 'undefined': 'grey', 'null': 'bold', 'string': 'green', 'date': 'magenta', // "name": intentionally not styling 'regexp': 'red' }; function stylizeWithColor(str, styleType) { var style = inspect.styles[styleType]; if (style) { return '\u001b[' + inspect.colors[style][0] + 'm' + str + '\u001b[' + inspect.colors[style][1] + 'm'; } else { return str; } } function stylizeNoColor(str, styleType) { return str; } function arrayToHash(array) { var hash = {}; array.forEach(function(val, idx) { hash[val] = true; }); return hash; } function formatValue(ctx, value, recurseTimes) { // Provide a hook for user-specified inspect functions. // Check that value is an object with an inspect function on it if (ctx.customInspect && value && isFunction(value.inspect) && // Filter out the util module, it's inspect function is special value.inspect !== exports.inspect && // Also filter out any prototype objects using the circular check. !(value.constructor && value.constructor.prototype === value)) { var ret = value.inspect(recurseTimes, ctx); if (!isString(ret)) { ret = formatValue(ctx, ret, recurseTimes); } return ret; } // Primitive types cannot have properties var primitive = formatPrimitive(ctx, value); if (primitive) { return primitive; } // Look up the keys of the object. var keys = Object.keys(value); var visibleKeys = arrayToHash(keys); if (ctx.showHidden) { keys = Object.getOwnPropertyNames(value); } // IE doesn't make error fields non-enumerable // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx if (isError(value) && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { return formatError(value); } // Some type of object without properties can be shortcutted. if (keys.length === 0) { if (isFunction(value)) { var name = value.name ? ': ' + value.name : ''; return ctx.stylize('[Function' + name + ']', 'special'); } if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } if (isDate(value)) { return ctx.stylize(Date.prototype.toString.call(value), 'date'); } if (isError(value)) { return formatError(value); } } var base = '', array = false, braces = ['{', '}']; // Make Array say that they are Array if (isArray(value)) { array = true; braces = ['[', ']']; } // Make functions say that they are functions if (isFunction(value)) { var n = value.name ? ': ' + value.name : ''; base = ' [Function' + n + ']'; } // Make RegExps say that they are RegExps if (isRegExp(value)) { base = ' ' + RegExp.prototype.toString.call(value); } // Make dates with properties first say the date if (isDate(value)) { base = ' ' + Date.prototype.toUTCString.call(value); } // Make error with message first say the error if (isError(value)) { base = ' ' + formatError(value); } if (keys.length === 0 && (!array || value.length == 0)) { return braces[0] + base + braces[1]; } if (recurseTimes < 0) { if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } else { return ctx.stylize('[Object]', 'special'); } } ctx.seen.push(value); var output; if (array) { output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); } else { output = keys.map(function(key) { return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); }); } ctx.seen.pop(); return reduceToSingleString(output, base, braces); } function formatPrimitive(ctx, value) { if (isUndefined(value)) return ctx.stylize('undefined', 'undefined'); if (isString(value)) { var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') .replace(/'/g, "\\'") .replace(/\\"/g, '"') + '\''; return ctx.stylize(simple, 'string'); } if (isNumber(value)) return ctx.stylize('' + value, 'number'); if (isBoolean(value)) return ctx.stylize('' + value, 'boolean'); // For some reason typeof null is "object", so special case here. if (isNull(value)) return ctx.stylize('null', 'null'); } function formatError(value) { return '[' + Error.prototype.toString.call(value) + ']'; } function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { var output = []; for (var i = 0, l = value.length; i < l; ++i) { if (hasOwnProperty(value, String(i))) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true)); } else { output.push(''); } } keys.forEach(function(key) { if (!key.match(/^\d+$/)) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true)); } }); return output; } function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { var name, str, desc; desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; if (desc.get) { if (desc.set) { str = ctx.stylize('[Getter/Setter]', 'special'); } else { str = ctx.stylize('[Getter]', 'special'); } } else { if (desc.set) { str = ctx.stylize('[Setter]', 'special'); } } if (!hasOwnProperty(visibleKeys, key)) { name = '[' + key + ']'; } if (!str) { if (ctx.seen.indexOf(desc.value) < 0) { if (isNull(recurseTimes)) { str = formatValue(ctx, desc.value, null); } else { str = formatValue(ctx, desc.value, recurseTimes - 1); } if (str.indexOf('\n') > -1) { if (array) { str = str.split('\n').map(function(line) { return ' ' + line; }).join('\n').substr(2); } else { str = '\n' + str.split('\n').map(function(line) { return ' ' + line; }).join('\n'); } } } else { str = ctx.stylize('[Circular]', 'special'); } } if (isUndefined(name)) { if (array && key.match(/^\d+$/)) { return str; } name = JSON.stringify('' + key); if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { name = name.substr(1, name.length - 2); name = ctx.stylize(name, 'name'); } else { name = name.replace(/'/g, "\\'") .replace(/\\"/g, '"') .replace(/(^"|"$)/g, "'"); name = ctx.stylize(name, 'string'); } } return name + ': ' + str; } function reduceToSingleString(output, base, braces) { var numLinesEst = 0; var length = output.reduce(function(prev, cur) { numLinesEst++; if (cur.indexOf('\n') >= 0) numLinesEst++; return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; }, 0); if (length > 60) { return braces[0] + (base === '' ? '' : base + '\n ') + ' ' + output.join(',\n ') + ' ' + braces[1]; } return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; } // NOTE: These type checking functions intentionally don't use `instanceof` // because it is fragile and can be easily faked with `Object.create()`. function isArray(ar) { return Array.isArray(ar); } exports.isArray = isArray; function isBoolean(arg) { return typeof arg === 'boolean'; } exports.isBoolean = isBoolean; function isNull(arg) { return arg === null; } exports.isNull = isNull; function isNullOrUndefined(arg) { return arg == null; } exports.isNullOrUndefined = isNullOrUndefined; function isNumber(arg) { return typeof arg === 'number'; } exports.isNumber = isNumber; function isString(arg) { return typeof arg === 'string'; } exports.isString = isString; function isSymbol(arg) { return typeof arg === 'symbol'; } exports.isSymbol = isSymbol; function isUndefined(arg) { return arg === void 0; } exports.isUndefined = isUndefined; function isRegExp(re) { return isObject(re) && objectToString(re) === '[object RegExp]'; } exports.isRegExp = isRegExp; function isObject(arg) { return typeof arg === 'object' && arg !== null; } exports.isObject = isObject; function isDate(d) { return isObject(d) && objectToString(d) === '[object Date]'; } exports.isDate = isDate; function isError(e) { return isObject(e) && (objectToString(e) === '[object Error]' || e instanceof Error); } exports.isError = isError; function isFunction(arg) { return typeof arg === 'function'; } exports.isFunction = isFunction; function isPrimitive(arg) { return arg === null || typeof arg === 'boolean' || typeof arg === 'number' || typeof arg === 'string' || typeof arg === 'symbol' || // ES6 symbol typeof arg === 'undefined'; } exports.isPrimitive = isPrimitive; exports.isBuffer = require('./support/isBuffer'); function objectToString(o) { return Object.prototype.toString.call(o); } function pad(n) { return n < 10 ? '0' + n.toString(10) : n.toString(10); } var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; // 26 Feb 16:19:34 function timestamp() { var d = new Date(); var time = [pad(d.getHours()), pad(d.getMinutes()), pad(d.getSeconds())].join(':'); return [d.getDate(), months[d.getMonth()], time].join(' '); } // log is just a thin wrapper to console.log that prepends a timestamp exports.log = function() { console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); }; /** * Inherit the prototype methods from one constructor into another. * * The Function.prototype.inherits from lang.js rewritten as a standalone * function (not on Function.prototype). NOTE: If this file is to be loaded * during bootstrapping this function needs to be rewritten using some native * functions as prototype setup using normal JavaScript does not work as * expected during bootstrapping (see mirror.js in r114903). * * @param {function} ctor Constructor function which needs to inherit the * prototype. * @param {function} superCtor Constructor function to inherit prototype from. */ exports.inherits = require('inherits'); exports._extend = function(origin, add) { // Don't do anything if add isn't an object if (!add || !isObject(add)) return origin; var keys = Object.keys(add); var i = keys.length; while (i--) { origin[keys[i]] = add[keys[i]]; } return origin; }; function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./support/isBuffer":23,"_process":9,"inherits":7}],25:[function(require,module,exports){ var util = require('util'); var intersect = require('intersect'); var WildEmitter = require('wildemitter'); var webrtc = require('webrtcsupport'); var BaseSession = require('jingle-session'); var MediaSession = require('jingle-media-session'); var FileSession = require('jingle-filetransfer-session'); function SessionManager(conf) { WildEmitter.call(this); conf = conf || {}; this.jid = conf.jid; this.selfID = conf.selfID || (this.jid && this.jid.full) || this.jid || ''; this.sessions = {}; this.peers = {}; this.prepareSession = conf.prepareSession || function (opts) { if (opts.descriptionTypes.indexOf('rtp') >= 0) { return new MediaSession(opts); } if (opts.descriptionTypes.indexOf('filetransfer') >= 0) { return new FileSession(opts); } }; this.performTieBreak = conf.performTieBreak || function (sess, req) { var descriptionTypes = req.jingle.contents.map(function (content) { if (content.description) { return content.description.descType; } }); var matching = intersect(sess.pendingDescriptionTypes, descriptionTypes); return matching.length > 0; }; this.screenSharingSupport = webrtc.screenSharing; this.capabilities = [ 'urn:xmpp:jingle:1' ]; if (webrtc.support) { this.capabilities = [ 'urn:xmpp:jingle:1', 'urn:xmpp:jingle:apps:rtp:1', 'urn:xmpp:jingle:apps:rtp:audio', 'urn:xmpp:jingle:apps:rtp:video', 'urn:xmpp:jingle:apps:rtp:rtcb-fb:0', 'urn:xmpp:jingle:apps:rtp:rtp-hdrext:0', 'urn:xmpp:jingle:apps:rtp:ssma:0', 'urn:xmpp:jingle:apps:dtls:0', 'urn:xmpp:jingle:apps:grouping:0', 'urn:xmpp:jingle:apps:file-transfer:3', 'urn:xmpp:jingle:transports:ice-udp:1', 'urn:xmpp:jingle:transports.dtls-sctp:1', 'urn:ietf:rfc:3264', 'urn:ietf:rfc:5576', 'urn:ietf:rfc:5888' ]; } this.config = { debug: false, peerConnectionConfig: { iceServers: conf.iceServers || [{'url': 'stun:stun.l.google.com:19302'}] }, peerConnectionConstraints: { optional: [ {DtlsSrtpKeyAgreement: true}, {RtpDataChannels: false} ] }, media: { audio: true, video: true } }; for (var item in conf) { this.config[item] = conf[item]; } this.iceServers = this.config.peerConnectionConfig.iceServers; } util.inherits(SessionManager, WildEmitter); SessionManager.prototype.addICEServer = function (server) { // server == { // url: '', // [username: '',] // [credential: ''] // } if (typeof server === 'string') { server = {url: server}; } this.iceServers.push(server); }; SessionManager.prototype.addSession = function (session) { var self = this; var sid = session.sid; var peer = session.peerID; this.sessions[sid] = session; if (!this.peers[peer]) { this.peers[peer] = []; } this.peers[peer].push(session); // Automatically clean up tracked sessions session.on('terminated', function () { var peers = self.peers[peer] || []; if (peers.length) { peers.splice(peers.indexOf(session), 1); } delete self.sessions[sid]; }); // Proxy session events session.on('*', function (name, data, extraData, extraData2) { // Listen for when we actually try to start a session to // trigger the outgoing event. if (name === 'send') { var action = data.jingle && data.jingle.action; if (session.isInitiator && action === 'session-initiate') { self.emit('outgoing', session); } } if (self.config.debug && (name === 'log:debug' || name === 'log:error')) { console.log('Jingle:', data, extraData, extraData2); } // Don't proxy change:* events, since those don't apply to // the session manager itself. if (name.indexOf('change') === 0) { return; } self.emit(name, data, extraData, extraData2); }); this.emit('createdSession', session); return session; }; SessionManager.prototype.createMediaSession = function (peer, sid, stream) { var session = new MediaSession({ sid: sid, peer: peer, initiator: true, stream: stream, parent: this, iceServers: this.iceServers, constraints: this.config.peerConnectionConstraints }); this.addSession(session); return session; }; SessionManager.prototype.createFileTransferSession = function (peer, sid) { var session = new FileSession({ sid: sid, peer: peer, initiator: true, parent: this }); this.addSession(session); return session; }; SessionManager.prototype.endPeerSessions = function (peer, reason, silent) { peer = peer.full || peer; var sessions = this.peers[peer] || []; delete this.peers[peer]; sessions.forEach(function (session) { session.end(reason || 'gone', silent); }); }; SessionManager.prototype.endAllSessions = function (reason, silent) { var self = this; Object.keys(this.peers).forEach(function (peer) { self.endPeerSessions(peer, reason, silent); }); }; SessionManager.prototype._createIncomingSession = function (meta, req) { var session; if (this.prepareSession) { session = this.prepareSession(meta, req); } // Fallback to a generic session type, which can // only be used to end the session. if (!session) { session = new BaseSession(meta); } this.addSession(session); return session; }; SessionManager.prototype._sendError = function (to, id, data) { if (!data.type) { data.type = 'cancel'; } this.emit('send', { to: to, id: id, type: 'error', error: data }); }; SessionManager.prototype._log = function (level, message) { this.emit('log:' + level, message); }; SessionManager.prototype.process = function (req) { var self = this; // Extract the request metadata that we need to verify var sid = !!req.jingle ? req.jingle.sid : null; var session = this.sessions[sid] || null; var rid = req.id; var sender = req.from.full || req.from; if (req.type === 'error') { var isTieBreak = req.error && req.error.jingleCondition === 'tie-break'; if (session && session.pending && isTieBreak) { return session.end('alternative-session', true); } else { if (session) { session.pendingAction = false; } return this.emit('error', req); } } if (req.type === 'result') { if (session) { session.pendingAction = false; } return; } var action = req.jingle.action; var contents = req.jingle.contents || []; var descriptionTypes = contents.map(function (content) { if (content.description) { return content.description.descType; } }); var transportTypes = contents.map(function (content) { if (content.transport) { return content.transport.transType; } }); // Now verify that we are allowed to actually process the // requested action if (action !== 'session-initiate') { // Can't modify a session that we don't have. if (!session) { this._log('error', 'Unknown session', sid); return this._sendError(sender, rid, { condition: 'item-not-found', jingleCondition: 'unknown-session' }); } // Check if someone is trying to hijack a session. if (session.peerID !== sender || session.ended) { this._log('error', 'Session has ended, or action has wrong sender'); return this._sendError(sender, rid, { condition: 'item-not-found', jingleCondition: 'unknown-session' }); } // Can't accept a session twice if (action === 'session-accept' && !session.pending) { this._log('error', 'Tried to accept session twice', sid); return this._sendError(sender, rid, { condition: 'unexpected-request', jingleCondition: 'out-of-order' }); } // Can't process two requests at once, need to tie break if (action !== 'session-terminate' && action === session.pendingAction) { this._log('error', 'Tie break during pending request'); if (session.isInitiator) { return this._sendError(sender, rid, { condition: 'conflict', jingleCondition: 'tie-break' }); } } } else if (session) { // Don't accept a new session if we already have one. if (session.peerID !== sender) { this._log('error', 'Duplicate sid from new sender'); return this._sendError(sender, rid, { condition: 'service-unavailable' }); } // Check if we need to have a tie breaker because both parties // happened to pick the same random sid. if (session.pending) { if (this.selfID > session.peerID && this.performTieBreak(session, req)) { this._log('error', 'Tie break new session because of duplicate sids'); return this._sendError(sender, rid, { condition: 'conflict', jingleCondition: 'tie-break' }); } } else { // The other side is just doing it wrong. this._log('error', 'Someone is doing this wrong'); return this._sendError(sender, rid, { condition: 'unexpected-request', jingleCondition: 'out-of-order' }); } } else if (this.peers[sender] && this.peers[sender].length) { // Check if we need to have a tie breaker because we already have // a different session with this peer that is using the requested // content description types. for (var i = 0, len = this.peers[sender].length; i < len; i++) { var sess = this.peers[sender][i]; if (sess && sess.pending && sess.sid > sid && this.performTieBreak(sess, req)) { this._log('info', 'Tie break session-initiate'); return this._sendError(sender, rid, { condition: 'conflict', jingleCondition: 'tie-break' }); } } } // We've now weeded out invalid requests, so we can process the action now. if (action === 'session-initiate') { if (!contents.length) { return self._sendError(sender, rid, { condition: 'bad-request' }); } session = this._createIncomingSession({ sid: sid, peer: req.from, peerID: sender, initiator: false, parent: this, descriptionTypes: descriptionTypes, transportTypes: transportTypes, iceServers: this.iceServers, constraints: this.config.peerConnectionConstraints }, req); } session.process(action, req.jingle, function (err) { if (err) { self._log('error', 'Could not process request', req, err); self._sendError(sender, rid, err); } else { self.emit('send', { to: sender, id: rid, type: 'result', }); // Wait for the initial action to be processed before emitting // the session for the user to accept/reject. if (action === 'session-initiate') { self.emit('incoming', session); } } }); }; module.exports = SessionManager; },{"intersect":28,"jingle-filetransfer-session":29,"jingle-media-session":78,"jingle-session":109,"util":24,"webrtcsupport":112,"wildemitter":113}],26:[function(require,module,exports){ (function (process){ /*! * async * https://github.com/caolan/async * * Copyright 2010-2014 Caolan McMahon * Released under the MIT license */ /*jshint onevar: false, indent:4 */ /*global setImmediate: false, setTimeout: false, console: false */ (function () { var async = {}; // global on the server, window in the browser var root, previous_async; root = this; if (root != null) { previous_async = root.async; } async.noConflict = function () { root.async = previous_async; return async; }; function only_once(fn) { var called = false; return function() { if (called) throw new Error("Callback was already called."); called = true; fn.apply(root, arguments); } } //// cross-browser compatiblity functions //// var _toString = Object.prototype.toString; var _isArray = Array.isArray || function (obj) { return _toString.call(obj) === '[object Array]'; }; var _each = function (arr, iterator) { for (var i = 0; i < arr.length; i += 1) { iterator(arr[i], i, arr); } }; var _map = function (arr, iterator) { if (arr.map) { return arr.map(iterator); } var results = []; _each(arr, function (x, i, a) { results.push(iterator(x, i, a)); }); return results; }; var _reduce = function (arr, iterator, memo) { if (arr.reduce) { return arr.reduce(iterator, memo); } _each(arr, function (x, i, a) { memo = iterator(memo, x, i, a); }); return memo; }; var _keys = function (obj) { if (Object.keys) { return Object.keys(obj); } var keys = []; for (var k in obj) { if (obj.hasOwnProperty(k)) { keys.push(k); } } return keys; }; //// exported async module functions //// //// nextTick implementation with browser-compatible fallback //// if (typeof process === 'undefined' || !(process.nextTick)) { if (typeof setImmediate === 'function') { async.nextTick = function (fn) { // not a direct alias for IE10 compatibility setImmediate(fn); }; async.setImmediate = async.nextTick; } else { async.nextTick = function (fn) { setTimeout(fn, 0); }; async.setImmediate = async.nextTick; } } else { async.nextTick = process.nextTick; if (typeof setImmediate !== 'undefined') { async.setImmediate = function (fn) { // not a direct alias for IE10 compatibility setImmediate(fn); }; } else { async.setImmediate = async.nextTick; } } async.each = function (arr, iterator, callback) { callback = callback || function () {}; if (!arr.length) { return callback(); } var completed = 0; _each(arr, function (x) { iterator(x, only_once(done) ); }); function done(err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; if (completed >= arr.length) { callback(); } } } }; async.forEach = async.each; async.eachSeries = function (arr, iterator, callback) { callback = callback || function () {}; if (!arr.length) { return callback(); } var completed = 0; var iterate = function () { iterator(arr[completed], function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; if (completed >= arr.length) { callback(); } else { iterate(); } } }); }; iterate(); }; async.forEachSeries = async.eachSeries; async.eachLimit = function (arr, limit, iterator, callback) { var fn = _eachLimit(limit); fn.apply(null, [arr, iterator, callback]); }; async.forEachLimit = async.eachLimit; var _eachLimit = function (limit) { return function (arr, iterator, callback) { callback = callback || function () {}; if (!arr.length || limit <= 0) { return callback(); } var completed = 0; var started = 0; var running = 0; (function replenish () { if (completed >= arr.length) { return callback(); } while (running < limit && started < arr.length) { started += 1; running += 1; iterator(arr[started - 1], function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; running -= 1; if (completed >= arr.length) { callback(); } else { replenish(); } } }); } })(); }; }; var doParallel = function (fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.each].concat(args)); }; }; var doParallelLimit = function(limit, fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [_eachLimit(limit)].concat(args)); }; }; var doSeries = function (fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.eachSeries].concat(args)); }; }; var _asyncMap = function (eachfn, arr, iterator, callback) { arr = _map(arr, function (x, i) { return {index: i, value: x}; }); if (!callback) { eachfn(arr, function (x, callback) { iterator(x.value, function (err) { callback(err); }); }); } else { var results = []; eachfn(arr, function (x, callback) { iterator(x.value, function (err, v) { results[x.index] = v; callback(err); }); }, function (err) { callback(err, results); }); } }; async.map = doParallel(_asyncMap); async.mapSeries = doSeries(_asyncMap); async.mapLimit = function (arr, limit, iterator, callback) { return _mapLimit(limit)(arr, iterator, callback); }; var _mapLimit = function(limit) { return doParallelLimit(limit, _asyncMap); }; // reduce only has a series version, as doing reduce in parallel won't // work in many situations. async.reduce = function (arr, memo, iterator, callback) { async.eachSeries(arr, function (x, callback) { iterator(memo, x, function (err, v) { memo = v; callback(err); }); }, function (err) { callback(err, memo); }); }; // inject alias async.inject = async.reduce; // foldl alias async.foldl = async.reduce; async.reduceRight = function (arr, memo, iterator, callback) { var reversed = _map(arr, function (x) { return x; }).reverse(); async.reduce(reversed, memo, iterator, callback); }; // foldr alias async.foldr = async.reduceRight; var _filter = function (eachfn, arr, iterator, callback) { var results = []; arr = _map(arr, function (x, i) { return {index: i, value: x}; }); eachfn(arr, function (x, callback) { iterator(x.value, function (v) { if (v) { results.push(x); } callback(); }); }, function (err) { callback(_map(results.sort(function (a, b) { return a.index - b.index; }), function (x) { return x.value; })); }); }; async.filter = doParallel(_filter); async.filterSeries = doSeries(_filter); // select alias async.select = async.filter; async.selectSeries = async.filterSeries; var _reject = function (eachfn, arr, iterator, callback) { var results = []; arr = _map(arr, function (x, i) { return {index: i, value: x}; }); eachfn(arr, function (x, callback) { iterator(x.value, function (v) { if (!v) { results.push(x); } callback(); }); }, function (err) { callback(_map(results.sort(function (a, b) { return a.index - b.index; }), function (x) { return x.value; })); }); }; async.reject = doParallel(_reject); async.rejectSeries = doSeries(_reject); var _detect = function (eachfn, arr, iterator, main_callback) { eachfn(arr, function (x, callback) { iterator(x, function (result) { if (result) { main_callback(x); main_callback = function () {}; } else { callback(); } }); }, function (err) { main_callback(); }); }; async.detect = doParallel(_detect); async.detectSeries = doSeries(_detect); async.some = function (arr, iterator, main_callback) { async.each(arr, function (x, callback) { iterator(x, function (v) { if (v) { main_callback(true); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(false); }); }; // any alias async.any = async.some; async.every = function (arr, iterator, main_callback) { async.each(arr, function (x, callback) { iterator(x, function (v) { if (!v) { main_callback(false); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(true); }); }; // all alias async.all = async.every; async.sortBy = function (arr, iterator, callback) { async.map(arr, function (x, callback) { iterator(x, function (err, criteria) { if (err) { callback(err); } else { callback(null, {value: x, criteria: criteria}); } }); }, function (err, results) { if (err) { return callback(err); } else { var fn = function (left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; }; callback(null, _map(results.sort(fn), function (x) { return x.value; })); } }); }; async.auto = function (tasks, callback) { callback = callback || function () {}; var keys = _keys(tasks); var remainingTasks = keys.length if (!remainingTasks) { return callback(); } var results = {}; var listeners = []; var addListener = function (fn) { listeners.unshift(fn); }; var removeListener = function (fn) { for (var i = 0; i < listeners.length; i += 1) { if (listeners[i] === fn) { listeners.splice(i, 1); return; } } }; var taskComplete = function () { remainingTasks-- _each(listeners.slice(0), function (fn) { fn(); }); }; addListener(function () { if (!remainingTasks) { var theCallback = callback; // prevent final callback from calling itself if it errors callback = function () {}; theCallback(null, results); } }); _each(keys, function (k) { var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; var taskCallback = function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } if (err) { var safeResults = {}; _each(_keys(results), function(rkey) { safeResults[rkey] = results[rkey]; }); safeResults[k] = args; callback(err, safeResults); // stop subsequent errors hitting callback multiple times callback = function () {}; } else { results[k] = args; async.setImmediate(taskComplete); } }; var requires = task.slice(0, Math.abs(task.length - 1)) || []; var ready = function () { return _reduce(requires, function (a, x) { return (a && results.hasOwnProperty(x)); }, true) && !results.hasOwnProperty(k); }; if (ready()) { task[task.length - 1](taskCallback, results); } else { var listener = function () { if (ready()) { removeListener(listener); task[task.length - 1](taskCallback, results); } }; addListener(listener); } }); }; async.retry = function(times, task, callback) { var DEFAULT_TIMES = 5; var attempts = []; // Use defaults if times not passed if (typeof times === 'function') { callback = task; task = times; times = DEFAULT_TIMES; } // Make sure times is a number times = parseInt(times, 10) || DEFAULT_TIMES; var wrappedTask = function(wrappedCallback, wrappedResults) { var retryAttempt = function(task, finalAttempt) { return function(seriesCallback) { task(function(err, result){ seriesCallback(!err || finalAttempt, {err: err, result: result}); }, wrappedResults); }; }; while (times) { attempts.push(retryAttempt(task, !(times-=1))); } async.series(attempts, function(done, data){ data = data[data.length - 1]; (wrappedCallback || callback)(data.err, data.result); }); } // If a callback is passed, run this as a controll flow return callback ? wrappedTask() : wrappedTask }; async.waterfall = function (tasks, callback) { callback = callback || function () {}; if (!_isArray(tasks)) { var err = new Error('First argument to waterfall must be an array of functions'); return callback(err); } if (!tasks.length) { return callback(); } var wrapIterator = function (iterator) { return function (err) { if (err) { callback.apply(null, arguments); callback = function () {}; } else { var args = Array.prototype.slice.call(arguments, 1); var next = iterator.next(); if (next) { args.push(wrapIterator(next)); } else { args.push(callback); } async.setImmediate(function () { iterator.apply(null, args); }); } }; }; wrapIterator(async.iterator(tasks))(); }; var _parallel = function(eachfn, tasks, callback) { callback = callback || function () {}; if (_isArray(tasks)) { eachfn.map(tasks, function (fn, callback) { if (fn) { fn(function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } callback.call(null, err, args); }); } }, callback); } else { var results = {}; eachfn.each(_keys(tasks), function (k, callback) { tasks[k](function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } results[k] = args; callback(err); }); }, function (err) { callback(err, results); }); } }; async.parallel = function (tasks, callback) { _parallel({ map: async.map, each: async.each }, tasks, callback); }; async.parallelLimit = function(tasks, limit, callback) { _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); }; async.series = function (tasks, callback) { callback = callback || function () {}; if (_isArray(tasks)) { async.mapSeries(tasks, function (fn, callback) { if (fn) { fn(function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } callback.call(null, err, args); }); } }, callback); } else { var results = {}; async.eachSeries(_keys(tasks), function (k, callback) { tasks[k](function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } results[k] = args; callback(err); }); }, function (err) { callback(err, results); }); } }; async.iterator = function (tasks) { var makeCallback = function (index) { var fn = function () { if (tasks.length) { tasks[index].apply(null, arguments); } return fn.next(); }; fn.next = function () { return (index < tasks.length - 1) ? makeCallback(index + 1): null; }; return fn; }; return makeCallback(0); }; async.apply = function (fn) { var args = Array.prototype.slice.call(arguments, 1); return function () { return fn.apply( null, args.concat(Array.prototype.slice.call(arguments)) ); }; }; var _concat = function (eachfn, arr, fn, callback) { var r = []; eachfn(arr, function (x, cb) { fn(x, function (err, y) { r = r.concat(y || []); cb(err); }); }, function (err) { callback(err, r); }); }; async.concat = doParallel(_concat); async.concatSeries = doSeries(_concat); async.whilst = function (test, iterator, callback) { if (test()) { iterator(function (err) { if (err) { return callback(err); } async.whilst(test, iterator, callback); }); } else { callback(); } }; async.doWhilst = function (iterator, test, callback) { iterator(function (err) { if (err) { return callback(err); } var args = Array.prototype.slice.call(arguments, 1); if (test.apply(null, args)) { async.doWhilst(iterator, test, callback); } else { callback(); } }); }; async.until = function (test, iterator, callback) { if (!test()) { iterator(function (err) { if (err) { return callback(err); } async.until(test, iterator, callback); }); } else { callback(); } }; async.doUntil = function (iterator, test, callback) { iterator(function (err) { if (err) { return callback(err); } var args = Array.prototype.slice.call(arguments, 1); if (!test.apply(null, args)) { async.doUntil(iterator, test, callback); } else { callback(); } }); }; async.queue = function (worker, concurrency) { if (concurrency === undefined) { concurrency = 1; } function _insert(q, data, pos, callback) { if (!q.started){ q.started = true; } if (!_isArray(data)) { data = [data]; } if(data.length == 0) { // call drain immediately if there are no tasks return async.setImmediate(function() { if (q.drain) { q.drain(); } }); } _each(data, function(task) { var item = { data: task, callback: typeof callback === 'function' ? callback : null }; if (pos) { q.tasks.unshift(item); } else { q.tasks.push(item); } if (q.saturated && q.tasks.length === q.concurrency) { q.saturated(); } async.setImmediate(q.process); }); } var workers = 0; var q = { tasks: [], concurrency: concurrency, saturated: null, empty: null, drain: null, started: false, paused: false, push: function (data, callback) { _insert(q, data, false, callback); }, kill: function () { q.drain = null; q.tasks = []; }, unshift: function (data, callback) { _insert(q, data, true, callback); }, process: function () { if (!q.paused && workers < q.concurrency && q.tasks.length) { var task = q.tasks.shift(); if (q.empty && q.tasks.length === 0) { q.empty(); } workers += 1; var next = function () { workers -= 1; if (task.callback) { task.callback.apply(task, arguments); } if (q.drain && q.tasks.length + workers === 0) { q.drain(); } q.process(); }; var cb = only_once(next); worker(task.data, cb); } }, length: function () { return q.tasks.length; }, running: function () { return workers; }, idle: function() { return q.tasks.length + workers === 0; }, pause: function () { if (q.paused === true) { return; } q.paused = true; }, resume: function () { if (q.paused === false) { return; } q.paused = false; // Need to call q.process once per concurrent // worker to preserve full concurrency after pause for (var w = 1; w <= q.concurrency; w++) { async.setImmediate(q.process); } } }; return q; }; async.priorityQueue = function (worker, concurrency) { function _compareTasks(a, b){ return a.priority - b.priority; }; function _binarySearch(sequence, item, compare) { var beg = -1, end = sequence.length - 1; while (beg < end) { var mid = beg + ((end - beg + 1) >>> 1); if (compare(item, sequence[mid]) >= 0) { beg = mid; } else { end = mid - 1; } } return beg; } function _insert(q, data, priority, callback) { if (!q.started){ q.started = true; } if (!_isArray(data)) { data = [data]; } if(data.length == 0) { // call drain immediately if there are no tasks return async.setImmediate(function() { if (q.drain) { q.drain(); } }); } _each(data, function(task) { var item = { data: task, priority: priority, callback: typeof callback === 'function' ? callback : null }; q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); if (q.saturated && q.tasks.length === q.concurrency) { q.saturated(); } async.setImmediate(q.process); }); } // Start with a normal queue var q = async.queue(worker, concurrency); // Override push to accept second parameter representing priority q.push = function (data, priority, callback) { _insert(q, data, priority, callback); }; // Remove unshift function delete q.unshift; return q; }; async.cargo = function (worker, payload) { var working = false, tasks = []; var cargo = { tasks: tasks, payload: payload, saturated: null, empty: null, drain: null, drained: true, push: function (data, callback) { if (!_isArray(data)) { data = [data]; } _each(data, function(task) { tasks.push({ data: task, callback: typeof callback === 'function' ? callback : null }); cargo.drained = false; if (cargo.saturated && tasks.length === payload) { cargo.saturated(); } }); async.setImmediate(cargo.process); }, process: function process() { if (working) return; if (tasks.length === 0) { if(cargo.drain && !cargo.drained) cargo.drain(); cargo.drained = true; return; } var ts = typeof payload === 'number' ? tasks.splice(0, payload) : tasks.splice(0, tasks.length); var ds = _map(ts, function (task) { return task.data; }); if(cargo.empty) cargo.empty(); working = true; worker(ds, function () { working = false; var args = arguments; _each(ts, function (data) { if (data.callback) { data.callback.apply(null, args); } }); process(); }); }, length: function () { return tasks.length; }, running: function () { return working; } }; return cargo; }; var _console_fn = function (name) { return function (fn) { var args = Array.prototype.slice.call(arguments, 1); fn.apply(null, args.concat([function (err) { var args = Array.prototype.slice.call(arguments, 1); if (typeof console !== 'undefined') { if (err) { if (console.error) { console.error(err); } } else if (console[name]) { _each(args, function (x) { console[name](x); }); } } }])); }; }; async.log = _console_fn('log'); async.dir = _console_fn('dir'); /*async.info = _console_fn('info'); async.warn = _console_fn('warn'); async.error = _console_fn('error');*/ async.memoize = function (fn, hasher) { var memo = {}; var queues = {}; hasher = hasher || function (x) { return x; }; var memoized = function () { var args = Array.prototype.slice.call(arguments); var callback = args.pop(); var key = hasher.apply(null, args); if (key in memo) { async.nextTick(function () { callback.apply(null, memo[key]); }); } else if (key in queues) { queues[key].push(callback); } else { queues[key] = [callback]; fn.apply(null, args.concat([function () { memo[key] = arguments; var q = queues[key]; delete queues[key]; for (var i = 0, l = q.length; i < l; i++) { q[i].apply(null, arguments); } }])); } }; memoized.memo = memo; memoized.unmemoized = fn; return memoized; }; async.unmemoize = function (fn) { return function () { return (fn.unmemoized || fn).apply(null, arguments); }; }; async.times = function (count, iterator, callback) { var counter = []; for (var i = 0; i < count; i++) { counter.push(i); } return async.map(counter, iterator, callback); }; async.timesSeries = function (count, iterator, callback) { var counter = []; for (var i = 0; i < count; i++) { counter.push(i); } return async.mapSeries(counter, iterator, callback); }; async.seq = function (/* functions... */) { var fns = arguments; return function () { var that = this; var args = Array.prototype.slice.call(arguments); var callback = args.pop(); async.reduce(fns, args, function (newargs, fn, cb) { fn.apply(that, newargs.concat([function () { var err = arguments[0]; var nextargs = Array.prototype.slice.call(arguments, 1); cb(err, nextargs); }])) }, function (err, results) { callback.apply(that, [err].concat(results)); }); }; }; async.compose = function (/* functions... */) { return async.seq.apply(null, Array.prototype.reverse.call(arguments)); }; var _applyEach = function (eachfn, fns /*args...*/) { var go = function () { var that = this; var args = Array.prototype.slice.call(arguments); var callback = args.pop(); return eachfn(fns, function (fn, cb) { fn.apply(that, args.concat([cb])); }, callback); }; if (arguments.length > 2) { var args = Array.prototype.slice.call(arguments, 2); return go.apply(this, args); } else { return go; } }; async.applyEach = doParallel(_applyEach); async.applyEachSeries = doSeries(_applyEach); async.forever = function (fn, callback) { function next(err) { if (err) { if (callback) { return callback(err); } throw err; } fn(next); } next(); }; // Node.js if (typeof module !== 'undefined' && module.exports) { module.exports = async; } // AMD / RequireJS else if (typeof define !== 'undefined' && define.amd) { define([], function () { return async; }); } // included directly via