Generate the node required for user display length changing
@param {object} oSettings dataTables settings object
@returns {node} Display length feature node
@memberof DataTable#oApi
189916
function _fnFeatureHtmlLength ( oSettings )
		{
			if ( oSettings.oScroll.bInfinite )
			{
				return null;
			}
			
			/* This can be overruled by not using the _MENU_ var/macro in the language variable */
			var sName = 'name="'+oSettings.sTableId+'_length"';
			var sStdMenu = '<select size="1" '+sName+'>';
			var i, iLen;
			var aLengthMenu = oSettings.aLengthMenu;
			
			if ( aLengthMenu.length == 2 && typeof aLengthMenu[0] === 'object' && 
					typeof aLengthMenu[1] === 'object' )
			{
				for ( i=0, iLen=aLengthMenu[0].length ; i<iLen ; i++ )
				{
					sStdMenu += '<option value="'+aLengthMenu[0][i]+'">'+aLengthMenu[1][i]+'</option>';
				}
			}
			else
			{
				for ( i=0, iLen=aLengthMenu.length ; i<iLen ; i++ )
				{
					sStdMenu += '<option value="'+aLengthMenu[i]+'">'+aLengthMenu[i]+'</option>';
				}
			}
			sStdMenu += '</select>';
			
			var nLength = document.createElement( 'div' );
			if ( !oSettings.aanFeatures.l )
			{
				nLength.id = oSettings.sTableId+'_length';
			}
			nLength.className = oSettings.oClasses.sLength;
			nLength.innerHTML = '<label>'+oSettings.oLanguage.sLengthMenu.replace( '_MENU_', sStdMenu )+'</label>';
			
			/*
			 * Set the length to the current display length - thanks to Andrea Pavlovic for this fix,
			 * and Stefan Skopnik for fixing the fix!
			 */
			$('select option[value="'+oSettings._iDisplayLength+'"]', nLength).attr("selected", true);
			
			$('select', nLength).bind( 'change.DT', function(e) {
				var iVal = $(this).val();
				
				/* Update all other length options for the new display */
				var n = oSettings.aanFeatures.l;
				for ( i=0, iLen=n.length ; i<iLen ; i++ )
				{
					if ( n[i] != this.parentNode )
					{
						$('select', n[i]).val( iVal );
					}
				}
				
				/* Redraw the table */
				oSettings._iDisplayLength = parseInt(iVal, 10);
				_fnCalculateEnd( oSettings );
				
				/* If we have space to show extra rows (backing up from the end point - then do so */
				if ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() )
				{
					oSettings._iDisplayStart = oSettings.fnDisplayEnd() - oSettings._iDisplayLength;
					if ( oSettings._iDisplayStart < 0 )
					{
						oSettings._iDisplayStart = 0;
					}
				}
				
				if ( oSettings._iDisplayLength == -1 )
				{
					oSettings._iDisplayStart = 0;
				}
				
				_fnDraw( oSettings );
			} );
		
		
			$('select', nLength).attr('aria-controls', oSettings.sTableId);
			
			return nLength;
		}
472250
function length(description) {
  if (arguments.length < 2) {
    throw new Error('Handlebar Helper \'length\'' +
    ' needs 1 parameter');
  }

  if ((typeof description) !== 'string') {
    throw new TypeError('Handlebars Helper \'length\'' +
      'requires path to be a string');
  }

  var desc = description;
  if (len !== -1) {
    description = strObj(description).truncate(len - 50).s;
  }

  return jsStringEscape(description);
}
295920
function _fnBuildHead( oSettings )
	{
		var i, ien, cell, row, column;
		var thead = oSettings.nTHead;
		var tfoot = oSettings.nTFoot;
		var createHeader = $('th, td', thead).length === 0;
		var classes = oSettings.oClasses;
		var columns = oSettings.aoColumns;
	
		if ( createHeader ) {
			row = $('<tr/>').appendTo( thead );
		}
	
		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
			column = columns[i];
			cell = $( column.nTh ).addClass( column.sClass );
	
			if ( createHeader ) {
				cell.appendTo( row );
			}
	
			// 1.11 move into sorting
			if ( oSettings.oFeatures.bSort ) {
				cell.addClass( column.sSortingClass );
	
				if ( column.bSortable !== false ) {
					cell
						.attr( 'tabindex', oSettings.iTabIndex )
						.attr( 'aria-controls', oSettings.sTableId );
	
					_fnSortAttachListener( oSettings, column.nTh, i );
				}
			}
	
			if ( column.sTitle != cell.html() ) {
				cell.html( column.sTitle );
			}
	
			_fnRenderer( oSettings, 'header' )(
				oSettings, cell, column, i, classes
			);
		}
	
		if ( createHeader ) {
			_fnDetectHeader( oSettings.aoHeader, thead );
		}
	
		/* ARIA role for the rows */
		$(thead).find('>tr').attr('role', 'row');
	
		/* Deal with the footer - add classes if required */
		$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
		$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
	
		// Cache the footer cells. Note that we only take the cells from the first
		// row in the footer. If there is more than one row the user wants to
		// interact with, they need to use the table().foot() method. Note also this
		// allows cells to be used for multiple columns using colspan
		if ( tfoot !== null ) {
			var cells = oSettings.aoFooter[0];
	
			for ( i=0, ien=cells.length ; i<ien ; i++ ) {
				column = columns[i];
				column.nTf = cells[i].cell;
	
				if ( column.sClass ) {
					$(column.nTf).addClass( column.sClass );
				}
			}
		}
	}
