/*
 * draggable_options.js
 */
(function($) {

function testScroll(position) {
	$("#main").css('position', position);
	drag(el, 50, 50);
	moved(50, 50, position+' parent');
}

function setScroll(what) {
	if(what) {
		$(document).scrollTop(100); $(document).scrollLeft(100);
	} else {
		$("#main")[0].scrollTop = 100; $("#main")[0].scrollLeft = 100;
	}
}

function border(el, side) {
	return parseInt(el.css('border-' + side + '-width'), 10);
}
function margin(el, side) {
	return parseInt(el.css('margin-' + side), 10);
}

module("draggable: options");

test("{ addClasses: true }, default", function() {
	el = $("

").draggable({ addClasses: true });
	ok(el.is(".ui-draggable"), "'ui-draggable' class added");

	el.draggable("destroy");
});

test("{ addClasses: false }", function() {
	el = $("

").draggable({ addClasses: false });
	ok(!el.is(".ui-draggable"), "'ui-draggable' class not added");

	el.draggable("destroy");
});

test("{ appendTo: 'parent' }, default", function() {
	el = $("#draggable2").draggable({ appendTo: 'parent' });
	drag(el, 50, 50);
	moved(50, 50);

	el = $("#draggable1").draggable({ appendTo: 'parent' });
	drag(el, 50, 50);
	moved(50, 50);

});

test("{ appendTo: Element }", function() {
	el = $("#draggable2").draggable({ appendTo: $("#draggable2").parent()[0] });
	drag(el, 50, 50);
	moved(50, 50);

	el = $("#draggable1").draggable({ appendTo: $("#draggable2").parent()[0] });
	drag(el, 50, 50);
	moved(50, 50);
});

test("{ appendTo: Selector }", function() {
	el = $("#draggable2").draggable({ appendTo: "#main" });
	drag(el, 50, 50);
	moved(50, 50);

	el = $("#draggable1").draggable({ appendTo: "#main" });
	drag(el, 50, 50);
	moved(50, 50);
});

test("{ axis: false }, default", function() {
	el = $("#draggable2").draggable({ axis: false });
	drag(el, 50, 50);
	moved(50, 50);
});

test("{ axis: 'x' }", function() {
	el = $("#draggable2").draggable({ axis: "x" });
	drag(el, 50, 50);
	moved(50, 0);
});

test("{ axis: 'y' }", function() {
	el = $("#draggable2").draggable({ axis: "y" });
	drag(el, 50, 50);
	moved(0, 50);
});

test("{ axis: ? }, unexpected", function() {
	var unexpected = {
		"true": true,
		"{}": {},
		"[]": [],
		"null": null,
		"undefined": undefined,
		"function() {}": function() {}
	};
	$.each(unexpected, function(key, val) {
		el = $("#draggable2").draggable({ axis: val });
		drag(el, 50, 50);
		moved(50, 50, "axis: " + key);
		el.draggable("destroy");
	});
});

test("{ cancel: 'input,textarea,button,select,option' }, default", function() {
	$('
<input type="text">
').appendTo('#main');

	el = $("#draggable-option-cancel-default").draggable({ cancel: "input,textarea,button,select,option" });
	drag("#draggable-option-cancel-default", 50, 50);
	moved(50, 50);

	el = $("#draggable-option-cancel-default").draggable({ cancel: "input,textarea,button,select,option" });
	drag("#draggable-option-cancel-default input", 50, 50);
	moved(0, 0);

	el.draggable("destroy");
});

test("{ cancel: 'span' }", function() {
	el = $("#draggable2").draggable();
	drag("#draggable2 span", 50, 50);
	moved(50, 50);

	el.draggable("destroy");

	el = $("#draggable2").draggable({ cancel: 'span' });
	drag("#draggable2 span", 50, 50);
	moved(0, 0);
});

test("{ cancel: ? }, unexpected", function() {
	var unexpected = {
		"true": true,
		"false": false,
		"{}": {},
		"[]": [],
		"null": null,
		"undefined": undefined,
		"function() {return '';}": function() {return '';},
		"function() {return true;}": function() {return true;},
		"function() {return false;}": function() {return false;}
	};
	$.each(unexpected, function(key, val) {
		el = $("#draggable2").draggable({ cancel: val });
		drag(el, 50, 50);
		var expected = [50, 50];
		moved(expected[0], expected[1], "cancel: " + key);
		el.draggable("destroy");
	});
});

test("{ containment: false }, default", function() {
	ok(false, 'missing test - untested code is broken code');
});

test("{ containment: Element }", function() {
	ok(false, 'missing test - untested code is broken code');
});

test("{ containment: 'parent' }, relative", function() {
	el = $("#draggable1").draggable({ containment: 'parent' });
	var p = el.parent(),
		po = p.offset(),
		expected = {
			left: po.left + border(p, 'left') + margin(el, 'left'),
			top: po.top + border(p, 'top') + margin(el, 'top')
		};
	drag(el, -100, -100);
	deepEqual(offsetAfter, expected, 'compare offset to parent');
});

test("{ containment: 'parent' }, absolute", function() {
	el = $("#draggable2").draggable({ containment: 'parent' });
	var p = el.parent(),
		po = p.offset(),
		expected = {
			left: po.left + border(p, 'left') + margin(el, 'left'),
			top: po.top + border(p, 'top') + margin(el, 'top')
		};
	drag(el, -100, -100);
	deepEqual(offsetAfter, expected, 'compare offset to parent');
});

test("{ containment: 'document' }", function() {
	ok(false, 'missing test - untested code is broken code');
});

test("{ containment: 'window' }", function() {
	ok(false, 'missing test - untested code is broken code');
});

test("{ containment: Selector }", function() {
	ok(false, 'missing test - untested code is broken code');
});

test("{ containment: [x1, y1, x2, y2] }", function() {
	ok(false, 'missing test - untested code is broken code');
});

test("{ cursor: 'auto' }, default", function() {
	function getCursor() { return $("#draggable2").css("cursor"); }

	expect(2);

	var expected = "auto", actual, before, after;

	el = $("#draggable2").draggable({
		cursor: expected,
		start: function(event, ui) {
			actual = getCursor();
		}
	});

	before = getCursor();
	drag("#draggable2", -1, -1);
	after = getCursor();

	equal(actual, expected, "start callback: cursor '" + expected + "'");
	equal(after, before, "after drag: cursor restored");

});

test("{ cursor: 'move' }", function() {

	function getCursor() { return $("body").css("cursor"); }

	expect(2);

	var expected = "move", actual, before, after;

	el = $("#draggable2").draggable({
		cursor: expected,
		start: function(event, ui) {
			actual = getCursor();
		}
	});

	before = getCursor();
	drag("#draggable2", -1, -1);
	after = getCursor();

	equal(actual, expected, "start callback: cursor '" + expected + "'");
	equal(after, before, "after drag: cursor restored");

});

test("{ cursorAt: false}, default", function() {
	ok(false, 'missing test - untested code is broken code');
});

test("{ cursorAt: { left: -5, top: -5 } }", function() {
	expect(4);

	var deltaX = -3, deltaY = -3,
		offsetX = 5, offsetY = 5,
		cursorAtX = -5, cursorAtY = -5;

	$.each(['relative', 'absolute'], function(i, position) {
		var el = $('#draggable' + (i + 1)).draggable({
				cursorAt: { left: cursorAtX, top: cursorAtY },
				drag: function(event, ui) {
					equal(ui.offset.left, expected.left, position + ' left');
					equal(ui.offset.top, expected.top, position + ' top');
				}
			}),
			before = el.offset(),
			pos = {
				clientX: before.left + offsetX,
				clientY: before.top + offsetY
			},
			expected = {
				left: before.left + offsetX - cursorAtX + deltaX,
				top: before.top + offsetY - cursorAtY + deltaY
			};

		el.simulate("mousedown", pos);
		pos.clientX += deltaX;
		pos.clientY += deltaY;
		$(document).simulate("mousemove", pos);
		el.simulate("mouseup", pos);
	});
});

test("{ cursorAt: { right: 10, bottom: 20 } }", function() {
	expect(4);

	var deltaX = -3, deltaY = -3,
		offsetX = 5, offsetY = 5,
		cursorAtX = 10, cursorAtY = 20;

	$.each(['relative', 'absolute'], function(i, position) {
		var el = $('#draggable' + (i + 1)).draggable({
				cursorAt: { right: cursorAtX, bottom: cursorAtY },
				drag: function(event, ui) {
					equal(ui.offset.left, expected.left, position + ' left');
					equal(ui.offset.top, expected.top, position + ' top');
				}
			}),
			before = el.offset(),
			pos = {
				clientX: before.left + offsetX,
				clientY: before.top + offsetY
			},
			expected = {
				left: before.left + offsetX - el.width() + cursorAtX + deltaX,
				top: before.top + offsetY - el.height() + cursorAtY + deltaY
			};

		el.simulate("mousedown", pos);
		pos.clientX += deltaX;
		pos.clientY += deltaY;
		$(document).simulate("mousemove", pos);
		el.simulate("mouseup", pos);
	});
});

test("{ cursorAt: [10, 20] }", function() {
	expect(4);

	var deltaX = -3, deltaY = -3,
		offsetX = 5, offsetY = 5,
		cursorAtX = 10, cursorAtY = 20;

	$.each(['relative', 'absolute'], function(i, position) {
		var el = $('#draggable' + (i + 1)).draggable({
				cursorAt: { left: cursorAtX, top: cursorAtY },
				drag: function(event, ui) {
					equal(ui.offset.left, expected.left, position + ' left');
					equal(ui.offset.top, expected.top, position + ' top');
				}
			}),
			before = el.offset(),
			pos = {
				clientX: before.left + offsetX,
				clientY: before.top + offsetY
			},
			expected = {
				left: before.left + offsetX - cursorAtX + deltaX,
				top: before.top + offsetY - cursorAtY + deltaY
			};

		el.simulate("mousedown", pos);
		pos.clientX += deltaX;
		pos.clientY += deltaY;
		$(document).simulate("mousemove", pos);
		el.simulate("mouseup", pos);
	});
});

test("{ cursorAt: '20, 40' }", function() {
	expect(4);

	var deltaX = -3, deltaY = -3,
		offsetX = 5, offsetY = 5,
		cursorAtX = 20, cursorAtY = 40;

	$.each(['relative', 'absolute'], function(i, position) {
		var el = $('#draggable' + (i + 1)).draggable({
				cursorAt: { left: cursorAtX, top: cursorAtY },
				drag: function(event, ui) {
					equal(ui.offset.left, expected.left, position + ' left');
					equal(ui.offset.top, expected.top, position + ' top');
				}
			}),
			before = el.offset(),
			pos = {
				clientX: before.left + offsetX,
				clientY: before.top + offsetY
			},
			expected = {
				left: before.left + offsetX - cursorAtX + deltaX,
				top: before.top + offsetY - cursorAtY + deltaY
			};

		el.simulate("mousedown", pos);
		pos.clientX += deltaX;
		pos.clientY += deltaY;
		$(document).simulate("mousemove", pos);
		el.simulate("mouseup", pos);
	});
});

test("{ distance: 10 }", function() {

	el = $("#draggable2").draggable({ distance: 10 });
	drag(el, -9, -9);
	moved(0, 0, 'distance not met');

	drag(el, -10, -10);
	moved(-10, -10, 'distance met');

	drag(el, 9, 9);
	moved(0, 0, 'distance not met');

});

test("{ grid: [50, 50] }, relative", function() {
	el = $("#draggable1").draggable({ grid: [50, 50] });
	drag(el, 24, 24);
	moved(0, 0);
	drag(el, 26, 25);
	moved(50, 50);
});

test("{ grid: [50, 50] }, absolute", function() {
	el = $("#draggable2").draggable({ grid: [50, 50] });
	drag(el, 24, 24);
	moved(0, 0);
	drag(el, 26, 25);
	moved(50, 50);
});

test("{ handle: 'span' }", function() {
	el = $("#draggable2").draggable({ handle: 'span' });

	drag("#draggable2 span", 50, 50);
	moved(50, 50, "drag span");

	drag("#draggable2", 50, 50);
	moved(0, 0, "drag element");
});

test("{ helper: 'clone' }, relative", function() {
	el = $("#draggable1").draggable({ helper: "clone" });
	drag(el, 50, 50);
	moved(0, 0);
});

test("{ helper: 'clone' }, absolute", function() {
	el = $("#draggable2").draggable({ helper: "clone" });
	drag(el, 50, 50);
	moved(0, 0);
});

test("{ helper: 'original' }, relative, with scroll offset on parent", function() {

	el = $("#draggable1").draggable({ helper: "original" });

	setScroll();
	testScroll('relative');

	setScroll();
	testScroll('static');

	setScroll();
	testScroll('absolute');

	restoreScroll();

});

test("{ helper: 'original' }, relative, with scroll offset on root", function() {

	el = $("#draggable1").draggable({ helper: "original" });

	setScroll('root');
	testScroll('relative');

	setScroll('root');
	testScroll('static');

	setScroll('root');
	testScroll('absolute');

	restoreScroll('root');

});

test("{ helper: 'original' }, relative, with scroll offset on root and parent", function() {

	el = $("#draggable1").draggable({ helper: "original" });

	setScroll();
	setScroll('root');
	testScroll('relative');

	setScroll();
	setScroll('root');
	testScroll('static');

	setScroll();
	setScroll('root');
	testScroll('absolute');

	restoreScroll();
	restoreScroll('root');

});

test("{ helper: 'original' }, absolute, with scroll offset on parent", function() {

	el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });

	setScroll();
	testScroll('relative');

	setScroll();
	testScroll('static');

	setScroll();
	testScroll('absolute');

	restoreScroll();

});

test("{ helper: 'original' }, absolute, with scroll offset on root", function() {

	el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });

	setScroll('root');
	testScroll('relative');

	setScroll('root');
	testScroll('static');

	setScroll('root');
	testScroll('absolute');

	restoreScroll('root');

});

test("{ helper: 'original' }, absolute, with scroll offset on root and parent", function() {

	el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });

	setScroll();
	setScroll('root');
	testScroll('relative');

	setScroll();
	setScroll('root');
	testScroll('static');

	setScroll();
	setScroll('root');
	testScroll('absolute');

	restoreScroll();
	restoreScroll('root');

});

