import { setupRerender } from 'preact/test-utils';
import { createElement, render, Component } from 'preact';
import { setupScratch, teardown } from '../../_util/helpers';

/** @jsx createElement */

describe('Lifecycle methods', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	/** @type {() => void} */
	let rerender;

	beforeEach(() => {
		scratch = setupScratch();
		rerender = setupRerender();
	});

	afterEach(() => {
		teardown(scratch);
	});

	describe('#getSnapshotBeforeUpdate', () => {
		it('should pass the return value from getSnapshotBeforeUpdate to componentDidUpdate', () => {
			let log = [];

			class MyComponent extends Component {
				constructor(props) {
					super(props);
					this.state = {
						value: 0
					};
				}
				static getDerivedStateFromProps(nextProps, prevState) {
					return {
						value: prevState.value + 1
					};
				}
				getSnapshotBeforeUpdate(prevProps, prevState) {
					log.push(
						`getSnapshotBeforeUpdate() prevProps:${prevProps.value} prevState:${prevState.value}`
					);
					return 'abc';
				}
				componentDidUpdate(prevProps, prevState, snapshot) {
					log.push(
						`componentDidUpdate() prevProps:${prevProps.value} prevState:${prevState.value} snapshot:${snapshot}`
					);
				}
				render() {
					log.push('render');
					return null;
				}
			}

			render(<MyComponent value="foo" />, scratch);
			expect(log).to.deep.equal(['render']);
			log = [];

			render(<MyComponent value="bar" />, scratch);
			expect(log).to.deep.equal([
				'render',
				'getSnapshotBeforeUpdate() prevProps:foo prevState:1',
				'componentDidUpdate() prevProps:foo prevState:1 snapshot:abc'
			]);
			log = [];

			render(<MyComponent value="baz" />, scratch);
			expect(log).to.deep.equal([
				'render',
				'getSnapshotBeforeUpdate() prevProps:bar prevState:2',
				'componentDidUpdate() prevProps:bar prevState:2 snapshot:abc'
			]);
			log = [];

			render(
, scratch, scratch.firstChild);
			expect(log).to.deep.equal([]);
		});

		it('should call getSnapshotBeforeUpdate before mutations are committed', () => {
			let log = [];

			class MyComponent extends Component {
				getSnapshotBeforeUpdate(prevProps) {
					log.push('getSnapshotBeforeUpdate');
					expect(this.divRef.textContent).to.equal(`value:${prevProps.value}`);
					return 'foobar';
				}
				componentDidUpdate(prevProps, prevState, snapshot) {
					log.push('componentDidUpdate');
					expect(this.divRef.textContent).to.equal(`value:${this.props.value}`);
					expect(snapshot).to.equal('foobar');
				}
				render() {
					log.push('render');
					return (

 (this.divRef = ref)}
						>{`value:${this.props.value}`}

					);
				}
			}

			render(<MyComponent value="foo" />, scratch);
			expect(log).to.deep.equal(['render']);
			log = [];

			render(<MyComponent value="bar" />, scratch);
			expect(log).to.deep.equal([
				'render',
				'getSnapshotBeforeUpdate',
				'componentDidUpdate'
			]);
		});

		it('should be passed the previous props and state', () => {
			/** @type {() => void} */
			let updateState;

			let prevPropsArg;
			let prevStateArg;
			let curProps;
			let curState;

			class Foo extends Component {
				constructor(props) {
					super(props);
					this.state = {
						value: 0
					};
					updateState = () =>
						this.setState({
							value: this.state.value + 1
						});
				}
				static getDerivedStateFromProps(props, state) {
					// NOTE: Don't do this in real production code!
					// https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
					return {
						value: state.value + 1
					};
				}
				getSnapshotBeforeUpdate(prevProps, prevState) {
					// These object references might be updated later so copy
					// object so we can assert their values at this snapshot in time
					prevPropsArg = { ...prevProps };
					prevStateArg = { ...prevState };

					curProps = { ...this.props };
					curState = { ...this.state };
				}
				render() {
					return
{this.state.value}
;
				}
			}

			// Expectation:
			// `prevState` in getSnapshotBeforeUpdate should be
			// the state before setState or getDerivedStateFromProps was called.
			// `this.state` in getSnapshotBeforeUpdate should be
			// the updated state after getDerivedStateFromProps was called.

			// Initial render
			// state.value: initialized to 0 in constructor, 0 -> 1 in gDSFP
			render(<Foo foo="foo" />, scratch);
			const element = scratch.firstChild;

			expect(element.textContent).to.be.equal('1');
			expect(prevPropsArg).to.be.undefined;
			expect(prevStateArg).to.be.undefined;
			expect(curProps).to.be.undefined;
			expect(curState).to.be.undefined;

			// New props
			// state.value: 1 -> 2 in gDSFP
			render(<Foo foo="bar" />, scratch);

			expect(element.textContent).to.be.equal('2');
			expect(prevPropsArg).to.deep.equal({
				foo: 'foo'
			});
			expect(prevStateArg).to.deep.equal({
				value: 1
			});
			expect(curProps).to.deep.equal({
				foo: 'bar'
			});
			expect(curState).to.deep.equal({
				value: 2
			});

			// New state
			// state.value: 2 -> 3 in updateState, 3 -> 4 in gDSFP
			updateState();
			rerender();
			expect(element.textContent).to.be.equal('4');
			expect(prevPropsArg).to.deep.equal({
				foo: 'bar'
			});
			expect(prevStateArg).to.deep.equal({
				value: 2
			});
			expect(curProps).to.deep.equal({
				foo: 'bar'
			});
			expect(curState).to.deep.equal({
				value: 4
			});
		});
	});
});


frameworks: ['source-map-support', 'mocha', 'chai-sinon'],

keep keep keep keep replace keep keep keep keep

import { setupRerender } from 'preact/test-utils';
import { createElement, render, Component, Fragment, hydrate } from 'preact';
import { setupScratch, teardown } from '../_util/helpers';
import { div, span, input as inputStr, h1, h2 } from '../_util/dom';

/** @jsx createElement */
/* eslint-disable react/jsx-boolean-value */

