keep replace replace replace replace replace replace keep keep keep

var filtersFactory = (function(){
	var ob = {};
	ob.createFilter = createFilter;
	ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;

	function createFilter(filId){
        	var fil = createNS('filter');
        	fil.setAttribute('id',filId);
                fil.setAttribute('filterUnits','objectBoundingBox');
                fil.setAttribute('x','0%');
                fil.setAttribute('y','0%');
                fil.setAttribute('width','100%');
                fil.setAttribute('height','100%');
                return fil;
	}

	function createAlphaToLuminanceFilter(){
                var feColorMatrix = createNS('feColorMatrix');
                feColorMatrix.setAttribute('type','matrix');
                feColorMatrix.setAttribute('color-interpolation-filters','sRGB');
                feColorMatrix.setAttribute('values','0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
                return feColorMatrix;
	}

	return ob;
}());


function GradientProperty(elem,data,container){
    this.data = data;
    this.c = createTypedArray('uint8c', data.p*4);
    var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p*4) : data.k.k.length - data.p*4;
    this.o = createTypedArray('float32', cLength);
    this._cmdf = false;
    this._omdf = false;
    this._collapsable = this.checkCollapsable();
    this._hasOpacity = cLength;
    this.initDynamicPropertyContainer(container);
    this.prop = PropertyFactory.getProp(elem,data.k,1,null,this);
    this.k = this.prop.k;
    this.getValue(true);
}

GradientProperty.prototype.comparePoints = function(values, points) {
    var i = 0, len = this.o.length/2, diff;
    while(i < len) {
        diff = Math.abs(values[i*4] - values[points*4 + i*2]);
        if(diff > 0.01){
            return false;
        }
        i += 1;
    }
    return true;
};

GradientProperty.prototype.checkCollapsable = function() {
    if (this.o.length/2 !== this.c.length/4) {
        return false;
    }
    if (this.data.k.k[0].s) {
        var i = 0, len = this.data.k.k.length;
        while (i < len) {
            if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
                return false;
            }
            i += 1;
        }
    } else if(!this.comparePoints(this.data.k.k, this.data.p)) {
        return false;
    }
    return true;
};

GradientProperty.prototype.getValue = function(forceRender){
    this.prop.getValue();
    this._mdf = false;
    this._cmdf = false;
    this._omdf = false;
    if(this.prop._mdf || forceRender){
        var i, len = this.data.p*4;
        var mult, val;
        for(i=0;i<len;i+=1){
            mult = i%4 === 0 ? 100 : 255;
            val = Math.round(this.prop.v[i]*mult);
            if(this.c[i] !== val){
                this.c[i] = val;
                this._cmdf = !forceRender;
            }
        }
        if(this.o.length){
            len = this.prop.v.length;
            for(i=this.data.p*4;i<len;i+=1){
                mult = i%2 === 0 ? 100 : 1;
                val = i%2 === 0 ?  Math.round(this.prop.v[i]*100):this.prop.v[i];
                if(this.o[i-this.data.p*4] !== val){
                    this.o[i-this.data.p*4] = val;
                    this._omdf = !forceRender;
                }
            }
        }
        this._mdf = !forceRender;
    }
};

extendPrototype([DynamicPropertyContainer], GradientProperty);


function SVGStrokeStyleData(elem, data, styleOb){
	this.initDynamicPropertyContainer(elem);
	this.getValue = this.iterateDynamicProperties;
	this.o = PropertyFactory.getProp(elem,data.o,0,0.01,this);
	this.w = PropertyFactory.getProp(elem,data.w,0,null,this);
	this.d = new DashProperty(elem,data.d||{},'svg',this);
	this.c = PropertyFactory.getProp(elem,data.c,1,255,this);
	this.style = styleOb;
    this._isAnimated = !!this._isAnimated;
}

extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);


Match Name

After Effect's Match Name. Used for expressions.

Name

After Effect's Name. Used for expressions.

Type

Shape content type.

Radius

Rounded Corner Radius


/** @typedef {import('preact').VNode} VNode */

* This file exports various methods that implement Babel's "automatic" JSX runtime API:

import options from './options';

/**
 * Create an virtual node (used for JSX)
 * @param {import('./internal').VNode["type"]} type The node name or Component
 * constructor for this virtual node
 * @param {object | null | undefined} [props] The properties of the virtual node
 * @param {Array<import('.').ComponentChildren>} [children] The children of the virtual node
 * @returns {import('./internal').VNode}
 */
export function createElement(type, props, children) {
	let normalizedProps = {},
		key,
		ref,
		i;
	for (i in props) {
		if (i == 'key') key = props[i];
		else if (i == 'ref') ref = props[i];
		else normalizedProps[i] = props[i];
	}

	if (arguments.length > 3) {
		children = [children];
		// https://github.com/preactjs/preact/issues/1916
		for (i = 3; i < arguments.length; i++) {
			children.push(arguments[i]);
		}
	}
	if (children != null) {
		normalizedProps.children = children;
	}

	// If a Component VNode, check for and apply defaultProps
	// Note: type may be undefined in development, must never error here.
	if (typeof type == 'function' && type.defaultProps != null) {
		for (i in type.defaultProps) {
			if (normalizedProps[i] === undefined) {
				normalizedProps[i] = type.defaultProps[i];
			}
		}
	}

	return createVNode(type, normalizedProps, key, ref, null);
}

/**
 * Create a VNode (used internally by Preact)
 * @param {import('./internal').VNode["type"]} type The node name or Component
 * Constructor for this virtual node
 * @param {object | string | number | null} props The properties of this virtual node.
 * If this virtual node represents a text node, this is the text of the node (string or number).
 * @param {string | number | null} key The key for this virtual node, used when
 * diffing it against its children
 * @param {import('./internal').VNode["ref"]} ref The ref property that will
 * receive a reference to its created child
 * @returns {import('./internal').VNode}
 */
export function createVNode(type, props, key, ref, original) {
	// V8 seems to be better at detecting type shapes if the object is allocated from the same call site
	// Do not inline into createElement and coerceToVNode!
	const vnode = {
		type,
		props,
		key,
		ref,
		_children: null,
		_parent: null,
		_depth: 0,
		_dom: null,
		// _nextDom must be initialized to undefined b/c it will eventually
		// be set to dom.nextSibling which can return `null` and it is important
		// to be able to distinguish between an uninitialized _nextDom and
		// a _nextDom that has been set to `null`
		_nextDom: undefined,
		_component: null,
		_hydrating: null,
		constructor: undefined,
		_original: original == null ? ++options._vnodeId : original
	};

	if (options.vnode != null) options.vnode(vnode);

	return vnode;
}

export function createRef() {
	return { current: null };
}

export function Fragment(props) {
	return props.children;
}

/**
 * Check if a the argument is a valid Preact VNode.
 * @param {*} vnode
 * @returns {vnode is import('./internal').VNode}
 */
export const isValidElement = vnode =>
	vnode != null && vnode.constructor === undefined;


import React, { render, createElement, createFactory } from 'preact/compat';
import { setupScratch, teardown } from '../../../test/_util/helpers';

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

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

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

	it('should create a DOM element', () => {
		render(createFactory('span')({ class: 'foo' }, '1'), scratch);
		expect(scratch.innerHTML).to.equal('1');
	});

	it('should create a component', () => {
		const Foo = ({ id, children }) =>
foo {children}
;
		render(createFactory(Foo)({ id: 'value' }, 'bar'), scratch);
		expect(scratch.innerHTML).to.equal('
foo bar
');
	});
});


It controls protected/private property mangling so that minified builds have consistent property names.

Most properties are only used on one type of objects, so they can have the same name since they will never collide. Doing this reduces size.


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

import { Router, Route, Switch } from './simple-router';

/** @jsx createElement */

let Hello = lazy(() => import('./hello.js'));
let Bye = lazy(() => import('./bye.js'));

function Loading() {
	return
Hey! This is a fallback because we're loading things! :D
;
}

export default function SuspenseRouterBug() {
	return (
		<Router>

Suspense Router bug

			<Suspense fallback={<Loading />}>
				<Switch>
					<Route path="/" exact>
						<Hello />
					</Route>
					<Route path="/bye">
						<Bye />
					</Route>
				</Switch>
			</Suspense>
		</Router>
	);
}