69272
function(sViewName, sControlId, vObject) { // TODO: Fragments and Views are mixed here
				var mSettings;
				// TODO: checking order of components?
				findConfig(CONFIG_VIEW_MODIFICATIONS, vObject, function(oConfig) {
					var oSettings = oConfig[sViewName] && oConfig[sViewName][sControlId];
					var oUsedSettings = {};
					var bValidConfigFound = false;
					if (oSettings) {
						jQuery.each(oSettings, function(sName, vValue) {
							if (sName === "visible") {
								bValidConfigFound = true;
								oUsedSettings[sName] = vValue;
								Log.info("Customizing: custom value for property '" + sName + "' of control '" + sControlId + "' in View '" + sViewName + "' applied: " + vValue);
							} else {
								Log.warning("Customizing: custom value for property '" + sName + "' of control '" + sControlId + "' in View '" + sViewName + "' ignored: only the 'visible' property can be customized.");
							}
						});
						if (bValidConfigFound) { // initialize only when there is actually something to add
							mSettings = mSettings || {}; // merge with any previous calls to findConfig in case of multiple definition sections
							jQuery.extend(mSettings, oUsedSettings); // FIXME: this currently overrides customizations from different components in random order
						}
					}
				});
				return mSettings;
			}
488417
function render(renderSettings) {
	    var image = null;
	    var mode = renderSettings.mode;
	    var el = renderSettings.el;
	    var holderSettings = renderSettings.holderSettings;
	    var engineSettings = renderSettings.engineSettings;

	    switch (engineSettings.renderer) {
	        case 'svg':
	            if (!App.setup.supportsSVG) return;
	            break;
	        case 'canvas':
	            if (!App.setup.supportsCanvas) return;
	            break;
	        default:
	            return;
	    }

	    //todo: move generation of scene up to flag generation to reduce extra object creation
	    var scene = {
	        width: holderSettings.dimensions.width,
	        height: holderSettings.dimensions.height,
	        theme: holderSettings.theme,
	        flags: holderSettings.flags
	    };

	    var sceneGraph = buildSceneGraph(scene);

	    function getRenderedImage() {
	        var image = null;
	        switch (engineSettings.renderer) {
	            case 'canvas':
	                image = sgCanvasRenderer(sceneGraph, renderSettings);
	                break;
	            case 'svg':
	                image = svgRenderer(sceneGraph, renderSettings);
	                break;
	            default:
	                throw 'Holder: invalid renderer: ' + engineSettings.renderer;
	        }

	        return image;
	    }

	    image = getRenderedImage();

	    if (image == null) {
	        throw 'Holder: couldn\'t render placeholder';
	    }

	    //todo: add <object> canvas rendering
	    if (mode == 'background') {
	        el.style.backgroundImage = 'url(' + image + ')';

	        if (!engineSettings.noBackgroundSize) {
	            el.style.backgroundSize = scene.width + 'px ' + scene.height + 'px';
	        }
	    } else {
	        if (el.nodeName.toLowerCase() === 'img') {
	            DOM.setAttr(el, {
	                'src': image
	            });
	        } else if (el.nodeName.toLowerCase() === 'object') {
	            DOM.setAttr(el, {
	                'data': image,
	                'type': 'image/svg+xml'
	            });
	        }
	        if (engineSettings.reRender) {
	            global.setTimeout(function () {
	                var image = getRenderedImage();
	                if (image == null) {
	                    throw 'Holder: couldn\'t render placeholder';
	                }
	                //todo: refactor this code into a function
	                if (el.nodeName.toLowerCase() === 'img') {
	                    DOM.setAttr(el, {
	                        'src': image
	                    });
	                } else if (el.nodeName.toLowerCase() === 'object') {
	                    DOM.setAttr(el, {
	                        'data': image,
	                        'type': 'image/svg+xml'
	                    });
	                }
	            }, 150);
	        }
	    }
	    //todo: account for re-rendering
	    DOM.setAttr(el, {
	        'data-holder-rendered': true
	    });
	}