describe('focus', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	/** @type {() => void} */
	let rerender;

	const List = ({ children }) =>
{children}
;
	const ListItem = ({ children }) => {children};
	const InputWithId = ({ i }) => <input id={`input-${i}`} type="text" />;
	const Input = () => <input type="text" />;

	function focusInput() {
		if (!scratch) return;

		const input = scratch.querySelector('input');
		input.value = 'a word';
		input.focus();
		input.setSelectionRange(2, 5);

		expect(document.activeElement).to.equalNode(input);

		return input;
	}

	function focusInputById() {
		if (!scratch) return;

		const input = scratch.querySelector('#input-0');
		input.value = 'a word';
		input.focus();
		input.setSelectionRange(2, 5);

		expect(document.activeElement).to.equalNode(input);

		return input;
	}

	/**
	 * Validate an input tag has maintained focus
	 * @param {HTMLInputElement} input The input to validate
	 * @param {string} [message] Message to show if the activeElement is not
	 * equal to the `input` parameter
	 */
	function validateFocus(input, message) {
		expect(document.activeElement).to.equalNode(input, message);
		expect(input.selectionStart).to.equal(2);
		expect(input.selectionEnd).to.equal(5);
	}

	/**
	 * @param {Array<number | string>} before
	 * @param {Array<number | string>} after
	 */
	function getListHtml(before, after) {
		return div([
			...before.map(i => span(i)),
			inputStr(),
			...after.map(i => span(i))
		]);
	}

	beforeEach(() => {
		scratch = setupScratch();
		rerender = setupRerender();
	});

	afterEach(() => {
		teardown(scratch);
	});

	it.skip('should maintain focus when swapping elements', () => {
		render(
			<List>
				<Input />
				<ListItem>fooo</ListItem>
			</List>,
			scratch
		);

		const input = focusInput();
		expect(scratch.innerHTML).to.equal(getListHtml([], ['fooo']));

		render(
			<List>
				<ListItem>fooo</ListItem>
				<Input />
			</List>,
			scratch
		);
		validateFocus(input);
		expect(scratch.innerHTML).to.equal(getListHtml(['fooo'], []));
	});

	it('should maintain focus when moving the input around', () => {
		function App({ showFirst, showLast }) {
			return (
				<List>
					{showFirst ? <ListItem>1</ListItem> : null}
					<Input />
					{showLast ? <ListItem>2</ListItem> : null}
				</List>
			);
		}

		render(<App showFirst={true} showLast={true} />, scratch);

		let input = focusInput();
		render(<App showFirst={false} showLast={true} />, scratch);
		expect(scratch.innerHTML).to.equal(getListHtml([], [2]));
		validateFocus(input, 'move from middle to beginning');

		input = focusInput();
		render(<App showFirst={true} showLast={true} />, scratch);
		expect(scratch.innerHTML).to.equal(getListHtml([1], [2]));
		validateFocus(input, 'move from beginning to middle');

		input = focusInput();
		render(<App showFirst={true} showLast={false} />, scratch);
		expect(scratch.innerHTML).to.equal(getListHtml([1], []));
		validateFocus(input, 'move from middle to end');

		input = focusInput();
		render(<App showFirst={true} showLast={true} />, scratch);
		expect(scratch.innerHTML).to.equal(getListHtml([1], [2]));
		validateFocus(input, 'move from end to middle');
	});

	it('should maintain focus when adding children around input', () => {
		render(
			<List>
				<Input />
			</List>,
			scratch
		);

		let input = focusInput();
		expect(scratch.innerHTML).to.equal(getListHtml([], []));

		render(
			<List>
				<ListItem key="1">1</ListItem>
				<Input />
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([1], []));
		validateFocus(input, 'insert sibling before');

		render(
			<List>
				<ListItem key="1">1</ListItem>
				<Input />
				<ListItem key="2">2</ListItem>
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([1], [2]));
		validateFocus(input, 'insert sibling after');

		render(
			<List>
				<ListItem key="1">1</ListItem>
				<Input />
				<ListItem key="2">2</ListItem>
				<ListItem key="3">3</ListItem>
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([1], [2, 3]));
		validateFocus(input, 'insert sibling after again');

		render(
			<List>
				<ListItem key="0">0</ListItem>
				<ListItem key="1">1</ListItem>
				<Input />
				<ListItem key="2">2</ListItem>
				<ListItem key="3">3</ListItem>
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([0, 1], [2, 3]));
		validateFocus(input, 'insert sibling before again');
	});

	it('should maintain focus when conditional elements around input', () => {
		render(
			<List>
				<ListItem>0</ListItem>
				<ListItem>1</ListItem>
				<Input />
				<ListItem>2</ListItem>
				<ListItem>3</ListItem>
			</List>,
			scratch
		);

		let input = focusInput();
		expect(scratch.innerHTML).to.equal(getListHtml([0, 1], [2, 3]));

		render(
			<List>
				{false && <ListItem>0</ListItem>}
				<ListItem>1</ListItem>
				<Input />
				<ListItem>2</ListItem>
				<ListItem>3</ListItem>
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([1], [2, 3]));
		validateFocus(input, 'remove sibling before');

		render(
			<List>
				{false && <ListItem>0</ListItem>}
				<ListItem>1</ListItem>
				<Input />
				<ListItem>2</ListItem>
				{false && <ListItem>3</ListItem>}
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([1], [2]));
		validateFocus(input, 'remove sibling after');

		render(
			<List>
				{false && <ListItem>0</ListItem>}
				<ListItem>1</ListItem>
				<Input />
				{false && <ListItem>2</ListItem>}
				{false && <ListItem>3</ListItem>}
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([1], []));
		validateFocus(input, 'remove sibling after 2');

		render(
			<List>
				{false && <ListItem>0</ListItem>}
				{false && <ListItem>1</ListItem>}
				<Input />
				{false && <ListItem>2</ListItem>}
				{false && <ListItem>3</ListItem>}
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([], []));
		validateFocus(input, 'remove sibling before 2');
	});

	it('should maintain focus when removing elements around input', () => {
		render(
			<List>
				<ListItem key="0">0</ListItem>
				<ListItem key="1">1</ListItem>
				<Input />
				<ListItem key="2">2</ListItem>
				<ListItem key="3">3</ListItem>
			</List>,
			scratch
		);

		let input = focusInput();
		expect(scratch.innerHTML).to.equal(getListHtml([0, 1], [2, 3]));

		render(
			<List>
				<ListItem key="1">1</ListItem>
				<Input />
				<ListItem key="2">2</ListItem>
				<ListItem key="3">3</ListItem>
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([1], [2, 3]));
		validateFocus(input, 'remove sibling before');

		render(
			<List>
				<ListItem key="1">1</ListItem>
				<Input />
				<ListItem key="2">2</ListItem>
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([1], [2]));
		validateFocus(input, 'remove sibling after');

		render(
			<List>
				<ListItem key="1">1</ListItem>
				<Input />
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([1], []));
		validateFocus(input, 'remove sibling after 2');

		render(
			<List>
				<Input />
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(getListHtml([], []));
		validateFocus(input, 'remove sibling before 2');
	});

	it('should maintain focus when adding input next to the current input', () => {
		render(
			<List>
				<InputWithId i={0} />
			</List>,
			scratch
		);

		let input = focusInputById();

		render(
			<List>
				<Input key="1" />
				<InputWithId i={0} />
			</List>,
			scratch
		);
		validateFocus(input, 'add input before');

		input = focusInputById();

		render(
			<List>
				<Input key="1" />
				<InputWithId i={0} />
				<Input key="2" />
			</List>,
			scratch
		);
		validateFocus(input, 'add input after');

		input = focusInputById();

		render(
			<List>
				<Input key="0" />
				<Input key="1" />
				<InputWithId i={0} />
				<Input key="2" />
			</List>,
			scratch
		);
		validateFocus(input, 'add input first place');

		input = focusInputById();

		render(
			<List>
				<Input key="-1" />
				<Input key="0" />
				<Input key="1" />
				<InputWithId i={0} />
				<Input key="2" />
			</List>,
			scratch
		);
		validateFocus(input, 'add input before');
	});

	it('should maintain focus when hydrating', () => {
		const html = div([span('1'), span('2'), span('3'), inputStr()]);

		scratch.innerHTML = html;
		const input = focusInput();

		hydrate(
			<List>
				<ListItem>1</ListItem>
				<ListItem>2</ListItem>
				<ListItem>3</ListItem>
				<Input />
			</List>,
			scratch
		);

		expect(scratch.innerHTML).to.equal(html);
		validateFocus(input);
	});

	it('should keep focus in Fragments', () => {
		/** @type {HTMLInputElement} */
		let input;

		/** @type {() => void} */
		let updateState;

		class App extends Component {
			constructor() {
				super();
				this.state = { active: false };
				updateState = () => this.setState(prev => ({ active: !prev.active }));
			}

			render() {
				return (

Heading

						{!this.state.active ? (
							<Fragment>
								foobar
								<Fragment>
									Hello World

yo

								</Fragment>
								<input type="text" ref={i => (input = i)} />
							</Fragment>
						) : (
							<Fragment>
								<Fragment>
									Hello World

yo

								</Fragment>
								foobar
								<input type="text" ref={i => (input = i)} />
							</Fragment>
						)}

				);
			}
		}

		render(<App />, scratch);

		input.focus();
		updateState();

		expect(document.activeElement).to.equalNode(input, 'Before rerender');
		rerender();

		expect(scratch.innerHTML).to.equal(
			div([h1('Heading'), 'Hello World', h2('yo'), 'foobar', inputStr()])
		);
		expect(document.activeElement).to.equalNode(input, 'After rerender');
	});

	it('should keep text selection', () => {
		/** @type {HTMLInputElement} */
		let input;

		/** @type {() => void} */
		let updateState;

		class App extends Component {
			constructor() {
				super();
				this.state = { active: false };
				updateState = () => this.setState(prev => ({ active: !prev.active }));
			}

			render() {
				return (

Heading

						{!this.state.active ? (
							<Fragment>
								foobar
								<Fragment>
									Hello World

yo

								</Fragment>
								<input type="text" ref={i => (input = i)} value="foobar" />
							</Fragment>
						) : (
							<Fragment>
								<Fragment>
									Hello World

yo

								</Fragment>
								foobar
								<input type="text" ref={i => (input = i)} value="foobar" />
							</Fragment>
						)}

				);
			}
		}

		render(<App />, scratch);

		input.focus();
		input.setSelectionRange(2, 5);
		updateState();

		expect(document.activeElement).to.equalNode(input, 'Before rerender');
		rerender();

		expect(scratch.innerHTML).to.equal(
			div([h1('Heading'), 'Hello World', h2('yo'), 'foobar', inputStr()])
		);
		expect(input.selectionStart).to.equal(2);
		expect(input.selectionEnd).to.equal(5);
		expect(document.activeElement).to.equalNode(input, 'After rerender');
	});
});


keep keep keep replace replace replace replace replace replace replace replace replace keep keep keep

/*eslint no-var:0, object-shorthand:0 */

var coverage = String(process.env.COVERAGE) === 'true',
	ci = String(process.env.CI).match(/^(1|true)$/gi),
	pullRequest = !String(process.env.TRAVIS_PULL_REQUEST).match(
		/^(0|false|undefined)$/gi
	),
	masterBranch = String(process.env.TRAVIS_BRANCH).match(/^master$/gi),
	sauceLabs = ci && !pullRequest && masterBranch,
	performance = !coverage && String(process.env.PERFORMANCE) !== 'false',
	webpack = require('webpack'),
	path = require('path');

var sauceLabsLaunchers = {
	sl_chrome: {
		base: 'SauceLabs',
		browserName: 'chrome',
		platform: 'Windows 10'
	},
	sl_firefox: {
		base: 'SauceLabs',
		browserName: 'firefox',
		platform: 'Windows 10'
	},
	// TODO: Safari always fails and disconnects before any tests are executed.
	// This seems to be an issue with Saucelabs and they're actively investigating
	// that (see: https://mobile.twitter.com/bromann/status/1136323458328084482).
	// We'll disable Safari for now until that's resolved.
	// sl_safari: {
	// 	base: 'SauceLabs',
	// 	browserName: 'Safari',
	// 	version: '11',
	// 	platform: 'OS X 10.13'
	// },
	sl_edge: {
		base: 'SauceLabs',
		browserName: 'MicrosoftEdge',
		platform: 'Windows 10'
	},
	sl_ie_11: {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		version: '11.0',
		platform: 'Windows 7'
	}
};

var localLaunchers = {
	ChromeNoSandboxHeadless: {
		base: 'Chrome',
		flags: [
			'--no-sandbox',
			'--disable-setuid-sandbox',
			// See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
			'--headless',
			'--disable-gpu',
			'--no-gpu',
			// Without a remote debugging port, Google Chrome exits immediately.
			'--remote-debugging-port=9333'
		]
	}
};