function createVNode(type, props, key, __source, __self) {

// We'll want to preserve `ref` in props to get rid of the need for

// forwardRef components in the future, but that should happen via

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

let normalizedProps = {},
ref,
i;
for (i in props) {
if (i == 'ref') {
ref = props[i];
} else {

import * as preact from './index';

export enum HookType {
	useState = 1,
	useReducer = 2,
	useEffect = 3,
	useLayoutEffect = 4,
	useRef = 5,
	useImperativeHandle = 6,
	useMemo = 7,
	useCallback = 8,
	useContext = 9,
	useErrorBoundary = 10,
	// Not a real hook, but the devtools treat is as such
	useDebugvalue = 11
}

export interface DevSource {
	fileName: string;
	lineNumber: number;
}

export interface Options extends preact.Options {
	_vnodeId: number;
	/** Attach a hook that is invoked before render, mainly to check the arguments. */
	_root?(
		vnode: ComponentChild,
		parent: Element | Document | ShadowRoot | DocumentFragment
	): void;
	/** Attach a hook that is invoked before a vnode is diffed. */
	_diff?(vnode: VNode): void;
	/** Attach a hook that is invoked after a tree was mounted or was updated. */
	_commit?(vnode: VNode, commitQueue: Component[]): void;
	/** Attach a hook that is invoked before a vnode has rendered. */
	_render?(vnode: VNode): void;
	/** Attach a hook that is invoked before a hook's state is queried. */
	_hook?(component: Component, index: number, type: HookType): void;
	/** Bypass effect execution. Currenty only used in devtools for hooks inspection */
	_skipEffects?: boolean;
	/** Attach a hook that is invoked after an error is caught in a component but before calling lifecycle hooks */
	_catchError(error: any, vnode: VNode, oldVNode?: VNode | undefined): void;
}

export type ComponentChild =
	| VNode<any>
	| string
	| number
	| boolean
	| null
	| undefined;
export type ComponentChildren = ComponentChild[] | ComponentChild;

export interface FunctionComponent<P = {}> extends preact.FunctionComponent<P> {
	// Internally, createContext uses `contextType` on a Function component to
	// implement the Consumer component
	contextType?: PreactContext;

	// Internally, createContext stores a ref to the context object on the Provider
	// Function component to help devtools
	_contextRef?: PreactContext;

	// Define these properties as undefined on FunctionComponent to get rid of
	// some errors in `diff()`
	getDerivedStateFromProps?: undefined;
	getDerivedStateFromError?: undefined;
}

export interface ComponentClass<P = {}> extends preact.ComponentClass<P> {
	_contextRef?: any;

	// Override public contextType with internal PreactContext type
	contextType?: PreactContext;
}

// Redefine ComponentType using our new internal FunctionComponent interface above
export type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;

export interface PreactElement extends HTMLElement {
	_children?: VNode<any> | null;
	/** Event listeners to support event delegation */
	_listeners?: Record<string, (e: Event) => void>;

	// Preact uses this attribute to detect SVG nodes
	ownerSVGElement?: SVGElement | null;

	// style: HTMLElement["style"]; // From HTMLElement

	data?: string | number; // From Text node
}

// We use the `current` property to differentiate between the two kinds of Refs so
// internally we'll define `current` on both to make TypeScript happy
type RefObject<T> = { current: T | null };
type RefCallback<T> = { (instance: T | null): void; current: undefined };
type Ref<T> = RefObject<T> | RefCallback<T>;

export interface VNode<P = {}> extends preact.VNode<P> {
	// Redefine type here using our internal ComponentType type
	type: string | ComponentType<P>;
	props: P & { children: ComponentChildren };
	ref?: Ref<any> | null;
	_children: Array<VNode<any>> | null;
	_parent: VNode | null;
	_depth: number | null;
	/**
	 * The [first (for Fragments)] DOM child of a VNode
	 */
	_dom: PreactElement | null;
	/**
	 * The last dom child of a Fragment, or components that return a Fragment
	 */
	_nextDom: PreactElement | null;
	_component: Component | null;
	_hydrating: boolean | null;
	constructor: undefined;
	_original: number;
}

export interface Component<P = {}, S = {}> extends preact.Component<P, S> {
	// When component is functional component, this is reset to functional component
	constructor: ComponentType<P>;
	state: S; // Override Component["state"] to not be readonly for internal use, specifically Hooks
	base?: PreactElement;

	_dirty: boolean;
	_force?: boolean;
	_renderCallbacks: Array<() => void>; // Only class components
	_globalContext?: any;
	_vnode?: VNode<P> | null;
	_nextState?: S | null; // Only class components
	/** Only used in the devtools to later dirty check if state has changed */
	_prevState?: S | null;
	/**
	 * Pointer to the parent dom node. This is only needed for top-level Fragment
	 * components or array returns.
	 */
	_parentDom?: PreactElement | null;
	// Always read, set only when handling error
	_processingException?: Component<any, any> | null;
	// Always read, set only when handling error. This is used to indicate at diffTime to set _processingException
	_pendingError?: Component<any, any> | null;
}

export interface PreactContext extends preact.Context<any> {
	_id: string;
	_defaultValue: any;
}


import { setupScratch, teardown } from '../../../test/_util/helpers';
import React, { createElement, render } from 'preact/compat';

describe('Select', () => {
	let scratch;

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

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

	it('should work with multiple selected (array of values)', () => {
		function App() {
			return (
				<select multiple value={['B', 'C']}>
					<option value="A">A</option>
					<option value="B">B</option>
					<option value="C">C</option>
				</select>
			);
		}

		render(<App />, scratch);
		const options = scratch.firstChild.children;
		expect(options[0]).to.have.property('selected', false);
		expect(options[1]).to.have.property('selected', true);
		expect(options[2]).to.have.property('selected', true);
		expect(scratch.firstChild.value).to.equal('B');
	});
});


// function createRoot(title) {
// 	let div = document.createElement('div');
// 	let h2 = document.createElement('h2');
// 	h2.textContent = title;
// 	div.appendChild(h2);
// 	document.body.appendChild(div);
// 	return div;
// }

/*
function logCall(obj, method, name) {
	let old = obj[method];
	obj[method] = function(...args) {
		console.log(`<${this.localName}>.`+(name || `${method}(${args})`));
		return old.apply(this, args);
	};
}

logCall(HTMLElement.prototype, 'appendChild');
logCall(HTMLElement.prototype, 'removeChild');
logCall(HTMLElement.prototype, 'insertBefore');
logCall(HTMLElement.prototype, 'replaceChild');
logCall(HTMLElement.prototype, 'setAttribute');
logCall(HTMLElement.prototype, 'removeAttribute');
let d = Object.getOwnPropertyDescriptor(Node.prototype, 'nodeValue');
Object.defineProperty(Text.prototype, 'nodeValue', {
	get() {
		let value = d.get.call(this);
		console.log('get Text#nodeValue: ', value);
		return value;
	},
	set(v) {
		console.log('set Text#nodeValue', v);
		return d.set.call(this, v);
	}
});

render((

This is a test.

		<Foo />
		<time>...</time>

), createRoot('Stateful component update demo:'));

class Foo extends Component {
	componentDidMount() {
		console.log('mounted');
		this.timer = setInterval( () => {
			this.setState({ time: Date.now() });
		}, 5000);
	}
	componentWillUnmount() {
		clearInterval(this.timer);
	}
	render(props, state, context) {
		// console.log('rendering', props, state, context);
		return <time>test: {state.time}</time>
	}
}

render((

This is a test.

		<Foo />
		<time>...</time>

), createRoot('Stateful component update demo:'));

let items = [];
let count = 0;
let three = createRoot('Top-level render demo:');

setInterval( () => {
	if (count++ %20 < 10 ) {
		items.push(
item #{items.length}
);
	}
	else {
		items.shift();
	}

	render((

This is a test.

			<time>{Date.now()}</time>

{items}

	), three);
}, 5000);

// Mount the top-level component to the DOM:
render(, document.body);
*/


const vnode = {
type,
props: normalizedProps,
key,
ref: props && props.ref,
_children: null,
_parent: null,
_depth: 0,
_dom: null,
_nextDom: undefined,

keep keep keep keep replace keep keep keep keep keep


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);
	});

	it('should call nested new lifecycle methods in the right order', () => {
		let updateOuterState;
		let updateInnerState;
		let forceUpdateOuter;
		let forceUpdateInner;

		let log;
		function logger(msg) {
			return function() {
				// return true for shouldComponentUpdate
				log.push(msg);
				return true;
			};
		}

		class Outer extends Component {
			static getDerivedStateFromProps() {
				log.push('outer getDerivedStateFromProps');
				return null;
			}
			constructor() {
				super();
				log.push('outer constructor');

				this.state = { value: 0 };
				forceUpdateOuter = () =>
					this.forceUpdate(() => log.push('outer forceUpdate callback'));
				updateOuterState = () =>
					this.setState(
						prevState => ({ value: prevState.value % 2 }),
						() => log.push('outer setState callback')
					);
			}
			render() {
				log.push('outer render');
				return (

						<Inner x={this.props.x} outerValue={this.state.value} />

				);
			}
		}
		Object.assign(Outer.prototype, {
			componentDidMount: logger('outer componentDidMount'),
			shouldComponentUpdate: logger('outer shouldComponentUpdate'),
			getSnapshotBeforeUpdate: logger('outer getSnapshotBeforeUpdate'),
			componentDidUpdate: logger('outer componentDidUpdate'),
			componentWillUnmount: logger('outer componentWillUnmount')
		});

		class Inner extends Component {
			static getDerivedStateFromProps() {
				log.push('inner getDerivedStateFromProps');
				return null;
			}
			constructor() {
				super();
				log.push('inner constructor');

				this.state = { value: 0 };
				forceUpdateInner = () =>
					this.forceUpdate(() => log.push('inner forceUpdate callback'));
				updateInnerState = () =>
					this.setState(
						prevState => ({ value: prevState.value % 2 }),
						() => log.push('inner setState callback')
					);
			}
			render() {
				log.push('inner render');
				return (

						{this.props.x} {this.props.outerValue} {this.state.value}

				);
			}
		}
		Object.assign(Inner.prototype, {
			componentDidMount: logger('inner componentDidMount'),
			shouldComponentUpdate: logger('inner shouldComponentUpdate'),
			getSnapshotBeforeUpdate: logger('inner getSnapshotBeforeUpdate'),
			componentDidUpdate: logger('inner componentDidUpdate'),
			componentWillUnmount: logger('inner componentWillUnmount')
		});

		// Constructor & mounting
		log = [];
		render(<Outer x={1} />, scratch);
		expect(log).to.deep.equal([
			'outer constructor',
			'outer getDerivedStateFromProps',
			'outer render',
			'inner constructor',
			'inner getDerivedStateFromProps',
			'inner render',
			'inner componentDidMount',
			'outer componentDidMount'
		]);

		// Outer & Inner props update
		log = [];
		render(<Outer x={2} />, scratch);
		// Note: we differ from react here in that we apply changes to the dom
		// as we find them while diffing. React on the other hand separates this
		// into specific phases, meaning changes to the dom are only flushed
		// once the whole diff-phase is complete. This is why
		// "outer getSnapshotBeforeUpdate" is called just before the "inner" hooks.
		// For react this call would be right before "outer componentDidUpdate"
		expect(log).to.deep.equal([
			'outer getDerivedStateFromProps',
			'outer shouldComponentUpdate',
			'outer render',
			'outer getSnapshotBeforeUpdate',
			'inner getDerivedStateFromProps',
			'inner shouldComponentUpdate',
			'inner render',
			'inner getSnapshotBeforeUpdate',
			'inner componentDidUpdate',
			'outer componentDidUpdate'
		]);

		// Outer state update & Inner props update
		log = [];
		updateOuterState();
		rerender();
		expect(log).to.deep.equal([
			'outer getDerivedStateFromProps',
			'outer shouldComponentUpdate',
			'outer render',
			'outer getSnapshotBeforeUpdate',
			'inner getDerivedStateFromProps',
			'inner shouldComponentUpdate',
			'inner render',
			'inner getSnapshotBeforeUpdate',
			'inner componentDidUpdate',
			'outer setState callback',
			'outer componentDidUpdate'
		]);

		// Inner state update
		log = [];
		updateInnerState();
		rerender();
		expect(log).to.deep.equal([
			'inner getDerivedStateFromProps',
			'inner shouldComponentUpdate',
			'inner render',
			'inner getSnapshotBeforeUpdate',
			'inner setState callback',
			'inner componentDidUpdate'
		]);

		// Force update Outer
		log = [];
		forceUpdateOuter();
		rerender();
		expect(log).to.deep.equal([
			'outer getDerivedStateFromProps',
			'outer render',
			'outer getSnapshotBeforeUpdate',
			'inner getDerivedStateFromProps',
			'inner shouldComponentUpdate',
			'inner render',
			'inner getSnapshotBeforeUpdate',
			'inner componentDidUpdate',
			'outer forceUpdate callback',
			'outer componentDidUpdate'
		]);

		// Force update Inner
		log = [];
		forceUpdateInner();
		rerender();
		expect(log).to.deep.equal([
			'inner getDerivedStateFromProps',
			'inner render',
			'inner getSnapshotBeforeUpdate',
			'inner forceUpdate callback',
			'inner componentDidUpdate'
		]);

		// Unmounting Outer & Inner
		log = [];
		render(
, scratch);
		expect(log).to.deep.equal([
			'outer componentWillUnmount',
			'inner componentWillUnmount'
		]);
	});

	describe('#constructor and component(Did|Will)(Mount|Unmount)', () => {
		let setState;
		class Outer extends Component {
			constructor(p, c) {
				super(p, c);
				this.state = { show: true };
				setState = s => this.setState(s);
			}
			render(props, { show }) {
				return
{show && <Inner {...props} />}
;
			}
		}

		class LifecycleTestComponent extends Component {
			componentWillMount() {}
			componentDidMount() {}
			componentWillUnmount() {}
			render() {
				return
;
			}
		}

		class Inner extends LifecycleTestComponent {
			render() {
				return (

						<InnerMost />

				);
			}
		}

		class InnerMost extends LifecycleTestComponent {
			render() {
				return
;
			}
		}

		let spies = [
			'componentWillMount',
			'componentDidMount',
			'componentWillUnmount'
		];

		let verifyLifecycleMethods = TestComponent => {
			let proto = TestComponent.prototype;
			spies.forEach(s => sinon.spy(proto, s));
			let reset = () => spies.forEach(s => proto[s].resetHistory());

			it('should be invoked for components on initial render', () => {
				reset();
				render(<Outer />, scratch);
				expect(proto.componentDidMount).to.have.been.called;
				expect(proto.componentWillMount).to.have.been.calledBefore(
					proto.componentDidMount
				);
				expect(proto.componentDidMount).to.have.been.called;
			});

			it('should be invoked for components on unmount', () => {
				reset();
				setState({ show: false });
				rerender();

				expect(proto.componentWillUnmount).to.have.been.called;
			});

			it('should be invoked for components on re-render', () => {
				reset();
				setState({ show: true });
				rerender();

				expect(proto.componentDidMount).to.have.been.called;
				expect(proto.componentWillMount).to.have.been.calledBefore(
					proto.componentDidMount
				);
				expect(proto.componentDidMount).to.have.been.called;
			});
		};

		describe('inner components', () => {
			verifyLifecycleMethods(Inner);
		});

		describe('innermost components', () => {
			verifyLifecycleMethods(InnerMost);
		});

		describe('when shouldComponentUpdate() returns false', () => {
			let setState;

			class Outer extends Component {
				constructor() {
					super();
					this.state = { show: true };
					setState = s => this.setState(s);
				}
				render(props, { show }) {
					return (

							{show && (

									<Inner {...props} />

							)}

					);
				}
			}

			class Inner extends Component {
				shouldComponentUpdate() {
					return false;
				}
				componentWillMount() {}
				componentDidMount() {}
				componentWillUnmount() {}
				render() {
					return
;
				}
			}

			let proto = Inner.prototype;
			let spies = [
				'componentWillMount',
				'componentDidMount',
				'componentWillUnmount'
			];
			spies.forEach(s => sinon.spy(proto, s));

			let reset = () => spies.forEach(s => proto[s].resetHistory());

			beforeEach(() => reset());

			it('should be invoke normally on initial mount', () => {
				render(<Outer />, scratch);
				expect(proto.componentWillMount).to.have.been.called;
				expect(proto.componentWillMount).to.have.been.calledBefore(
					proto.componentDidMount
				);
				expect(proto.componentDidMount).to.have.been.called;
			});

			it('should be invoked normally on unmount', () => {
				setState({ show: false });
				rerender();

				expect(proto.componentWillUnmount).to.have.been.called;
			});

			it('should still invoke mount for shouldComponentUpdate():false', () => {
				setState({ show: true });
				rerender();

				expect(proto.componentWillMount).to.have.been.called;
				expect(proto.componentWillMount).to.have.been.calledBefore(
					proto.componentDidMount
				);
				expect(proto.componentDidMount).to.have.been.called;
			});

			it('should still invoke unmount for shouldComponentUpdate():false', () => {
				setState({ show: false });
				rerender();

				expect(proto.componentWillUnmount).to.have.been.called;
			});
		});
	});

	describe('#setState', () => {
		// From preactjs/preact#1170
		it('should NOT mutate state, only create new versions', () => {
			const stateConstant = {};
			let didMount = false;
			let componentState;

			class Stateful extends Component {
				constructor() {
					super(...arguments);
					this.state = stateConstant;
				}

				componentDidMount() {
					didMount = true;

					// eslint-disable-next-line react/no-did-mount-set-state
					this.setState({ key: 'value' }, () => {
						componentState = this.state;
					});
				}

				render() {
					return
;
				}
			}

			render(<Stateful />, scratch);
			rerender();

			expect(didMount).to.equal(true);
			expect(componentState).to.deep.equal({ key: 'value' });
			expect(stateConstant).to.deep.equal({});
		});

		// This feature is not mentioned in the docs, but is part of the release
		// notes for react v16.0.0: https://reactjs.org/blog/2017/09/26/react-v16.0.html#breaking-changes
		it('should abort if updater function returns null', () => {
			let updateState;
			class Foo extends Component {
				constructor() {
					super();
					this.state = { value: 0 };
					updateState = () =>
						this.setState(prev => {
							prev.value++;
							return null;
						});
				}

				render() {
					return 'value: ' + this.state.value;
				}
			}

			let renderSpy = sinon.spy(Foo.prototype, 'render');
			render(<Foo />, scratch);
			renderSpy.resetHistory();

			updateState();
			rerender();
			expect(renderSpy).to.not.be.called;
		});

		it('should call callback with correct this binding', () => {
			let inst;
			let updateState;
			class Foo extends Component {
				constructor() {
					super();
					updateState = () => this.setState({}, this.onUpdate);
				}

				onUpdate() {
					inst = this;
				}
			}

			render(<Foo />, scratch);
			updateState();
			rerender();

			expect(inst).to.be.instanceOf(Foo);
		});
	});

	describe('Lifecycle DOM Timing', () => {
		it('should be invoked when dom does (DidMount, WillUnmount) or does not (WillMount, DidUnmount) exist', () => {
			let setState;
			class Outer extends Component {
				constructor() {
					super();
					this.state = { show: true };
					setState = s => {
						this.setState(s);
						this.forceUpdate();
					};
				}
				componentWillMount() {
					expect(
						document.getElementById('OuterDiv'),
						'Outer componentWillMount'
					).to.not.exist;
				}
				componentDidMount() {
					expect(document.getElementById('OuterDiv'), 'Outer componentDidMount')
						.to.exist;
				}
				componentWillUnmount() {
					expect(
						document.getElementById('OuterDiv'),
						'Outer componentWillUnmount'
					).to.exist;
					setTimeout(() => {
						expect(
							document.getElementById('OuterDiv'),
							'Outer after componentWillUnmount'
						).to.not.exist;
					}, 0);
				}
				render(props, { show }) {
					return (

							{show && (

									<Inner {...props} />

							)}

					);
				}
			}

			class Inner extends Component {
				componentWillMount() {
					expect(
						document.getElementById('InnerDiv'),
						'Inner componentWillMount'
					).to.not.exist;
				}
				componentDidMount() {
					expect(document.getElementById('InnerDiv'), 'Inner componentDidMount')
						.to.exist;
				}
				componentWillUnmount() {
					// @TODO Component mounted into elements (non-components)
					// are currently unmounted after those elements, so their
					// DOM is unmounted prior to the method being called.
					//expect(document.getElementById('InnerDiv'), 'Inner componentWillUnmount').to.exist;
					setTimeout(() => {
						expect(
							document.getElementById('InnerDiv'),
							'Inner after componentWillUnmount'
						).to.not.exist;
					}, 0);
				}

				render() {
					return
;
				}
			}

			let proto = Inner.prototype;
			let spies = [
				'componentWillMount',
				'componentDidMount',
				'componentWillUnmount'
			];
			spies.forEach(s => sinon.spy(proto, s));

			let reset = () => spies.forEach(s => proto[s].resetHistory());

			render(<Outer />, scratch);
			expect(proto.componentWillMount).to.have.been.called;
			expect(proto.componentWillMount).to.have.been.calledBefore(
				proto.componentDidMount
			);
			expect(proto.componentDidMount).to.have.been.called;

			reset();
			setState({ show: false });
			rerender();

			expect(proto.componentWillUnmount).to.have.been.called;

			reset();
			setState({ show: true });
			rerender();

			expect(proto.componentWillMount).to.have.been.called;
			expect(proto.componentWillMount).to.have.been.calledBefore(
				proto.componentDidMount
			);
			expect(proto.componentDidMount).to.have.been.called;
		});

		it('should be able to use getDerivedStateFromError and componentDidCatch together', () => {
			let didCatch = sinon.spy(),
				getDerived = sinon.spy();
			const error = new Error('hi');

			class Boundary extends Component {
				static getDerivedStateFromError(err) {
					getDerived(err);
					return { err };
				}

				componentDidCatch(err) {
					didCatch(err);
				}

				render() {
					return this.state.err ?
 : this.props.children;
				}
			}

			const ThrowErr = () => {
				throw error;
			};

			render(
				<Boundary>
					<ThrowErr />
				</Boundary>,
				scratch
			);
			rerender();

			expect(didCatch).to.have.been.calledWith(error);

			expect(getDerived).to.have.been.calledWith(error);
		});

		it('should remove this.base for HOC', () => {
			let createComponent = (name, fn) => {
				class C extends Component {
					componentWillUnmount() {
						expect(this.base, `${name}.componentWillUnmount`).to.exist;
						setTimeout(() => {
							expect(this.base, `after ${name}.componentWillUnmount`).not.to
								.exist;
						}, 0);
					}
					render(props) {
						return fn(props);
					}
				}
				sinon.spy(C.prototype, 'componentWillUnmount');
				sinon.spy(C.prototype, 'render');
				return C;
			};

			class Wrapper extends Component {
				render({ children }) {
					return
{children}
;
				}
			}

			let One = createComponent('One', () => <Wrapper>one</Wrapper>);
			let Two = createComponent('Two', () => <Wrapper>two</Wrapper>);
			let Three = createComponent('Three', () => <Wrapper>three</Wrapper>);

			let components = [One, Two, Three];

			let Selector = createComponent('Selector', ({ page }) => {
				let Child = components[page];
				return Child && <Child />;
			});

			let app;
			class App extends Component {
				constructor() {
					super();
					app = this;
				}

				render(_, { page }) {
					return <Selector page={page} />;
				}
			}

			render(<App />, scratch);

			for (let i = 0; i < 20; i++) {
				app.setState({ page: i % components.length });
				app.forceUpdate();
			}
		});
	});
});