328762
function (settings) {
          var buttons, callback = settings.callback || function () { };

          function createButton(text, status, primary) {
            return {
              type: "button",
              text: text,
              subtype: primary ? 'primary' : '',
              onClick: function (e) {
                e.control.parents()[1].close();
                callback(status);
              }
            };
          }

          switch (settings.buttons) {
            case MessageBox.OK_CANCEL:
              buttons = [
                createButton('Ok', true, true),
                createButton('Cancel', false)
              ];
              break;

            case MessageBox.YES_NO:
            case MessageBox.YES_NO_CANCEL:
              buttons = [
                createButton('Yes', 1, true),
                createButton('No', 0)
              ];

              if (settings.buttons == MessageBox.YES_NO_CANCEL) {
                buttons.push(createButton('Cancel', -1));
              }
              break;

            default:
              buttons = [
                createButton('Ok', true, true)
              ];
              break;
          }

          return new Window({
            padding: 20,
            x: settings.x,
            y: settings.y,
            minWidth: 300,
            minHeight: 100,
            layout: "flex",
            pack: "center",
            align: "center",
            buttons: buttons,
            title: settings.title,
            role: 'alertdialog',
            items: {
              type: "label",
              multiline: true,
              maxWidth: 500,
              maxHeight: 200,
              text: settings.text
            },
            onPostRender: function () {
              this.aria('describedby', this.items()[0]._id);
            },
            onClose: settings.onClose,
            onCancel: function () {
              callback(false);
            }
          }).renderTo(document.body).reflow();
        }
1280582
function _fnColumnOptions( oSettings, iCol, oOptions )
		{
			var oCol = oSettings.aoColumns[ iCol ];
			
			/* User specified column options */
			if ( oOptions !== undefined && oOptions !== null )
			{
				if ( oOptions.sType !== undefined )
				{
					oCol.sType = oOptions.sType;
					oCol._bAutoType = false;
				}
				
				$.extend( oCol, oOptions );
				_fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
		
				/* iDataSort to be applied (backwards compatibility), but aDataSort will take
				 * priority if defined
				 */
				if ( oOptions.iDataSort !== undefined )
				{
					oCol.aDataSort = [ oOptions.iDataSort ];
				}
				_fnMap( oCol, oOptions, "aDataSort" );
			}
		
			/* Cache the data get and set functions for speed */
			oCol.fnGetData = _fnGetObjectDataFn( oCol.mDataProp );
			oCol.fnSetData = _fnSetObjectDataFn( oCol.mDataProp );
			
			/* Feature sorting overrides column specific when off */
			if ( !oSettings.oFeatures.bSort )
			{
				oCol.bSortable = false;
			}
			
			/* Check that the class assignment is correct for sorting */
			if ( !oCol.bSortable ||
				 ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) )
			{
				oCol.sSortingClass = oSettings.oClasses.sSortableNone;
				oCol.sSortingClassJUI = "";
			}
			else if ( oCol.bSortable ||
			          ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) )
			{
			  oCol.sSortingClass = oSettings.oClasses.sSortable;
			  oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI;
			}
			else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 )
			{
				oCol.sSortingClass = oSettings.oClasses.sSortableAsc;
				oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed;
			}
			else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 )
			{
				oCol.sSortingClass = oSettings.oClasses.sSortableDesc;
				oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed;
			}
		}