module.exports = function(config) {
	const watchMode = config.singleRun;

	config.set({
		browsers: sauceLabs
			? Object.keys(sauceLabsLaunchers)
			: Object.keys(localLaunchers),

		frameworks: ['source-map-support', 'mocha', 'chai-sinon'],

		reporters: ['mocha'].concat(
			coverage ? 'coverage' : [],
			sauceLabs ? 'saucelabs' : []
		),

		coverageReporter: {
			dir: path.join(__dirname, 'coverage'),
			reporters: [
				{ type: 'text-summary' },
				{ type: 'html' },
				{ type: 'lcovonly', subdir: '.', file: 'lcov.info' }
			]
		},

		mochaReporter: {
			showDiff: true
		},

		browserLogOptions: { terminal: true },
		browserConsoleLogOptions: { terminal: true },

		browserNoActivityTimeout: 5 * 60 * 1000,

		// Use only two browsers concurrently, works better with open source Sauce Labs remote testing
		concurrency: 2,

		captureTimeout: 0,

		sauceLabs: {
			build: `CI #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`,
			tunnelIdentifier:
				process.env.TRAVIS_JOB_NUMBER ||
				`local${require('./package.json').version}`,
			connectLocationForSERelay: 'localhost',
			connectPortForSERelay: 4445,
			startConnect: false
		},

		customLaunchers: sauceLabs ? sauceLabsLaunchers : localLaunchers,

		files: [
			{ pattern: 'test/polyfills.js', watched: false },
			{
				pattern:
					config.grep ||
					'{debug,hooks,compat,test-utils,}/test/{browser,shared}/**/*.test.js',
				watched: false
			}
		],

		preprocessors: {
			'{debug,hooks,compat,test-utils,}/test/**/*': ['webpack', 'sourcemap']
		},

		webpack: {
			output: {
				filename: '[name].js'
			},
			mode: 'development',
			devtool: 'inline-source-map',
			module: {
				noParse: [/benchmark\.js$/],

				/* Transpile source and test files */
				rules: [
					// Special case for sinon.js which ships ES2015+ code in their
					// esm bundle
					{
						test: /node_modules\/sinon\/.*\.jsx?$/,
						loader: 'babel-loader'
					},

					{
						test: /\.jsx?$/,
						exclude: /node_modules/,
						loader: 'babel-loader',
						options: {
							plugins: [
								coverage && ['istanbul', { include: '**/dist/**/*.js' }]
							].filter(Boolean)
						}
					}
				]
			},
			resolve: {
				// The React DevTools integration requires preact as a module
				// rather than referencing source files inside the module
				// directly
				alias: {
					'preact/debug': path.join(__dirname, './debug/'),
					'preact/devtools': path.join(__dirname, './devtools/'),
					'preact/compat': path.join(__dirname, './compat/'),
					'preact/hooks': path.join(__dirname, './hooks/'),
					'preact/test-utils': path.join(__dirname, './test-utils/'),
					preact: path.join(__dirname, '')
				}
			},
			plugins: [
				new webpack.DefinePlugin({
					coverage: coverage,
					NODE_ENV: JSON.stringify(process.env.NODE_ENV || ''),
					ENABLE_PERFORMANCE: performance
				})
			],
			performance: {
				hints: false
			}
		},

		webpackMiddleware: {
			noInfo: true,
			stats: 'errors-only'
		}
	});
};


// import React from '../../src';
import * as React from '../../src';
class ReactIsh extends React.Component {
	render() {
		return
Text

	}
}


hooks

Hook addon for Preact

karma start test/karma.conf.js --single-run

karma start test/karma.conf.js --no-single-run


import { createElement, Suspense, lazy, Component } from 'react';

const Loading = function() {
	return
Loading...
;
};
const Error = function({ resetState }) {
	return (

			Error!

				Reset app

	);
};

const pause = timeout =>
	new Promise(d => setTimeout(d, timeout), console.log(timeout));

const DropZone = lazy(() =>
	pause(Math.random() * 1000).then(() => import('./dropzone.js'))
);
const Editor = lazy(() =>
	pause(Math.random() * 1000).then(() => import('./editor.js'))
);
const AddNewComponent = lazy(() =>
	pause(Math.random() * 1000).then(() => import('./addnewcomponent.js'))
);
const GenerateComponents = lazy(() =>
	pause(Math.random() * 1000).then(() => import('./component-container.js'))
);

export default class App extends Component {
	state = { hasError: false };

	static getDerivedStateFromError(error) {
		// Update state so the next render will show the fallback UI.
		console.warn(error);
		return { hasError: true };
	}

	render() {
		return this.state.hasError ? (
			<Error resetState={() => this.setState({ hasError: false })} />
		) : (
			<Suspense fallback={<Loading />}>
				<DropZone appearance={0} />
				<Editor title="APP_TITLE">

						<Suspense fallback={<Loading />}>
							<GenerateComponents appearance={1} />
						</Suspense>
						<AddNewComponent appearance={2} />

							<Suspense fallback={<Loading />}>
								<GenerateComponents appearance={3} />
							</Suspense>
							<AddNewComponent appearance={4} />

				</Editor>

				Footer here
			</Suspense>
		);
	}
}