import { observer } from "mobx-react"
import { Component, h } from "preact"
import { Profile } from "./profile"
import { Link, Route, Router } from "./router"
import { store } from "./store"

import "./styles/index.scss";

@observer
export default class App extends Component {
  componentDidMount() {
    store.loadUsers().catch(console.error)
  }

  render() {
    return (
      <Router>

              Sort by{" "}
              <select
                value={store.usersOrder}
                onChange={(ev: any) => {
                  store.setUsersOrder(ev.target.value)
                }}
              >
                <option value="name">Name</option>
                <option value="id">ID</option>
              </select>

              {store.getSortedUsers().map((user, i) => (
                <li
                  key={user.id}
                  style={{
                    animationDelay: `${i * 20}ms`,
                    top: `calc(var(--menu-item-height) * ${i})`,
                    transitionDelay: `${i * 20}ms`,
                  }}
                >
                  <Link href={`people/${user.id}`} active>

                    {user.name.first} {user.name.last}
                  </Link>

              ))}

            <Route match="people">
              <Route match="*" component={Profile} />
            </Route>

      </Router>
    )
  }
}


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('static getDerivedStateFromProps', () => {
		it('should set initial state with value returned from getDerivedStateFromProps', () => {
			class Foo extends Component {
				static getDerivedStateFromProps(props) {
					return {
						foo: props.foo,
						bar: 'bar'
					};
				}
				render() {
					return <div className={`${this.state.foo} ${this.state.bar}`} />;
				}
			}

			render(<Foo foo="foo" />, scratch);
			expect(scratch.firstChild.className).to.be.equal('foo bar');
		});

		it('should update initial state with value returned from getDerivedStateFromProps', () => {
			class Foo extends Component {
				constructor(props, context) {
					super(props, context);
					this.state = {
						foo: 'foo',
						bar: 'bar'
					};
				}
				static getDerivedStateFromProps(props, state) {
					return {
						foo: `not-${state.foo}`
					};
				}
				render() {
					return <div className={`${this.state.foo} ${this.state.bar}`} />;
				}
			}

			render(<Foo />, scratch);
			expect(scratch.firstChild.className).to.equal('not-foo bar');
		});

		it("should update the instance's state with the value returned from getDerivedStateFromProps when props change", () => {
			class Foo extends Component {
				constructor(props, context) {
					super(props, context);
					this.state = {
						value: 'initial'
					};
				}
				static getDerivedStateFromProps(props) {
					if (props.update) {
						return {
							value: 'updated'
						};
					}

					return null;
				}
				componentDidMount() {}
				componentDidUpdate() {}
				render() {
					return
;
				}
			}

			sinon.spy(Foo, 'getDerivedStateFromProps');
			sinon.spy(Foo.prototype, 'componentDidMount');
			sinon.spy(Foo.prototype, 'componentDidUpdate');

			render(<Foo update={false} />, scratch);
			expect(scratch.firstChild.className).to.equal('initial');
			expect(Foo.getDerivedStateFromProps).to.have.callCount(1);
			expect(Foo.prototype.componentDidMount).to.have.callCount(1); // verify mount occurred
			expect(Foo.prototype.componentDidUpdate).to.have.callCount(0);

			render(<Foo update />, scratch);
			expect(scratch.firstChild.className).to.equal('updated');
			expect(Foo.getDerivedStateFromProps).to.have.callCount(2);
			expect(Foo.prototype.componentDidMount).to.have.callCount(1);
			expect(Foo.prototype.componentDidUpdate).to.have.callCount(1); // verify update occurred
		});

		it("should update the instance's state with the value returned from getDerivedStateFromProps when state changes", () => {
			class Foo extends Component {
				constructor(props, context) {
					super(props, context);
					this.state = {
						value: 'initial'
					};
				}
				static getDerivedStateFromProps(props, state) {
					// Don't change state for call that happens after the constructor
					if (state.value === 'initial') {
						return null;
					}

					return {
						value: state.value + ' derived'
					};
				}
				componentDidMount() {
					// eslint-disable-next-line react/no-did-mount-set-state
					this.setState({ value: 'updated' });
				}
				render() {
					return
;
				}
			}

			sinon.spy(Foo, 'getDerivedStateFromProps');

			render(<Foo />, scratch);
			expect(scratch.firstChild.className).to.equal('initial');
			expect(Foo.getDerivedStateFromProps).to.have.been.calledOnce;

			rerender(); // call rerender to handle cDM setState call
			expect(scratch.firstChild.className).to.equal('updated derived');
			expect(Foo.getDerivedStateFromProps).to.have.been.calledTwice;
		});

		it('should NOT modify state if null is returned', () => {
			class Foo extends Component {
				constructor(props, context) {
					super(props, context);
					this.state = {
						foo: 'foo',
						bar: 'bar'
					};
				}
				static getDerivedStateFromProps() {
					return null;
				}
				render() {
					return <div className={`${this.state.foo} ${this.state.bar}`} />;
				}
			}

			sinon.spy(Foo, 'getDerivedStateFromProps');

			render(<Foo />, scratch);
			expect(scratch.firstChild.className).to.equal('foo bar');
			expect(Foo.getDerivedStateFromProps).to.have.been.called;
		});

		// NOTE: Difference from React
		// React v16.3.2 warns if undefined if returned from getDerivedStateFromProps
		it('should NOT modify state if undefined is returned', () => {
			class Foo extends Component {
				constructor(props, context) {
					super(props, context);
					this.state = {
						foo: 'foo',
						bar: 'bar'
					};
				}
				static getDerivedStateFromProps() {}
				render() {
					return <div className={`${this.state.foo} ${this.state.bar}`} />;
				}
			}

			sinon.spy(Foo, 'getDerivedStateFromProps');

			render(<Foo />, scratch);
			expect(scratch.firstChild.className).to.equal('foo bar');
			expect(Foo.getDerivedStateFromProps).to.have.been.called;
		});

		it('should NOT invoke deprecated lifecycles (cWM/cWRP) if new static gDSFP is present', () => {
			class Foo extends Component {
				static getDerivedStateFromProps() {}
				componentWillMount() {}
				componentWillReceiveProps() {}
				render() {
					return
;
				}
			}

			sinon.spy(Foo, 'getDerivedStateFromProps');
			sinon.spy(Foo.prototype, 'componentWillMount');
			sinon.spy(Foo.prototype, 'componentWillReceiveProps');

			render(<Foo />, scratch);
			expect(Foo.getDerivedStateFromProps).to.have.been.called;
			expect(Foo.prototype.componentWillMount).to.not.have.been.called;
			expect(Foo.prototype.componentWillReceiveProps).to.not.have.been.called;
		});

		it('is not called if neither state nor props have changed', () => {
			let logs = [];
			let childRef;

			class Parent extends Component {
				constructor(props) {
					super(props);
					this.state = { parentRenders: 0 };
				}

				static getDerivedStateFromProps(props, state) {
					logs.push('parent getDerivedStateFromProps');
					return state.parentRenders + 1;
				}

				render() {
					logs.push('parent render');
					return <Child parentRenders={this.state.parentRenders} />;
				}
			}

			class Child extends Component {
				constructor(props) {
					super(props);
					childRef = this;
				}
				render() {
					logs.push('child render');
					return this.props.parentRenders;
				}
			}

			render(<Parent />, scratch);
			expect(logs).to.deep.equal([
				'parent getDerivedStateFromProps',
				'parent render',
				'child render'
			]);

			logs = [];
			childRef.setState({});
			rerender();
			expect(logs).to.deep.equal(['child render']);
		});

		// TODO: Investigate this test:
		// [should not override state with stale values if prevState is spread within getDerivedStateFromProps](https://github.com/facebook/react/blob/25dda90c1ecb0c662ab06e2c80c1ee31e0ae9d36/packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js#L1035)

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

			let propsArg;
			let stateArg;

			class Foo extends Component {
				constructor(props) {
					super(props);
					this.state = {
						value: 0
					};
					updateState = () =>
						this.setState({
							value: this.state.value + 1
						});
				}
				static getDerivedStateFromProps(props, state) {
					// These object references might be updated later so copy
					// object so we can assert their values at this snapshot in time
					propsArg = { ...props };
					stateArg = { ...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
					};
				}
				render() {
					return
{this.state.value}
;
				}
			}

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

			let element = scratch.firstChild;
			expect(element.textContent).to.be.equal('1');
			expect(propsArg).to.deep.equal({
				foo: 'foo'
			});
			expect(stateArg).to.deep.equal({
				value: 0
			});

			// New Props
			// state.value: 1 -> 2 in gDSFP
			render(<Foo foo="bar" />, scratch);
			expect(element.textContent).to.be.equal('2');
			expect(propsArg).to.deep.equal({
				foo: 'bar'
			});
			expect(stateArg).to.deep.equal({
				value: 1
			});

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

			// New Props (see #1446)
			// 4 -> 5 in gDSFP
			render(<Foo foo="baz" />, scratch);
			expect(element.textContent).to.be.equal('5');
			expect(stateArg).to.deep.equal({
				value: 4
			});

			// New Props (see #1446)
			// 5 -> 6 in gDSFP
			render(<Foo foo="qux" />, scratch);
			expect(element.textContent).to.be.equal('6');
			expect(stateArg).to.deep.equal({
				value: 5
			});
		});

		// From preactjs/preact#1170
		it('should NOT mutate state on mount, only create new versions', () => {
			const stateConstant = {};
			let componentState;

			class Stateful extends Component {
				static getDerivedStateFromProps() {
					return { key: 'value' };
				}

				constructor() {
					super(...arguments);
					this.state = stateConstant;
				}

				componentDidMount() {
					componentState = this.state;
				}

				render() {
					return
;
				}
			}

			render(<Stateful />, scratch);

			// Verify captured object references didn't get mutated
			expect(componentState).to.deep.equal({ key: 'value' });
			expect(stateConstant).to.deep.equal({});
		});

		it('should NOT mutate state on update, only create new versions', () => {
			const initialState = {};
			const capturedStates = [];

			let setState;

			class Stateful extends Component {
				static getDerivedStateFromProps(props, state) {
					return { value: (state.value || 0) + 1 };
				}

				constructor() {
					super(...arguments);
					this.state = initialState;
					capturedStates.push(this.state);

					setState = this.setState.bind(this);
				}

				componentDidMount() {
					capturedStates.push(this.state);
				}

				componentDidUpdate() {
					capturedStates.push(this.state);
				}

				render() {
					return
;
				}
			}

			render(<Stateful />, scratch);

			setState({ value: 10 });
			rerender();

			// Verify captured object references didn't get mutated
			expect(capturedStates).to.deep.equal([{}, { value: 1 }, { value: 11 }]);
		});
	});
});