test("{ helper: 'original' }, fixed, with scroll offset on parent", function() {

	el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });

	setScroll();
	testScroll('relative');

	setScroll();
	testScroll('static');

	setScroll();
	testScroll('absolute');

	restoreScroll();

});

test("{ helper: 'original' }, fixed, with scroll offset on root", function() {

	el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });

	setScroll('root');
	testScroll('relative');

	setScroll('root');
	testScroll('static');

	setScroll('root');
	testScroll('absolute');

	restoreScroll('root');
});

test("{ helper: 'original' }, fixed, with scroll offset on root and parent", function() {

	el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });

	setScroll();
	setScroll('root');
	testScroll('relative');

	setScroll();
	setScroll('root');
	testScroll('static');

	setScroll();
	setScroll('root');
	testScroll('absolute');

	restoreScroll();
	restoreScroll('root');

});

test("{ helper: 'clone' }, absolute", function() {

	var helperOffset = null,
		origOffset = $("#draggable1").offset();

	el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
		helperOffset = ui.helper.offset();
	} });

	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

});

test("{ helper: 'clone' }, absolute with scroll offset on parent", function() {

	setScroll();
	var helperOffset = null,
	origOffset = null;

	el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
		helperOffset = ui.helper.offset();
	} });

	$("#main").css('position', 'relative');
	origOffset = $("#draggable1").offset();
	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

	$("#main").css('position', 'static');
	origOffset = $("#draggable1").offset();
	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

	$("#main").css('position', 'absolute');
	origOffset = $("#draggable1").offset();
	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

	restoreScroll();

});

test("{ helper: 'clone' }, absolute with scroll offset on root", function() {

	setScroll('root');
	var helperOffset = null,
		origOffset = null;

	el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
		helperOffset = ui.helper.offset();
	} });

	$("#main").css('position', 'relative');
	origOffset = $("#draggable1").offset();
	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

	$("#main").css('position', 'static');
	origOffset = $("#draggable1").offset();
	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

	$("#main").css('position', 'absolute');
	origOffset = $("#draggable1").offset();
	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

	restoreScroll('root');

});

test("{ helper: 'clone' }, absolute with scroll offset on root and parent", function() {

	setScroll('root');
	setScroll();
	var helperOffset = null,
		origOffset = null;

	el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
		helperOffset = ui.helper.offset();
	} });

	$("#main").css('position', 'relative');
	origOffset = $("#draggable1").offset();
	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

	$("#main").css('position', 'static');
	origOffset = $("#draggable1").offset();
	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

	$("#main").css('position', 'absolute');
	origOffset = $("#draggable1").offset();
	drag(el, 1, 1);
	deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');

	restoreScroll('root');
	restoreScroll();

});

test("{ opacity: 0.5 }", function() {

	expect(1);

	var opacity = null;
	el = $("#draggable2").draggable({
		opacity: 0.5,
		start: function(event, ui) {
			opacity = $(this).css("opacity");
		}
	});

	drag("#draggable2", -1, -1);

	equal(opacity, 0.5, "start callback: opacity is");

});

test("{ zIndex: 10 }", function() {

	expect(1);

	var actual,
		expected = 10,
		zIndex = null;
	el = $("#draggable2").draggable({
		zIndex: expected,
		start: function(event, ui) {
			actual = $(this).css("zIndex");
		}
	});

	drag("#draggable2", -1, -1);

	equal(actual, expected, "start callback: zIndex is");

});

})(jQuery);


exports.VIEW_HIDE_SIDEBAR           = "view.hideSidebar";

exports.VIEW_INCREASE_FONT_SIZE     = "view.increaseFontSize";

exports.VIEW_DECREASE_FONT_SIZE     = "view.decreaseFontSize";

exports.VIEW_RESTORE_FONT_SIZE      = "view.restoreFontSize";

exports.TOGGLE_CLOSE_BRACKETS       = "view.autoCloseBrackets";

exports.TOGGLE_JSLINT               = "debug.jslint";

exports.SORT_WORKINGSET_BY_ADDED    = "view.sortWorkingSetByAdded";

exports.SORT_WORKINGSET_BY_NAME     = "view.sortWorkingSetByName";

exports.SORT_WORKINGSET_BY_TYPE     = "view.sortWorkingSetByType";

keep keep keep keep keep replace keep keep keep keep

A pure javascript CRC32 algorithm that plays nice with binary data

# buffer-crc32