(function ($) {

  var methods = {
    init : function(options) {
      var defaults = {
        menuWidth: 240,
        edge: 'left',
        closeOnClick: false
      };
      options = $.extend(defaults, options);

      $(this).each(function(){
        var $this = $(this);
        var menu_id = $("#"+ $this.attr('data-activates'));

        // Set to width
        if (options.menuWidth != 240) {
          menu_id.css('width', options.menuWidth);
        }

        // Add Touch Area
        var dragTarget = $('

');
        $('body').append(dragTarget);

        if (options.edge == 'left') {
          menu_id.css('transform', 'translateX(-100%)');
          dragTarget.css({'left': 0}); // Add Touch Area
        }
        else {
          menu_id.addClass('right-aligned') // Change text-alignment to right
            .css('transform', 'translateX(100%)');
          dragTarget.css({'right': 0}); // Add Touch Area
        }

        // If fixed sidenav, bring menu out
        if (menu_id.hasClass('fixed')) {
            if (window.innerWidth > 992) {
              menu_id.css('transform', 'translateX(0)');
            }
          }

        // Window resize to reset on large screens fixed
        if (menu_id.hasClass('fixed')) {
          $(window).resize( function() {
            if (window.innerWidth > 992) {
              // Close menu if window is resized bigger than 992 and user has fixed sidenav
              if ($('#sidenav-overlay').length != 0 && menuOut) {
                removeMenu(true);
              }
              else {
                // menu_id.removeAttr('style');
                menu_id.css('transform', 'translateX(0%)');
                // menu_id.css('width', options.menuWidth);
              }
            }
            else if (menuOut === false){
              if (options.edge === 'left') {
                menu_id.css('transform', 'translateX(-100%)');
              } else {
                menu_id.css('transform', 'translateX(100%)');
              }

            }

          });
        }

        // if closeOnClick, then add close event for all a tags in side sideNav
        if (options.closeOnClick === true) {
          menu_id.on("click.itemclick", "a:not(.collapsible-header)", function(){
            removeMenu();
          });
        }

        function removeMenu(restoreNav) {
          panning = false;
          menuOut = false;
          // Reenable scrolling
          $('body').css('overflow', '');

          $('#sidenav-overlay').velocity({opacity: 0}, {duration: 200,
              queue: false, easing: 'easeOutQuad',
            complete: function() {
              $(this).remove();
            } });
          if (options.edge === 'left') {
            // Reset phantom div
            dragTarget.css({width: '', right: '', left: '0'});
            menu_id.velocity(
              {'translateX': '-100%'},
              { duration: 200,
                queue: false,
                easing: 'easeOutCubic',
                complete: function() {
                  if (restoreNav === true) {
                    // Restore Fixed sidenav
                    menu_id.removeAttr('style');
                    menu_id.css('width', options.menuWidth);
                  }
                }

            });
          }
          else {
            // Reset phantom div
            dragTarget.css({width: '', right: '0', left: ''});
            menu_id.velocity(
              {'translateX': '100%'},
              { duration: 200,
                queue: false,
                easing: 'easeOutCubic',
                complete: function() {
                  if (restoreNav === true) {
                    // Restore Fixed sidenav
                    menu_id.removeAttr('style');
                    menu_id.css('width', options.menuWidth);
                  }
                }
              });
          }
        }

        // Touch Event
        var panning = false;
        var menuOut = false;

        dragTarget.on('click', function(){
          removeMenu();
        });

        dragTarget.hammer({
          prevent_default: false
        }).bind('pan', function(e) {

          if (e.gesture.pointerType == "touch") {

            var direction = e.gesture.direction;
            var x = e.gesture.center.x;
            var y = e.gesture.center.y;
            var velocityX = e.gesture.velocityX;

            // Disable Scrolling
            $('body').css('overflow', 'hidden');

            // If overlay does not exist, create one and if it is clicked, close menu
            if ($('#sidenav-overlay').length === 0) {
              var overlay = $('

');
              overlay.css('opacity', 0).click( function(){
                removeMenu();
              });
              $('body').append(overlay);
            }

            // Keep within boundaries
            if (options.edge === 'left') {
              if (x > options.menuWidth) { x = options.menuWidth; }
              else if (x < 0) { x = 0; }
            }

            if (options.edge === 'left') {
              // Left Direction
              if (x < (options.menuWidth / 2)) { menuOut = false; }
              // Right Direction
              else if (x >= (options.menuWidth / 2)) { menuOut = true; }
              menu_id.css('transform', 'translateX(' + (x - options.menuWidth) + 'px)');
            }
            else {
              // Left Direction
              if (x < (window.innerWidth - options.menuWidth / 2)) {
                menuOut = true;
              }
              // Right Direction
              else if (x >= (window.innerWidth - options.menuWidth / 2)) {
               menuOut = false;
             }
              var rightPos = (x - options.menuWidth / 2);
              if (rightPos < 0) {
                rightPos = 0;
              }

              menu_id.css('transform', 'translateX(' + rightPos + 'px)');
            }

            // Percentage overlay
            var overlayPerc;
            if (options.edge === 'left') {
              overlayPerc = x / options.menuWidth;
              $('#sidenav-overlay').velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'});
            }
            else {
              overlayPerc = Math.abs((x - window.innerWidth) / options.menuWidth);
              $('#sidenav-overlay').velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'});
            }
          }

        }).bind('panend', function(e) {

          if (e.gesture.pointerType == "touch") {
            var velocityX = e.gesture.velocityX;
            var x = e.gesture.center.x;
            var leftPos = x - options.menuWidth;
            var rightPos = x - options.menuWidth / 2;
            if (leftPos > 0 ) {
              leftPos = 0;
            }
            if (rightPos < 0) {
              rightPos = 0;
            }
            panning = false;

            if (options.edge === 'left') {
              // If velocityX <= 0.3 then the user is flinging the menu closed so ignore menuOut
              if ((menuOut && velocityX <= 0.3) || velocityX < -0.5) {
                if (leftPos != 0) {
                  menu_id.velocity({'translateX': [0, leftPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
                }

                // menu_id.css({'translateX': 0});
                $('#sidenav-overlay').velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
                dragTarget.css({width: '50%', right: 0, left: ''});
              }
              else if (!menuOut || velocityX > 0.3) {
                // Enable Scrolling
                $('body').css('overflow', '');
                // Slide menu closed
                menu_id.velocity({'translateX': [-1 * options.menuWidth - 10, leftPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'});
                $('#sidenav-overlay').velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad',
                  complete: function () {
                    $(this).remove();
                  }});
                dragTarget.css({width: '10px', right: '', left: 0});
              }
            }
            else {
              if ((menuOut && velocityX >= -0.3) || velocityX > 0.5) {
                menu_id.velocity({'translateX': [0, rightPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
                $('#sidenav-overlay').velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
                dragTarget.css({width: '50%', right: '', left: 0});
              }
              else if (!menuOut || velocityX < -0.3) {
                // Enable Scrolling
                $('body').css('overflow', '');
                // Slide menu closed
                menu_id.velocity({'translateX': [options.menuWidth + 10, rightPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'});
                $('#sidenav-overlay').velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad',
                  complete: function () {
                    $(this).remove();
                  }});
                dragTarget.css({width: '10px', right: 0, left: ''});
              }
            }

          }
        });

          $this.click(function() {
            if (menuOut === true) {
              menuOut = false;
              panning = false;
              removeMenu();
            }
            else {

              // Disable Scrolling
              $('body').css('overflow', 'hidden');
              // Push current drag target on top of DOM tree
              $('body').append(dragTarget);

              if (options.edge === 'left') {
                dragTarget.css({width: '50%', right: 0, left: ''});
                menu_id.velocity({'translateX': [0, -1 * options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
              }
              else {
                dragTarget.css({width: '50%', right: '', left: 0});
                menu_id.velocity({'translateX': [0, options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
              }

              var overlay = $('

');
              overlay.css('opacity', 0)
              .click(function(){
                menuOut = false;
                panning = false;
                removeMenu();
                overlay.velocity({opacity: 0}, {duration: 300, queue: false, easing: 'easeOutQuad',
                  complete: function() {
                    $(this).remove();
                  } });

              });
              $('body').append(overlay);
              overlay.velocity({opacity: 1}, {duration: 300, queue: false, easing: 'easeOutQuad',
                complete: function () {
                  menuOut = true;
                  panning = false;
                }
              });
            }

            return false;
          });
      });

    },
    show : function() {
      this.trigger('click');
    },
    hide : function() {
      $('#sidenav-overlay').trigger('click');
    }
  };

    $.fn.sideNav = function(methodOrOptions) {
      if ( methods[methodOrOptions] ) {
        return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));
      } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
        // Default to "init"
        return methods.init.apply( this, arguments );
      } else {
        $.error( 'Method ' +  methodOrOptions + ' does not exist on jQuery.sideNav' );
      }
    }; // Plugin end
}( jQuery ));


- var no_nav = false
- var page = "Dialogs"

doctype html
html(lang="en")
  head
    include _head.jade
  body
    include _navbar.jade
    main
      include page-contents/dialogs_content.html
    include _footer.html
    include _scripts.html
  script(type='text/javascript').
    var displayCustomHTMLToast = function () {
      var $toastContent = $('I am toast content');
      Materialize.toast($toastContent, 5000);
    }


!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(t){function e(){var e=a(this),o=r.settings;return isNaN(e.datetime)||(0==o.cutoff||Math.abs(n(e.datetime))<o.cutoff)&&t(this).text(i(e.datetime)),this}function a(e){if(e=t(e),!e.data("timeago")){e.data("timeago",{datetime:r.datetime(e)});var a=t.trim(e.text());r.settings.localeTitle?e.attr("title",e.data("timeago").datetime.toLocaleString()):!(a.length>0)||r.isTime(e)&&e.attr("title")||e.attr("title",a)}return e.data("timeago")}function i(t){return r.inWords(n(t))}function n(t){return(new Date).getTime()-t.getTime()}t.timeago=function(e){return i(e instanceof Date?e:"string"==typeof e?t.timeago.parse(e):"number"==typeof e?new Date(e):t.timeago.datetime(e))};var r=t.timeago;t.extend(t.timeago,{settings:{refreshMillis:6e4,allowPast:!0,allowFuture:!1,localeTitle:!1,cutoff:0,strings:{prefixAgo:null,prefixFromNow:null,suffixAgo:"ago",suffixFromNow:"from now",inPast:"any moment now",seconds:"less than a minute",minute:"about a minute",minutes:"%d minutes",hour:"about an hour",hours:"about %d hours",day:"a day",days:"%d days",month:"about a month",months:"%d months",year:"about a year",years:"%d years",wordSeparator:" ",numbers:[]}},inWords:function(e){function a(a,n){var r=t.isFunction(a)?a(n,e):a,o=i.numbers&&i.numbers[n]||n;return r.replace(/%d/i,o)}if(!this.settings.allowPast&&!this.settings.allowFuture)throw"timeago allowPast and allowFuture settings can not both be set to false.";var i=this.settings.strings,n=i.prefixAgo,r=i.suffixAgo;if(this.settings.allowFuture&&0>e&&(n=i.prefixFromNow,r=i.suffixFromNow),!this.settings.allowPast&&e>=0)return this.settings.strings.inPast;var o=Math.abs(e)/1e3,s=o/60,u=s/60,m=u/24,l=m/365,d=45>o&&a(i.seconds,Math.round(o))||90>o&&a(i.minute,1)||45>s&&a(i.minutes,Math.round(s))||90>s&&a(i.hour,1)||24>u&&a(i.hours,Math.round(u))||42>u&&a(i.day,1)||30>m&&a(i.days,Math.round(m))||45>m&&a(i.month,1)||365>m&&a(i.months,Math.round(m/30))||1.5>l&&a(i.year,1)||a(i.years,Math.round(l)),f=i.wordSeparator||"";return void 0===i.wordSeparator&&(f=" "),t.trim([n,d,r].join(f))},parse:function(e){var a=t.trim(e);return a=a.replace(/\.\d+/,""),a=a.replace(/-/,"/").replace(/-/,"/"),a=a.replace(/T/," ").replace(/Z/," UTC"),a=a.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"),a=a.replace(/([\+\-]\d\d)$/," $100"),new Date(a)},datetime:function(e){var a=t(e).attr(r.isTime(e)?"datetime":"title");return r.parse(a)},isTime:function(e){return"time"===t(e).get(0).tagName.toLowerCase()}});var o={init:function(){var a=t.proxy(e,this);a();var i=r.settings;i.refreshMillis>0&&(this._timeagoInterval=setInterval(a,i.refreshMillis))},update:function(a){var i=r.parse(a);t(this).data("timeago",{datetime:i}),r.settings.localeTitle&&t(this).attr("title",i.toLocaleString()),e.apply(this)},updateFromDOM:function(){t(this).data("timeago",{datetime:r.parse(t(this).attr(r.isTime(this)?"datetime":"title"))}),e.apply(this)},dispose:function(){this._timeagoInterval&&(window.clearInterval(this._timeagoInterval),this._timeagoInterval=null)}};t.fn.timeago=function(t,e){var a=t?o[t]:o.init;if(!a)throw new Error("Unknown function name '"+t+"' for timeago");return this.each(function(){a.call(this,e)}),this},document.createElement("abbr"),document.createElement("time")});


keep keep keep replace keep keep keep keep keep


module.exports = function(grunt) {

  // configure the tasks
  grunt.initConfig({
    //  Copy
    copy: {
      dist: { cwd: 'fonts', src: [ '**' ], dest: 'dist/fonts', expand: true },
    },

    //  Jasmine
    jasmine: {
      components: {
	src: [
          'bin/materialize.js'
        ],
        options: {
          vendor: [
            'node_modules/jquery/dist/jquery.min.js',
            'node_modules/jasmine-jquery/lib/jasmine-jquery.js'
          ],
          styles: 'bin/materialize.css',
          specs: 'tests/spec/**/*Spec.js',
          helpers: 'tests/spec/helper.js',
          keepRunner : true,
          //helpers: 'test/spec/*.js'
        }
      }
    },

    //  Sass
    sass: {                              // Task
      expanded: {                            // Target
        options: {                       // Target options
          outputStyle: 'expanded',
          sourcemap: false,
        },
        files: {
          'dist/css/materialize.css': 'sass/materialize.scss',
        }
      },

      min: {
        options: {
          outputStyle: 'compressed',
          sourcemap: false
        },
        files: {
          'dist/css/materialize.min.css': 'sass/materialize.scss',
        }
      },

      // Compile ghpages css
      gh: {
        options: {
          outputStyle: 'compressed',
          sourcemap: false
        },
        files: {
          'css/ghpages-materialize.css': 'sass/ghpages-materialize.scss',
        }
      },

      // Compile bin css
      bin: {
        options: {
          outputStyle: 'expanded',
          sourcemap: false
        },
        files: {
          'bin/materialize.css': 'sass/materialize.scss',
        }
      }
    },

    // PostCss Autoprefixer
    postcss: {
      options: {
        processors: [
          require('autoprefixer')({
            browsers: [
              'last 2 versions',
              'Chrome >= 30',
              'Firefox >= 30',
              'ie >= 10',
              'Safari >= 8']
          })
        ]
      },
      expended: {
        src: 'dist/css/materialize.css'
      },
      min: {
        src: 'dist/css/materialize.min.css'
      },
      gh: {
        src: 'css/ghpages-materialize.css'
      },
      bin: {
        src: 'bin/materialize.css'
      }
    },

    // Browser Sync integration
    browserSync: {
      bsFiles: ["bin/*.js", "bin/*.css", "!**/node_modules/**/*"],
      options: {
        server: {
          baseDir: "./" // make server from root dir
        },
        port: 8000,
        ui: {
          port: 8080,
          weinre: {
            port: 9090
          }
        },
        open: false
      }
    },

    //  Concat
    concat: {
      options: {
        separator: ';'
      },
      dist: {
        // the files to concatenate
        src: [
          "js/initial.js",
          "js/jquery.easing.1.3.js",
          "js/animation.js",
          "js/velocity.min.js",
          "js/hammer.min.js",
          "js/jquery.hammer.js",
          "js/global.js",
          "js/collapsible.js",
          "js/dropdown.js",
          "js/leanModal.js",
          "js/materialbox.js",
          "js/parallax.js",
          "js/tabs.js",
          "js/tooltip.js",
          "js/waves.js",
          "js/toasts.js",
          "js/sideNav.js",
          "js/scrollspy.js",
          "js/forms.js",
          "js/slider.js",
          "js/cards.js",
          "js/chips.js",
          "js/pushpin.js",
          "js/buttons.js",
          "js/transitions.js",
          "js/scrollFire.js",
          "js/date_picker/picker.js",
          "js/date_picker/picker.date.js",
          "js/character_counter.js",
          "js/carousel.js",
        ],
        // the location of the resulting JS file
        dest: 'dist/js/materialize.js'
      },
      temp: {
        // the files to concatenate
        src: [
          "js/initial.js",
          "js/jquery.easing.1.3.js",
          "js/animation.js",
          "js/velocity.min.js",
          "js/hammer.min.js",
          "js/jquery.hammer.js",
          "js/global.js",
          "js/collapsible.js",
          "js/dropdown.js",
          "js/leanModal.js",
          "js/materialbox.js",
          "js/parallax.js",
          "js/tabs.js",
          "js/tooltip.js",
          "js/waves.js",
          "js/toasts.js",
          "js/sideNav.js",
          "js/scrollspy.js",
          "js/forms.js",
          "js/slider.js",
          "js/cards.js",
          "js/chips.js",
          "js/pushpin.js",
          "js/buttons.js",
          "js/transitions.js",
          "js/scrollFire.js",
          "js/date_picker/picker.js",
          "js/date_picker/picker.date.js",
          "js/character_counter.js",
          "js/carousel.js",
        ],
        // the location of the resulting JS file
        dest: 'temp/js/materialize.js'
      },
    },

    //  Uglify
    uglify: {
      options: {
        // Use these options when debugging
        // mangle: false,
        // compress: false,
        // beautify: true

      },
      dist: {
        files: {
          'dist/js/materialize.min.js': ['dist/js/materialize.js']
        }
      },
      bin: {
        files: {
          'bin/materialize.js': ['temp/js/materialize.js']
        }
      },
      extras: {
        files: {
          'extras/noUiSlider/nouislider.min.js': ['extras/noUiSlider/nouislider.js']
        }
      }
    },

    //  Compress
    compress: {
      main: {
        options: {
          archive: 'bin/materialize.zip',
          level: 6
        },
        files:[
          { expand: true, cwd: 'dist/', src: ['**/*'], dest: 'materialize/'},
          { expand: true, cwd: './', src: ['LICENSE', 'README.md'], dest: 'materialize/'},
        ]
      },

      src: {
        options: {
          archive: 'bin/materialize-src.zip',
          level: 6
        },
        files:[
          {expand: true, cwd: 'fonts/', src: ['**/*'], dest: 'materialize-src/fonts/'},
          {expand: true, cwd: 'sass/', src: ['materialize.scss'], dest: 'materialize-src/sass/'},
          {expand: true, cwd: 'sass/', src: ['components/**/*'], dest: 'materialize-src/sass/'},
          {expand: true, cwd: 'js/', src: [
            "initial.js",
            "jquery.easing.1.3.js",
            "animation.js",
            "velocity.min.js",
            "hammer.min.js",
            "jquery.hammer.js",
            "global.js",
            "collapsible.js",
            "dropdown.js",
            "leanModal.js",
            "materialbox.js",
            "parallax.js",
            "tabs.js",
            "tooltip.js",
            "waves.js",
            "toasts.js",
            "sideNav.js",
            "scrollspy.js",
            "forms.js",
            "slider.js",
            "cards.js",
            "chips.js",
            "pushpin.js",
            "buttons.js",
            "transitions.js",
            "scrollFire.js",
            "date_picker/picker.js",
            "date_picker/picker.date.js",
            "character_counter.js",
            "carousel.js",
          ], dest: 'materialize-src/js/'},
          {expand: true, cwd: 'dist/js/', src: ['**/*'], dest: 'materialize-src/js/bin/'},
          {expand: true, cwd: './', src: ['LICENSE', 'README.md'], dest: 'materialize-src/'}

        ]
      },

      starter_template: {
        options: {
          archive: 'templates/starter-template.zip',
          level: 6
        },
        files:[
          { expand: true, cwd: 'dist/', src: ['**/*'], dest: 'starter-template/'},
          { expand: true, cwd: 'templates/starter-template/', src: ['index.html', 'LICENSE'], dest: 'starter-template/'},
          { expand: true, cwd: 'templates/starter-template/css', src: ['style.css'], dest: 'starter-template/css'},
          { expand: true, cwd: 'templates/starter-template/js', src: ['init.js'], dest: 'starter-template/js'}

        ]
      },

      parallax_template: {
        options: {
          archive: 'templates/parallax-template.zip',
          level: 6
        },
        files:[
          { expand: true, cwd: 'dist/', src: ['**/*'], dest: 'parallax-template/'},
          { expand: true, cwd: 'templates/parallax-template/', src: ['index.html', 'LICENSE', 'background1.jpg', 'background2.jpg', 'background3.jpg'], dest: 'parallax-template/'},
          { expand: true, cwd: 'templates/parallax-template/css', src: ['style.css'], dest: 'parallax-template/css'},
          { expand: true, cwd: 'templates/parallax-template/js', src: ['init.js'], dest: 'parallax-template/js'}

        ]
      }

    },

    //  Clean
    clean: {
      temp: {
        src: [ 'temp/' ]
      },
    },

    //  Jade
    jade: {
      compile: {
        options: {
          pretty: true,
          data: {
            debug: false
          }
        },
        files: {
          "index.html": "jade/index.jade",
          "icons.html": "jade/icons.jade",
          "about.html": "jade/about.jade",
          "sass.html": "jade/sass.jade",
          "getting-started.html": "jade/getting-started.jade",
          "mobile.html": "jade/mobile.jade",
          "showcase.html": "jade/showcase.jade",
          "parallax.html": "jade/parallax.jade",
          "parallax-demo.html": "jade/parallax-demo.jade",
          "typography.html": "jade/typography.jade",
          "color.html": "jade/color.jade",
          "shadow.html": "jade/shadow.jade",
          "grid.html": "jade/grid.jade",
          "media-css.html": "jade/media-css.jade",
          "table.html": "jade/table.jade",
          "helpers.html": "jade/helpers.jade",
          "forms.html": "jade/forms.jade",
          "buttons.html": "jade/buttons.jade",
          "navbar.html": "jade/navbar.jade",
          "cards.html": "jade/cards.jade",
          "preloader.html": "jade/preloader.jade",
          "collections.html": "jade/collections.jade",
          "badges.html": "jade/badges.jade",
          "footer.html": "jade/footer.jade",
          "dialogs.html": "jade/dialogs.jade",
          "modals.html": "jade/modals.jade",
          "dropdown.html": "jade/dropdown.jade",
          "tabs.html": "jade/tabs.jade",
          "side-nav.html": "jade/sideNav.jade",
          "pushpin.html": "jade/pushpin.jade",
          "waves.html": "jade/waves.jade",
          "media.html": "jade/media.jade",
          "collapsible.html": "jade/collapsible.jade",
          "chips.html": "jade/chips.jade",
          "scrollfire.html": "jade/scrollFire.jade",
          "scrollspy.html": "jade/scrollspy.jade",
          "transitions.html": "jade/transitions.jade",
          "fullscreen-slider-demo.html": "jade/fullscreen-slider-demo.jade",
          "pagination.html": "jade/pagination.jade",
          "breadcrumbs.html": "jade/breadcrumbs.jade"

        }
      }
    },

    //  Watch Files
    watch: {
      jade: {
        files: ['jade/**/*'],
        tasks: ['jade_compile'],
        options: {
          interrupt: false,
          spawn: false,
        },
      },

      js: {
        files: [ "js/**/*", "!js/init.js"],
        tasks: ['js_compile'],
        options: {
          interrupt: false,
          spawn: false,
        },
      },

      sass: {
        files: ['sass/**/*'],
        tasks: ['sass_compile'],
        options: {
          interrupt: false,
          spawn: false,
        },
      }
    },

    //  Concurrent
    concurrent: {
      options: {
        logConcurrentOutput: true,
        limit: 10,
      },
      monitor: {
        tasks: ["watch:jade", "watch:js", "watch:sass", "notify:watching", 'server']
      },
    },

    //  Notifications
    notify: {
      watching: {
        options: {
          enabled: true,
          message: 'Watching Files!',
          title: "Materialize", // defaults to the name in package.json, or will use project directory's name
          success: true, // whether successful grunt executions should be notified automatically
          duration: 1 // the duration of notification in seconds, for `notify-send only
        }
      },

      sass_compile: {
        options: {
          enabled: true,
          message: 'Sass Compiled!',
          title: "Materialize",
          success: true,
          duration: 1
        }
      },

      js_compile: {
        options: {
          enabled: true,
          message: 'JS Compiled!',
          title: "Materialize",
          success: true,
          duration: 1
        }
      },

      jade_compile: {
        options: {
          enabled: true,
          message: 'Jade Compiled!',
          title: "Materialize",
          success: true,
          duration: 1
        }
      },

      server: {
        options: {
          enabled: true,
          message: 'Server Running!',
          title: "Materialize",
          success: true,
          duration: 1
        }
      }
    },

    // Text Replace
    replace: {
      version: { // Does not edit README.md
        src: [
          'bower.json',
          'package.json',
          'package.js',
          'jade/**/*.html'
        ],
        overwrite: true,
        replacements: [{
          from: grunt.option( "oldver" ),
          to: grunt.option( "newver" )
        }]
      },
      readme: { // Changes README.md
        src: [
          'README.md'
        ],
        overwrite: true,
        replacements: [{
          from: 'Current Version : v'+grunt.option( "oldver" ),
          to: 'Current Version : v'+grunt.option( "newver" )
        }]
      },
    },

    // Create Version Header for files
    usebanner: {
      release: {
        options: {
          position: 'top',
          banner: "/*!\n * Materialize v"+ grunt.option( "newver" ) +" (http://materializecss.com)\n * Copyright 2014-2015 Materialize\n * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)\n */",
          linebreak: true
        },
        files: {
          src: [ 'dist/css/*.css', 'dist/js/*.js']
        }
      }
    },

    // Rename files
    rename: {
      rename_src: {
        src: 'bin/materialize-src'+'.zip',
        dest: 'bin/materialize-src-v'+grunt.option( "newver" )+'.zip',
        options: {
          ignore: true
        }
      },
      rename_compiled: {
        src: 'bin/materialize'+'.zip',
        dest: 'bin/materialize-v'+grunt.option( "newver" )+'.zip',
        options: {
          ignore: true
        }
      },
    },

    // Removes console logs
    removelogging: {
      source: {
        src: ["js/**/*.js", "!js/velocity.min.js"],
        options: {
          // see below for options. this is optional.
        }
      }
    },
  });

  // load the tasks
  // grunt.loadNpmTasks('grunt-gitinfo');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-sass');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-compress');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-jade');
  grunt.loadNpmTasks('grunt-concurrent');
  grunt.loadNpmTasks('grunt-notify');
  grunt.loadNpmTasks('grunt-text-replace');
  grunt.loadNpmTasks('grunt-banner');
  grunt.loadNpmTasks('grunt-rename');
  grunt.loadNpmTasks('grunt-remove-logging');
  grunt.loadNpmTasks('grunt-browser-sync');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-postcss');
  // define the tasks
  grunt.registerTask(
    'release',[
      'lint',
      'copy',
      'sass:expanded',
      'sass:min',
      'postcss:expended',
      'postcss:min',
      'concat:dist',
      'uglify:dist',
      'uglify:extras',
      'usebanner:release',
      'compress:main',
      'compress:src',
      'compress:starter_template',
      'compress:parallax_template',
      'replace:version',
      'replace:readme',
      'rename:rename_src',
      'rename:rename_compiled'
    ]
  );

  grunt.registerTask('jade_compile', ['jade', 'notify:jade_compile']);
  grunt.registerTask('js_compile', ['concat:temp', 'uglify:bin', 'notify:js_compile', 'clean:temp']);
  grunt.registerTask('sass_compile', ['sass:gh', 'sass:bin', 'postcss:gh', 'postcss:bin', 'notify:sass_compile']);
  grunt.registerTask('server', ['browserSync', 'notify:server']);
  grunt.registerTask('lint', ['removelogging:source']);
  grunt.registerTask('monitor', ["concurrent:monitor"]);
  grunt.registerTask('travis', ['jasmine']);
};


/* Radio Buttons
   ========================================================================== */

// Remove default Radio Buttons
[type="radio"]:not(:checked),
[type="radio"]:checked {
  position: absolute;
  left: -9999px;
  opacity: 0;
}

[type="radio"]:not(:checked) + label,
[type="radio"]:checked + label {
  position: relative;
  padding-left: 35px;
  cursor: pointer;
  display: inline-block;
  height: 25px;
  line-height: 25px;
  font-size: 1rem;
  transition: .28s ease;

  -khtml-user-select: none; /* webkit (konqueror) browsers */
  user-select: none;
}

[type="radio"] + label:before,
[type="radio"] + label:after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  margin: 4px;
  width: 16px;
  height: 16px;
  z-index: 0;
  transition: .28s ease;
}

/* Unchecked styles */
[type="radio"]:not(:checked) + label:before,
[type="radio"]:not(:checked) + label:after,
[type="radio"]:checked + label:before,
[type="radio"]:checked + label:after,
[type="radio"].with-gap:checked + label:before,
[type="radio"].with-gap:checked + label:after {
  border-radius: 50%;
}

[type="radio"]:not(:checked) + label:before,
[type="radio"]:not(:checked) + label:after {
  border: 2px solid $radio-empty-color;
}

[type="radio"]:not(:checked) + label:after {
  z-index: -1;
  transform: scale(0);
}

/* Checked styles */
[type="radio"]:checked + label:before {
  border: 2px solid transparent;
}

[type="radio"]:checked + label:after,
[type="radio"].with-gap:checked + label:before,
[type="radio"].with-gap:checked + label:after {
  border: $radio-border;
}

[type="radio"]:checked + label:after,
[type="radio"].with-gap:checked + label:after {
  background-color: $radio-fill-color;
  z-index: 0;
}

[type="radio"]:checked + label:after {
  transform: scale(1.02);
}

/* Radio With gap */
[type="radio"].with-gap:checked + label:after {
  transform: scale(.5);
}

/* Focused styles */
[type="radio"].tabbed:focus + label:before {
  box-shadow: 0 0 0 10px rgba(0,0,0,.1);
}

/* Disabled Radio With gap */
[type="radio"].with-gap:disabled:checked + label:before {
  border: 2px solid $input-disabled-color;
}

[type="radio"].with-gap:disabled:checked + label:after {
  border: none;
  background-color: $input-disabled-color;
}

/* Disabled style */
[type="radio"]:disabled:not(:checked) + label:before,
[type="radio"]:disabled:checked + label:before {
  background-color: transparent;
  border-color: $input-disabled-color;
}

[type="radio"]:disabled + label {
  color: $input-disabled-color;
}

[type="radio"]:disabled:not(:checked) + label:before {
  border-color: $input-disabled-color;
}

[type="radio"]:disabled:checked + label:after {
  background-color: $input-disabled-color;
  border-color: $input-disabled-solid-color;
}


<!DOCTYPE html>

  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
  <title>Parallax Template - Materialize</title>

  <link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
  <link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>

      Logo

Navbar Link

Navbar Link

Parallax Template

A modern responsive front-end framework based on Material Design

          Get Started

Speeds up development

We did most of the heavy lifting for you to provide a default stylings that incorporate our custom components. Additionally, we refined animations and transitions to provide a smoother experience for developers.

User Experience Focused

By utilizing elements and principles of Material Design, we were able to create a framework that incorporates components and animations that provide more feedback to users. Additionally, a single underlying responsive system across all platforms allow for a more unified user experience.

Easy to work with

We have provided detailed documentation as well as specific code examples to help new users get started. We are also always open to feedback and can answer any questions a user may have about Materialize.

A modern responsive front-end framework based on Material Design

Contact Us

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam scelerisque id nunc nec volutpat. Etiam pellentesque tristique arcu, non consequat magna fermentum ac. Cras ut ultricies eros. Maecenas eros justo, ullamcorper a sapien id, viverra ultrices eros. Morbi sem neque, posuere et pretium eget, bibendum sollicitudin lacus. Aliquam eleifend sollicitudin diam, eu mattis nisl maximus sed. Nulla imperdiet semper molestie. Morbi massa odio, condimentum sed ipsum ac, gravida ultrices erat. Nullam eget dignissim mauris, non tristique erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;

A modern responsive front-end framework based on Material Design

Company Bio

We are a team of college students working on this project like it's our full time job. Any amount would help support and continue development on this project and is greatly appreciated.

Settings

Link 1

Link 2

Link 3

Link 4

Connect

Link 1

Link 2

Link 3

Link 4

      Made by Materialize


keep keep keep replace replace keep keep keep keep keep

// Enable scrolling
$('body').css({
overflow: '',
width: ''
});

(function($) {
    var _stack = 0,
    _lastID = 0,
    _generateID = function() {
      _lastID++;
      return 'materialize-lean-overlay-' + _lastID;
    };

  $.fn.extend({
    openModal: function(options) {

      $('body').css('overflow', 'hidden');

      var defaults = {
        opacity: 0.5,
        in_duration: 350,
        out_duration: 250,
        ready: undefined,
        complete: undefined,
        dismissible: true,
        starting_top: '4%'
      },
      $modal = $(this);

      if ($modal.hasClass('open')) {
        return;
      }

      overlayID = _generateID();
      $overlay = $('

');
      lStack = (++_stack);

      // Store a reference of the overlay
      $overlay.attr('id', overlayID).css('z-index', 1000 + lStack * 2);
      $modal.data('overlay-id', overlayID).css('z-index', 1000 + lStack * 2 + 1);
      $modal.addClass('open');

      $("body").append($overlay);

      // Override defaults
      options = $.extend(defaults, options);

      if (options.dismissible) {
        $overlay.click(function() {
          $modal.closeModal(options);
        });
        // Return on ESC
        $(document).on('keyup.leanModal' + overlayID, function(e) {
          if (e.keyCode === 27) {   // ESC key
            $modal.closeModal(options);
          }
        });
      }

      $modal.find(".modal-close").on('click.close', function(e) {
        $modal.closeModal(options);
      });

      $overlay.css({ display : "block", opacity : 0 });

      $modal.css({
        display : "block",
        opacity: 0
      });

      $overlay.velocity({opacity: options.opacity}, {duration: options.in_duration, queue: false, ease: "easeOutCubic"});
      $modal.data('associated-overlay', $overlay[0]);

      // Define Bottom Sheet animation
      if ($modal.hasClass('bottom-sheet')) {
        $modal.velocity({bottom: "0", opacity: 1}, {
          duration: options.in_duration,
          queue: false,
          ease: "easeOutCubic",
          // Handle modal ready callback
          complete: function() {
            if (typeof(options.ready) === "function") {
              options.ready();
            }
          }
        });
      }
      else {
        $.Velocity.hook($modal, "scaleX", 0.7);
        $modal.css({ top: options.starting_top });
        $modal.velocity({top: "10%", opacity: 1, scaleX: '1'}, {
          duration: options.in_duration,
          queue: false,
          ease: "easeOutCubic",
          // Handle modal ready callback
          complete: function() {
            if (typeof(options.ready) === "function") {
              options.ready();
            }
          }
        });
      }

    }
  });

  $.fn.extend({
    closeModal: function(options) {
      var defaults = {
        out_duration: 250,
        complete: undefined
      },
      $modal = $(this),
      overlayID = $modal.data('overlay-id'),
      $overlay = $('#' + overlayID);
      $modal.removeClass('open');

      options = $.extend(defaults, options);

      // Disable scrolling
      $('body').css('overflow', '');

      $modal.find('.modal-close').off('click.close');
      $(document).off('keyup.leanModal' + overlayID);

      $overlay.velocity( { opacity: 0}, {duration: options.out_duration, queue: false, ease: "easeOutQuart"});

      // Define Bottom Sheet animation
      if ($modal.hasClass('bottom-sheet')) {
        $modal.velocity({bottom: "-100%", opacity: 0}, {
          duration: options.out_duration,
          queue: false,
          ease: "easeOutCubic",
          // Handle modal ready callback
          complete: function() {
            $overlay.css({display:"none"});

            // Call complete callback
            if (typeof(options.complete) === "function") {
              options.complete();
            }
            $overlay.remove();
            _stack--;
          }
        });
      }
      else {
        $modal.velocity(
          { top: options.starting_top, opacity: 0, scaleX: 0.7}, {
          duration: options.out_duration,
          complete:
            function() {

              $(this).css('display', 'none');
              // Call complete callback
              if (typeof(options.complete) === "function") {
                options.complete();
              }
              $overlay.remove();
              _stack--;
            }
          }
        );
      }
    }
  });

  $.fn.extend({
    leanModal: function(option) {
      return this.each(function() {

        var defaults = {
          starting_top: '4%'
        },
        // Override defaults
        options = $.extend(defaults, option);

        // Close Handlers
        $(this).click(function(e) {
          options.starting_top = ($(this).offset().top - $(window).scrollTop()) /1.15;
          var modal_id = $(this).attr("href") || '#' + $(this).data('target');
          $(modal_id).openModal(options);
          e.preventDefault();
        }); // done set on click
      }); // done return
    }
  });
})(jQuery);


<!DOCTYPE html>

  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
  <title>Parallax Template - Materialize</title>

  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  <link href="../../dist/css/materialize.min.css" type="text/css" rel="stylesheet" media="screen,projection"/>
  <link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>

      Logo

Navbar Link

Navbar Link

      menu

Parallax Template

A modern responsive front-end framework based on Material Design

          Get Started

flash_on

Speeds up development

We did most of the heavy lifting for you to provide a default stylings that incorporate our custom components. Additionally, we refined animations and transitions to provide a smoother experience for developers.

group

User Experience Focused

By utilizing elements and principles of Material Design, we were able to create a framework that incorporates components and animations that provide more feedback to users. Additionally, a single underlying responsive system across all platforms allow for a more unified user experience.

settings

Easy to work with

We have provided detailed documentation as well as specific code examples to help new users get started. We are also always open to feedback and can answer any questions a user may have about Materialize.

A modern responsive front-end framework based on Material Design

Contact Us

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam scelerisque id nunc nec volutpat. Etiam pellentesque tristique arcu, non consequat magna fermentum ac. Cras ut ultricies eros. Maecenas eros justo, ullamcorper a sapien id, viverra ultrices eros. Morbi sem neque, posuere et pretium eget, bibendum sollicitudin lacus. Aliquam eleifend sollicitudin diam, eu mattis nisl maximus sed. Nulla imperdiet semper molestie. Morbi massa odio, condimentum sed ipsum ac, gravida ultrices erat. Nullam eget dignissim mauris, non tristique erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;

A modern responsive front-end framework based on Material Design

Company Bio

We are a team of college students working on this project like it's our full time job. Any amount would help support and continue development on this project and is greatly appreciated.

Settings

Link 1

Link 2

Link 3

Link 4

Connect

Link 1

Link 2

Link 3

Link 4

      Made by Materialize


- var page = "Parallax"

doctype html
html(lang="en")
  head
    include _head.jade
  body(class="parallax-demo")
    include page-contents/parallax_demo_content.html
    include _footer.html
    include _scripts.html


(function ($) {

  // Add posibility to scroll to selected option
  // usefull for select for example
  $.fn.scrollTo = function(elem) {
    $(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top);
    return this;
  };

  $.fn.dropdown = function (option) {
    var defaults = {
      inDuration: 300,
      outDuration: 225,
      constrain_width: true, // Constrains width of dropdown to the activator
      hover: false,
      gutter: 0, // Spacing from edge
      belowOrigin: false,
      alignment: 'left'
    };

    this.each(function(){
    var origin = $(this);
    var options = $.extend({}, defaults, option);
    var isFocused = false;

    // Dropdown menu
    var activates = $("#"+ origin.attr('data-activates'));

    function updateOptions() {
      if (origin.data('induration') !== undefined)
        options.inDuration = origin.data('inDuration');
      if (origin.data('outduration') !== undefined)
        options.outDuration = origin.data('outDuration');
      if (origin.data('constrainwidth') !== undefined)
        options.constrain_width = origin.data('constrainwidth');
      if (origin.data('hover') !== undefined)
        options.hover = origin.data('hover');
      if (origin.data('gutter') !== undefined)
        options.gutter = origin.data('gutter');
      if (origin.data('beloworigin') !== undefined)
        options.belowOrigin = origin.data('beloworigin');
      if (origin.data('alignment') !== undefined)
        options.alignment = origin.data('alignment');
    }

    updateOptions();

    // Attach dropdown to its activator
    origin.after(activates);

    /*
      Helper function to position and resize dropdown.
      Used in hover and click handler.
    */
    function placeDropdown(eventType) {
      // Check for simultaneous focus and click events.
      if (eventType === 'focus') {
        isFocused = true;
      }

      // Check html data attributes
      updateOptions();

      // Set Dropdown state
      activates.addClass('active');
      origin.addClass('active');

      // Constrain width
      if (options.constrain_width === true) {
        activates.css('width', origin.outerWidth());

      } else {
        activates.css('white-space', 'nowrap');
      }

      // Offscreen detection
      var windowHeight = window.innerHeight;
      var originHeight = origin.innerHeight();
      var offsetLeft = origin.offset().left;
      var offsetTop = origin.offset().top - $(window).scrollTop();
      var currAlignment = options.alignment;
      var gutterSpacing = 0;
      var leftPosition = 0;

      // Below Origin
      var verticalOffset = 0;
      if (options.belowOrigin === true) {
        verticalOffset = originHeight;
      }

      // Check for scrolling positioned container.
      var scrollOffset = 0;
      var wrapper = origin.parent();
      if (!wrapper.is('body') && wrapper[0].scrollHeight > wrapper[0].clientHeight) {
        scrollOffset = wrapper[0].scrollTop;
      }

      if (offsetLeft + activates.innerWidth() > $(window).width()) {
        // Dropdown goes past screen on right, force right alignment
        currAlignment = 'right';

      } else if (offsetLeft - activates.innerWidth() + origin.innerWidth() < 0) {
        // Dropdown goes past screen on left, force left alignment
        currAlignment = 'left';
      }
      // Vertical bottom offscreen detection
      if (offsetTop + activates.innerHeight() > windowHeight) {
        // If going upwards still goes offscreen, just crop height of dropdown.
        if (offsetTop + originHeight - activates.innerHeight() < 0) {
          var adjustedHeight = windowHeight - offsetTop - verticalOffset;
          activates.css('max-height', adjustedHeight);
        } else {
          // Flow upwards.
          if (!verticalOffset) {
            verticalOffset += originHeight;
          }
          verticalOffset -= activates.innerHeight();
        }
      }

      // Handle edge alignment
      if (currAlignment === 'left') {
        gutterSpacing = options.gutter;
        leftPosition = origin.position().left + gutterSpacing;
      }
      else if (currAlignment === 'right') {
        var offsetRight = origin.position().left + origin.outerWidth() - activates.outerWidth();
        gutterSpacing = -options.gutter;
        leftPosition =  offsetRight + gutterSpacing;
      }

      // Position dropdown
      activates.css({
        position: 'absolute',
        top: origin.position().top + verticalOffset + scrollOffset,
        left: leftPosition
      });

      // Show dropdown
      activates.stop(true, true).css('opacity', 0)
        .slideDown({
        queue: false,
        duration: options.inDuration,
        easing: 'easeOutCubic',
        complete: function() {
          $(this).css('height', '');
        }
      })
        .animate( {opacity: 1}, {queue: false, duration: options.inDuration, easing: 'easeOutSine'});
    }

    function hideDropdown() {
      // Check for simultaneous focus and click events.
      isFocused = false;
      activates.fadeOut(options.outDuration);
      activates.removeClass('active');
      origin.removeClass('active');
      setTimeout(function() { activates.css('max-height', ''); }, options.outDuration);
    }

    // Hover
    if (options.hover) {
      var open = false;
      origin.unbind('click.' + origin.attr('id'));
      // Hover handler to show dropdown
      origin.on('mouseenter', function(e){ // Mouse over
        if (open === false) {
          placeDropdown();
          open = true;
        }
      });
      origin.on('mouseleave', function(e){
        // If hover on origin then to something other than dropdown content, then close
        var toEl = e.toElement || e.relatedTarget; // added browser compatibility for target element
        if(!$(toEl).closest('.dropdown-content').is(activates)) {
          activates.stop(true, true);
          hideDropdown();
          open = false;
        }
      });

      activates.on('mouseleave', function(e){ // Mouse out
        var toEl = e.toElement || e.relatedTarget;
        if(!$(toEl).closest('.dropdown-button').is(origin)) {
          activates.stop(true, true);
          hideDropdown();
          open = false;
        }
      });

    // Click
    } else {
      // Click handler to show dropdown
      origin.unbind('click.' + origin.attr('id'));
      origin.bind('click.'+origin.attr('id'), function(e){
        if (!isFocused) {
          if ( origin[0] == e.currentTarget &&
               !origin.hasClass('active') &&
               ($(e.target).closest('.dropdown-content').length === 0)) {
            e.preventDefault(); // Prevents button click from moving window
            placeDropdown('click');
          }
          // If origin is clicked and menu is open, close menu
          else if (origin.hasClass('active')) {
            hideDropdown();
            $(document).unbind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id'));
          }
          // If menu open, add click close handler to document
          if (activates.hasClass('active')) {
            $(document).bind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id'), function (e) {
              if (!activates.is(e.target) && !origin.is(e.target) && (!origin.find(e.target).length) ) {
                hideDropdown();
                $(document).unbind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id'));
              }
            });
          }
        }
      });

    } // End else

    // Listen to open and close event - useful for select component
    origin.on('open', function(e, eventType) {
      placeDropdown(eventType);
    });
    origin.on('close', hideDropdown);

   });
  }; // End dropdown plugin

  $(document).ready(function(){
    $('.dropdown-button').dropdown();
  });
}( jQuery ));


$('#sidenav-overlay').velocity({opacity: 0}, {duration: 200,

keep keep keep keep keep replace keep keep keep keep keep

$('body').css({
overflow: '',
width: ''
});


- var no_nav = false
- var page = "Tabs"

doctype html
html(lang="en")
  head
    include _head.jade
  body
    include _navbar.jade
    main
      include page-contents/tabs_content.html
    include _footer.html
    include _scripts.html


(function ($) {

  $.fn.characterCounter = function(){
    return this.each(function(){
      var $input = $(this);
      var $counterElement = $input.parent().find('span[class="character-counter"]');

      // character counter has already been added appended to the parent container
      if ($counterElement.length) {
        return;
      }

      var itHasLengthAttribute = $input.attr('length') !== undefined;

      if(itHasLengthAttribute){
        $input.on('input', updateCounter);
        $input.on('focus', updateCounter);
        $input.on('blur', removeCounterElement);

        addCounterElement($input);
      }

    });
  };

  function updateCounter(){
    var maxLength     = +$(this).attr('length'),
    actualLength      = +$(this).val().length,
    isValidLength     = actualLength <= maxLength;

    $(this).parent().find('span[class="character-counter"]')
                    .html( actualLength + '/' + maxLength);

    addInputStyle(isValidLength, $(this));
  }

  function addCounterElement($input) {
    var $counterElement = $input.parent().find('span[class="character-counter"]');

    if ($counterElement.length) {
      return;
    }

    $counterElement = $('<span/>')
                        .addClass('character-counter')
                        .css('float','right')
                        .css('font-size','12px')
                        .css('height', 1);

    $input.parent().append($counterElement);
  }

  function removeCounterElement(){
    $(this).parent().find('span[class="character-counter"]').html('');
  }

  function addInputStyle(isValidLength, $input){
    var inputHasInvalidClass = $input.hasClass('invalid');
    if (isValidLength && inputHasInvalidClass) {
      $input.removeClass('invalid');
    }
    else if(!isValidLength && !inputHasInvalidClass){
      $input.removeClass('valid');
      $input.addClass('invalid');
    }
  }

  $(document).ready(function(){
    $('input, textarea').characterCounter();
  });

}( jQuery ));


// If overlay does not exist, create one and if it is clicked, close menu

if ($('#sidenav-overlay').length === 0) {


/* Text Inputs + Textarea
   ========================================================================== */

/* Style Placeholders */

::-webkit-input-placeholder {
  color: $placeholder-text-color;
}

:-moz-placeholder { /* Firefox 18- */
  color: $placeholder-text-color;
}

::-moz-placeholder {  /* Firefox 19+ */
  color: $placeholder-text-color;
}

:-ms-input-placeholder {
  color: $placeholder-text-color;
}

/* Text inputs */

input:not([type]),
input[type=text],
input[type=password],
input[type=email],
input[type=url],
input[type=time],
input[type=date],
input[type=datetime],
input[type=datetime-local],
input[type=tel],
input[type=number],
input[type=search],
textarea.materialize-textarea {

  // General Styles
  background-color: transparent;
  border: none;
  border-bottom: $input-border;
  border-radius: 0;
  outline: none;
  height: $input-height;
  width: 100%;
  font-size: $input-font-size;
  margin: $input-margin;
  padding: $input-padding;
  box-shadow: none;
  box-sizing: content-box;
  transition: $input-transition;

  // Disabled input style
  &:disabled,
  &[readonly="readonly"] {
    color: $input-disabled-color;
    border-bottom: $input-disabled-border;
  }

  // Disabled label style
  &:disabled+label,
  &[readonly="readonly"]+label {
    color: $input-disabled-color;
  }

  // Focused input style
  &:focus:not([readonly]) {
    border-bottom: 1px solid $input-focus-color;
    box-shadow: 0 1px 0 0 $input-focus-color;
  }

  // Focused label style
  &:focus:not([readonly])+label {
    color: $input-focus-color;
  }

  // Valid Input Style
  &.valid,
  &:focus.valid {
    border-bottom: 1px solid $input-success-color;
    box-shadow: 0 1px 0 0 $input-success-color;
  }

  // Custom Success Message
  &.valid + label:after,
  &:focus.valid + label:after {
    content: attr(data-success);
    color: $input-success-color;
    opacity: 1;
  }

  // Invalid Input Style
  &.invalid,
  &:focus.invalid {
    border-bottom: $input-invalid-border;
    box-shadow: 0 1px 0 0 $input-error-color;
  }

  // Custom Error message
  &.invalid + label:after,
  &:focus.invalid + label:after {
    content: attr(data-error);
    color: $input-error-color;
    opacity: 1;
  }

  // Full width label when using validate for error messages
  &.validate + label {
    width: 100%;
    pointer-events: none;
  }

  // Form Message Shared Styles
  & + label:after {
    display: block;
    content: "";
    position: absolute;
    top: 65px;
    opacity: 0;
    transition: .2s opacity ease-out, .2s color ease-out;
  }
}

// Styling for input field wrapper
.input-field {
  position: relative;
  margin-top: 1rem;

  label {
    color: $input-border-color;
    position: absolute;
    top: 0.8rem;
    left: $gutter-width / 2;
    font-size: 1rem;
    cursor: text;
    transition: .2s ease-out;
  }

  label.active {
    font-size: $label-font-size;
    transform: translateY(-140%);
  }

  // Prefix Icons
  .prefix {
    position: absolute;
    width: $input-height;
    font-size: 2rem;
    transition: color .2s;

    &.active { color: $input-focus-color; }
  }

  .prefix ~ input,
  .prefix ~ textarea {
    margin-left: 3rem;
    width: 92%;
    width: calc(100% - 3rem);
  }

  .prefix ~ textarea { padding-top: .8rem; }
  .prefix ~ label { margin-left: 3rem; }

  @media #{$medium-and-down} {
    .prefix ~ input {
      width: 86%;
      width: calc(100% - 3rem);
    }
  }

  @media #{$small-and-down} {
    .prefix ~ input {
      width: 80%;
      width: calc(100% - 3rem);
    }
  }
}

/* Search Field */

.input-field input[type=search] {
  display: block;
  line-height: inherit;
  padding-left: 4rem;
  width: calc(100% - 4rem);

  &:focus {
    background-color: $input-background;
    border: 0;
    box-shadow: none;
    color: #444;

    & + label i,
    & ~ .mdi-navigation-close,
    & ~ .material-icons {
      color: #444;
    }
  }

  & + label {
    left: 1rem;
  }

  & ~ .mdi-navigation-close,
  & ~ .material-icons {
    position: absolute;
    top: 0;
    right: 1rem;
    color: transparent;
    cursor: pointer;
    font-size: 2rem;
    transition: .3s color;
  }
}

/* Textarea */

// Default textarea
textarea {
  width: 100%;
  height: $input-height;
  background-color: transparent;

  &.materialize-textarea {
    overflow-y: hidden; /* prevents scroll bar flash */
    padding: 1.6rem 0; /* prevents text jump on Enter keypress */
    resize: none;
    min-height: $input-height;
  }
}

// For textarea autoresize
.hiddendiv {
  display: none;
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow-wrap: break-word; /* future version of deprecated 'word-wrap' */
  padding-top: 1.2rem; /* prevents text jump on Enter keypress */
}


dragTarget.css({width: '50%', right: 0, left: ''});

menu_id.velocity({'translateX': [-1 * options.menuWidth - 10, leftPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'});

$('#sidenav-overlay').velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad',

keep keep keep keep replace keep keep keep keep keep


- var no_nav = false
- var page = "Pagination"

doctype html
html(lang="en")
  head
    include _head.jade
  body
    include _navbar.jade
    main
      include page-contents/pagination_content.html
    include _footer.html
    include _scripts.html