_component: null,
_hydrating: null,
constructor: undefined,
_original: ++options._vnodeId,
__source,
__self
};

import { _catchError } from './diff/catch-error';

/**
 * The `option` object can potentially contain callback functions
 * that are called during various stages of our renderer. This is the
 * foundation on which all our addons like `preact/debug`, `preact/compat`,
 * and `preact/hooks` are based on. See the `Options` type in `internal.d.ts`
 * for a full list of available option hooks (most editors/IDEs allow you to
 * ctrl+click or cmd+click on mac the type definition below).
 * @type {import('./internal').Options}
 */
const options = {
	_catchError,
	_vnodeId: 0
};

export default options;


!(function() {
	'use strict';
	function h(nodeName, attributes) {
		var lastSimple,
			child,
			simple,
			i,
			children = EMPTY_CHILDREN;
		for (i = arguments.length; i-- > 2; ) stack.push(arguments[i]);
		if (attributes && null != attributes.children) {
			if (!stack.length) stack.push(attributes.children);
			delete attributes.children;
		}
		while (stack.length)
			if ((child = stack.pop()) && void 0 !== child.pop)
				for (i = child.length; i--; ) stack.push(child[i]);
			else {
				if ('boolean' == typeof child) child = null;
				if ((simple = 'function' != typeof nodeName))
					if (null == child) child = '';
					else if ('number' == typeof child) child = String(child);
					else if ('string' != typeof child) simple = !1;
				if (simple && lastSimple) children[children.length - 1] += child;
				else if (children === EMPTY_CHILDREN) children = [child];
				else children.push(child);
				lastSimple = simple;
			}
		var p = new VNode();
		p.nodeName = nodeName;
		p.children = children;
		p.attributes = null == attributes ? void 0 : attributes;
		p.key = null == attributes ? void 0 : attributes.key;
		if (void 0 !== options.vnode) options.vnode(p);
		return p;
	}
	function extend(obj, props) {
		for (var i in props) obj[i] = props[i];
		return obj;
	}
	function applyRef(ref, value) {
		if ('function' == typeof ref) ref(value);
		else if (null != ref) ref.current = value;
	}
	function cloneElement(vnode, props) {
		return h(
			vnode.nodeName,
			extend(extend({}, vnode.attributes), props),
			arguments.length > 2 ? [].slice.call(arguments, 2) : vnode.children
		);
	}
	function enqueueRender(component) {
		if (!component.__d && (component.__d = !0) && 1 == items.push(component))
			(options.debounceRendering || defer)(rerender);
	}
	function rerender() {
		var p;
		while ((p = items.pop())) if (p.__d) renderComponent(p);
	}
	function isSameNodeType(node, vnode, hydrating) {
		if ('string' == typeof vnode || 'number' == typeof vnode)
			return void 0 !== node.splitText;
		if ('string' == typeof vnode.nodeName)
			return !node._componentConstructor && isNamedNode(node, vnode.nodeName);
		else return hydrating || node._componentConstructor === vnode.nodeName;
	}
	function isNamedNode(node, nodeName) {
		return (
			node.__n === nodeName ||
			node.nodeName.toLowerCase() === nodeName.toLowerCase()
		);
	}
	function getNodeProps(vnode) {
		var props = extend({}, vnode.attributes);
		props.children = vnode.children;
		var defaultProps = vnode.nodeName.defaultProps;
		if (void 0 !== defaultProps)
			for (var i in defaultProps)
				if (void 0 === props[i]) props[i] = defaultProps[i];
		return props;
	}
	function createNode(nodeName, isSvg) {
		var node = isSvg
			? document.createElementNS('http://www.w3.org/2000/svg', nodeName)
			: document.createElement(nodeName);
		node.__n = nodeName;
		return node;
	}
	function removeNode(node) {
		var parentNode = node.parentNode;
		if (parentNode) parentNode.removeChild(node);
	}
	function setAccessor(node, name, old, value, isSvg) {
		if ('className' === name) name = 'class';
		if ('key' === name);
		else if ('ref' === name) {
			applyRef(old, null);
			applyRef(value, node);
		} else if ('class' === name && !isSvg) node.className = value || '';
		else if ('style' === name) {
			if (!value || 'string' == typeof value || 'string' == typeof old)
				node.style.cssText = value || '';
			if (value && 'object' == typeof value) {
				if ('string' != typeof old)
					for (var i in old) if (!(i in value)) node.style[i] = '';
				for (var i in value)
					node.style[i] =
						'number' == typeof value[i] && !1 === IS_NON_DIMENSIONAL.test(i)
							? value[i] + 'px'
							: value[i];
			}
		} else if ('dangerouslySetInnerHTML' === name) {
			if (value) node.innerHTML = value.__html || '';
		} else if ('o' == name[0] && 'n' == name[1]) {
			var useCapture = name !== (name = name.replace(/Capture$/, ''));
			name = name.toLowerCase().substring(2);
			if (value) {
				if (!old) node.addEventListener(name, eventProxy, useCapture);
			} else node.removeEventListener(name, eventProxy, useCapture);
			(node.__l || (node.__l = {}))[name] = value;
		} else if ('list' !== name && 'type' !== name && !isSvg && name in node) {
			try {
				node[name] = null == value ? '' : value;
			} catch (e) {}
			if ((null == value || !1 === value) && 'spellcheck' != name)
				node.removeAttribute(name);
		} else {
			var ns = isSvg && name !== (name = name.replace(/^xlink:?/, ''));
			if (null == value || !1 === value)
				if (ns)
					node.removeAttributeNS(
						'http://www.w3.org/1999/xlink',
						name.toLowerCase()
					);
				else node.removeAttribute(name);
			else if ('function' != typeof value)
				if (ns)
					node.setAttributeNS(
						'http://www.w3.org/1999/xlink',
						name.toLowerCase(),
						value
					);
				else node.setAttribute(name, value);
		}
	}
	function eventProxy(e) {
		return this.__l[e.type]((options.event && options.event(e)) || e);
	}
	function flushMounts() {
		var c;
		while ((c = mounts.pop())) {
			if (options.afterMount) options.afterMount(c);
			if (c.componentDidMount) c.componentDidMount();
		}
	}
	function diff(dom, vnode, context, mountAll, parent, componentRoot) {
		if (!diffLevel++) {
			isSvgMode = null != parent && void 0 !== parent.ownerSVGElement;
			hydrating = null != dom && !('__preactattr_' in dom);
		}
		var ret = idiff(dom, vnode, context, mountAll, componentRoot);
		if (parent && ret.parentNode !== parent) parent.appendChild(ret);
		if (!--diffLevel) {
			hydrating = !1;
			if (!componentRoot) flushMounts();
		}
		return ret;
	}
	function idiff(dom, vnode, context, mountAll, componentRoot) {
		var out = dom,
			prevSvgMode = isSvgMode;
		if (null == vnode || 'boolean' == typeof vnode) vnode = '';
		if ('string' == typeof vnode || 'number' == typeof vnode) {
			if (
				dom &&
				void 0 !== dom.splitText &&
				dom.parentNode &&
				(!dom._component || componentRoot)
			) {
				if (dom.nodeValue != vnode) dom.nodeValue = vnode;
			} else {
				out = document.createTextNode(vnode);
				if (dom) {
					if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
					recollectNodeTree(dom, !0);
				}
			}
			out.__preactattr_ = !0;
			return out;
		}
		var vnodeName = vnode.nodeName;
		if ('function' == typeof vnodeName)
			return buildComponentFromVNode(dom, vnode, context, mountAll);
		isSvgMode =
			'svg' === vnodeName ? !0 : 'foreignObject' === vnodeName ? !1 : isSvgMode;
		vnodeName = String(vnodeName);
		if (!dom || !isNamedNode(dom, vnodeName)) {
			out = createNode(vnodeName, isSvgMode);
			if (dom) {
				while (dom.firstChild) out.appendChild(dom.firstChild);
				if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
				recollectNodeTree(dom, !0);
			}
		}
		var fc = out.firstChild,
			props = out.__preactattr_,
			vchildren = vnode.children;
		if (null == props) {
			props = out.__preactattr_ = {};
			for (var a = out.attributes, i = a.length; i--; )
				props[a[i].name] = a[i].value;
		}
		if (
			!hydrating &&
			vchildren &&
			1 === vchildren.length &&
			'string' == typeof vchildren[0] &&
			null != fc &&
			void 0 !== fc.splitText &&
			null == fc.nextSibling
		) {
			if (fc.nodeValue != vchildren[0]) fc.nodeValue = vchildren[0];
		} else if ((vchildren && vchildren.length) || null != fc)
			innerDiffNode(
				out,
				vchildren,
				context,
				mountAll,
				hydrating || null != props.dangerouslySetInnerHTML
			);
		diffAttributes(out, vnode.attributes, props);
		isSvgMode = prevSvgMode;
		return out;
	}
	function innerDiffNode(dom, vchildren, context, mountAll, isHydrating) {
		var j,
			c,
			f,
			vchild,
			child,
			originalChildren = dom.childNodes,
			children = [],
			keyed = {},
			keyedLen = 0,
			min = 0,
			len = originalChildren.length,
			childrenLen = 0,
			vlen = vchildren ? vchildren.length : 0;
		if (0 !== len)
			for (var i = 0; i < len; i++) {
				var _child = originalChildren[i],
					props = _child.__preactattr_,
					key =
						vlen && props
							? _child._component
								? _child._component.__k
								: props.key
							: null;
				if (null != key) {
					keyedLen++;
					keyed[key] = _child;
				} else if (
					props ||
					(void 0 !== _child.splitText
						? isHydrating
							? _child.nodeValue.trim()
							: !0
						: isHydrating)
				)
					children[childrenLen++] = _child;
			}
		if (0 !== vlen)
			for (var i = 0; i < vlen; i++) {
				vchild = vchildren[i];
				child = null;
				var key = vchild.key;
				if (null != key) {
					if (keyedLen && void 0 !== keyed[key]) {
						child = keyed[key];
						keyed[key] = void 0;
						keyedLen--;
					}
				} else if (min < childrenLen)
					for (j = min; j < childrenLen; j++)
						if (
							void 0 !== children[j] &&
							isSameNodeType((c = children[j]), vchild, isHydrating)
						) {
							child = c;
							children[j] = void 0;
							if (j === childrenLen - 1) childrenLen--;
							if (j === min) min++;
							break;
						}
				child = idiff(child, vchild, context, mountAll);
				f = originalChildren[i];
				if (child && child !== dom && child !== f)
					if (null == f) dom.appendChild(child);
					else if (child === f.nextSibling) removeNode(f);
					else dom.insertBefore(child, f);
			}
		if (keyedLen)
			for (var i in keyed)
				if (void 0 !== keyed[i]) recollectNodeTree(keyed[i], !1);
		while (min <= childrenLen)
			if (void 0 !== (child = children[childrenLen--]))
				recollectNodeTree(child, !1);
	}
	function recollectNodeTree(node, unmountOnly) {
		var component = node._component;
		if (component) unmountComponent(component);
		else {
			if (null != node.__preactattr_) applyRef(node.__preactattr_.ref, null);
			if (!1 === unmountOnly || null == node.__preactattr_) removeNode(node);
			removeChildren(node);
		}
	}
	function removeChildren(node) {
		node = node.lastChild;
		while (node) {
			var next = node.previousSibling;
			recollectNodeTree(node, !0);
			node = next;
		}
	}
	function diffAttributes(dom, attrs, old) {
		var name;
		for (name in old)
			if ((!attrs || null == attrs[name]) && null != old[name])
				setAccessor(dom, name, old[name], (old[name] = void 0), isSvgMode);
		for (name in attrs)
			if (
				!(
					'children' === name ||
					'innerHTML' === name ||
					(name in old &&
						attrs[name] ===
							('value' === name || 'checked' === name ? dom[name] : old[name]))
				)
			)
				setAccessor(dom, name, old[name], (old[name] = attrs[name]), isSvgMode);
	}
	function createComponent(Ctor, props, context) {
		var inst,
			i = recyclerComponents.length;
		if (Ctor.prototype && Ctor.prototype.render) {
			inst = new Ctor(props, context);
			Component.call(inst, props, context);
		} else {
			inst = new Component(props, context);
			inst.constructor = Ctor;
			inst.render = doRender;
		}
		while (i--)
			if (recyclerComponents[i].constructor === Ctor) {
				inst.__b = recyclerComponents[i].__b;
				recyclerComponents.splice(i, 1);
				return inst;
			}
		return inst;
	}
	function doRender(props, state, context) {
		return this.constructor(props, context);
	}
	function setComponentProps(component, props, renderMode, context, mountAll) {
		if (!component.__x) {
			component.__x = !0;
			component.__r = props.ref;
			component.__k = props.key;
			delete props.ref;
			delete props.key;
			if (void 0 === component.constructor.getDerivedStateFromProps)
				if (!component.base || mountAll) {
					if (component.componentWillMount) component.componentWillMount();
				} else if (component.componentWillReceiveProps)
					component.componentWillReceiveProps(props, context);
			if (context && context !== component.context) {
				if (!component.__c) component.__c = component.context;
				component.context = context;
			}
			if (!component.__p) component.__p = component.props;
			component.props = props;
			component.__x = !1;
			if (0 !== renderMode)
				if (
					1 === renderMode ||
					!1 !== options.syncComponentUpdates ||
					!component.base
				)
					renderComponent(component, 1, mountAll);
				else enqueueRender(component);
			applyRef(component.__r, component);
		}
	}
	function renderComponent(component, renderMode, mountAll, isChild) {
		if (!component.__x) {
			var rendered,
				inst,
				cbase,
				props = component.props,
				state = component.state,
				context = component.context,
				previousProps = component.__p || props,
				previousState = component.__s || state,
				previousContext = component.__c || context,
				isUpdate = component.base,
				nextBase = component.__b,
				initialBase = isUpdate || nextBase,
				initialChildComponent = component._component,
				skip = !1,
				snapshot = previousContext;
			if (component.constructor.getDerivedStateFromProps) {
				state = extend(
					extend({}, state),
					component.constructor.getDerivedStateFromProps(props, state)
				);
				component.state = state;
			}
			if (isUpdate) {
				component.props = previousProps;
				component.state = previousState;
				component.context = previousContext;
				if (
					2 !== renderMode &&
					component.shouldComponentUpdate &&
					!1 === component.shouldComponentUpdate(props, state, context)
				)
					skip = !0;
				else if (component.componentWillUpdate)
					component.componentWillUpdate(props, state, context);
				component.props = props;
				component.state = state;
				component.context = context;
			}
			component.__p = component.__s = component.__c = component.__b = null;
			component.__d = !1;
			if (!skip) {
				rendered = component.render(props, state, context);
				if (component.getChildContext)
					context = extend(extend({}, context), component.getChildContext());
				if (isUpdate && component.getSnapshotBeforeUpdate)
					snapshot = component.getSnapshotBeforeUpdate(
						previousProps,
						previousState
					);
				var toUnmount,
					base,
					childComponent = rendered && rendered.nodeName;
				if ('function' == typeof childComponent) {
					var childProps = getNodeProps(rendered);
					inst = initialChildComponent;
					if (
						inst &&
						inst.constructor === childComponent &&
						childProps.key == inst.__k
					)
						setComponentProps(inst, childProps, 1, context, !1);
					else {
						toUnmount = inst;
						component._component = inst = createComponent(
							childComponent,
							childProps,
							context
						);
						inst.__b = inst.__b || nextBase;
						inst.__u = component;
						setComponentProps(inst, childProps, 0, context, !1);
						renderComponent(inst, 1, mountAll, !0);
					}
					base = inst.base;
				} else {
					cbase = initialBase;
					toUnmount = initialChildComponent;
					if (toUnmount) cbase = component._component = null;
					if (initialBase || 1 === renderMode) {
						if (cbase) cbase._component = null;
						base = diff(
							cbase,
							rendered,
							context,
							mountAll || !isUpdate,
							initialBase && initialBase.parentNode,
							!0
						);
					}
				}
				if (
					initialBase &&
					base !== initialBase &&
					inst !== initialChildComponent
				) {
					var baseParent = initialBase.parentNode;
					if (baseParent && base !== baseParent) {
						baseParent.replaceChild(base, initialBase);
						if (!toUnmount) {
							initialBase._component = null;
							recollectNodeTree(initialBase, !1);
						}
					}
				}
				if (toUnmount) unmountComponent(toUnmount);
				component.base = base;
				if (base && !isChild) {
					var componentRef = component,
						t = component;
					while ((t = t.__u)) (componentRef = t).base = base;
					base._component = componentRef;
					base._componentConstructor = componentRef.constructor;
				}
			}
			if (!isUpdate || mountAll) mounts.unshift(component);
			else if (!skip) {
				if (component.componentDidUpdate)
					component.componentDidUpdate(previousProps, previousState, snapshot);
				if (options.afterUpdate) options.afterUpdate(component);
			}
			while (component.__h.length) component.__h.pop().call(component);
			if (!diffLevel && !isChild) flushMounts();
		}
	}
	function buildComponentFromVNode(dom, vnode, context, mountAll) {
		var c = dom && dom._component,
			originalComponent = c,
			oldDom = dom,
			isDirectOwner = c && dom._componentConstructor === vnode.nodeName,
			isOwner = isDirectOwner,
			props = getNodeProps(vnode);
		while (c && !isOwner && (c = c.__u))
			isOwner = c.constructor === vnode.nodeName;
		if (c && isOwner && (!mountAll || c._component)) {
			setComponentProps(c, props, 3, context, mountAll);
			dom = c.base;
		} else {
			if (originalComponent && !isDirectOwner) {
				unmountComponent(originalComponent);
				dom = oldDom = null;
			}
			c = createComponent(vnode.nodeName, props, context);
			if (dom && !c.__b) {
				c.__b = dom;
				oldDom = null;
			}
			setComponentProps(c, props, 1, context, mountAll);
			dom = c.base;
			if (oldDom && dom !== oldDom) {
				oldDom._component = null;
				recollectNodeTree(oldDom, !1);
			}
		}
		return dom;
	}
	function unmountComponent(component) {
		if (options.beforeUnmount) options.beforeUnmount(component);
		var base = component.base;
		component.__x = !0;
		if (component.componentWillUnmount) component.componentWillUnmount();
		component.base = null;
		var inner = component._component;
		if (inner) unmountComponent(inner);
		else if (base) {
			if (base.__preactattr_ && base.__preactattr_.ref)
				base.__preactattr_.ref(null);
			component.__b = base;
			removeNode(base);
			recyclerComponents.push(component);
			removeChildren(base);
		}
		applyRef(component.__r, null);
	}
	function Component(props, context) {
		this.__d = !0;
		this.context = context;
		this.props = props;
		this.state = this.state || {};
		this.__h = [];
	}
	function render(vnode, parent, merge) {
		return diff(merge, vnode, {}, !1, parent, !1);
	}
	function createRef() {
		return {};
	}
	var VNode = function() {};
	var options = {};
	var stack = [];
	var EMPTY_CHILDREN = [];
	var defer =
		'function' == typeof Promise
			? Promise.resolve().then.bind(Promise.resolve())
			: setTimeout;
	var IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i;
	var items = [];
	var mounts = [];
	var diffLevel = 0;
	var isSvgMode = !1;
	var hydrating = !1;
	var recyclerComponents = [];
	extend(Component.prototype, {
		setState: function(state, callback) {
			if (!this.__s) this.__s = this.state;
			this.state = extend(
				extend({}, this.state),
				'function' == typeof state ? state(this.state, this.props) : state
			);
			if (callback) this.__h.push(callback);
			enqueueRender(this);
		},
		forceUpdate: function(callback) {
			if (callback) this.__h.push(callback);
			renderComponent(this, 2);
		},
		render: function() {}
	});
	var preact = {
		h: h,
		createElement: h,
		cloneElement: cloneElement,
		createRef: createRef,
		Component: Component,
		render: render,
		rerender: rerender,
		options: options
	};
	if ('undefined' != typeof module) module.exports = preact;
	else self.preact = preact;
})();
//# sourceMappingURL=preact.js.map