[![Build Status](https://secure.travis-ci.org/brianloveswords/buffer-crc32.png?branch=master)](http://travis-ci.org/brianloveswords/buffer-crc32)

crc32 that works with binary data and fancy character sets, outputs
buffer, signed or unsigned data and has tests.

Derived from the sample CRC implementation in the PNG specification: http://www.w3.org/TR/PNG/#D-CRCAppendix

# install
```
npm install buffer-crc32
```

# example
```js
var crc32 = require('buffer-crc32');
// works with buffers
var buf = Buffer([[0x00, 0x73, 0x75, 0x70, 0x20, 0x62, 0x72, 0x6f, 0x00])
crc32(buf) // -> <Buffer 94 5a ab 4a>

// has convenience methods for getting signed or unsigned ints
crc32.signed(buf) // -> -1805997238
crc32.unsigned(buf) // -> 2488970058

// will cast to buffer if given a string, so you can
// directly use foreign characters safely
crc32('自動販売機') // -> <Buffer cb 03 1a c5>
```

# tests
This was tested against the output of zlib's crc32 method. You can run
the tests with`npm test` (requires tap)


<!doctype html>

	<meta charset="utf-8">
	<title>jQuery UI Accordion Test Suite</title>

	<link rel="stylesheet" href="../../../external/qunit.css">

jQuery UI Accordion Test Suite

There is one obvious advantage:

			You've seen it coming!

			Buy now and get nothing for free!

			Well, at least no free beer. Perhaps a bear, if you can afford it.

Now that you've got...

			your bear, you have to admit it!

			No, we aren't selling bears.

			We could talk about renting one.

Rent one bear, ...

			get two for three beer.

			And now, for something completely different.

Guitar

Electric

Acoustic

Amps

Effects

Accessories

Bass

Electric

Acoustic

Amps

Effects

Accessories

Accessories

Accessories

Drums

Acoustic

Electronic

Accessories

		Accordion Header 1

		Accordion Content 1

		Accordion Header 2

		Accordion Content 2

		Accordion Header 3

		Accordion Content 3


"CMD_LINE_UP"                         : "Move Line Up",

"CMD_LINE_DOWN"                       : "Move Line Down",

"VIEW_MENU"                           : "View",

"CMD_HIDE_SIDEBAR"                    : "Hide Sidebar",

"CMD_SHOW_SIDEBAR"                    : "Show Sidebar",

/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define */

define({
    /**
     * Errors
     */

    // General file io error strings
    "GENERIC_ERROR"                     : "(error {0})",
    "NOT_FOUND_ERR"                     : "The file could not be found.",
    "NOT_READABLE_ERR"                  : "The file could not be read.",
    "NO_MODIFICATION_ALLOWED_ERR"       : "The target directory cannot be modified.",
    "NO_MODIFICATION_ALLOWED_ERR_FILE"  : "The permissions do not allow you to make modifications.",
    "FILE_EXISTS_ERR"                   : "The file already exists.",

    // Project error strings
    "ERROR_LOADING_PROJECT"             : "Error loading project",
    "OPEN_DIALOG_ERROR"                 : "An error occurred when showing the open file dialog. (error {0})",
    "REQUEST_NATIVE_FILE_SYSTEM_ERROR"  : "An error occurred when trying to load the directory {0}. (error {1})",
    "READ_DIRECTORY_ENTRIES_ERROR"      : "An error occurred when reading the contents of the directory {0}. (error {1})",

    // File open/save error string
    "ERROR_OPENING_FILE_TITLE"          : "Error opening file",
    "ERROR_OPENING_FILE"                : "An error occurred when trying to open the file {0}. {1}",
    "ERROR_RELOADING_FILE_TITLE"        : "Error reloading changes from disk",
    "ERROR_RELOADING_FILE"              : "An error occurred when trying to reload the file {0}. {1}",
    "ERROR_SAVING_FILE_TITLE"           : "Error saving file",
    "ERROR_SAVING_FILE"                 : "An error occurred when trying to save the file {0}. {1}",
    "ERROR_RENAMING_FILE_TITLE"         : "Error renaming file",
    "ERROR_RENAMING_FILE"               : "An error occurred when trying to rename the file {0}. {1}",
    "INVALID_FILENAME_TITLE"            : "Invalid file name",
    "INVALID_FILENAME_MESSAGE"          : "Filenames cannot contain the following characters: /?*:;{}<>\\|",
    "FILE_ALREADY_EXISTS"               : "The file {0} already exists.",
    "ERROR_CREATING_FILE_TITLE"         : "Error creating file",
    "ERROR_CREATING_FILE"               : "An error occurred when trying to create the file {0}. {1}",

    // Application error strings
    "ERROR_IN_BROWSER_TITLE"            : "Oops! {APP_NAME} doesn't run in browsers yet.",
    "ERROR_IN_BROWSER"                  : "{APP_NAME} is built in HTML, but right now it runs as a desktop app so you can use it to edit local files. Please use the application shell in the github.com/adobe/brackets-shell repo to run {APP_NAME}.",

    // FileIndexManager error string
    "ERROR_MAX_FILES_TITLE"             : "Error Indexing Files",
    "ERROR_MAX_FILES"                   : "The maximum number of files have been indexed. Actions that look up files in the index may function incorrectly.",

    // Live Development error strings
    "ERROR_LAUNCHING_BROWSER_TITLE"     : "Error launching browser",
    "ERROR_CANT_FIND_CHROME"            : "The Google Chrome browser could not be found. Please make sure it is installed.",
    "ERROR_LAUNCHING_BROWSER"           : "An error occurred when launching the browser. (error {0})",

    "LIVE_DEVELOPMENT_ERROR_TITLE"      : "Live Preview Error",
    "LIVE_DEVELOPMENT_RELAUNCH_TITLE"   : "Connecting to Browser",
    "LIVE_DEVELOPMENT_ERROR_MESSAGE"    : "In order for Live Preview to connect, Chrome needs to be relaunched with remote debugging enabled.

Would you like to relaunch Chrome and enable remote debugging?",
    "LIVE_DEV_NEED_HTML_MESSAGE"        : "Open an HTML file in order to launch live preview.",
    "LIVE_DEV_NEED_BASEURL_MESSAGE"     : "To launch live preview with a server-side file, you need to specify a Base URL for this project.",
    "LIVE_DEV_SERVER_NOT_READY_MESSAGE" : "Error starting up the HTTP server for live development files. Please try again.",
    "LIVE_DEVELOPMENT_INFO_TITLE"       : "Welcome to Live Preview!",
    "LIVE_DEVELOPMENT_INFO_MESSAGE"     : "Live Preview connects {APP_NAME} to your browser. It launches a preview of your HTML file in the browser, then updates the preview instantly as you edit your code.

In this early version of {APP_NAME}, Live Preview only works with Google Chrome and updates live as you edit CSS files. Changes to HTML or JavaScript files are automatically reloaded when you save.

(You'll only see this message once.)",
    "LIVE_DEVELOPMENT_TROUBLESHOOTING"  : "For more information, see Troubleshooting Live Development connection errors.",

    "LIVE_DEV_STATUS_TIP_NOT_CONNECTED" : "Live Preview",
    "LIVE_DEV_STATUS_TIP_PROGRESS1"     : "Live Preview: Connecting\u2026",
    "LIVE_DEV_STATUS_TIP_PROGRESS2"     : "Live Preview: Initializing\u2026",
    "LIVE_DEV_STATUS_TIP_CONNECTED"     : "Disconnect Live Preview",
    "LIVE_DEV_STATUS_TIP_OUT_OF_SYNC"   : "Live Preview: Click to disconnect (Save file to update)",

    "SAVE_CLOSE_TITLE"                  : "Save Changes",
    "SAVE_CLOSE_MESSAGE"                : "Do you want to save the changes you made in the document {0}?",
    "SAVE_CLOSE_MULTI_MESSAGE"          : "Do you want to save your changes to the following files?",
    "EXT_MODIFIED_TITLE"                : "External Changes",
    "EXT_MODIFIED_MESSAGE"              : "{0} has been modified on disk, but also has unsaved changes in {APP_NAME}.

Which version do you want to keep?",
    "EXT_DELETED_MESSAGE"               : "{0} has been deleted on disk, but has unsaved changes in {APP_NAME}.

Do you want to keep your changes?",

    // Find, Replace, Find in Files
    "SEARCH_REGEXP_INFO"                : "Use /re/ syntax for regexp search",
    "FIND_RESULT_COUNT"                 : "{0} results",
    "WITH"                              : "With",
    "BUTTON_YES"                        : "Yes",
    "BUTTON_NO"                         : "No",
    "BUTTON_STOP"                       : "Stop",

    "OPEN_FILE"                         : "Open File",
    "CHOOSE_FOLDER"                     : "Choose a folder",

    "RELEASE_NOTES"                     : "Release Notes",
    "NO_UPDATE_TITLE"                   : "You're up to date!",
    "NO_UPDATE_MESSAGE"                 : "You are running the latest version of {APP_NAME}.",

    "FIND_IN_FILES_TITLE"               : "for \"{4}\" {5} - {0} {1} in {2} {3}",
    "FIND_IN_FILES_SCOPED"              : "in {0}",
    "FIND_IN_FILES_NO_SCOPE"            : "in project",
    "FIND_IN_FILES_FILE"                : "file",
    "FIND_IN_FILES_FILES"               : "files",
    "FIND_IN_FILES_MATCH"               : "match",
    "FIND_IN_FILES_MATCHES"             : "matches",
    "FIND_IN_FILES_MORE_THAN"           : "More than ",
    "FIND_IN_FILES_MAX"                 : " (showing the first {0} matches)",
    "FIND_IN_FILES_FILE_PATH"           : "File: {0}",
    "FIND_IN_FILES_LINE"                : "line: {0}",

    "ERROR_FETCHING_UPDATE_INFO_TITLE"  : "Error getting update info",
    "ERROR_FETCHING_UPDATE_INFO_MSG"    : "There was a problem getting the latest update information from the server. Please make sure you are connected to the internet and try again.",

    // Switch language
    "LANGUAGE_TITLE"                    : "Switch Language",
    "LANGUAGE_MESSAGE"                  : "Please select the desired language from the list below:",
    "LANGUAGE_SUBMIT"                   : "Reload {APP_NAME}",
    "LANGUAGE_CANCEL"                   : "Cancel",

    /**
     * ProjectManager
     */

    "UNTITLED" : "Untitled",

    /**
     * Keyboard modifier names
     */

    "KEYBOARD_CTRL"   : "Ctrl",
    "KEYBOARD_SHIFT"  : "Shift",
    "KEYBOARD_SPACE"  : "Space",

    /**
     * StatusBar strings
     */
    "STATUSBAR_CURSOR_POSITION"             : "Line {0}, Column {1}",
    "STATUSBAR_INDENT_TOOLTIP_SPACES"       : "Click to switch indentation to spaces",
    "STATUSBAR_INDENT_TOOLTIP_TABS"         : "Click to switch indentation to tabs",
    "STATUSBAR_INDENT_SIZE_TOOLTIP_SPACES"  : "Click to change number of spaces used when indenting",
    "STATUSBAR_INDENT_SIZE_TOOLTIP_TABS"    : "Click to change tab character width",
    "STATUSBAR_SPACES"                      : "Spaces",
    "STATUSBAR_TAB_SIZE"                    : "Tab Size",
    "STATUSBAR_LINE_COUNT"                  : "{0} Lines",

    /**
     * Command Name Constants
     */

    // File menu commands
    "FILE_MENU"                           : "File",
    "CMD_FILE_NEW"                        : "New File",
    "CMD_FILE_NEW_FOLDER"                 : "New Folder",
    "CMD_FILE_OPEN"                       : "Open\u2026",
    "CMD_ADD_TO_WORKING_SET"              : "Add To Working Set",
    "CMD_OPEN_FOLDER"                     : "Open Folder\u2026",
    "CMD_FILE_CLOSE"                      : "Close",
    "CMD_FILE_CLOSE_ALL"                  : "Close All",
    "CMD_FILE_SAVE"                       : "Save",
    "CMD_FILE_SAVE_ALL"                   : "Save All",
    "CMD_LIVE_FILE_PREVIEW"               : "Live Preview",
    "CMD_LIVE_HIGHLIGHT"                  : "Live Highlight",
    "CMD_PROJECT_SETTINGS"                : "Project Settings\u2026",
    "CMD_FILE_RENAME"                     : "Rename",
    "CMD_QUIT"                            : "Quit",
    // Used in native File menu on Windows
    "CMD_EXIT"                            : "Exit",

    // Edit menu commands
    "EDIT_MENU"                           : "Edit",
    "CMD_UNDO"                            : "Undo",
    "CMD_REDO"                            : "Redo",
    "CMD_CUT"                             : "Cut",
    "CMD_COPY"                            : "Copy",
    "CMD_PASTE"                           : "Paste",
    "CMD_SELECT_ALL"                      : "Select All",
    "CMD_SELECT_LINE"                     : "Select Line",
    "CMD_FIND"                            : "Find",
    "CMD_FIND_IN_FILES"                   : "Find in Files",
    "CMD_FIND_IN_SUBTREE"                 : "Find in\u2026",
    "CMD_FIND_NEXT"                       : "Find Next",
    "CMD_FIND_PREVIOUS"                   : "Find Previous",
    "CMD_REPLACE"                         : "Replace",
    "CMD_INDENT"                          : "Indent",
    "CMD_UNINDENT"                        : "Unindent",
    "CMD_DUPLICATE"                       : "Duplicate",
    "CMD_DELETE_LINES"                    : "Delete Line",
    "CMD_COMMENT"                         : "Toggle Line Comment",
    "CMD_BLOCK_COMMENT"                   : "Toggle Block Comment",
    "CMD_LINE_UP"                         : "Move Line Up",
    "CMD_LINE_DOWN"                       : "Move Line Down",

    // View menu commands
    "VIEW_MENU"                           : "View",
    "CMD_HIDE_SIDEBAR"                    : "Hide Sidebar",
    "CMD_SHOW_SIDEBAR"                    : "Show Sidebar",
    "CMD_INCREASE_FONT_SIZE"              : "Increase Font Size",
    "CMD_DECREASE_FONT_SIZE"              : "Decrease Font Size",
    "CMD_RESTORE_FONT_SIZE"               : "Restore Font Size",
    "CMD_TOGGLE_CLOSE_BRACKETS"           : "Enable Close Brackets",
    "CMD_SORT_WORKINGSET_BY_ADDED"        : "Sort by Added",
    "CMD_SORT_WORKINGSET_BY_NAME"         : "Sort by Name",
    "CMD_SORT_WORKINGSET_BY_TYPE"         : "Sort by Type",
    "CMD_SORT_WORKINGSET_AUTO"            : "Automatic Sort",

    // Navigate menu Commands
    "NAVIGATE_MENU"                       : "Navigate",
    "CMD_QUICK_OPEN"                      : "Quick Open",
    "CMD_GOTO_LINE"                       : "Go to Line",
    "CMD_GOTO_DEFINITION"                 : "Go to Definition",
    "CMD_JSLINT_FIRST_ERROR"              : "Go to First JSLint Error",
    "CMD_TOGGLE_QUICK_EDIT"               : "Quick Edit",
    "CMD_QUICK_EDIT_PREV_MATCH"           : "Previous Match",
    "CMD_QUICK_EDIT_NEXT_MATCH"           : "Next Match",
    "CMD_NEXT_DOC"                        : "Next Document",
    "CMD_PREV_DOC"                        : "Previous Document",
    "CMD_SHOW_IN_TREE"                    : "Show in File Tree",

    // Debug menu commands
    "DEBUG_MENU"                          : "Debug",
    "CMD_REFRESH_WINDOW"                  : "Reload {APP_NAME}",
    "CMD_SHOW_DEV_TOOLS"                  : "Show Developer Tools",
    "CMD_RUN_UNIT_TESTS"                  : "Run Tests",
    "CMD_JSLINT"                          : "Enable JSLint",
    "CMD_SHOW_PERF_DATA"                  : "Show Performance Data",
    "CMD_NEW_BRACKETS_WINDOW"             : "New {APP_NAME} Window",
    "CMD_SHOW_EXTENSIONS_FOLDER"          : "Show Extensions Folder",
    "CMD_SWITCH_LANGUAGE"                 : "Switch Language",
    "CMD_ENABLE_NODE_DEBUGGER"            : "Enable Node Debugger",
    "CMD_LOG_NODE_STATE"                  : "Log Node State to Console",
    "CMD_RESTART_NODE"                    : "Restart Node",

    // Help menu commands
    "HELP_MENU"                           : "Help",
    "CMD_CHECK_FOR_UPDATE"                : "Check for Updates",
    "CMD_HOW_TO_USE_BRACKETS"             : "How to Use {APP_NAME}",
    "CMD_FORUM"                           : "{APP_NAME} Forum",
    "CMD_RELEASE_NOTES"                   : "Release Notes",
    "CMD_REPORT_AN_ISSUE"                 : "Report an Issue",
    "CMD_TWITTER"                         : "{TWITTER_NAME} on Twitter",
    "CMD_ABOUT"                           : "About {APP_TITLE}",

    // Special commands invoked by the native shell
    "CMD_CLOSE_WINDOW"                    : "Close Window",
    "CMD_ABORT_QUIT"                      : "Abort Quit",

    // Strings for main-view.html
    "EXPERIMENTAL_BUILD"                   : "experimental build",
    "DEVELOPMENT_BUILD"                    : "development build",
    "JSLINT_ERRORS"                        : "JSLint Errors",
    "JSLINT_ERROR_INFORMATION"             : "1 JSLint Error",
    "JSLINT_ERRORS_INFORMATION"            : "{0} JSLint Errors",
    "JSLINT_NO_ERRORS"                     : "No JSLint errors - good job!",
    "JSLINT_DISABLED"                      : "JSLint disabled or not working for the current file",
    "SEARCH_RESULTS"                       : "Search Results",
    "OK"                                   : "OK",
    "DONT_SAVE"                            : "Don't Save",
    "SAVE"                                 : "Save",
    "CANCEL"                               : "Cancel",
    "RELOAD_FROM_DISK"                     : "Reload from Disk",
    "KEEP_CHANGES_IN_EDITOR"               : "Keep Changes in Editor",
    "CLOSE_DONT_SAVE"                      : "Close (Don't Save)",
    "RELAUNCH_CHROME"                      : "Relaunch Chrome",
    "ABOUT"                                : "About",
    "APP_NAME"                             : "Brackets",
    "CLOSE"                                : "Close",
    "ABOUT_TEXT_LINE1"                     : "sprint {VERSION_MINOR} {BUILD_TYPE} {VERSION}",
    "ABOUT_TEXT_LINE3"                     : "Notices, terms and conditions pertaining to third party software are located at http://www.adobe.com/go/thirdparty/ and incorporated by reference herein.",
    "ABOUT_TEXT_LINE4"                     : "Documentation and source at https://github.com/adobe/brackets/",
    "ABOUT_TEXT_LINE5"                     : "Made with \u2764 and JavaScript by:",
    "ABOUT_TEXT_LINE6"                     : "Lots of people (but we're having trouble loading that data right now).",
    "UPDATE_NOTIFICATION_TOOLTIP"          : "There's a new build of {APP_NAME} available! Click here for details.",
    "UPDATE_AVAILABLE_TITLE"               : "Update Available",
    "UPDATE_MESSAGE"                       : "Hey, there's a new build of {APP_NAME} available. Here are some of the new features:",
    "GET_IT_NOW"                           : "Get it now!",
    "PROJECT_SETTINGS_TITLE"               : "Project Settings for: {0}",
    "PROJECT_SETTING_BASE_URL"             : "Live Preview Base URL",
    "PROJECT_SETTING_BASE_URL_HINT"        : "(to use a local server, specify url)",
    "BASEURL_ERROR_INVALID_PROTOCOL"       : "The {0} protocol isn't supported by Live Preview—please use http: or https: .",
    "BASEURL_ERROR_SEARCH_DISALLOWED"      : "The base URL can't contain search parameters like \"{0}\".",
    "BASEURL_ERROR_HASH_DISALLOWED"        : "The base URL can't contain hashes like \"{0}\".",
    "BASEURL_ERROR_INVALID_CHAR"           : "Special characters like '{0}' must be %-encoded.",
    "BASEURL_ERROR_UNKOWN_ERROR"           : "Unknown error parsing Base URL",

    // extensions/default/InlineColorEditor
    "COLOR_EDITOR_CURRENT_COLOR_SWATCH_TIP"     : "Current Color",
    "COLOR_EDITOR_ORIGINAL_COLOR_SWATCH_TIP"    : "Original Color",
    "COLOR_EDITOR_RGBA_BUTTON_TIP"              : "RGBa Format",
    "COLOR_EDITOR_HEX_BUTTON_TIP"               : "Hex Format",
    "COLOR_EDITOR_HSLA_BUTTON_TIP"              : "HSLa Format",
    "COLOR_EDITOR_USED_COLOR_TIP_SINGULAR"      : "{0} (Used {1} time)",
    "COLOR_EDITOR_USED_COLOR_TIP_PLURAL"        : "{0} (Used {1} times)"
});


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Slider - Range slider</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

	<link rel="stylesheet" href="../demos.css">

	Price range:
	<input type="text" id="amount" style="border:0; color:#f6931f; font-weight:bold;" />

Set the range option to true to capture a range of values with two drag handles.  The space between the handles is filled with a different background color to indicate those values are selected.


/* Albanian initialisation for the jQuery UI date picker plugin. */
/* Written by Flakron Bytyqi (flakron@gmail.com). */
jQuery(function($){
	$.datepicker.regional['sq'] = {
		closeText: 'mbylle',
		prevText: '<mbrapa',
		nextText: 'Përpara>',
		currentText: 'sot',
		monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor',
		'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'],
		monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer',
		'Kor','Gus','Sht','Tet','Nën','Dhj'],
		dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'],
		dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'],
		dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'],
		weekHeader: 'Ja',
		dateFormat: 'dd.mm.yy',
		firstDay: 1,
		isRTL: false,
		showMonthAfterYear: false,
		yearSuffix: ''};
	$.datepicker.setDefaults($.datepicker.regional['sq']);
});


(function( $ ) {

var setupTeardown = TestHelpers.accordion.setupTeardown,
	state = TestHelpers.accordion.state;

module( "accordion: core", setupTeardown() );

$.each( { div: "#list1", ul: "#navigation", dl: "#accordion-dl" }, function( type, selector ) {
	test( "markup structure: " + type, function() {
		expect( 4 );
		var element = $( selector ).accordion();
		ok( element.hasClass( "ui-accordion" ), "main element is .ui-accordion" );
		equal( element.find( ".ui-accordion-header" ).length, 3,
			".ui-accordion-header elements exist, correct number" );
		equal( element.find( ".ui-accordion-content" ).length, 3,
			".ui-accordion-content elements exist, correct number" );
		deepEqual( element.find( ".ui-accordion-header" ).next().get(),
			element.find( ".ui-accordion-content" ).get(),
			"content panels come immediately after headers" );
	});
});

test( "handle click on header-descendant", function() {
	expect( 1 );
	var element = $( "#navigation" ).accordion();
	$( "#navigation h2:eq(1) a" ).click();
	state( element, 0, 1, 0 );
});

test( "accessibility", function () {
	expect( 37 );
	var element = $( "#list1" ).accordion({
			active: 1
		}),
		headers = element.find( ".ui-accordion-header" );

	equal( element.attr( "role" ), "tablist", "element role" );
	headers.each(function( i ) {
		var header = headers.eq( i ),
			panel = header.next();
		equal( header.attr( "role" ), "tab", "header " + i + " role" );
		equal( header.attr( "aria-controls" ), panel.attr( "id" ), "header " + i + " aria-controls" );
		equal( panel.attr( "role" ), "tabpanel", "panel " + i + " role" );
		equal( panel.attr( "aria-labelledby" ), header.attr( "id" ), "panel " + i + " aria-labelledby" );
	});

	equal( headers.eq( 1 ).attr( "tabindex" ), 0, "active header has tabindex=0" );
	equal( headers.eq( 1 ).attr( "aria-selected" ), "true", "active tab has aria-selected=true" );
	equal( headers.eq( 1 ).next().attr( "aria-expanded" ), "true", "active tabpanel has aria-expanded=true" );
	equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "false", "active tabpanel has aria-hidden=false" );
	equal( headers.eq( 0 ).attr( "tabindex" ), -1, "inactive header has tabindex=-1" );
	equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab has aria-selected=false" );
	equal( headers.eq( 0 ).next().attr( "aria-expanded" ), "false", "inactive tabpanel has aria-expanded=false" );
	equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel has aria-hidden=true" );
	equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header has tabindex=-1" );
	equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab has aria-selected=false" );
	equal( headers.eq( 2 ).next().attr( "aria-expanded" ), "false", "inactive tabpanel has aria-expanded=false" );
	equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel has aria-hidden=true" );

	element.accordion( "option", "active", 0 );
	equal( headers.eq( 0 ).attr( "tabindex" ), 0, "active header has tabindex=0" );
	equal( headers.eq( 0 ).attr( "aria-selected" ), "true", "active tab has aria-selected=true" );
	equal( headers.eq( 0 ).next().attr( "aria-expanded" ), "true", "active tabpanel has aria-expanded=true" );
	equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "false", "active tabpanel has aria-hidden=false" );
	equal( headers.eq( 1 ).attr( "tabindex" ), -1, "inactive header has tabindex=-1" );
	equal( headers.eq( 1 ).attr( "aria-selected" ), "false", "inactive tab has aria-selected=false" );
	equal( headers.eq( 1 ).next().attr( "aria-expanded" ), "false", "inactive tabpanel has aria-expanded=false" );
	equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel has aria-hidden=true" );
	equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header has tabindex=-1" );
	equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab has aria-selected=false" );
	equal( headers.eq( 2 ).next().attr( "aria-expanded" ), "false", "inactive tabpanel has aria-expanded=false" );
	equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel has aria-hidden=true" );
});

asyncTest( "keyboard support", function() {
	expect( 13 );
	var element = $( "#list1" ).accordion(),
		headers = element.find( ".ui-accordion-header" ),
		anchor = headers.eq( 1 ).next().find( "a" ).eq( 0 ),
		keyCode = $.ui.keyCode;
	equal( headers.filter( ".ui-state-focus" ).length, 0, "no headers focused on init" );
	headers.eq( 0 ).simulate( "focus" );
	setTimeout(function() {
		ok( headers.eq( 0 ).is( ".ui-state-focus" ), "first header has focus" );
		headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.DOWN } );
		ok( headers.eq( 1 ).is( ".ui-state-focus" ), "DOWN moves focus to next header" );
		headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.RIGHT } );
		ok( headers.eq( 2 ).is( ".ui-state-focus" ), "RIGHT moves focus to next header" );
		headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.DOWN } );
		ok( headers.eq( 0 ).is( ".ui-state-focus" ), "DOWN wraps focus to first header" );

		headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.UP } );
		ok( headers.eq( 2 ).is( ".ui-state-focus" ), "UP wraps focus to last header" );
		headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.LEFT } );
		ok( headers.eq( 1 ).is( ".ui-state-focus" ), "LEFT moves focus to previous header" );

		headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.HOME } );
		ok( headers.eq( 0 ).is( ".ui-state-focus" ), "HOME moves focus to first header" );
		headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.END } );
		ok( headers.eq( 2 ).is( ".ui-state-focus" ), "END moves focus to last header" );

		headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.ENTER } );
		equal( element.accordion( "option", "active" ) , 2, "ENTER activates panel" );
		headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.SPACE } );
		equal( element.accordion( "option", "active" ), 1, "SPACE activates panel" );

		anchor.simulate( "focus" );
		setTimeout(function() {
			ok( !headers.eq( 1 ).is( ".ui-state-focus" ), "header loses focus when focusing inside the panel" );
			anchor.simulate( "keydown", { keyCode: keyCode.UP, ctrlKey: true } );
			ok( headers.eq( 1 ).is( ".ui-state-focus" ), "CTRL+UP moves focus to header" );
			start();
		}, 1 );
	}, 1 );
});

}( jQuery ) );