631689
function _fnFeatureHtmlTable ( settings )
	{
		var scroll = settings.oScroll;
	
		if ( scroll.sX === '' && scroll.sY === '' ) {
			return settings.nTable;
		}
	
		var scrollX = scroll.sX;
		var scrollY = scroll.sY;
		var classes = settings.oClasses;
		var table = $(settings.nTable);
		var caption = table.children('caption');
		var captionSide = caption.length ? caption[0]._captionSide : null;
		var headerClone = $( table[0].cloneNode(false) );
		var footerClone = $( table[0].cloneNode(false) );
		var footer = table.children('tfoot');
		var _div = '<div/>';
		var size = function ( s ) {
			return !s ? null : _fnStringToCss( s );
		};
	
		if ( ! footer.length ) {
			footer = null;
		}
	
		/*
		 * The HTML structure that we want to generate in this function is:
		 *  div - scroller
		 *    div - scroll head
		 *      div - scroll head inner
		 *        table - scroll head table
		 *          thead - thead
		 *    div - scroll body
		 *      table - table (master table)
		 *        thead - thead clone for sizing
		 *        tbody - tbody
		 *    div - scroll foot
		 *      div - scroll foot inner
		 *        table - scroll foot table
		 *          tfoot - tfoot
		 */
		var scroller = $( _div, { 'class': classes.sScrollWrapper } )
			.append(
				$(_div, { 'class': classes.sScrollHead } )
					.css( {
						overflow: 'hidden',
						position: 'relative',
						border: 0,
						width: scrollX ? size(scrollX) : '100%'
					} )
					.append(
						$(_div, { 'class': classes.sScrollHeadInner } )
							.css( {
								'box-sizing': 'content-box',
								width: scroll.sXInner || '100%'
							} )
							.append(
								headerClone
									.removeAttr('id')
									.css( 'margin-left', 0 )
									.append(
										table.children('thead')
									)
							)
					)
					.append( captionSide === 'top' ? caption : null )
			)
			.append(
				$(_div, { 'class': classes.sScrollBody } )
					.css( {
						overflow: 'auto',
						height: size( scrollY ),
						width: size( scrollX )
					} )
					.append( table )
			);
	
		if ( footer ) {
			scroller.append(
				$(_div, { 'class': classes.sScrollFoot } )
					.css( {
						overflow: 'hidden',
						border: 0,
						width: scrollX ? size(scrollX) : '100%'
					} )
					.append(
						$(_div, { 'class': classes.sScrollFootInner } )
							.append(
								footerClone
									.removeAttr('id')
									.css( 'margin-left', 0 )
									.append(
										table.children('tfoot')
									)
							)
					)
					.append( captionSide === 'bottom' ? caption : null )
			);
		}
	
		var children = scroller.children();
		var scrollHead = children[0];
		var scrollBody = children[1];
		var scrollFoot = footer ? children[2] : null;
	
		// When the body is scrolled, then we also want to scroll the headers
		if ( scrollX ) {
			$(scrollBody).scroll( function (e) {
				var scrollLeft = this.scrollLeft;
	
				scrollHead.scrollLeft = scrollLeft;
	
				if ( footer ) {
					scrollFoot.scrollLeft = scrollLeft;
				}
			} );
		}
	
		settings.nScrollHead = scrollHead;
		settings.nScrollBody = scrollBody;
		settings.nScrollFoot = scrollFoot;
	
		// On redraw - align columns
		settings.aoDrawCallback.push( {
			"fn": _fnScrollDraw,
			"sName": "scrolling"
		} );
	
		return scroller[0];
	}