import { createElement, cloneElement, createRef } from 'preact';

/** @jsx createElement */

describe('cloneElement', () => {
	it('should clone components', () => {
		function Comp() {}
		const instance = <Comp prop1={1}>hello</Comp>;
		const clone = cloneElement(instance);

		expect(clone.prototype).to.equal(instance.prototype);
		expect(clone.type).to.equal(instance.type);
		expect(clone.props).not.to.equal(instance.props); // Should be a different object...
		expect(clone.props).to.deep.equal(instance.props); // with the same properties
	});

	it('should merge new props', () => {
		function Foo() {}
		const instance = <Foo prop1={1} prop2={2} />;
		const clone = cloneElement(instance, { prop1: -1, newProp: -2 });

		expect(clone.prototype).to.equal(instance.prototype);
		expect(clone.type).to.equal(instance.type);
		expect(clone.props).not.to.equal(instance.props);
		expect(clone.props.prop1).to.equal(-1);
		expect(clone.props.prop2).to.equal(2);
		expect(clone.props.newProp).to.equal(-2);
	});

	it('should override children if specified', () => {
		function Foo() {}
		const instance = <Foo>hello</Foo>;
		const clone = cloneElement(instance, null, 'world', '!');

		expect(clone.prototype).to.equal(instance.prototype);
		expect(clone.type).to.equal(instance.type);
		expect(clone.props).not.to.equal(instance.props);
		expect(clone.props.children).to.deep.equal(['world', '!']);
	});

	it('should override key if specified', () => {
		function Foo() {}
		const instance = <Foo key="1">hello</Foo>;

		let clone = cloneElement(instance);
		expect(clone.key).to.equal('1');

		clone = cloneElement(instance, { key: '2' });
		expect(clone.key).to.equal('2');
	});

	it('should override ref if specified', () => {
		function a() {}
		function b() {}
		function Foo() {}
		const instance = <Foo ref={a}>hello</Foo>;

		let clone = cloneElement(instance);
		expect(clone.ref).to.equal(a);

		clone = cloneElement(instance, { ref: b });
		expect(clone.ref).to.equal(b);
	});

	it('should normalize props (ref)', () => {
		const div =
hello
;
		const clone = cloneElement(div, { ref: createRef() });
		expect(clone.props.ref).to.equal(undefined);
	});

	it('should normalize props (key)', () => {
		const div =
hello
;
		const clone = cloneElement(div, { key: 'myKey' });
		expect(clone.props.key).to.equal(undefined);
	});
});