"CMD_INCREASE_FONT_SIZE"              : "Increase Font Size",

"CMD_DECREASE_FONT_SIZE"              : "Decrease Font Size",

"CMD_RESTORE_FONT_SIZE"               : "Restore Font Size",

"CMD_TOGGLE_CLOSE_BRACKETS"           : "Enable Close Brackets",

"CMD_SORT_WORKINGSET_BY_ADDED"        : "Sort by Added",

"CMD_SORT_WORKINGSET_BY_NAME"         : "Sort by Name",

"CMD_SORT_WORKINGSET_BY_TYPE"         : "Sort by Type",

"CMD_SORT_WORKINGSET_AUTO"            : "Automatic Sort",

keep keep keep keep keep replace keep keep keep keep keep


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Datepicker - Display month & year menus</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

	<link rel="stylesheet" href="../demos.css">

Date: <input type="text" id="datepicker">

Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes.  Add the boolean changeMonth and changeYear options.


TestHelpers.commonWidgetTests( "droppable", {
	defaults: {
		accept: "*",
		activeClass: false,
		addClasses: true,
		disabled: false,
		greedy: false,
		hoverClass: false,
		scope: "default",
		tolerance: "intersect"
	}
});


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Droppable - Revert draggable position</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

	<link rel="stylesheet" href="../demos.css">

