/* --------------------------------------------------------------------------------- file-start: js/jquery/jquery.lj.calendar.js */ /* --------------------------------------------------------------------------------- file-start: js/jquery/jquery.lj.inlineCalendar.js */ /*! * LiveJournal Inline calendar * * Copyright 2011, dmitry.petrov@sup.com * * http://docs.jquery.com/UI * * Depends: * jquery.ui.core.js * jquery.ui.widget.js * * @overview Inline calendar widget. * * Widget can be attached to any existant markup. * * Date wildcards used: * - %D - day ( 01 - 31 ) * - %M - month ( 01 - 02 ) * - %Y - year ( yyyy, e.g. 2002 ) * - %s - unix timestamp in ms * * Options: * - dayRef: Format of the url that will be attached to each day in the calendar. * - allRefs: Wether to attach links to days in the calendar. * and override currentDate on success. * Could be: true/false/Object {from: Date, to: Date} (all fields are not required) * - activeFrom: Days before this will be inactive in calendar. * - actoveUntil: Days after this willbe inactive incalendar. * - startMonth: Widget will not allow to switch calendar pane to the month before this. * - endMonth: Widget will not allow to switch calendar pane to the month after this. * - startAtSunday: Wether to count sunday as the start of the week. * - events: Object, containing events to show in the calendar. They will be rendered as links. Structure of the object: * { "yyyy": { "mm1" : [ d1, d2, d3, d4 ], "mm2": [ d5, d6, d7 ] } } * * Events: * - daySelected: Event is triggered when user selects a day in the calendar. The second parameter passed to the * function is a Date object. * - dateChange Event is triggered when user click on next or prev month/year button. * - currentDateChange: Events is triggered when a new date is set in calendar as current. * * Consistent options ( setting these options is guaranteed to work correctly ): * - currentDate, date - Set/get current date. * - activeFrom, date - Set/get earliest active date. * - activeUntil, date - Set/get last active date. * - title, title - set calendar title. * - events, obj - override current events object * * @TODO: move all service functions to the widget object and merge it with the view. * */ (function( $, window ) { var defaultOptions = { dayRef: '/%Y/%M/%D', monthRef: '', //the same, but for the months and year. Calendar will render link, if options are set yearRef: '', allRefs: false, currentDate: new Date(), //allow user to select dates in this range activeUntil: null, activeFrom: null, //allow user to switch months between these dates startMonth: new Date( 1900, 0, 1 ), endMonth: new Date( 2050, 0, 1 ), startAtSunday: !(LJ.ml('date.format.offset') !== '0') || false, dateFormat: "%Y-%M-%D", defaultTitle: "Calendar", longMonth: false, events: null, //object with events to show in the calendar displayedMonth: null, //month displayed on the calendar. If not specified at //startup currentDate is used instead. dateChange: null, selectors: { table: 'table', title: 'h5', tbody: 'tbody', month: '.cal-nav-month', year: '.cal-nav-year', monthSelect: '.cal-nav-month-select', yearSelect: '.cal-nav-year-select', prevMonth: '.cal-nav-month .cal-nav-prev', nextMonth: '.cal-nav-month .cal-nav-next', prevYear: '.cal-nav-year .cal-nav-prev', nextYear: '.cal-nav-year .cal-nav-next', monthLabel: '.cal-nav-month .cal-month', yearLabel: '.cal-nav-year .cal-year' }, classNames: { container: '', inactive : 'other', future : 'other', current : 'current', weekend: 'weekend', nextDisabled : 'cal-nav-next-dis', prevDisabled : 'cal-nav-prev-dis', cellHover : 'hover', longMonth: 'sidebar-cal-longmonth' }, //now, all lang variables are collected from Site.ml_text and should not be modified mlPrefix: { monthNamesShort: ['monthNames', 'date.month.{name}.short'], monthNamesLong: ['monthNames', 'date.month.{name}.long'], dayNamesShort: ['dayNames', 'date.day.{name}.short'] }, ml: { monthNames: [ "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"], dayNames: ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'], caption: "Calendar" } }; function getDateNumber( d, dropDays ) { dropDays = dropDays || false; var day = d.getDate().toString(); if( day.length === 1 ) { day = "0" + day; } if( dropDays ) { day = ""; } var month = d.getMonth().toString(); if( month.length === 1 ) { month = "0" + month; } return parseInt( d.getFullYear().toString() + month + day, 10); } function insideTimeRange( range, iDate ) { return getDateNumber( iDate, true ) >= getDateNumber( range[0], true ) && getDateNumber( iDate, true ) <= getDateNumber( range[1], true ); } function View(nodes, styles, o) { this.initialize = function (date) { this.tbody = this.catchTableStructure(date); }; this.modelChanged = function (monthDate, events, switcherStates) { var monthml = o.longMonth? o.ml.monthNamesLong : o.ml.monthNamesShort; //we have a 30% speedup when we temporary remove tbody from dom this.tbody.detach(); this.fillDates(monthDate, events); for (var sws in switcherStates) { nodes[sws][ (!switcherStates[sws]) ? 'addClass' : 'removeClass']( this.disabledStyle(sws) ); } var monthText = o.monthRef ? $( '', { href: LJ.Util.Date.format( monthDate, o.monthRef ), text: monthml[ monthDate.getMonth() ] + (o.monthWithYear ? (' ' + monthDate.getFullYear()) : '') } ) : monthml[ monthDate.getMonth() ]; var yearText = o.yearRef ? $( '', { href: LJ.Util.Date.format( monthDate, o.yearRef ), text: monthDate.getFullYear() } ) : monthDate.getFullYear(); nodes.monthLabel.empty().append( monthText ); nodes.yearLabel.empty().append( yearText ); this.tbody.appendTo( nodes.table ); }; this.catchTableStructure = function(date) { var tbody = nodes.tbody[0]; nodes.daysCells = []; nodes.daysSpans = []; var row, rowsCount = tbody.rows.length, cell, cellsCount; var toAdd = 6 - rowsCount; var rowStr = ''; for( var i = 0; i < 7; ++i ) { rowStr += ''; } rowStr += ''; while( toAdd-- > 0 ) { //add missing rows if server has rendered not enough markup $( rowStr ).hide().appendTo( nodes.tbody ); } rowsCount = 6; nodes.lastRow = jQuery( tbody.rows[ tbody.rows.length - 1 ] ); date = new Date(date); for( row = 0; row < rowsCount; ++row ) { for( cell = 0, cellsCount = tbody.rows[ row ].cells.length; cell < cellsCount; ++cell ) { // take into account span inside td var node = jQuery( tbody.rows[ row ].cells[ cell ] ), children = node.children(), day = children.text().trim(); if(day) { date.setDate(day); node.data('isActive', true); node.data('day', date); } nodes.daysCells.push(node); nodes.daysSpans.push(children); } } return jQuery( tbody ); }; this.fillDates = function (monthDate, events) { function hasEvents( date ) { var year = date.getFullYear(), month = date.getMonth(), day = date.getDate(); return( events && events[ year ] && events[ year ][ month ] && events[ year ][ month ][ day ] ); } var d = new Date( monthDate ); d.setDate( 1 ); var offset; if( o.startAtSunday ) { offset = d.getDay(); } else { offset = ( d.getDay() === 0 ? 6 : d.getDay() - 1 ); } d.setDate( 1 - offset ); for( var i = 0, l = nodes.daysCells.length; i < l; ++i ) { var cell = nodes.daysCells[ i ], span = nodes.daysSpans[ i ]; this.formDayString( d, cell, span, hasEvents( d ), this.isActiveDate( d, monthDate ) ); d.setDate( d.getDate() + 1 ); } d.setDate( d.getDate() - 1 ); //get the date from the last cell //we do not use show and hide methods, because show method sets display: block; if( d.getDate() < 7 ) { nodes.lastRow.css('display', ''); } else { nodes.lastRow.css('display', 'none'); } }; this.isActiveDate = function( date, currentMonth ) { var isActive = true; isActive = ( currentMonth.getFullYear() === date.getFullYear() && currentMonth.getMonth() === date.getMonth() ); if( isActive && ( o.activeFrom || o.activeUntil ) ) { isActive = ( o.activeFrom && getDateNumber( o.activeFrom ) <= getDateNumber( date ) ) || ( o.activeUntil && getDateNumber( o.activeUntil ) >= getDateNumber( date ) ); } return isActive; }; this.formDayString = function( d, cell, span, hasEvents, isActive ) { d = new Date( d ); var oldDay = cell.data( 'day' ), oldHasEvents = cell.data( 'hasEvents' ), oldIsActive = cell.data( 'isActive' ); var isCurrentDay = ( getDateNumber( d ) === getDateNumber( o.currentDate ) ); cell.data( 'day', d ); cell.data( 'isActive', isActive ); cell.data( 'hasEvents', hasEvents ); cell[isCurrentDay ? 'addClass' : 'removeClass']( styles.current ); cell.removeClass( styles.cellHover ); if( !isActive ) { cell.addClass( styles.inactive ); span.html(d.getDate()); } else if( hasEvents || o.allRefs ) { var _tmpAllRefs = true; if (o.allRefs && typeof o.allRefs === 'object') { if (o.allRefs.from && d < o.allRefs.from) { _tmpAllRefs = false; } if (o.allRefs.to && d > o.allRefs.to) { _tmpAllRefs = false; } } if (_tmpAllRefs) { cell.removeClass( styles.inactive ); span.html( $( '', { html: d.getDate(), href: LJ.Util.Date.format( d, o.dayRef ), target: '_self' })); } else { cell.removeClass(styles.inactive); span.html(d.getDate()); } } else { cell.removeClass( styles.inactive ); span.html(d.getDate()); } }; this.disabledStyle = function (sws) { if(sws === 'prevMonth' || sws === 'prevYear') { return styles.prevDisabled; } else { return styles.nextDisabled; } }; } var Calendar = { options: {}, //all options were move to the default options object _create: function() { this._preInit(); this._initialize(); this._postInit(); }, _preInit: function() { var def = $[ this.namespace ][ this.widgetName ].getDefaults(); this.options = jQuery.extend( true, {}, def, this.options ); this._prepareMLVars(); }, _prepareMLVars: function() { var self = this, expandVar = function(prefix, name) { return LJ.ml(prefix.supplant({name: name})); }, prefixData; for (var prefix in this.options.mlPrefix) { if (this.options.mlPrefix.hasOwnProperty(prefix)) { prefixData = this.options.mlPrefix[prefix]; this.options.ml[prefix] = this.options.ml[prefixData[0]].map(expandVar.bind(null, prefixData[1])); } } }, // @TODO: need to change the structure of initialization code to remove this method _initialize: function() { if( !this.options.displayedMonth ) { this.options.displayedMonth = new Date( this.options.currentDate ); } this._events = this.options.events; this._hideTimer = null; this._nodes = this._nodes || { container: this.element, root: this.element }; this._invalidateTimer = null; if (this.element.hasClass(this.options.classNames.longMonth)) { this.options.longMonth = true; } this._bindNodes(); this.options.startMonth.setDate( 1 ); this._view = new (this._getView())( this._nodes, this.options.classNames, this.options ); this._view.initialize(this.options.currentDate); if( this._nodes.table.hasClass( "monday" ) ) { this._setOption( "startAtSunday", false ); } this._nodes.monthSelect.val(this.options.displayedMonth.getMonth()); this._nodes.yearSelect.val(this.options.displayedMonth.getFullYear()); this._bindEvents(); }, _postInit: function() { }, _getView: function() { return View; }, _bindNodes: function() { for( var i in this.options.selectors ) { if( !( i in this._nodes ) ) { this._nodes[ i ] = this._nodes.container.find( this.options.selectors[ i ] ); } } var displayedMonth = LJ.Util.Date.parse(this._nodes.table.attr( "data-date"), this.options.dateFormat) if(displayedMonth) { this.options.displayedMonth = displayedMonth; } }, destroy: function() { $.Widget.prototype.destroy.apply(this, arguments); }, _bindEvents: function() { var self = this; var switcherStates = this._getSwitcherStates( this.options.currentDate ), switcherMouseDown = function( item ) { return function (ev) { ev.preventDefault(); ev.stopPropagation(); var switcherStates = self._getSwitcherStates( self.options.currentDate ); if( switcherStates[item] ) { self["_" + item](); } }; }; for (var sws in switcherStates) { this._nodes[sws].click( switcherMouseDown(sws) ); } this._nodes.monthSelect.change(function(ev) { var d = new Date(self.options.currentDate); d.setMonth(this.value); self._setOption('currentDate', d); }); this._nodes.yearSelect.change(function(ev) { var d = new Date(self.options.currentDate); d.setFullYear(this.value); self._setOption('currentDate', d); }); this._nodes.tbody .delegate( 'td', 'click', function( ev ) { self._cellSelectedEvent( $( this ), ev ); } ); }, _switchMonth: function ( go ) { var event = jQuery.Event( "dateChange" ); event.moveForward = go > 0; event.switchType = Math.abs( go ) === 12 ? "year" : ( Math.abs( go ) === 1 ? "month" : null ); event.date = new Date(this.options.displayedMonth.getFullYear(), this.options.displayedMonth.getMonth() + go, 1); this._nodes.root.trigger( event ); this._setOption( 'displayedMonth', event.date ); }, _prevMonth: function () { this._switchMonth( -1 ); }, _nextMonth: function () { this._switchMonth( 1 ); }, _prevYear : function () { this._switchMonth( -12 ); }, _nextYear : function () { this._switchMonth( 12 ); }, _cellSelectedEvent: function( cell, ev ) { //if cell is inactive or user controls it's behavior we do not pass event to the link if( !cell.data('isActive' ) || this._cellSelected( cell.data( 'day' ) ) ) { ev.stopPropagation(); ev.preventDefault(); } }, /** * @return {Boolean} returns true if user prevents default behaviour */ _cellSelected: function( date ) { var event = jQuery.Event( "daySelected" ); this._nodes.root.trigger( event, [ date, LJ.Util.Date.format(date, this.options.dateFormat) ] ); if( !event.isDefaultPrevented() ) { this._setOption( 'currentDate', date ); } return !event.isDefaultPrevented(); }, _fitDate: function( date ) { date = new Date( date ); var enabledMonthsRange = [ this.options.startMonth, this.options.endMonth ]; if( !insideTimeRange( enabledMonthsRange, date ) ) { if( getDateNumber( date, true ) < getDateNumber( enabledMonthsRange[ 0 ], true ) ) { date = new Date( enabledMonthsRange[ 0 ] ); } else { date = new Date( enabledMonthsRange[ 1 ] ); } } return date; }, _getSwitcherStates: function () { var monthDate = this.options.displayedMonth, yearStart = new Date( monthDate.getFullYear(), 0, 1 ), yearEnd = new Date( monthDate.getFullYear(), 11, 1 ); return { prevMonth: this._isActivePrev( monthDate ) !== false, prevYear: this._isActivePrev( yearStart ) !== false, nextMonth: this._isActiveNext( monthDate ) !== false, nextYear: this._isActiveNext( yearEnd ) !== false }; }, _isActiveNext: function( date ) { return this._isActiveDate( date, 1 ); }, _isActivePrev: function( date ) { return this._isActiveDate( date, -1 ); }, _isActiveDate: function( date, dir ) { var d = new Date( date ); d.setMonth( d.getMonth() + dir ); d.setDate( 1 ); return insideTimeRange( [ this.options.startMonth, this.options.endMonth ], d ); }, _invalidateDisplay: function() { var self = this; clearTimeout( this._invalidateTimer ); setTimeout( function() { self._view.modelChanged( self.options.displayedMonth, self._events, self._getSwitcherStates() ); }, 50 ); }, _setOption: function( name, value ) { switch( name ) { case 'currentDate': this.options.currentDate = this._fitDate( value ); var event = jQuery.Event("currentDateChange"), date = new Date(this.options.currentDate); this._nodes.root.trigger( event, [ date, LJ.Util.Date.format(date, this.options.dateFormat) ] ); this._setOption( 'displayedMonth', value ); this._invalidateDisplay(); break; case 'activeFrom': this.options.activeFrom = new Date( value ); this._invalidateDisplay(); break; case 'activeUntil': this.options.activeUntil = new Date( value ); this._invalidateDisplay(); break; case 'title': this._title = value; this._nodes.title.html( value ); break; case 'events': this._events = value; this._invalidateDisplay(); break; case 'displayedMonth': var newDate = this._fitDate( new Date( value ) ), isCurrentMonth = getDateNumber(newDate, true) === getDateNumber(this.options.displayedMonth, true); if( !isCurrentMonth ) { this.options.displayedMonth = this._fitDate( new Date( value ) ); this._nodes.monthSelect.val(this.options.displayedMonth.getMonth()); this._nodes.yearSelect.val(this.options.displayedMonth.getFullYear()); this._invalidateDisplay(); } break; case 'startMonth': this.options.startMonth = new Date( value ); this._invalidateDisplay(); break; case 'endMonth': this.options.endMonth = new Date( value ); this._invalidateDisplay(); break; case 'startAtSunday': this.options.startAtSunday = !!value; break; case 'monthWithYear': this.options.monthWithYear = Boolean(value); break; } }, getElement: function( name ) { if( name in this._nodes ) { return this._nodes[ name ]; } else { return null; } } }; $.widget('lj.inlineCalendar', Calendar ); jQuery.extend( $.lj.inlineCalendar, { getDefaults: function() { return defaultOptions; }, setDefaults: function ( opts ) { if( opts ) { jQuery.extend( true, defaultOptions, opts ); } } } ); } ( jQuery, window ) ); ; /* file-end: js/jquery/jquery.lj.inlineCalendar.js ----------------------------------------------------------------------------------*/ !function(a,b){var c,d={showOn:"click",closeControl:!0,showCellHovers:!1,hoverDelay:400,align:"center",events:null,displayedMonth:null,bubbleClass:!1,selectors:{tmpl:".appwidget-calendar .calendar"},classNames:{showCellHovers:"all-days",popup:"b-bubble-calendar"},templates:{calendar:''}},e={options:{},_initialize:function(){c||(c=this._buildDOM()),this._nodes={container:c.clone(),root:this.element},a.lj.inlineCalendar.prototype._initialize.apply(this),this._invalidateDisplay()},_bindNodes:function(){a.lj.inlineCalendar.prototype._bindNodes.apply(this);var b=this;this._nodes.container.bubble({classNames:{containerAddClass:this.options.bubbleClass?this.options.classNames.popup:""},target:this._nodes.root,align:this.options.align,closeControl:this.options.closeControl,showOn:this.options.showOn,closeOnContentClick:!1}).bind("bubbleshow",function(){b._trigger("show")}).bind("bubblehide",function(){b._trigger("hide")}).addClass(this.options.classNames.container),this._nodes.input=this.options.input?this.options.input:this._nodes.root.is("[type=text]")?this._nodes.root:a(),this._nodes.input.mask&&this._nodes.input.mask("?dddd-dd-dd",{placeholder:" "}),this._nodes.input.input(this._parseInputValue.bind(this));var c=LJ.Util.Date.parse(this._nodes.input.val(),this.options.dateFormat);c&&(this.options.currentDate=c),this.options.showCellHovers&&this._nodes.table.addClass(this.options.classNames.showCellHovers)},destroy:function(){this._nodes.container.bubble("destroy"),a.lj.inlineCalendar.prototype.destroy.apply(this)},_buildDOM:function(){var a=this.options.ml.dayNamesShort.map(function(a){return{day:a}}),b=0,c=6,d=function(a,b){for(var c=[];a--;)c.push(b);return c};this.options.startAtSunday||(a[7]=a[0],a.shift(),b=5);for(var e=[],f=[],g=this.options.endMonth.getFullYear(),h=this.options.startMonth.getFullYear();g>=h;)e.push({year:g--});f=this.options.ml.monthNamesLong.map(function(a){return{month:a}});var i={caption:this.options.ml.caption,days:a,months:f,years:e,cells:d(42,{}),weekend1:b,weekend2:c};return-1!==this.options.templates.calendar.indexOf(" ")?jQuery.tmpl(this.options.templates.calendar,i):LJ.UI.template(this.options.templates.calendar,i)},_parseInputValue:function(){var a=LJ.Util.Date.parse(this._nodes.input.val(),this.options.dateFormat);a&&this._cellSelected(a)},_cellSelectedEvent:function(c,d){var e=this;a.lj.inlineCalendar.prototype._cellSelectedEvent.call(this,c,d),e.options.showCellHovers&&c.data("isActive")&&e._nodes.container.bubble("hide"),"a"==d.target.tagName.toLowerCase()&&(b.location.href=d.target.href)},_invalidateDisplay:function(){this._view.modelChanged(this.options.displayedMonth,this._events,this._getSwitcherStates())},_setOption:function(b,c){switch(a.lj.inlineCalendar.prototype._setOption.call(this,b,c),b){case"currentDate":this._nodes.input.val(LJ.Util.Date.format(this.options.currentDate,this.options.dateFormat))}}};a.widget("lj.calendar",a.lj.inlineCalendar,e),jQuery.extend(a.lj.calendar,{getDefaults:function(){return jQuery.extend(!0,{},a.lj.inlineCalendar.getDefaults(),d)},setDefaults:function(a){a&&jQuery.extend(d,a)}})}(jQuery,window);; /* file-end: js/jquery/jquery.lj.calendar.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/jquery/jquery.mask.js */ !function(a){var b=(a.browser.msie?"paste":"input")+".mask",c=void 0!=window.orientation;a.mask={definitions:{d:"[0-9]",w:"[A-Za-z]","*":"[A-Za-z0-9а-яА-Я]"}},a.fn.extend({unmask:function(){return this.trigger("unmask")},mask:function(d,e){if(!d&&this.length>0){var f=a(this[0]),g=f.data("tests");return a.map(f.data("buffer"),function(a,b){return g[b]?a:null}).join("")}e=a.extend({placeholder:"_",completed:null},e);var h=a.mask.definitions,g=[],i=d.length,j=null,k=d.length;return a.each(d.split(""),function(a,b){"?"==b?(k--,i=a):h[b]?(g.push(new RegExp(h[b])),null==j&&(j=g.length-1)):g.push(null)}),this.each(function(){function f(a){for(;++a<=k&&!g[a];);return a}function l(a){for(;!g[a]&&--a>=0;);for(var b=a;k>b;b++)if(g[b]){t[b]=e.placeholder;var c=f(b);if(!(k>c&&g[b].test(t[c])))break;t[b]=t[c]}q(),s.caret(Math.max(j,a))}function m(a){for(var b=a,c=e.placeholder;k>b;b++)if(g[b]){var d=f(b),h=t[b];if(t[b]=c,!(k>d&&g[d].test(h)))break;c=h}}function n(b){var d=a(this).caret(),e=b.keyCode;return u=16>e||e>16&&32>e||e>32&&41>e,d.start-d.end==0||u&&8!=e&&46!=e||p(d.start,d.end),8==e||46==e||c&&127==e?(l(d.start+(46==e?0:-1)),!1):27==e?(s.val(v),s.caret(0,r()),!1):void 0}function o(b){if(u)return u=!1,8==b.keyCode?!1:null;b=b||window.event;var c=b.charCode||b.keyCode||b.which,d=a(this).caret();if(b.ctrlKey||b.altKey||b.metaKey)return!0;if(c>=32&&125>=c||c>186){var h=f(d.start-1);if(k>h){var i=String.fromCharCode(c);if(g[h].test(i)){m(h),t[h]=i,q();var d=f(h);a(this).caret(d),e.completed&&d==k&&e.completed.call(s)}}}return!1}function p(a,b){for(var c=a;b>c&&k>c;c++)g[c]&&(t[c]=e.placeholder)}function q(){return s.val(t.join("")).val()}function r(a){for(var b=s.val(),c=-1,d=0,f=0;k>d;d++)if(g[d]){for(t[d]=e.placeholder;f++b.length)break}else t[d]==b.charAt(f)&&d!=i&&(f++,c=d);return!a&&i>c+1?(s.val(""),p(0,k)):(a||c+1>=i)&&(q(),a||s.val(s.val().substring(0,c+1))),i?d:j}var s=a(this),t=a.map(d.split(""),function(a){return"?"!=a?h[a]?e.placeholder:a:void 0}),u=!1,v=s.val();s.data("buffer",t).data("tests",g),s.attr("readonly")||s.one("unmask",function(){s.unbind(".mask").removeData("buffer").removeData("tests")}).bind("focus.mask",function(){v=s.val();var a=r();q(),setTimeout(function(){a==d.length?s.caret(0,a):s.caret(a)},0)}).bind("blur.mask",function(){r(),s.val()!=v&&s.change()}).bind("keydown.mask",n).bind("keypress.mask",o).bind(b,function(){setTimeout(function(){s.caret(r(!0))},0)}),r()})}})}(jQuery);; /* file-end: js/jquery/jquery.mask.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/controlstrip.js */ /* --------------------------------------------------------------------------------- file-start: js/jquery/jquery.calendarEvents.js */ !function(a){var b={};a.fn.calendarEvents=function(c){function d(a,b){return"cache_"+a+b}function e(a,b){var c=this;this.calendar=a,this.events=null,this.options=b,this._ajaxActive=!1,this._currentDate;var e,f=function(b,f){"string"!=typeof a.data("noFetch")&&(clearTimeout(e),c._currentDate=d(b.getFullYear(),b.getMonth()+1),e=setTimeout(function(){c.fetchEvents(b.getFullYear(),b.getMonth()+1,f)},200))};this.calendar.bind("dateChange",function(a){var b=c.calendar[c.options.calendarType]("option","displayedMonth"),d=1===Math.abs(12*(a.date.getFullYear()-b.getFullYear())+(a.date.getMonth()-b.getMonth()));f(a.date,d)}),this.options.fetchOnFirstDisplay&&this.calendar.one("calendarshow",function(){f(new Date,!0)})}var f={calendarType:"calendar",classNames:{idle:"idle"},fetchOnFirstDisplay:!1};return e.prototype={getEvents:function(a,b,c){var d={};return d[+a]={},d[+a][+b-1]=c,d},fetchEvents:function(c,e,f){f=arguments.length>=3?!!f:!0;var g=this,h=(this.calendar[this.options.calendarType]("option","displayedMonth"),this.calendar[this.options.calendarType]("getElement",f?"month":"year")),i=this.options.classNames.idle,j=!0,k=function(){g._ajaxActive||j||h.removeClass(i)};this.calendar[this.options.calendarType]("getElement","year").removeClass(i),this.calendar[this.options.calendarType]("getElement","month").removeClass(i),h.addClass(i),this._ajaxActive=!0,setTimeout(function(){j=!1,k()},500);var l=d(c,e);processResults=function(){l===g._currentDate&&(g.events=b[l],g.calendar[g.options.calendarType]("option","events",g.getEvents(g.events.year,g.events.month,g.events.days)),g._ajaxActive=!1,k())},l in b?processResults(b[l]):a.getJSON(LiveJournal.getAjaxUrl("calendar"),{year:c,month:e},function(a){b[l]=a,processResults(a)})}},this.each(function(){new e(a(this),a.extend({},f,c))})}}(jQuery);; /* file-end: js/jquery/jquery.calendarEvents.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/relations/menu.js */ /** * Change relations from controlstrip/profile menu block */ /* --------------------------------------------------------------------------------- file-start: js/lib/angular/1.2.26/angular.min.js */ /* AngularJS v1.2.26 (c) 2010-2014 Google, Inc. http://angularjs.org License: MIT */ (function(W,X,t){'use strict';function C(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.26/"+(b?b+"/":"")+a;for(c=1;c").append(b).html();try{return 3===b[0].nodeType?K(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+K(b)})}catch(d){return K(c)}}function dc(b){try{return decodeURIComponent(b)}catch(a){}}function ec(b){var a={},c,d;r((b||"").split("&"),function(b){b&&(c=b.replace(/\+/g,"%20").split("="),d=dc(c[0]),y(d)&&(b=y(c[1])?dc(c[1]):!0,kb.call(a,d)?J(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Cb(b){var a= [];r(b,function(b,d){J(b)?r(b,function(b){a.push(Ca(d,!0)+(!0===b?"":"="+Ca(b,!0)))}):a.push(Ca(d,!0)+(!0===b?"":"="+Ca(b,!0)))});return a.length?a.join("&"):""}function lb(b){return Ca(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Ca(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Xc(b,a){function c(a){a&&d.push(a)}var d=[b],e,f,g=["ng:app","ng-app","x-ng-app", "data-ng-app"],k=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;r(g,function(a){g[a]=!0;c(X.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(r(b.querySelectorAll("."+a),c),r(b.querySelectorAll("."+a+"\\:"),c),r(b.querySelectorAll("["+a+"]"),c))});r(d,function(a){if(!e){var b=k.exec(" "+a.className+" ");b?(e=a,f=(b[2]||"").replace(/\s+/g,",")):r(a.attributes,function(b){!e&&g[b.name]&&(e=a,f=b.value)})}});e&&a(e,f?[f]:[])}function fc(b,a){var c=function(){b=w(b);if(b.injector()){var c=b[0]===X? "document":ia(b);throw Ta("btstrpd",c.replace(//,">"));}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=gc(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate",function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(W&&!d.test(W.name))return c();W.name=W.name.replace(d,"");Va.resumeBootstrap=function(b){r(b,function(b){a.push(b)});c()}}function mb(b,a){a= a||"_";return b.replace(Yc,function(b,d){return(d?a:"")+b.toLowerCase()})}function Db(b,a,c){if(!b)throw Ta("areq",a||"?",c||"required");return b}function Wa(b,a,c){c&&J(b)&&(b=b[b.length-1]);Db(P(b),a,"not a function, got "+(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function Da(b,a){if("hasOwnProperty"===b)throw Ta("badname",a);}function hc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g "+e[1]+a.replace(me,"<$1>")+e[2];d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a=Q?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ka(b,a){var c=typeof b,d;"function"==c||"object"==c&&null!==b?"function"==typeof(d= b.$$hashKey)?d=b.$$hashKey():d===t&&(d=b.$$hashKey=(a||hb)()):d=b;return c+":"+d}function bb(b,a){if(a){var c=0;this.nextUid=function(){return++c}}r(b,this.put,this)}function sc(b){var a,c;"function"===typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(pe,""),c=c.match(qe),r(c[1].split(re),function(b){b.replace(se,function(b,c,d){a.push(d)})})),b.$inject=a):J(b)?(c=b.length-1,Wa(b[c],"fn"),a=b.slice(0,c)):Wa(b,"fn",!0);return a}function gc(b){function a(a){return function(b,c){if(T(b))r(b, $b(a));else return a(b,c)}}function c(a,b){Da(a,"service");if(P(b)||J(b))b=n.instantiate(b);if(!b.$get)throw cb("pget",a);return l[a+k]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,f,k;r(a,function(a){if(!h.get(a)){h.put(a,!0);try{if(v(a))for(c=Ya(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,f=0,k=d.length;f 4096 bytes)!"));else{if(m.cookie!== da)for(da=m.cookie,d=da.split("; "),O={},f=0;fh&&this.remove(p.key),b},get:function(a){if(h").parent()[0])});var f=L(a,b,a,c,d,e);ca(a,"ng-scope");return function(b,c,d,e){Db(b,"scope");var g=c?La.clone.call(a):a;r(d,function(a,b){g.data("$"+b+"Controller",a)});d=0;for(var m=g.length;darguments.length&& (b=a,a=t);K&&(c=da);return p(a,b,c)}var u,M,z,O,I,B,da={},rb;u=c===f?d:ha(d,new Ob(w(f),d.$attr));M=u.$$element;if(L){var Na=/^\s*([@=&])(\??)\s*(\w*)\s*$/;B=e.$new(!0);!H||H!==L&&H!==L.$$originalDirective?M.data("$isolateScopeNoTemplate",B):M.data("$isolateScope",B);ca(M,"ng-isolate-scope");r(L.scope,function(a,c){var d=a.match(Na)||[],f=d[3]||c,g="?"==d[2],d=d[1],m,l,n,p;B.$$isolateBindings[c]=d+f;switch(d){case "@":u.$observe(f,function(a){B[c]=a});u.$$observers[f].$$scope=e;u[f]&&(B[c]=b(u[f])(e)); break;case "=":if(g&&!u[f])break;l=q(u[f]);p=l.literal?Aa:function(a,b){return a===b||a!==a&&b!==b};n=l.assign||function(){m=B[c]=l(e);throw ja("nonassign",u[f],L.name);};m=B[c]=l(e);B.$watch(function(){var a=l(e);p(a,B[c])||(p(a,m)?n(e,a=B[c]):B[c]=a);return m=a},null,l.literal);break;case "&":l=q(u[f]);B[c]=function(a){return l(e,a)};break;default:throw ja("iscp",L.name,c,a);}})}rb=p&&F;R&&r(R,function(a){var b={$scope:a===L||a.$$isolateScope?B:e,$element:M,$attrs:u,$transclude:rb},c;I=a.controller; "@"==I&&(I=u[a.name]);c=s(I,b);da[a.name]=c;K||M.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});g=0;for(z=m.length;gG.priority)break;if(V=G.scope)O=O||G,G.templateUrl||(db("new/isolated scope",L,G,Z),T(V)&&(L=G));C=G.name;!G.templateUrl&&G.controller&&(V=G.controller,R=R||{},db("'"+C+"' controller",R[C],G,Z),R[C]=G);if(V=G.transclude)x=!0,G.$$tlb|| (db("transclusion",fa,G,Z),fa=G),"element"==V?(K=!0,u=G.priority,V=Z,Z=d.$$element=w(X.createComment(" "+C+": "+d[C]+" ")),c=Z[0],Na(f,Ba.call(V,0),c),S=z(V,e,u,g&&g.name,{nonTlbTranscludeDirective:fa})):(V=w(Kb(c)).contents(),Z.empty(),S=z(V,e));if(G.template)if(D=!0,db("template",H,G,Z),H=G,V=P(G.template)?G.template(Z,d):G.template,V=W(V),G.replace){g=G;V=Ib.test(V)?w(aa(V)):[];c=V[0];if(1!=V.length||1!==c.nodeType)throw ja("tplrt",C,"");Na(f,Z,c);qa={$attr:{}};V=da(c,[],qa);var $=a.splice(Fa+ 1,a.length-(Fa+1));L&&y(V);a=a.concat(V).concat($);E(d,qa);qa=a.length}else Z.html(V);if(G.templateUrl)D=!0,db("template",H,G,Z),H=G,G.replace&&(g=G),N=ue(a.splice(Fa,a.length-Fa),Z,d,f,x&&S,m,n,{controllerDirectives:R,newIsolateScopeDirective:L,templateDirective:H,nonTlbTranscludeDirective:fa}),qa=a.length;else if(G.compile)try{Q=G.compile(Z,d,S),P(Q)?F(null,Q,U,Y):Q&&F(Q.pre,Q.post,U,Y)}catch(ve){l(ve,ia(Z))}G.terminal&&(N.terminal=!0,u=Math.max(u,G.priority))}N.scope=O&&!0===O.scope;N.transcludeOnThisElement= x;N.templateOnThisElement=D;N.transclude=S;p.hasElementTranscludeDirective=K;return N}function y(a){for(var b=0,c=a.length;bp.priority)&&-1!=p.restrict.indexOf(f)&&(q&&(p=bc(p,{$$start:q,$$end:n})),b.push(p),h=p)}catch(F){l(F)}}return h}function E(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;r(a,function(d,e){"$"!= e.charAt(0)&&(b[e]&&b[e]!==d&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});r(b,function(b,f){"class"==f?(ca(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):"style"==f?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||(a[f]=b,d[f]=c[f])})}function ue(a,b,c,d,e,f,g,h){var m=[],l,q,s=b[0],u=a.shift(),F=D({},u,{templateUrl:null,transclude:null,replace:null,$$originalDirective:u}),N=P(u.templateUrl)?u.templateUrl(b,c):u.templateUrl; b.empty();n.get(A.getTrustedResourceUrl(N),{cache:p}).success(function(n){var p,A;n=W(n);if(u.replace){n=Ib.test(n)?w(aa(n)):[];p=n[0];if(1!=n.length||1!==p.nodeType)throw ja("tplrt",u.name,N);n={$attr:{}};Na(d,b,p);var z=da(p,[],n);T(u.scope)&&y(z);a=z.concat(a);E(c,n)}else p=s,b.html(n);a.unshift(F);l=H(a,p,c,e,b,u,f,g,h);r(d,function(a,c){a==p&&(d[c]=b[0])});for(q=L(b[0].childNodes,e);m.length;){n=m.shift();A=m.shift();var R=m.shift(),I=m.shift(),z=b[0];if(A!==s){var B=A.className;h.hasElementTranscludeDirective&& u.replace||(z=Kb(p));Na(R,w(A),z);ca(w(z),B)}A=l.transcludeOnThisElement?O(n,l.transclude,I):I;l(q,n,z,d,A)}m=null}).error(function(a,b,c,d){throw ja("tpload",d.url);});return function(a,b,c,d,e){a=e;m?(m.push(b),m.push(c),m.push(d),m.push(a)):(l.transcludeOnThisElement&&(a=O(b,l.transclude,e)),l(q,b,c,d,a))}}function x(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.namea.status?d:n.reject(d)}var c={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},d=function(a){var b=e.headers,c=D({},a.headers),d,f,b=D({},b.common,b[K(a.method)]); a:for(d in b){a=K(d);for(f in c)if(K(f)===a)continue a;c[d]=b[d]}(function(a){var b;r(a,function(c,d){P(c)&&(b=c(),null!=b?a[d]=b:delete a[d])})})(c);return c}(a);D(c,a);c.headers=d;c.method=Ia(c.method);var f=[function(a){d=a.headers;var c=xc(a.data,wc(d),a.transformRequest);x(c)&&r(d,function(a,b){"content-type"===K(b)&&delete d[b]});x(a.withCredentials)&&!x(e.withCredentials)&&(a.withCredentials=e.withCredentials);return s(a,c,d).then(b,b)},t],g=n.when(c);for(r(A,function(a){(a.request||a.requestError)&& f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var m=f.shift(),g=g.then(a,m)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,c)});return g};g.error=function(a){g.then(null,function(b){a(b.data,b.status,b.headers,c)});return g};return g}function s(c,f,g){function h(a,b,c,e){I&&(200<=a&&300>a?I.put(w,[a,b,vc(c),e]):I.remove(w));p(b,a,c,e);d.$$phase||d.$apply()}function p(a,b,d,e){b=Math.max(b,0);(200<= b&&300>b?A.resolve:A.reject)({data:a,status:b,headers:wc(d),config:c,statusText:e})}function s(){var a=Ra(q.pendingRequests,c);-1!==a&&q.pendingRequests.splice(a,1)}var A=n.defer(),r=A.promise,I,H,w=F(c.url,c.params);q.pendingRequests.push(c);r.then(s,s);!c.cache&&!e.cache||(!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method)||(I=T(c.cache)?c.cache:T(e.cache)?e.cache:u);if(I)if(H=I.get(w),y(H)){if(H&&P(H.then))return H.then(s,s),H;J(H)?p(H[1],H[0],ha(H[2]),H[3]):p(H,200,{},"OK")}else I.put(w,r);x(H)&& ((H=Pb(c.url)?b.cookies()[c.xsrfCookieName||e.xsrfCookieName]:t)&&(g[c.xsrfHeaderName||e.xsrfHeaderName]=H),a(c.method,w,f,h,g,c.timeout,c.withCredentials,c.responseType));return r}function F(a,b){if(!b)return a;var c=[];Tc(b,function(a,b){null===a||x(a)||(J(a)||(a=[a]),r(a,function(a){T(a)&&(a=ta(a)?a.toISOString():na(a));c.push(Ca(b)+"="+Ca(a))}))});0=Q&&(!b.match(/^(get|post|head|put|delete|options)$/i)|| !W.XMLHttpRequest))return new W.ActiveXObject("Microsoft.XMLHTTP");if(W.XMLHttpRequest)return new W.XMLHttpRequest;throw C("$httpBackend")("noxhr");}function Vd(){this.$get=["$browser","$window","$document",function(b,a,c){return ye(b,xe,b.defer,a.angular.callbacks,c[0])}]}function ye(b,a,c,d,e){function f(a,b,c){var f=e.createElement("script"),g=null;f.type="text/javascript";f.src=a;f.async=!0;g=function(a){$a(f,"load",g);$a(f,"error",g);e.body.removeChild(f);f=null;var k=-1,s="unknown";a&&("load"!== a.type||d[b].called||(a={type:"error"}),s=a.type,k="error"===a.type?404:200);c&&c(k,s)};sb(f,"load",g);sb(f,"error",g);8>=Q&&(f.onreadystatechange=function(){v(f.readyState)&&/loaded|complete/.test(f.readyState)&&(f.onreadystatechange=null,g({type:"load"}))});e.body.appendChild(f);return g}var g=-1;return function(e,m,h,l,n,p,q,s){function F(){A=g;R&&R();z&&z.abort()}function u(a,d,e,f,g){L&&c.cancel(L);R=z=null;0===d&&(d=e?200:"file"==ua(m).protocol?404:0);a(1223===d?204:d,e,f,g||"");b.$$completeOutstandingRequest(E)} var A;b.$$incOutstandingRequestCount();m=m||b.url();if("jsonp"==K(e)){var N="_"+(d.counter++).toString(36);d[N]=function(a){d[N].data=a;d[N].called=!0};var R=f(m.replace("JSON_CALLBACK","angular.callbacks."+N),N,function(a,b){u(l,a,d[N].data,"",b);d[N]=E})}else{var z=a(e);z.open(e,m,!0);r(n,function(a,b){y(a)&&z.setRequestHeader(b,a)});z.onreadystatechange=function(){if(z&&4==z.readyState){var a=null,b=null,c="";A!==g&&(a=z.getAllResponseHeaders(),b="response"in z?z.response:z.responseText);A===g&& 10>Q||(c=z.statusText);u(l,A||z.status,b,a,c)}};q&&(z.withCredentials=!0);if(s)try{z.responseType=s}catch(ca){if("json"!==s)throw ca;}z.send(h||null)}if(0=k&&(n.resolve(q),l(p.$$intervalId),delete e[p.$$intervalId]);s||b.$apply()},g);e[p.$$intervalId]=n;return p}var e={};d.cancel= function(b){return b&&b.$$intervalId in e?(e[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),delete e[b.$$intervalId],!0):!1};return d}]}function bd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "), SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function Qb(b){b=b.split("/");for(var a=b.length;a--;)b[a]= lb(b[a]);return b.join("/")}function zc(b,a,c){b=ua(b,c);a.$$protocol=b.protocol;a.$$host=b.hostname;a.$$port=U(b.port)||ze[b.protocol]||null}function Ac(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=ua(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=ec(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function ra(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function eb(b){var a= b.indexOf("#");return-1==a?b:b.substr(0,a)}function Rb(b){return b.substr(0,eb(b).lastIndexOf("/")+1)}function Bc(b,a){this.$$html5=!0;a=a||"";var c=Rb(b);zc(b,this,b);this.$$parse=function(a){var e=ra(c,a);if(!v(e))throw Sb("ipthprfx",a,c);Ac(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Cb(this.$$search),b=this.$$hash?"#"+lb(this.$$hash):"";this.$$url=Qb(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e; if((e=ra(b,d))!==t)return d=e,(e=ra(a,e))!==t?c+(ra("/",e)||e):b+d;if((e=ra(c,d))!==t)return c+e;if(c==d+"/")return c}}function Tb(b,a){var c=Rb(b);zc(b,this,b);this.$$parse=function(d){var e=ra(b,d)||ra(c,d),e="#"==e.charAt(0)?ra(a,e):this.$$html5?e:"";if(!v(e))throw Sb("ihshprfx",d,a);Ac(e,this,b);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Cb(this.$$search),e=this.$$hash? "#"+lb(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(eb(b)==eb(a))return a}}function Ub(b,a){this.$$html5=!0;Tb.apply(this,arguments);var c=Rb(b);this.$$rewrite=function(d){var e;if(b==eb(d))return d;if(e=ra(c,d))return b+a+e;if(c===d+"/")return c};this.$$compose=function(){var c=Cb(this.$$search),e=this.$$hash?"#"+lb(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+a+this.$$url}}function tb(b){return function(){return this[b]}} function Cc(b,a){return function(c){if(x(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Wd(){var b="",a=!1;this.hashPrefix=function(a){return y(a)?(b=a,this):b};this.html5Mode=function(b){return y(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function g(a){c.$broadcast("$locationChangeSuccess",k.absUrl(),a)}var k,m,h=d.baseHref(),l=d.url(),n;a?(n=l.substring(0,l.indexOf("/",l.indexOf("//")+2))+(h||"/"),m=e.history?Bc:Ub):(n= eb(l),m=Tb);k=new m(n,"#"+b);k.$$parse(k.$$rewrite(l));var p=/^\s*(javascript|mailto):/i;f.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var e=w(a.target);"a"!==K(e[0].nodeName);)if(e[0]===f[0]||!(e=e.parent())[0])return;var g=e.prop("href");T(g)&&"[object SVGAnimatedString]"===g.toString()&&(g=ua(g.animVal).href);if(!p.test(g)){if(m===Ub){var h=e.attr("href")||e.attr("xlink:href");if(h&&0>h.indexOf("://"))if(g="#"+b,"/"==h[0])g=n+g+h;else if("#"==h[0])g=n+g+(k.path()||"/")+h; else{var l=k.path().split("/"),h=h.split("/");2!==l.length||l[1]||(l.length=1);for(var q=0;qe?Dc(d[0],d[1],d[2],d[3],d[4],c,a):function(b,f){var g=0,k;do k=Dc(d[g++],d[g++],d[g++],d[g++],d[g++],c,a)(b,f),f=t,b=k;while(ga)for(b in h++,e)e.hasOwnProperty(b)&&!d.hasOwnProperty(b)&&(r--,delete e[b])}else e!==d&&(e=d,h++);return h},function(){n?(n=!1,b(d,d,c)):b(d,g,c);if(k)if(T(d))if(Pa(d)){g=Array(d.length);for(var a=0;at&&(w=4-t,O[w]||(O[w]=[]),B=P(d.exp)?"fn: "+(d.exp.name||d.exp.toString()): d.exp,B+="; newVal: "+na(f)+"; oldVal: "+na(k),O[w].push(B));else if(d===c){z=!1;break a}}catch(y){p.$$phase=null,e(y)}if(!(h=L.$$childHead||L!==this&&L.$$nextSibling))for(;L!==this&&!(h=L.$$nextSibling);)L=L.$parent}while(L=h);if((z||l.length)&&!t--)throw p.$$phase=null,a("infdig",b,na(O));}while(z||l.length);for(p.$$phase=null;r.length;)try{r.shift()()}catch(v){e(v)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this!==p&&(r(this.$$listenerCount, Bb(null,l,this)),a.$$childHead==this&&(a.$$childHead=this.$$nextSibling),a.$$childTail==this&&(a.$$childTail=this.$$prevSibling),this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling),this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling),this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null,this.$$listeners={},this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[],this.$destroy=this.$digest=this.$apply=E,this.$on= this.$watch=function(){return E})}},$eval:function(a,b){return f(a)(this,b)},$evalAsync:function(a){p.$$phase||p.$$asyncQueue.length||g.defer(function(){p.$$asyncQueue.length&&p.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return m("$apply"),this.$eval(a)}catch(b){e(b)}finally{p.$$phase=null;try{p.$digest()}catch(c){throw e(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]= c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){c[Ra(c,b)]=null;l(e,1,a)}},$emit:function(a,b){var c=[],d,f=this,g=!1,k={name:a,targetScope:f,stopPropagation:function(){g=!0},preventDefault:function(){k.defaultPrevented=!0},defaultPrevented:!1},h=[k].concat(Ba.call(arguments,1)),l,m;do{d=f.$$listeners[a]||c;k.currentScope=f;l=0;for(m=d.length;lc.msieDocumentMode)throw xa("iequirks");var e=ha(ga);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b}, e.valueOf=Qa);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b,d(a,c))}};var f=e.parseAs,g=e.getTrusted,k=e.trustAs;r(ga,function(a,b){var c=K(b);e[Za("parse_as_"+c)]=function(b){return f(a,b)};e[Za("get_trusted_"+c)]=function(b){return g(a,b)};e[Za("trust_as_"+c)]=function(b){return k(a,b)}});return e}]}function ce(){this.$get=["$window","$document",function(b,a){var c={},d=U((/android (\d+)/.exec(K((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator|| {}).userAgent),f=a[0]||{},g=f.documentMode,k,m=/^(Moz|webkit|O|ms)(?=[A-Z])/,h=f.body&&f.body.style,l=!1,n=!1;if(h){for(var p in h)if(l=m.exec(p)){k=l[0];k=k.substr(0,1).toUpperCase()+k.substr(1);break}k||(k="WebkitOpacity"in h&&"webkit");l=!!("transition"in h||k+"Transition"in h);n=!!("animation"in h||k+"Animation"in h);!d||l&&n||(l=v(f.body.style.webkitTransition),n=v(f.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!g||7< g),hasEvent:function(a){if("input"==a&&9==Q)return!1;if(x(c[a])){var b=f.createElement("div");c[a]="on"+a in b}return c[a]},csp:Xa(),vendorPrefix:k,transitions:l,animations:n,android:d,msie:Q,msieDocumentMode:g}}]}function ee(){this.$get=["$rootScope","$browser","$q","$exceptionHandler",function(b,a,c,d){function e(e,k,m){var h=c.defer(),l=h.promise,n=y(m)&&!m;k=a.defer(function(){try{h.resolve(e())}catch(a){h.reject(a),d(a)}finally{delete f[l.$$timeoutId]}n||b.$apply()},k);l.$$timeoutId=k;f[k]=h; return l}var f={};e.cancel=function(b){return b&&b.$$timeoutId in f?(f[b.$$timeoutId].reject("canceled"),delete f[b.$$timeoutId],a.defer.cancel(b.$$timeoutId)):!1};return e}]}function ua(b,a){var c=b;Q&&(Y.setAttribute("href",c),c=Y.href);Y.setAttribute("href",c);return{href:Y.href,protocol:Y.protocol?Y.protocol.replace(/:$/,""):"",host:Y.host,search:Y.search?Y.search.replace(/^\?/,""):"",hash:Y.hash?Y.hash.replace(/^#/,""):"",hostname:Y.hostname,port:Y.port,pathname:"/"===Y.pathname.charAt(0)?Y.pathname: "/"+Y.pathname}}function Pb(b){b=v(b)?ua(b):b;return b.protocol===Hc.protocol&&b.host===Hc.host}function fe(){this.$get=ba(W)}function mc(b){function a(d,e){if(T(d)){var f={};r(d,function(b,c){f[c]=a(c,b)});return f}return b.factory(d+c,e)}var c="Filter";this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+c)}}];a("currency",Ic);a("date",Jc);a("filter",Ce);a("json",De);a("limitTo",Ee);a("lowercase",Fe);a("number",Kc);a("orderBy",Lc);a("uppercase",Ge)}function Ce(){return function(b, a,c){if(!J(b))return b;var d=typeof c,e=[];e.check=function(a){for(var b=0;bb;b=Math.abs(b);var g=b+"",k="",m=[],h=!1;if(-1!==g.indexOf("e")){var l=g.match(/([\d\.]+)e(-?)(\d+)/);l&&"-"==l[2]&& l[3]>e+1?(g="0",b=0):(k=g,h=!0)}if(h)0b)&&(k=b.toFixed(e));else{g=(g.split(Nc)[1]||"").length;x(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac));b=+(Math.round(+(b.toString()+"e"+e)).toString()+"e"+-e);0===b&&(f=!1);b=(""+b).split(Nc);g=b[0];b=b[1]||"";var l=0,n=a.lgSize,p=a.gSize;if(g.length>=n+p)for(l=g.length-n,h=0;hb&&(d="-",b=-b);for(b=""+b;b.length-c)e+=c;0===e&&-12==c&&(e=12);return Xb(e,a,d)}}function vb(b,a){return function(c,d){var e=c["get"+b](),f=Ia(a?"SHORT"+b:b);return d[f][e]}}function Jc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,k=b[8]? a.setUTCFullYear:a.setFullYear,m=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=U(b[9]+b[10]),g=U(b[9]+b[11]));k.call(a,U(b[1]),U(b[2])-1,U(b[3]));f=U(b[4]||0)-f;g=U(b[5]||0)-g;k=U(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));m.call(a,f,g,k,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var f="",g=[],k,m;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;v(c)&&(c=He.test(c)?U(c):a(c));ib(c)&&(c=new Date(c)); if(!ta(c))return c;for(;e;)(m=Ie.exec(e))?(g=g.concat(Ba.call(m,1)),e=g.pop()):(g.push(e),e=null);r(g,function(a){k=Je[a];f+=k?k(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return f}}function De(){return function(b){return na(b,!0)}}function Ee(){return function(b,a){if(!J(b)&&!v(b))return b;a=Infinity===Math.abs(Number(a))?Number(a):U(a);if(v(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0a||37<=a&&40>=a)||q()});if(e.hasEvent("paste"))a.on("paste cut",q)}a.on("change",n);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)};var s=c.ngPattern;s&&((e=s.match(/^\/(.*)\/([gim]*)$/))?(s=RegExp(e[1],e[2]),e=function(a){return sa(d, "pattern",d.$isEmpty(a)||s.test(a),a)}):e=function(c){var e=b.$eval(s);if(!e||!e.test)throw C("ngPattern")("noregexp",s,e,ia(a));return sa(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var r=U(c.ngMinlength);e=function(a){return sa(d,"minlength",d.$isEmpty(a)||a.length>=r,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var u=U(c.ngMaxlength);e=function(a){return sa(d,"maxlength",d.$isEmpty(a)||a.length<=u,a)};d.$parsers.push(e); d.$formatters.push(e)}}function Yb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;dQ?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Ia(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Xa=function(){if(y(Xa.isActive_))return Xa.isActive_;var b=!(!X.querySelector("[ng-csp]")&&!X.querySelector("[data-ng-csp]")); if(!b)try{new Function("")}catch(a){b=!0}return Xa.isActive_=b},Yc=/[A-Z]/g,ad={full:"1.2.26",major:1,minor:2,dot:26,codeName:"captivating-disinterest"};S.expando="ng339";var ab=S.cache={},ne=1,sb=W.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},$a=W.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};S._data=function(b){return this.cache[b[this.expando]]||{}};var ie=/([\:\-\_]+(.))/g, je=/^moz([A-Z])/,Hb=C("jqLite"),ke=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Ib=/<|&#?\w+;/,le=/<([\w:]+)/,me=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ea={option:[1,'"],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ea.optgroup=ea.option;ea.tbody=ea.tfoot=ea.colgroup=ea.caption=ea.thead;ea.th= ea.td;var La=S.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===X.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),S(W).on("load",a))},toString:function(){var b=[];r(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?w(this[b]):w(this[this.length+b])},length:0,push:Me,sort:[].sort,splice:[].splice},qb={};r("multiple selected checked disabled readOnly required open".split(" "),function(b){qb[K(b)]=b});var rc={};r("input select option textarea button form details".split(" "), function(b){rc[Ia(b)]=!0});r({data:Mb,removeData:Lb},function(b,a){S[a]=b});r({data:Mb,inheritedData:pb,scope:function(b){return w.data(b,"$scope")||pb(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return w.data(b,"$isolateScope")||w.data(b,"$isolateScopeNoTemplate")},controller:oc,injector:function(b){return pb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Nb,css:function(b,a,c){a=Za(a);if(y(c))b.style[a]=c;else{var d;8>=Q&&(d=b.currentStyle&&b.currentStyle[a], ""===d&&(d="auto"));d=d||b.style[a];8>=Q&&(d=""===d?t:d);return d}},attr:function(b,a,c){var d=K(a);if(qb[d])if(y(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||E).specified?d:t;else if(y(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?t:b},prop:function(b,a,c){if(y(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(x(d))return e?b[e]:"";b[e]=d}var a=[];9>Q?(a[1]= "innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(x(a)){if("SELECT"===Ma(b)&&b.multiple){var c=[];r(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(x(a))return b.innerHTML;for(var c=0,d=b.childNodes;c":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Re={n:"\n",f:"\f",r:"\r", t:"\t",v:"\v","'":"'",'"':'"'},Wb=function(a){this.options=a};Wb.prototype={constructor:Wb,lex:function(a){this.text=a;this.index=0;this.ch=t;this.lastCh=":";for(this.tokens=[];this.index=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=y(c)?"s "+c+"-"+this.index+" ["+ this.text.substring(c,d)+"]":" "+d;throw la("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(fb.ZERO,a.fn, this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Ec(d,this.options,this.text);return D(function(c,d,k){return e(k||a(c,d))},{assign:function(e,g,k){(k=a(e,k))||a.assign(e,k={});return ub(k,d,g,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return D(function(e,f){var g=a(e,f),k=d(e,f),m;ka(k,c.text);if(!g)return t;(g=va(g[k],c.text))&&(g.then&&c.options.unwrapPromises)&& (m=g,"$$v"in g||(m.$$v=t,m.then(function(a){m.$$v=a})),g=g.$$v);return g},{assign:function(e,f,g){var k=ka(d(e,g),c.text);(g=va(a(e,g),c.text))||a.assign(e,g={});return g[k]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(f,g){for(var k=[],m=c?c(f,g):f,h=0;ha.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Xb(Math[0< a?"floor":"ceil"](a/60),2)+Xb(Math.abs(a%60),2))}},Ie=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,He=/^\-?\d+$/;Jc.$inject=["$locale"];var Fe=ba(K),Ge=ba(Ia);Lc.$inject=["$parse"];var dd=ba({restrict:"E",compile:function(a,c){8>=Q&&(c.href||c.name||c.$set("href",""),a.append(X.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var f="[object SVGAnimatedString]"===za.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(f)|| a.preventDefault()})}}}),Fb={};r(qb,function(a,c){if("multiple"!=a){var d=pa("ng-"+c);Fb[d]=function(){return{priority:100,link:function(a,f,g){a.$watch(g[d],function(a){g.$set(c,!!a)})}}}}});r(["src","srcset","href"],function(a){var c=pa("ng-"+a);Fb[c]=function(){return{priority:99,link:function(d,e,f){var g=a,k=a;"href"===a&&"[object SVGAnimatedString]"===za.call(e.prop("href"))&&(k="xlinkHref",f.$attr[k]="xlink:href",g=null);f.$observe(c,function(c){c?(f.$set(k,c),Q&&g&&e.prop(g,f[k])):"href"=== a&&f.$set(k,null)})}}}});var yb={$addControl:E,$removeControl:E,$setValidity:E,$setDirty:E,$setPristine:E};Oc.$inject=["$element","$attrs","$scope","$animate"];var Rc=function(a){return["$timeout",function(c){return{name:"form",restrict:a?"EAC":"E",controller:Oc,compile:function(){return{pre:function(a,e,f,g){if(!f.action){var k=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};sb(e[0],"submit",k);e.on("$destroy",function(){c(function(){$a(e[0],"submit",k)},0,!1)})}var m=e.parent().controller("form"), h=f.name||f.ngForm;h&&ub(a,h,g,h);if(m)e.on("$destroy",function(){m.$removeControl(g);h&&ub(a,h,t,h);D(g,yb)})}}}}}]},ed=Rc(),rd=Rc(!0),Se=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,Te=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,Ue=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Sc={text:Ab,number:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Ue.test(a))return e.$setValidity("number", !0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return t});Ke(e,"number",Ve,null,e.$$validityState);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return sa(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a),e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return sa(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return sa(e,"number",e.$isEmpty(a)|| ib(a),a)})},url:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);a=function(a){return sa(e,"url",e.$isEmpty(a)||Se.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);a=function(a){return sa(e,"email",e.$isEmpty(a)||Te.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){x(d.name)&&c.attr("name",hb());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue}; d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var f=d.ngTrueValue,g=d.ngFalseValue;v(f)||(f=!0);v(g)||(g=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==f};e.$formatters.push(function(a){return a===f});e.$parsers.push(function(a){return a?f:g})},hidden:E,button:E,submit:E,reset:E,file:E},Ve=["badInput"],jc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel", link:function(d,e,f,g){g&&(Sc[K(f.type)]||Sc.text)(d,e,f,g,c,a)}}}],wb="ng-valid",xb="ng-invalid",Oa="ng-pristine",zb="ng-dirty",We=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,f,g){function k(a,c){c=c?"-"+mb(c,"-"):"";g.removeClass(e,(a?xb:wb)+c);g.addClass(e,(a?wb:xb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name= d.name;var m=f(d.ngModel),h=m.assign;if(!h)throw C("ngModel")("nonassign",d.ngModel,ia(e));this.$render=E;this.$isEmpty=function(a){return x(a)||""===a||null===a||a!==a};var l=e.inheritedData("$formController")||yb,n=0,p=this.$error={};e.addClass(Oa);k(!0);this.$setValidity=function(a,c){p[a]!==!c&&(c?(p[a]&&n--,n||(k(!0),this.$valid=!0,this.$invalid=!1)):(k(!1),this.$invalid=!0,this.$valid=!1,n++),p[a]=!c,k(c,a),l.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine= !0;g.removeClass(e,zb);g.addClass(e,Oa)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,g.removeClass(e,Oa),g.addClass(e,zb),l.$setDirty());r(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,h(a,d),r(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}}))};var q=this;a.$watch(function(){var c=m(a);if(q.$modelValue!==c){var d=q.$formatters,e=d.length;for(q.$modelValue=c;e--;)c=d[e](c);q.$viewValue!==c&&(q.$viewValue= c,q.$render())}return c})}],Gd=function(){return{require:["ngModel","^?form"],controller:We,link:function(a,c,d,e){var f=e[0],g=e[1]||yb;g.$addControl(f);a.$on("$destroy",function(){g.$removeControl(f)})}}},Id=ba({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),kc=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var f=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required", !0),a};e.$formatters.push(f);e.$parsers.unshift(f);d.$observe("required",function(){f(e.$viewValue)})}}}},Hd=function(){return{require:"ngModel",link:function(a,c,d,e){var f=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!x(a)){var c=[];a&&r(a.split(f),function(a){a&&c.push(aa(a))});return c}});e.$formatters.push(function(a){return J(a)?a.join(", "):t});e.$isEmpty=function(a){return!a||!a.length}}}},Xe=/^(true|false|\d+)$/,Jd=function(){return{priority:100, compile:function(a,c){return Xe.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},jd=ya({compile:function(a){a.addClass("ng-binding");return function(a,d,e){d.data("$binding",e.ngBind);a.$watch(e.ngBind,function(a){d.text(a==t?"":a)})}}}),ld=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}], kd=["$sce","$parse",function(a,c){return{compile:function(d){d.addClass("ng-binding");return function(d,f,g){f.data("$binding",g.ngBindHtml);var k=c(g.ngBindHtml);d.$watch(function(){return(k(d)||"").toString()},function(c){f.html(a.getTrustedHtml(k(d))||"")})}}}}],md=Yb("",!0),od=Yb("Odd",0),nd=Yb("Even",1),pd=ya({compile:function(a,c){c.$set("ngCloak",t);a.removeClass("ng-cloak")}}),qd=[function(){return{scope:!0,controller:"@",priority:500}}],lc={},Ye={blur:!0,focus:!0};r("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "), function(a){var c=pa("ng-"+a);lc[c]=["$parse","$rootScope",function(d,e){return{compile:function(f,g){var k=d(g[c]);return function(c,d){d.on(a,function(d){var f=function(){k(c,{$event:d})};Ye[a]&&e.$$phase?c.$evalAsync(f):c.$apply(f)})}}}}]});var td=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var k,m,h;c.$watch(e.ngIf,function(f){Ua(f)?m||(m=c.$new(),g(m,function(c){c[c.length++]=X.createComment(" end ngIf: "+e.ngIf+ " ");k={clone:c};a.enter(c,d.parent(),d)})):(h&&(h.remove(),h=null),m&&(m.$destroy(),m=null),k&&(h=Eb(k.clone),a.leave(h,function(){h=null}),k=null))})}}}],ud=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,f){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Va.noop,compile:function(g,k){var m=k.ngInclude||k.src,h=k.onload||"",l=k.autoscroll;return function(g,k,q,r,F){var u=0,t,w,R,z=function(){w&&(w.remove(),w=null);t&&(t.$destroy(),t=null); R&&(e.leave(R,function(){w=null}),w=R,R=null)};g.$watch(f.parseAsResourceUrl(m),function(f){var m=function(){!y(l)||l&&!g.$eval(l)||d()},q=++u;f?(a.get(f,{cache:c}).success(function(a){if(q===u){var c=g.$new();r.template=a;a=F(c,function(a){z();e.enter(a,null,k,m)});t=c;R=a;t.$emit("$includeContentLoaded");g.$eval(h)}}).error(function(){q===u&&z()}),g.$emit("$includeContentRequested")):(z(),r.template=null)})}}}}],Kd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude", link:function(c,d,e,f){d.html(f.template);a(d.contents())(c)}}}],vd=ya({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),wd=ya({terminal:!0,priority:1E3}),xd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,f,g){var k=g.count,m=g.$attr.when&&f.attr(g.$attr.when),h=g.offset||0,l=e.$eval(m)||{},n={},p=c.startSymbol(),q=c.endSymbol(),s=/^when(Minus)?(.+)$/;r(g,function(a,c){s.test(c)&&(l[K(c.replace("when","").replace("Minus","-"))]= f.attr(g.$attr[c]))});r(l,function(a,e){n[e]=c(a.replace(d,p+k+"-"+h+q))});e.$watch(function(){var c=parseFloat(e.$eval(k));if(isNaN(c))return"";c in l||(c=a.pluralCat(c-h));return n[c](e,f,!0)},function(a){f.text(a)})}}}],yd=["$parse","$animate",function(a,c){var d=C("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,link:function(e,f,g,k,m){var h=g.ngRepeat,l=h.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),n,p,q,s,t,u,A={$id:Ka};if(!l)throw d("iexp", h);g=l[1];k=l[2];(l=l[3])?(n=a(l),p=function(a,c,d){u&&(A[u]=a);A[t]=c;A.$index=d;return n(e,A)}):(q=function(a,c){return Ka(c)},s=function(a){return a});l=g.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!l)throw d("iidexp",g);t=l[3]||l[1];u=l[2];var y={};e.$watchCollection(k,function(a){var g,k,l=f[0],n,A={},B,I,H,v,E,C,x,J=[];if(Pa(a))C=a,E=p||q;else{E=p||s;C=[];for(H in a)a.hasOwnProperty(H)&&"$"!=H.charAt(0)&&C.push(H);C.sort()}B=C.length;k=J.length=C.length;for(g=0;gB;)d=t.pop(),p.removeOption(d.label),d.element.remove()}for(;z.length>M;)z.pop()[0].element.remove()}var h;if(!(h=s.match(d)))throw Ze("iexp",s,ia(f));var l=c(h[2]||h[1]),m=h[4]||h[6],n=h[5],r=c(h[3]||""),u=c(h[2]? h[1]:m),w=c(h[7]),x=h[8]?c(h[8]):null,z=[[{element:f,label:""}]];F&&(a(F)(e),F.removeClass("ng-scope"),F.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=w(e)||[],d={},h,l,p,r,s,v,y;if(q)for(l=[],r=0,v=z.length;r@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}.ng-hide-add-active,.ng-hide-remove{display:block!important;}'); //# sourceMappingURL=angular.min.js.map ; /* file-end: js/lib/angular/1.2.26/angular.min.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/core/angular/common.js */ /* * Include LJ.Templates as module dependency to have access to templates, * required using require_template. Don't forget to require this file. * * @example * js: * angular.module('MyModule', ['LJ.Templates']); * * html: *
* * If you need direct access to template as a string, use $templateCache. * * Notice: * By default required templates will be named in $templateCache as filename, * e.g. `angular/widgets/social/twitter.ng.tmpl` will have name `twitter.ng.tmpl` * * If two files have same name, but located in different folders, e.g. * `angular/widgets/social/v1/twitter.ng.tmpl` and `angular/widgets/social/v2/twitter.ng.tmpl` * files will be named as a file and folder they are located in => * `v1/twitter.ng.tmpl` and `v2/twitter.ng.tmpl` * */ angular.module('LJ.Templates', []).run(['$templateCache', function($templateCache) { var templates = angular.copy( LJ.get('template') ); var temp = []; function getDups(array, regexp) { return array.filter(function (item) { return item.match(regexp) && item; }); } function getContains(string1, string2) { var index = 0; for (var i = 0; i < string1.length; i++) { if ( string2.indexOf( string1.substr(0, i + 1) ) !== -1 ) { index = i + 1; } } return string1.slice(0, index); } angular.forEach(templates, function (value, key) { temp.push(key.split('').reverse().join('')); }); // Convert templates to uniq names temp.forEach(function (value) { var match = value.match(/([\w\.]*)/), name, regexp, dups, max, pathPattern; if ( !(match && match[1]) ) { return; } regexp = new RegExp( match[1].replace('.', '\\.') ); dups = getDups(temp, regexp); max = value.length - 1; dups.forEach(function (dup) { var contains = getContains(value, dup); var length = contains.length; max = max > length ? length : max; }); if (dups.length === 1) { name = value.split('').reverse().join(''); templates[name.split('/').pop()] = templates[name]; delete templates[name]; return; } dups.push(value); pathPattern = new RegExp('\\/?(\\w*.{' + max + '})$'); dups.forEach(function (item) { var exec; item = item.split('').reverse().join(''); exec = pathPattern.exec(item); if (templates.hasOwnProperty(item) && (exec && exec[1]) ) { templates[exec[1]] = templates[item]; if (exec[1] !== item) { delete templates[item]; } } }); }); angular.forEach(templates, function (value, key) { if ( key.indexOf('/') !== -1 ) { console.warn('Template `%s` has been registered with path', key); } $templateCache.put(key, value); }); }]); /* * Common directives */ angular.module('LJ.Directives', []) /** * Insert html and do not watch for changes */ .directive('ljHtml', ['$parse', function ($parse) { return { compile: function (element, attrs) { var getter = $parse( attrs.ljHtml ); return function link(scope, element) { element.html( getter(scope) || '' ); }; } }; }]) /** * Insert html and watch for changes */ .directive('ljHtmlLive', ['$parse', function ($parse) { return { scope: true, restrict: 'A', compile: function (element, attrs) { var getValue = $parse(attrs.ljHtmlLive); return function link(scope, element) { scope.$watch(function () { return getValue(scope); }, function (value) { element.html( value || '' ); }); }; } }; }]) /** * Replace ng-include root with it's content, * if you have to just include template into the DOM. * Notice: should be used in conjunction with ng-include * * @example * *
*/ .directive('includeReplace', function () { return { require: 'ngInclude', link: function (scope, element) { element.replaceWith( element.contents() ); } }; }) /** * Notice: * lj-ml-compile could be only used on node without any other directives, * otherwise their behavior will be duplicated (ng-click handlers for example) * * @example * * * * @example * * * * @example * * * * @example * * * * @example * * Html: * * Simple: * * * Deferred: * * * * var mlDefer = $q.defer(); * * // Notice: * // Object with `promise` field is needed! * // If promise is assigned directly, it will be resolved to `undefined` * $scope.mlResolve = { promise: mlDefer.promise } * mlDefer.resolve({ username: 'good' }) */ .directive('ljMl', ['$parse', '$compile', function($parse, $compile) { return { link: function(scope, element, attrs) { if ( attrs.hasOwnProperty('ljMlDynamic') ) { attrs.$observe('ljMl', function () { processMl(attrs.ljMl); }); } processMl(attrs.ljMl); function processMl(mlVar) { var resolve; // ml has been processed yet if ( attrs.mlParsed ) { return; } // we don't need substitutions if ( !attrs.ljMlResolve ) { replaceMl(mlVar); return; } resolve = $parse(attrs.ljMlResolve)(scope); if ( !resolve.promise ) { replaceMl(mlVar, resolve); return; } // if object has promise key => wait for promise resolve resolve.promise.then(function (data) { replaceMl(mlVar, data); }); } // replace variable with value function replaceMl(mlVar, dictionary) { var ml = LJ.ml(objNotation( mlVar ), dictionary); // attribute if (attrs.ljMlAttr) { element.attr( attrs.ljMlAttr, ml); } else { // html element.html(ml); } if ( attrs.hasOwnProperty('ljMlCompile') ) { // prevent cycled compilation of lj-ml directive element.attr('ml-parsed', true); $compile(element)(scope); } } /** * Allow object notation for ml * @param {String} mlVar Variable value to check * @return {String} Result ml variable value */ function objNotation(mlVar) { if ( mlVar.indexOf('{') === -1 ) { return mlVar; } var obj = scope.$eval(mlVar), prop; if ( obj && typeof obj === 'object' ) { for (prop in obj) { if ( obj.hasOwnProperty(prop) && obj[prop] ) { return prop; } } } return mlVar; } } }; }]) .directive('ljSwitchOff', ['$document', '$parse', function ( $document , $parse ) { /* * When area outside of element is clicked or ESC is pressed * 'showPopup' will be set to false and 'doSomething()' will be evaluated. * *
* * Skip switching: * Notice: now skipping of switch is working for all `lj-switch-off` directives (is not grouped) * This element prevents switching via `lj-switch-off` directive * */ return { restrict: 'A', link: function (scope, element, attrs) { var state = $parse(attrs.ljSwitchOff), _clicked = false; element.on('click', function () { _clicked = true; }); $document .on('keydown', keyPressed) .on('click', '[lj-switch-off-skip]', preventSwitching) .on('click', documentClick); // cleanup scope.$on('$destroy', function () { $document .off('keydown', keyPressed) .off('click', '[lj-switch-off-skip]', preventSwitching) .off('click', documentClick); }); function close() { if (attrs.ljSwitchOffAction) { scope.$eval(attrs.ljSwitchOffAction); } state.assign(scope, false); } function preventSwitching() { _clicked = true; } function documentClick(event) { // right click in Firefox is closing the bubble if (event.button === 2) { return; } if ( !_clicked && state(scope, { $event: event }) ) { scope.$apply(close); } _clicked = false; } function keyPressed(event) { /** ESC */ if ( event.which === 27 && state(scope, { $event: event }) ) { scope.$apply(close); } } } }; }]). directive('ljDisabled', [function() { /* * Toggles disabled state for LiveJournal button * *
* *
*/ return function (scope, element, attrs) { scope.$watch(attrs.ljDisabled, function(value) { element.prop('disabled', value); element.parent().toggleClass('b-ljbutton-disabled', value); }); }; }]) .directive('focusAndSelect', ['$timeout', function ($timeout) { /* * Focus and select an input or textarea when expression is true * * */ return { restrict: 'A', link: function (scope, element, attrs) { var attr = attrs.focusAndSelect, timeout = 50; // scroll can jump under 50ms scope.$watch(attr, function (value, prev) { if (value) { $timeout(function () { element[0].focus(); element[0].select(); }, timeout); } else if (prev) { // fix: blur for IE element[0].blur(); } }); } }; }]) /** * Debounced update of scope variable on changes * [lj-debounce-delay]: option for set delay duration (in milliseconds). Default: 300 * * @example * * * * * js: * angular.module('MyModule', ['LJ.Bubble']) * .controller('MyCtrl', ['$scope', 'Bubble', function($scope, Bubble) { * * // Use Bubble.open to control bubble from JS. * // You can pass jQuery node to reposition the bubble from the original placement. * Bubble.open('myBubble', { 'some-stuff': 'optional' }, jQuery('.b-some-other-block')); * }]); * * @todo * Refactor detection of current bubble open * Refactor disableClick option of directive * * @authors * Artem Tyurin (artem.tyurin@sup.com) * Valeriy Vasin (valeriy.vasin@sup.com) */ (function($) { 'use strict'; angular.module('LJ.Bubble', ['LJ.Templates', 'LJ.Directives', 'LJ.Ref']) .factory('Bubble', ['$rootScope', '$compile', 'Ref', function ($rootScope, $compile, Ref) { var factory = {}, // bubbles options _options = {}, // body className flag bubbleOpenClass = 'p-openpopup'; // currently opened bubble name factory.current = null; // we can change bubble node while opening bubble factory.node = null; /** * Register bubble from service * @example * Bubble.register({ name: 'share', template: 'share.ng.tmpl' }); */ factory.register = (function () { // cache for registerd from service bubbles var cache = {}; function register(opts, scope) { if ( !opts || !opts.name || !opts.template ) { throw new Error('Incorrect bubble options. You should provide name and template.', opts); } var name = opts.name; // click is always disabled when register from factory opts.disableClick = true; // bubble has been registered before - increase counter if ( cache[name] ) { cache[name].count += 1; return unregister.bind(null, name); } // create lj-bubble node with params var bubbleNode = $('
').attr('lj-bubble', JSON.stringify(opts)); // create new isolated scope for the bubble if we not provided it var isScopeCreated = typeof scope === 'undefined'; if ( isScopeCreated ) { scope = $rootScope.$new(true); } bubbleNode.appendTo('body'); $compile(bubbleNode)(scope); cache[name] = { count: 1, node: bubbleNode, scope: scope, isScopeCreated: isScopeCreated }; // unregistration function return unregister.bind(null, name); } function unregister(name) { var opts = cache[name]; if ( !opts ) { // nothing to unregister return; } opts.count -= 1; // perform remove if ( opts.count === 0 ) { // do not destroy scope we have not created if ( !opts.isScopeCreated ) { opts.scope.$destroy(); } opts.node.remove(); delete cache[name]; } } return register; }()); /** * Register bubble * @param {String} name Bubble name */ factory._register = function (name, options) { if ( _options.hasOwnProperty(name) ) { console.warn('Warning: bubble with name `%s` has been registered before!', name); return false; } var opts = angular.isDefined(options) ? angular.copy(options) : {}; // extend with default options opts = angular.extend({ closeControl: true }, opts); _options[name] = opts; }; factory._unregister = function (name) { delete _options[name]; if (factory.current === name) { factory.current = null; } }; /** * Open bubble with provided name * @param {String} name Bubble name * @param {Object} [options] Options that will be available for bubble * @param {jQuery|String} [node] jQuery: Node relative to which bubble will be positioned * String: Registered ref id */ factory.open = function (name, options, node) { if ( !_options.hasOwnProperty(name) ) { throw new Error('Bubble `'+ name +'` can\'t be opened, it has not been registered yet.'); } if ( options instanceof jQuery ) { node = options; options = {}; } if ( typeof options === 'string' ) { node = Ref.get(options); options = {}; } if (typeof options === 'object') { factory.options(name, options); } if (node instanceof jQuery) { factory.node = node; } if (typeof node === 'string') { factory.node = Ref.get(node); } factory.current = name; $rootScope.$broadcast('bubble:open' , name, options, node); $rootScope.$broadcast('bubble:open:' + name, name, options, node); angular.element('body').addClass(bubbleOpenClass); }; /** * Close all opened bubbles * @param {String} [name] Close bubble */ factory.close = function () { var name = factory.current, options = _options[name], option; $rootScope.$broadcast('bubble:close' , name, options, factory.node); $rootScope.$broadcast('bubble:close:' + name, name, options, factory.node); // clear current bubble options for (option in options) { if ( options.hasOwnProperty(option) ) { delete options[option]; } } factory.current = null; factory.node = null; angular.element('body').removeClass(bubbleOpenClass); }; /** * Set context for opened bubble * @param {String} name Bubble name * @param {Object} options Opening context (arguments) * @return {Object} Bubble options */ factory.options = function (name, options) { if (typeof options === 'undefined' || options === _options[name]) { return _options[name]; } angular.copy(options, _options[name]); }; return factory; }]) .directive('ljBubble', ['Bubble', '$parse', '$compile', '$timeout', '$templateCache', function( Bubble, $parse, $compile, $timeout, $templateCache ) { return { scope: true, link: function(scope, element, attrs) { var options = $parse(attrs.ljBubble)(scope), name = options.name, bubble = $compile($templateCache.get('ljBubble.tmpl'))(scope), arrow = bubble.find('.i-popup-arr'), $window = angular.element(window); scope.show = false; Bubble._register(name, options); scope.template = options.template || (name + '.html'); scope.bubble = { name: name, close: Bubble.close, options: Bubble.options(name) }; scope.arrow = { vertical: 't', /* top (t) or bottom (b) */ horizontal: 'l' /* left (l) or right (r) */ }; scope.position = { x: -9999, y: -9999 }; scope.visibility = 'hidden'; scope.arrowClass = function () { var opts = scope.bubble.options; return opts.aside || options.aside ? 'i-popup-arr' + scope.arrow.horizontal + scope.arrow.vertical : 'i-popup-arr' + scope.arrow.vertical + scope.arrow.horizontal; }; scope.$watch(function() { return Bubble.current; }, function(value) { hideFromViewport(); $timeout(function() { scope.show = value === name; if (value && scope.show) { $timeout(setPosition); } }); }, true); function setPosition() { // try to use top/left coords var vertical = scope.arrow.vertical, horizontal = scope.arrow.horizontal, opts = scope.bubble.options; scope.visibility = 'hidden'; // calculate positions initially recalculatePositions(); // if there is not enough vertical space, // bubble shows at the top of the target if ( isOutOfViewportY() ) { // we should change arrow position if possible scope.arrow.vertical = vertical === 't' ? (opts.alwaysTop ? 'b' : 't'): (opts.alwaysBottom ? 't' : 'b'); } // if there is not enough horizontal space, // bubble shows at the right of the target if ( isOutOfViewportX() ) { // we should change arrow position scope.arrow.horizontal = horizontal === 'r' ? (opts.alwaysRight ? 'l' : 'r') : (opts.alwaysLeft ? 'r' : 'l'); } // top/left coords can't be used if ( scope.arrow.horizontal !== horizontal || scope.arrow.vertical !== vertical ) { // positions should be recalculated // timeout is needed to apply arrow positions $timeout(function () { recalculatePositions(); scope.visibility = 'visible'; }); } else { scope.visibility = 'visible'; } } function recalculatePositions() { var el = Bubble.node || element, centerX = el.offset().left + Math.floor(el.outerWidth() / 2), forceX = scope.bubble.options.forceX || 0, forceY = scope.bubble.options.forceY || 0; if ( scope.bubble.options.aside || options.aside ) { scope.position.x = scope.arrow.horizontal === 'r' ? el.offset().left - bubble.outerWidth() - arrow.outerWidth() : el.offset().left + el.outerWidth() + arrow.outerWidth(); scope.position.y = el.offset().top - arrow.position().top + ( el.outerHeight() - arrow.outerHeight() )/ 2 + forceY; } else { scope.position.x = centerX - arrow.position().left - Math.floor(arrow.outerWidth() / 2) - 2 + forceX; scope.position.y = scope.arrow.vertical === 't' ? el.offset().top + el.outerHeight() + arrow.outerHeight() : el.offset().top - arrow.outerHeight() - bubble.outerHeight(); } } function hideFromViewport() { scope.position.x = -9999; } function isOutOfViewportY() { var scrollTop = $window.scrollTop(); if ( scope.position.y < scrollTop || scope.bubble.options.aside ) { return true; } return scope.position.y + bubble.outerHeight() > scrollTop + $window.outerHeight(); } function isOutOfViewportX() { var scrollLeft = $window.scrollLeft(); if ( scope.position.x < scrollLeft || scope.bubble.options.aside ) { return true; } return scope.position.x + bubble.outerWidth() > scrollLeft + $window.outerWidth(); } /** * Bubble target click handler * @param {jQuery.Event} event Click event object */ function onTargetClick(event) { event.preventDefault(); if ( Bubble.current === options.name ) { return; } $timeout(function() { Bubble.open(options.name); }); } function onResize() { if (scope.show) { $timeout(setPosition); } } if ( !options.disableClick ) { element.on('click', onTargetClick); } $window.on('resize', onResize); if ( options.recalculateOnScroll ) { $window.on('scroll', onResize); } $('body').append(bubble); scope.$on('$destroy', function () { element.off('click', onTargetClick); $window.off('resize', onResize); Bubble._unregister(name); bubble.remove(); }); } }; }]); })(jQuery); ; /* file-end: js/core/angular/bubble.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/core/angular/ljUser.js */ /* --------------------------------------------------------------------------------- file-start: js/core/angular/api.js */ /* --------------------------------------------------------------------------------- file-start: js/core/angular/messages.js */ Site.page.template['angular/ljMessages.ng.tmpl'] = '\n \n \n
\n
\n
\n \n \n ×\n \n
\n
\n'; LJ.injectStyle('/* System Message\n----------------------------------- */\n.b-msgsystem-wrapper {\n width: 100%;\n height: auto;\n }\n .b-msgsystem-wrapper.b-msgsystem-wrapper-fixed {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1001;\n overflow: hidden;\n padding: 0 0 10px;\n }\n .s-schemius .b-msgsystem-wrapper.b-msgsystem-wrapper-fixed {\n top: 60px;\n }\n\n .g-sensor .b-msgsystem-wrapper.b-msgsystem-wrapper-fixed,\n .mobile-msg .b-msgsystem-wrapper.b-msgsystem-wrapper-fixed {\n position: static;\n padding: 0;\n background-image: none;\n }\n\n.b-msgsystem {\n position: relative;\n min-height: 50px;\n padding: 10px 140px 10px 120px;\n font: 14px/1.357 Arial, Helvetica, sans-serif;\n }\n .b-msgsystem DD,\n .b-msgsystem DT,\n .b-msgsystem TH,\n .b-msgsystem TD,\n .b-msgsystem P,\n .b-msgsystem DIV,\n .b-msgsystem LI,\n .b-msgsystem PRE,\n .b-msgsystem CODE,\n .b-msgsystem KBD {\n font-size: 100%;\n }\n .b-msgsystem .i-ljuser-userhead {\n vertical-align: top !important;\n margin: 3px 0 0 0;\n }\n.b-msgsystem:after {\n position: absolute;\n bottom: -10px;\n left: 0;\n display: block;\n content: \'\';\n width: 100%;\n height: 10px;\n background-image: -webkit-linear-gradient(top, rgba(53, 99, 161, 0.3), rgba(53, 99, 161, 0));\n background-image: -moz-linear-gradient(top, rgba(53, 99, 161, 0.3), rgba(53, 99, 161, 0));\n background-image: -o-linear-gradient(top, rgba(53, 99, 161, 0.3), rgba(53, 99, 161, 0));\n background-image: linear-gradient(to bottom, rgba(53, 99, 161, 0.3), rgba(53, 99, 161, 0));\n -webkit-background-size: 10px 10px;\n -o-background-size: 10px 10px;\n background-size: 10px 10px;\n background-position: 0 100%;\n background-repeat: repeat-x;\n }\n .b-msgsystem-head {\n margin: 0 0 0.357em;\n padding: 0;\n font-size: 1.142em;\n font-weight: bold;\n }\n .b-msgsystem-wrap {\n line-height: 50px;\n min-height: 50px;\n }\n\n .b-msgsystem-head ~ .b-msgsystem-wrap {\n line-height: inherit;\n min-height: 0;\n }\n\n .b-msgsystem-body {\n display: inline-block;\n vertical-align: middle;\n line-height: 1.571;\n font-size: 1em;\n color: #787878;\n }\n\n.b-msgsystem .i-ljuser-username,\n.b-msgsystem .i-ljuser-username:link,\n.b-msgsystem .i-ljuser-username:visited {\n color: #0051B7 !important;\n }\n.b-msgsystem .i-ljuser-username:hover,\n.b-msgsystem .i-ljuser-username:active {\n color: #C00 !important;\n }\n\n.b-msgsystem-type-error {\n background: #FFEFEF no-repeat 2.7em 50% url(\'data:image/png;base64,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\');\n color: #CB1427;\n }\n .b-msgsystem-type-error + .b-msgsystem-type-error {\n border-top: 1px solid #FFDFDF;\n }\n.b-msgsystem-type-warning {\n background: #FCF8E3 no-repeat 2.7em 50% url(\'data:image/png;base64,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\');\n color: #C09853;\n }\n .b-msgsystem-type-warning + .b-msgsystem-type-warning {\n border-top: 1px solid #F9F1C7;\n }\n.b-msgsystem-type-success {\n background: #DFF0D8 no-repeat 2.7em 50% url(\'data:image/png;base64,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\');\n color: #468847;\n }\n .b-msgsystem-type-success + .b-msgsystem-type-success {\n border-top: 1px solid #BFE1B1;\n }\n.b-msgsystem-type-info {\n background: #D9EDF7 no-repeat 2.7em 50% url(\'data:image/png;base64,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\');\n color: #3A87AD;\n }\n .b-msgsystem-type-info + .b-msgsystem-type-info {\n border-top: 1px solid #B3DBEF;\n }\n\n.b-msgsystem-close {\n position: absolute;\n right: 0;\n top: 50%;\n width: 100px;\n margin: -0.714em 0 0;\n padding: 0 2em 0 0;\n text-align: right;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n color: #000;\n }\n.b-msgsystem-close:hover {\n color: #C00;\n }\n .b-msgsystem-close-text {\n border-bottom: 1px dotted;\n }\n .b-msgsystem-close-ctrl {\n margin: 0 0 0 0.1em;\n vertical-align: middle;\n font-size: 1.3em;\n }\n\n\n/* xs-size screen (45em) ~ 630px */\n@media all and (max-width: 45em) {\n .b-msgsystem {\n padding: 10px 50px 10px 44px;\n background-position: 10px 10px;\n -webkit-background-size: 24px;\n -o-background-size: 24px;\n background-size: 24px;\n }\n\n .b-msgsystem-close {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n margin: 0;\n width: 50px;\n }\n .b-msgsystem-close-text {\n display: none;\n }\n .b-msgsystem-close-ctrl {\n position: absolute;\n top: 50%;\n left: 50%;\n margin: -0.6em 0 0 -0.2em;\n text-shadow: 0 -1px 0 rgba(255, 255, 255, 0.5);\n font-size: 1.7em;\n color: rgba(0, 0, 0, 0.5);\n }\n}\n\n/* Toggle */\n.b-msgsystem {\n top: 0;\n opacity: 1;\n -webkit-transition: 0.3s top, 0.3s opacity;\n -moz-transition: 0.3s top, 0.3s opacity;\n -ms-transition: 0.3s top, 0.3s opacity;\n -o-transition: 0.3s top, 0.3s opacity;\n transition: 0.3s top, 0.3s opacity;\n }\n.b-msgsystem-enter,\n.b-msgsystem-leave {\n top: -100px;\n opacity: 0;\n }\n\n'); //= require_ml component.messages.close /* * LiveJournal page messages * https://conf.sup.com/pages/viewpage.action?pageId=6161047#id-1AddRemoveLinksandButtonsFRSCR-Warnings * * Available methods: * - error * - info * - success * - warning * * @example * // show error message * Message.error('Call the cops'); * * // show error message with title * Messages.error({ body: 'Call the cops!', title: 'Title is optional' }); * * // General form of message showing (providing type directly) * Messages.add({ type: 'error', body: 'Call the cops!', title: 'Title is optional' }); * * @example * Alternatively, you can use it from Perl controller: * * LJ::need_var(messages => [{ * title => 'hello', * body => 'world', * type => 'success' * }]); */ (function() { 'use strict'; angular.module('LJ.Messages', ['LJ.Templates', 'LJ.Directives']) .run(['$compile', '$rootScope', function($compile, $rootScope) { $compile( '
' )($rootScope) .appendTo('body'); }]) .factory('Messages', [function() { var messages = []; var factory = { get: get, add: add, remove: remove, clear: clear }; var MESSAGE_TYPES = ['error', 'info', 'success', 'warning']; // is needed for filtering of messages on the page var _cache = {}; // show messages that come from server if ( LJ.get('messages') ) { LJ.get('messages').forEach(add); } /** * Add message * @param {Object} message Message object * @param {String} message.type Message type: one of `MESSAGE_TYPES` * @param {String} [message.title] Title of the message * @param {String} message.body Body of the message */ function add(message) { if ( MESSAGE_TYPES.indexOf(message.type) === -1 ) { return; } // check if message with same body is currently on the page if ( _cache[message.body] ) { return; } _cache[message.body] = true; messages.push(message); return factory; } MESSAGE_TYPES.forEach(function (type) { factory[type] = function (message) { if ( typeof message === 'string' ) { message = { body: message }; } message.type = type; add(message); }; }); function clear() { messages.length = 0; _cache = {}; } function remove(message) { messages = messages.filter(function (_message) { return _message !== message; }); delete _cache[message.body]; return factory; } function get() { return messages; } return factory; }]) .directive('ljMessages', ['$timeout', 'Messages', function( $timeout, Messages ) { return { templateUrl: 'ljMessages.ng.tmpl', scope: true, controllerAs: 'directive', controller: ['$scope', function ($scope) { var that = this; this.messages = Messages.get(); this.close = Messages.remove; $scope.$watchCollection(Messages.get, function (messages) { that.messages = messages; }); }] }; }]); })(); ; /* file-end: js/core/angular/messages.js ----------------------------------------------------------------------------------*/ /** * @description Angular wrapper of LJ.Api * @author Valeriy Vasin (valeriy.vasin@sup.com) * * Available options: * - cache: turn on/off caching for the request * - silent: turn on/off messages (error/info etc) * - meta: result will be returned with meta information * is needed to determine is response from cache or not at the moment * If provided promise will be resolved with object that contains fields: * - response: {*} - server response * - fromCache: {Boolean} - is response from cache or not * * @example * // fetch without caching * Api.call('rpc.method', {param: 'value'}); * * // fetch with caching * Api.call('rpc.method', { param: 'value' }, { cache: true }); * * // usage of meta information * Api.call('ratings.journals_top', params, { cache: true, meta: true }) * .then(function (result) { * var response = result.response; * * // cache users if result is from server * if ( !result.fromCache ) { * * Users.Cache.add( * response.journals.map( LJ.Function.get('user') ) * ); * } * }); * * // turn off messages for the request * Api.call('rpc.method', {param: 'value'}, {silent: true}); */ angular.module('LJ.Api', ['LJ.Messages']) .factory('Api', ['$cacheFactory', '$rootScope', '$q', 'Messages', function ( $cacheFactory, $rootScope, $q, Messages ) { var factory = {}, cachePromises = $cacheFactory('LJApiPromises'); /** * Call JSON Rpc API * * @param {String} method JSON Rpc method * @param {Object} [params] JSON Rpc method params * @param {Function} [callback] Callback to call after data recieved * @param {Object} [options] Additional api options * @param {Boolean} [options.cache] Cache options: turn on/off cache for request * @param {Boolean} [options.silent] Turn on/off messages (error/info etc) * @param {Boolean} [options.meta] If set to `true` - result will be returned with meta * information, e.g. { response, fromCache } * * @return {Promise} Promise that will be resolved when data received */ factory.call = function (method, params, callback, options) { var defer = $q.defer(), defaults = { cache: false, silent: false, meta: false }, fromCache = false, promise, cacheKey; // only `Object` and `null` are allowed, otherwise - empty object if ( typeof params !== 'object' || params === null ) { params = {}; } if (typeof callback === 'object') { options = callback; callback = null; } options = angular.extend(defaults, options || {}); cacheKey = method + JSON.stringify(params); if ( options.cache ) { promise = cachePromises.get(cacheKey); if (promise) { fromCache = true; } } if ( !fromCache ) { promise = defer.promise; LJ.Api.call(method, params, function (response) { if (response.error) { defer.reject(response.error); } else { defer.resolve(response); } $rootScope.$apply(); }); // save original promise if ( options.cache ) { cachePromises.put(cacheKey, promise); } } // trigger events LJ.Event.trigger('api:request:change', method, true); promise.then(function() { LJ.Event.trigger('api:request:change', method, false); }); // show errors/messages if ( !options.silent ) { promise.then(function showMessage(response) { var message = response.message; if (typeof message === 'undefined') { return; } message.body = message.content; Messages.add(message); }, function showErrorMessage(error) { // no error message provided if ( typeof error.message === 'undefined' ) { return; } // Do not show internal api error // See: lj.api.js#handleError if ( error.code === 1 ) { return; } Messages.error({ body: error.message }); }); } // add meta information if ( options.meta ) { promise = promise.then(function (response) { return { response: response, fromCache: fromCache }; }); } if (typeof callback === 'function') { promise.then(callback); } return promise; }; return factory; } ]); ; /* file-end: js/core/angular/api.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/core/angular/users.js */ /* --------------------------------------------------------------------------------- file-start: js/core/angular/options.js */ angular.module("LJ.Options",[]).factory("Options",[function(){return{create:function(a){function b(b,c){"undefined"==typeof c?angular.extend(a,b):a[b]=c}function c(b){return a[b]}function d(){return a}if("undefined"==typeof a&&(a={}),"object"!=typeof a)throw new TypeError("Options should be an object.");return{set:b,get:c,raw:d}}}}]);; /* file-end: js/core/angular/options.js ----------------------------------------------------------------------------------*/ ;(function () { 'use strict'; angular.module('Users', ['LJ.Api', 'LJ.Options']) // Relations wrapper. Currently works through js/relations/relations.js .factory('Relations', ['$q', '$timeout', 'UsersCache', function ( $q, $timeout, UsersCache ) { /** * // add friend without options. State will be changed immediately * Relations.toggleFriend('test', true); * * // unsubscribe, but don't change user props immediately * Relations.toggleSubscription('test', false, { immediate: false }); */ /** * Helper that helps to interact with exiting relations * @param {String} username Username of user we are changing relation * @param {String} action Action to perform * @param {Object} [options] Options * @param {Boolean} [options.wait] Wait for response before updating user props * @return {Promise} Promise that will be resolved after action is completed */ function _action(username, action, options) { var defer = $q.defer(), // immediate update user props updateProps = { addFriend: { is_invite_sent: true }, removeFriend: { is_friend: false }, subscribe: { is_subscribedon: true }, unsubscribe: { is_subscribedon: false }, join: { is_invite_sent: true }, leave: { is_member: false }, setBan: { is_banned: true }, setUnban: { is_banned: false } }, // revert properties values if error happens revertProps = { addFriend: { is_invite_sent: false }, removeFriend: { is_friend: true }, subscribe: { is_subscribedon: false }, unsubscribe: { is_subscribedon: true }, join: { is_invite_sent: false }, leave: { is_member: true }, setBan: { is_banned: false }, setUnban: { is_banned: true } }, // save current props userProps = angular.copy( UsersCache.get(username) || {} ); if (typeof options === 'undefined') { options = {}; } if ( !options.wait ) { UsersCache.update(username, updateProps[action] || {}); } LJ.Event.trigger('relations.change', { username: username, action: action, callback: function (data) { $timeout(function () { if (data.error) { // rollback props if ( !options.wait ) { UsersCache.update( username, angular.extend(revertProps[action], userProps) ); } defer.reject(data.error.message); return; } var props = LJ.Object.pick(data, 'is_banned', 'is_friend', 'is_member', 'is_subscriber', 'is_subscribedon', 'is_friend_of', 'is_invite_sent' ); // update user props UsersCache.update(username, props); defer.resolve(data); }); } }); return defer.promise; } /** * Toggles subscription status of a user with provided username * * @param {String} username Username * @param {Boolean} state State: subscribe (true) or unsubscribe (false) * @param {Object} [options] Options * @param {Boolean} [options.wait] Wait for response before updating user props * @return {Promise} Promise that will be resolved with data after * subscription status will be changed */ function toggleSubscription(username, state, options) { var promise = _action(username, state ? 'subscribe' : 'unsubscribe', options); // reset filter mask after unsubscribe if ( !state ) { promise.then(function () { UsersCache.update(username, { filtermask: 0 }); }); } return promise; } /** * Toggles friend status of a user with provided username * * @param {String} username Username * @param {Boolean} state State: add friend (true) or remove from friend (false) * @param {Object} [options] Options * @param {Boolean} [options.wait] Wait for response before updating user props * @return {Promise} Promise that will be resolved with data after * friend status will be changed */ function toggleFriend(username, state, options) { return _action(username, state ? 'addFriend' : 'removeFriend', options); } /** * Join/leave community * * @param {String} username Username * @param {Boolean} state State: add friend (true) or remove from friend (false) * @param {Object} [options] Options * @param {Boolean} [options.wait] Wait for response before updating user props * @return {Promise} Promise that will be resolved with data after action completeness */ function toggleMember(username, state, options) { return _action(username, state ? 'join' : 'leave', options); } /** * Ban/unban usern * * @param {String} username Username * @param {Boolean} state State: ban (true) or unban user (false) * @param {Object} [options] Options * @param {Boolean} [options.wait] Wait for response before updating user props * @return {Promise} Promise that will be resolved with data after action is completed */ function toggleBan(username, state, options) { return _action(username, state ? 'setBan' : 'setUnban', options); } /** * Ban/unban user everywhere * * @param {String} username Username * @param {Boolean} state State: ban (true) or unban user (false) everywhere * @param {Object} [options] Options * @param {Boolean} [options.wait] Wait for response before updating user props * @return {Promise} Promise that will be resolved with data after action is completed */ function toggleBanEverywhere(username, state, options) { return _action(username, state ? 'banEverywhere' : 'unbanEverywhere', options); } return { toggleFriend: toggleFriend, toggleSubscription: toggleSubscription, toggleMember: toggleMember, toggleBan: toggleBan, toggleBanEverywhere: toggleBanEverywhere }; }]) // mask operations .factory('Mask', function () { var factory = {}; /** * Notice: first bit of a mask is not used */ /** * Notice: * Our max filter id is equal 31: last bit (of 32) could be equal to 1 * * JavaScript bitwise operators converts numbers to signed integers: * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers * * If max bit is equal to 1, it will be converted to negative number. * * That is why we should manually interpret number as unsigned integer */ function unsigned(number) { return number >>> 0; } /** * Change mask accroding to provided operations * * @param {Number} mask Mask field * @param {Object} actions Operations * @param {Number|Array} [actions.add] Group id(s) to be added in * @param {Number|Array} [actions.remove] Group id(s) to be removed from * * @return {Number} Updated mask */ factory.change = function (mask, actions) { var add = actions.add, remove = actions.remove; // add if (typeof add !== 'undefined') { if ( !Array.isArray(add) ) { add = [add]; } mask = add.reduce(function (mask, id) { return unsigned( mask | Math.pow(2, id) ); }, mask); } // remove if (typeof remove !== 'undefined') { if ( !Array.isArray(remove) ) { remove = [remove]; } mask = remove.reduce(function (mask, id) { var filterMask = (Math.pow(2, 32) - 1) - Math.pow(2, id); return unsigned( mask & filterMask ); }, mask); } return mask; }; /** * Check mask for inclusion in group * * @param {Number} mask Mask * @param {Number} groupId Group id * @return {Boolean} Result of the check */ factory.check = function (mask, groupId) { var groupMask = Math.pow(2, groupId); // convert to Boolean, because `&` returns number (group id) return Boolean(mask & groupMask); }; return factory; }) /** * Service is responsible for retrieving, caching and updating users * * // get by username * UsersCache.get('test'); * * // get all available users * UsersCache.get(); * * // get users that satisfy filtering function * UsersCache.get( LJ.Function.get('is_community') ); */ .factory('UsersCache', ['$q', '$cacheFactory', 'Options', function ( $q, $cacheFactory, Options ) { var _cache = $cacheFactory('users'), options = Options.create({ journal: LJ.get('remoteUser') }), factory; /** * Add / update user(s) to cache * @param {Array|Object} users Models to cache * @return {Array|Object} Cached models */ function add(users) { if (typeof users === 'undefined') { return; } var hash = _cache.get( options.get('journal') ) || {}, result = users; if ( !Array.isArray(users) ) { users = [users]; } users.forEach(function (user) { if (!user || typeof user !== 'object' || typeof user.username === 'undefined') { return; } var existed = hash[user.username]; hash[user.username] = existed ? angular.extend(existed, user) : user; }); _cache.put(options.get('journal'), hash); return result; } /** * Check if user exists in cache * * @param {String} username Username * @return {Boolean} Checking result */ function exists(username) { var cachedUsers = _cache.get( options.get('journal') ); return Boolean( cachedUsers[username] ); } /** * User(s) getter * @param {String|Function} [username] Get users by username if string passed, * apply filtering function for all users if function passed, * return all users, if nothing has been passed * @return {Object|Array|NULL} Result * * @example * * // get by username * get('test'); * * // get all communities * get( LJ.Function.get('is_community') ); * * // get all users * get(); */ function get(username) { var type = typeof username, cache; if (type === 'string') { cache = _cache.get( options.get('journal') ); return cache && cache[username] ? cache[username] : null; } if (type === 'function') { // get users with filter function return _users(username); } if (type === 'undefined') { // get all users return _users(); } throw new TypeError('Incorrect argument passed.'); } /** * Getter helper * @param {Function} [filter] Filter function * @return {Array} List of users */ function _users(filter) { var cachedUsers = _cache.get( options.get('journal') ), result = [], username; for (username in cachedUsers) { if ( cachedUsers.hasOwnProperty(username) ) { // skip users that not satisfy filter function if (filter && !filter( cachedUsers[username] )) { continue; } result.push(cachedUsers[username]); } } return result; } /** * Update user props * * @param {String} username Username of user to update * @param {Object} props Props to update * @return {Object} Updated user */ function update(username, props) { var user = get(username) || { username: username }; angular.extend(user, props); add(user); return user; } factory = { // cache users add: add, update: update, // work with options set: options.set, // work with users get: get, exists: exists }; return factory; }]) .factory('Users', ['$q', '$timeout', 'Api', 'Mask', 'UsersCache', 'Options', function ( $q, $timeout, Api, Mask, UsersCache, Options ) { var rpc = { friends: { read: 'relations.list_friends', readOne: 'relations.get_friend', update: 'groups.update_users' }, subscriptions: { read: 'relations.list_subscriptions', readOne: 'relations.get_subscription', update: 'filters.update_users' } }, options = Options.create({ type: 'friends', journal: LJ.get('remoteUser') }); function _rpc(rpcType) { return rpc[ options.get('type') ][rpcType]; } /** * Check if user should be extracted from cache according friend/subscription status * @param {Object} user User model * @return {Boolean} Result */ function _isUserCorrect(user) { if (options.get('type') === 'subscriptions') { return Boolean( user.is_subscribedon ); } // we are able to add any user to group, that is why any know user is correct for groups return true; } /** * Mask getter * * @param {Object} user User object * @param {Number} [value] Mask value to set * @return {Number} Mask */ function mask(user, value) { if (typeof value === 'undefined') { return user[ maskField() ] || 1; } user[ maskField() ] = value; } function maskField() { return options.get('type') === 'subscriptions' ? 'filtermask' : 'groupmask'; } function fetchUser(username, fields, options) { return Api.call('user.get', { target: username, fields: fields }, options) .then(function (response) { var user = response.user; UsersCache.add(user); return user; }); } /** * Fetch friends of current user * @param {Object} [fields] Fields to fetch, * e.g. { groupmask: 1, is_personal: 1, is_identity: 1 } * @param {Object} [apiOptions] Api options: {cache: true} * @return {Promise} Promise that will be resolved with data */ function fetchFriends(fields, apiOptions) { return Api.call('relations.list_friends', { journal: options.get('journal'), fields: fields }, apiOptions).then( _setFlagAndCache('is_friend') ); } function fetchGroupUsers(fields) { return Api.call('groups.list_users', { journal: options.get('journal'), fields: fields }).then(function (response) { UsersCache.add(response.users); return response; }); } function fetchSubscriptions(fields) { return Api.call('relations.list_subscriptions', { journal: options.get('journal'), fields: fields }).then( _setFlagAndCache('is_subscribedon') ); } function fetchBanned(fields) { return Api.call('relations.list_banned', { journal: options.get('journal'), fields: fields }).then( _setFlagAndCache('is_banned') ); } /** * Fetch helper method: set flag for fetched users, cache and return them * @return {Function} Function to use inside of .then() */ function _setFlagAndCache(flag) { return function (response) { var users = response.users; users.forEach( LJ.Function.set(flag, true) ); UsersCache.add(users); return users; }; } function fetchCount(type) { return Api.call('relations.'+ type +'_count').then(function (response) { return response.count; }); } /** * Sync user(s) model(s) with server * * @param {Array|Object} users User model or collection of models * @return {Promise} Promise that will be resolved after server response */ function sync(users) { if ( !angular.isArray(users) ) { users = [users]; } if (users.length === 0) { return $q.reject('You should provide users to sync.'); } return Api.call(_rpc('update'), { users: users, journal: options.get('journal') }).then(function (response) { UsersCache.add(response.users); return response; }); } /** * Check is user listed in group/filter with `id` * * @method isUserInGroup * * @param {String} username Username * @param {Number} id Filter/Group id (1..30) * @return {Boolean} Result */ function isUserInGroup(username, id) { var user = UsersCache.get(username); return user ? Mask.check(mask(user), id) : false; } /** * @todo Remove this method and replace it usage in controller * * Temp method for extracting only existing users by usernames * * @param {Array} usernames Username(s) * @return {Array} Array of existing users */ function getExisting(usernames) { return usernames.filter(UsersCache.exists) .map(UsersCache.get) .filter(_isUserCorrect); } /** * Filter users that are in exact group * * @method fromGroup * * @param {Object} options Options for users filtering * @param {Number} options.id Group id: (1..31) * @param {Number} [options.limit] Limit of users to extract * @param {String} [options.filter] Filter username string * @return {Array} Array of users that are in group */ function fromGroup(options) { var filter = (options.filter || '').toLowerCase(), users = UsersCache.get(function (user) { // filter friends/subscription if ( !_isUserCorrect(user) ) { return false; } if ( !Mask.check(mask(user), options.id) ) { return false; } if ( filter && user.display_username.toLowerCase().indexOf(filter) === -1 ) { return false; } return true; }); if (options.limit) { users = users.slice(0, options.limit); } return users; } /** * Filter users that are out of exact group * * @method outOfGroup * * @param {Object} options Options for users filtering * @param {Number} options.id Group id: (1..30) * @param {Number} [options.limit] Limit of users to extract * @param {String} [options.filter] Filter username string * @return {Array} Array of users that are out of group */ function outOfGroup(options) { var filter = (options.filter || '').toLowerCase(), users = UsersCache.get(function (user) { // filter friends/subscription if ( !_isUserCorrect(user) ) { return false; } if ( Mask.check(mask(user), options.id) ) { return false; } if ( filter && user.display_username.toLowerCase().indexOf(filter) === -1 ) { return false; } return true; }); if (options.limit) { users = users.slice(0, options.limit); } return users; } /** * Add users to group * * @method addToGroup * * @param {Number} id Group id * @param {String|Array} usernames Username(s) of users to add * @return {Promise} Promise that will be resolved * with synced users */ function addToGroup(id, usernames) { if ( !Array.isArray(usernames) ) { usernames = [usernames]; } var users; if (options.get('type') === 'subscriptions') { // for subscriptions we should filter non-existed users = getExisting(usernames); } else { users = usernames.map(function (username) { return UsersCache.get(username) || { username: username }; }); } users.forEach(function (user) { mask(user, Mask.change(mask(user), { add: id })); }); return sync(users); } /** * Remove users from group * * @method removeFromGroup * * @param {Number} id Group id * @param {String|Array} usernames Username(s) of users to remove * @param {Object} [options] Options * @param {Boolean} [options.silent] Remove users from group without sync * * @return {Promise|Undefined} Promise that will be resolved * with synced users or Undefined, if options.silent provided */ function removeFromGroup(id, usernames, options) { if ( !Array.isArray(usernames) ) { usernames = [usernames]; } var existing = getExisting(usernames); // update mask existing.forEach(function (user) { mask(user, Mask.change(mask(user), { remove: id })); }); // return without sync if silent if (options && options.silent) { return; } return sync(existing); } /** * Set alias for user * * @param {String} username Username * @param {String} value User alias * @return {Promise} Promise that will be resolved with data when complete */ function alias(username, value) { UsersCache.update(username, { alias: value }); return Api.call('user.alias_set', { target: username, alias: value }); } /** * Sort helper * * @param {String} prop Property. Available: username or display_username * @return {Function} Comparator function * * @example * * users.sort( Users.comparator('username') ); */ function comparator(prop) { return function (a, b) { return a[prop].toLowerCase().localeCompare( b[prop].toLowerCase() ); }; } /** * Patched version of options.set * * If we set journal for users it should also set journal for cache */ function set() { var old = options.get('journal'), journal; options.set.apply(null, arguments); journal = options.get('journal'); // update journal of cache if it changed if ( journal !== old ) { UsersCache.set('journal', journal); } } return { USERHEAD_FIELDS: { alias: 1, journal_url: 1, profile_url: 1, userhead_url: 1, is_invisible: 1, journaltype: 1 }, // options set: set, get: options.get, Cache: UsersCache, // work with server fetchUser: fetchUser, fetchBanned: fetchBanned, fetchFriends: fetchFriends, fetchGroupUsers: fetchGroupUsers, fetchSubscriptions: fetchSubscriptions, fetchCount: fetchCount, sync: sync, alias: alias, isUserInGroup: isUserInGroup, getExisting: getExisting, fromGroup: fromGroup, outOfGroup: outOfGroup, addToGroup: addToGroup, removeFromGroup: removeFromGroup, comparator: comparator }; }]); }()); ; /* file-end: js/core/angular/users.js ----------------------------------------------------------------------------------*/ Site.page.template['angular/ljUser.ng.tmpl'] = '
\n'; angular.module("LJ.User",["LJ.Api","LJ.Templates","Users"]).factory("ljUser",["$rootScope","Api","$q","$templateCache","$compile","$timeout","Users",function(a,b,c,d,e,f,g){function h(a){var b=c.defer(),d=g.Cache.get(a);return d&&d.userhead_url?(b.resolve(d),b.promise):g.fetchUser(a,g.USERHEAD_FIELDS,{cache:!0})}function i(b,d){var i=c.defer(),l=a.$new();return h(b).then(function(){var a;l.user=angular.extend({},g.Cache.get(b),d||{}),a=e(k)(l),f(function(){i.resolve(j.empty().append(a).html()),l.$destroy()})}),i.promise}var j=angular.element("
"),k=d.get("ljUser.ng.tmpl");return{prepare:h,get:i}}]).directive("ljUserDynamic",["$parse","Users","ljUser",function(a,b,c){return{templateUrl:"ljUser.ng.tmpl",replace:!0,scope:!0,compile:function(d,e){var f=a(e.ljUserDynamic),g=a(e.ljUserDynamicOptions);return function(a){var d=f(a),e=g(a);a.user=angular.extend({username:d,display_username:d},e||{}),c.prepare(d).then(function(){a.$watch(function(){return b.Cache.get(d)},function(b){angular.extend(a.user,b)},!0)})}}}}]);; /* file-end: js/core/angular/ljUser.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/settings/services/filters/filters.js */ ;(function () { 'use strict'; angular.module('GroupsAndFilters.Services.Filters', ['LJ.Api', 'LJ.Options', 'Users']) // filter for output filters and groups .filter('filtersOrder', function () { return function filtersOrder(filters) { // copy array to prevent digest loop during sort var copy = filters.slice(0); copy.sort(function (a, b) { if ( a.id === 31 ) { return -1; } if (b.id === 31) { return 1; } var aName = a.name.toLowerCase(), bName = b.name.toLowerCase(); return aName > bName ? 1 : -1; }); // return sorted copy return copy; }; }) .factory('FilterGroupFactory', ['$q', '$timeout', 'Api', 'Options', 'Users', function ( $q, $timeout, Api, Options, Users ) { /** * Filter/Group factory * * @class FilterGroupFactory * @type {Angular.Service} * @constructor * @private */ function Factory() { angular.extend( this, { MAX_COUNT: 31, // filters cache filters: [], // API key: filters/groups key: 'filters', // RPC endpoints: should be redefined rpc: {} }, Options.create({ journal: LJ.get('remoteUser') }) ); } /** * Get filter JSON params, exclude not needed * * @method toJSON * @param {Object} filter Filter object * @return {Object} Filtered fields */ Factory.prototype.toJSON = function (filter) { var json = angular.copy(filter); delete json.checked; delete json.users; return json; }; /** * Generate id for new filter/group based on existed: * next free id (that is not used by any existed filter) * * @method nextId * @return {Number} Generated next id */ Factory.prototype.nextId = function () { var id = null, ids = this.filters.map( LJ.Function.get('id') ), // id = 0 - is not used i = 1, max = this.MAX_COUNT; while (i < max && id === null) { if ( ids.indexOf(i) === -1) { id = i; } i += 1; } return id; }; /** * Sync current state of filter(s) with server * * @method sync * @param {Array|Object} filters Filter instance(s) */ Factory.prototype.sync = function (filters) { var params = {}; // wrap single filter to array if ( !angular.isArray(filters) ) { filters = [filters]; } params[this.key] = filters.map(this.toJSON); params.journal = this.get('journal'); return Api.call(this.rpc.update, params); }; /** * Fetch filters from server * * @method fetch * * @param {Object} [options] Request option * @param {Boolean} [options.cache=false] Cache request or not * * @return {Promise} Promise that will be resolved with filters data */ Factory.prototype.fetch = function (options) { var that = this, params = { journal: this.get('journal') }; options = angular.extend(options || {}, { cache: false }); return Api.call(this.rpc.read, params, options).then(function (response) { // save fetched filters that.filters = response[that.key]; return that.filters; }); }; /** * Check is filter/group name uniq * @param {String} name Filter/group name to check * @return {Boolean} Check result */ Factory.prototype._isNameUniq = function (name) { var names = this.filters.map(function (filter) { return filter.name.toLowerCase(); }); name = name.toLowerCase(); return names.indexOf(name) === -1; }; /** * Create filter * * @method create * @param {String} name Filter name * @return {Promise} Promise that will be resolved with created * filter data */ Factory.prototype.create = function (name) { var filter; name = name.trim(); if ( name.length === 0 ) { return $q.reject( this.key === 'filters' ? LJ.ml('api.error.filters.filter_name_not_specified') : LJ.ml('api.error.groups.group_name_not_specified') ); } // check if filter name is uniq if ( !this._isNameUniq(name) ) { return $q.reject( this.key === 'filters' ? LJ.ml('api.error.filters.filter_already_exist', { name: name }) : LJ.ml('api.error.groups.group_already_exist', { name: name }) ); } filter = { id: this.nextId(), name: name, users: [], public: false, journal: this.get('journal') }; this.filters.push(filter); return Api.call(this.rpc.create, filter); }; /** * Remove filter(s) * * @method remove * @param {Object|Object[]} filters Filters to remove * @return {Promise} Promise that will be resolved * with removed filters data */ Factory.prototype.remove = function (filters) { var that = this, params = {}; filters = Array.isArray(filters) ? filters : [filters]; params[this.key] = filters.map( LJ.Function.get('id') ); params.journal = this.get('journal'); // splice filters filters.forEach(function (filter) { that.filters.splice( that.filters.indexOf(filter), 1 ); }); return Api.call(this.rpc.remove, params); }; /** * Get filter/group count * @method getCount * @return {Promise} Promise that will be resolved when server respond */ Factory.prototype.getCount = function () { return Api.call(this.rpc.count, { journal: this.get('journal') }).then( LJ.Function.get('count') ); }; /** * Get filters/groups for user * @param {String} username Username of the user * @return {Array} Array of filters */ Factory.prototype.by = function (username) { var user = Users.Cache.get(username); if ( !user ) { return []; } return this.filters.filter(function (filter) { return Users.isUserInGroup(username, filter.id); }); }; return Factory; } ]) .factory('Filter', ['FilterGroupFactory', function (Factory) { /** * @class Filter * @extends FilterGroupFactory * @constructor */ function Filter() { /** * RPC endpoints * @property {Object} rpc * * @property {String} rpc.create Create filter endpoint * @property {String} rpc.read Read filters endpoint * @property {String} rpc.update Update filter(s) endpoint * @property {String} rpc.remove Remove filter(s) endpoint * @property {String} rpc.count Count filters endpoint */ this.rpc = { create: 'filters.create', read: 'filters.list', update: 'filters.update', remove: 'filters.remove', count: 'filters.count' }; /** * API key: filters/groups * @property {String} key */ this.key = 'filters'; } Filter.prototype = new Factory(); /** * Update privacy for filter(s) * * @method _setPrivacy * @private * @param {Objects[]|Object} filters Filter(s) object(s) to set privacy * @param {String} privacy Privacy to be set: 'public' or 'private' * @return {Promise} Promise that will be resolved when sync is done */ Filter.prototype._setPrivacy = function (filters, privacy) { filters = Array.isArray(filters) ? filters : [filters]; filters.forEach( LJ.Function.set('public', privacy === 'public') ); return this.sync(filters); }; /** * Update filter(s) privacy to private * * @method private * @param {Object|Object[]} filters Filter(s) to update * @return {Promise} Promise that will be resolved * with update filters data */ Filter.prototype.private = function (filters) { return this._setPrivacy(filters, 'private'); }; /** * Update filter(s) privacy to public * * @method public Set privacy to public * @param {Object|Object[]} filters Filter(s) to update * @return {Promise} Promise that will be resolved * with update filters data */ Filter.prototype.public = function (filters) { return this._setPrivacy(filters, 'public'); }; return new Filter(); }]) .factory('Group', ['FilterGroupFactory', function (Factory) { /** * @class Group * @extends FilterGroupFactory * @constructor */ function Group() { /** * RPC endpoints * @property {Object} rpc * * @property {String} rpc.create Create group endpoint * @property {String} rpc.read Read groups endpoint * @property {String} rpc.update Update group(s) endpoint * @property {String} rpc.remove Remove group(s) endpoint * @property {String} rpc.count Count groups endpoint */ this.rpc = { create: 'groups.create', read: 'groups.list', update: 'groups.update', remove: 'groups.remove', count: 'groups.count' }; /** * Key for group and filter distinction * * @property {String} key * @type {String} */ this.key = 'groups'; } Group.prototype = new Factory(); return new Group(); }]); }()); ; /* file-end: js/settings/services/filters/filters.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/settings/directives/filtersFor.js */ LJ.injectStyle('.b-filterset{max-width:290px;font:14px/1.4 Arial,sans-serif;color:#000}.b-filterset DD,.b-filterset DT,.b-filterset TH,.b-filterset TD,.b-filterset P,.b-filterset DIV,.b-filterset SPAN,.b-filterset EM,.b-filterset STRONG,.b-filterset B,.b-filterset I,.b-filterset LI,.b-filterset LABEL,.b-filterset PRE,.b-filterset CODE,.b-filterset KBD{font-size:100%}.b-filterset .i-ljuser-userhead{vertical-align:top!important;margin:1px 0 0!important;border:none!important}.b-filterset .i-ljuser-username:link,.b-filterset .i-ljuser-username:visited,.b-filterset .i-ljuser-username:hover,.b-filterset .i-ljuser-username:active{color:#0051B7!important;text-decoration:none!important;border:none!important}.b-filterset .b-filterset-title{font-weight:700!important}.b-filterset .b-filterset-title,.b-filterset .b-filterset-subtitle{margin:0 1.142em .5em 0!important;color:#222!important}.b-filterset-list{position:relative;z-index:1;overflow:auto;max-height:14em;min-width:220px;margin:0 0 .3em;padding:0;background-attachment:scroll;-moz-background-clip:border-box;background-clip:border-box;background-image:-webkit-radial-gradient(farthest-side at 50% 0,rgba(0,0,0,.1),transparent),-webkit-radial-gradient(farthest-side at 50% 100%,rgba(0,0,0,.1),transparent);background-image:-o-radial-gradient(farthest-side at 50% 0,rgba(0,0,0,.1),transparent),-o-radial-gradient(farthest-side at 50% 100%,rgba(0,0,0,.1),transparent);background-image:-moz-radial-gradient(farthest-side at 50% 0,rgba(0,0,0,.1),transparent),-moz-radial-gradient(farthest-side at 50% 100%,rgba(0,0,0,.1),transparent);background-image:radial-gradient(farthest-side at 50% 0,rgba(0,0,0,.1),transparent),radial-gradient(farthest-side at 50% 100%,rgba(0,0,0,.1),transparent);-moz-background-origin:padding-box;background-origin:padding-box;background-position:0 0,0 100%;background-repeat:no-repeat;-moz-background-size:100% 7px;background-size:100% 7px}.b-filterset-list:before,.b-filterset-list:after{position:relative;z-index:-1;display:block;content:\"\";height:14px;margin:0 0 -14px;background:-webkit-linear-gradient(top,#F4F5F6,#F4F5F6 30%,rgba(244,245,246,0)) 0 0;background:-moz-linear-gradient(top,#F4F5F6,#F4F5F6 30%,rgba(244,245,246,0)) 0 0;background:-o-linear-gradient(top,#F4F5F6,#F4F5F6 30%,rgba(244,245,246,0)) 0 0;background:linear-gradient(to bottom,#F4F5F6,#F4F5F6 30%,rgba(244,245,246,0)) 0 0}.b-filterset-list:after{margin:-14px 0 0;background:-webkit-linear-gradient(top,rgba(228,229,233,0),#E4E5E9 70%,#E4E5E9) 0 0;background:-moz-linear-gradient(top,rgba(228,229,233,0),#E4E5E9 70%,#E4E5E9) 0 0;background:-o-linear-gradient(top,rgba(228,229,233,0),#E4E5E9 70%,#E4E5E9) 0 0;background:linear-gradient(to bottom,rgba(228,229,233,0),#E4E5E9 70%,#E4E5E9) 0 0}.b-filterset-list LI{margin:0;padding:0;list-style-type:none}.b-filterset-list LI.loading{background:url(/img/preloader/preloader-blue-gray.gif?v=16423) no-repeat 100% 50%}.b-filterset-list LABEL{display:block;white-space:nowrap;line-height:1.333;font-size:.857em}.b-filterset-list LABEL:hover{background:#7292BD;color:#FFF}.b-filterset-addnew-input{display:block;margin:0 0 .5em;white-space:nowrap;line-height:1.333;font-size:.857em}.b-filterset-addnew{margin:.5em 0 0}.b-filterset-pseudo{font-size:.857em;color:#0051B7}.b-filterset-submit{text-align:right}.b-filterset-loader:after,.b-filterset-loader:before{display:inline-block;visibility:hidden;content:\'\';width:21px;height:21px;margin:-2px 0 0 4px;background:url(/img/preloader/preloader-blue-gray.gif?v=16423) no-repeat 50% 50%;vertical-align:middle}.b-filterset-loader-before:after,.b-filterset-loader-after:before{display:none}.b-filterset-loading .b-filterset-loader-after:after,.b-filterset-loading .b-filterset-loader-before:before{visibility:visible}'); Site.page.template['angular/controlstrip/filters.ng.tmpl'] = '
\n
    \n
  • \n \n
  • \n\n
  • \n \n
    \n \n \n \n
    \n
  • \n
\n\n \n \n \n
\n
\n'; !function(){"use strict";function a(a,b,c,d,e,f){function g(){return Array.isArray(a.usernames)?a.usernames:[a.usernames]}a.loading={},a.filters=[],c.fetch({cache:!0}).then(function(b){a.filters=b}),a.model={newFilter:"",showCreateDialog:!1},a.toggleFilter=function(b,c){var e;f.clear(),a.loading[b]=!0,e=c?d.addToGroup(b,g()):d.removeFromGroup(b,g()),e.then(function(){a.loading[b]=!1})},a.isActive=function(a){var b=g().every(function(b){return d.isUserInGroup(b,a)});return b},a.isCountReached=function(){return a.filters.length>=c.MAX_COUNT},a.createFilter=function(){var b=a.model.newFilter.trim();a.resetFilter(),0!==b.length&&(a.model.loading=!0,c.create(b).then(function(b){var c=b.filter;d.addToGroup(c.id,g()).then(function(){a.model.loading=!1})}))},a.resetFilter=function(){a.model.newFilter="",a.model.showCreateDialog=!1},a.$on("bubble:open:controlstrip",a.resetFilter)}angular.module("Filters.List",[]).controller("FiltersForCtrl",["$scope","$q","Filter","Users","Bubble","Messages",a]).controller("GroupsForCtrl",["$scope","$q","Group","Users","Bubble","Messages",a]).directive("filtersFor",[function(){return{controller:"FiltersForCtrl",scope:{usernames:"=filtersFor"},templateUrl:"filters.ng.tmpl",link:function(a){a.isFiltersFor=!0}}}]).directive("groupsFor",[function(){return{controller:"GroupsForCtrl",scope:{usernames:"=groupsFor"},templateUrl:"filters.ng.tmpl",link:function(a){a.isGroupsFor=!0}}}])}();; /* file-end: js/settings/directives/filtersFor.js ----------------------------------------------------------------------------------*/ Site.page.template['angular/controlstrip/controlstrip.ng.tmpl'] = '\n\n \n
\n\n \n
\n
\n\n \n
\n\n \n
\n
\n
\n
\n \n
\n
\n\n \n \n\n
\n
\n
\n \n\n'; /*global ContextualPopup, Hourglass */ ;(function ($) { 'use strict'; /** * Event tracking helper */ function trackEvent(value) { LJ.Track.event('Relations', 'Menu', value); } angular.module('Relations.Menu', [ 'LJ.Templates', 'LJ.Bubble', 'LJ.Directives', 'LJ.User', 'LJ.Messages', 'GroupsAndFilters.Services.Filters', 'Users', 'Filters.List' ]) // fix interactions with history API .value('$anchorScroll', null) .controller('MenuCtrl', ['$scope', 'Bubble', '$timeout', '$q', 'ljUser', 'Filter', 'Users', 'Relations', 'Messages', function ( $scope, Bubble, $timeout, $q, ljUser, Filter, Users, Relations, Messages ) { var status = $('.w-cs-status'), username = LJ.get('journal.username'), hourglass, mlDefer; // turn on subscriptions mode Users.set({ type: 'subscriptions' }); // need it in scope to show lj-user-dynamic $scope.username = username; $scope.filters = []; $scope.status = LJ.get('controlstrip.status'); // cache current journal Users.Cache.add( LJ.get('journal') ); // override error showing method ContextualPopup.showNote = angular.identity; mlDefer = $q.defer(); $scope.mlResolve = { promise: mlDefer.promise }; ljUser.get(username, { noctxpopup: true }).then(function (html) { mlDefer.resolve({ username: html }); }); // watch current journal and update states $scope.$watch(function () { return Users.Cache.get(username); }, function (user) { $scope.states = LJ.Object.pick(user, 'is_friend', 'is_member', 'is_subscribedon', 'is_invite_sent'); }, true); /** * Toggle loading state * @param {Boolean} state If `true`: show loader, otherwise: hide loader */ $scope.toggleLoading = function (state) { $scope.loading = state; }; // clear messages when relations change request starts LJ.Event.on('relations.change', function () { $timeout(Messages.clear); }); function changeRelation(action, $event) { var relationPromise; if ( $event ) { showHourglass($event); } switch (action) { case 'addFriend': relationPromise = Relations.toggleFriend(username, true, { wait: true }); break; case 'removeFriend': relationPromise = Relations.toggleFriend(username, false, { wait: true }); break; case 'join': relationPromise = Relations.toggleMember(username, true, { wait: true }); break; case 'leave': relationPromise = Relations.toggleMember(username, false, { wait: true }); break; case 'subscribe': relationPromise = Relations.toggleSubscription(username, true, { wait: true }); break; case 'unsubscribe': relationPromise = Relations.toggleSubscription(username, false, { wait: true }); break; } // Notice: .finally() is not allowed in IE8, // that is why we need call it with ['finally']() notation return relationPromise['finally'](hideHourglass).then(function (data) { // Hide contextual popup if we are changing status from contextual popup // in control strip. if ( ContextualPopup.currentElement === status.find('.ljuser img').get(0) ) { ContextualPopup.hide(); } // show error if (data.error) { return $q.reject(data.error.message); } // show messages if (data.message) { data.message.body = data.message.content; Messages.add(data.message); } // update controlstrip status if (typeof data.controlstrip_status !== 'undefined') { $scope.status = data.controlstrip_status; } // We should fetch data updates to show filters dialog when: // 1) we are subscribing to user/community // 2) we are adding friend (add friend also subscribes us to user) // 3) we are joining community that we have been subscribed to already if ( action === 'subscribe' || action === 'addFriend' || (action === 'join' && data.is_subscribedon) ) { return fetchFilters(); } // Reset filters. This line fixes incorrect ng-checked directive behavior: // When lots of digest loops in a time it could stay not synced with data // This code could be removed after fixing performance issue $scope.filters = []; }, function onFail(message) { Messages.error({ body: message }); }); } /** * Fetch filters data and user filtermask * @return {Promise} Promise that will be resolved when data is ready */ function fetchFilters() { var user = Users.Cache.get(username), userPromise; // we could fetch filters and filtermask only if we subscribed to user if ( !user.is_subscribedon ) { return $q.reject(); } if ( !user.filtermask ) { // fetch filtermask userPromise = Users.fetchUser(username, { filtermask: 1 }); } else { // filtermask has been fetched before userPromise = $q.defer().resolve(); } return $q.all({ filters: Filter.fetch({ cache: true }), user: userPromise }).then(function (results) { $scope.filters = results.filters; }); } $scope.subscribe = function ($event) { $event.preventDefault(); trackEvent('subscribe'); changeRelation('subscribe', $event).then(function () { if ( $scope.states.is_subscribedon ) { $scope.mode = 'subscribe'; Bubble.open('controlstrip', 'unsubscribe'); } }); }; $scope.unsubscribe = function ($event) { $event.preventDefault(); trackEvent('unsubscribe'); changeRelation('unsubscribe', $event); }; $scope.addFriend = function ($event) { $event.preventDefault(); trackEvent('add friend'); changeRelation('addFriend', $event).then(function () { if ( $scope.states.is_friend ) { $scope.mode = 'add'; Bubble.open('controlstrip', 'removeFriend'); } }); }; $scope.removeFriend = function ($event) { $event.preventDefault(); trackEvent('remove friend'); changeRelation('removeFriend', $event); }; $scope.watch = function ($event) { $event.preventDefault(); trackEvent('subscribe to community'); changeRelation('subscribe', $event).then(function () { if ( $scope.states.is_subscribedon ) { $scope.mode = 'watch'; Bubble.open('controlstrip', 'unwatch'); } }); }; $scope.unwatch = function ($event) { $event.preventDefault(); trackEvent('unsubscribe from community'); changeRelation('unsubscribe', $event); }; $scope.join = function ($event) { $event.preventDefault(); trackEvent('join community'); changeRelation('join', $event).then(function () { if ( $scope.states.is_member ) { $scope.mode = $scope.states.is_subscribedon ? 'joinSubscribed' : 'join'; Bubble.open('controlstrip', 'leave'); } }); }; $scope.leave = function ($event) { $event.preventDefault(); trackEvent('leave community'); changeRelation('leave', $event); }; /** * Subscribe to community updates in a bubble after join action */ $scope.subscribeAfterJoin = function () { $scope.toggleLoading(true); trackEvent('subscribe to community (after join)'); changeRelation('subscribe').then(function () { $scope.toggleLoading(false); $scope.mode = 'watch'; }); }; /** * Show hourglass for event * * @param {jQuery.Event} event jQuery event (click) */ function showHourglass(event) { if (hourglass) { hideHourglass(); } hourglass = new Hourglass().setEvent(event).show(); } /** * Hide hourglass */ function hideHourglass() { if (hourglass) { hourglass.remove(); hourglass = null; } } }]); }(jQuery)); ; /* file-end: js/relations/menu.js ----------------------------------------------------------------------------------*/ /** * @author Valeriy Vasin (valeriy.vasin@sup.com) * @description Controlstrip functionality */ ;(function ($) { 'use strict'; // currently in IE8 when documentMode IE7 Standards is ON, some stuff is not working properly (e.g. ng-class) // Use fallback for that browser. Angular functionality should be turned off var IE7mode = Boolean(typeof document.documentMode !== 'undefined' && document.documentMode < 8); /** * Add community filter functionality for control strip */ function initFilter() { var bubble, form, input, submit; // filter is available only for logged in users if ( !LJ.get('remoteUser') ) { return; } bubble = $('#lj_controlstrip_new .w-cs-filter-inner'); // exit if filter content is not currently on the page if ( bubble.length === 0 ) { return; } form = $('#sortByPoster'); input = form.find('[name=poster]'); submit = form.find('[type=image]'); bubble.bubble({ target: '#lj_controlstrip_new .w-cs-filter-icon', showOn: 'click', closeControl: false }); input.input(function () { if( this.value.length ) { submit.css('opacity', 1) .prop('disabled', false); } else { submit.css('opacity', 0) .prop('disabled', true); } }); form.on('submit', function (e) { if( !input.val().length ) { e.preventDefault(); } }); } /** * Add labled placeholders for the control strip */ function addLabledPlaceholders() { $('#lj_controlstrip_new input[placeholder]').labeledPlaceholder(); } /** * Initialize control strip */ function init() { initFilter(); addLabledPlaceholders(); if ( LJ.Flags.isEnabled('new_friends_and_subscriptions') && !IE7mode ) { // init angular angular.bootstrap( $('[data-controlstrip]'), ['Relations.Menu']); } // calendar (function initCalendar() { var calendarLink = $('#lj_controlstrip_new .w-cs-i-calendar a'), // checks if we are on /friends page or not. There special calendar behavior is needed journalViewFriends = /^\/friends/.test( location.pathname ), journalUrlBase = LJ.get('current_journal.url_journal'), earlyDate = LJ.get('controlstrip.calendar.earlyDate'), lastDate = LJ.get('controlstrip.calendar.lastDate'); if ( calendarLink.length ) { calendarLink .calendar({ showOn: 'click', closeControl: false, dayRef: journalUrlBase + '/' + (journalViewFriends ? 'friends/' : '') + '%Y/%M/%D', allRefs: journalViewFriends, startMonth: earlyDate ? parseDate( LJ.get('controlstrip.calendar.earlyDate') ) : new Date(), endMonth: lastDate ? parseDate( LJ.get('controlstrip.calendar.lastDate') ) : new Date(), classNames: { container: 'w-cs-calendar' }, ml: { caption: LJ.ml('web.controlstrip.view.calendar') } }) .on('daySelected', function (event) { event.preventDefault(); }); if ( !journalViewFriends ) { calendarLink.calendarEvents( { fetchOnFirstDisplay: true } ); } } /** * Convert string e.g. "2009,10,27" to Date object * @return {Date} Parsed Date */ function parseDate(str) { var date = str.split(',').map(Number); return new Date(date[0], date[1], date[2]); } }()); $('.b-loginpopup').bubble({ target: '.i-auth-control', closeControl: false, showOn: 'click' }); $('input.text').labeledPlaceholder(); } $(function () { // load control strip if it's not available on document ready // Notice: some s2 users could turn off control strip for all users if (!document.getElementById('lj_controlstrip') && !document.getElementById('lj_controlstrip_new')) { // fetch control strip from server $.get( LiveJournal.getAjaxUrl('controlstrip'), { user: LJ.get('currentJournal') }, function (data) { $(data).appendTo(document.body); init(); } ); } else { init(); } }); }(jQuery)); ; /* file-end: js/controlstrip.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/jquery/jquery.lj.repostbutton.js */ LJ.UI.registerTemplate('templates-CleanHtml-PaidRepost', "{{if 1}} {{if !$data.owner}}+{{html $data.cost}}{{else $data.budget}}{{html $data.budget}}{{/if}}{{html $data.count}} {{else}} {{html LJ.mltext(\'paidrepost.button.label\')}} {{if !($data.owner)}}{{html $data.cost}}{{/if}} {{html LJ.mltext(\'paidrepost.button.label.done\')}}{{if !($data.owner)}}{{html $data.cost}}{{/if}} {{html $data.count}} {{/if}} ", 'JQuery.stat'); LJ.UI.registerTemplate('templates-CleanHtml-Repost', "{{if 1}} {{if !$data.owner}}+{{html $data.cost}}{{else $data.budget}}{{html $data.budget}}{{/if}}{{html $data.count}} {{else}} {{html LJ.mltext(\'repost.button.label\')}} {{html LJ.mltext(\'entry.reference.label.reposted\')}} {{html $data.count}} {{/if}} ", 'JQuery.stat'); LJ.UI.registerTemplate('templates-CleanHtml-reposted', "{{if $data.content}} {{each ($value.users || $data.users)}}{{if !((!$index) && !($value.dropComma || $data.dropComma))}}, {{/if}}{{html ($value.user || $data.user)}}{{/each}} {{else}}
{{html LJ.mltext(\'repost.popup.head\')}}
{{/if}} ", 'JQuery.stat'); /** * @name $.lj.repostbutton * @requires $.ui.core, $.ui.widget, $.lj.basicWidget, $.lj.bubble * @class Represents repost button * @author dmitry.petrov@sup.com (Dmitry Petrov), anazarov@sup.com (Alexander Nazarov) */ ;(function ($) { 'use strict'; /** @lends $.lj.repostbutton.prototype */ $.widget('lj.repostbutton', $.lj.basicWidget, { options: { classNames: { active: 'repost-button-active', inactive: 'repost-button-inactive', popupLoad: 'b-reposted-popup-load', popupNomore: 'b-reposted-popup-footer-hide', repostError: 'repost-error' }, selectors: { counterParent: '.lj-button-c', button: '.lj-button-b', counter: '.lj-like-item-count', buttonLink: '.lj-button-link', popupContent: '.b-reposted-popup-content', popupFooter: '.b-reposted-popup-footer', popupMore: '.b-reposted-popup-footer > a' }, templates: { popup: 'templates-CleanHtml-reposted' }, url: '', reposted: false, cost: 0, budget: 0, paid: false }, _create: function() { if ( LJ.Flags.isEnabled('ljlike_v3') ) { this.options.classNames = { active: 'b-flatrepost-reposted', inactive: 'b-flatrepost-disabled', popupLoad: 'b-reposted-popup-load', popupNomore: 'b-reposted-popup-footer-hide', repostError: 'repost-error' }; this.options.selectors = { counterParent: '.b-flatrepost-counter', button: '.b-flatrepost-name', counter: '.b-flatrepost-counter', buttonLink: '.b-flatrepost-name', popupContent: '.b-reposted-popup-content', popupFooter: '.b-reposted-popup-footer', popupMore: '.b-reposted-popup-footer > a' }; } $.lj.basicWidget.prototype._create.apply(this); if (!this.options.url) { console.warn(this.widgetName, ': no url in options, initialization won\'t continue'); } this._journal = LJ.get('currentJournal'); this._count = null; this._remote = LJ.get('remoteUser'); this._reposted = this.options.reposted; this._el('buttonLink'); this._href = this.element.find(this._s('button')).data('href'); this._href = LJ.Util.Journal.parseLink(this._href) || {}; if (!this._canRepost()) { this.element.addClass(this._cl('inactive')); this._buttonLink.removeAttr('title'); this._lock(); } this._popup = null; this._popupContent = null; this._popupLocked = false; this._lastUser = null; this._el('counterParent'); this._el('counter'); if (!Number(this._counter.html())) { this._hideCounter(); } this._bindControls(); }, _hideCounter: function () { this._counterParent.addClass('empty'); }, _showCounter: function () { this._counterParent.removeClass('empty'); }, _bindControls: function() { var repost = this; this.element.on('click', this._s('button'), this._onUpdateButton.bind(this)); this._counterParent.one('click', function() { if ( !Number(repost._counter.html()) ) { return; } repost._popup = repost._tmpl('popup'); repost._el('popupFooter', repost._popup); repost._popupContent = repost._popup.find(repost._s('popupContent')); repost._popup.bubble({ showOn: 'click', align: 'side', alwaysShowUnderTarget: true, target: repost._counterParent }) .on('bubblehide', function () { repost._lastUser = null; repost._popupContent.empty(); repost._popupFooter.removeClass(repost._cl('popupNomore')); }) .on('bubbleshow', function () { repost._loadRepostedList(); }) .on('click', repost._s('popupMore'), repost._loadRepostedList.bind(repost)); Function.defer(function() { repost._popup.bubble('show'); }); }); $.lj.basicWidget.prototype._bindControls.apply(repost); }, _loadRepostedList: function(ev) { var repost = this; if (ev) { ev.preventDefault(); } if (this._popupLocked) { return; } this._popupLocked = true; this._popupContent.addClass(this._cl('popupLoad')); LJ.Api.call('repost.get_list', { url: this.options.url, last: this._lastUser }, function(answer) { repost._popupContent.removeClass(repost._cl('popupLoad')); repost._popupLocked = false; if (answer.error) { repost._handleAnswer(answer); } else { repost._render(answer.users, answer.nomore, answer.count); repost._lastUser = answer.last; } }); }, _render: function(users, nomore, count) { var repost = this; /* Display users */ if (users.length > 0) { repost._tmpl('popup', { content: true, dropComma: !!repost._lastUser, users: users }).appendTo(repost._popupContent); } this._updateCounter(count); /* Hide 'Show More' button */ if (nomore) { repost._popupFooter.addClass(repost._cl('popupNomore')); } }, _onUpdateButton: function(ev) { if (!this.locked()) { this.toggleRepost(); } ev.preventDefault(); }, _handleAnswer: function(answer) { if (answer.hasOwnProperty('delete')) { if (answer.message) { this._showMessage(answer.message); } /* LJSUP-13479: Repost type or cost changed */ if ( this.paid !== Boolean(answer.paid) || this.paid && (this.cost !== answer.cost) ) { this.element.replaceWith(LJ.Social.renderRepostButton(this.options.url, answer)); return; } } if (answer.error) { if (answer.error.message) { this._showMessage(answer.error.message); } if (answer.error.data) { // Redraw button completely with new data this.element.replaceWith(LJ.Social.renderRepostButton(this.options.url, answer.error.data)); return; } } else { this._updateButton( !this._reposted ); } if (!answer.hasOwnProperty('count') && answer.hasOwnProperty('delete')) { answer.count = this._count - 1; } this._updateCounter(answer.count); this._unlock(); }, _showMessage: function (message) { var errorBubble = $('
', { 'class': this._cl('repostError'), text: message }) .bubble({ target: this.element, align: 'center', hide: function () { errorBubble.remove(); } }) .bubble('show'); }, _updateButton: function(reposted) { this._reposted = reposted; this.element.toggleClass(this._cl('active'), this._reposted); }, _updateCounter: function (count) { if (typeof count !== 'undefined') { this._count = Number(count); this._counter.html(this._count); } if (!Number(this._counter.html())) { this._hideCounter(); } else { this._showCounter(); } }, _canRepost: function () { if (LJ.get('preview')) { return false; } if (!this._remote) { return false; } if (LJ.get('remote_is_identity')) { return false; } if (this._remote === this._href.journal) { return false; } return true; }, toggleRepost: function() { var repost = this, args = { url: this.options.url }; if (!this._canRepost()) { return; } if (this._count === null) { this._count = parseInt( this._el('counter').html(), 10) || 0; } this._lock(); if (this._reposted) { LJ.Api.call('repost.delete', args, function (answer) { /* LJSUP-12559: Reload page when repost is deleted in remote user's journal */ if ( !answer.error && !answer.reposted && repost._journal === repost._remote && !location.href.match(/\/(friends|times|feed)\b/) ) { location.reload(); } else { repost._handleAnswer(answer); } }); } else { args.timezone = LJ.Util.Date.timezone(); if (this.options.paid) { args.cost = this.options.cost; } LJ.Api.call('repost.create', args, this._handleAnswer.bind(this)); } } }); }(jQuery)); ; /* file-end: js/jquery/jquery.lj.repostbutton.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/s2.js */ /* --------------------------------------------------------------------------------- file-start: js/discovery/directives.js */ Site.page.template['angular/ljImage.ng.tmpl'] = '\n
\n \n
\n
\n
\n'; Site.page.template['angular/ljGallery.ng.tmpl'] = '\n \n state.index\n }\"\n >\n
\n \n
\n
\n \n
\n \n
\n \n \n \n\n'; Site.page.template['angular/discovery/ljSuggest.ng.tmpl'] = '\n\n \n \n\n \n
    \n \n \n \n \n \n \n \n \n \n
\n\n'; Site.page.template['angular/widgets/authors/posts.ng.tmpl'] = '\n\n\n\n \n
\n \n \n
\n\n \n
\n\n \n
    \n\n \n
  • \n\n \n \n \n \n \n \n \n\n
  • \n\n
\n\n \n
\n
\n \n
\n \n
\n
\n
\n \n
\n \n
\n
\n
\n \n
\n \n
\n
\n
\n\n
\n\n\n\n\n'; LJ.injectStyle('/* Journal Gallery\n----------------------------------- */\n/*\n\n подпись \n подпись \n подпись \n\n*/\n.b-journalgallery {\n overflow: hidden;\n display: block;\n position: relative;\n width: 100%;\n margin: 0 auto;\n padding: 0 0 70px;\n font: 0.8125rem/1.1 \"ProximaNovaSemibold\",Tahoma,Arial,sans-serif;\n }\n /* container */\n .b-journalgallery-container {\n position: relative;\n background: #FFF;\n }\n /* picture */\n .b-journalgallery-picture {\n position: absolute;\n width: 100%;\n margin: 0;\n background: url(/img/preloader/preloader-disc-blue-white-16.gif?v=39502) no-repeat 50% 50%;\n -webkit-transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n -moz-transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n -ms-transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n -o-transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n text-align: center;\n }\n .b-journalgallery-picture:after {\n content: \'\';\n display: inline-block;\n height: 100%;\n margin: 0 0 0 -0.05em; /* To offset spacing. May vary by font */\n vertical-align: middle;\n }\n .b-journalgallery-wrapper {\n display: inline-block;\n vertical-align: middle;\n max-width: 99%;\n max-width: calc(100% - 0.3em);\n }\n .b-journalgallery-hightpriority .b-journalgallery-wrapper {\n display: inline;\n }\n .b-journalgallery-image {\n position: relative;\n max-width: 100%;\n margin: 0;\n vertical-align: top;\n opacity: 1;\n -webkit-transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n -moz-transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n -ms-transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n -o-transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n transition: 500ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;\n width: auto \\9;\n height: auto \\9;\n }\n .b-journalgallery-hightpriority .b-journalgallery-image {\n max-height: 100%;\n }\n .b-journalgallery-caption {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n height: 70px; /* eq to b-journalgallery padding-bottom */\n margin: 0;\n padding: 0;\n border: 0;\n text-align: center;\n background: #FFF;\n color: #829399;\n }\n .b-journalgallery-caption-title {\n overflow: hidden;\n position: absolute;\n top: 0;\n right: 40px;\n left: 40px;\n height: 2.2em;\n margin: 0;\n padding: 10px 2px 0;\n }\n .b-journalgallery-picture-loaded {\n background-image: none;\n }\n .b-journalgallery-picture-loaded .b-journalgallery-image {\n opacity: 1;\n }\n .b-journalgallery-picture-prev {\n -webkit-transform: translate3d(-100%, 0, 0);\n -moz-transform: translate3d(-100%, 0, 0);\n -ms-transform: translate3d(-100%, 0, 0);\n -o-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n opacity: 0;\n }\n .b-journalgallery-picture-next {\n -webkit-transform: translate3d(100%, 0, 0);\n -moz-transform: translate3d(100%, 0, 0);\n -ms-transform: translate3d(100%, 0, 0);\n -o-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n opacity: 0;\n }\n .b-journalgallery-picture-current {\n -webkit-transform: translate3d(0, 0, 0);\n -moz-transform: translate3d(0, 0, 0);\n -ms-transform: translate3d(0, 0, 0);\n -o-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n }\n /* counter */\n .b-journalgallery-counter {\n position: absolute;\n bottom: 44px;\n right: 0;\n margin: 0;\n padding: 2px;\n border: 0;\n text-align: right;\n color: #829399;\n }\n /* prev-next arrows */\n .b-journalgallery-nav {\n position: absolute;\n top: 0;\n bottom: 70px; /* .b-journalgallery {padding-bottom} */\n margin: 0;\n padding: 0;\n border: 0;\n cursor: pointer;\n font: 0/0 a;\n }\n .b-journalgallery-nav:before {\n content: \" \";\n position: absolute;\n top: 50%;\n width: 50px;\n height: 50px;\n margin: -25px 0 0;\n padding: 0;\n border: 0;\n border-radius: 3px;\n background: #839399;\n }\n .b-journalgallery-nav:hover:before {\n background: #09C;\n }\n .b-discoveryarticle .b-journalgallery-nav:hover:before {\n background: #39BF71;\n }\n .b-journalgallery-nav:after {\n content: \" \";\n position: absolute;\n top: 50%;\n width: 9px;\n height: 16px;\n margin: -8px 0 0;\n padding: 0;\n background: url(/img/icons/journalgallery.png?v=39648) no-repeat 0 0;\n }\n /* prev */\n .b-journalgallery-nav-prev {\n left: 0;\n width: 30%;\n }\n .b-journalgallery-nav-prev:before {\n left: 20px;\n }\n .b-journalgallery-nav-prev:after {\n left: 40px;\n }\n /* next */\n .b-journalgallery-nav-next {\n right: 0;\n width: 70%;\n }\n .b-journalgallery-nav-next:before {\n right: 20px;\n }\n .b-journalgallery-nav-next:after {\n right: 40px;\n background-position: 0 -17px;\n }\n\n\n'); LJ.injectStyle('/* AUTHOR\'S POSTS */\n\n\n\n.b-authorsposts {\n width: 300px;\n margin: 0 0 25px;\n margin: 0 0 1.5625rem;\n padding: 0 0 25px 30px;\n padding: 0 0 1.5625rem 30px;\n border-bottom: 1px solid #DAE3E6;\n }\n\n /* head */\n .b-authorsposts-head {\n margin: 0 0 16px;\n margin: 0 0 1rem;\n padding: 0;\n }\n .b-feedwidgets .b-authorsposts-head {\n margin: 0 0 13px;\n margin: 0 0 0.8125rem;\n }\n .b-authorsposts-title {\n margin: 0;\n padding: 0;\n font-style: normal;\n font-weight: normal;\n font-size: 20px;\n font-size: 1.25rem;\n text-transform: uppercase;\n color: #829399;\n }\n\n /* body */\n .b-authorsposts-body {\n margin: 0;\n padding: 0;\n }\n .b-feedwidgets .b-authorsposts-body {\n font-size: 14px;\n font-size: 0.875rem;\n }\n\n /* items */\n .b-authorsposts-items {\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n /* item */\n .b-authorsposts-item {\n margin: 16px 0 0;\n margin: 1rem 0 0;\n padding: 0;\n }\n .b-authorsposts-item:first-child {\n margin-top: 0;\n }\n\n /* link */\n .b-authorsposts-link {\n position: relative;\n display: block;\n margin: 0;\n padding: 0;\n }\n .b-discoveryarticle .b-authorsposts-link:link,\n .b-discoveryarticle .b-authorsposts-link:visited {\n color: #242f33\n }\n .b-discoveryarticle .b-authorsposts-link:hover,\n .b-discoveryarticle .b-authorsposts-link:active {\n color: #00a3d9;\n }\n\n /* pic */\n .b-authorsposts-pic {\n display: block;\n height: 200px;\n margin: 0 0 0.5em;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n }\n\n /* subject */\n .b-authorsposts-subject {\n display: block;\n margin: 0;\n font-size: 1.25em;\n line-height: 1.2;\n }\n\n /* dummy loader */\n .b-authorsposts-dummy {\n display: none;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .b-authorsposts-dummy-item {\n margin: 32px 0 0;\n margin: 2rem 0 0;\n padding: 0;\n }\n .b-authorsposts-dummy-item:first-child {\n margin-top: 0;\n }\n /* image */\n .b-authorsposts-dummy-pic {\n display: inline-block;\n width: 300px;\n height: 200px;\n margin: 0 0 8px;\n margin: 0 0 0.5rem;\n padding: 0;\n background: #F8F8F8;\n -webkit-animation: loading-authorsposts 1s infinite;\n -moz-animation: loading-authorsposts 1s infinite;\n -o-animation: loading-authorsposts 1s infinite;\n animation: loading-authorsposts 1s infinite;\n }\n /* hide at /feed page (LJSUP-18145) */\n .b-feedwidgets .b-authorsposts-dummy-pic {\n display: none;\n }\n /* caption */\n .b-authorsposts-dummy-caption {\n display: block;\n height: 48px;\n height: 3rem;\n margin: 0 0 8px;\n margin: 0 0 0.5rem;\n padding: 0;\n }\n .b-authorsposts-dummy-subject {\n position: relative;\n display: block;\n width: 250px;\n height: 19px;\n height: 1.2rem;\n margin: 0 0 32px;\n margin: 0 0 2rem;\n padding: 0;\n background: #F8F8F8;\n -webkit-animation: loading-authorsposts 1s infinite;\n -moz-animation: loading-authorsposts 1s infinite;\n -o-animation: loading-authorsposts 1s infinite;\n animation: loading-authorsposts 1s infinite;\n }\n .b-authorsposts-dummy-subject:after {\n content: \" \";\n position: absolute;\n top: 24px;\n top: 1.5rem;\n left: 0;\n width: 200px;\n height: 19px;\n height: 1.2rem;\n margin: 0;\n padding: 0;\n background: #F8F8F8;\n }\n /* meta */\n .b-authorsposts-dummy-meta {\n display: inline-block;\n width: 120px;\n height: 16px;\n height: 1rem;\n margin: 0;\n padding: 0;\n background: #F8F8F8;\n -webkit-animation: loading-authorsposts 1s infinite;\n -moz-animation: loading-authorsposts 1s infinite;\n -o-animation: loading-authorsposts 1s infinite;\n animation: loading-authorsposts 1s infinite;\n }\n @-webkit-keyframes loading-authorsposts {\n 0% { background: #F8F8F8; }\n 50% { background: #FBFBFB; }\n 100% { background: #F8F8F8; }\n }\n @-moz-keyframes loading-authorsposts {\n 0% { background: #F8F8F8; }\n 50% { background: #FBFBFB; }\n 100% { background: #F8F8F8; }\n }\n @-o-keyframes loading-authorsposts {\n 0% { background: #F8F8F8; }\n 50% { background: #FBFBFB; }\n 100% { background: #F8F8F8; }\n }\n @keyframes loading-authorsposts {\n 0% { background: #F8F8F8; }\n 50% { background: #FBFBFB; }\n 100% { background: #F8F8F8; }\n }\n\n/* loading */\n.b-authorsposts-loading {\n }\n .b-authorsposts-loading .b-authorsposts-body {\n min-height: 300px;\n }\n .b-authorsposts-loading .b-authorsposts-dummy {\n display: block;\n }\n .b-authorsposts-loading .b-authorsposts-items {\n visibility: hidden;\n }\n\n\n\n/* empty */\n.b-authorsposts-empty {\n display: none;\n }\n /* hide */\n .b-authorsposts-empty .b-authorsposts-head {\n display: none;\n }\n .b-authorsposts-empty .b-authorsposts-body {\n display: none;\n }\n\n\n\n@media all and (max-width: 1000px) {\n\n .b-authorsposts {\n width: auto;\n max-width: 650px;\n }\n .b-authorsposts-item {\n display: block;\n width: auto;\n margin-bottom: 1.5em;\n }\n .b-authorsposts-link {\n margin-right: 0;\n }\n\n}\n\n\n\n@media all and (max-width: 800px) {\n\n .b-authorsposts {\n width: 300px;\n }\n}\n\n\n\n@media all and (max-width: 650px) {\n\n .b-authorsposts {\n width: auto;\n max-width: 300px;\n padding-left: 15px;\n padding-right: 15px;\n }\n}\n\n\n'); angular.module('Discovery.Tags', [ 'LJ.Templates', 'LJ.Api' ]) /** * Discovery tags bootstrap. Should be used in conjunction with lj-html directive */ .directive('ljDiscoveryTags', ['$compile', function ($compile) { var TAGS = [ 'lj-gallery', '[lj-memories]', '[lj-lazy]', '[lj-share]', '[lj-cut]', '[lj-screenable]' ]; return { restrict: 'A', terminal: true, link: function (scope, element) { $compile( element.find( TAGS.join(',') ) )(scope); } }; }]) .directive('ljGallery', ['$templateCache', '$compile', function ( $templateCache, $compile ) { return { restrict: 'E', scope: true, link: function (scope, element, attrs) { scope.dimensions = { maxWidth: attrs.width + 'px', height: attrs.height || 350 }; scope.items = element.find('lj-gallery-item').map(function(){ var image = angular.element(this).find('img'), link = angular.element(this).find('a'), capture = angular.element(this).find('lj-gallery-item-capture'); return { content: capture.html(), src: image.attr('src'), href: link.attr('href') }; }).toArray(); scope.isTall = ( typeof attrs.tall !== 'undefined' ); scope.next = function () { scope.state.index += 1; }; scope.prev = function () { scope.state.index -= 1; }; scope.state = { index: 0, total: scope.items.length - 1 }; scope.isNearby = function (index) { return Math.abs(scope.state.index - index) <= 1; }; // replace existed content with our template element.html( $compile( $templateCache.get('ljGallery.ng.tmpl') )(scope) ); } }; }]) .directive('ljSuggest', ['Api', function (Api) { return { templateUrl: 'ljSuggest.ng.tmpl', scope: { itemId: '@ljSuggest' }, link: function (scope) { Api.call('discovery.suggest', { itemid: scope.itemId }, {cache: true}) .then(function (response) { scope.suggest = response.items; }); } }; }]) .directive('ljWidgetAuthorsPosts', ['Api', function (Api) { return { templateUrl: 'posts.ng.tmpl', scope: { userId: '@ljWidgetAuthorsPosts', itemId: '@ljWidgetAuthorsPostsExclude' }, link: function (scope) { scope.state = { isLoading: true }; Api.call('discovery.author_posts', { itemid: scope.itemId, userid: scope.userId }, { cache: true }).then(function (response) { scope.state.isLoading = false; scope.posts = response.items; }); } }; }]); ; /* file-end: js/discovery/directives.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/core/angular/ljMemories.js */ Site.page.template['angular/memories.ng.tmpl'] = '
\n\n \n\n \n \n\n \n

\n \n \n

\n\n \n
    \n\n
  • \n \n
  • \n\n
  • \n \n
  • \n\n
  • \n \n
  • \n\n
\n\n \n \n \n \n
\n \n \n\n

\n \n

\n\n \n\n\n'; LJ.injectStyle('/* LJSUP-17006: [S1 entry, memories] Popup in S1 entries */\n/* Add to Memories */\n\n.b-addtomemories {\n width: 150px;\n margin: 0;\n padding: 0;\n }\n .b-addtomemories-head {\n margin: 0 0 0.5em;\n padding: 0;\n font: bold 1.13em/1.1 Arial,sans-serif;\n color: #000;\n }\n .b-addtomemories-intro {\n margin: 0 0 0.3em;\n }\n .b-addtomemories-items {\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .b-addtomemories-item {\n margin: 0;\n padding: 0;\n }\n .b-addtomemories-label {\n display: block;\n margin: 0 -5px;\n padding: 5px;\n cursor: pointer;\n }\n .b-addtomemories-item:hover .b-addtomemories-label {\n background: #C8E6FF;\n }\n .b-addtomemories-footer {\n margin: 1em 0;\n }\n /* hide old-design button on schemius and show new one (LJSUP-19209) */\n .b-addtomemories-footer .b-ljbutton {\n display: inline-block;\n }\n .b-addtomemories-footer .b-flatbutton {\n display: none;\n }\n .s-schemius .b-addtomemories-footer .b-ljbutton {\n display: none;\n }\n .s-schemius .b-addtomemories-footer .b-flatbutton {\n display: inline-block;\n }\n .b-addtomemories-options {\n margin: 0.3em -5px 0;\n padding: 0.3em 5px 0;\n border-top: 1px solid #DAE3E6;\n }\n.b-addtomemories-loading {\n background: url(/img/preloader/preloader-blue-gray.gif?v=16423) no-repeat 50% 50%;\n }\n .b-addtomemories-loading .b-addtomemories-head,\n .b-addtomemories-loading .b-addtomemories-intro,\n .b-addtomemories-loading .b-addtomemories-items,\n .b-addtomemories-loading .b-addtomemories-footer,\n .b-addtomemories-loading .b-addtomemories-options {\n visibility: hidden;\n }\n\n'); (function($) { angular.module('LJ.Memories', ['LJ.Bubble', 'LJ.Api']) /** * Directive build memories popup * * Usage: * * * * or * * * * * @authors * Georgii Kats (g.kats@sup.com) */ .directive('ljMemories', ['$parse', '$timeout', 'Bubble', function ($parse, $timeout, Bubble) { return { scope: { ljMemories: '&' }, link: function (scope, element) { var options; function clickHandler (event) { event.preventDefault(); if ( !options ) { options = ( typeof scope.ljMemories === 'function' ) ? scope.ljMemories({ element: element }) : scope.ljMemories; } Bubble.open('memories', options, $(element)); scope.$apply(); } element.on('click', clickHandler); scope.$on('$destroy', function () { element.off('click', clickHandler); }); } }; }]) .controller('MemoriesCtrl', ['$scope', 'Api', function( $scope , Api ) { var bubble = $scope.bubble; $scope.security = null; // bubble size could change because of button, reposition $scope.$watch('removeButton', function() { $(window).trigger('resize'); }); $scope.$on('bubble:open:memories', function() { Api.call('memories.get', bubble.options, function(result) { $scope.security = result.result ? result.result.security : null; $scope.removeButton = Boolean($scope.security); }); }); $scope.$on('bubble:close:memories', function() { $scope.removeButton = false; }); $scope.siteroot = LJ.get('siteroot'); $scope.update = function() { Api.call('memories.set', { journal: bubble.options.journal, ditemid: bubble.options.ditemid, description: bubble.options.journal + ': ' + bubble.options.title, security: $scope.security }, function(result) { $scope.security = result; bubble.close(); $scope.removeButton = true; }); }; $scope.remove = function() { Api.call('memories.remove', { journal: bubble.options.journal, ditemid: bubble.options.ditemid }, function() { $scope.security = null; bubble.close(); $scope.removeButton = false; }); }; LJ.Event.on('api:request:change', function(method, state) { if (/^memories/.test(method)) { $scope.loading = state; } }); }]); })(jQuery); ; /* file-end: js/core/angular/ljMemories.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/core/angular/share.js */ /* --------------------------------------------------------------------------------- file-start: js/core/string.js */ ;(function () { 'use strict'; LJ.define('LJ.String'); /** * Add leading zeros to number until it will have correct length * @param {*} str Any string or value that will be stringified * @param {Number} length Needed length * @param {String} symbol Symbol for padding * @return {String} Padded value * * @example * var padded = LJ.string.pad('hello', 8, ' '); // => ' hello'; */ LJ.String.pad = function (str, length, symbol) { str = str.toString(); if (typeof length === 'undefined') { throw new Error('You should provide padding string length'); } if (typeof symbol === 'undefined') { throw new Error('You should provide padding symbol'); } if (str.length >= length) { return str; } while (str.length < length) { str = symbol + str; } return str.length === length ? str : str.slice(-length); }; /** * Capitalize string * @param {String} str String to be capitalized * @return {String} Capitalized string * * @example * LJ.String.capitalize('HELLO'); // => "Hello" */ LJ.String.capitalize = function (str) { var length; if (typeof str !== 'string') { throw new Error('You should provide string as argument'); } length = str.length; if (length === 0) { return str; } else if (length === 1) { return str.toUpperCase(); } else { return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); } }; /** * Add http:// if not present * @param {String} str Input string * * @return {String} Link with default protocol (http://) if needed */ LJ.String.linkify = function(str) { var rxLink = new RegExp('^(?:([a-zA-Z]+):)?//'), alternative = /^[a-zA-Z]+:/, // mailto: rxEmptyProtocol = /^:\/\//; // ://yandex.ru var defaultProtocol = alternative.test(str) ? '' : 'http://'; return rxLink.test(str) ? str : defaultProtocol + (rxEmptyProtocol.test(str) ? str.replace('://', '') : str); }; /** * Split by char(s), trim all values, remove empty elements * * @param {String} str String to split * @param {String} separator Separator to use for splitting * @return {Array} Array of splitted values */ LJ.String.smartSplit = function(str, separator) { if (typeof separator === 'undefined') { separator = ','; } return str.split(separator).map(function(item) { return item.trim(); }).filter(Boolean); }; LJ.String.encodeHTML = function(str) { var encodeMap = { '<': '<', '>': '>', '"': '"', '\'': ''' }; return str.replace(/([<>&\"\'])/g, function(m, c) { return encodeMap[c] ? encodeMap[c] : c; }); }; }()); ; /* file-end: js/core/string.js ----------------------------------------------------------------------------------*/ Site.page.template['angular/share.ng.tmpl'] = '

\n\n\n \n \n \n\n'; //= require_ml sharing.popup.title ;(function () { 'use strict'; /** * Options: * [lj-share-scrollable] - position of bubble will be recalculated on scroll if provided. * It's actual bubble setting - `recalculateOnScroll` * [lj-share-services] - services to show. If not provided - services from server config will be shown * [lj-share-services-exclude] - exclude services from bubble * * * @example * Share me */ angular.module('LJ.Share', [ 'LJ.Directives', 'LJ.Templates', 'LJ.Bubble' ]) .directive('ljShare', ['Bubble', function (Bubble) { return { restrict: 'A', scope: true, link: function ($scope, element, $attrs) { var params = $scope.$eval( $attrs.ljShare ); // string with comma separated services to show in the bubble var services = $scope.$eval( $attrs.ljShareServices ); // string with comma separated services to exclude from bubble var exclude = $scope.$eval( $attrs.ljShareServicesExclude ); services = services ? LJ.String.smartSplit( services ) : LJ.Social.Share.services(); exclude = exclude ? LJ.String.smartSplit( exclude ) : []; if ( exclude.length ) { services = services.filter(function (service) { return exclude.indexOf(service) === -1; }); } function share() { Bubble.open('share', { params: params, services: services }, element); $scope.$apply(); } // no services to show - do nothing if ( !services.length ) { return; } var unregisterBubble = Bubble.register({ name: 'share', template: 'share.ng.tmpl', recalculateOnScroll: $attrs.hasOwnProperty('ljShareScrollable') }); element.on('click', share); $scope.$on('$destroy', function () { element.off('click', share); unregisterBubble(); }); } }; }]) .controller('ShareBubbleCtrl', ['$scope', 'Bubble', function ($scope, Bubble) { var that = this; $scope.$on('bubble:open:share', function() { that.services = $scope.bubble.options.services.map(function(service) { return { name: service, link: LJ.Social.Share.getUrl(service, $scope.bubble.options.params), title: LJ.Social.Share.getTitle(service) }; }); }); that.openPopup = function(event, service, params) { if ( LJ.Social.Share.isTab(service) ) { Bubble.close('share'); return; } event.preventDefault(); LJ.Social.Share.openPopup(service, params); Bubble.close('share'); }; }]); }()); ; /* file-end: js/core/angular/share.js ----------------------------------------------------------------------------------*/ ;(function ($) { 'use strict'; angular.module('S2Layout', ['Discovery.Tags', 'LJ.Memories', 'LJ.Share']) // HTML5 mode is on to keep anchor links working // by LJSV-2932 .run(function () { // fix html5mode $('a:not([target])').attr('target', '_self'); }) .config(['$locationProvider', function($locationProvider) { $locationProvider.html5Mode(true); }]); LJ.Event.on('page_load', function() { var sidebarCalendar = $('.sidebar-cal'); /* Nothing to do if widget was not loaded */ if ( !$.fn.hasOwnProperty('inlineCalendar') ) { return; } // inline calendar could not be available for the style sidebarCalendar .inlineCalendar( { selectors: { month: '.sbar-cal-nav-month', year: '.sbar-cal-nav-year', prevMonth: '.sbar-cal-nav-month .sbar-cal-nav-prev', nextMonth: '.sbar-cal-nav-month .sbar-cal-nav-next', prevYear: '.sbar-cal-nav-year .sbar-cal-nav-prev', nextYear: '.sbar-cal-nav-year .sbar-cal-nav-next', monthLabel: '.sbar-cal-nav-month .sbar-cal-month', yearLabel: '.sbar-cal-nav-year .sbar-cal-year' }, classNames: { current : 'today', nextDisabled : 'disabled', prevDisabled : 'disabled' }, dayRef: LJ.get('currentJournalBase') + '/%Y/%M/%D', monthRef: LJ.get('currentJournalBase') + '/%Y/%M', yearRef: LJ.get('currentJournalBase') + '/%Y', endMonth: new Date(), startAtSunday: true }).on('daySelected', function (event) { event.preventDefault(); }); // calendar events should be available if ( $.fn.hasOwnProperty('calendarEvents') ) { sidebarCalendar.calendarEvents({ calendarType: 'inlineCalendar' }); } }); LJ.Event.on('page_load', function () { var className = 'hover', tabElements = $('.sidebar dl'), tabHeaders = $('.sidebar dt'), preventClose = false; if ($('.sidebar-friendstimes').length === 0) { return; } if (LJ.Support.touch) { tabHeaders.on('touchstart', function () { $(this).parent() .toggleClass(className) .siblings() .removeClass(className); }); tabElements.on('touchstart', function () { preventClose = true; }); $(document).on('touchstart', function () { if (preventClose) { preventClose = false; } else { tabElements.removeClass(className); } }); } else { tabElements.on({ mouseenter: function () { $(this).addClass('hover'); }, mouseleave: function () { $(this).removeClass('hover'); } }); } }); // S2 comments LJ.Event.on('page_load', function () { if (LJ.get('LJ_cmtinfo')) { window.LJ_cmtinfo = LJ.get('LJ_cmtinfo'); } if ($.fn.subjecticons) { $('.b-subjecticons').subjecticons(); } if ($.fn.commentator && $.fn.authtype && $.fn.quotescreator) { $('#postform-wrapper') .commentator({ publicKey: LJ.get('captcha_public'), captchaContainerId: 'captcha-container' }) .authtype({ forceStartupCaptcha: !!(Number(LJ.get('need_captcha'))), selectors: { authTypeRadios: '.b-postform-login-{authType} .b-postform-login-radio' } }) .quotescreator(); } if ($.fn.placeholder) { $('#cookieusername').placeholder(); } // Scroll to top $(document.body).on('click', '[data-s2-helper-scrollTop]', function(event) { event.preventDefault(); $('body,html').animate({ scrollTop: 0 }, 500); }); }); $(function () { // Switch to new feed version on /friends // Notice: code below is only needed for old friends feed that // relies on S2 and hasn't it's own JS file $('body').on('click', '.b-lenta-msg-close', function (e) { e.preventDefault(); LJ.Api.call('friendsfeed.close_friendsfeed_line', {}, function () { $('.b-lenta-msg').remove(); $('body').addClass('b-lenta-msg-hidden'); }); }); }); }(jQuery)); ; /* file-end: js/s2.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/esn.js */ /* --------------------------------------------------------------------------------- file-start: js/lj_ippu.js */ /* --------------------------------------------------------------------------------- file-start: js/deprecated/dom.js */ /** * All deprecated manipulations with the DOM will be here */ // handy utilities to create elements with just text in them function _textSpan() { return _textElements('span', arguments); } function _textDiv() { return _textElements('div', arguments); } function _textElements(eleType, txts) { var ele = []; for (var i = 0; i < txts.length; i++) { var node = document.createElement(eleType); node.innerHTML = txts[i]; ele.push(node); } return ele.length == 1 ? ele[0] : ele; } ; /* file-end: js/deprecated/dom.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/ippu.js */ function changeOpac(a,b){var c=$(a);if(c&&c.style){var d=c.style;d&&(IPPU.isSafari()&&b>=100&&(b=99.99),d.filters&&(d.filters.alpha.opacity=100*b),d.opacity=b)}}IPPU=new Class(Object,{setFixedPosition:function(a){IPPU.isIE()||(this.fixedPosition=a,this.updateContent())},clickHandler:function(a){if(this.clickToClose&&this.visible()){a=Event.prep(a);var b=a.target;DOM.getAncestorsByClassName(b,"ippu",!0).length>0||this.cancel()}},setCancelledCallback:function(a){this.cancelledCallback=a},cancel:function(){this.cancelledCallback&&this.cancelledCallback(),this.hide()},setHiddenCallback:function(a){this.hiddenCallback=a},setupClickCapture:function(){if(this.visible()&&!this.clickHandlerSetup&&(this.clickToClose||this.modal)){if(this.clickHandlerFunc=this.clickHandler.bindEventListener(this),this.modal){if(this.overlay)return;this.overlay=document.createElement("div"),this.overlay.style.left="0px",this.overlay.style.top="0px",this.overlay.style.margin="0px",this.overlay.style.padding="0px",this.overlay.style.backgroundColor="#000000",this.overlay.style.zIndex="900",IPPU.isIE()?(this.overlay.style.filter="progid:DXImageTransform.Microsoft.Alpha(opacity=50)",this.overlay.style.position="absolute",this.overlay.style.width=document.body.scrollWidth,this.overlay.style.height=document.body.scrollHeight):this.overlay.style.position="fixed",this.ele.parentNode.insertBefore(this.overlay,this.ele),this.updateOverlay(),DOM.addEventListener(this.overlay,"click",this.clickHandlerFunc)}else DOM.addEventListener(document,"click",this.clickHandlerFunc);this.clickHandlerSetup=!0}},updateOverlay:function(){if(this.overlay){var a=DOM.getClientDimensions();this.overlay.style.width=a.x-1+"px",IPPU.isIE()||(this.overlay.style.height=a.y-1+"px"),this.visibleOverlay?(this.overlay.backgroundColor="#000000",changeOpac(this.overlay,.5)):(this.overlay.backgroundColor="#FFFFFF",changeOpac(this.overlay,0))}},resizeHandler:function(){this.updateContent()},removeClickHandlers:function(){if(this.clickHandlerSetup){DOM.removeEventListener(document,"click",this.clickHandlerFunc,!1),this.overlay&&(DOM.removeEventListener(this.overlay,"click",this.clickHandlerFunc,!0),this.overlay.parentNode.removeChild(this.overlay),this.overlay=void 0),this.clickHandlerFunc=void 0,this.clickHandlerSetup=!1}},setClickToClose:function(a){if(this.clickToClose=a,!this.clickHandlerSetup&&a&&this.visible()){var b=this.setupClickCapture.bind(this);window.setTimeout(b,100)}else!a&&this.clickHandlerSetup&&this.removeClickHandlers();this.updateContent()},setModal:function(a){var b=this.modal==a;a&&this.setClickToClose(!1),this.modal=a,b&&(this.removeClickHandlers(),this.updateContent())},setOverlayVisible:function(a){this.visibleOverlay=a,this.updateContent()},updateContent:function(){this.autoCenter(),this.updateTitlebar(),this.updateOverlay(),this.titlebar&&this.setTitlebarClass(this.titlebar.className);var a=this.setupClickCapture.bind(this);window.setTimeout(a,100),this.fixedPosition&&"fixed"!=this.ele.style.position?this.ele.style.position="fixed":this.fixedPosition||"fixed"!=this.ele.style.position||(this.ele.style.position="absolute")},getTitlebarElement:function(){return this.titlebar},setTitlebarClass:function(a){this.titlebar&&(this.titlebar.className=a)},setOverflow:function(a){this.ele&&(this.ele.style.overflow=a)},visible:function(){return this.shown},setTitlebar:function(a){if(this.showTitlebar=a,a){if(!this.titlebar){var b=document.createElement("div");if(!b)return;b.style.width="100%",this.title&&(b.innerHTML=this.title),this.ele.insertBefore(b,this.content),this.titlebar=b}}else this.titlebar&&(this.ele.removeChild(this.titlebar),this.titlebar=!1)},setTitle:function(a){this.title=a,this.updateTitlebar()},updateTitlebar:function(){this.showTitlebar&&this.titlebar&&this.title!=this.titlebar.innerHTML&&(this.titlebar.innerHTML=this.title)},addClass:function(a){DOM.addClassName(this.ele,a)},removeClass:function(a){DOM.removeClassName(this.ele,a)},setAutoCenterCallback:function(a){this.autoCenterCallback=a},autoCenter:function(){if(this.visible&&this.visible()){if(this.autoCenterCallback)return void this.autoCenterCallback(this);this.autoCenterX&&this.centerX(),this.autoCenterY&&this.centerY()}},center:function(){this.centerX(),this.centerY()},centerOnWidget:function(a,b,c){b=b||0,c=c||0,this.setAutoCenter(!1,!1),this.setAutoCenterCallback(null);var d=DOM.getAbsoluteDimensions(a),e=DOM.getAbsoluteDimensions(this.ele),f=d.absoluteRight-d.offsetWidth/2-e.offsetWidth/2+c,g=d.absoluteBottom-d.offsetHeight/2-e.offsetHeight/2+b;f=0>f?0:f,g=0>g?0:g,DOM.setLeft(this.ele,f),DOM.setTop(this.ele,g)},centerX:function(){if(this.visible&&this.visible()){var a=DOM.getClientDimensions(),b=a.x/2-this.ele.offsetWidth/2;if(!this.fixedPosition){var c=DOM.getWindowScroll();b+=c.left}DOM.setLeft(this.ele,b)}},centerY:function(){if(this.visible&&this.visible()){var a=DOM.getClientDimensions(),b=a.y/2-this.ele.offsetHeight/2;if(!this.fixedPosition){var c=DOM.getWindowScroll();b+=c.top}DOM.setTop(this.ele,b)}},setAutoCenter:function(a,b){return this.autoCenterX=a||!1,this.autoCenterY=b||!1,a||b?void this.autoCenter():void this.setAutoCenterCallback(null)},setDimensions:function(a,b){a+="",b+="",a.match(/^\d+$/)&&(a+="px"),b.match(/^\d+$/)&&(b+="px"),this.ele.style.width=a,this.ele.style.height=b},moveForward:function(a){a||(a=1),this.ele&&(this.ele.style.zIndex+=a)},moveBackward:function(a){a||(a=1),this.ele&&(this.ele.style.zIndex-=a)},setLocation:function(a,b){this.setLeft(a),this.setTop(b)},setTop:function(a){"string"!=typeof a&&(a+="px"),this.ele.style.top=a},setLeft:function(a){"string"!=typeof a&&(a+="px"),this.ele.style.left=a},getElement:function(){return this.ele},setContent:function(a){this.content.innerHTML=a},setContentElement:function(a){for(;this.content.firstChild;)this.content.removeChild(this.content.firstChild);this.content.appendChild(a)},setFadeIn:function(a){this.fadeIn=a},setFadeOut:function(a){this.fadeOut=a},setFadeSpeed:function(a){this.fadeSpeed=a},show:function(){if(this.shown=!0,this.fadeIn){var a=.01;changeOpac(this.ele,a)}document.body.appendChild(this.ele),this.ele.style.position="absolute",(this.autoCenterX||this.autoCenterY)&&this.center(),this.updateContent(),this.resizeHandlerFunc||(this.resizeHandlerFunc=this.resizeHandler.bindEventListener(this),DOM.addEventListener(window,"resize",this.resizeHandlerFunc,!1)),this.fadeIn&&this.fade("in"),this.hideSelects()},fade:function(a,b){var c,d,e=10;"in"==a?(d=1/e,c=.1):(c=this.ele.style.opacity?finiteFloat(this.ele.style.opacity):.99,d=-1/e);var f=this.fadeSpeed;f||(f=1);var g=e/f*5;this.fadeMode=a;var h=this,i=function(){return c+=d,h.fadeMode&&h.fadeMode!=a?void(b&&b.call(h,[])):.1>=c?(b&&b.call(h,[]),void(h.fadeMode=null)):c>=1?(b&&b.call(h,[]),void(h.fadeMode=null)):(changeOpac(h.ele,c),void window.setTimeout(i,g))};i()},hide:function(){this.visible()&&(this.fadeOut&&this.ele?this.fade("out",this._hide.bind(this)):this._hide())},_hide:function(){this.hiddenCallback&&this.hiddenCallback(),this.shown=!1,this.removeClickHandlers(),this.ele&&document.body.removeChild(this.ele),this.resizeHandlerFunc&&DOM.removeEventListener(window,"resize",this.resizeHandlerFunc),this.showSelects()},setAutoHideSelects:function(a){this.autoHideSelects=a,this.updateContent()},hideSelects:function(){if(this.autoHideSelects&&IPPU.isIE())for(var a,b=document.getElementsByTagName("select"),c=0;c0||"hidden"!=a.style.visibility&&(a.style.visibility="hidden",this.hiddenSelects.push(a)))},showSelects:function(){if(this.autoHideSelects)for(var a;a=this.hiddenSelects.pop();)a.style.visibility=""},init:function(a){var b=document.createElement("div");this.ele=b,this.shown=!1,this.autoCenterX=!1,this.autoCenterY=!1,this.titlebar=null,this.title="",this.showTitlebar=!1,this.clickToClose=!1,this.modal=!1,this.clickHandlerSetup=!1,this.docOverlay=!1,this.visibleOverlay=!1,this.clickHandlerFunc=!1,this.resizeHandlerFunc=!1,this.fixedPosition=!1,this.autoCenterCallback=null,this.cancelledCallback=null,this.autoHideSelects=!1,this.hiddenCallback=null,this.fadeOut=!1,this.fadeIn=!1,this.hiddenSelects=[],this.fadeMode=null,b.style.position="absolute",b.style.top=0,b.style.zIndex="1000",DOM.addClassName(b,"ippu"),this.content=document.createElement("div"),this.content.innerHTML=a,this.ele.appendChild(this.content)}}),IPPU.center=function(a){a.centerX(),a.centerY()},IPPU.centerX=function(a){a.centerX()},IPPU.centerY=function(a){a.centerY()},IPPU.isIE=function(){var a=navigator.userAgent.toLowerCase();return-1!=a.indexOf("msie")?!0:!1},IPPU.isSafari=function(){var a=navigator.userAgent.toLowerCase();return-1!=a.indexOf("safari")?!0:!1};; /* file-end: js/ippu.js ----------------------------------------------------------------------------------*/ LJ_IPPU = new Class ( IPPU, { init: function(title) { if (!title) title = ""; LJ_IPPU.superClass.init.apply(this, []); this.uniqId = this.generateUniqId(); this.cancelThisFunc = this.cancel.bind(this); this.setTitle(title); this.setTitlebar(true); this.setTitlebarClass("lj_ippu_titlebar"); this.addClass("lj_ippu"); this.setAutoCenterCallback(IPPU.center); this.setDimensions(514, "auto"); //this.setOverflow("hidden"); this.setFixedPosition(true); this.setClickToClose(true); this.setAutoHideSelects(true); }, setTitle: function (title) { var titlebarContent = "\
" + "
" + title; LJ_IPPU.superClass.setTitle.apply(this, [titlebarContent]); }, generateUniqId: function() { var theDate = new Date(); return "lj_ippu_" + theDate.getHours() + theDate.getMinutes() + theDate.getMilliseconds(); }, show: function() { LJ_IPPU.superClass.show.apply(this); var setupCallback = this.setup_lj_ippu.bind(this); this.timerSetup = window.setTimeout(setupCallback, 300); }, setup_lj_ippu: function (evt) { var cancelCallback = this.cancelThisFunc; $(this.uniqId + "_cancel").onclick = function(){ cancelCallback(); }; }, hide: function() { clearInterval(this.timerSetup); LJ_IPPU.superClass.hide.apply(this); } } ); // Class method to show a popup to show a note to the user // note = message to show // underele = element to display the note underneath LJ_IPPU.showNote = function (note, underele, timeout, style) { var noteElement = document.createElement("div"); noteElement.innerHTML = note; return LJ_IPPU.showNoteElement(noteElement, underele, timeout, style); }; LJ_IPPU.showErrorNote = function (note, underele, timeout) { return LJ_IPPU.showNote(note, underele, timeout, "ErrorNote"); }; LJ_IPPU.showNoteElement = function (noteEle, underele, timeout, style) { var notePopup = new IPPU(); notePopup.init(); var inner = document.createElement("div"); DOM.addClassName(inner, "Inner"); inner.appendChild(noteEle); notePopup.setContentElement(inner); notePopup.setTitlebar(false); notePopup.setFadeIn(true); notePopup.setFadeOut(true); notePopup.setFadeSpeed(4); notePopup.setDimensions("auto", "auto"); if (!style) style = "Note"; notePopup.addClass(style); var dim; if (underele) { // pop up the box right under the element dim = DOM.getAbsoluteDimensions(underele); if (!dim) return; } var bounds = DOM.getClientDimensions(); if (!bounds) return; if (!dim) { // no element specified to pop up on, show in the middle // notePopup.setModal(true); // notePopup.setOverlayVisible(true); notePopup.setAutoCenter(true, true); notePopup.show(); } else { // default is to auto-center, don't want that notePopup.setAutoCenter(false, false); notePopup.setLocation(dim.absoluteLeft, dim.absoluteBottom + 4); notePopup.show(); var popupBounds = DOM.getAbsoluteDimensions(notePopup.getElement()); if (popupBounds.absoluteRight > bounds.x) { notePopup.setLocation(bounds.x - popupBounds.offsetWidth - 30, dim.absoluteBottom + 4); } } notePopup.setClickToClose(true); notePopup.moveForward(); if (timeout === undefined) { timeout = 5000; } if (timeout) { window.setTimeout(function () { if (notePopup) notePopup.hide(); }, timeout); } return notePopup; }; LJ_IPPU.textPrompt = function (title, prompt, callback, options) { options = options || {}; title += ''; var notePopup = new LJ_IPPU(title); var inner = document.createElement("div"); DOM.addClassName(inner, "ljippu_textprompt"); // label if (prompt) inner.appendChild(_textDiv(prompt)); // text field var field = document.createElement("textarea"); DOM.addClassName(field, "htmlfield"); field.cols = 40; field.rows = 5; inner.appendChild(field); // submit btn var btncont = document.createElement("div"); DOM.addClassName(btncont, "submitbtncontainer"); var btn = document.createElement("input"); DOM.addClassName(btn, "submitbtn"); btn.type = "button"; btn.value = "Insert"; btncont.appendChild(btn); inner.appendChild(btncont); notePopup.setContentElement(inner); notePopup.setAutoCenter(true, true); notePopup.setDimensions(options.width || "60%", "auto"); notePopup.show(); field.focus(); DOM.addEventListener(btn, "click", function (e) { notePopup.hide(); if (callback) callback.apply(null, [field.value]); }); } ; /* file-end: js/lj_ippu.js ----------------------------------------------------------------------------------*/ var ESN = {}; (function ($, ESN) { // When page loads, set up "check all" checkboxes ESN.initCheckAllBtns = function () { var ntids = $("ntypeids"); var catids = $("catids"); if (!ntids || !catids) return; ntidList = ntids.value; catidList = catids.value; if (!ntidList || !catidList) return; ntids = ntidList.split(","); catids = catidList.split(","); catids.forEach( function (catid) { ntids.forEach( function (ntypeid) { var className = "SubscribeCheckbox-" + catid + "-" + ntypeid; var cab = new CheckallButton(); cab.init({ "class": className, "button": $("CheckAll-" + catid + "-" + ntypeid), "parent": $("CategoryRow-" + catid) }); }); }); } // attach event handlers to all track buttons ESN.initTrackBtns = function (node) { // don't do anything if no remote if ( !LJ.get('remote') ) { return; } node = node || document; var trackBtns = DOM.getElementsByTagAndClassName(node, 'img', 'TrackButton'); trackBtns.forEach(function (trackBtn) { if (!trackBtn || !trackBtn.getAttribute) return; if (!trackBtn.getAttribute("lj_subid") && !trackBtn.getAttribute("lj_journalid")) return; if (trackBtn.getAttribute("lj_dtalkid") && !LJ.get('remote_can_track_threads') ) return; DOM.addEventListener(trackBtn, 'click', ESN.trackBtnClickHandler.bindEventListener(trackBtn)); }); }; ESN.trackBtnClickHandler = function (evt) { var trackBtn = evt.target; if (! trackBtn || trackBtn.tagName.toLowerCase() != "img") return true; Event.stop(evt); var btnInfo = {}; ['arg1', 'arg2', 'etypeid', 'newentry_etypeid', 'newentry_token', 'newentry_subid', 'journalid', 'subid', 'auth_token'].forEach(function (arg) { btnInfo[arg] = trackBtn.getAttribute("lj_" + arg); }); // pop up little dialog to either track by inbox/email or go to more options var dlg = document.createElement("div"); var title = _textDiv("Email me when"); DOM.addClassName(title, "track_title"); dlg.appendChild(title); var TrackCheckbox = function (title, checked) { var checkContainer = document.createElement("div"); var newCheckbox = document.createElement("input"); newCheckbox.type = "checkbox"; newCheckbox.id = "newentrytrack" + Unique.id(); var newCheckboxLabel = document.createElement("label"); newCheckboxLabel.setAttribute("for", newCheckbox.id); newCheckboxLabel.innerHTML = title; checkContainer.appendChild(newCheckbox); checkContainer.appendChild(newCheckboxLabel); dlg.appendChild(checkContainer); newCheckbox.checked = checked ? true : false; return newCheckbox; }; // global trackPopup so we can only have one if (ESN.trackPopup) { ESN.trackPopup.hide(); ESN.trackPopup = null; } var saveChangesBtn = document.createElement("input"); saveChangesBtn.type = "button"; saveChangesBtn.value = "Save Changes"; DOM.addClassName(saveChangesBtn, "track_savechanges"); var trackingNewEntries = Number(btnInfo['newentry_subid']) ? 1 : 0; var trackingNewComments = Number(btnInfo['subid']) ? 1 : 0; var newEntryTrackBtn; var commentsTrackBtn; if (trackBtn.getAttribute("lj_dtalkid")) { // this is a thread tracking button // always checked: either because they're subscribed, or because // they're going to subscribe. commentsTrackBtn = TrackCheckbox("someone replies in this comment thread", 1); } else { // entry tracking button newEntryTrackBtn = TrackCheckbox(trackBtn.getAttribute('lj_username') + ' posts a new entry', trackingNewEntries); commentsTrackBtn = TrackCheckbox("someone comments on this post", trackingNewComments); } DOM.addEventListener(saveChangesBtn, "click", function () { ESN.toggleSubscriptions(btnInfo, evt, trackBtn, { newEntry: newEntryTrackBtn ? newEntryTrackBtn.checked : false, newComments: commentsTrackBtn.checked }); if (ESN.trackPopup) ESN.trackPopup.hide(); }); var btnsContainer = document.createElement("div"); DOM.addClassName(btnsContainer, "track_btncontainer"); dlg.appendChild(btnsContainer); btnsContainer.appendChild(saveChangesBtn); var custTrackLink = document.createElement("a"); custTrackLink.href = trackBtn.parentNode.href; btnsContainer.appendChild(custTrackLink); custTrackLink.innerHTML = "More Options"; DOM.addClassName(custTrackLink, "track_moreopts"); ESN.trackPopup = new LJ_IPPU.showNoteElement(dlg, trackBtn, 0); DOM.addEventListener(custTrackLink, "click", function (evt) { Event.stop(evt); document.location.href = trackBtn.parentNode.href; if (ESN.trackPopup) ESN.trackPopup.hide(); return false; }); return false; } // toggles subscriptions ESN.toggleSubscriptions = function (subInfo, evt, btn, subs) { subInfo["subid"] = Number(subInfo["subid"]); if ((subInfo["subid"] && ! subs["newComments"]) || (! subInfo["subid"] && subs["newComments"])) { ESN.toggleSubscription(subInfo, evt, btn, "newComments"); } subInfo["newentry_subid"] = Number(subInfo["newentry_subid"]); if ((subInfo["newentry_subid"] && ! subs["newEntry"]) || (! subInfo["newentry_subid"] && subs["newEntry"])) { var newentrySubInfo = new Object(subInfo); newentrySubInfo["subid"] = Number(btn.getAttribute("lj_newentry_subid")); ESN.toggleSubscription(newentrySubInfo, evt, btn, "newEntry"); } }; // (Un)subscribes to an event ESN.toggleSubscription = function (subInfo, evt, btn, sub) { var action = ""; var params = { auth_token: sub == "newEntry" ? subInfo.newentry_token : subInfo.auth_token }; if (Number(subInfo.subid)) { // subscription exists action = "delsub"; params.subid = subInfo.subid; } else { // create a new subscription action = "addsub"; var param_keys; if (sub == "newEntry") { params.etypeid = subInfo.newentry_etypeid; param_keys = ["journalid"]; } else { param_keys = ["journalid", "arg1", "arg2", "etypeid"]; } param_keys.forEach(function (param) { if (Number(subInfo[param])) params[param] = parseInt(subInfo[param]); }); } params.action = action; var reqInfo = { "method": "POST", "url": LiveJournal.getAjaxUrl('esn_subs'), "data": HTTPReq.formEncoded(params) }; var gotInfoCallback = function (info) { if (! info) return LJ_IPPU.showNote("Error changing subscription", btn); if (info.error) return LJ_IPPU.showNote(info.error, btn); if (info.success) { if (info.msg) LJ_IPPU.showNote(info.msg, btn); if (info.subscribed) { if (info.subid) btn.setAttribute('lj_subid', info.subid); if (info.newentry_subid) btn.setAttribute('lj_newentry_subid', info.newentry_subid); btn.setAttribute('title', 'Untrack This'); // update subthread tracking icons var dtalkid = btn.getAttribute("lj_dtalkid"); if (dtalkid) ESN.updateThreadIcons(dtalkid, "on"); else // not thread tracking button btn.src = LJ.get('imgprefix') + "/btn_tracking.gif?v=17312"; } else { if (info["event_class"] == "LJ::Event::JournalNewComment") btn.setAttribute('lj_subid', 0); else if (info["event_class"] == "LJ::Event::JournalNewEntry") btn.setAttribute('lj_newentry_subid', 0); btn.setAttribute('title', 'Track This'); // update subthread tracking icons var dtalkid = btn.getAttribute("lj_dtalkid"); if (dtalkid) { // set state to "off" if no parents tracking this, // otherwise set state to "parent" var state = "off"; var parentBtn; var parent_dtalkid = dtalkid; while (parentBtn = ESN.getThreadParentBtn(parent_dtalkid)) { parent_dtalkid = parentBtn.getAttribute("lj_dtalkid"); if (! parent_dtalkid) { break; } if (! Number(parentBtn.getAttribute("lj_subid"))) continue; state = "parent"; break; } ESN.updateThreadIcons(dtalkid, state); } else { // not thread tracking button btn.src = LJ.get('imgprefix') + "/btn_track.gif?v=17312"; } } if (info.auth_token) btn.setAttribute('lj_auth_token', info.auth_token); if (info.newentry_token) btn.setAttribute('lj_newentry_token', info.newentry_token); } }; reqInfo.onData = gotInfoCallback; reqInfo.onError = function (err) { LJ_IPPU.showNote("Error: " + err) }; HTTPReq.getJSON(reqInfo); }; // given a dtalkid, find the track button for its parent comment (if any) ESN.getThreadParentBtn = function (dtalkid) { var cmtInfo = LJ_cmtinfo[dtalkid + ""]; if (! cmtInfo) { return null; } var parent_dtalkid = cmtInfo.parent; if (! parent_dtalkid) return null; return $("lj_track_btn_" + parent_dtalkid); }; // update all the tracking icons under a parent comment ESN.updateThreadIcons = function (dtalkid, tracking) { var btn = $("lj_track_btn_" + dtalkid); if (! btn) { return; } var cmtInfo = LJ_cmtinfo[dtalkid + ""]; if (! cmtInfo) { return; } if (Number(btn.getAttribute("lj_subid")) && tracking != "on") { // subscription already exists on this button, don't mess with it return; } if (cmtInfo.rc && cmtInfo.rc.length) { // update children cmtInfo.rc.forEach(function (child_dtalkid) { window.setTimeout(function () { var state; switch (tracking) { case "on": state = "parent"; break; case "off": state = "off"; break; case "parent": state = "parent"; break; default: alert("Unknown tracking state " + tracking); break; } ESN.updateThreadIcons(child_dtalkid, state); }, 300); }); } // update icon var uri; switch (tracking) { case "on": uri = "/btn_tracking.gif?v=17312"; break; case "off": uri = "/btn_track.gif?v=17312"; break; case "parent": uri = "/btn_tracking_thread.gif?v=17312"; break; default: alert("Unknown tracking state " + tracking); break; } btn.src = LJ.get('imgprefix') + uri; }; jQuery(function($) { ESN.initCheckAllBtns(); ESN.initTrackBtns(); $('#settings_form').on('click', 'a.delete-group', function(e) { var match = this.search.match(/delete_group=([-\d]+)/), group = match ? match[1] : null; e.preventDefault(); if (!group) { return; } $.post(location.href, { delete_group: group }); $(this).closest('tr').remove(); }); }); }(DOM.getElement, ESN)); ; /* file-end: js/esn.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/jquery/jquery.lj.confirmbubble.js */ LJ.UI.registerTemplate('templates-Widgets-popupcontent', "
{{if $data.show_header}}
{{html $data.header_text}}
{{/if}} {{html $data.confirm_text}} {{if $data.show_check}}
{{/if}}
{{html $data.no_text}}
", 'JQuery.stat'); !function(a){a.widget("lj.confirmbubble",a.lj.basicWidget,{options:{selectors:{ok:".b-popup-btn",cancel:".b-popup-cancel",check:".b-popup-check"},templates:{content:"templates-Widgets-popupcontent"},confirm:jQuery.noop,confirmText:"",yesText:"",noText:"",checkText:"",headerText:"",showCheck:!1,showHeader:!1},_create:function(){a.lj.basicWidget.prototype._create.apply(this),this._content=this._tmpl("content",{confirm_text:this.options.confirmText,yes_text:this.options.confirmYes||LJ.ml("confirm.bubble.yes"),no_text:this.options.confirmNo||LJ.ml("confirm.bubble.no"),show_check:this.options.showCheck,show_header:this.options.showHeader,header_text:this.options.headerText,check_text:this.options.checkText}),this._bindControls(),this._content.bubble({showOn:"click",target:this.element}),this.options.showCheck&&this._content.find(this._s("ok")).attr("disabled",!0),Function.defer(this._content.bubble.bind(this._content,"show"))},_bindControls:function(){var b=this,c=this._content,d=c.find(this._s("ok")),e=this.options;a.lj.basicWidget.prototype._bindControls.apply(this),c.on("click",this._s("ok"),function(){c.bubble("hide"),e.confirm()}).on("change",this._s("check"),function(){a(this).attr("checked")?d.removeAttr("disabled"):d.attr("disabled",!0)}).on("click",this._s("cancel"),function(){c.bubble("hide")}).on("bubblehide",function(){b._trigger("hide")}).on("bubbleshow",function(){b._trigger("show")})},show:function(){this._content.bubble("show")},hide:function(){this._content.bubble("hide")}})}(jQuery,this);; /* file-end: js/jquery/jquery.lj.confirmbubble.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/jquery/jquery.lj.ljcut.js */ /** * @author Valeriy Vasin (valeriy.vasin@sup.com) * @name $.lj.ljcut * @requires $.ui.core, $.ui.widget, $.lj.basicWidget, LJ * @class The widget is responsible for expanding cuts */ ;(function ($) { "use strict"; $.widget('lj.ljcut', $.lj.basicWidget, { options: { // journal identifier (comes from server) journalid: null, // post identifier (comes from server) ditemid: null, // cut identifier inside of the post (comes from server) cutid: null, // server request param: use placeholders or not (1 or 0). Comes from server placeholders: 0, sticky: false, selectors: { expand: '.ljcut-link-expand', collapse: '.ljcut-link-collapse', // bottom collapse link collapseLink: '.ljcut-pseudolink-collapse', // sticky collapse link stickyLink: '.b-sticky-cut-link' }, classNames: { 'preloader': 'ljcut-link-expanding', 'expanded': 'ljcut-expanded', 'sticky-cut-visible': 'b-sticky-cut-visible', 'cut': '.b-sticky-cut' } }, _create: function () { $.lj.basicWidget.prototype._create.apply(this); this._window = $(window); this.cut = $(this._cl('cut')); // use current this in handler this._stickyCollapseHandler = this._collapse.bind(this); // jQuery element that will contain loaded content of the cut this.content = null; // test OS for Mac this._isMac = (/Mac/).test(navigator.userAgent); // $.browser.opera is deprecated this._isOpera = (/Opera/.test(navigator.userAgent)); // create collapse node that will be cloned and appended into each ljcut this._collapseNode = $('{close}'.supplant({close: this._ml('collapse')})); this._bindControls(); }, _bindControls: function () { var that = this; var tapping = false; var buttons = [this._s('expand'), this._s('collapse')].join(', '); $.lj.basicWidget.prototype._bindControls.apply(this); this.element.on('click', this._s('expand'), this._expand.bind(this)); this.element.on('click', this._s('collapse'), this._collapse.bind(this)); // Add fast click for iOS this.element.on('touchstart', buttons, function(e) { tapping = true; }); this.element.on('touchmove', buttons, function(e) { tapping = false; }); this.element.on('touchend', buttons, function(e) { if (tapping) { $(e.target).trigger('click'); } }); $(document).on('keydown', this._shortcuts.bind(this)); this._window.on('scroll', this._scrolling.bind(this)); }, /** * Shortcuts handler * @param {Object} e jQuery event object */ _shortcuts: function (e) { var ctrl = (this._isMac && this._isOpera) ? e.metaKey : e.ctrlKey, alt = e.altKey; if (!ctrl || !alt) { return; } switch (e.which) { // expand: ctrl + alt + "+" case 61: // FireFox, IE // fall through case 187: // Opera, Chrome, Safari this.expand(); break; // collapse: ctrl + alt + "-" case 173: // FireFox // fall through case 31: // Opera Mac // fall through case 109: // Opera Windows // fall through case 189: // Chrome, Safari this.collapse(); break; // no default } e.preventDefault(); }, /** * Show or hide preloader * @param {Boolean} state Preloader state: True (show) or False (hide) */ _togglePreloader: function (state) { this.element.toggleClass( this._cl('preloader'), state ); }, /** * Toggle content state * @param {Boolean} state State of content: expand (true) or collapse (false) */ _toggleContent: function (state, callback) { var that = this, _top; if (this.locked() || !this.content) { return; } this._lock(); if (typeof callback !== 'function') { callback = $.noop; } this.element.toggleClass( that._cl('expanded'), state ); if (state) { this._showContent(callback); } else { _top = this.element.offset().top - 30; if ( !this.element.is(':screenable') ) { $('body').animate({ scrollTop: _top }, 300, function () { //delay before collapsing to let user know what is happening setTimeout(that._hideContent.bind(that, callback), 50); }); } else { this._hideContent(callback); } } }, /** * Show content state */ _showContent: function (callback) { var that = this; this.content.slideDown('fast', function () { that._trigger('show', null, that); callback(); that._unlock(); }); }, /** * Hide content state */ _hideContent: function (callback) { var that = this; this.content.slideUp(50, function () { that._trigger('hide', null, that); callback(); that._unlock(); }); }, /** * Request server for the cut content * @param {Object} data Data that is needed for request */ _requestContent: function (data) { var that = this; this._lock(); this._togglePreloader(true); LJ.Api.call('event.get_lj_cut', data, function (response) { that.content = $('
', { html: response.text }).hide(); that.element.after( that.content ); that._unlock(); that._togglePreloader(false); // add handlers after content becomes visible that._toggleContent(true, that._addHandlers.bind(that)); // statistic if (response.counter_image_url) { LJ.Stat.addCounter(response.counter_image_url); } }); }, /** * Provide dynamic behavior for the content (javascript handlers) * @private */ _addHandlers: function () { this.content.ljLikes(); LJ.Event.trigger('social:widgets:parse'); }, /** * Expand content */ expand: function () { if ( this.locked() ) { return; } if ( this.content ) { this._toggleContent(true); } else { this._requestContent({ journalid: this.options.journalid, ditemid: this.options.ditemid, cutid: this.options.cutid, placeholders: this.options.placeholders }); } }, /** * Collapse content (for external usage) */ collapse: function () { if ( !this.locked() ) { this._toggleContent(false); this._toggleStickyClass(false); } }, /** * Expand link click handler * @param {Object} e jQuery event object */ _expand: function (e) { // open link in new tab if (e.metaKey || e.ctrlKey) { return true; } e.preventDefault(); this.expand(); }, /** * Collapse link click handler * @param {Object} e jQuery event object */ _collapse: function (e) { // open link in new tab if (e.metaKey || e.ctrlKey) { return true; } e.preventDefault(); this.collapse(); }, /** * Handler for scrolling event */ _scrolling: function () { this._updateStickyCutState(); }, /** * Check if a sticky cut element is needed to be displayed on the screen and show/hide it * */ _updateStickyCutState: function () { var viewportHeight, viewportTop, contentHeight, contentTop, contentBottom, state, collapse; if ( this._isExpanded() && this.options.sticky && this.content ) { viewportHeight = this._window.height(); viewportTop = $(document).scrollTop(); contentHeight = this.content.height(); contentTop = this.content.offset().top; contentBottom = contentTop + contentHeight; collapse = this.element.find( this._s('collapse') ); state = contentTop < viewportTop && contentBottom - viewportHeight > viewportTop; this._toggleStickyClass(state); } }, /** * Toggle class of the sticky cut * * @param {Boolean} state if `true` - show sticky, cut. Otherwise: hide */ _toggleStickyClass: function (state) { this.cut.toggleClass( this._cl('sticky-cut-visible'), state ); if (state) { $(document).on('click', this._s('stickyLink'), this._stickyCollapseHandler); } else { $(document).off('click', this._s('stickyLink'), this._stickyCollapseHandler); } }, /** * Extend lj-cut functionality with bottom collapse link and it's handlers */ _addBottomCollapser: function () { if ( !this._bottomCloser && this.options.sticky) { this._bottomCloser = this._collapseNode.appendTo(this.content); this._bottomCloser .find( this._s('collapseLink') ) .on('click', this._bottomCloserClickHandler.bind(this)); } return this._bottomCloser; }, _bottomCloserClickHandler: function () { event.preventDefault(); this.collapse(); }, _isExpanded: function () { return this.element.hasClass( this._cl('expanded') ); }, _isCollapsed: function () { return !this._isExpanded(); } }); }(jQuery)); ; /* file-end: js/jquery/jquery.lj.ljcut.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/fb-select-image.js */ jQuery(function(){function a(a,b){jQuery("
"+b+"
").find("img").each(function(){a.push(this.src)})}function b(){n.close()}var c=$("repost_facebook"),d=$("repost_facebook_thumbnail"),e=$("select-fb-thumbnail"),f=$("select-fb-thumbnail-comments"),g=$("userpic_preview_image"),h=$("fbimg_select_window"),i=$("fbimg_select_window_nav"),j=e||f,k="nothumb",l="userpic";if(null!=j){var m={};m=e?{getText:function(){return window.switchedRteOn?CKEDITOR.instances.draft.getData():jQuery("#draft").val()},getUserPic:function(){return g?g.src:""}}:{getText:function(){var a=$("commenttext")||$("body");return a.value},getUserPic:function(){var a=jQuery("#userpics > [name=prop_picture_keyword]");if(0==a.length&&(a=jQuery("#prop_picture_keyword")),0==a.length)return"";var b=a.val();return b in userpicmap?userpicmap[b]:defaultpicurl||""}};var n={init:function(){this.opened=!1,this.page=1,this.totalImages=1,this.pager={prev:jQuery(i).children(".i-repost-nav-prev"),next:jQuery(i).children(".i-repost-nav-next"),counter:jQuery(i).children(".i-repost-nav-counter")},this.listWrapper=jQuery(h).children(".b-repost-pics-wrapper"),this.list=this.listWrapper.children(".b-repost-pics-items"),this.pagerSize=4,this.pagesNum=1,this.cellWidth=0,this.pager.prev.click(function(){n.changePage(-1)}),this.pager.next.click(function(){n.changePage(1)}),this.firstLi=this.list.children("span:first").click(function(){n.setPicture(k)})},setPicture:function(a){d.value=a,this.close()},updatePager:function(){i.style.display=this.totalImages").addClass(d).append(jQuery("").attr("src",a)).click(function(){n.setPicture(b)})},open:function(a){this.list.children("span:gt(0)").remove(),this.totalImages=a.length,this.page=1,0!=a.length&&-1!=jQuery.inArray(d.value,a)||d.value==l||d.value==k||(d.value="");var b=m.getUserPic();if(b.length>0){var c=b;this.makeListItem(c,l,l==d.value).appendTo(this.list),this.totalImages++}this.pagesNum=Math.ceil((this.totalImages+1)/this.pagerSize),this.totalImages>1&&""==d.value&&(d.value=a[0]);for(var e=1,f=0;f0?1:0))/this.pagerSize)+1),this.makeListItem(a[f],a[f],a[f]==d.value).appendTo(this.list);this.firstLi[this.totalImages<=1&&""==d.value||d.value==k?"addClass":"removeClass"]("b-repost-pics-active"),h.style.display="block",this.opened=!0,this.firstLi.each(function(){n.cellWidth=this.offsetWidth+this.offsetLeft});var g=this.pagerSize>this.totalImages?this.cellWidth*(this.totalImages+1)+"px":"";this.listWrapper.css("width",g),this.changePage(e-1)},changePage:function(a){this.page+=a,this.page=this.page<1?1:this.page>this.pagesNum?this.pagesNum:this.page;var b=-this.cellWidth*(this.page-1)*this.pagerSize;this.list.css("left",b+"px"),this.updatePager()},close:function(){h.style.display="none",this.opened=!1}};n.init(),h.onmousedown=function(a){a=a||window.event,a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},j.onmousedown=function(a){a=a||window.event,n.opened&&(a.stopPropagation?a.stopPropagation():a.cancelBubble=!0)},j.onclick=function(d){d=d||window.event;var e=[];(null===c.getAttribute("disabled")||c.getAttribute("disabled")===!1)&&(n.opened?b():(e.length=0,a(e,m.getText()),n.open(e),setTimeout(function(){DOM.addEventListener(document,"mousedown",b,!1)},0))),d.preventDefault?d.preventDefault():d.returnValue=!1}}});; /* file-end: js/fb-select-image.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/quickreply.js */ QuickReply = { lastDiv: 'qrdiv', reply: function(dtid, pid, newsubject) { var targetname = 'ljqrt' + dtid, targetcomment = 'ljcmt' + dtid, qr_ptid = $('parenttalkid'), qr_rto = $('replyto'), qr_dtid = $('dtid'), qr_div = $('qrdiv'), cur_div = $(targetname), qr_form_div = $('qrformdiv'), qr_form = $('qrform'), subject = $('subject'); // Is this a dumb browser? if (!qr_ptid || !qr_rto || !qr_dtid || !qr_div || !cur_div || !qr_form || !qr_form_div || !subject) { return true; } qr_ptid.value = pid; qr_dtid.value = dtid; qr_rto.value = pid; if (QuickReply.lastDiv == 'qrdiv') { qr_div.style.display = 'inline'; // Only one swap } else if (QuickReply.lastDiv != dtid) { } var comments = $('comments'), targetcomment = $(targetcomment); //LJSUP-11059: when we show old style entry page, comment form should be placed under comment with //shift according to its depth. if (!comments || comments.className.indexOf('entry-comments-s1') === -1 || !targetcomment) { cur_div.parentNode.insertBefore(qr_div, cur_div); QuickReply._scrollForm(); } else { targetcomment.appendChild(qr_div); } QuickReply.lastDiv = targetname; if (!subject.value || subject.value == subject.defaultValue || subject.value.substr(0, 4) == 'Re: ') { subject.value = newsubject; subject.defaultValue = newsubject; } qr_form_div.className = cur_div.className || ''; return false; }, more: function() { var qr_form = $('qrform_hidden'), basepath = $('basepath'), dtid = $('dtid'), pidform = $('parenttalkid'); // do not do the default form action (post comment) if something is broke if (!qr_form || !basepath || !dtid || !pidform) { return false; } if(dtid.value > 0 && pidform.value > 0) { //a reply to a comment qr_form.action = basepath.value + "replyto=" + dtid.value + "#add_comment"; } else { qr_form.action = basepath.value + "mode=reply#add_comment"; } // we changed the form action so submit ourselves // and don't use the default form action qr_form.submit(); return false; }, submit: function() { var submitmore = $('submitmoreopts'), submit = $('submitpost'); if (!submitmore || !submit) { return false; } submit.disabled = true; submitmore.disabled = true; // New top-level comments var dtid = $('dtid'); if (!Number(dtid.value)) { dtid.value =+ 0; } var qr_form = $('qrform_hidden'); qr_form.action = Site.siteroot + '/talkpost_do.bml'; qr_form.submit(); // don't do default form action return false; }, check: function() { var qr_form = $('qrform_hidden'); if (!qr_form) return true; var len = qr_form.body.value.length; if (len > 4300) { alert('Sorry, but your comment of ' + len + ' characters exceeds the maximum character length of 4300. Please try shortening it and then post again.'); return false; } return true; }, // Maintain entry through browser navigations. save: function() { var qr_form = $('qrform_hidden'); if (!qr_form) { return false; } var do_spellcheck = $('do_spellcheck'), qr_upic = $('prop_picture_keyword'); $('saved_body').value = qr_form.body.value; $('saved_subject').value = $('subject').value; $('saved_dtid').value = $('dtid').value; $('saved_ptid').value = $('parenttalkid').value; if (do_spellcheck) { $('saved_spell').value = do_spellcheck.checked; } if (qr_upic) { // if it was in the form $('saved_upic').value = qr_upic.selectedIndex; } return false; }, // Restore saved_entry text across platforms. restore: function() { setTimeout(function(){ var saved_body = $('saved_body'), dtid = $('saved_dtid'), subject = $('saved_subject'), subject_str = '', qr_form = $('qrform_hidden'); if (!saved_body || saved_body.value == '' || !qr_form || !dtid) { return; } if (subject) { subject_str = subject.value; } QuickReply.reply(dtid.value, parseInt($('saved_ptid').value, 10), subject_str); qr_form.body.value = saved_body.value; // if it was in the form var upic = $('prop_picture_keyword'); if (upic) { upic.selectedIndex = $('saved_upic').value; } }, 100); }, cloneForm: function (action) { var form = jQuery('#qrform'), fields = form.find('input'), fieldsReplica = form.find('textarea, select'), clonedForm = jQuery('#qrform_hidden'); (clonedForm.length ? clonedForm.empty() : jQuery('
')) .hide() .append(fields.clone()) .append(fieldsReplica.clone().each(function (index, element) { //copy values to cloned textareas and selects. jQuery(element).val(fieldsReplica.eq(index).val()); })) .appendTo('body'); if ( QuickReply[action]() ) { QuickReply.submit(); } }, userpicSelect: function() { var ups = new UserpicSelect(); ups.init(); ups.setPicSelectedCallback(function(picid, keywords) { var kws_dropdown = $('prop_picture_keyword'); if (kws_dropdown) { var items = kws_dropdown.options; // select the keyword in the dropdown keywords.forEach(function(kw) { for (var i = 0; i < items.length; i++) { var item = items[i]; if (item.value == kw) { kws_dropdown.selectedIndex = i; return; } } }); } }); ups.show(); }, _scrollForm: function () { var _body = jQuery('html, body'), scrollTop = jQuery(window).scrollTop(), scrollBottom = scrollTop + jQuery(window).height(), qr_form = jQuery('#qrform'), offsetTop = qr_form.offset().top, // expected position of quick reply form offsetBottom = offsetTop + qr_form.height(); // is expected form position keep on screen (vertical) if ( offsetTop > scrollTop || offsetTop < scrollBottom || offsetBottom > scrollTop || offsetBottom < scrollBottom ) { // scroll to keep form on screen. _body.animate({ scrollTop: offsetTop }, '300'); // and focus on comment textarea qr_form.find('textarea').focus(); } } }; jQuery(QuickReply.restore); DOM.addEventListener(window, 'unload', QuickReply.save); ; /* file-end: js/quickreply.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/md5.js */ /* * md5.jvs 1.0b 27/06/96 * * Javascript implementation of the RSA Data Security, Inc. MD5 * Message-Digest Algorithm. * * Copyright (c) 1996 Henri Torgemane. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for any purposes and without * fee is hereby granted provided that this copyright notice * appears in all copies. * * Of course, this soft is provided "as is" without express or implied * warranty of any kind. */ function array(n) { for(i=0;i> 4 with it.. * Of course, these functions are slower than the original would be, but * at least, they work! */ function integer(n) { return n%(0xffffffff+1); } function shr(a,b) { a=integer(a); b=integer(b); if (a-0x80000000>=0) { a=a%0x80000000; a>>=b; a+=0x40000000>>(b-1); } else a>>=b; return a; } function shl1(a) { a=a%0x80000000; if (a&0x40000000==0x40000000) { a-=0x40000000; a*=2; a+=0x80000000; } else a*=2; return a; } function shl(a,b) { a=integer(a); b=integer(b); for (var i=0;i=0) if (t2>=0) return ((t1&t2)+0x80000000); else return (t1&b); else if (t2>=0) return (a&t2); else return (a&b); } function or(a,b) { a=integer(a); b=integer(b); var t1=(a-0x80000000); var t2=(b-0x80000000); if (t1>=0) if (t2>=0) return ((t1|t2)+0x80000000); else return ((t1|b)+0x80000000); else if (t2>=0) return ((a|t2)+0x80000000); else return (a|b); } function xor(a,b) { a=integer(a); b=integer(b); var t1=(a-0x80000000); var t2=(b-0x80000000); if (t1>=0) if (t2>=0) return (t1^t2); else return ((t1^b)+0x80000000); else if (t2>=0) return ((a^t2)+0x80000000); else return (a^b); } function not(a) { a=integer(a); return (0xffffffff-a); } /* Here begin the real algorithm */ var state = new array(4); var count = new array(2); count[0] = 0; count[1] = 0; var buffer = new array(64); var transformBuffer = new array(16); var digestBits = new array(16); var S11 = 7; var S12 = 12; var S13 = 17; var S14 = 22; var S21 = 5; var S22 = 9; var S23 = 14; var S24 = 20; var S31 = 4; var S32 = 11; var S33 = 16; var S34 = 23; var S41 = 6; var S42 = 10; var S43 = 15; var S44 = 21; function F(x,y,z) { return or(and(x,y),and(not(x),z)); } function G(x,y,z) { return or(and(x,z),and(y,not(z))); } function H(x,y,z) { return xor(xor(x,y),z); } function I(x,y,z) { return xor(y ,or(x , not(z))); } function rotateLeft(a,n) { return or(shl(a, n),(shr(a,(32 - n)))); } function FF(a,b,c,d,x,s,ac) { a = a+F(b, c, d) + x + ac; a = rotateLeft(a, s); a = a+b; return a; } function GG(a,b,c,d,x,s,ac) { a = a+G(b, c, d) +x + ac; a = rotateLeft(a, s); a = a+b; return a; } function HH(a,b,c,d,x,s,ac) { a = a+H(b, c, d) + x + ac; a = rotateLeft(a, s); a = a+b; return a; } function II(a,b,c,d,x,s,ac) { a = a+I(b, c, d) + x + ac; a = rotateLeft(a, s); a = a+b; return a; } function transform(buf,offset) { var a=0, b=0, c=0, d=0; var x = transformBuffer; a = state[0]; b = state[1]; c = state[2]; d = state[3]; for (i = 0; i < 16; i++) { x[i] = and(buf[i*4+offset],0xff); for (j = 1; j < 4; j++) { x[i]+=shl(and(buf[i*4+j+offset] ,0xff), j * 8); } } /* Round 1 */ a = FF ( a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ d = FF ( d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ c = FF ( c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ b = FF ( b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ a = FF ( a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ d = FF ( d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ c = FF ( c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ b = FF ( b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ a = FF ( a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ d = FF ( d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ c = FF ( c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ b = FF ( b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ a = FF ( a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ d = FF ( d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ c = FF ( c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ b = FF ( b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ a = GG ( a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ d = GG ( d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ c = GG ( c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ b = GG ( b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ a = GG ( a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ d = GG ( d, a, b, c, x[10], S22, 0x2441453); /* 22 */ c = GG ( c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ b = GG ( b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ a = GG ( a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ d = GG ( d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ c = GG ( c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ b = GG ( b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ a = GG ( a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ d = GG ( d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ c = GG ( c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ b = GG ( b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ a = HH ( a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ d = HH ( d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ c = HH ( c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ b = HH ( b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ a = HH ( a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ d = HH ( d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ c = HH ( c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ b = HH ( b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ a = HH ( a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ d = HH ( d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ c = HH ( c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ b = HH ( b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ a = HH ( a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ d = HH ( d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ c = HH ( c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ b = HH ( b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ a = II ( a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ d = II ( d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ c = II ( c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ b = II ( b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ a = II ( a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ d = II ( d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ c = II ( c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ b = II ( b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ a = II ( a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ d = II ( d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ c = II ( c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ b = II ( b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ a = II ( a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ d = II ( d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ c = II ( c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ b = II ( b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ state[0] +=a; state[1] +=b; state[2] +=c; state[3] +=d; } function init() { count[0]=count[1] = 0; state[0] = 0x67452301; state[1] = 0xefcdab89; state[2] = 0x98badcfe; state[3] = 0x10325476; for (i = 0; i < digestBits.length; i++) digestBits[i] = 0; } function update(b) { var index,i; index = and(shr(count[0],3) , 0x3f); if (count[0]<0xffffffff-7) count[0] += 8; else { count[1]++; count[0]-=0xffffffff+1; count[0]+=8; } buffer[index] = and(b,0xff); if (index >= 63) { transform(buffer, 0); } } function finish() { var bits = new array(8); var padding; var i=0, index=0, padLen=0; for (i = 0; i < 4; i++) { bits[i] = and(shr(count[0],(i * 8)), 0xff); } for (i = 0; i < 4; i++) { bits[i+4]=and(shr(count[1],(i * 8)), 0xff); } index = and(shr(count[0], 3) ,0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); padding = new array(64); padding[0] = 0x80; for (i=0;i?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; function MD5(entree) { var l,s,k,ka,kb,kc,kd; init(); for (k=0;k HTML element from where Expander was called this.url; // full url of thread to be expanded this.id; // id of the thread this.stored_caller; this.iframe; // iframe, where the thread will be loaded this.is_S1; // bool flag, true == journal is in S1, false == in S2 } Expander.Collection={}; Expander.make = function(el,url,id,is_S1){ var local = (new Expander).set({__caller__:el,url:url.replace(/#.*$/,''),id:id,is_S1:!!is_S1}); local.get(); } Expander.prototype.set = function(options){ for(var opt in options){ this[opt] = options[opt]; } return this; } Expander.prototype.getCanvas = function(id,context){ return context.document.getElementById('ljcmt'+id); } Expander.prototype.parseLJ_cmtinfo = function(context,callback){ var map={}, node, j; var LJ = context.LJ_cmtinfo; if(!LJ)return false; for(j in LJ){ if(/^\d*$/.test(j) && (node = this.getCanvas(j,context))){ map[j] = {info:LJ[j],canvas:node}; if(typeof callback == 'function'){ callback(j,map[j]); } } } return map; } Expander.prototype.loadingStateOn = function(){ this.stored_caller = this.__caller__.cloneNode(true); this.__caller__.setAttribute('already_clicked','already_clicked'); this.__caller__.onclick = function(){return false} this.__caller__.style.color = '#ccc'; } Expander.prototype.loadingStateOff = function(){ if(this.__caller__){ // actually, the element is removed from main window by // copying comment from ifame, so this code is not executed (?) this.__caller__.removeAttribute('already_clicked','already_clicked'); if(this.__caller__.parentNode) this.__caller__.parentNode.replaceChild(this.stored_caller,this.__caller__); } var obj = this; // When frame is removed immediately, IE raises an error sometimes window.setTimeout(function(){obj.killFrame()},100); } Expander.prototype.killFrame = function(){ document.body.removeChild(this.iframe); } Expander.prototype.isFullComment = function(comment){ return !!Number(comment.info.full); } Expander.prototype.killDuplicate = function(comments){ var comment; var id,id_,el,el_; for(var j in comments){ if(!/^\d*$/.test(j))continue; el_ = comments[j].canvas; id_ = el_.id; id = id_.replace(/_$/,''); el = document.getElementById(id); if(el!=null){ //in case we have a duplicate; el_.parentNode.removeChild(el_); }else{ el_.id = id; window.ContextualPopup && ContextualPopup.searchAndAdd(el_); window.setupAjax && setupAjax(el_); window.ESN && ESN.initTrackBtns(el_); } } } Expander.prototype.getS1width = function(canvas){ //TODO: may be we should should add somie ID to the spacer img instead of searching it //yet, this works until we have not changed the spacers url = 'dot.gif?v=557'); var img, imgs; imgs = canvas.getElementsByTagName('img'); for(var j=0;j'); }else{ // branch for all other browsers iframe = document.createElement('iframe'); iframe.onload = function(obj){return function(){ obj.onLoadHandler(iframe); }}(this); } iframe.style.height='1px'; iframe.style.width='1px'; iframe.style.display = 'none'; iframe.src = this.url; iframe.id = this.id; document.body.appendChild(iframe); this.iframe=iframe; return true; }; ; /* file-end: js/thread_expander.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/thread_expander.ex.js */ /* * ExpanderEx object is used in s1 style comment pages and provides * ajax functionality to expand comments instead of loading iframe page as it is * in old Expander * expander object is also used in commentmanage.js */ ExpanderEx = function(){ this.__caller__; // HTML element from where ExpanderEx was called this.url; // full url of thread to be expanded this.id; // id of the thread this.stored_caller; this.is_S1; // bool flag, true == journal is in S1, false == in S2 } ExpanderEx.Collection={}; ExpanderEx.ReqCache = {}; ExpanderEx.make = function(ev,el,url,id,is_S1){ var local = (new ExpanderEx).set({__caller__:el,url:url.replace(/#.*$/,''),id:id,is_S1:!!is_S1}); local.get(); jQuery.event.fix(ev).preventDefault(); } ExpanderEx.collapse = function(ev,el,url,id,is_S1){ var local = (new ExpanderEx).set({__caller__:el,url:url.replace(/#.*$/,''),id:id,is_S1:!!is_S1}); local.collapseThread(); jQuery.event.fix(ev).preventDefault(); } ExpanderEx.prototype.set = function(options){ for(var opt in options){ this[opt] = options[opt]; } return this; } ExpanderEx.prototype.getCanvas = function(id,context){ return context.document.getElementById('ljcmt'+id); } ExpanderEx.prototype.parseLJ_cmtinfo = function(context,callback){ var map={}, node, j; var LJ = context.LJ_cmtinfo; if(!LJ)return false; for(j in LJ){ if(/^\d*$/.test(j) && (node = this.getCanvas(j,context))){ map[j] = {info:LJ[j],canvas:node}; if(typeof callback == 'function'){ callback(j,map[j]); } } } return map; } ExpanderEx.preloadImg = function(){ (new Image()).src = Site.imgprefix + '/preloader-s.gif?v=9673'; } ExpanderEx.prototype.addPreloader = function(){ this.loader = new Image(); this.loader.src = Site.imgprefix + '/preloader-s.gif?v=9673'; this.loader.className = 'i-exp-preloader'; this.__caller__.parentNode.appendChild( this.loader ); } ExpanderEx.prototype.removePreloader = function(){ if( !this.loader ){ return; } if( this.loader.parentNode ){ this.loader.parentNode.removeChild( this.loader ); } delete this.loader; }; ExpanderEx.prototype.loadingStateOn = function(){ // turn on preloader there this.addPreloader(); this.stored_caller = this.__caller__.cloneNode(true); this.__caller__.setAttribute('already_clicked','already_clicked'); this.__caller__.onclick = function(){return false} this.__caller__.style.color = '#ccc'; } ExpanderEx.prototype.loadingStateOff = function(){ if(this.__caller__){ // actually, the element is removed from main window by // copying comment from ifame, so this code is not executed (?) this.__caller__.removeAttribute('already_clicked','already_clicked'); if(this.__caller__.parentNode) this.__caller__.parentNode.replaceChild(this.stored_caller,this.__caller__); //remove preloader if exist this.removePreloader(); } var obj = this; // When frame is removed immediately, IE raises an error sometimes } ExpanderEx.prototype.killFrame = function(){ document.body.removeChild(this.iframe); } ExpanderEx.prototype.isFullComment = function( comment ) { return !!Number(comment.info.full); } ExpanderEx.prototype.expandThread = function( json ) { this.loadingStateOff(); //we show expand link if comment block has collapsed children function isChildCollapsed( idx ) { var state; for( var i = idx + 1; i < json.length; ++i ) { state = json[ i ].state; if( state === "expanded" ) { return false; } if( state === "collapsed" ) { return true; } } return false; } var threadId, cell, html; for( var i = 0; i < json.length; ++i ) { //we skip comment blocks thate were not expanded if( json[ i ].state === 'deleted' ) { LJ_cmtinfo[ json[ i ].thread ].is_deleted = true; } if( !( json[ i ].thread in LJ_cmtinfo ) ) { continue; } if( json[ i ].state && json[ i ].state !== "expanded") { continue; } threadId = json[ i ].thread; html = ExpanderEx.prepareCommentBlock( jQuery( json[ i ].html ), threadId, isChildCollapsed( i ) ); var oldHtml = LiveJournal.CommentManager.updateCell( threadId, html ); if( !( threadId in ExpanderEx.Collection ) ) { ExpanderEx.Collection[ threadId ] = oldHtml; } } //duplicate cycle, because we do not know, that external scripts do with node for( var i = 0; i < json.length; ++i ) { threadId = json[ i ].thread; LJ_cmtinfo[ threadId ].parent = this.id; if( json[ i ].state && json[ i ].state === "expanded") { this.initCommentBlock( jQuery( '#ljcmt' + threadId )[0] , threadId ); } } return true; } ExpanderEx.prototype.collapseThread = function( id ){ var threadId = id || this.id; this.collapseBlock( threadId ); var children = LJ_cmtinfo[ threadId ].rc; for( var i = 0; i < children.length; ++i ) this.collapseThread( children[ i ] ); } ExpanderEx.prototype.collapseBlock = function( id ) { if( id in ExpanderEx.Collection ) { LiveJournal.CommentManager.updateCell( id, ExpanderEx.Collection[ id ] ); this.initCommentBlock( LiveJournal.CommentManager.getCell( id )[0], id, true ); delete ExpanderEx.Collection[ id ]; } } ExpanderEx.prototype.initCommentBlock = function( el_, id, restoreInitState ) { if( !restoreInitState ){ LJ_cmtinfo[ id ].oldvars = { full: LJ_cmtinfo[ id ].full || 0, expanded: LJ_cmtinfo[ id ].expanded || 0 } LJ_cmtinfo[ id ].full = 1; LJ_cmtinfo[ id ].expanded = 1; } else { LJ_cmtinfo[ id ].full = LJ_cmtinfo[ id ].oldvars.full; LJ_cmtinfo[ id ].expanded = LJ_cmtinfo[ id ].oldvars.expanded; delete LJ_cmtinfo[ id ].oldvars; } window.ContextualPopup && ContextualPopup.searchAndAdd(el_); //window.setupAjax && setupAjax(el_, true); window.ESN && ESN.initTrackBtns(el_); } //just for debugging ExpanderEx.prototype.toString = function(){ return '__'+this.id+'__'; } ExpanderEx.prototype.get = function(){ if(this.__caller__.getAttribute('already_clicked')){ return false; } this.loadingStateOn(); var obj = this; //set timeout to allow browser to display image before request setTimeout( function(){ LiveJournal.CommentManager.getThreadJSON( obj.id, function(result) { obj.expandThread(result); ExpanderEx.ReqCache[ obj.id ] = result; }, false, false, true ); }, 0 ); return true; } //toggle visibility of expand and collapse links, if server returns //html with both of them ( with every ajax request) ExpanderEx.prepareCommentBlock = function(html, id, showExpand){ this.showExpandLink( id, html, showExpand ); return html; } ExpanderEx.showExpandLink = function ( id, block, showExpand ) { var expandSel = "#expand_" + id, collapseSel = "#collapse_" + id, selector, resetSelector; if( LJ_cmtinfo[ id ].has_link > 0 ) { if( showExpand ) { selector = collapseSel; resetSelector = expandSel; } else { selector = expandSel; resetSelector = collapseSel; } block.find( resetSelector ).css( 'display', '' ); } else { selector = collapseSel + "," + expandSel; } block.find( selector ) .css( 'display', 'none' ); } ExpanderEx.preloadImg(); ; /* file-end: js/thread_expander.ex.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/commentmanage.js */ // called by S2: function setStyle (did, attr, val) { if (! document.getElementById) return; var de = document.getElementById(did); if (! de) return; if (de.style) de.style[attr] = val } // called by S2: function setInner (did, val) { if (! document.getElementById) return; var de = document.getElementById(did); if (! de) return; de.innerHTML = val; } // called by S2: function hideElement (did) { if (! document.getElementById) return; var de = document.getElementById(did); if (! de) return; de.style.display = 'none'; } // called by S2: function setAttr (did, attr, classname) { if (! document.getElementById) return; var de = document.getElementById(did); if (! de) return; de.setAttribute(attr, classname); } // called from Page: function multiformSubmit (form, txt) { var sel_val = form.mode.value; if (!sel_val) { alert(txt.no_action); return false; } if (sel_val.substring(0, 4) == 'all:') { // mass action return; } var i = -1, has_selected = false; // at least one checkbox while (form[++i]) { if (form[i].name.substring(0, 9) == 'selected_' && form[i].checked) { has_selected = true; break; } } if (!has_selected) { alert(txt.no_comments); return false; } if (sel_val == 'delete' || sel_val == 'deletespam') { return confirm(txt.conf_delete); } } function getLocalizedStr( key, username ) { return LJ.ml( key, { username: username } ); } // hsv to rgb // h, s, v = [0, 1), [0, 1], [0, 1] // r, g, b = [0, 255], [0, 255], [0, 255] function hsv_to_rgb (h, s, v) { if (s == 0) { v *= 255; return [v,v,v]; } h *= 6; var i = Math.floor(h); var f = h - i; var p = v * (1 - s); var q = v * (1 - s * f); var t = v * (1 - s * (1 - f)); v = Math.floor(v * 255 + 0.5); t = Math.floor(t * 255 + 0.5); p = Math.floor(p * 255 + 0.5); q = Math.floor(q * 255 + 0.5); if (i == 0) return [v,t,p]; if (i == 1) return [q,v,p]; if (i == 2) return [p,v,t]; if (i == 3) return [p,q,v]; if (i == 4) return [t,p,v]; return [v,p,q]; } function deleteComment (ditemid, action) { action = action || 'delete'; var curJournal = (Site.currentJournal !== "") ? (Site.currentJournal) : (LJ_cmtinfo.journal); var form = $('ljdelopts' + ditemid), todel = $('ljcmt' + ditemid), opt_delthread, opt_delauthor, is_deleted, is_error, pulse = 0, url = LiveJournal.getAjaxUrl('delcomment')+'?mode=js&journal=' + curJournal + '&id=' + ditemid; var postdata = 'confirm=1'; if (form && action == 'delete') { if (form.ban && form.ban.checked) { postdata += '&ban=1'; } if (form.spam && form.spam.checked) { postdata += '&spam=1'; } if (form.delthread && form.delthread.checked) { postdata += '&delthread=1'; opt_delthread = true; } if (form.delauthor && form.delauthor.checked) { postdata += '&delauthor=1'; opt_delauthor = true; } } else if (action == 'markAsSpam') { opt_delauthor = opt_delthread = true; postdata += '&ban=1&spam=1&delauthor=1'; } postdata += '&lj_form_auth=' + decodeURIComponent(LJ_cmtinfo.form_auth); var opts = { url: url, data: postdata, method: 'POST', onData: function(data) { is_deleted = !!data; is_error = !is_deleted; }, onError: function() { alert('Error deleting ' + ditemid); is_error = true; } }; HTTPReq.getJSON(opts); var flash = function () { var rgb = hsv_to_rgb(0, Math.cos((pulse + 1) / 2), 1); pulse += 3.14159 / 5; var color = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")"; todel.style.border = "2px solid " + color; if (is_error) { todel.style.border = ""; // and let timer expire } else if (is_deleted) { removeComment(ditemid, opt_delthread); if (opt_delauthor && LJ_cmtinfo[ditemid].u !== '') { for (var item in LJ_cmtinfo) { if ( LJ_cmtinfo[item].u == LJ_cmtinfo[ditemid].u && !LJ_cmtinfo[ item ].is_deleted) { removeComment(item, false); } } } } else { window.setTimeout(flash, 50); } }; window.setTimeout(flash, 5); } function removeComment (ditemid, killChildren) { if( LiveJournal.CommentManager.getState() !== 'iframe'){ var threadId = ditemid; LiveJournal.CommentManager.getThreadJSON(threadId, function(result) { LiveJournal.CommentManager.processThreadJSON( result, function( dtid, html, comment) { if (LJ_cmtinfo[ threadId ].u !== LJ_cmtinfo[ dtid ].u) { return; } html = ExpanderEx.prepareCommentBlock( html, dtid ); //, isChildCollapsed( i ) ); LiveJournal.CommentManager.updateCell( dtid, html ); if( comment.is_deleted && ( dtid in ExpanderEx.Collection ) ) { delete ExpanderEx.Collection[ dtid ]; } } ); }, true ); } else { var todel = document.getElementById("ljcmt" + ditemid); if (todel) { todel.style.display = 'none'; var userhook = window["userhook_delete_comment_ARG"]; if (userhook) userhook(ditemid); } } if (killChildren) { var com = LJ_cmtinfo[ditemid]; for (var i = 0; i < com.rc.length; i++) { removeComment(com.rc[i], true); } } } function createDeleteFunction(ae, dItemid, action) { action = action || 'delete'; return function (e) { e = jQuery.event.fix(e || window.event); e.stopPropagation(); e.preventDefault(); var doIT = 0; // immediately delete on shift key if (e.shiftKey) { doIT = 1; deleteComment(dItemid, action); return true; } if (!LJ_cmtinfo) { return true; } var com = LJ_cmtinfo[dItemid], comUser = LJ_cmtinfo[dItemid].u, remoteUser = LJ_cmtinfo.remote; if (!com || !remoteUser) { return true; } var canAdmin = LJ_cmtinfo.canAdmin; var markSpamMLPrefix = (Site.remote_is_maintainer == 1 && com.u !== '') ? 'comment.mark.spam.' : 'comment.mark.spam2.'; if (action == 'markAsSpam') { if (!window.ctrlPopup) { window.ctrlPopup = jQuery('
') .delegate('input.spam-comment-button', 'click', function () { window.ctrlPopup.bubble('hide'); }); } window.ctrlPopup .html('
' + getLocalizedStr(markSpamMLPrefix + 'title', comUser) + '
' + getLocalizedStr(markSpamMLPrefix + 'subject', comUser) + '
', ae, e, 'spamComment' + dItemid) .bubble() .bubble('show', ae); return true; } else if (action == 'delete') { var inHTML = [ "
" + getLocalizedStr( 'comment.delete.q', comUser ) + "
" ]; var lbl; if (com.username !== "" && com.username != remoteUser && canAdmin) { lbl = "ljpopdel" + dItemid + "ban"; inHTML.push("
"); } if (com.rc && com.rc.length && canAdmin) { lbl = "ljpopdel" + dItemid + "thread"; inHTML.push("
"); } if (canAdmin&&com.username) { lbl = "ljpopdel" + dItemid + "author"; inHTML.push("
"); } inHTML.push("
" + getLocalizedStr( 'comment.delete.no.options', comUser ) + "
"); if (!window.delPopup) { window.delPopup = jQuery('
') .delegate('input.delete-comment-button', 'click', function () { window.delPopup.bubble('hide'); }); } window.delPopup .html(inHTML.join(' ')) .bubble() .bubble('show', ae); } else if (action == 'unspam') { deleteComment(dItemid, action); } }; } function poofAt (pos) { var de = document.createElement("div"); de.style.position = "absolute"; de.style.background = "#FFF"; de.style.overflow = "hidden"; var opp = 1.0; var top = pos.y; var left = pos.x; var width = 5; var height = 5; document.body.appendChild(de); var fade = function () { opp -= 0.15; width += 10; height += 10; top -= 5; left -= 5; if (opp <= 0.1) { de.parentNode.removeChild(de); } else { de.style.left = left + "px"; de.style.top = top + "px"; de.style.height = height + "px"; de.style.width = width + "px"; de.style.filter = "alpha(opacity=" + Math.floor(opp * 100) + ")"; de.style.opacity = opp; window.setTimeout(fade, 20); } }; fade(); } function updateLink (ae, resObj, clickTarget) { ae.href = resObj.newurl; var userhook = window["userhook_" + resObj.mode + "_comment_ARG"]; var did_something = 0; if (clickTarget && clickTarget.src && clickTarget.src == resObj.oldimage) { clickTarget.src = resObj.newimage; did_something = 1; } if (userhook) { userhook(resObj.id); did_something = 1; } // if all else fails, at least remove the link so they're not as confused if (! did_something) { if (ae && ae.style) ae.style.display = 'none'; if (clickTarget && clickTarget.style) clickTarget.style.dispay = 'none'; } } var tsInProg = {} // dict of { ditemid => 1 } function createModerationFunction(control, dItemid, action) { var action = action || 'screen', comUser = LJ_cmtinfo[dItemid].u; return function (e) { var e = jQuery.event.fix(e || window.event), pos = { x: e.pageX, y: e.pageY }, modeParam = LiveJournal.parseGetArgs(location.href).mode, hourglass; e.stopPropagation(); e.preventDefault(); sendModerateRequest(); function sendModerateRequest() { var bmlName = (action == 'unspam') ? 'spamcomment' : 'talkscreen', postUrl = control.href.replace(new RegExp('.+' + bmlName + '\.bml'), LiveJournal.getAjaxUrl(bmlName)), postParams = { 'confirm': 'Y', lj_form_auth: decodeURIComponent(LJ_cmtinfo.form_auth) }; if (action == 'unspam') { postUrl += '&jsmode=1'; } hourglass = jQuery(e).hourglass()[0]; jQuery.post(postUrl, postParams, function (json) { tsInProg[dItemid] = 0; if (action == 'unspam') { json = jQuery.parseJSON(json); if (json.result) { removeEmptyMarkup(dItemid); hourglass.hide(); return true; } else { alert(json.errormsg); } } if( LiveJournal.CommentManager.getState() !== 'iframe' ) { handleNew(); } else { var ids = checkRcForNoCommentsPage(); handleIframe(ids); } }); } function handleNew() { var newNode, showExpand, j, children, threadId = dItemid, threadExpanded = !!(LJ_cmtinfo[ threadId ].oldvars && LJ_cmtinfo[ threadId ].full), populateComments = function (result) { LiveJournal.CommentManager.processThreadJSON( result, function( dtid, html ) { if( LJ_cmtinfo[ dtid ].full ){ showExpand = !( 'oldvars' in LJ_cmtinfo[ dtid ]); //still show expand button if children comments are folded if( !showExpand ) { children = LJ_cmtinfo[ dtid ].rc; for( j = 0; j < children.length; ++j ) { if( !LJ_cmtinfo[ children[j] ].full && !LJ_cmtinfo[ children[j] ].is_deleted ) { // if( !( 'oldvars' in LJ_cmtinfo[ children[j] ] ) ) { showExpand = true; } } } if (!html) { removeEmptyMarkup(result[i].thread); } var newNode = ExpanderEx.prepareCommentBlock( html, dtid, showExpand ); LiveJournal.CommentManager.updateCell( dtid, newNode ); } } ); hourglass.hide(); poofAt(pos); }; LiveJournal.CommentManager.getThreadJSON(threadId, function (result) { //if comment is expanded we need to fetch it's collapsed state additionally if( threadExpanded && LJ_cmtinfo[ threadId ].oldvars.full ) { LiveJournal.CommentManager.getThreadJSON( threadId, function (result2) { ExpanderEx.Collection[ threadId ] = ExpanderEx.prepareCommentBlock( jQuery( "
" + result2[0].html + "
" ), threadId, true ).html() //ExpanderEx.Collection[ threadId ] = result2[0].html; populateComments( result ); }, true, true ); } else { populateComments( result ); } }, false, !threadExpanded); } function handleIframe(ids) { // modified jQuery.fn.load jQuery.ajax({ url: location.href, type: 'GET', dataType: 'html', complete: function (res, status) { // If successful, inject the HTML into all the matched elements if (status == 'success' || status == 'notmodified') { // Create a dummy div to hold the results var nodes = jQuery('
') // inject the contents of the document in, removing the scripts // to avoid any 'Permission Denied' errors in IE .append(res.responseText.replace(//gi, '')) // Locate the specified elements .find(ids) .each(function () { var id = this.id.replace(/[^0-9]/g, ''); if (LJ_cmtinfo[id].expanded) { var expand = this.innerHTML.match(/Expander\.make\(.+?\)/)[0]; (function(){ eval(expand); }).apply(document.createElement('a')); } else { jQuery('#' + this.id).replaceWith(this); } }); hourglass.hide(); poofAt(pos); } } }); } function checkRcForNoCommentsPage() { var commsArray = [ dItemid ], ids; // check rc for no comments page if (LJ_cmtinfo[dItemid].rc) { if (/mode=(un)?freeze/.test(control.href)) { mapComms(dItemid); } ids = '#ljcmt' + commsArray.join(',#ljcmt'); } else { var rpcRes; eval(json); updateLink(control, rpcRes, control.getElementsByTagName('img')[0]); // /tools/recent_comments.bml if (document.getElementById('ljcmtbar'+dItemid)) { ids = '#ljcmtbar' + dItemid; } // ex.: portal/ else { hourglass.hide(); poofAt(pos); return; } } function mapComms(id) { var i = -1, newId; while (newId = LJ_cmtinfo[id].rc[++i]) { if (LJ_cmtinfo[newId].full) { commsArray.push(newId); mapComms(String(newId)); } } } return ids; } return false; } } function removeEmptyMarkup(threadId) { jQuery('#ljcmt' + threadId).remove(); } (function( $, window ) { window.LiveJournal.CommentManager = function() { this.bindLinks(); } LiveJournal.CommentManager.prototype.bindLinks = function() { $( 'body' ).delegate( 'a', 'click', function( ev ) { var rex_id = /id=(\d+)/, ae = this; if (ae.href.indexOf('talkscreen.bml') != -1) { var reMatch = rex_id.exec(ae.href); if (!reMatch) return; var id = reMatch[1]; if (!document.getElementById('ljcmt' + id)) return; createModerationFunction(ae, id)( ev ); } else if (ae.href.indexOf('delcomment.bml') != -1) { if (LJ_cmtinfo && LJ_cmtinfo.disableInlineDelete) return; var reMatch = rex_id.exec(ae.href); if (!reMatch) return; var id = reMatch[1]; if (!document.getElementById('ljcmt' + id)) return; var action = (ae.href.indexOf('spam=1') != -1) ? 'markAsSpam' : 'delete'; createDeleteFunction(ae, id, action)( ev ); // unspam } else if (ae.href.indexOf('spamcomment.bml') != -1) { var reMatch = rex_id.exec(ae.href); if (!reMatch) return; var id = reMatch[1]; if (!document.getElementById('ljcmt' + id)) return; createModerationFunction(ae, id, 'unspam')( ev ); } else { return; } ev.preventDefault(); ev.stopPropagation(); } ); } var manager = window.LiveJournal.CommentManager; window.LiveJournal.CommentManager.getState = function() { if( LJ_cmtinfo.use_old_thread_expander ) { return "iframe"; } else { return "old"; } } /** * @param {Number} threadId Id of thread to update * @param {Node} node Collection of nodes with new content * * @return {String} Returns a string containing old content of the cell; */ LiveJournal.CommentManager.updateCell = function( threadId, node ) { var cell = $( "#ljcmt" + threadId ), old_html = $( '
' ). append( cell.clone() ); cell.replaceWith( $( node ).filter( "#ljcmt" + threadId ) ); return old_html.html(); } LiveJournal.CommentManager.getCell = function( threadId ) { return $( "#ljcmt" + threadId ); } LiveJournal.CommentManager.getThreadJSON = function(threadId, success, getSingle) { var postid = location.href.match(/\/(\d+).html/)[1], modeParam = LiveJournal.parseGetArgs(location.href).mode, params = { journal: Site.currentJournal, itemid: postid, thread: threadId, depth: LJ_cmtinfo[ threadId ].depth }; if( getSingle) { params.single = '1'; } if (modeParam) { params.mode = modeParam; } var getArgs = LiveJournal.parseGetArgs( location.href ); if( getArgs && !!getArgs.style && getArgs.style === "mine" ) { params.style = "mine"; } var endpoint = LiveJournal.getAjaxUrl( 'get_thread' ); jQuery.get( LiveJournal.constructUrl( endpoint, params ), success, 'json' ); } LiveJournal.CommentManager.processThreadJSON = function( result, callback ) { var comment, dom; for( var i = 0; i < result.length; ++i ){ if( !( result[ i ].thread in LJ_cmtinfo ) ) { continue; } comment = {}; comment.is_deleted = ( result[i].state === "deleted" ); if( comment.is_deleted ) { LJ_cmtinfo[ result[i].thread ].is_deleted = true; } dom = $( result[i].html ).filter( "#ljcmt" + result[i].thread ); callback( result[i].thread, dom, comment ); } } $( function() { new LiveJournal.CommentManager(); } ); }( jQuery, window )) function LJ_Mul( a, b ) { return parseInt(a, 10) * parseInt(b, 10) } function LJ_JoinURL( url /* parts */ ) { var add = [].slice.call( arguments, 1 ).join( '&' ); url += ( url.indexOf( '?' ) > -1 ) ? '&' : '?'; return url + add; } function LJ_Concat( /* parts */ ) { return [].slice.call( arguments, 0 ).join( '' ); } ; /* file-end: js/commentmanage.js ----------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------- file-start: js/ljlive/main.js */ LJ.injectStyle('.b-ljtimes-wrapper {\n position: fixed;\n top: auto;\n right: auto;\n bottom: 0;\n left: 0;\n width: 100%;\n margin: 0;\n padding: 0;\n z-index: 2999;\n font-size: 0;\n background: #FFF;\n }\n\n@media all and (max-width: 650px) {\n .b-ljtimes-wrapper {\n display: none;\n }\n}\n\n.b-ljtimes-lwrapper {\n position: fixed;\n bottom: 0;\n left: 0;\n }\n.i-ljtimes-border {\n position: absolute;\n top: -1px;\n left: 0;\n display: block;\n overflow: hidden;\n width: 100%;\n height: 1px;\n background: #CCC;\n font: 0/0 serif;\n }\n .i-ljtimes-bl,\n .i-ljtimes-br {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n font: 0/0 serif;\n width: 3000px;\n height: 10px;\n background: url(/img/ljtimes/border.png?v=9478) repeat 0 0;\n }\n .i-ljtimes-bl {\n margin: 0 0 0 -3030px;\n }\n .i-ljtimes-br {\n margin: 0 0 0 30px;\n } \n.b-ljtimes-lwrapper .i-ljtimes-border {\n display: none;\n }\n.i-ljtimes-btn {\n overflow: hidden;\n position: absolute;\n top: -17px;\n left: 14px;\n width: 46px;\n height: 17px;\n background: url(/img/ljtimes/button.png?v=10067) no-repeat 0 0;\n font: 0/0 serif;\n }\n.b-ljtimes-lwrapper .i-ljtimes-btn {\n bottom: auto;\n top: 0;\n left: 50%;\n height: 24px;\n width: 60px;\n margin: 0 0 0 -30px;\n background: none;\n }\n .i-ljtimes-drag {\n display: block;\n position: absolute;\n top: 0;\n left: 0;\n width: 60px;\n height: 5px;\n font: 0/0 serif;\n cursor: row-resize;\n }\n .b-ljtimes-lwrapper .i-ljtimes-drag {\n top: 16px;\n height: 8px;\n background: url(/img/ljtimes/down.png?v=10005) no-repeat 0 0; \n cursor: pointer;\n }\n .i-ljtimes-click {\n overflow: hidden;\n display: block;\n position: absolute;\n top: 5px;\n left: 0;\n width: 46px;\n height: 18px;\n font: 0/0 serif;\n cursor: pointer;\n }\n .b-ljtimes-lwrapper .i-ljtimes-click {\n top: 0;\n width: 60px;\n height: 16px;\n background: url(/img/ljtimes/arrow.png?v=10005) no-repeat 0 0;\n }\n.b-ljtimes-inbox {\n position: fixed;\n bottom: 33px;\n right: 0;\n width: 300px;\n font: 11px/1.2 Arial,sans-serif;\n color: #000;\n z-index: 999;\n }\n .b-ljtimes-inbox-head {\n display:block;\n margin: 0;\n padding: 7px 10px;\n text-align: center;\n font-weight: normal;\n }\n .b-ljtimes-inbox-item {\n display:block;\n margin: 0;\n padding: 5px 10px 7px;\n list-style: none;\n border-top: 1px solid #C1C1C1;\n }\n .b-ljtimes-inbox-item:first-child {\n border: 0;\n }\n .b-ljtimes-inbox-item B {\n font-weight: normal;\n }\n .b-ljtimes-inbox-item IMG {\n vertical-align: -5px !important;\n }\n .b-ljtimes-inbox A:link,\n .b-ljtimes-inbox A:visited {\n color: #41789C !important;\n text-decoration: underline !important;\n border: 0 !important;\n }\n .b-ljtimes-inbox A:hover,\n .b-ljtimes-inbox A:active {\n color: #41789C !important;\n text-decoration: none !important;\n border: 0 !important;\n }\n .b-ljtimes-inbox .i-popup-arr {\n left: auto;\n right: 15px;\n margin: 0;\n }\n.b-ljtimes-update {\n position: fixed;\n bottom: 33px;\n right: 0;\n width: 380px;\n font: 11px/1.2 Arial,sans-serif;\n z-index: 9999;\n }\n .b-ljtimes-update .b-popup {\n position: static;\n }\n .b-ljtimes-logged-label {\n display: block;\n margin: 0;\n padding: 0;\n }\n .b-ljtimes-logged-input {\n overflow: hidden;\n display: block;\n margin: 1px 0 7px;\n padding: 1px;\n }\n .b-ljtimes-logged .i-ljtimes-text {\n width: 330px;\n margin: 0;\n padding: 2px 1px;\n font: 12px/1.2 Arial,sans-serif;\n }\n .b-ljtimes-logged .i-ljtimes-textarea {\n width: 330px;\n height: 65px;\n margin: 0;\n padding: 2px 1px;\n font: 12px/1.2 Arial,sans-serif;\n }\n .b-ljtimes-logged .i-ljtimes-tags {\n float: left;\n width: 180px;\n }\n .b-ljtimes-logged-submit {\n float: right;\n margin: 0;\n }\n .b-ljtimes-success {\n color: #000;\n }\n .b-ljtimes-success .b-popup-inner {\n padding: 30px;\n }\n .b-ljtimes-success-title {\n display: block;\n margin: 0 0 10px;\n font: bold 15px/1.2 Arial,sans-serif;\n text-align: center;\n }\n .b-ljtimes-success-body {\n display: block;\n line-height: 1.4;\n text-align: center;\n }\n .b-ljtimes-login {\n color: #000;\n font-size: 12px;\n }\n .b-ljtimes-login-form {\n position: relative;\n overflow: hidden;\n display:block;\n margin: 0;\n padding: 0;\n text-align: left;\n }\n .b-ljtimes-login-head,\n .b-ljtimes-logged-head {\n display:block;\n margin: 0 0 5px;\n padding: 0;\n font: bold 14px/1.2 Arial,sans-serif;\n color: #000;\n }\n .b-ljtimes-login-input {\n float: left;\n margin: 0;\n padding: 20px 5px 20px 1px;\n list-style: none;\n line-height: 1.2;\n }\n .b-ljtimes-login .i-ljtimes-text {\n width: 115px;\n margin: 0 0 5px;\n padding: 2px 1px;\n font: 12px/1.2 Arial,sans-serif;\n }\n .b-ljtimes-login .i-ljtimes-submit {\n vertical-align: -6px;\n }\n .b-ljtimes-login-create {\n position: absolute;\n top: 0;\n left: 0;\n }\n .b-ljtimes-login-remember {\n position: absolute;\n top: 45px;\n left: 0;\n }\n .b-ljtimes-login-lostinfo {\n position: absolute;\n top: 48px;\n left: 158px;\n }\n .b-ljtimes-login-connect {\n margin: 0;\n padding: 0;\n text-align: left;\n }\n .b-ljtimes-login-connect IMG {\n border: 0;\n margin: 0 3px 0 0;\n }\n .b-ljtimes-update A:link,\n .b-ljtimes-update A:visited {\n color: #41789C !important;\n text-decoration: underline !important;\n border: 0 !important;\n }\n .b-ljtimes-update A:hover,\n .b-ljtimes-update A:active {\n color: #41789C !important;\n text-decoration: none !important;\n border: 0 !important;\n }\n.b-ljtimes-bubble {\n position: absolute;\n left: 14px;\n width: 292px;\n margin: 0;\n padding: 0;\n font: 12px/1.2 Arial,sans-serif;\n color: #000;\n text-align: left;\n }\n .b-ljtimes-bubble-top,\n .b-ljtimes-bubble-bg,\n .b-ljtimes-bubble-close {\n display: block;\n position: absolute;\n margin: 0;\n padding: 0;\n font: 0/0 serif;\n }\n .b-ljtimes-bubble-top {\n top: 0;\n left: 0;\n width: 292px;\n height: 7px;\n background: url(/img/ljtimes/bubble-top.png?v=10269) no-repeat 0 0;\n }\n .b-ljtimes-bubble-content{\n overflow: hidden;\n position: relative;\n top: 7px;\n margin: 0;\n padding: 8px 15px 22px;\n }\n .b-ljtimes-bubble-head {\n position: relative;\n display: block;\n margin: 0 20px 5px 0;\n padding: 0;\n font-weight: bold;\n z-index: 2;\n }\n .b-ljtimes-bubble-p {\n position: relative;\n display: block;\n z-index: 2;\n }\n .b-ljtimes-bubble-bg {\n bottom: 0;\n left: 0;\n width: 292px;\n height: 357px;\n background: url(/img/ljtimes/bubble-bg.png?v=10269) no-repeat 0 0;\n z-index: 1;\n }\n .b-ljtimes-bubble-close {\n top: 8px;\n right: 16px;\n width: 12px;\n height: 12px;\n background: url(/img/ljtimes/bubble-close.gif?v=10269) no-repeat 0 0;\n cursor: pointer;\n z-index: 3;\n }\n.b-ljtimes-suggest,\n.b-ljtimes-suggestbbl {\n position: fixed;\n bottom: 33px;\n right: 0;\n width: 380px;\n font: 11px/1.2 Arial,sans-serif;\n color: #000;\n z-index: 999;\n }\n .b-ljtimes-suggest .i-ljtimes-text {\n width: 245px;\n margin: 0 0 5px;\n padding: 2px 1px;\n font: 12px/1.2 Arial,sans-serif;\n }\n .b-ljtimes-suggest-alert {\n margin: 0 0 5px;\n padding: 0;\n font: 11px/1.2 Arial,sans-serif;\n }\n .b-ljtimes-suggestbbl-alert {\n margin: 0 0 5px;\n padding: 0;\n font: 12px/1.2 Arial,sans-serif;\n }\n .b-ljtimes-suggest-input .i-ljtimes-submit {\n vertical-align: 0;\n }\n \n/* Pages without footer */\n.p-nofooter #ljtime_bottom {\n height: 21px !important; \n }\n.p-footer-lite #ljtime_bottom {\n height: 21px !important;\n }\n.p-footer-lite.ljtimes-minimized #ljtime_bottom {\n height: 0 !important;\n }\n\n'); /** * LJ Live main file */ ;(function ($) { 'use strict'; var IFRAME_HEIGHT = 50, wrapper = $('
', { id: 'ljlive', 'class': 'b-ljtimes-wrapper b-ljtimes-wrapper_v2' }), brandingTemplate = LJ.get('ljlive.branding_template'), // load iframe from cdn when user is not logged in: LJSUP-19269 iframeOrigin = LJ.get('remote') ? LJ.get('siteroot') : LJ.get('statprefix'), iframe = createIframe(); wrapper.append(iframe); if (brandingTemplate) { wrapper.append( $.parseHTML(brandingTemplate) ); } /** * Create hidden iframe */ function createIframe() { var params = { lang: LJ.get('locale'), is_paid: LJ.get('journal.is_paid'), country: LJ.get('country'), v: LJ.get('v') }; // we should not provide lots of params for non-logged users // because of CDN cache if ( LJ.get('remote') ) { // send origin that will be applied to postMessage params.origin = location.origin; if ( typeof LJ.get('journal.id') !== 'undefined' ) { params.journalid = LJ.get('journal.id'); } if ( typeof LJ.get('entry.ditemid') !== 'undefined' ) { params.entryditemid = LJ.get('entry.ditemid'); } } if ( brandingTemplate ) { params.branding = true; } return $('