html, body {
  font: 14px system-ui, sans-serif;
}
.list {
  list-style: none;
  padding: 0;
}
.list > li {
  position: relative;
  padding: 5px 10px;
  animation: fadeIn 1s ease;
}
@keyframes fadeIn {
  0% {
    box-shadow: inset 0 0 2px 2px red,
                0 0 2px 2px red;
  }
}
.list > .odd {
  background-color: #def;
}
.list > .even {
  background-color: #fed;
}


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

if (typeof type === 'function' && (ref = type.defaultProps)) {

if (typeof normalizedProps[i] === 'undefined') {

import { options, Fragment } from 'preact';

/** @typedef {import('preact').VNode} VNode */

/**
 * @fileoverview
 * This file exports various methods that implement Babel's "automatic" JSX runtime API:
 * - jsx(type, props, key)
 * - jsxs(type, props, key)
 * - jsxDEV(type, props, key, __source, __self)
 *
 * The implementation of createVNode here is optimized for performance.
 * Benchmarks: https://esbench.com/bench/5f6b54a0b4632100a7dcd2b3
 */

/**
 * JSX.Element factory used by Babel's {runtime:"automatic"} JSX transform
 * @param {VNode['type']} type
 * @param {VNode['props']} props
 * @param {VNode['key']} [key]
 * @param {string} [__source]
 * @param {string} [__self]
 */
function createVNode(type, props, key, __source, __self) {
	// We'll want to preserve `ref` in props to get rid of the need for
	// forwardRef components in the future, but that should happen via
	// a separate PR.
	let normalizedProps = {};
	for (let i in props) {
		if (i != 'ref') {
			normalizedProps[i] = props[i];
		}
	}

	const vnode = {
		type,
		props: normalizedProps,
		key,
		ref: props && props.ref,
		_children: null,
		_parent: null,
		_depth: 0,
		_dom: null,
		_nextDom: undefined,
		_component: null,
		_hydrating: null,
		constructor: undefined,
		_original: ++options._vnodeId,
		__source,
		__self
	};

	// If a Component VNode, check for and apply defaultProps.
	// Note: `type` is often a String, and can be `undefined` in development.
	let defaults, i;
	if (typeof type === 'function' && (defaults = type.defaultProps)) {
		for (i in defaults)
			if (normalizedProps[i] === undefined) {
				normalizedProps[i] = defaults[i];
			}
	}

	if (options.vnode) options.vnode(vnode);
	return vnode;
}

export {
	createVNode as jsx,
	createVNode as jsxs,
	createVNode as jsxDEV,
	Fragment
};


import { createElement, Component } from 'preact';
import { connect, Provider } from 'react-redux';
import { createStore } from 'redux';
import { HashRouter, Route, Link } from 'react-router-dom';

const store = createStore(
	(state, action) => ({ ...state, display: action.display }),
	{ display: false }
);

function _Redux({ showMe, counter }) {
	if (!showMe) return null;
	return
showMe {counter}
;
}
const Redux = connect(
	state => console.log('injecting', state.display) || { showMe: state.display }
)(_Redux);

let display = false;
class Test extends Component {
	componentDidUpdate(prevProps) {
		if (this.props.start != prevProps.start) {
			this.setState({ f: (this.props.start || 0) + 1 });
			setTimeout(() => this.setState({ i: (this.state.i || 0) + 1 }));
		}
	}

	render() {
		const { f } = this.state;
		return (

				<button
					onClick={() => {
						display = !display;
						store.dispatch({ type: 1, display });
					}}
				>
					Toggle visibility
				</button>
				<Link to={`/${(parseInt(this.props.start) || 0) + 1}`}>Click me</Link>

				<Redux counter={f} />

		);
	}
}

function App() {
	return (
		<Provider store={store}>
			<HashRouter>
				<Route
					path="/:start?"
					render={({ match }) => <Test start={match.params.start || 0} />}
				/>
			</HashRouter>
		</Provider>
	);
}

export default App;


const ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';

let loggedTypeFailures = {};

/**
 * Reset the history of which prop type warnings have been logged.
 */
export function resetPropWarnings() {
	loggedTypeFailures = {};
}

/**
 * Assert that the values match with the type specs.
 * Error messages are memorized and will only be shown once.
 *
 * Adapted from https://github.com/facebook/prop-types/blob/master/checkPropTypes.js
 *
 * @param {object} typeSpecs Map of name to a ReactPropType
 * @param {object} values Runtime values that need to be type-checked
 * @param {string} location e.g. "prop", "context", "child context"
 * @param {string} componentName Name of the component for error messages.
 * @param {?Function} getStack Returns the component stack.
 */
export function checkPropTypes(
	typeSpecs,
	values,
	location,
	componentName,
	getStack
) {
	Object.keys(typeSpecs).forEach(typeSpecName => {
		let error;
		try {
			error = typeSpecs[typeSpecName](
				values,
				typeSpecName,
				componentName,
				location,
				null,
				ReactPropTypesSecret
			);
		} catch (e) {
			error = e;
		}
		if (error && !(error.message in loggedTypeFailures)) {
			loggedTypeFailures[error.message] = true;
			console.error(
				`Failed ${location} type: ${error.message}${(getStack &&
					`\n${getStack()}`) ||
					''}`
			);
		}
	});
}


import 'mocha';
import { expect } from 'chai';
import { createElement, Component, RenderableProps, Fragment } from '../../';

// Test `this` binding on event handlers
function onHandler(this: HTMLInputElement, event: any) {
	return this.value;
}
const foo = <input onChange={onHandler} />;

export class ContextComponent extends Component<{ foo: string }> {
	getChildContext() {
		return { something: 2 };
	}

	render() {
		return null;
	}
}

export interface SimpleComponentProps {
	initialName: string | null;
}

export interface SimpleState {
	name: string | null;
}

export class SimpleComponent extends Component<
	SimpleComponentProps,
	SimpleState
> {
	constructor(props: SimpleComponentProps) {
		super(props);
		this.state = {
			name: props.initialName
		};
	}

	render() {
		if (!this.state.name) {
			return null;
		}
		const { initialName, children } = this.props;
		return (

					{initialName} / {this.state.name}

				{children}

		);
	}
}

class DestructuringRenderPropsComponent extends Component<
	SimpleComponentProps,
	SimpleState
> {
	constructor(props: SimpleComponentProps) {
		super(props);
		this.state = {
			name: props.initialName
		};
	}

	render({ initialName, children }: RenderableProps<SimpleComponentProps>) {
		if (!this.state.name) {
			return null;
		}
		return (

				{this.props.initialName} / {this.state.name}

		);
	}
}

interface RandomChildrenComponentProps {
	num?: number;
	val?: string;
	span?: boolean;
}

class RandomChildrenComponent extends Component<RandomChildrenComponentProps> {
	render() {
		const { num, val, span } = this.props;
		if (num) {
			return num;
		}
		if (val) {
			return val;
		}
		if (span) {
			return hi;
		}
		return null;
	}
}

class StaticComponent extends Component<SimpleComponentProps, SimpleState> {
	static getDerivedStateFromProps(
		props: SimpleComponentProps,
		state: SimpleState
	): Partial<SimpleState> {
		return {
			...props,
			...state
		};
	}

	static getDerivedStateFromError(err: Error) {
		return {
			name: err.message
		};
	}

	render() {
		return null;
	}
}

function MapperItem(props: { foo: number }) {
	return
;
}

function Mapper() {
	return [1, 2, 3].map(x => <MapperItem foo={x} key={x} />);
}

describe('Component', () => {
	const component = new SimpleComponent({ initialName: 'da name' });

	it('has state', () => {
		expect(component.state.name).to.eq('da name');
	});

	it('has props', () => {
		expect(component.props.initialName).to.eq('da name');
	});

	it('has no base when not mounted', () => {
		expect(component.base).to.not.exist;
	});

	describe('setState', () => {
		// No need to execute these tests. because we only need to check if
		// the types are working. Executing them would require the DOM.
		// TODO: Run TS tests in our standard karma setup
		it.skip('can be used with an object', () => {
			component.setState({ name: 'another name' });
		});

		it.skip('can be used with a function', () => {
			const updater = (state: any, props: any) => ({
				name: `${state.name} - ${props.initialName}`
			});
			component.setState(updater);
		});
	});

	describe('render', () => {
		it('can return null', () => {
			const comp = new SimpleComponent({ initialName: null });
			const actual = comp.render();

			expect(actual).to.eq(null);
		});
	});

	describe('Fragment', () => {
		it('should render nested Fragments', () => {
			var vnode = (
				<Fragment>
					<Fragment>foo</Fragment>
					bar
				</Fragment>
			);

			expect(vnode.type).to.be.equal(Fragment);
		});
	});
});


keep keep keep replace keep keep keep keep keep

import options from './options';

/**
 * Create an virtual node (used for JSX)
 * @param {import('./internal').VNode["type"]} type The node name or Component
 * constructor for this virtual node
 * @param {object | null | undefined} [props] The properties of the virtual node
 * @param {Array<import('.').ComponentChildren>} [children] The children of the virtual node
 * @returns {import('./internal').VNode}
 */
export function createElement(type, props, children) {
	let normalizedProps = {},
		key,
		ref,
		i;
	for (i in props) {
		if (i == 'key') key = props[i];
		else if (i == 'ref') ref = props[i];
		else normalizedProps[i] = props[i];
	}

	if (arguments.length > 3) {
		children = [children];
		// https://github.com/preactjs/preact/issues/1916
		for (i = 3; i < arguments.length; i++) {
			children.push(arguments[i]);
		}
	}
	if (children != null) {
		normalizedProps.children = children;
	}

	// If a Component VNode, check for and apply defaultProps
	// Note: type may be undefined in development, must never error here.
	if (typeof type == 'function' && type.defaultProps != null) {
		for (i in type.defaultProps) {
			if (normalizedProps[i] === undefined) {
				normalizedProps[i] = type.defaultProps[i];
			}
		}
	}

	return createVNode(type, normalizedProps, key, ref, null);
}

/**
 * Create a VNode (used internally by Preact)
 * @param {import('./internal').VNode["type"]} type The node name or Component
 * Constructor for this virtual node
 * @param {object | string | number | null} props The properties of this virtual node.
 * If this virtual node represents a text node, this is the text of the node (string or number).
 * @param {string | number | null} key The key for this virtual node, used when
 * diffing it against its children
 * @param {import('./internal').VNode["ref"]} ref The ref property that will
 * receive a reference to its created child
 * @returns {import('./internal').VNode}
 */
export function createVNode(type, props, key, ref, original) {
	// V8 seems to be better at detecting type shapes if the object is allocated from the same call site
	// Do not inline into createElement and coerceToVNode!
	const vnode = {
		type,
		props,
		key,
		ref,
		_children: null,
		_parent: null,
		_depth: 0,
		_dom: null,
		// _nextDom must be initialized to undefined b/c it will eventually
		// be set to dom.nextSibling which can return `null` and it is important
		// to be able to distinguish between an uninitialized _nextDom and
		// a _nextDom that has been set to `null`
		_nextDom: undefined,
		_component: null,
		_hydrating: null,
		constructor: undefined,
		_original: original == null ? ++options._vnodeId : original
	};

	if (options.vnode != null) options.vnode(vnode);

	return vnode;
}

export function createRef() {
	return { current: null };
}

export function Fragment(props) {
	return props.children;
}

/**
 * Check if a the argument is a valid Preact VNode.
 * @param {*} vnode
 * @returns {vnode is import('./internal').VNode}
 */
export const isValidElement = vnode =>
	vnode != null && vnode.constructor === undefined;


/* eslint-disable */
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const preact = path.join(__dirname, '..', 'src');
const compat = path.join(__dirname, '..', 'compat', 'src');

module.exports = {
	context: __dirname,
	entry: './index',
	output: {
		publicPath: '/'
	},
	resolve: {
		alias: {
			['preact/debug']: path.join(__dirname, '..', 'debug'),
			['preact/devtools']: path.join(__dirname, '..', 'devtools'),
			['preact/hooks']: path.join(__dirname, '..', 'hooks', 'src'),
			preact: preact,
			react: compat,
			'react-dom': compat
		},
		extensions: ['.tsx', '.ts', '.js']
	},
	module: {
		rules: [
			{
				test: /\.tsx?$/,
				loader: 'babel-loader',
				options: {
					sourceMap: true,
					presets: [
						[require.resolve('@babel/preset-typescript'), { jsxPragma: 'h' }],
						[
							require.resolve('@babel/preset-env'),
							{
								targets: {
									browsers: ['last 2 versions', 'IE >= 9']
								},
								modules: false,
								loose: true
							}
						],
						[require.resolve('@babel/preset-react')]
					],
					plugins: [
						[require.resolve('@babel/plugin-transform-runtime')],
						[require.resolve('@babel/plugin-transform-react-jsx-source')],
						[
							require.resolve('@babel/plugin-transform-react-jsx'),
							{ pragma: 'h', pragmaFrag: 'Fragment' }
						],
						[
							require.resolve('@babel/plugin-proposal-decorators'),
							{ legacy: true }
						],
						[
							require.resolve('@babel/plugin-proposal-class-properties'),
							{ loose: true }
						]
					]
				}
			},
			{
				test: /\.js$/,
				loader: 'babel-loader',
				options: {
					sourceMap: true,
					presets: [
						[
							require.resolve('@babel/preset-env'),
							{
								targets: {
									browsers: ['last 2 versions', 'IE >= 9']
								},
								modules: false,
								loose: true
							}
						],
						[require.resolve('@babel/preset-react')]
					],
					plugins: [
						[require.resolve('@babel/plugin-transform-react-jsx-source')],
						[
							require.resolve('@babel/plugin-transform-react-jsx'),
							{ pragma: 'createElement', pragmaFrag: 'Fragment' }
						],
						[require.resolve('@babel/plugin-proposal-class-properties')],
						[
							require.resolve('@babel/plugin-transform-react-constant-elements')
						],
						[require.resolve('@babel/plugin-syntax-dynamic-import')]
					]
				}
			},
			{
				test: /\.s?css$/,
				use: ['style-loader', 'css-loader', 'sass-loader']
			}
		]
	},
	devtool: 'inline-source-map',
	node: {
		process: 'mock',
		Buffer: false,
		setImmediate: false
	},
	devServer: {
		historyApiFallback: true
	},
	plugins: [new HtmlWebpackPlugin()]
};


import { createElement, render, createRef, Component, Fragment } from 'preact';
import {
	setupScratch,
	teardown,
	serializeHtml
} from '../../../test/_util/helpers';
import './fakeDevTools';
import 'preact/debug';
import * as PropTypes from 'prop-types';

// eslint-disable-next-line no-duplicate-imports
import { resetPropWarnings } from 'preact/debug';

const h = createElement;
/** @jsx createElement */

describe('debug', () => {
	let scratch;
	let errors = [];
	let warnings = [];

	beforeEach(() => {
		errors = [];
		warnings = [];
		scratch = setupScratch();
		sinon.stub(console, 'error').callsFake(e => errors.push(e));
		sinon.stub(console, 'warn').callsFake(w => warnings.push(w));
	});

	afterEach(() => {
		/** @type {*} */
		(console.error).restore();
		console.warn.restore();
		teardown(scratch);
	});

	it('should initialize devtools', () => {
		expect(window.__PREACT_DEVTOOLS__.attachPreact).to.have.been.called;
	});

	it('should print an error on rendering on undefined parent', () => {
		let fn = () => render(
, undefined);
		expect(fn).to.throw(/render/);
	});

	it('should print an error on rendering on invalid parent', () => {
		let fn = () => render(
, 6);
		expect(fn).to.throw(/valid HTML node/);
		expect(fn).to.throw(/
 {
		const App = () =>
;
		let fn = () => render(<App />, 6);
		expect(fn).to.throw(/<App/);
		expect(fn).to.throw(/6/);

		fn = () => render(<App />, {});
		expect(fn).to.throw(/<App/);
		expect(fn).to.throw(/[object Object]/);

		fn = () => render(<Fragment />, 'badroot');
		expect(fn).to.throw(/<Fragment/);
		expect(fn).to.throw(/badroot/);
	});

	it('should print an error with (class) component name when available', () => {
		class App extends Component {
			render() {
				return
;
			}
		}
		let fn = () => render(<App />, 6);
		expect(fn).to.throw(/<App/);
	});

	it('should print an error on undefined component', () => {
		let fn = () => render(h(undefined), scratch);
		expect(fn).to.throw(/createElement/);
	});

	it('should print an error on invalid object component', () => {
		let fn = () => render(h({}), scratch);
		expect(fn).to.throw(/createElement/);
	});

	it('should print an error when component is an array', () => {
		let fn = () => render(h([
]), scratch);
		expect(fn).to.throw(/createElement/);
	});

	it('should print an error on double jsx conversion', () => {
		let Foo =
;
		let fn = () => render(h(<Foo />), scratch);
		expect(fn).to.throw(/JSX twice/);
	});

	it('should add __source to the vnode in debug mode.', () => {
		const vnode = h('div', {
			__source: {
				fileName: 'div.jsx',
				lineNumber: 3
			}
		});
		expect(vnode.__source).to.deep.equal({
			fileName: 'div.jsx',
			lineNumber: 3
		});
		expect(vnode.props.__source).to.be.undefined;
	});

	it('should add __self to the vnode in debug mode.', () => {
		const vnode = h('div', {
			__self: {}
		});
		expect(vnode.__self).to.deep.equal({});
		expect(vnode.props.__self).to.be.undefined;
	});

	it('should warn when accessing certain attributes', () => {
		const vnode = h('div', null);

		// Push into an array to avoid empty statements being dead code eliminated
		const res = [];
		res.push(vnode);
		res.push(vnode.attributes);
		expect(console.warn).to.be.calledOnce;
		expect(console.warn.args[0]).to.match(/use vnode.props/);
		res.push(vnode.nodeName);
		expect(console.warn).to.be.calledTwice;
		expect(console.warn.args[1]).to.match(/use vnode.type/);
		res.push(vnode.children);
		expect(console.warn).to.be.calledThrice;
		expect(console.warn.args[2]).to.match(/use vnode.props.children/);

		// Should only warn once
		res.push(vnode.attributes);
		expect(console.warn).to.be.calledThrice;
		res.push(vnode.nodeName);
		expect(console.warn).to.be.calledThrice;
		res.push(vnode.children);
		expect(console.warn).to.be.calledThrice;

		vnode.attributes = {};
		expect(console.warn.args[3]).to.match(/use vnode.props/);
		vnode.nodeName = '';
		expect(console.warn.args[4]).to.match(/use vnode.type/);
		vnode.children = [];
		expect(console.warn.args[5]).to.match(/use vnode.props.children/);

		// Should only warn once
		vnode.attributes = {};
		expect(console.warn.args.length).to.equal(6);
		vnode.nodeName = '';
		expect(console.warn.args.length).to.equal(6);
		vnode.children = [];
		expect(console.warn.args.length).to.equal(6);

		// Mark res as used, otherwise it will be dead code eliminated
		expect(res.length).to.equal(7);
	});

	it('should warn when calling setState inside the constructor', () => {
		class Foo extends Component {
			constructor(props) {
				super(props);
				this.setState({ foo: true });
			}
			render() {
				return
foo
;
			}
		}

		render(<Foo />, scratch);
		expect(console.warn).to.be.calledOnce;
		expect(console.warn.args[0]).to.match(/no-op/);
	});

	it('should NOT warn when calling setState inside the cWM', () => {
		class Foo extends Component {
			componentWillMount() {
				this.setState({ foo: true });
			}
			render() {
				return
foo
;
			}
		}

		render(<Foo />, scratch);
		expect(console.warn).to.not.be.called;
	});

	it('should warn when calling setState on an unmounted Component', () => {
		let setState;

		class Foo extends Component {
			constructor(props) {
				super(props);
				setState = () => this.setState({ foo: true });
			}
			render() {
				return
foo
;
			}
		}

		render(<Foo />, scratch);
		expect(console.warn).to.not.be.called;

		render(null, scratch);

		setState();
		expect(console.warn).to.be.calledOnce;
		expect(console.warn.args[0]).to.match(/no-op/);
	});

	it('should warn when calling forceUpdate inside the constructor', () => {
		class Foo extends Component {
			constructor(props) {
				super(props);
				this.forceUpdate();
			}
			render() {
				return
foo
;
			}
		}

		render(<Foo />, scratch);
		expect(console.warn).to.be.calledOnce;
		expect(console.warn.args[0]).to.match(/no-op/);
	});

	it('should warn when calling forceUpdate on an unmounted Component', () => {
		let forceUpdate;

		class Foo extends Component {
			constructor(props) {
				super(props);
				forceUpdate = () => this.forceUpdate();
			}
			render() {
				return
foo
;
			}
		}

		render(<Foo />, scratch);
		forceUpdate();
		expect(console.warn).to.not.be.called;

		render(null, scratch);

		forceUpdate();
		expect(console.warn).to.be.calledOnce;
		expect(console.warn.args[0]).to.match(/no-op/);
	});

	it('should print an error when child is a plain object', () => {
		let fn = () => render(
{{}}
, scratch);
		expect(fn).to.throw(/not valid/);
	});

	it('should print an error on invalid refs', () => {
		let fn = () => render(
, scratch);
		expect(fn).to.throw(/createRef/);
	});

	it('should not print for null as a handler', () => {
		let fn = () => render(
, scratch);
		expect(fn).not.to.throw();
	});

	it('should not print for undefined as a handler', () => {
		let fn = () => render(
, scratch);
		expect(fn).not.to.throw();
	});

	it('should not print for attributes starting with on for Components', () => {
		const Comp = () =>
online
;
		let fn = () => render(<Comp online={false} />, scratch);
		expect(fn).not.to.throw();
	});

	it('should print an error on invalid handler', () => {
		let fn = () => render(
, scratch);
		expect(fn).to.throw(/"onclick" property should be a function/);
	});

	it('should NOT print an error on valid refs', () => {
		let noop = () => {};
		render(
, scratch);

		let ref = createRef();
		render(
, scratch);
		expect(console.error).to.not.be.called;
	});

	describe('duplicate keys', () => {
		const List = props =>
{props.children}
;
		const ListItem = props =>
{props.children}
;

		it('should print an error on duplicate keys with DOM nodes', () => {
			render(

,
				scratch
			);
			expect(console.error).to.be.calledOnce;
		});

		it('should allow distinct object keys', () => {
			const A = { is: 'A' };
			const B = { is: 'B' };
			render(

,
				scratch
			);
			expect(console.error).not.to.be.called;
		});

		it('should print an error for duplicate object keys', () => {
			const A = { is: 'A' };
			render(

,
				scratch
			);
			expect(console.error).to.be.calledOnce;
		});

		it('should print an error on duplicate keys with Components', () => {
			function App() {
				return (
					<List>
						<ListItem key="a">a</ListItem>
						<ListItem key="b">b</ListItem>
						<ListItem key="b">d</ListItem>
						<ListItem key="d">d</ListItem>
					</List>
				);
			}

			render(<App />, scratch);
			expect(console.error).to.be.calledOnce;
		});

		it('should print an error on duplicate keys with Fragments', () => {
			function App() {
				return (
					<Fragment>
						<List key="list">
							<ListItem key="a">a</ListItem>
							<ListItem key="b">b</ListItem>
							<Fragment key="b">
								{/* Should be okay to duplicate keys since these are inside a Fragment */}
								<ListItem key="a">c</ListItem>
								<ListItem key="b">d</ListItem>
								<ListItem key="c">e</ListItem>
							</Fragment>
							<ListItem key="f">f</ListItem>
						</List>

sibling

					</Fragment>
				);
			}

			render(<App />, scratch);
			expect(console.error).to.be.calledTwice;
		});
	});

	describe('table markup', () => {
		it('missing
/
/
/
', () => {
			const Table = () => (

					hi

			);
			render(
, scratch);
			expect(console.error).to.be.calledOnce;
		});

		it('missing
 with
', () => {
			const Table = () => (

						hi

			);
			render(
, scratch);
			expect(console.error).to.be.calledOnce;
		});

		it('missing
 with
', () => {
			const Table = () => (

						hi

			);
			render(
, scratch);
			expect(console.error).to.be.calledOnce;
		});

		it('missing
 with
', () => {
			const Table = () => (

						hi

			);
			render(
, scratch);
			expect(console.error).to.be.calledOnce;
		});

		it('missing
', () => {
			const Table = () => (

						Hi

			);
			render(
, scratch);
			expect(console.error).to.be.calledOnce;
		});

		it('missing
 with td component', () => {
			const Cell = ({ children }) => {children}	;
			const Table = () => (

						<Cell>Hi</Cell>

			);
			render(
, scratch);
			expect(console.error).to.be.calledOnce;
		});

		it('missing
 with th component', () => {
			const Cell = ({ children }) => {children}	;
			const Table = () => (

						<Cell>Hi</Cell>

			);
			render(
, scratch);
			expect(console.error).to.be.calledOnce;
		});

		it('Should accept  instead of  in
', () => {
			const Table = () => (

							Hi

			);
			render(
, scratch);
			expect(console.error).to.not.be.called;
		});

		it('Accepts well formed table with TD components', () => {
			const Cell = ({ children }) => {children}	;
			const Table = () => (

							Head

							Body

							<Cell>Body</Cell>

			);
			render(
, scratch);
			expect(console.error).to.not.be.called;
		});

		it('Accepts well formed table', () => {
			const Table = () => (

							Head

							Body

							Body

			);
			render(
, scratch);
			expect(console.error).to.not.be.called;
		});

		it('Accepts minimal well formed table', () => {
			const Table = () => (

						Head

						Body

			);
			render(
, scratch);
			expect(console.error).to.not.be.called;
		});
	});

	describe('PropTypes', () => {
		beforeEach(() => {
			resetPropWarnings();
		});

		it("should fail if props don't match prop-types", () => {
			function Foo(props) {
				return
{props.text}
;
			}

			Foo.propTypes = {
				text: PropTypes.string.isRequired
			};

			render(<Foo text={123} />, scratch);

			expect(console.error).to.be.calledOnce;

			// The message here may change when the "prop-types" library is updated,
			// but we check it exactly to make sure all parameters were supplied
			// correctly.
			expect(console.error).to.have.been.calledOnceWith(
				sinon.match(
					/^Failed prop type: Invalid prop `text` of type `number` supplied to `Foo`, expected `string`\.\n {2}in Foo \(at (.*)[/\\]debug[/\\]test[/\\]browser[/\\]debug\.test\.js:[0-9]+\)$/m
				)
			);
		});

		it('should only log a given prop type error once', () => {
			function Foo(props) {
				return
{props.text}
;
			}

			Foo.propTypes = {
				text: PropTypes.string.isRequired,
				count: PropTypes.number
			};

			// Trigger the same error twice. The error should only be logged
			// once.
			render(<Foo text={123} />, scratch);
			render(<Foo text={123} />, scratch);

			expect(console.error).to.be.calledOnce;

			// Trigger a different error. This should result in a new log
			// message.
			console.error.resetHistory();
			render(<Foo text="ok" count="123" />, scratch);
			expect(console.error).to.be.calledOnce;
		});

		it('should render with error logged when validator gets signal and throws exception', () => {
			function Baz(props) {
				return
{props.unhappy}
;
			}

			Baz.propTypes = {
				unhappy: function alwaysThrows(obj, key) {
					if (obj[key] === 'signal') throw Error('got prop');
				}
			};

			render(<Baz unhappy={'signal'} />, scratch);

			expect(console.error).to.be.calledOnce;
			expect(errors[0].includes('got prop')).to.equal(true);
			expect(serializeHtml(scratch)).to.equal('
signal
');
		});

		it('should not print to console when types are correct', () => {
			function Bar(props) {
				return
{props.text}
;
			}

			Bar.propTypes = {
				text: PropTypes.string.isRequired
			};

			render(<Bar text="foo" />, scratch);
			expect(console.error).to.not.be.called;
		});
	});
});