I revert when I'm dropped

I revert when I'm not dropped

Drop me here

Return the draggable (or it's helper) to its original location when dragging stops with the boolean revert option set on the draggable.


var GetTileAtWorldXY = function (worldX, worldY, nonNull, camera, layer)

layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera);

return GetTileAt(tileX, tileY, nonNull, layer);

keep keep keep keep replace replace replace replace keep keep keep

return GetTileAt(point.x, point.y, nonNull, layer);

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Tile = require('../Tile');
var IsInLayerBounds = require('./IsInLayerBounds');
var CalculateFacesAt = require('./CalculateFacesAt');
var SetTileCollision = require('./SetTileCollision');

/**
 * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index
 * or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified
 * location. If you pass in an index, only the index at the specified location will be changed.
 * Collision information will be recalculated at the specified location.
 *
 * @function Phaser.Tilemaps.Components.PutTileAt
 * @since 3.0.0
 *
 * @param {(integer|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object.
 * @param {integer} tileX - The x coordinate, in tiles, not pixels.
 * @param {integer} tileY - The y coordinate, in tiles, not pixels.
 * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
 * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon.
 *
 * @return {Phaser.Tilemaps.Tile} The Tile object that was created or added to this map.
 */
var PutTileAt = function (tile, tileX, tileY, recalculateFaces, layer)
{
    if (!IsInLayerBounds(tileX, tileY, layer)) { return null; }
    if (recalculateFaces === undefined) { recalculateFaces = true; }

    var oldTile = layer.data[tileY][tileX];
    var oldTileCollides = oldTile && oldTile.collides;

    if (tile instanceof Tile)
    {
        if (layer.data[tileY][tileX] === null)
        {
            layer.data[tileY][tileX] = new Tile(layer, tile.index, tileX, tileY, layer.tileWidth, layer.tileHeight);
        }

        layer.data[tileY][tileX].copy(tile);
    }
    else
    {
        var index = tile;

        if (layer.data[tileY][tileX] === null)
        {
            layer.data[tileY][tileX] = new Tile(layer, index, tileX, tileY, layer.tileWidth, layer.tileHeight);
        }
        else
        {
            layer.data[tileY][tileX].index = index;
        }
    }

    // Updating colliding flag on the new tile
    var newTile = layer.data[tileY][tileX];
    var collides = layer.collideIndexes.indexOf(newTile.index) !== -1;

    SetTileCollision(newTile, collides);

    // Recalculate faces only if the colliding flag at (tileX, tileY) has changed
    if (recalculateFaces && (oldTileCollides !== newTile.collides))
    {
        CalculateFacesAt(tileX, tileY, layer);
    }

    return newTile;
};

module.exports = PutTileAt;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Box3 = require('../math/Box3');
var BufferAttribute = require('./BufferAttribute');
var Class = require('../../utils/Class');
var Sphere = require('../math/Sphere');

var geometryId = 1;

var Geometry = new Class({

    initialize:

    function Geometry ()
    {
        this.id = geometryId++;

        /**
         * This hashmap has an id the name of the attribute to be set and as value the buffer to set it to.
         * Rather than accessing this property directly, use `addAttribute` and `getAttribute` to access attributes of this geometry.
         */
        this.attributes = {};

        /**
         * Hashmap of Attributes Array for morph targets.
         */
        this.morphAttributes = {};

        /**
         * Allows for vertices to be re-used across multiple triangles; this is called using "indexed triangles" and each triangle is associated with the indices of three vertices.
         * This attribute therefore stores the index of each vertex for each triangular face.
         * If this attribute is not set, the renderer assumes that each three contiguous positions represent a single triangle.
         * @type {BufferAttribute}
         */
        this.index = null;

        /**
         * Bounding box for the bufferGeometry, which can be calculated with `computeBoundingBox`.
         * @type {Box3}
         */
        this.boundingBox = new Box3();

        /**
         * Bounding sphere for the bufferGeometry, which can be calculated with `computeBoundingSphere`.
         * @type {Sphere}
         */
        this.boundingSphere = new Sphere();

        /**
         * Split the geometry into groups, each of which will be rendered in a separate WebGL draw call. This allows an array of materials to be used with the geometry.
         * Each group is an object of the form:
         * { start: Integer, count: Integer, materialIndex: Integer }
         */
        this.groups = [];

        /**
         * A version number, incremented every time the attribute object or index object changes to mark VAO drity.
         */
        this.version = 0;

        this.sceneProperties = {
            created: false,
            attributes: {},
            vaos: {}
        };
    },

    /**
     * Adds an attribute to this geometry.
     * Use this rather than the attributes property.
     * @param {string} name
     * @param {BufferAttribute|InterleavedBufferAttribute} attribute
     */
    addAttribute: function (name, attribute)
    {
        this.attributes[name] = attribute;
    },

    /**
     * Returns the attribute with the specified name.
     * @return {BufferAttribute|InterleavedBufferAttribute}
     */
    getAttribute: function (name)
    {
        return this.attributes[name];
    },

    /**
     * Removes the attribute with the specified name.
     */
    removeAttribute: function (name)
    {
        delete this.attributes[name];
    },

    /**
     * Set the index buffer.
     * @param {Array|BufferAttribute} index
     */
    setIndex: function (index)
    {
        if (Array.isArray(index))
        {
            this.index = new BufferAttribute(new Uint16Array(index), 1);
        }
        else
        {
            this.index = index;
        }
    },

    /**
     * Adds a group to this geometry; see the groups for details.
     * @param {number} start
     * @param {number} count
     * @param {number} materialIndex
     */
    addGroup: function (start, count, materialIndex)
    {
        this.groups.push({
            start: start,
            count: count,
            materialIndex: materialIndex !== undefined ? materialIndex : 0
        });
    },

    /**
     * Clears all groups.
     */
    clearGroups: function ()
    {
        this.groups = [];
    },

    /**
     * Computes bounding box of the geometry, updating `boundingBox`.
     * Bounding boxes aren't computed by default. They need to be explicitly computed.
     */
    computeBoundingBox: function ()
    {
        var position = this.attributes['a_Position'] || this.attributes['position'];

        if (position.isInterleavedBufferAttribute)
        {
            var data = position.data;

            this.boundingBox.setFromArray(data.array, data.stride);
        }
        else
        {
            this.boundingBox.setFromArray(position.array, position.size);
        }
    },

    /**
     * Computes bounding sphere of the geometry, updating `boundingSphere`.
     *
     * Bounding spheres aren't computed by default. They need to be explicitly computed.
     */
    computeBoundingSphere: function ()
    {
        var position = this.attributes['a_Position'] || this.attributes['position'];

        if (position.isInterleavedBufferAttribute)
        {
            var data = position.data;

            this.boundingSphere.setFromArray(data.array, data.stride);
        }
        else
        {
            this.boundingSphere.setFromArray(position.array, position.size);
        }
    },

    /**
     * Disposes the object from memory.
     * You need to call this when you want the BufferGeometry removed while the application is running.
     */
    dispose: function ()
    {
        //  TODO
    }

});