514874
function _fnSort ( oSettings, bApplyClasses )
		{
			var
				i, iLen, j, jLen, k, kLen,
				sDataType, nTh,
				aaSort = [],
			 	aiOrig = [],
				oSort = DataTable.ext.oSort,
				aoData = oSettings.aoData,
				aoColumns = oSettings.aoColumns,
				oAria = oSettings.oLanguage.oAria;
			
			/* No sorting required if server-side or no sorting array */
			if ( !oSettings.oFeatures.bServerSide && 
				(oSettings.aaSorting.length !== 0 || oSettings.aaSortingFixed !== null) )
			{
				aaSort = ( oSettings.aaSortingFixed !== null ) ?
					oSettings.aaSortingFixed.concat( oSettings.aaSorting ) :
					oSettings.aaSorting.slice();
				
				/* If there is a sorting data type, and a fuction belonging to it, then we need to
				 * get the data from the developer's function and apply it for this column
				 */
				for ( i=0 ; i<aaSort.length ; i++ )
				{
					var iColumn = aaSort[i][0];
					var iVisColumn = _fnColumnIndexToVisible( oSettings, iColumn );
					sDataType = oSettings.aoColumns[ iColumn ].sSortDataType;
					if ( DataTable.ext.afnSortData[sDataType] )
					{
						var aData = DataTable.ext.afnSortData[sDataType].call( 
							oSettings.oInstance, oSettings, iColumn, iVisColumn
						);
						if ( aData.length === aoData.length )
						{
							for ( j=0, jLen=aoData.length ; j<jLen ; j++ )
							{
								_fnSetCellData( oSettings, j, iColumn, aData[j] );
							}
						}
						else
						{
							_fnLog( oSettings, 0, "Returned data sort array (col "+iColumn+") is the wrong length" );
						}
					}
				}
				
				/* Create a value - key array of the current row positions such that we can use their
				 * current position during the sort, if values match, in order to perform stable sorting
				 */
				for ( i=0, iLen=oSettings.aiDisplayMaster.length ; i<iLen ; i++ )
				{
					aiOrig[ oSettings.aiDisplayMaster[i] ] = i;
				}
		
				/* Build an internal data array which is specific to the sort, so we can get and prep
				 * the data to be sorted only once, rather than needing to do it every time the sorting
				 * function runs. This make the sorting function a very simple comparison
				 */
				var iSortLen = aaSort.length;
				var fnSortFormat, aDataSort;
				for ( i=0, iLen=aoData.length ; i<iLen ; i++ )
				{
					for ( j=0 ; j<iSortLen ; j++ )
					{
						aDataSort = aoColumns[ aaSort[j][0] ].aDataSort;
		
						for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
						{
							sDataType = aoColumns[ aDataSort[k] ].sType;
							fnSortFormat = oSort[ (sDataType ? sDataType : 'string')+"-pre" ];
							
							aoData[i]._aSortData[ aDataSort[k] ] = fnSortFormat ?
								fnSortFormat( _fnGetCellData( oSettings, i, aDataSort[k], 'sort' ) ) :
								_fnGetCellData( oSettings, i, aDataSort[k], 'sort' );
						}
					}
				}
				
				/* Do the sort - here we want multi-column sorting based on a given data source (column)
				 * and sorting function (from oSort) in a certain direction. It's reasonably complex to
				 * follow on it's own, but this is what we want (example two column sorting):
				 *  fnLocalSorting = function(a,b){
				 *  	var iTest;
				 *  	iTest = oSort['string-asc']('data11', 'data12');
				 *  	if (iTest !== 0)
				 *  		return iTest;
				 *    iTest = oSort['numeric-desc']('data21', 'data22');
				 *    if (iTest !== 0)
				 *  		return iTest;
				 *  	return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
				 *  }
				 * Basically we have a test for each sorting column, if the data in that column is equal,
				 * test the next column. If all columns match, then we use a numeric sort on the row 
				 * positions in the original data array to provide a stable sort.
				 */
				oSettings.aiDisplayMaster.sort( function ( a, b ) {
					var k, l, lLen, iTest, aDataSort, sDataType;
					for ( k=0 ; k<iSortLen ; k++ )
					{
						aDataSort = aoColumns[ aaSort[k][0] ].aDataSort;
		
						for ( l=0, lLen=aDataSort.length ; l<lLen ; l++ )
						{
							sDataType = aoColumns[ aDataSort[l] ].sType;
							
							iTest = oSort[ (sDataType ? sDataType : 'string')+"-"+aaSort[k][1] ](
								aoData[a]._aSortData[ aDataSort[l] ],
								aoData[b]._aSortData[ aDataSort[l] ]
							);
						
							if ( iTest !== 0 )
							{
								return iTest;
							}
						}
					}
					
					return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
				} );
			}
			
			/* Alter the sorting classes to take account of the changes */
			if ( (bApplyClasses === undefined || bApplyClasses) && !oSettings.oFeatures.bDeferRender )
			{
				_fnSortingClasses( oSettings );
			}
		
			for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
			{
				var sTitle = aoColumns[i].sTitle.replace( /<.*?>/g, "" );
				nTh = aoColumns[i].nTh;
				nTh.removeAttribute('aria-sort');
				nTh.removeAttribute('aria-label');
				
				/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
				if ( aoColumns[i].bSortable )
				{
					if ( aaSort.length > 0 && aaSort[0][0] == i )
					{
						nTh.setAttribute('aria-sort', aaSort[0][1]=="asc" ? "ascending" : "descending" );
						
						var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ? 
							aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0];
						nTh.setAttribute('aria-label', sTitle+
							(nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
					}
					else
					{
						nTh.setAttribute('aria-label', sTitle+
							(aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
					}
				}
				else
				{
					nTh.setAttribute('aria-label', sTitle);
				}
			}
			
			/* Tell the draw function that we have sorted the data */
			oSettings.bSorted = true;
			$(oSettings.oInstance).trigger('sort', oSettings);
			
			/* Copy the master data into the draw array and re-draw */
			if ( oSettings.oFeatures.bFilter )
			{
				/* _fnFilter() will redraw the table for us */
				_fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 );
			}
			else
			{
				oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
				oSettings._iDisplayStart = 0; /* reset display back to page 0 */
				_fnCalculateEnd( oSettings );
				_fnDraw( oSettings );
			}
		}
1048066
function validateNode(opts: Options) {
    const isRow = node => node.type === opts.typeRow;
    const isCell = node => node.type === opts.typeCell;
    const countCells = row => row.nodes.count(isCell);

    return node => {
        if (node.type !== opts.typeTable) {
            return undefined;
        }

        const rows = node.nodes.filter(isRow);
        const maxColumns = Math.max(
            // Minimum 1 column
            1,
            rows.map(countCells).max()
        );
        const rowsMissingColumns = rows.filter(
            row => countCells(row) < maxColumns
        );

        if (rowsMissingColumns.isEmpty()) {
            return undefined;
        }

        return change => {
            rowsMissingColumns.forEach(row => {
                const numberOfCellsToAdd = maxColumns - row.nodes.size;
                const cells = Array.from({ length: numberOfCellsToAdd }).map(
                    () => createCell(opts)
                );
                cells.forEach(cell =>
                    change.insertNodeByKey(row.key, row.nodes.size, cell, {
                        normalize: false
                    })
                );
            });
        };
    };
}
163726
function (namespace, extendSettings) {

    if (typeof namespace !== 'string' || !namespace.trim().length) {
      throw new Error('A valid string namespace is required as first parameter.');
    }

    namespace = namespace.trim();

    var settings = extend({}, globalSettings, extendSettings);
    var history = [];

    /**
     * Update instance settings.
     * @param  {Object} newSettings
     */
    this.update = function (newExtendSettings) {
      settings = extend({}, settings, newExtendSettings);
    };

    /**
     * Return settings.
     * @return {Object}
     */
    this.getSettings = function () {
      return extend({}, settings);
    };

    /**
     * Add a new method level to instance.
     * @param {Object} level - Level description.
     * @param {String} level.name - Level name.
     * @param {Number} [level.priority] - Number priority. Default to 3.
     * @param {String} [level.color] - The console color. Default `null`.
     */
     this.addLevel = function (level) {
      level = addLevel(level);
      this[level.name] = function () {
        this._execute(level, arguments);
      };
    };

    /**
     * Get a copy of the history. Meta objects are referenced.
     * @return {Array}
     */
    this.getHistory = function () {
      return history.map(function (item) {
        return extend({}, item);
      });
    };

    /**
     * Record a log in logger history if configured.
     * @private
     * @param  {Date} date - Date of log.
     * @param  {Object} level - Reference to the level definition.
     * @param  {String} text - The raw message.
     * @param  {Object} [meta] - Metadata.
     */
    this._record = function (date, level, text, meta) {
      if (settings.history) {
        var item = {
          date: date.getTime(),
          level: level.name,
          text: text,
        };
        if (meta) item.meta = meta;
        history.push(item);
      }
    };

    /**
     * Create a log description message by logger configuration.
     * @private
     * @param  {Date} date - Date of log.
     * @param  {Object} level - Reference to the level definition.
     * @return {String} - The description.
     */
    this._prefix = function (date, level) {

      var dtime = '';
      var dlevel = '';
      var dnamespace = '';

      if (settings.displayTime) {
        var hh = formatTime(date.getHours());
        var mm = formatTime(date.getMinutes());
        var ss = formatTime(date.getSeconds());
        var ms = formatTime(date.getMilliseconds(), 3);
        dtime = hh + ':' + mm + ':' + ss + '.' + ms + ' ';
      }

      if (settings.displayLevel) {
        dlevel = level.name.toUpperCase() +' ';
      }

      if (settings.displayNamespace) {
        dnamespace = '['+ namespace +'] ';
      }

      var dmsg = (dtime + dlevel + dnamespace).trim();
      dmsg = dmsg.length ? dmsg : '';

      return dmsg;
    };

    /**
     * Log the message in the console.
     * @private
     * @param  {Array} msgParts - Array of strings to log.
     */
    this._log = function (msgParts) {
      if (settings.display) {
        if (console && console.log) {
          console.log.apply(console.log, msgParts);
        }
      }
    };

    /**
     * Log method definition.
     * @private
     * @param  {Object} level - Reference to the level definition.
     * @param  {Array} args - The arguments received by the log method.
     */
    this._execute = function (level, args) {

      var date = new Date();
      var text = '';
      var meta = void 0;

      args = Array.prototype.slice.call(args, 0);
      for (var i=0; i<args.length; i++) {
        if (typeof args[i] === 'function') {
          // Functions are not used.
        } else if (i === args.length - 1 && Object(args[i]) === args[i]) {
          meta = args[i];
        } else {
          text += ' '+ args[i];
        }
      }
      text = text.trim();

      this._record(date, level, text, meta);

      if (settings.throwErrors && level.priority <= 0) {
        throw new Error(text);
      }

      if (level.priority <= settings.priority) {

        var prefix = this._prefix(date, level);
        var msgParts = [text];

        if (prefix.length) {
          if (settings.colors && level.color) {
            if (isNode) {
              msgParts = [level.color.node + prefix + NODE_COLOR_END +' '+ text];
            } else {
              msgParts = ['%c'+ prefix +' %c'+ text, level.color.browser, BROWSER_COLOR_END];
            }
          } else {
            msgParts = [prefix +' '+ text];
          }
        }

        this._log(msgParts);
      }
    };
  }
1236123
function BarVisualization(){
	/*
		Define the ID, name, and initialize the container. These are a part
		of the visualization template and are necessary.
	*/
	this.id = 'bar_visualization';
	this.name = 'Bar Visualization';
	this.container = '';

	/**
	 * Define the preferences for the visualization
	 */
	this.preferences = {
		bar_color: '#ff0000',
		width: 500,
		height: 200,
		inherit: true,
		spacer_width: 10,
		bar_width: 5,
		offset: 100,
		cutoff: 23
	}

	/*
		Intiialize the analyser used to generate the visualization.
	*/
	this.analyser = '';

	/*
		Initialize the local canvas height, canvas width, context, canvas
		and request animation variables.
	*/
	this.canvasHeight = '';
	this.canvasWidth = '';
	this.ctx = '';
	this.canvas = '';
	this.requestAnimation = '';

	/**
	 * Get the ID of the visualization.
	 */
	this.getID = function(){
		return this.id;
	}

	/**
	 * Get the name of the visualization.
	 */
	this.getName = function(){
		return this.name;
	}

	/**
	 * Set the preferences for the visualization.
	 *
	 * @param {object} userPreferences - The user preferences for the visualization.
	 */
	this.setPreferences = function( userPreferences ){
		for( var key in this.preferences ){
			if( userPreferences[ key ] != undefined) {
				this.preferences[key] = userPreferences[key];
			}
		}
	}

	/**
	 * Start the visualization.
	 *
	 * @param {Node} element - The element that will contain the visualization.
	 */
	this.startVisualization = function( element ){
		/*
			Set the analyser to the Amplitude analyser.
		*/
		this.analyser = Amplitude.getAnalyser();

		/*
			Set the container to the element passed in.
		*/
		this.container = element;

		/*
			Build a canvas element we can draw on for the visualization.
		*/
		this.canvas = document.createElement('canvas');

		/*
			If the user wants the size of the canvas to be the size of the container,
			set the width and height of the visualization to the width and height
			of the container.
		*/
		if( this.preferences.inherit ){
			this.preferences.width = this.container.offsetWidth;
			this.preferences.height = this.container.offsetHeight;
		}

		/*
			Set the width and height of the canvas element in the container.
		*/
		this.canvas.setAttribute('width', this.preferences.width);
		this.canvas.setAttribute('height', this.preferences.height);

		/*
			Get the 2D context of the canvas and append the canvas to the container.
		*/
		this.ctx = this.canvas.getContext('2d');
		this.container.appendChild( this.canvas );

		/*
			Set the local canvas height and canvas width variables to the width
			and height of the canvas. We will use these later.
		*/
		this.canvasHeight = this.canvas.height;
		this.canvasWidth = this.canvas.width;

		/*
			Kick off the visualization.
		*/
		this.rafCallback();
	}

	/**
	 * Stops the visualization and clears the container.
	 */
	this.stopVisualization = function(){
		window.cancelAnimationFrame( this.requestAnimation );
		this.container.innerHTML = '';
	}

	/**
	 * The callback that draws the visualization based on the frequency of the song.
	 */
	this.rafCallback = function( ){
		/*
			Builds an animation frame that updates the visualization to what is
			in the frequency.
		*/
		this.requestAnimation = window.requestAnimationFrame( this.rafCallback.bind(this), this.canvas );

		/*
			Get the frequency data from the analyser.
		*/
		let freqByteData = new Uint8Array( this.analyser.frequencyBinCount );
		this.analyser.getByteFrequencyData( freqByteData );

		/*
			Compute how many bars we need to have
		*/
		let numberOfBars = Math.round( this.canvasWidth / this.preferences.spacer_width );

		/*
			Build the rectangle for each of the elements in the visualization.
		*/
		this.ctx.clearRect( 0, 0, this.canvasWidth, this.canvasHeight );
		this.ctx.fillStyle = this.preferences.bar_color;
		this.ctx.lineCap = 'round';

		/*
			Iterate over how many bars we need and draw the height based
			off of the magnitude of the wave we are displaying
		*/
		for( let i = 0; i < numberOfBars; i++ ){
			let magnitude = freqByteData[ i + this.preferences.offset ];

			this.ctx.fillRect( i * this.preferences.spacer_width, this.canvasHeight, this.preferences.bar_width, -magnitude );
		}
	}
}
1062961
function _fnGetTrNodes ( oSettings )
		{
			var aNodes = [];
			var aoData = oSettings.aoData;
			for ( var i=0, iLen=aoData.length ; i<iLen ; i++ )
			{
				if ( aoData[i].nTr !== null )
				{
					aNodes.push( aoData[i].nTr );
				}
			}
			return aNodes;
		}
375379
function _fnBuildHead( oSettings )
		{
			var i, nTh, iLen, j, jLen;
			var iThs = oSettings.nTHead.getElementsByTagName('th').length;
			var iCorrector = 0;
			var jqChildren;
			
			/* If there is a header in place - then use it - otherwise it's going to get nuked... */
			if ( iThs !== 0 )
			{
				/* We've got a thead from the DOM, so remove hidden columns and apply width to vis cols */
				for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
				{
					nTh = oSettings.aoColumns[i].nTh;
					nTh.setAttribute('role', 'columnheader');
					if ( oSettings.aoColumns[i].bSortable )
					{
						nTh.setAttribute('tabindex', oSettings.iTabIndex);
						nTh.setAttribute('aria-controls', oSettings.sTableId);
					}
		
					if ( oSettings.aoColumns[i].sClass !== null )
					{
						$(nTh).addClass( oSettings.aoColumns[i].sClass );
					}
					
					/* Set the title of the column if it is user defined (not what was auto detected) */
					if ( oSettings.aoColumns[i].sTitle != nTh.innerHTML )
					{
						nTh.innerHTML = oSettings.aoColumns[i].sTitle;
					}
				}
			}
			else
			{
				/* We don't have a header in the DOM - so we are going to have to create one */
				var nTr = document.createElement( "tr" );
				
				for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
				{
					nTh = oSettings.aoColumns[i].nTh;
					nTh.innerHTML = oSettings.aoColumns[i].sTitle;
					nTh.setAttribute('tabindex', '0');
					
					if ( oSettings.aoColumns[i].sClass !== null )
					{
						$(nTh).addClass( oSettings.aoColumns[i].sClass );
					}
					
					nTr.appendChild( nTh );
				}
				$(oSettings.nTHead).html( '' )[0].appendChild( nTr );
				_fnDetectHeader( oSettings.aoHeader, oSettings.nTHead );
			}
			
			/* ARIA role for the rows */	
			$(oSettings.nTHead).children('tr').attr('role', 'row');
			
			/* Add the extra markup needed by jQuery UI's themes */
			if ( oSettings.bJUI )
			{
				for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
				{
					nTh = oSettings.aoColumns[i].nTh;
					
					var nDiv = document.createElement('div');
					nDiv.className = oSettings.oClasses.sSortJUIWrapper;
					$(nTh).contents().appendTo(nDiv);
					
					var nSpan = document.createElement('span');
					nSpan.className = oSettings.oClasses.sSortIcon;
					nDiv.appendChild( nSpan );
					nTh.appendChild( nDiv );
				}
			}
			
			if ( oSettings.oFeatures.bSort )
			{
				for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
				{
					if ( oSettings.aoColumns[i].bSortable !== false )
					{
						_fnSortAttachListener( oSettings, oSettings.aoColumns[i].nTh, i );
					}
					else
					{
						$(oSettings.aoColumns[i].nTh).addClass( oSettings.oClasses.sSortableNone );
					}
				}
			}
			
			/* Deal with the footer - add classes if required */
			if ( oSettings.oClasses.sFooterTH !== "" )
			{
				$(oSettings.nTFoot).children('tr').children('th').addClass( oSettings.oClasses.sFooterTH );
			}
			
			/* Cache the footer elements */
			if ( oSettings.nTFoot !== null )
			{
				var anCells = _fnGetUniqueThs( oSettings, null, oSettings.aoFooter );
				for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
				{
					if ( anCells[i] )
					{
						oSettings.aoColumns[i].nTf = anCells[i];
						if ( oSettings.aoColumns[i].sClass )
						{
							$(anCells[i]).addClass( oSettings.aoColumns[i].sClass );
						}
					}
				}
			}
		}
1088918
function(node, text, settings) {
      var prefix = settings('prefix') || '',
          size = node[prefix + 'size'];

      var fontSize = (settings('labelSize') === 'fixed') ?
        settings('defaultLabelSize') :
        settings('labelSizeRatio') * size;

      // Case when we don't want to display the label
      if (!settings('forceLabels') && size < settings('labelThreshold'))
        return;

      if (typeof node.label !== 'string')
        return;

      // Updating
      text.setAttributeNS(null, 'x',
        Math.round(node[prefix + 'x'] + size + 3));
      text.setAttributeNS(null, 'y',
        Math.round(node[prefix + 'y'] + fontSize / 3));

      // Showing
      text.style.display = '';

      return this;
    }
636610
function(setting, node, html) {
		var checkedKey = setting.data.key.checked;
		if (setting.check.enable) {
			data.makeChkFlag(setting, node);
			html.push("<span ID='", node.tId, consts.id.CHECK, "' class='", view.makeChkClass(setting, node), "' treeNode", consts.id.CHECK, (node.nocheck === true?" style='display:none;'":""),"></span>");
		}
	}
1299509
function(newSettings) {
      var s = '';

      if (typeof newSettings !== 'object') {
        throw new Error('ss.http.set() takes an object e.g. {static: {maxAge: 60000}}');
      }

      for (s in newSettings) {
        if (newSettings.hasOwnProperty(s)) {
          settings[s] = newSettings[s]
        }
      }
    }