global._ = require('lodash');
const Benchmark = (global.Benchmark = require('benchmark'));

export default function bench(benches, callback) {
	return new Promise(resolve => {
		const suite = new Benchmark.Suite();

		let i = 0;
		Object.keys(benches).forEach(name => {
			let run = benches[name];
			suite.add(name, () => {
				run(++i);
			});
		});

		suite.on('complete', () => {
			const result = {
				fastest: suite.filter('fastest')[0],
				results: [],
				text: ''
			};
			const useKilo = suite.filter(b => b.hz < 10000).length === 0;
			suite.forEach((bench, index) => {
				let r = {
					name: bench.name,
					slowdown:
						bench.name === result.fastest.name
							? 0
							: (((result.fastest.hz - bench.hz) / result.fastest.hz) * 100) |
							  0,
					hz: bench.hz.toFixed(bench.hz < 100 ? 2 : 0),
					rme: bench.stats.rme.toFixed(2),
					size: bench.stats.sample.length,
					error: bench.error ? String(bench.error) : undefined
				};
				result.text += `\n  ${r.name}: ${
					useKilo ? `${(r.hz / 1000) | 0} kHz` : `${r.hz} Hz`
				}${r.slowdown ? ` (-${r.slowdown}%)` : ''}`;
				result.results[index] = result.results[r.name] = r;
			});
			resolve(result);
			if (callback) callback(result);
		});
		suite.run({ async: true });
	});
}


* @param {import('./internal').VNode["type"]} type The node name or Component

* @param {object | null | undefined} [props] The properties of the virtual node