module.exports = Geometry;


/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2020 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License}
*/

var BasePlugin = require('./BasePlugin');
var Class = require('../utils/Class');
var SceneEvents = require('../scene/events');

/**
 * @classdesc
 * A Scene Level Plugin is installed into every Scene and belongs to that Scene.
 * It can listen for Scene events and respond to them.
 * It can map itself to a Scene property, or into the Scene Systems, or both.
 *
 * @class ScenePlugin
 * @memberof Phaser.Plugins
 * @extends Phaser.Plugins.BasePlugin
 * @constructor
 * @since 3.8.0
 *
 * @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin.
 * @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Plugin Manager.
 */
var ScenePlugin = new Class({

    Extends: BasePlugin,

    initialize:

    function ScenePlugin (scene, pluginManager)
    {
        BasePlugin.call(this, pluginManager);

        /**
         * A reference to the Scene that has installed this plugin.
         * Only set if it's a Scene Plugin, otherwise `null`.
         * This property is only set when the plugin is instantiated and added to the Scene, not before.
         * You can use it during the `boot` method.
         *
         * @name Phaser.Plugins.ScenePlugin#scene
         * @type {?Phaser.Scene}
         * @protected
         * @since 3.8.0
         */
        this.scene = scene;

        /**
         * A reference to the Scene Systems of the Scene that has installed this plugin.
         * Only set if it's a Scene Plugin, otherwise `null`.
         * This property is only set when the plugin is instantiated and added to the Scene, not before.
         * You can use it during the `boot` method.
         *
         * @name Phaser.Plugins.ScenePlugin#systems
         * @type {?Phaser.Scenes.Systems}
         * @protected
         * @since 3.8.0
         */
        this.systems = scene.sys;

        scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
    },

    /**
     * This method is called when the Scene boots. It is only ever called once.
     *
     * By this point the plugin properties `scene` and `systems` will have already been set.
     *
     * In here you can listen for {@link Phaser.Scenes.Events Scene events} and set-up whatever you need for this plugin to run.
     * Here are the Scene events you can listen to:
     *
     * - start
     * - ready
     * - preupdate
     * - update
     * - postupdate
     * - resize
     * - pause
     * - resume
     * - sleep
     * - wake
     * - transitioninit
     * - transitionstart
     * - transitioncomplete
     * - transitionout
     * - shutdown
     * - destroy
     *
     * At the very least you should offer a destroy handler for when the Scene closes down, i.e:
     *
     * ```javascript
     * var eventEmitter = this.systems.events;
     * eventEmitter.once('destroy', this.sceneDestroy, this);
     * ```
     *
     * @method Phaser.Plugins.ScenePlugin#boot
     * @since 3.8.0
     */
    boot: function ()
    {
    },

    /**
     * Game instance has been destroyed.
     *
     * You must release everything in here, all references, all objects, free it all up.
     *
     * @method Phaser.Plugins.ScenePlugin#destroy
     * @since 3.8.0
     */
    destroy: function ()
    {
        this.pluginManager = null;
        this.game = null;
        this.scene = null;
        this.systems = null;
    }

});

module.exports = ScenePlugin;


module.exports = [
    '#define SHADER_NAME PHASER_SINGLE_VS',
    '',
    'precision mediump float;',
    '',
    'uniform mat4 uProjectionMatrix;',
    'uniform mat4 uViewMatrix;',
    'uniform mat4 uModelMatrix;',
    '',
    'attribute vec2 inPosition;',
    'attribute vec2 inTexCoord;',
    'attribute float inTintEffect;',
    'attribute vec4 inTint;',
    '',
    'varying vec2 outTexCoord;',
    'varying float outTintEffect;',
    'varying vec4 outTint;',
    '',
    'void main ()',
    '{',
    '    gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(inPosition, 1.0, 1.0);',
    '',
    '    outTexCoord = inTexCoord;',
    '    outTint = inTint;',
    '    outTintEffect = inTintEffect;',
    '}',
    ''
].join('\n');


* @return {Phaser.Tilemaps.Tile} The Tile object that was created or added to this map.

var PutTileAt = function (tile, tileX, tileY, recalculateFaces, layer)

if (!IsInLayerBounds(tileX, tileY, layer)) { return null; }

if (recalculateFaces === undefined) { recalculateFaces = true; }

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var GetTileAt = require('./GetTileAt');
var Vector2 = require('../../math/Vector2');

var point = new Vector2();

/**
 * Gets a tile at the given world coordinates from the given layer.
 *
 * @function Phaser.Tilemaps.Components.GetTileAtWorldXY
 * @since 3.0.0
 *
 * @param {number} worldX - X position to get the tile from (given in pixels)
 * @param {number} worldY - Y position to get the tile from (given in pixels)
 * @param {boolean} [nonNull=false] - If true, function won't return null for empty tiles, but a Tile object with an index of -1.
 * @param {Phaser.Cameras.Scene2D.Camera} [camera=main camera] - The Camera to use when calculating the tile index from the world values.
 * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon.
 *
 * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates
 * were invalid.
 */
var GetTileAtWorldXY = function (worldX, worldY, nonNull, camera, layer)
{
    layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera);

    var tileX = point.x;
    var tileY = point.y;

    return GetTileAt(tileX, tileY, nonNull, layer);
};

module.exports = GetTileAtWorldXY;


/**
 * @typedef {object} Phaser.Types.Loader.FileTypes.SpriteSheetFileConfig
 *
 * @property {string} key - The key of the file. Must be unique within both the Loader and the Texture Manager.
 * @property {string} [url] - The absolute or relative URL to load the file from.
 * @property {string} [extension='png'] - The default file extension to use if no url is provided.
 * @property {string} [normalMap] - The filename of an associated normal map. It uses the same path and url to load as the image.
 * @property {Phaser.Types.Loader.FileTypes.ImageFrameConfig} [frameConfig] - The frame configuration object.
 * @property {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
 */


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Plugins
 */

module.exports = {

    BasePlugin: require('./BasePlugin'),
    DefaultPlugins: require('./DefaultPlugins'),
    PluginCache: require('./PluginCache'),
    PluginManager: require('./PluginManager'),
    ScenePlugin: require('./ScenePlugin')

};


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Contains = require('./Contains');

/**
 * Determines whether the specified point is contained within the rectangular region defined by this Rectangle object.
 *
 * @function Phaser.Geom.Rectangle.ContainsPoint
 * @since 3.0.0
 *
 * @param {Phaser.Geom.Rectangle} rect - The Rectangle object.
 * @param {Phaser.Geom.Point} point - The point object to be checked. Can be a Phaser Point object or any object with x and y values.
 *
 * @return {boolean} A value of true if the Rectangle object contains the specified point, otherwise false.
 */
var ContainsPoint = function (rect, point)
{
    return Contains(rect, point.x, point.y);
};

module.exports = ContainsPoint;


var oldTileCollides = oldTile && oldTile.collides;

if (!IsInLayerBounds(tileX, tileY, layer))


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Sound Stop Event.
 *
 * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are stopped.
 *
 * Listen to it from a Sound instance using `Sound.on('stop', listener)`, i.e.:
 *
 * ```javascript
 * var music = this.sound.add('key');
 * music.on('stop', listener);
 * music.play();
 * music.stop();
 * ```
 *
 * @event Phaser.Sound.Events#STOP
 * @since 3.0.0
 *
 * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event.
 */
module.exports = 'stop';


module.exports = [
    '#ifdef USE_AMBIENT_LIGHT',
    '    #include <ambientlight_pars_frag>',
    '#endif',
    '#if NUM_DIR_LIGHTS > 0',
    '    #include <directlight_pars_frag>',
    '#endif',
    '#if NUM_POINT_LIGHTS > 0',
    '    #include <pointlight_pars_frag>',
    '#endif',
    '#if NUM_SPOT_LIGHTS > 0',
    '    #include <spotlight_pars_frag>',
    '#endif',
    '',
    '#if defined(USE_PBR) && defined(USE_ENV_MAP)',
    '',
    '    vec3 getLightProbeIndirectIrradiance(const in int maxMIPLevel, const in vec3 envDir) {',
    '        // TODO: replace with properly filtered cubemaps and access the irradiance LOD level, be it the last LOD level',
    '    	// of a specular cubemap, or just the default level of a specially created irradiance cubemap.',
    '',
    '    	#ifdef TEXTURE_LOD_EXT',
    '',
    '    		vec4 envMapColor = textureCubeLodEXT( envMap, envDir, float( maxMIPLevel ) );',
    '',
    '    	#else',
    '',
    '    		// force the bias high to get the last LOD level as it is the most blurred.',
    '    		vec4 envMapColor = textureCube( envMap, envDir, float( maxMIPLevel ) );',
    '',
    '    	#endif',
    '',
    '        envMapColor = envMapTexelToLinear( envMapColor );',
    '',
    '        return PI * envMapColor.rgb * u_EnvMap_Intensity;',
    '    }',
    '',
    '    // taken from here: http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html',
    '    float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {',
    '',
    '    	//float envMapWidth = pow( 2.0, maxMIPLevelScalar );',
    '    	//float desiredMIPLevel = log2( envMapWidth * sqrt( 3.0 ) ) - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );',
    '',
    '    	float maxMIPLevelScalar = float( maxMIPLevel );',
    '    	float desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );',
    '',
    '    	// clamp to allowable LOD ranges.',
    '    	return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );',
    '',
    '    }',
    '',
    '    vec3 getLightProbeIndirectRadiance(const in float blinnShininessExponent, const in int maxMIPLevel, const in vec3 envDir) {',
    '        float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );',
    '',
    '        #ifdef TEXTURE_LOD_EXT',
    '',
    '    		vec4 envMapColor = textureCubeLodEXT( envMap, envDir, specularMIPLevel );',
    '',
    '    	#else',
    '',
    '    		vec4 envMapColor = textureCube( envMap, envDir, specularMIPLevel );',
    '',
    '    	#endif',
    '',
    '        envMapColor = envMapTexelToLinear( envMapColor );',
    '',
    '        return envMapColor.rgb * u_EnvMap_Intensity;',
    '    }',
    '',
    '    // ref: https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf',
    '    float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {',
    '',
    '    	return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );',
    '',
    '    }',
    '',
    '#endif'
].join('\n');


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var PropertyValueSet = require('./PropertyValueSet');

/**
 * Takes an array of Game Objects, or any objects that have the public property `scaleX`
 * and then sets it to the given value.
 *
 * The optional `step` property is applied incrementally, multiplied by each item in the array.
 *
 * To use this with a Group: `SetScaleX(group.getChildren(), value, step)`
 *
 * @function Phaser.Actions.SetScaleX
 * @since 3.0.0
 *
 * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return]
 *
 * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action.
 * @param {number} value - The amount to set the property to.
 * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
 * @param {integer} [index=0] - An optional offset to start searching from within the items array.
 * @param {integer} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning.
 *
 * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action.
 */
