text: 
  /* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells.
  ----------------------------------------------------------------------------------------------------------------------*/
  // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
  // It is responsible for managing width/height.
  
  var BasicView = View.extend({
  
  	dayGrid: null, // the main subcomponent that does most of the heavy lifting
  
  	dayNumbersVisible: false, // display day numbers on each day cell?
  	weekNumbersVisible: false, // display week numbers along the side?
  
  	weekNumberWidth: null, // width of all the week-number cells running down the side
  
  	headRowEl: null, // the fake row element of the day-of-week header
  
  
  	initialize: function() {
  		this.dayGrid = new DayGrid(this);
  		this.coordMap = this.dayGrid.coordMap; // the view's date-to-cell mapping is identical to the subcomponent's
  	},
  
  
  	// Sets the display range and computes all necessary dates
  	setRange: function(range) {
  		View.prototype.setRange.call(this, range); // call the super-method
  
  		this.dayGrid.breakOnWeeks = /year|month|week/.test(this.intervalUnit); // do before setRange
  		this.dayGrid.setRange(range);
  	},
  
  
  	// Compute the value to feed into setRange. Overrides superclass.
  	computeRange: function(date) {
  		var range = View.prototype.computeRange.call(this, date); // get value from the super-method
  
  		// year and month views should be aligned with weeks. this is already done for week
  		if (/year|month/.test(range.intervalUnit)) {
  			range.start.startOf('week');
  			range.start = this.skipHiddenDays(range.start);
  
  			// make end-of-week if not already
  			if (range.end.weekday()) {
  				range.end.add(1, 'week').startOf('week');
  				range.end = this.skipHiddenDays(range.end, -1, true); // exclusively move backwards
  			}
  		}
  
  		return range;
  	},
  
  
  	// Renders the view into `this.el`, which should already be assigned
  	renderDates: function() {
  
  		this.dayNumbersVisible = this.dayGrid.rowCnt > 1; // TODO: make grid responsible
  		this.weekNumbersVisible = this.opt('weekNumbers');
  		this.dayGrid.numbersVisible = this.dayNumbersVisible || this.weekNumbersVisible;
  
  		this.el.addClass('fc-basic-view').html(this.renderHtml());
  
  		this.headRowEl = this.el.find('thead .fc-row');
  
  		this.scrollerEl = this.el.find('.fc-day-grid-container');
  		this.dayGrid.coordMap.containerEl = this.scrollerEl; // constrain clicks/etc to the dimensions of the scroller
  
  		this.dayGrid.setElement(this.el.find('.fc-day-grid'));
  		this.dayGrid.renderDates(this.hasRigidRows());
  	},
  
  
  	// Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,
  	// always completely kill the dayGrid's rendering.
  	unrenderDates: function() {
  		this.dayGrid.unrenderDates();
  		this.dayGrid.removeElement();
  	},
  
  
  	renderBusinessHours: function() {
  		this.dayGrid.renderBusinessHours();
  	},
  
  
  	// Builds the HTML skeleton for the view.
  	// The day-grid component will render inside of a container defined by this HTML.
  	renderHtml: function() {
  		return '' +
  			'<table>' +
  				'<thead class="fc-head">' +
  					'<tr>' +
  						'<td class="' + this.widgetHeaderClass + '">' +
  							this.dayGrid.headHtml() + // render the day-of-week headers
  						'</td>' +
  					'</tr>' +
  				'</thead>' +
  				'<tbody class="fc-body">' +
  					'<tr>' +
  						'<td class="' + this.widgetContentClass + '">' +
  							'<div class="fc-day-grid-container">' +
  								'<div class="fc-day-grid"/>' +
  							'</div>' +
  						'</td>' +
  					'</tr>' +
  				'</tbody>' +
  			'</table>';
  	},
  
  
  	// Generates the HTML that will go before the day-of week header cells.
  	// Queried by the DayGrid subcomponent when generating rows. Ordering depends on isRTL.
  	headIntroHtml: function() {
  		if (this.weekNumbersVisible) {
  			return '' +
  				'<th class="fc-week-number ' + this.widgetHeaderClass + '" ' + this.weekNumberStyleAttr() + '>' +
  					'<span>' + // needed for matchCellWidths
  						htmlEscape(this.opt('weekNumberTitle')) +
  					'</span>' +
  				'</th>';
  		}
  	},
  
  
  	// Generates the HTML that will go before content-skeleton cells that display the day/week numbers.
  	// Queried by the DayGrid subcomponent. Ordering depends on isRTL.
  	numberIntroHtml: function(row) {
  		if (this.weekNumbersVisible) {
  			return '' +
  				'<td class="fc-week-number" ' + this.weekNumberStyleAttr() + '>' +
  					'<span>' + // needed for matchCellWidths
  						this.dayGrid.getCell(row, 0).start.format('w') +
  					'</span>' +
  				'</td>';
  		}
  	},
  
  
  	// Generates the HTML that goes before the day bg cells for each day-row.
  	// Queried by the DayGrid subcomponent. Ordering depends on isRTL.
  	dayIntroHtml: function() {
  		if (this.weekNumbersVisible) {
  			return '<td class="fc-week-number ' + this.widgetContentClass + '" ' +
  				this.weekNumberStyleAttr() + '></td>';
  		}
  	},
  
  
  	// Generates the HTML that goes before every other type of row generated by DayGrid. Ordering depends on isRTL.
  	// Affects helper-skeleton and highlight-skeleton rows.
  	introHtml: function() {
  		if (this.weekNumbersVisible) {
  			return '<td class="fc-week-number" ' + this.weekNumberStyleAttr() + '></td>';
  		}
  	},
  
  
  	// Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
  	// The number row will only exist if either day numbers or week numbers are turned on.
  	numberCellHtml: function(cell) {
  		var date = cell.start;
  		var classes;
  
  		if (!this.dayNumbersVisible) { // if there are week numbers but not day numbers
  			return '<td/>'; //  will create an empty space above events :(
  		}
  
  		classes = this.dayGrid.getDayClasses(date);
  		classes.unshift('fc-day-number');
  
  		return '' +
  			'<td class="' + classes.join(' ') + '" data-date="' + date.format() + '"><span>' +
  				date.date() +
  			'</span></td>';
  	},
  
  
  	// Generates an HTML attribute string for setting the width of the week number column, if it is known
  	weekNumberStyleAttr: function() {
  		if (this.weekNumberWidth !== null) {
  			return 'style="width:' + this.weekNumberWidth + 'px"';
  		}
  		return '';
  	},
  
  
  	// Determines whether each row should have a constant height
  	hasRigidRows: function() {
  		var eventLimit = this.opt('eventLimit');
  		return eventLimit && typeof eventLimit !== 'number';
  	},
  
  
  	/* Dimensions
  	------------------------------------------------------------------------------------------------------------------*/
  
  
  	// Refreshes the horizontal dimensions of the view
  	updateWidth: function() {
  		if (this.weekNumbersVisible) {
  			// Make sure all week number cells running down the side have the same width.
  			// Record the width for cells created later.
  			this.weekNumberWidth = matchCellWidths(
  				this.el.find('.fc-week-number')
  			);
  		}
  	},
  
  
  	// Adjusts the vertical dimensions of the view to the specified values
  	setHeight: function(totalHeight, isAuto) {
  		var eventLimit = this.opt('eventLimit');
  		var scrollerHeight;
  
  		// reset all heights to be natural
  		unsetScroller(this.scrollerEl);
  		uncompensateScroll(this.headRowEl);
  
  		this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
  
  		// is the event limit a constant level number?
  		if (eventLimit && typeof eventLimit === 'number') {
  			this.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after
  		}
  
  		scrollerHeight = this.computeScrollerHeight(totalHeight);
  		this.setGridHeight(scrollerHeight, isAuto);
  
  		// is the event limit dynamically calculated?
  		if (eventLimit && typeof eventLimit !== 'number') {
  			this.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set
  		}
  
  		if (!isAuto && setPotentialScroller(this.scrollerEl, scrollerHeight)) { // using scrollbars?
  
  			compensateScroll(this.headRowEl, getScrollbarWidths(this.scrollerEl));
  
  			// doing the scrollbar compensation might have created text overflow which created more height. redo
  			scrollerHeight = this.computeScrollerHeight(totalHeight);
  			this.scrollerEl.height(scrollerHeight);
  		}
  	},
  
  
  	// Sets the height of just the DayGrid component in this view
  	setGridHeight: function(height, isAuto) {
  		if (isAuto) {
  			undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding
  		}
  		else {
  			distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows
  		}
  	},
  
  
  	/* Events
  	------------------------------------------------------------------------------------------------------------------*/
  
  
  	// Renders the given events onto the view and populates the segments array
  	renderEvents: function(events) {
  		this.dayGrid.renderEvents(events);
  
  		this.updateHeight(); // must compensate for events that overflow the row
  	},
  
  
  	// Retrieves all segment objects that are rendered in the view
  	getEventSegs: function() {
  		return this.dayGrid.getEventSegs();
  	},
  
  
  	// Unrenders all event elements and clears internal segment data
  	unrenderEvents: function() {
  		this.dayGrid.unrenderEvents();
  
  		// we DON'T need to call updateHeight() because:
  		// A) a renderEvents() call always happens after this, which will eventually call updateHeight()
  		// B) in IE8, this causes a flash whenever events are rerendered
  	},
  
  
  	/* Dragging (for both events and external elements)
  	------------------------------------------------------------------------------------------------------------------*/
  
  
  	// A returned value of `true` signals that a mock "helper" event has been rendered.
  	renderDrag: function(dropLocation, seg) {
  		return this.dayGrid.renderDrag(dropLocation, seg);
  	},
  
  
  	unrenderDrag: function() {
  		this.dayGrid.unrenderDrag();
  	},
  
  
  	/* Selection
  	------------------------------------------------------------------------------------------------------------------*/
  
  
  	// Renders a visual indication of a selection
  	renderSelection: function(range) {
  		this.dayGrid.renderSelection(range);
  	},
  
  
  	// Unrenders a visual indications of a selection
  	unrenderSelection: function() {
  		this.dayGrid.unrenderSelection();
  	}
  
  });
  