var SetScaleX = function (items, value, step, index, direction)
{
    return PropertyValueSet(items, 'scaleX', value, step, index, direction);
};

module.exports = SetScaleX;


* Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either

var Vector2 = require('../../math/Vector2');

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CalculateFacesWithin = require('./CalculateFacesWithin');
var PutTileAt = require('./PutTileAt');

/**
 * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified
 * layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile,
 * all attributes will be copied over to the specified location. If you pass in an index, only the
 * index at the specified location will be changed. Collision information will be recalculated
 * within the region tiles were changed.
 *
 * @function Phaser.Tilemaps.Components.PutTilesAt
 * @since 3.0.0
 *
 * @param {(integer[]|integer[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place.
 * @param {integer} tileX - The x coordinate, in tiles, not pixels.
 * @param {integer} tileY - The y coordinate, in tiles, not pixels.
 * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
 * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon.
 *
 */
var PutTilesAt = function (tilesArray, tileX, tileY, recalculateFaces, layer)
{
    if (!Array.isArray(tilesArray)) { return null; }
    if (recalculateFaces === undefined) { recalculateFaces = true; }

    // Force the input array to be a 2D array
    if (!Array.isArray(tilesArray[0]))
    {
        tilesArray = [ tilesArray ];
    }

    var height = tilesArray.length;
    var width = tilesArray[0].length;

    for (var ty = 0; ty < height; ty++)
    {
        for (var tx = 0; tx < width; tx++)
        {
            var tile = tilesArray[ty][tx];

            PutTileAt(tile, tileX + tx, tileY + ty, false, layer);
        }
    }

    if (recalculateFaces)
    {
        // Recalculate the faces within the destination area and neighboring tiles
        CalculateFacesWithin(tileX - 1, tileY - 1, width + 2, height + 2, layer);
    }
};

module.exports = PutTilesAt;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Impact Bounce component.
 * Should be applied as a mixin.
 *
 * @namespace Phaser.Physics.Impact.Components.Bounce
 * @since 3.0.0
 */
var Bounce = {

    /**
     * Sets the impact physics bounce, or restitution, value.
     *
     * @method Phaser.Physics.Impact.Components.Bounce#setBounce
     * @since 3.0.0
     *
     * @param {number} value - A value between 0 (no rebound) and 1 (full rebound)
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setBounce: function (value)
    {
        this.body.bounciness = value;

        return this;
    },

    /**
     * Sets the minimum velocity the body is allowed to be moving to be considered for rebound.
     *
     * @method Phaser.Physics.Impact.Components.Bounce#setMinBounceVelocity
     * @since 3.0.0
     *
     * @param {number} value - The minimum allowed velocity.
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setMinBounceVelocity: function (value)
    {
        this.body.minBounceVelocity = value;

        return this;
    },

    /**
     * The bounce, or restitution, value of this body.
     * A value between 0 (no rebound) and 1 (full rebound)
     *
     * @name Phaser.Physics.Impact.Components.Bounce#bounce
     * @type {number}
     * @since 3.0.0
     */
    bounce: {

        get: function ()
        {
            return this.body.bounciness;
        },

        set: function (value)
        {
            this.body.bounciness = value;
        }

    }

};

module.exports = Bounce;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var AudioFile = require('./AudioFile.js');
var Class = require('../../utils/Class');
var FileTypesManager = require('../FileTypesManager');
var GetFastValue = require('../../utils/object/GetFastValue');
var IsPlainObject = require('../../utils/object/IsPlainObject');
var JSONFile = require('./JSONFile.js');
var MultiFile = require('../MultiFile.js');

/**
 * @classdesc
 * An Audio Sprite File suitable for loading by the Loader.
 *
 * These are created when you use the Phaser.Loader.LoaderPlugin#audioSprite method and are not typically created directly.
 *
 * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audioSprite.
 *
 * @class AudioSpriteFile
 * @extends Phaser.Loader.MultiFile
 * @memberof Phaser.Loader.FileTypes
 * @constructor
 * @since 3.7.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
 * @param {(string|Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig)} key - The key to use for this file, or a file configuration object.
 * @param {string} jsonURL - The absolute or relative URL to load the json file from. Or a well formed JSON object to use instead.
 * @param {{(string|string[])}} [audioURL] - The absolute or relative URL to load the audio file from. If empty it will be obtained by parsing the JSON file.
 * @param {any} [audioConfig] - The audio configuration options.
 * @param {Phaser.Types.Loader.XHRSettingsObject} [audioXhrSettings] - An XHR Settings configuration object for the audio file. Used in replacement of the Loaders default XHR Settings.
 * @param {Phaser.Types.Loader.XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings.
 */
var AudioSpriteFile = new Class({

    Extends: MultiFile,

    initialize:

    function AudioSpriteFile (loader, key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings)
    {
        if (IsPlainObject(key))
        {
            var config = key;

            key = GetFastValue(config, 'key');
            jsonURL = GetFastValue(config, 'jsonURL');
            audioURL = GetFastValue(config, 'audioURL');
            audioConfig = GetFastValue(config, 'audioConfig');
            audioXhrSettings = GetFastValue(config, 'audioXhrSettings');
            jsonXhrSettings = GetFastValue(config, 'jsonXhrSettings');
        }

        var data;

        //  No url? then we're going to do a json load and parse it from that
        if (!audioURL)
        {
            data = new JSONFile(loader, key, jsonURL, jsonXhrSettings);

            MultiFile.call(this, loader, 'audiosprite', key, [ data ]);

            this.config.resourceLoad = true;
            this.config.audioConfig = audioConfig;
            this.config.audioXhrSettings = audioXhrSettings;
        }
        else
        {
            var audio = AudioFile.create(loader, key, audioURL, audioConfig, audioXhrSettings);

            if (audio)
            {
                data = new JSONFile(loader, key, jsonURL, jsonXhrSettings);

                MultiFile.call(this, loader, 'audiosprite', key, [ audio, data ]);

                this.config.resourceLoad = false;
            }
        }
    },

    /**
     * Called by each File when it finishes loading.
     *
     * @method Phaser.Loader.FileTypes.AudioSpriteFile#onFileComplete
     * @since 3.7.0
     *
     * @param {Phaser.Loader.File} file - The File that has completed processing.
     */
    onFileComplete: function (file)
    {
        var index = this.files.indexOf(file);

        if (index !== -1)
        {
            this.pending--;

            if (this.config.resourceLoad && file.type === 'json' && file.data.hasOwnProperty('resources'))
            {
                //  Inspect the data for the files to now load
                var urls = file.data.resources;

                var audioConfig = GetFastValue(this.config, 'audioConfig');
                var audioXhrSettings = GetFastValue(this.config, 'audioXhrSettings');

                var audio = AudioFile.create(this.loader, file.key, urls, audioConfig, audioXhrSettings);

                if (audio)
                {
                    this.addToMultiFile(audio);

                    this.loader.addFile(audio);
                }
            }
        }
    },

    /**
     * Adds this file to its target cache upon successful loading and processing.
     *
     * @method Phaser.Loader.FileTypes.AudioSpriteFile#addToCache
     * @since 3.7.0
     */
    addToCache: function ()
    {
        if (this.isReadyToProcess())
        {
            var fileA = this.files[0];
            var fileB = this.files[1];

            fileA.addToCache();
            fileB.addToCache();

            this.complete = true;
        }
    }

});

/**
 * Adds a JSON based Audio Sprite, or array of audio sprites, to the current load queue.
 *
 * You can call this method from within your Scene's `preload`, along with any other files you wish to load:
 *
 * ```javascript
 * function preload ()
 * {
 *     this.load.audioSprite('kyobi', 'kyobi.json', [
 *         'kyobi.ogg',
 *         'kyobi.mp3',
 *         'kyobi.m4a'
 *     ]);
 * }
 * ```
 *
 * Audio Sprites are a combination of audio files and a JSON configuration.
 * The JSON follows the format of that created by https://github.com/tonistiigi/audiosprite
 *
 * If the JSON file includes a 'resource' object then you can let Phaser parse it and load the audio
 * files automatically based on its content. To do this exclude the audio URLs from the load:
 *
 * ```javascript
 * function preload ()
 * {
 *     this.load.audioSprite('kyobi', 'kyobi.json');
 * }
 * ```
 *
 * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
 * or if it's already running, when the next free load slot becomes available. This happens automatically if you
 * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
 * it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
 * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
 * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
 * loaded.
 *
 * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring
 * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details.
 *
 * The key must be a unique String. It is used to add the file to the global Audio Cache upon a successful load.
 * The key should be unique both in terms of files being loaded and files already present in the Audio Cache.
 * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
 * then remove it from the Audio Cache first, before loading a new one.
 *
 * Instead of passing arguments you can pass a configuration object, such as:
 *
 * ```javascript
 * this.load.audioSprite({
 *     key: 'kyobi',
 *     jsonURL: 'audio/Kyobi.json',
 *     audioURL: [
 *         'audio/Kyobi.ogg',
 *         'audio/Kyobi.mp3',
 *         'audio/Kyobi.m4a'
 *     ]
 * });
 * ```
 *
 * See the documentation for `Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig` for more details.
 *
 * Instead of passing a URL for the audio JSON data you can also pass in a well formed JSON object instead.
 *
 * Once the audio has finished loading you can use it create an Audio Sprite by referencing its key:
 *
 * ```javascript
 * this.load.audioSprite('kyobi', 'kyobi.json');
 * // and later in your game ...
 * var music = this.sound.addAudioSprite('kyobi');
 * music.play('title');
 * ```
 *
 * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
 * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and
 * this is what you would use to retrieve the image from the Texture Manager.
 *
 * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
 *
 * Due to different browsers supporting different audio file types you should usually provide your audio files in a variety of formats.
 * ogg, mp3 and m4a are the most common. If you provide an array of URLs then the Loader will determine which _one_ file to load based on
 * browser support.
 *
 * If audio has been disabled in your game, either via the game config, or lack of support from the device, then no audio will be loaded.
 *
 * Note: The ability to load this type of file will only be available if the Audio Sprite File type has been built into Phaser.
 * It is available in the default build but can be excluded from custom builds.
 *
 * @method Phaser.Loader.LoaderPlugin#audioSprite
 * @fires Phaser.Loader.LoaderPlugin#ADD
 * @since 3.0.0
 *
 * @param {(string|Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig|Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig[])} key - The key to use for this file, or a file configuration object, or an array of objects.
 * @param {string} jsonURL - The absolute or relative URL to load the json file from. Or a well formed JSON object to use instead.
 * @param {(string|string[])} [audioURL] - The absolute or relative URL to load the audio file from. If empty it will be obtained by parsing the JSON file.
 * @param {any} [audioConfig] - The audio configuration options.
 * @param {Phaser.Types.Loader.XHRSettingsObject} [audioXhrSettings] - An XHR Settings configuration object for the audio file. Used in replacement of the Loaders default XHR Settings.
 * @param {Phaser.Types.Loader.XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings.
 *
 * @return {this} The Loader.
 */
FileTypesManager.register('audioSprite', function (key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings)
{
    var game = this.systems.game;
    var gameAudioConfig = game.config.audio;
    var deviceAudio = game.device.audio;

    if ((gameAudioConfig && gameAudioConfig.noAudio) || (!deviceAudio.webAudio && !deviceAudio.audioData))
    {
        //  Sounds are disabled, so skip loading audio
        return this;
    }

    var multifile;

    //  Supports an Object file definition in the key argument
    //  Or an array of objects in the key argument
    //  Or a single entry where all arguments have been defined

    if (Array.isArray(key))
    {
        for (var i = 0; i < key.length; i++)
        {
            multifile = new AudioSpriteFile(this, key[i]);

            if (multifile.files)
            {
                this.addFile(multifile.files);
            }
        }
    }
    else
    {
        multifile = new AudioSpriteFile(this, key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings);

        if (multifile.files)
        {
            this.addFile(multifile.files);
        }
    }

    return this;
});


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../../utils/Class');
var CONST = require('../const');
var Material = require('./Material');

var LineMaterial = new Class({

    Extends: Material,

    initialize:

    function LineMaterial ()
    {
        Material.call(this);

        this.type = CONST.MATERIAL_TYPE.LINE;

        this.lineWidth = 1;
        this.drawMode = CONST.DRAW_MODE.LINES;
    }

});

module.exports = LineMaterial;


* @param {number} worldY - The y coordinate, in pixels.

* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.

* @param {Phaser.Cameras.Scene2D.Camera} [camera=main camera] - The Camera to use when calculating the tile index from the world values.

* @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon.

var PutTileAtWorldXY = function (tile, worldX, worldY, recalculateFaces, camera, layer)

keep keep keep keep replace keep keep keep


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../../utils/Class');
var CONST = require('../const');
var File = require('../File');
var FileTypesManager = require('../FileTypesManager');
var GetFastValue = require('../../utils/object/GetFastValue');
var IsPlainObject = require('../../utils/object/IsPlainObject');

/**
 * @classdesc
 * A single CSS File suitable for loading by the Loader.
 *
 * These are created when you use the Phaser.Loader.LoaderPlugin#css method and are not typically created directly.
 *
 * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#css.
 *
 * @class CSSFile
 * @extends Phaser.Loader.File
 * @memberof Phaser.Loader.FileTypes
 * @constructor
 * @since 3.17.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
 * @param {(string|Phaser.Types.Loader.FileTypes.CSSFileConfig)} key - The key to use for this file, or a file configuration object.
 * @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.js`, i.e. if `key` was "alien" then the URL will be "alien.js".
 * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
 */
var CSSFile = new Class({

    Extends: File,

    initialize:

    function CSSFile (loader, key, url, xhrSettings)
    {
        var extension = 'css';

        if (IsPlainObject(key))
        {
            var config = key;

            key = GetFastValue(config, 'key');
            url = GetFastValue(config, 'url');
            xhrSettings = GetFastValue(config, 'xhrSettings');
            extension = GetFastValue(config, 'extension', extension);
        }

        var fileConfig = {
            type: 'script',
            cache: false,
            extension: extension,
            responseType: 'text',
            key: key,
            url: url,
            xhrSettings: xhrSettings
        };

        File.call(this, loader, fileConfig);
    },

    /**
     * Called automatically by Loader.nextFile.
     * This method controls what extra work this File does with its loaded data.
     *
     * @method Phaser.Loader.FileTypes.CSSFile#onProcess
     * @since 3.17.0
     */
    onProcess: function ()
    {
        this.state = CONST.FILE_PROCESSING;

        this.data = document.createElement('style');
        this.data.defer = false;
        this.data.innerHTML = this.xhrLoader.responseText;

        document.head.appendChild(this.data);

        this.onProcessComplete();
    }

});

/**
 * Adds a CSS file, or array of CSS files, to the current load queue.
 *
 * You can call this method from within your Scene's `preload`, along with any other files you wish to load:
 *
 * ```javascript
 * function preload ()
 * {
 *     this.load.css('headers', 'styles/headers.css');
 * }
 * ```
 *
 * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
 * or if it's already running, when the next free load slot becomes available. This happens automatically if you
 * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
 * it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
 * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
 * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
 * loaded.
 *
 * The key must be a unique String and not already in-use by another file in the Loader.
 *
 * Instead of passing arguments you can pass a configuration object, such as:
 *
 * ```javascript
 * this.load.css({
 *     key: 'headers',
 *     url: 'styles/headers.css'
 * });
 * ```
 *
 * See the documentation for `Phaser.Types.Loader.FileTypes.CSSFileConfig` for more details.
 *
 * Once the file has finished loading it will automatically be converted into a style DOM element
 * via `document.createElement('style')`. It will have its `defer` property set to false and then the
 * resulting element will be appended to `document.head`. The CSS styles are then applied to the current document.
 *
 * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
 *
 * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien"
 * and no URL is given then the Loader will set the URL to be "alien.css". It will always add `.css` as the extension, although
 * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
 *
 * Note: The ability to load this type of file will only be available if the CSS File type has been built into Phaser.
 * It is available in the default build but can be excluded from custom builds.
 *
 * @method Phaser.Loader.LoaderPlugin#css
 * @fires Phaser.Loader.LoaderPlugin#ADD
 * @since 3.17.0
 *
 * @param {(string|Phaser.Types.Loader.FileTypes.CSSFileConfig|Phaser.Types.Loader.FileTypes.CSSFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
 * @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.css`, i.e. if `key` was "alien" then the URL will be "alien.css".
 * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings.
 *
 * @return {this} The Loader instance.
 */
FileTypesManager.register('css', function (key, url, xhrSettings)
{
    if (Array.isArray(key))
    {
        for (var i = 0; i < key.length; i++)
        {
            //  If it's an array it has to be an array of Objects, so we get everything out of the 'key' object
            this.addFile(new CSSFile(this, key[i]));
        }
    }
    else
    {
        this.addFile(new CSSFile(this, key, url, xhrSettings));
    }

    return this;
});

module.exports = CSSFile;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Tranlates the points of the given Polygon.
 *
 * @function Phaser.Geom.Polygon.Translate
 * @since 3.50.0
 *
 * @generic {Phaser.Geom.Polygon} O - [polygon,$return]
 *
 * @param {Phaser.Geom.Polygon} polygon - The Polygon to modify.
 * @param {number} x - The amount to horizontally translate the points by.
 * @param {number} y - The amount to vertically translate the points by.
 *
 * @return {Phaser.Geom.Polygon} The modified Polygon.
 */
var Translate = function (polygon, x, y)
{
    var points = polygon.points;

    for (var i = 0; i < points.length; i++)
    {
        points[i].x += x;
        points[i].y += y;
    }

    return polygon;
};

module.exports = Translate;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CircumferencePoint = require('./CircumferencePoint');
var FromPercent = require('../../math/FromPercent');
var MATH_CONST = require('../../math/const');
var Point = require('../point/Point');

/**
 * Returns a Point object containing the coordinates of a point on the circumference of the Circle
 * based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point
 * at 180 degrees around the circle.
 *
 * @function Phaser.Geom.Circle.GetPoint
 * @since 3.0.0
 *
 * @generic {Phaser.Geom.Point} O - [out,$return]
 *
 * @param {Phaser.Geom.Circle} circle - The Circle to get the circumference point on.
 * @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the circle.
 * @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created.
 *
 * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the circle.
 */
var GetPoint = function (circle, position, out)
{
    if (out === undefined) { out = new Point(); }

    var angle = FromPercent(position, 0, MATH_CONST.PI2);

    return CircumferencePoint(circle, angle, out);
};

module.exports = GetPoint;


return PutTileAt(tile, tileX, tileY, recalculateFaces, layer);

layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera, layer);

return PutTileAt(tile, point.x, point.y, recalculateFaces, layer);

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var RemoveTileAt = require('./RemoveTileAt');

/**
 * Removes the tile at the given world coordinates in the specified layer and updates the layer's
 * collision information.
 *
 * @function Phaser.Tilemaps.Components.RemoveTileAtWorldXY
 * @since 3.0.0
 *
 * @param {number} worldX - The x coordinate, in pixels.
 * @param {number} worldY - The y coordinate, in pixels.
 * @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1.
 * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
 * @param {Phaser.Cameras.Scene2D.Camera} [camera=main camera] - The Camera to use when calculating the tile index from the world values.
 * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon.
 *
 * @return {Phaser.Tilemaps.Tile} The Tile object that was removed.
 */
var RemoveTileAtWorldXY = function (worldX, worldY, replaceWithNull, recalculateFaces, camera, layer)
{
    var point = layer.tilemapLayer.worldToTileXY(worldX, worldY, true, undefined, camera, layer);
    var tileX = point.x;
    var tileY = point.y;
    return RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, layer);
};

module.exports = RemoveTileAtWorldXY;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var COLLIDES = require('./COLLIDES');
var Events = require('./events');
var SeparateX = require('./SeparateX');
var SeparateY = require('./SeparateY');

/**
 * Impact Physics Solver
 *
 * @function Phaser.Physics.Impact.Solver
 * @fires Phaser.Physics.Impact.Events#COLLIDE
 * @since 3.0.0
 *
 * @param {Phaser.Physics.Impact.World} world - The Impact simulation to run the solver in.
 * @param {Phaser.Physics.Impact.Body} bodyA - The first body in the collision.
 * @param {Phaser.Physics.Impact.Body} bodyB - The second body in the collision.
 */
var Solver = function (world, bodyA, bodyB)
{
    var weak = null;

    if (bodyA.collides === COLLIDES.LITE || bodyB.collides === COLLIDES.FIXED)
    {
        weak = bodyA;
    }
    else if (bodyB.collides === COLLIDES.LITE || bodyA.collides === COLLIDES.FIXED)
    {
        weak = bodyB;
    }

    if (bodyA.last.x + bodyA.size.x > bodyB.last.x && bodyA.last.x < bodyB.last.x + bodyB.size.x)
    {
        if (bodyA.last.y < bodyB.last.y)
        {
            SeparateY(world, bodyA, bodyB, weak);
        }
        else
        {
            SeparateY(world, bodyB, bodyA, weak);
        }

        bodyA.collideWith(bodyB, 'y');
        bodyB.collideWith(bodyA, 'y');

        world.emit(Events.COLLIDE, bodyA, bodyB, 'y');
    }
    else if (bodyA.last.y + bodyA.size.y > bodyB.last.y && bodyA.last.y < bodyB.last.y + bodyB.size.y)
    {
        if (bodyA.last.x < bodyB.last.x)
        {
            SeparateX(world, bodyA, bodyB, weak);
        }
        else
        {
            SeparateX(world, bodyB, bodyA, weak);
        }

        bodyA.collideWith(bodyB, 'x');
        bodyB.collideWith(bodyA, 'x');

        world.emit(Events.COLLIDE, bodyA, bodyB, 'x');
    }
};

module.exports = Solver;